Search in sources :

Example 1 with MatchPredicate

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

the class PatternCompiler method addScriptConstraint.

private static void addScriptConstraint(Project project, String name, MatchVariableConstraint constraint, SubstitutionHandler handler) {
    if (constraint.getScriptCodeConstraint() != null && constraint.getScriptCodeConstraint().length() > 2) {
        final String script = StringUtil.stripQuotesAroundValue(constraint.getScriptCodeConstraint());
        final String s = ScriptSupport.checkValidScript(script);
        if (s != null)
            throw new MalformedPatternException("Script constraint for " + constraint.getName() + " has problem " + s);
        MatchPredicate predicate = new ScriptPredicate(project, name, script);
        addPredicate(handler, predicate);
    }
}
Also used : MatchPredicate(com.intellij.structuralsearch.impl.matcher.handlers.MatchPredicate)

Example 2 with MatchPredicate

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

the class PatternCompiler method doCompile.

private static List<PsiElement> doCompile(Project project, MatchOptions options, CompiledPattern result, PrefixProvider prefixProvider, CompileContext context) {
    result.clearHandlers();
    context.init(result, options, project, options.getScope() instanceof GlobalSearchScope);
    final StringBuilder buf = new StringBuilder();
    Template template = TemplateManager.getInstance(project).createTemplate("", "", options.getSearchPattern());
    int segmentsCount = template.getSegmentsCount();
    String text = template.getTemplateText();
    buf.setLength(0);
    int prevOffset = 0;
    for (int i = 0; i < segmentsCount; ++i) {
        final int offset = template.getSegmentOffset(i);
        final String name = template.getSegmentName(i);
        final String prefix = prefixProvider.getPrefix(i);
        if (prefix == null) {
            throw new MalformedPatternException();
        }
        buf.append(text.substring(prevOffset, offset));
        buf.append(prefix);
        buf.append(name);
        MatchVariableConstraint constraint = options.getVariableConstraint(name);
        if (constraint == null) {
            // we do not edited the constraints
            constraint = new MatchVariableConstraint();
            constraint.setName(name);
            options.addVariableConstraint(constraint);
        }
        SubstitutionHandler handler = result.createSubstitutionHandler(name, prefix + name, constraint.isPartOfSearchResults(), constraint.getMinCount(), constraint.getMaxCount(), constraint.isGreedy());
        if (constraint.isWithinHierarchy()) {
            handler.setSubtype(true);
        }
        if (constraint.isStrictlyWithinHierarchy()) {
            handler.setStrictSubtype(true);
        }
        MatchPredicate predicate;
        if (!StringUtil.isEmptyOrSpaces(constraint.getRegExp())) {
            predicate = new RegExpPredicate(constraint.getRegExp(), options.isCaseSensitiveMatch(), name, constraint.isWholeWordsOnly(), constraint.isPartOfSearchResults());
            if (constraint.isInvertRegExp()) {
                predicate = new NotPredicate(predicate);
            }
            addPredicate(handler, predicate);
        }
        if (constraint.isReference()) {
            predicate = new ReferencePredicate(constraint.getNameOfReferenceVar());
            if (constraint.isInvertReference()) {
                predicate = new NotPredicate(predicate);
            }
            addPredicate(handler, predicate);
        }
        addExtensionPredicates(options, constraint, handler);
        addScriptConstraint(project, name, constraint, handler);
        if (!StringUtil.isEmptyOrSpaces(constraint.getContainsConstraint())) {
            predicate = new ContainsPredicate(name, constraint.getContainsConstraint());
            if (constraint.isInvertContainsConstraint()) {
                predicate = new NotPredicate(predicate);
            }
            addPredicate(handler, predicate);
        }
        if (!StringUtil.isEmptyOrSpaces(constraint.getWithinConstraint())) {
            assert false;
        }
        prevOffset = offset;
    }
    MatchVariableConstraint constraint = options.getVariableConstraint(Configuration.CONTEXT_VAR_NAME);
    if (constraint != null) {
        SubstitutionHandler handler = result.createSubstitutionHandler(Configuration.CONTEXT_VAR_NAME, Configuration.CONTEXT_VAR_NAME, constraint.isPartOfSearchResults(), constraint.getMinCount(), constraint.getMaxCount(), constraint.isGreedy());
        if (!StringUtil.isEmptyOrSpaces(constraint.getWithinConstraint())) {
            MatchPredicate predicate = new WithinPredicate(Configuration.CONTEXT_VAR_NAME, constraint.getWithinConstraint(), options.getFileType(), project);
            if (constraint.isInvertWithinConstraint()) {
                predicate = new NotPredicate(predicate);
            }
            addPredicate(handler, predicate);
        }
        addExtensionPredicates(options, constraint, handler);
        addScriptConstraint(project, Configuration.CONTEXT_VAR_NAME, constraint, handler);
    }
    buf.append(text.substring(prevOffset, text.length()));
    PsiElement[] matchStatements;
    try {
        matchStatements = MatcherImplUtil.createTreeFromText(buf.toString(), PatternTreeContext.Block, options.getFileType(), options.getDialect(), options.getPatternContext(), project, false);
        if (matchStatements.length == 0)
            throw new MalformedPatternException();
    } catch (IncorrectOperationException e) {
        throw new MalformedPatternException(e.getMessage());
    }
    NodeFilter filter = LexicalNodesFilter.getInstance();
    GlobalCompilingVisitor compilingVisitor = new GlobalCompilingVisitor();
    compilingVisitor.compile(matchStatements, context);
    ArrayList<PsiElement> elements = new ArrayList<>();
    for (PsiElement matchStatement : matchStatements) {
        if (!filter.accepts(matchStatement)) {
            elements.add(matchStatement);
        }
    }
    new DeleteNodesAction(compilingVisitor.getLexicalNodes()).run();
    return elements;
}
Also used : TIntArrayList(gnu.trove.TIntArrayList) MatchPredicate(com.intellij.structuralsearch.impl.matcher.handlers.MatchPredicate) Template(com.intellij.codeInsight.template.Template) SubstitutionHandler(com.intellij.structuralsearch.impl.matcher.handlers.SubstitutionHandler) GlobalSearchScope(com.intellij.psi.search.GlobalSearchScope) IncorrectOperationException(com.intellij.util.IncorrectOperationException) NodeFilter(com.intellij.dupLocator.util.NodeFilter)

Example 3 with MatchPredicate

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

the class JavaMatchPredicateProvider method collectPredicates.

@Override
public void collectPredicates(MatchVariableConstraint constraint, String name, MatchOptions options, Set<MatchPredicate> predicates) {
    if (constraint.isReadAccess()) {
        MatchPredicate predicate = new ReadPredicate();
        if (constraint.isInvertReadAccess()) {
            predicate = new NotPredicate(predicate);
        }
        predicates.add(predicate);
    }
    if (constraint.isWriteAccess()) {
        MatchPredicate predicate = new WritePredicate();
        if (constraint.isInvertWriteAccess()) {
            predicate = new NotPredicate(predicate);
        }
        predicates.add(predicate);
    }
    if (!StringUtil.isEmptyOrSpaces(constraint.getNameOfExprType())) {
        MatchPredicate predicate = new ExprTypePredicate(constraint.getNameOfExprType(), name, constraint.isExprTypeWithinHierarchy(), options.isCaseSensitiveMatch(), constraint.isPartOfSearchResults());
        if (constraint.isInvertExprType()) {
            predicate = new NotPredicate(predicate);
        }
        predicates.add(predicate);
    }
    if (!StringUtil.isEmptyOrSpaces(constraint.getNameOfFormalArgType())) {
        MatchPredicate predicate = new FormalArgTypePredicate(constraint.getNameOfFormalArgType(), name, constraint.isFormalArgTypeWithinHierarchy(), options.isCaseSensitiveMatch(), constraint.isPartOfSearchResults());
        if (constraint.isInvertFormalType()) {
            predicate = new NotPredicate(predicate);
        }
        predicates.add(predicate);
    }
}
Also used : MatchPredicate(com.intellij.structuralsearch.impl.matcher.handlers.MatchPredicate)

Example 4 with MatchPredicate

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

the class JavaMatchingVisitor method matchImplicitQualifier.

private void matchImplicitQualifier(MatchingHandler matchingHandler, PsiElement target, MatchContext context) {
    if (!(matchingHandler instanceof SubstitutionHandler)) {
        myMatchingVisitor.setResult(false);
        return;
    }
    final SubstitutionHandler substitutionHandler = (SubstitutionHandler) matchingHandler;
    final MatchPredicate predicate = substitutionHandler.getPredicate();
    if (substitutionHandler.getMinOccurs() != 0) {
        myMatchingVisitor.setResult(false);
        return;
    }
    if (predicate == null) {
        myMatchingVisitor.setResult(true);
        return;
    }
    if (target == null) {
        myMatchingVisitor.setResult(false);
        return;
    }
    if (target instanceof PsiModifierListOwner && ((PsiModifierListOwner) target).hasModifierProperty(PsiModifier.STATIC)) {
        myMatchingVisitor.setResult(predicate.match(null, PsiTreeUtil.getParentOfType(target, PsiClass.class), context));
    } else {
        final PsiElementFactory factory = JavaPsiFacade.getElementFactory(target.getProject());
        final PsiExpression implicitReference = factory.createExpressionFromText("this", target);
        myMatchingVisitor.setResult(predicate.match(null, implicitReference, context));
    }
}
Also used : SubstitutionHandler(com.intellij.structuralsearch.impl.matcher.handlers.SubstitutionHandler) MatchPredicate(com.intellij.structuralsearch.impl.matcher.handlers.MatchPredicate)

Example 5 with MatchPredicate

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

the class JavaMatchingVisitor method visitNewExpression.

@Override
public void visitNewExpression(final PsiNewExpression new1) {
    final PsiElement other = myMatchingVisitor.getElement();
    final PsiJavaCodeReferenceElement classReference = new1.getClassReference();
    if (other instanceof PsiArrayInitializerExpression && other.getParent() instanceof PsiVariable && new1.getArrayDimensions().length == 0 && new1.getArrayInitializer() != null) {
        final MatchContext matchContext = myMatchingVisitor.getMatchContext();
        final MatchingHandler handler = matchContext.getPattern().getHandler(classReference);
        final boolean looseMatching = myMatchingVisitor.getMatchContext().getOptions().isLooseMatching();
        if ((handler instanceof SubstitutionHandler && ((SubstitutionHandler) handler).getMinOccurs() != 0) || !looseMatching) {
            myMatchingVisitor.setResult(false);
            return;
        }
        final PsiType otherType = ((PsiArrayInitializerExpression) other).getType();
        if (handler instanceof SubstitutionHandler && otherType != null) {
            final PsiElementFactory factory = JavaPsiFacade.getElementFactory(other.getProject());
            final PsiTypeElement otherTypeElement = factory.createTypeElement(otherType.getDeepComponentType());
            final SubstitutionHandler substitutionHandler = (SubstitutionHandler) handler;
            final MatchPredicate predicate = substitutionHandler.getPredicate();
            myMatchingVisitor.setResult(predicate == null || predicate.match(null, otherTypeElement, matchContext));
        } else {
            final PsiType type = new1.getType();
            myMatchingVisitor.setResult(type != null && type.equals(otherType));
        }
        if (myMatchingVisitor.getResult()) {
            myMatchingVisitor.matchSons(new1.getArrayInitializer(), other);
        }
        return;
    }
    if (!(other instanceof PsiNewExpression)) {
        myMatchingVisitor.setResult(false);
        return;
    }
    final PsiNewExpression new2 = (PsiNewExpression) other;
    if (classReference != null) {
        if (new2.getClassReference() != null) {
            myMatchingVisitor.setResult(myMatchingVisitor.match(classReference, new2.getClassReference()) && myMatchingVisitor.matchSons(new1.getArrayInitializer(), new2.getArrayInitializer()));
            if (myMatchingVisitor.getResult()) {
                // matching dims
                matchArrayDims(new1, new2);
            }
            return;
        } else {
            // match array of primitive by new 'T();
            final PsiKeyword newKeyword = PsiTreeUtil.getChildOfType(new2, PsiKeyword.class);
            final PsiElement element = PsiTreeUtil.getNextSiblingOfType(newKeyword, PsiWhiteSpace.class);
            if (element != null && element.getNextSibling() instanceof PsiKeyword) {
                ((LexicalNodesFilter) LexicalNodesFilter.getInstance()).setCareKeyWords(true);
                myMatchingVisitor.setResult(myMatchingVisitor.match(classReference, element.getNextSibling()) && myMatchingVisitor.matchSons(new1.getArrayInitializer(), new2.getArrayInitializer()));
                ((LexicalNodesFilter) LexicalNodesFilter.getInstance()).setCareKeyWords(false);
                if (myMatchingVisitor.getResult()) {
                    // matching dims
                    matchArrayDims(new1, new2);
                }
                return;
            }
        }
    }
    if (classReference == new2.getClassReference()) {
        // probably anonymous class or array of primitive type
        ((LexicalNodesFilter) LexicalNodesFilter.getInstance()).setCareKeyWords(true);
        myMatchingVisitor.setResult(myMatchingVisitor.matchSons(new1, new2));
        ((LexicalNodesFilter) LexicalNodesFilter.getInstance()).setCareKeyWords(false);
    } else if (new1.getAnonymousClass() == null && classReference != null && new2.getAnonymousClass() != null) {
        // allow matching anonymous class without pattern
        myMatchingVisitor.setResult(myMatchingVisitor.match(classReference, new2.getAnonymousClass().getBaseClassReference()) && myMatchingVisitor.matchSons(new1.getArgumentList(), new2.getArgumentList()));
    } else {
        myMatchingVisitor.setResult(false);
    }
}
Also used : LexicalNodesFilter(com.intellij.structuralsearch.impl.matcher.filters.LexicalNodesFilter) MatchingHandler(com.intellij.structuralsearch.impl.matcher.handlers.MatchingHandler) MatchPredicate(com.intellij.structuralsearch.impl.matcher.handlers.MatchPredicate) SubstitutionHandler(com.intellij.structuralsearch.impl.matcher.handlers.SubstitutionHandler)

Aggregations

MatchPredicate (com.intellij.structuralsearch.impl.matcher.handlers.MatchPredicate)5 SubstitutionHandler (com.intellij.structuralsearch.impl.matcher.handlers.SubstitutionHandler)3 Template (com.intellij.codeInsight.template.Template)1 NodeFilter (com.intellij.dupLocator.util.NodeFilter)1 GlobalSearchScope (com.intellij.psi.search.GlobalSearchScope)1 LexicalNodesFilter (com.intellij.structuralsearch.impl.matcher.filters.LexicalNodesFilter)1 MatchingHandler (com.intellij.structuralsearch.impl.matcher.handlers.MatchingHandler)1 IncorrectOperationException (com.intellij.util.IncorrectOperationException)1 TIntArrayList (gnu.trove.TIntArrayList)1