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
97
98
99
100
101
102
103
104
105
106
107
108
|
package com.intellij.structuralsearch.impl.matcher.handlers;
import com.intellij.dupLocator.equivalence.EquivalenceDescriptor;
import com.intellij.dupLocator.iterators.NodeIterator;
import com.intellij.dupLocator.util.DuplocatorUtil;
import com.intellij.dupLocator.util.NodeFilter;
import com.intellij.psi.PsiElement;
import com.intellij.structuralsearch.impl.matcher.MatchContext;
import com.intellij.structuralsearch.impl.matcher.filters.LexicalNodesFilter;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
/**
* @author Eugene.Kudelevsky
*/
public class SkippingHandler extends MatchingHandler implements DelegatingHandler {
private final MatchingHandler myDelegate;
public SkippingHandler(@NotNull MatchingHandler delegate) {
myDelegate = delegate;
}
public boolean match(PsiElement patternNode, PsiElement matchedNode, final MatchContext matchContext) {
if (patternNode == null || matchedNode == null || matchedNode.getClass() == patternNode.getClass()) {
return myDelegate.match(patternNode, matchedNode, matchContext);
}
/*if (patternNode != null && matchedNode != null && patternNode.getClass() == matchedNode.getClass()) {
//return myDelegate.match(patternNode, matchedNode, matchContext);
}*/
PsiElement newPatternNode = skipNodeIfNeccessary(patternNode);
matchedNode = skipNodeIfNeccessary(matchedNode);
if (newPatternNode != patternNode) {
return matchContext.getPattern().getHandler(newPatternNode).match(newPatternNode, matchedNode, matchContext);
}
return myDelegate.match(patternNode, matchedNode, matchContext);
}
@Override
public boolean canMatch(PsiElement patternNode, PsiElement matchedNode) {
return myDelegate.canMatch(patternNode, matchedNode);
}
@Override
public boolean matchSequentially(final NodeIterator nodes, final NodeIterator nodes2, final MatchContext context) {
return myDelegate.matchSequentially(nodes, nodes2, context);
}
public boolean match(PsiElement patternNode,
PsiElement matchedNode,
final int start,
final int end,
final MatchContext context) {
if (patternNode == null || matchedNode == null || patternNode.getClass() == matchedNode.getClass()) {
return myDelegate.match(patternNode, matchedNode, start, end, context);
}
PsiElement newPatternNode = skipNodeIfNeccessary(patternNode);
matchedNode = skipNodeIfNeccessary(matchedNode);
if (newPatternNode != patternNode) {
return context.getPattern().getHandler(newPatternNode).match(newPatternNode, matchedNode, start, end, context);
}
return myDelegate.match(patternNode, matchedNode, start, end, context);
}
protected boolean isMatchSequentiallySucceeded(final NodeIterator nodes2) {
return myDelegate.isMatchSequentiallySucceeded(nodes2);
}
@Override
public boolean shouldAdvanceTheMatchFor(PsiElement patternElement, PsiElement matchedElement) {
return true;
}
public MatchingHandler getDelegate() {
return myDelegate;
}
@Nullable
public static PsiElement getOnlyNonWhitespaceChild(PsiElement element) {
PsiElement onlyChild = null;
for (PsiElement child = element.getFirstChild(); child != null; child = child.getNextSibling()) {
if (DuplocatorUtil.isIgnoredNode(element) || child.getTextLength() == 0) {
continue;
}
if (onlyChild != null) {
return null;
}
onlyChild = child;
}
return onlyChild;
}
@Nullable
public static PsiElement skipNodeIfNeccessary(PsiElement element) {
return skipNodeIfNeccessary(element, null, null);
}
@Nullable
public static PsiElement skipNodeIfNeccessary(PsiElement element, EquivalenceDescriptor descriptor, NodeFilter filter) {
return DuplocatorUtil.skipNodeIfNeccessary(element, descriptor, filter != null ? filter : LexicalNodesFilter.getInstance());
}
}
|