summaryrefslogtreecommitdiff
path: root/plugins/structuralsearch/source/com/intellij/tokenindex/RecursiveTokenizingVisitor.java
blob: 013f804a82254277e4bd5f5ba4a56d4c475b62c7 (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
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
package com.intellij.tokenindex;

import com.intellij.lang.Language;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiRecursiveElementWalkingVisitor;
import com.intellij.structuralsearch.StructuralSearchProfile;
import com.intellij.structuralsearch.StructuralSearchUtil;
import com.intellij.util.containers.HashSet;

import java.util.ArrayList;
import java.util.List;
import java.util.Set;

/**
 * @author Eugene.Kudelevsky
 */
public class RecursiveTokenizingVisitor extends PsiRecursiveElementWalkingVisitor {
  private final int myBaseOffset;
  private final List<Token> myTokens;
  private final Set<String> myLanguages = new HashSet<String>();
  private final Set<Language> myAcceptableLanguages;

  private Language myLastLanguage;
  private StructuralSearchProfile myLastProfile;

  public RecursiveTokenizingVisitor(List<Token> tokens, Set<Language> acceptableLanguages, int baseOffset) {
    super(true);
    myTokens = tokens;
    myAcceptableLanguages = acceptableLanguages;
    myBaseOffset = baseOffset;
  }

  public RecursiveTokenizingVisitor(List<Token> tokens, Set<Language> acceptableLanguages) {
    this(tokens, acceptableLanguages, 0);
  }

  public RecursiveTokenizingVisitor() {
    this(new ArrayList<Token>(), null);
  }

  public List<Token> getTokens() {
    return myTokens;
  }

  public void addToken(Token token) {
    myTokens.add(token);
  }

  public Set<String> getLanguages() {
    return myLanguages;
  }

  @Override
  public void visitElement(PsiElement element) {
    Language language = element.getLanguage();
    if (language != myLastLanguage) {
      myLastLanguage = language;
      myLastProfile = StructuralSearchUtil.getProfileByPsiElement(element);
    }
    if (myLastProfile != null) {
      language = myLastProfile.getLanguage(element);
    }
    if (myAcceptableLanguages == null || myAcceptableLanguages.contains(language)) {
      Tokenizer tokenizer = StructuralSearchUtil.getTokenizerForLanguage(language);
      if (tokenizer != null) {
        myLanguages.add(language.getID());
        if (!tokenizer.visit(element, this)) {
          return;
        }
      }
    }
    super.visitElement(element);
  }

  @Override
  protected void elementFinished(PsiElement element) {
    Tokenizer tokenizer = StructuralSearchUtil.getTokenizerForLanguage(element.getLanguage());
    if (tokenizer != null) {
      tokenizer.elementFinished(element, this);
    }
  }

  public int getBaseOffset() {
    return myBaseOffset;
  }
}