diff options
Diffstat (limited to 'plugins/structuralsearch/source/com/intellij/structuralsearch/impl/matcher/handlers/SkippingHandler.java')
-rw-r--r-- | plugins/structuralsearch/source/com/intellij/structuralsearch/impl/matcher/handlers/SkippingHandler.java | 108 |
1 files changed, 108 insertions, 0 deletions
diff --git a/plugins/structuralsearch/source/com/intellij/structuralsearch/impl/matcher/handlers/SkippingHandler.java b/plugins/structuralsearch/source/com/intellij/structuralsearch/impl/matcher/handlers/SkippingHandler.java new file mode 100644 index 000000000000..389c4a7916c2 --- /dev/null +++ b/plugins/structuralsearch/source/com/intellij/structuralsearch/impl/matcher/handlers/SkippingHandler.java @@ -0,0 +1,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()); + } +} |