summaryrefslogtreecommitdiff
path: root/java/structuralsearch-java/src/com/intellij/structuralsearch/impl/matcher/iterators/DocValuesIterator.java
blob: c1323abd0951dd8e3cb589cfd8af7a6ee7454d6a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
package com.intellij.structuralsearch.impl.matcher.iterators;

import com.intellij.dupLocator.iterators.NodeIterator;
import com.intellij.psi.JavaDocTokenType;
import com.intellij.psi.PsiElement;
import com.intellij.psi.tree.IElementType;
import com.intellij.psi.javadoc.PsiDocToken;
import com.intellij.psi.javadoc.PsiDocTagValue;

import java.util.ArrayList;

/**
 * Iterates over java doc values tag
 */
public class DocValuesIterator extends NodeIterator {
  private int index;
  private final ArrayList<PsiElement> tokens = new ArrayList<PsiElement>(2);
  private static final IElementType tokenType = JavaDocTokenType.DOC_COMMENT_DATA;

  public DocValuesIterator(PsiElement start) {
    for(PsiElement e = start; e != null; e = e.getNextSibling()) {
      if (e instanceof PsiDocTagValue) tokens.add(e);
      else if (e instanceof PsiDocToken && ((PsiDocToken)e).getTokenType() == tokenType) {
        tokens.add(e);
        e = advanceToNext(e);
      }
    }
  }

  // since doctag value may be inside doc comment we specially skip that nodes from list
  static PsiElement advanceToNext(PsiElement e) {
    PsiElement nextSibling = e.getNextSibling();
    if (nextSibling instanceof PsiDocTagValue) e = nextSibling;

    nextSibling = e.getNextSibling();

    if (nextSibling instanceof PsiDocToken &&
        ((PsiDocToken)nextSibling).getTokenType() == tokenType
       ) {
      e = nextSibling;
    }
    return e;
  }

  public boolean hasNext() {
    return index >=0 && index < tokens.size();
  }

  public PsiElement current() {
    return hasNext() ? tokens.get(index) : null;
  }

  public void advance() {
    if (index < tokens.size()) ++ index;
  }

  public void rewind() {
    if (index >= 0) --index;
  }

  public void reset() {
    index = 0;
  }
}