summaryrefslogtreecommitdiff
path: root/platform/structuralsearch/source/com/intellij/structuralsearch/impl/matcher/handlers/TopLevelMatchingHandler.java
diff options
context:
space:
mode:
Diffstat (limited to 'platform/structuralsearch/source/com/intellij/structuralsearch/impl/matcher/handlers/TopLevelMatchingHandler.java')
-rw-r--r--platform/structuralsearch/source/com/intellij/structuralsearch/impl/matcher/handlers/TopLevelMatchingHandler.java85
1 files changed, 85 insertions, 0 deletions
diff --git a/platform/structuralsearch/source/com/intellij/structuralsearch/impl/matcher/handlers/TopLevelMatchingHandler.java b/platform/structuralsearch/source/com/intellij/structuralsearch/impl/matcher/handlers/TopLevelMatchingHandler.java
new file mode 100644
index 000000000000..6711bcb1fc7f
--- /dev/null
+++ b/platform/structuralsearch/source/com/intellij/structuralsearch/impl/matcher/handlers/TopLevelMatchingHandler.java
@@ -0,0 +1,85 @@
+package com.intellij.structuralsearch.impl.matcher.handlers;
+
+import com.intellij.dupLocator.iterators.NodeIterator;
+import com.intellij.dupLocator.iterators.SiblingNodeIterator;
+import com.intellij.psi.PsiComment;
+import com.intellij.psi.PsiElement;
+import com.intellij.structuralsearch.StructuralSearchUtil;
+import com.intellij.structuralsearch.impl.matcher.MatchContext;
+import com.intellij.structuralsearch.impl.matcher.iterators.SsrFilteringNodeIterator;
+import org.jetbrains.annotations.NotNull;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public final class TopLevelMatchingHandler extends MatchingHandler implements DelegatingHandler {
+ private final MatchingHandler delegate;
+
+ public TopLevelMatchingHandler(@NotNull MatchingHandler _delegate) {
+ delegate = _delegate;
+ setFilter(_delegate.getFilter());
+ }
+
+ public boolean match(final PsiElement patternNode, final PsiElement matchedNode, final MatchContext matchContext) {
+ final boolean matched = delegate.match(patternNode, matchedNode, matchContext);
+
+ if (matched) {
+ List<PsiElement> matchedNodes = matchContext.getMatchedNodes();
+ if (matchedNodes == null) {
+ matchedNodes = new ArrayList<PsiElement>();
+ matchContext.setMatchedNodes(matchedNodes);
+ }
+
+ PsiElement elementToAdd = matchedNode;
+
+ if (patternNode instanceof PsiComment && StructuralSearchUtil.isDocCommentOwner(matchedNode)) {
+ // psicomment and psidoccomment are placed inside the psimember next to them so
+ // simple topdown matching should do additional "dances" to cover this case.
+ elementToAdd = matchedNode.getFirstChild();
+ assert elementToAdd instanceof PsiComment;
+ }
+
+ matchedNodes.add(elementToAdd);
+ }
+
+ if ((!matched || matchContext.getOptions().isRecursiveSearch()) &&
+ matchContext.getPattern().getStrategy().continueMatching(matchedNode) &&
+ matchContext.shouldRecursivelyMatch()
+ ) {
+ matchContext.getMatcher().matchContext(
+ new SsrFilteringNodeIterator(
+ new SiblingNodeIterator(matchedNode.getFirstChild())
+ )
+ );
+ }
+ return matched;
+ }
+
+ @Override
+ public boolean canMatch(PsiElement patternNode, PsiElement matchedNode) {
+ return delegate.canMatch(patternNode, matchedNode);
+ }
+
+ @Override
+ public boolean matchSequentially(final NodeIterator nodes, final NodeIterator nodes2, final MatchContext context) {
+ return delegate.matchSequentially(nodes, nodes2, context);
+ }
+
+ public boolean match(final PsiElement patternNode,
+ final PsiElement matchedNode, final int start, final int end, final MatchContext context) {
+ return match(patternNode, matchedNode, context);
+ }
+
+ public boolean isMatchSequentiallySucceeded(final NodeIterator nodes2) {
+ return true;
+ }
+
+ @Override
+ public boolean shouldAdvanceTheMatchFor(final PsiElement patternElement, final PsiElement matchedElement) {
+ return delegate.shouldAdvanceTheMatchFor(patternElement, matchedElement);
+ }
+
+ public MatchingHandler getDelegate() {
+ return delegate;
+ }
+} \ No newline at end of file