Search in sources :

Example 6 with MatchingHandler

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

the class JavaMatchingVisitor method visitTypeParameter.

@Override
public void visitTypeParameter(PsiTypeParameter psiTypeParameter) {
    final PsiTypeParameter parameter = (PsiTypeParameter) myMatchingVisitor.getElement();
    final PsiIdentifier identifier = psiTypeParameter.getNameIdentifier();
    final PsiIdentifier identifier2 = parameter.getNameIdentifier();
    final MatchingHandler handler = myMatchingVisitor.getMatchContext().getPattern().getHandler(identifier);
    if (handler instanceof SubstitutionHandler) {
        myMatchingVisitor.setResult(((SubstitutionHandler) handler).handle(identifier2, myMatchingVisitor.getMatchContext()));
    } else {
        myMatchingVisitor.setResult(myMatchingVisitor.matchText(identifier, identifier2));
    }
    if (myMatchingVisitor.getResult()) {
        myMatchingVisitor.setResult(matchInAnyOrder(psiTypeParameter.getExtendsList(), parameter.getExtendsList()));
    }
    if (myMatchingVisitor.getResult()) {
        myMatchingVisitor.setResult(myMatchingVisitor.matchInAnyOrder(psiTypeParameter.getAnnotations(), parameter.getAnnotations()));
    }
}
Also used : SubstitutionHandler(com.intellij.structuralsearch.impl.matcher.handlers.SubstitutionHandler) MatchingHandler(com.intellij.structuralsearch.impl.matcher.handlers.MatchingHandler)

Example 7 with MatchingHandler

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

the class JavaMatchingVisitor method compareClasses.

private boolean compareClasses(final PsiClass clazz, final PsiClass clazz2) {
    final PsiClass saveClazz = this.myClazz;
    final MatchContext.MatchedElementsListener oldListener = myMatchingVisitor.getMatchContext().getMatchedElementsListener();
    this.myClazz = clazz2;
    final CompiledPattern pattern = myMatchingVisitor.getMatchContext().getPattern();
    assert pattern instanceof JavaCompiledPattern;
    final JavaCompiledPattern javaPattern = (JavaCompiledPattern) pattern;
    MatchContext.MatchedElementsListener listener = new MatchContext.MatchedElementsListener() {

        private Set<PsiElement> myMatchedElements;

        @Override
        public void matchedElements(Collection<PsiElement> matchedElements) {
            if (matchedElements == null)
                return;
            if (myMatchedElements == null) {
                myMatchedElements = new HashSet<>(matchedElements);
            } else {
                myMatchedElements.addAll(matchedElements);
            }
        }

        @Override
        public void commitUnmatched() {
            final List<PsiMember> members = PsiTreeUtil.getChildrenOfTypeAsList(clazz2, PsiMember.class);
            final List<PsiMember> unmatchedElements = ContainerUtil.filter(members, a -> myMatchedElements == null || !myMatchedElements.contains(a));
            MatchingHandler unmatchedSubstitutionHandler = null;
            for (PsiElement element = clazz.getFirstChild(); element != null; element = element.getNextSibling()) {
                if (element instanceof PsiTypeElement && element.getNextSibling() instanceof PsiErrorElement) {
                    unmatchedSubstitutionHandler = pattern.getHandler(element);
                    break;
                }
            }
            if (unmatchedSubstitutionHandler instanceof SubstitutionHandler) {
                final SubstitutionHandler handler = (SubstitutionHandler) unmatchedSubstitutionHandler;
                for (PsiMember element : unmatchedElements) {
                    handler.handle(element, myMatchingVisitor.getMatchContext());
                }
            } else {
                clazz2.putUserData(GlobalMatchingVisitor.UNMATCHED_ELEMENTS_KEY, unmatchedElements);
            }
        }
    };
    myMatchingVisitor.getMatchContext().setMatchedElementsListener(listener);
    boolean result = false;
    try {
        final boolean templateIsInterface = clazz.isInterface();
        if (templateIsInterface != clazz2.isInterface())
            return false;
        if (templateIsInterface && clazz.isAnnotationType() && !clazz2.isAnnotationType())
            return false;
        if (clazz.isEnum() && !clazz2.isEnum())
            return false;
        if (!matchInAnyOrder(clazz.getExtendsList(), clazz2.getExtendsList())) {
            return false;
        }
        // check if implements is in extended classes implements
        final PsiReferenceList implementsList = clazz.getImplementsList();
        if (implementsList != null) {
            if (!matchInAnyOrder(implementsList, clazz2.getImplementsList())) {
                final PsiReferenceList anotherExtendsList = clazz2.getExtendsList();
                final PsiJavaCodeReferenceElement[] referenceElements = implementsList.getReferenceElements();
                boolean accepted = false;
                if (referenceElements.length > 0 && anotherExtendsList != null) {
                    final HierarchyNodeIterator iterator = new HierarchyNodeIterator(clazz2, true, true, false);
                    accepted = myMatchingVisitor.matchInAnyOrder(new ArrayBackedNodeIterator(referenceElements), iterator);
                }
                if (!accepted)
                    return false;
            }
        }
        final PsiField[] fields = clazz.getFields();
        if (fields.length > 0) {
            final PsiField[] fields2 = javaPattern.isRequestsSuperFields() ? clazz2.getAllFields() : clazz2.getFields();
            if (!myMatchingVisitor.matchInAnyOrder(fields, fields2)) {
                return false;
            }
        }
        final PsiMethod[] methods = clazz.getMethods();
        if (methods.length > 0) {
            final PsiMethod[] methods2 = javaPattern.isRequestsSuperMethods() ? clazz2.getAllMethods() : clazz2.getMethods();
            if (!myMatchingVisitor.matchInAnyOrder(methods, methods2)) {
                return false;
            }
        }
        final PsiClass[] nestedClasses = clazz.getInnerClasses();
        if (nestedClasses.length > 0) {
            final PsiClass[] nestedClasses2 = javaPattern.isRequestsSuperInners() ? clazz2.getAllInnerClasses() : clazz2.getInnerClasses();
            if (!myMatchingVisitor.matchInAnyOrder(nestedClasses, nestedClasses2)) {
                return false;
            }
        }
        final PsiClassInitializer[] initializers = clazz.getInitializers();
        if (initializers.length > 0) {
            final PsiClassInitializer[] initializers2 = clazz2.getInitializers();
            if (!myMatchingVisitor.matchInAnyOrder(initializers, initializers2)) {
                return false;
            }
        }
        result = true;
        return true;
    } finally {
        if (result)
            listener.commitUnmatched();
        this.myClazz = saveClazz;
        myMatchingVisitor.getMatchContext().setMatchedElementsListener(oldListener);
    }
}
Also used : MatchingHandler(com.intellij.structuralsearch.impl.matcher.handlers.MatchingHandler) HierarchyNodeIterator(com.intellij.structuralsearch.impl.matcher.iterators.HierarchyNodeIterator) SubstitutionHandler(com.intellij.structuralsearch.impl.matcher.handlers.SubstitutionHandler) ArrayBackedNodeIterator(com.intellij.dupLocator.iterators.ArrayBackedNodeIterator)

Example 8 with MatchingHandler

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

the class JavaMatchingVisitor method visitLiteralExpression.

@Override
public void visitLiteralExpression(final PsiLiteralExpression const1) {
    final PsiLiteralExpression const2 = (PsiLiteralExpression) myMatchingVisitor.getElement();
    final MatchingHandler handler = (MatchingHandler) const1.getUserData(CompiledPattern.HANDLER_KEY);
    if (handler instanceof SubstitutionHandler) {
        final PsiType type1 = const1.getType();
        if (type1 != null && !type1.equals(const2.getType())) {
            myMatchingVisitor.setResult(false);
        } else {
            int offset = 0;
            int length = const2.getTextLength();
            final String text = const2.getText();
            if (length > 2 && text.charAt(0) == '"' && text.charAt(length - 1) == '"') {
                length--;
                offset++;
            }
            myMatchingVisitor.setResult(((SubstitutionHandler) handler).handle(const2, offset, length, myMatchingVisitor.getMatchContext()));
        }
    } else if (handler != null) {
        myMatchingVisitor.setResult(handler.match(const1, const2, myMatchingVisitor.getMatchContext()));
    } else {
        myMatchingVisitor.setResult(myMatchingVisitor.matchText(const1, const2));
    }
}
Also used : SubstitutionHandler(com.intellij.structuralsearch.impl.matcher.handlers.SubstitutionHandler) MatchingHandler(com.intellij.structuralsearch.impl.matcher.handlers.MatchingHandler)

Example 9 with MatchingHandler

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

the class JavaMatchingVisitor method visitMethodCallExpression.

@Override
public void visitMethodCallExpression(final PsiMethodCallExpression mcall) {
    final PsiElement element = myMatchingVisitor.getElement();
    if (!(element instanceof PsiMethodCallExpression)) {
        myMatchingVisitor.setResult(false);
        return;
    }
    final PsiMethodCallExpression mcall2 = (PsiMethodCallExpression) element;
    final PsiReferenceExpression mcallRef1 = mcall.getMethodExpression();
    final PsiReferenceExpression mcallRef2 = mcall2.getMethodExpression();
    final PsiElement patternMethodName = mcallRef1.getReferenceNameElement();
    final boolean isTypedVar = myMatchingVisitor.getMatchContext().getPattern().isTypedVar(patternMethodName);
    if (!isTypedVar && !myMatchingVisitor.matchText(patternMethodName, mcallRef2.getReferenceNameElement())) {
        myMatchingVisitor.setResult(false);
        return;
    }
    final PsiExpression patternQualifier = mcallRef1.getQualifierExpression();
    final PsiExpression matchedQualifier = mcallRef2.getQualifierExpression();
    if (patternQualifier != null) {
        if (matchedQualifier != null) {
            myMatchingVisitor.setResult(myMatchingVisitor.match(patternQualifier, matchedQualifier));
            if (!myMatchingVisitor.getResult())
                return;
        } else {
            final PsiMethod method = mcall2.resolveMethod();
            if (method != null) {
                if (patternQualifier instanceof PsiThisExpression) {
                    myMatchingVisitor.setResult(!method.hasModifierProperty(PsiModifier.STATIC));
                    return;
                }
            }
            final MatchingHandler handler = myMatchingVisitor.getMatchContext().getPattern().getHandler(patternQualifier);
            matchImplicitQualifier(handler, method, myMatchingVisitor.getMatchContext());
            if (!myMatchingVisitor.getResult()) {
                return;
            }
        }
    } else if (matchedQualifier != null) {
        myMatchingVisitor.setResult(false);
        return;
    }
    myMatchingVisitor.setResult(myMatchingVisitor.matchSons(mcall.getArgumentList(), mcall2.getArgumentList()));
    if (myMatchingVisitor.getResult()) {
        myMatchingVisitor.setResult(matchTypeParameters(mcallRef1, mcallRef2));
    }
    if (myMatchingVisitor.getResult() && isTypedVar) {
        boolean res = myMatchingVisitor.getResult();
        res &= myMatchingVisitor.handleTypedElement(patternMethodName, mcallRef2.getReferenceNameElement());
        myMatchingVisitor.setResult(res);
    }
}
Also used : MatchingHandler(com.intellij.structuralsearch.impl.matcher.handlers.MatchingHandler)

Example 10 with MatchingHandler

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

the class JavaMatchingVisitor method visitTryStatement.

@Override
public void visitTryStatement(final PsiTryStatement try1) {
    final PsiTryStatement try2 = (PsiTryStatement) myMatchingVisitor.getElement();
    myMatchingVisitor.setResult(myMatchingVisitor.matchSons(try1.getTryBlock(), try2.getTryBlock()));
    if (!myMatchingVisitor.getResult())
        return;
    final PsiResourceList resourceList1 = try1.getResourceList();
    final PsiCatchSection[] catches1 = try1.getCatchSections();
    final PsiCodeBlock finally1 = try1.getFinallyBlock();
    final PsiResourceList resourceList2 = try2.getResourceList();
    final PsiCatchSection[] catches2 = try2.getCatchSections();
    final PsiCodeBlock finally2 = try2.getFinallyBlock();
    if (!myMatchingVisitor.getMatchContext().getOptions().isLooseMatching() && ((catches1.length == 0 && catches2.length != 0) || (finally1 == null && finally2 != null) || (resourceList1 == null && resourceList2 != null)) || catches2.length < catches1.length) {
        myMatchingVisitor.setResult(false);
    } else {
        final List<PsiElement> unmatchedElements = new ArrayList<>();
        if (resourceList1 != null) {
            if (resourceList2 == null) {
                myMatchingVisitor.setResult(false);
                return;
            }
            final List<PsiResourceListElement> resources1 = PsiTreeUtil.getChildrenOfTypeAsList(resourceList1, PsiResourceListElement.class);
            final List<PsiResourceListElement> resources2 = PsiTreeUtil.getChildrenOfTypeAsList(resourceList2, PsiResourceListElement.class);
            myMatchingVisitor.setResult(myMatchingVisitor.matchInAnyOrder(resources1.toArray(new PsiResourceListElement[resources1.size()]), resources2.toArray(new PsiResourceListElement[resources2.size()])));
            if (!myMatchingVisitor.getResult())
                return;
        } else if (resourceList2 != null) {
            unmatchedElements.add(resourceList2);
        }
        ContainerUtil.addAll(unmatchedElements, catches2);
        for (PsiCatchSection catchSection : catches1) {
            final MatchingHandler handler = myMatchingVisitor.getMatchContext().getPattern().getHandler(catchSection);
            final PsiElement pinnedNode = handler.getPinnedNode(null);
            if (pinnedNode != null) {
                myMatchingVisitor.setResult(handler.match(catchSection, pinnedNode, myMatchingVisitor.getMatchContext()));
                if (!myMatchingVisitor.getResult())
                    return;
            } else {
                boolean matched = false;
                for (int j = 0; j < unmatchedElements.size(); ++j) {
                    if (handler.match(catchSection, unmatchedElements.get(j), myMatchingVisitor.getMatchContext())) {
                        unmatchedElements.remove(j);
                        matched = true;
                        break;
                    }
                }
                if (!matched) {
                    myMatchingVisitor.setResult(false);
                    return;
                }
            }
        }
        if (finally1 != null) {
            myMatchingVisitor.setResult(myMatchingVisitor.matchSons(finally1, finally2));
        } else if (finally2 != null) {
            unmatchedElements.add(finally2);
        }
        if (myMatchingVisitor.getResult() && unmatchedElements.size() > 0) {
            try2.putUserData(GlobalMatchingVisitor.UNMATCHED_ELEMENTS_KEY, unmatchedElements);
        }
    }
}
Also used : MatchingHandler(com.intellij.structuralsearch.impl.matcher.handlers.MatchingHandler)

Aggregations

MatchingHandler (com.intellij.structuralsearch.impl.matcher.handlers.MatchingHandler)18 SubstitutionHandler (com.intellij.structuralsearch.impl.matcher.handlers.SubstitutionHandler)8 ArrayBackedNodeIterator (com.intellij.dupLocator.iterators.ArrayBackedNodeIterator)3 TopLevelMatchingHandler (com.intellij.structuralsearch.impl.matcher.handlers.TopLevelMatchingHandler)3 NodeIterator (com.intellij.dupLocator.iterators.NodeIterator)2 PsiElement (com.intellij.psi.PsiElement)2 LanguageFileType (com.intellij.openapi.fileTypes.LanguageFileType)1 LexicalNodesFilter (com.intellij.structuralsearch.impl.matcher.filters.LexicalNodesFilter)1 DelegatingHandler (com.intellij.structuralsearch.impl.matcher.handlers.DelegatingHandler)1 MatchPredicate (com.intellij.structuralsearch.impl.matcher.handlers.MatchPredicate)1 SimpleHandler (com.intellij.structuralsearch.impl.matcher.handlers.SimpleHandler)1 HierarchyNodeIterator (com.intellij.structuralsearch.impl.matcher.iterators.HierarchyNodeIterator)1 SsrFilteringNodeIterator (com.intellij.structuralsearch.impl.matcher.iterators.SsrFilteringNodeIterator)1 CollectingMatchResultSink (com.intellij.structuralsearch.plugin.util.CollectingMatchResultSink)1 NotNull (org.jetbrains.annotations.NotNull)1