summaryrefslogtreecommitdiff
path: root/plugins/structuralsearch/source/com/intellij/structuralsearch/impl/matcher/handlers/SkippingHandler.java
diff options
context:
space:
mode:
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.java108
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());
+ }
+}