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;
}
}
|