summaryrefslogtreecommitdiff
path: root/java/structuralsearch-java/src/com/intellij/structuralsearch/impl/matcher/handlers/DeclarationStatementHandler.java
blob: 7342e96758f0bd35fc49f2d6867acd86990765e7 (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
87
88
89
90
91
92
93
94
95
96
package com.intellij.structuralsearch.impl.matcher.handlers;

import com.intellij.dupLocator.iterators.ArrayBackedNodeIterator;
import com.intellij.dupLocator.iterators.CountingNodeIterator;
import com.intellij.psi.*;
import com.intellij.structuralsearch.impl.matcher.GlobalMatchingVisitor;
import com.intellij.structuralsearch.impl.matcher.MatchContext;
import com.intellij.structuralsearch.impl.matcher.iterators.SsrFilteringNodeIterator;

/**
 * Created by IntelliJ IDEA.
 * User: maxim
 * Date: 31.12.2004
 * Time: 12:01:29
 * To change this template use File | Settings | File Templates.
 */
public class DeclarationStatementHandler extends MatchingHandler {
  private MatchingHandler myCommentHandler;

  public boolean match(PsiElement patternNode,PsiElement matchedNode, MatchContext context) {
    if (patternNode instanceof PsiComment) {
      //if (matchedNode instanceof  PsiComment || matchedNode instanceof PsiClass || matchedNode instanceof PsiField)
        return myCommentHandler.match(patternNode, matchedNode, context);
      //return false;
    }

    if (!super.match(patternNode,matchedNode,context)) return false;
    boolean result;
    PsiDeclarationStatement dcl = (PsiDeclarationStatement)patternNode;

    if (matchedNode instanceof PsiDeclarationStatement) {
      result = GlobalMatchingVisitor.continueMatchingSequentially(
        new SsrFilteringNodeIterator(patternNode.getFirstChild()),
        new SsrFilteringNodeIterator(matchedNode.getFirstChild()),
        context
      );
    } else {
      final PsiElement[] declared = dcl.getDeclaredElements();

      // declaration statement could wrap class or dcl
      if (declared.length >0 &&
          ( ( declared[0] instanceof PsiVariable && matchedNode instanceof PsiVariable) ||
            ( declared[0] instanceof PsiClass && matchedNode instanceof PsiClass)
          ) &&
          !(matchedNode.getParent() instanceof PsiDeclarationStatement) // skip twice matching for child
         ) {
        result = GlobalMatchingVisitor.continueMatchingSequentially(
          new ArrayBackedNodeIterator(declared),
          new CountingNodeIterator(
            declared.length,
            new SsrFilteringNodeIterator(matchedNode)
          ),
          context
        );

        if (result &&
            declared[0] instanceof PsiVariable && matchedNode instanceof PsiField
            ) {
          // we may have comments behind to match!
          final PsiElement[] children = dcl.getChildren();

          final PsiElement lastChild = children[children.length - 1];
          if (lastChild instanceof PsiComment) {
            final PsiElement[] fieldChildren = matchedNode.getChildren();

            result = context.getPattern().getHandler(lastChild).match(
              lastChild,
              fieldChildren[fieldChildren.length-1],
              context
            );
          }
        }
      } else {
        result = false;
      }
    }

    return result;
  }

  public boolean shouldAdvanceTheMatchFor(PsiElement patternElement, PsiElement matchedElement) {
    if (patternElement instanceof PsiComment &&
        ( matchedElement instanceof PsiField ||
          matchedElement instanceof PsiClass
        )
       ) {
      return false;
    }

    return super.shouldAdvanceTheMatchFor(patternElement,matchedElement);
  }

  public void setCommentHandler(final MatchingHandler commentHandler) {
    myCommentHandler = commentHandler;
  }
}