Search in sources :

Example 1 with CompiledPattern

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

the class MatchingHandler method matchInAnyOrder.

public boolean matchInAnyOrder(NodeIterator patternNodes, NodeIterator matchedNodes, final MatchContext context) {
    final MatchResultImpl saveResult = context.hasResult() ? context.getResult() : null;
    context.setResult(null);
    try {
        if (patternNodes.hasNext() && !matchedNodes.hasNext()) {
            return validateSatisfactionOfHandlers(patternNodes, context);
        }
        Set<PsiElement> matchedElements = null;
        for (; patternNodes.hasNext(); patternNodes.advance()) {
            final PsiElement patternNode = patternNodes.current();
            final CompiledPattern pattern = context.getPattern();
            final MatchingHandler handler = pattern.getHandler(patternNode);
            final PsiElement startMatching = matchedNodes.current();
            do {
                final PsiElement element = handler.getPinnedNode(null);
                final PsiElement matchedNode = element != null ? element : matchedNodes.current();
                if (element == null)
                    matchedNodes.advance();
                if (!matchedNodes.hasNext())
                    matchedNodes.reset();
                if (matchedElements == null || !matchedElements.contains(matchedNode)) {
                    if (handler.match(patternNode, matchedNode, context)) {
                        if (matchedElements == null)
                            matchedElements = new HashSet<>();
                        matchedElements.add(matchedNode);
                        if (handler.shouldAdvanceThePatternFor(patternNode, matchedNode)) {
                            break;
                        }
                    } else if (element != null) {
                        return false;
                    }
                    // clear state of dependent objects
                    clearingVisitor.clearState(pattern, patternNode);
                }
                // passed of elements and does not found the match
                if (startMatching == matchedNodes.current()) {
                    final boolean result = validateSatisfactionOfHandlers(patternNodes, context);
                    if (result && context.getMatchedElementsListener() != null) {
                        context.getMatchedElementsListener().matchedElements(matchedElements);
                    }
                    return result;
                }
            } while (true);
            if (!handler.shouldAdvanceThePatternFor(patternNode, null)) {
                patternNodes.rewind();
            }
        }
        final boolean result = validateSatisfactionOfHandlers(patternNodes, context);
        if (result && context.getMatchedElementsListener() != null) {
            context.getMatchedElementsListener().matchedElements(matchedElements);
        }
        return result;
    } finally {
        if (saveResult != null) {
            if (context.hasResult()) {
                saveResult.getMatches().addAll(context.getResult().getMatches());
            }
            context.setResult(saveResult);
        }
    }
}
Also used : CompiledPattern(com.intellij.structuralsearch.impl.matcher.CompiledPattern) MatchResultImpl(com.intellij.structuralsearch.impl.matcher.MatchResultImpl) HashSet(java.util.HashSet)

Example 2 with CompiledPattern

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

the class SubstitutionHandler method matchInAnyOrder.

public boolean matchInAnyOrder(NodeIterator patternNodes, NodeIterator matchedNodes, final MatchContext context) {
    final MatchResultImpl saveResult = context.hasResult() ? context.getResult() : null;
    context.setResult(null);
    try {
        if (patternNodes.hasNext() && !matchedNodes.hasNext()) {
            return validateSatisfactionOfHandlers(patternNodes, context);
        }
        Set<PsiElement> matchedElements = null;
        for (; patternNodes.hasNext(); patternNodes.advance()) {
            int matchedOccurs = 0;
            final PsiElement patternNode = patternNodes.current();
            final CompiledPattern pattern = context.getPattern();
            final MatchingHandler handler = pattern.getHandler(patternNode);
            final PsiElement startMatching = matchedNodes.current();
            do {
                final PsiElement element = handler.getPinnedNode(null);
                final PsiElement matchedNode = (element != null) ? element : matchedNodes.current();
                if (element == null)
                    matchedNodes.advance();
                if (!matchedNodes.hasNext())
                    matchedNodes.reset();
                if (matchedOccurs <= maxOccurs && (matchedElements == null || !matchedElements.contains(matchedNode))) {
                    if (handler.match(patternNode, matchedNode, context)) {
                        ++matchedOccurs;
                        if (matchedElements == null)
                            matchedElements = new HashSet<>();
                        matchedElements.add(matchedNode);
                        if (handler.shouldAdvanceThePatternFor(patternNode, matchedNode)) {
                            break;
                        }
                    } else if (element != null) {
                        return false;
                    }
                    // clear state of dependent objects
                    clearingVisitor.clearState(pattern, patternNode);
                }
                // passed of elements and does not found the match
                if (startMatching == matchedNodes.current()) {
                    final boolean result = validateSatisfactionOfHandlers(patternNodes, context) && matchedOccurs >= minOccurs && matchedOccurs <= maxOccurs;
                    if (result && context.getMatchedElementsListener() != null) {
                        context.getMatchedElementsListener().matchedElements(matchedElements);
                    }
                    return result;
                }
            } while (true);
            if (!handler.shouldAdvanceThePatternFor(patternNode, null)) {
                patternNodes.rewind();
            }
        }
        final boolean result = validateSatisfactionOfHandlers(patternNodes, context);
        if (result && context.getMatchedElementsListener() != null) {
            context.getMatchedElementsListener().matchedElements(matchedElements);
        }
        return result;
    } finally {
        if (saveResult != null) {
            if (context.hasResult()) {
                saveResult.getMatches().addAll(context.getResult().getMatches());
            }
            context.setResult(saveResult);
        }
    }
}
Also used : CompiledPattern(com.intellij.structuralsearch.impl.matcher.CompiledPattern) MatchResultImpl(com.intellij.structuralsearch.impl.matcher.MatchResultImpl) PsiElement(com.intellij.psi.PsiElement) HashSet(java.util.HashSet)

Example 3 with CompiledPattern

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

the class StructuralSearchProfileBase method checkReplacementPattern.

@Override
public void checkReplacementPattern(Project project, ReplaceOptions options) {
    final CompiledPattern compiledPattern = PatternCompiler.compilePattern(project, options.getMatchOptions());
    if (compiledPattern == null) {
        return;
    }
    final NodeIterator it = compiledPattern.getNodes();
    if (!it.hasNext()) {
        return;
    }
    final PsiElement root = it.current().getParent();
    if (!checkOptionalChildren(root) || !checkErrorElements(root)) {
        throw new UnsupportedPatternException(": Partial and expression patterns are not supported");
    }
}
Also used : FilteringNodeIterator(com.intellij.dupLocator.iterators.FilteringNodeIterator) NodeIterator(com.intellij.dupLocator.iterators.NodeIterator) SsrFilteringNodeIterator(com.intellij.structuralsearch.impl.matcher.iterators.SsrFilteringNodeIterator) CompiledPattern(com.intellij.structuralsearch.impl.matcher.CompiledPattern)

Example 4 with CompiledPattern

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

the class XmlCompilingVisitor method visitXmlTag.

@Override
public void visitXmlTag(XmlTag xmlTag) {
    myCompilingVisitor.setCodeBlockLevel(myCompilingVisitor.getCodeBlockLevel() + 1);
    super.visitXmlTag(xmlTag);
    myCompilingVisitor.setCodeBlockLevel(myCompilingVisitor.getCodeBlockLevel() - 1);
    if (myCompilingVisitor.getCodeBlockLevel() == 1) {
        final CompiledPattern pattern = myCompilingVisitor.getContext().getPattern();
        pattern.setStrategy(XmlMatchingStrategy.getInstance());
        pattern.setHandler(xmlTag, new TopLevelMatchingHandler(pattern.getHandler(xmlTag)));
    }
}
Also used : CompiledPattern(com.intellij.structuralsearch.impl.matcher.CompiledPattern) TopLevelMatchingHandler(com.intellij.structuralsearch.impl.matcher.handlers.TopLevelMatchingHandler)

Example 5 with CompiledPattern

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

the class StructuralSearchProfileBase method compile.

@Override
public void compile(PsiElement[] elements, @NotNull final GlobalCompilingVisitor globalVisitor) {
    final PsiElement topElement = elements[0].getParent();
    final PsiElement element = elements.length > 1 ? topElement : elements[0];
    element.accept(new MyCompilingVisitor(globalVisitor, topElement));
    element.accept(new PsiRecursiveElementVisitor() {

        @Override
        public void visitElement(PsiElement element) {
            super.visitElement(element);
            if (DuplocatorUtil.isIgnoredNode(element)) {
                return;
            }
            CompiledPattern pattern = globalVisitor.getContext().getPattern();
            MatchingHandler handler = pattern.getHandler(element);
            if (!(handler instanceof SubstitutionHandler) && !(handler instanceof TopLevelMatchingHandler) && !(handler instanceof LightTopLevelMatchingHandler)) {
                pattern.setHandler(element, new SkippingHandler(handler));
            }
            /*
        place skipping handler under top-level handler, because when we skip top-level node we can get non top-level handler, so
        depth matching won't be done!;
         */
            if (handler instanceof LightTopLevelMatchingHandler) {
                MatchingHandler delegate = ((LightTopLevelMatchingHandler) handler).getDelegate();
                if (!(delegate instanceof SubstitutionHandler)) {
                    pattern.setHandler(element, new LightTopLevelMatchingHandler(new SkippingHandler(delegate)));
                }
            }
        }
    });
    final Language baseLanguage = element.getContainingFile().getLanguage();
    // todo: try to optimize it: too heavy strategy!
    globalVisitor.getContext().getPattern().setStrategy(new MatchingStrategy() {

        @Override
        public boolean continueMatching(PsiElement start) {
            Language language = start.getLanguage();
            PsiFile file = start.getContainingFile();
            if (file != null) {
                Language fileLanguage = file.getLanguage();
                if (fileLanguage.isKindOf(language)) {
                    // dialect
                    language = fileLanguage;
                }
            }
            return language == baseLanguage;
        }

        @Override
        public boolean shouldSkip(PsiElement element, PsiElement elementToMatchWith) {
            return DuplocatorUtil.shouldSkip(element, elementToMatchWith);
        }
    });
}
Also used : Language(com.intellij.lang.Language) CompiledPattern(com.intellij.structuralsearch.impl.matcher.CompiledPattern) MatchingStrategy(com.intellij.structuralsearch.impl.matcher.strategies.MatchingStrategy)

Aggregations

CompiledPattern (com.intellij.structuralsearch.impl.matcher.CompiledPattern)9 JavaCompiledPattern (com.intellij.structuralsearch.impl.matcher.JavaCompiledPattern)3 Language (com.intellij.lang.Language)2 MatchResultImpl (com.intellij.structuralsearch.impl.matcher.MatchResultImpl)2 HashSet (java.util.HashSet)2 FilteringNodeIterator (com.intellij.dupLocator.iterators.FilteringNodeIterator)1 NodeIterator (com.intellij.dupLocator.iterators.NodeIterator)1 FileType (com.intellij.openapi.fileTypes.FileType)1 LanguageFileType (com.intellij.openapi.fileTypes.LanguageFileType)1 PsiElement (com.intellij.psi.PsiElement)1 PsiFileImpl (com.intellij.psi.impl.source.PsiFileImpl)1 GlobalSearchScope (com.intellij.psi.search.GlobalSearchScope)1 LocalSearchScope (com.intellij.psi.search.LocalSearchScope)1 TopLevelMatchingHandler (com.intellij.structuralsearch.impl.matcher.handlers.TopLevelMatchingHandler)1 SsrFilteringNodeIterator (com.intellij.structuralsearch.impl.matcher.iterators.SsrFilteringNodeIterator)1 MatchingStrategy (com.intellij.structuralsearch.impl.matcher.strategies.MatchingStrategy)1 TIntArrayList (gnu.trove.TIntArrayList)1