Search in sources :

Example 1 with SsrFilteringNodeIterator

use of com.intellij.structuralsearch.impl.matcher.iterators.SsrFilteringNodeIterator in project intellij-community by JetBrains.

the class DeclarationStatementHandler method match.

@Override
public boolean match(PsiElement patternNode, PsiElement matchedNode, MatchContext context) {
    if (patternNode instanceof PsiComment) {
        return myCommentHandler.match(patternNode, matchedNode, context);
    }
    if (!super.match(patternNode, matchedNode, context))
        return false;
    final PsiDeclarationStatement dcl = (PsiDeclarationStatement) patternNode;
    if (matchedNode instanceof PsiDeclarationStatement) {
        return context.getMatcher().matchSequentially(new SsrFilteringNodeIterator(patternNode.getFirstChild()), new SsrFilteringNodeIterator(matchedNode.getFirstChild()));
    }
    final PsiElement[] declared = dcl.getDeclaredElements();
    // declaration statement could wrap class or dcl
    if (declared.length > 0 && !(matchedNode.getParent() instanceof PsiDeclarationStatement)) /* skip twice matching for child*/
    {
        if (!(matchedNode instanceof PsiField)) {
            return context.getMatcher().matchSequentially(new ArrayBackedNodeIterator(declared), new CountingNodeIterator(declared.length, new SsrFilteringNodeIterator(matchedNode)));
        }
        // special handling for multiple fields in single declaration
        final PsiElement sibling = PsiTreeUtil.skipSiblingsBackward(matchedNode, PsiWhiteSpace.class);
        if (PsiUtil.isJavaToken(sibling, JavaTokenType.COMMA)) {
            return false;
        }
        final List<PsiElement> matchNodes = new ArrayList<>();
        matchNodes.add(matchedNode);
        PsiElement node = matchedNode;
        node = PsiTreeUtil.skipSiblingsForward(node, PsiWhiteSpace.class);
        while (PsiUtil.isJavaToken(node, JavaTokenType.COMMA)) {
            node = PsiTreeUtil.skipSiblingsForward(node, PsiWhiteSpace.class);
            if (node instanceof PsiField) {
                matchNodes.add(node);
            }
            node = PsiTreeUtil.skipSiblingsForward(node, PsiWhiteSpace.class);
        }
        boolean result = context.getMatcher().matchSequentially(new ArrayBackedNodeIterator(declared), new ArrayBackedNodeIterator(matchNodes.toArray(new PsiElement[matchNodes.size()])));
        if (result && declared[0] instanceof PsiVariable) {
            // we may have comments behind to match!
            final PsiElement lastChild = dcl.getLastChild();
            if (lastChild instanceof PsiComment) {
                final PsiElement[] fieldChildren = matchedNode.getChildren();
                result = context.getPattern().getHandler(lastChild).match(lastChild, fieldChildren[fieldChildren.length - 1], context);
            }
        }
        return result;
    }
    return false;
}
Also used : ArrayList(java.util.ArrayList) CountingNodeIterator(com.intellij.dupLocator.iterators.CountingNodeIterator) SsrFilteringNodeIterator(com.intellij.structuralsearch.impl.matcher.iterators.SsrFilteringNodeIterator) ArrayBackedNodeIterator(com.intellij.dupLocator.iterators.ArrayBackedNodeIterator)

Example 2 with SsrFilteringNodeIterator

use of com.intellij.structuralsearch.impl.matcher.iterators.SsrFilteringNodeIterator in project intellij-community by JetBrains.

the class TopLevelMatchingHandler method match.

@Override
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<>();
            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;
}
Also used : PsiComment(com.intellij.psi.PsiComment) SiblingNodeIterator(com.intellij.dupLocator.iterators.SiblingNodeIterator) SsrFilteringNodeIterator(com.intellij.structuralsearch.impl.matcher.iterators.SsrFilteringNodeIterator) PsiElement(com.intellij.psi.PsiElement)

Example 3 with SsrFilteringNodeIterator

use of com.intellij.structuralsearch.impl.matcher.iterators.SsrFilteringNodeIterator in project intellij-community by JetBrains.

the class SSBasedInspection method buildVisitor.

@NotNull
@Override
public PsiElementVisitor buildVisitor(@NotNull final ProblemsHolder holder, final boolean isOnTheFly) {
    final Map<Configuration, MatchContext> compiledOptions = SSBasedInspectionCompiledPatternsCache.getCompiledOptions(myConfigurations, holder.getProject());
    if (compiledOptions.isEmpty())
        return super.buildVisitor(holder, isOnTheFly);
    return new PsiElementVisitor() {

        final Matcher matcher = new Matcher(holder.getManager().getProject());

        final PairProcessor<MatchResult, Configuration> processor = (matchResult, configuration) -> {
            PsiElement element = matchResult.getMatch();
            String name = configuration.getName();
            LocalQuickFix fix = createQuickFix(holder.getManager().getProject(), matchResult, configuration);
            holder.registerProblem(holder.getManager().createProblemDescriptor(element, name, fix, ProblemHighlightType.GENERIC_ERROR_OR_WARNING, isOnTheFly));
            return true;
        };

        @Override
        public void visitElement(PsiElement element) {
            synchronized (LOCK) {
                if (LexicalNodesFilter.getInstance().accepts(element))
                    return;
                final SsrFilteringNodeIterator matchedNodes = new SsrFilteringNodeIterator(element);
                for (Map.Entry<Configuration, MatchContext> entry : compiledOptions.entrySet()) {
                    Configuration configuration = entry.getKey();
                    MatchContext context = entry.getValue();
                    if (MatcherImpl.checkIfShouldAttemptToMatch(context, matchedNodes)) {
                        final int nodeCount = context.getPattern().getNodeCount();
                        try {
                            matcher.processMatchesInElement(context, configuration, new CountingNodeIterator(nodeCount, matchedNodes), processor);
                        } catch (StructuralSearchException e) {
                            if (myProblemsReported.add(configuration.getName())) {
                                // don't overwhelm the user with messages
                                Notifications.Bus.notify(new Notification(SSRBundle.message("structural.search.title"), SSRBundle.message("template.problem", configuration.getName()), e.getMessage(), NotificationType.ERROR), element.getProject());
                            }
                        }
                        matchedNodes.reset();
                    }
                }
            }
        }
    };
}
Also used : ReplaceConfiguration(com.intellij.structuralsearch.plugin.replace.ui.ReplaceConfiguration) Configuration(com.intellij.structuralsearch.plugin.ui.Configuration) Matcher(com.intellij.structuralsearch.Matcher) PsiElementVisitor(com.intellij.psi.PsiElementVisitor) PairProcessor(com.intellij.util.PairProcessor) Notification(com.intellij.notification.Notification) StructuralSearchException(com.intellij.structuralsearch.StructuralSearchException) CountingNodeIterator(com.intellij.dupLocator.iterators.CountingNodeIterator) MatchContext(com.intellij.structuralsearch.impl.matcher.MatchContext) SsrFilteringNodeIterator(com.intellij.structuralsearch.impl.matcher.iterators.SsrFilteringNodeIterator) PsiElement(com.intellij.psi.PsiElement) NotNull(org.jetbrains.annotations.NotNull)

Example 4 with SsrFilteringNodeIterator

use of com.intellij.structuralsearch.impl.matcher.iterators.SsrFilteringNodeIterator in project intellij-community by JetBrains.

the class MatcherImpl method findMatches.

/**
   * Finds the matches of given pattern starting from given tree element.
   * @throws MalformedPatternException
   * @throws UnsupportedPatternException
   */
protected void findMatches(MatchResultSink sink, final MatchOptions options) throws MalformedPatternException, UnsupportedPatternException {
    CompiledPattern compiledPattern = prepareMatching(sink, options);
    if (compiledPattern == null) {
        return;
    }
    matchContext.getSink().setMatchingProcess(scheduler);
    scheduler.init();
    progress = matchContext.getSink().getProgressIndicator();
    if (isTesting) {
        // testing mode;
        final PsiElement[] elements = ((LocalSearchScope) options.getScope()).getScope();
        PsiElement parent = elements[0].getParent();
        if (elements.length > 0 && matchContext.getPattern().getStrategy().continueMatching(parent != null ? parent : elements[0])) {
            visitor.matchContext(new SsrFilteringNodeIterator(new ArrayBackedNodeIterator(elements)));
        } else {
            final LanguageFileType fileType = (LanguageFileType) matchContext.getOptions().getFileType();
            final Language language = fileType.getLanguage();
            for (PsiElement element : elements) {
                match(element, language);
            }
        }
        matchContext.getSink().matchingFinished();
        return;
    }
    if (!findMatches(options, compiledPattern)) {
        return;
    }
    if (scheduler.getTaskQueueEndAction() == null) {
        scheduler.setTaskQueueEndAction(() -> matchContext.getSink().matchingFinished());
    }
    scheduler.executeNext();
}
Also used : LocalSearchScope(com.intellij.psi.search.LocalSearchScope) LanguageFileType(com.intellij.openapi.fileTypes.LanguageFileType) Language(com.intellij.lang.Language) SsrFilteringNodeIterator(com.intellij.structuralsearch.impl.matcher.iterators.SsrFilteringNodeIterator) ArrayBackedNodeIterator(com.intellij.dupLocator.iterators.ArrayBackedNodeIterator)

Aggregations

SsrFilteringNodeIterator (com.intellij.structuralsearch.impl.matcher.iterators.SsrFilteringNodeIterator)4 ArrayBackedNodeIterator (com.intellij.dupLocator.iterators.ArrayBackedNodeIterator)2 CountingNodeIterator (com.intellij.dupLocator.iterators.CountingNodeIterator)2 PsiElement (com.intellij.psi.PsiElement)2 SiblingNodeIterator (com.intellij.dupLocator.iterators.SiblingNodeIterator)1 Language (com.intellij.lang.Language)1 Notification (com.intellij.notification.Notification)1 LanguageFileType (com.intellij.openapi.fileTypes.LanguageFileType)1 PsiComment (com.intellij.psi.PsiComment)1 PsiElementVisitor (com.intellij.psi.PsiElementVisitor)1 LocalSearchScope (com.intellij.psi.search.LocalSearchScope)1 Matcher (com.intellij.structuralsearch.Matcher)1 StructuralSearchException (com.intellij.structuralsearch.StructuralSearchException)1 MatchContext (com.intellij.structuralsearch.impl.matcher.MatchContext)1 ReplaceConfiguration (com.intellij.structuralsearch.plugin.replace.ui.ReplaceConfiguration)1 Configuration (com.intellij.structuralsearch.plugin.ui.Configuration)1 PairProcessor (com.intellij.util.PairProcessor)1 ArrayList (java.util.ArrayList)1 NotNull (org.jetbrains.annotations.NotNull)1