Search in sources :

Example 11 with StaticMethodCallExpression

use of org.codehaus.groovy.ast.expr.StaticMethodCallExpression in project groovy by apache.

the class StaticTypeCheckingVisitor method visitStaticMethodCallExpression.

@Override
public void visitStaticMethodCallExpression(final StaticMethodCallExpression call) {
    String name = call.getMethod();
    if (name == null) {
        addStaticTypeError("cannot resolve dynamic method name at compile time.", call);
        return;
    }
    if (extension.beforeMethodCall(call)) {
        extension.afterMethodCall(call);
        return;
    }
    Expression callArguments = call.getArguments();
    ArgumentListExpression argumentList = InvocationWriter.makeArgumentList(callArguments);
    checkForbiddenSpreadArgument(argumentList);
    ClassNode receiver = call.getOwnerType();
    visitMethodCallArguments(receiver, argumentList, false, null);
    ClassNode[] args = getArgumentTypes(argumentList);
    try {
        // method call receivers are :
        // - possible "with" receivers
        // - the actual receiver as found in the method call expression
        // - any of the potential receivers found in the instanceof temporary table
        // in that order
        List<Receiver<String>> receivers = new LinkedList<>();
        addReceivers(receivers, makeOwnerList(new ClassExpression(receiver)), false);
        List<MethodNode> mn = null;
        Receiver<String> chosenReceiver = null;
        for (Receiver<String> currentReceiver : receivers) {
            mn = findMethod(currentReceiver.getType(), name, args);
            if (!mn.isEmpty()) {
                if (mn.size() == 1) {
                    // GROOVY-8909, GROOVY-8961, GROOVY-9734, GROOVY-9844, GROOVY-9915, et al.
                    resolvePlaceholdersFromImplicitTypeHints(args, argumentList, mn.get(0).getParameters());
                    typeCheckMethodsWithGenericsOrFail(currentReceiver.getType(), args, mn.get(0), call);
                }
                chosenReceiver = currentReceiver;
                break;
            }
        }
        if (mn == null) {
            throw new GroovyBugError("Invalid state finding valid method: receivers should never be empty and findMethod should never return null");
        }
        if (mn.isEmpty()) {
            mn = extension.handleMissingMethod(receiver, name, argumentList, args, call);
        }
        boolean callArgsVisited = false;
        if (mn.isEmpty()) {
            addNoMatchingMethodError(receiver, name, args, call);
        } else {
            mn = disambiguateMethods(mn, receiver, args, call);
            if (mn.size() == 1) {
                MethodNode directMethodCallCandidate = mn.get(0);
                ClassNode returnType = getType(directMethodCallCandidate);
                if (returnType.isUsingGenerics() && !returnType.isEnum()) {
                    visitMethodCallArguments(receiver, argumentList, true, directMethodCallCandidate);
                    ClassNode irtg = inferReturnTypeGenerics(chosenReceiver.getType(), directMethodCallCandidate, callArguments);
                    returnType = irtg != null && implementsInterfaceOrIsSubclassOf(irtg, returnType) ? irtg : returnType;
                    callArgsVisited = true;
                }
                storeType(call, returnType);
                storeTargetMethod(call, directMethodCallCandidate);
            } else {
                addAmbiguousErrorMessage(mn, name, args, call);
            }
            if (!callArgsVisited) {
                visitMethodCallArguments(receiver, argumentList, true, call.getNodeMetaData(DIRECT_METHOD_CALL_TARGET));
            }
        }
    } finally {
        extension.afterMethodCall(call);
    }
}
Also used : StaticTypeCheckingSupport.findDGMMethodsForClassNode(org.codehaus.groovy.transform.stc.StaticTypeCheckingSupport.findDGMMethodsForClassNode) ClassNode(org.codehaus.groovy.ast.ClassNode) InnerClassNode(org.codehaus.groovy.ast.InnerClassNode) GroovyBugError(org.codehaus.groovy.GroovyBugError) ArgumentListExpression(org.codehaus.groovy.ast.expr.ArgumentListExpression) ClassExpression(org.codehaus.groovy.ast.expr.ClassExpression) StaticTypeCheckingSupport.toMethodParametersString(org.codehaus.groovy.transform.stc.StaticTypeCheckingSupport.toMethodParametersString) StaticTypeCheckingSupport.isParameterizedWithString(org.codehaus.groovy.transform.stc.StaticTypeCheckingSupport.isParameterizedWithString) StaticTypeCheckingSupport.isParameterizedWithGStringOrGStringString(org.codehaus.groovy.transform.stc.StaticTypeCheckingSupport.isParameterizedWithGStringOrGStringString) LinkedList(java.util.LinkedList) MethodNode(org.codehaus.groovy.ast.MethodNode) UnaryMinusExpression(org.codehaus.groovy.ast.expr.UnaryMinusExpression) ClosureListExpression(org.codehaus.groovy.ast.expr.ClosureListExpression) ArgumentListExpression(org.codehaus.groovy.ast.expr.ArgumentListExpression) MethodReferenceExpression(org.codehaus.groovy.ast.expr.MethodReferenceExpression) TernaryExpression(org.codehaus.groovy.ast.expr.TernaryExpression) PropertyExpression(org.codehaus.groovy.ast.expr.PropertyExpression) PrefixExpression(org.codehaus.groovy.ast.expr.PrefixExpression) PostfixExpression(org.codehaus.groovy.ast.expr.PostfixExpression) Expression(org.codehaus.groovy.ast.expr.Expression) UnaryPlusExpression(org.codehaus.groovy.ast.expr.UnaryPlusExpression) AnnotationConstantExpression(org.codehaus.groovy.ast.expr.AnnotationConstantExpression) BitwiseNegationExpression(org.codehaus.groovy.ast.expr.BitwiseNegationExpression) MapExpression(org.codehaus.groovy.ast.expr.MapExpression) ConstantExpression(org.codehaus.groovy.ast.expr.ConstantExpression) StaticTypeCheckingSupport.evaluateExpression(org.codehaus.groovy.transform.stc.StaticTypeCheckingSupport.evaluateExpression) NotExpression(org.codehaus.groovy.ast.expr.NotExpression) FieldExpression(org.codehaus.groovy.ast.expr.FieldExpression) EmptyExpression(org.codehaus.groovy.ast.expr.EmptyExpression) ConstructorCallExpression(org.codehaus.groovy.ast.expr.ConstructorCallExpression) ClassExpression(org.codehaus.groovy.ast.expr.ClassExpression) TupleExpression(org.codehaus.groovy.ast.expr.TupleExpression) MethodPointerExpression(org.codehaus.groovy.ast.expr.MethodPointerExpression) MapEntryExpression(org.codehaus.groovy.ast.expr.MapEntryExpression) VariableExpression(org.codehaus.groovy.ast.expr.VariableExpression) CastExpression(org.codehaus.groovy.ast.expr.CastExpression) StaticMethodCallExpression(org.codehaus.groovy.ast.expr.StaticMethodCallExpression) LambdaExpression(org.codehaus.groovy.ast.expr.LambdaExpression) ListExpression(org.codehaus.groovy.ast.expr.ListExpression) RangeExpression(org.codehaus.groovy.ast.expr.RangeExpression) SpreadExpression(org.codehaus.groovy.ast.expr.SpreadExpression) ArrayExpression(org.codehaus.groovy.ast.expr.ArrayExpression) BinaryExpression(org.codehaus.groovy.ast.expr.BinaryExpression) ElvisOperatorExpression(org.codehaus.groovy.ast.expr.ElvisOperatorExpression) MethodCallExpression(org.codehaus.groovy.ast.expr.MethodCallExpression) DeclarationExpression(org.codehaus.groovy.ast.expr.DeclarationExpression) ClosureExpression(org.codehaus.groovy.ast.expr.ClosureExpression) AttributeExpression(org.codehaus.groovy.ast.expr.AttributeExpression)

Example 12 with StaticMethodCallExpression

use of org.codehaus.groovy.ast.expr.StaticMethodCallExpression in project groovy by apache.

the class RecursivenessTester method isRecursive.

public boolean isRecursive(Map<String, ASTNode> params) {
    ASTNode method = params.get("method");
    assert MethodNode.class.equals(method.getClass());
    ASTNode call = params.get("call");
    Class<? extends ASTNode> callClass = call.getClass();
    assert MethodCallExpression.class.equals(callClass) || StaticMethodCallExpression.class.equals(callClass);
    if (callClass == MethodCallExpression.class) {
        return isRecursive((MethodNode) method, (MethodCallExpression) call);
    }
    return isRecursive((MethodNode) method, (StaticMethodCallExpression) call);
}
Also used : StaticMethodCallExpression(org.codehaus.groovy.ast.expr.StaticMethodCallExpression) MethodCallExpression(org.codehaus.groovy.ast.expr.MethodCallExpression) ASTNode(org.codehaus.groovy.ast.ASTNode) StaticMethodCallExpression(org.codehaus.groovy.ast.expr.StaticMethodCallExpression)

Example 13 with StaticMethodCallExpression

use of org.codehaus.groovy.ast.expr.StaticMethodCallExpression in project groovy by apache.

the class TailRecursiveASTTransformation method replaceRecursiveReturnsInsideClosures.

@SuppressWarnings("Instanceof")
private void replaceRecursiveReturnsInsideClosures(final MethodNode method, final Map<Integer, Map<String, Object>> positionMapping) {
    Closure<Boolean> whenRecursiveReturn = new Closure<Boolean>(this, this) {

        public Boolean doCall(Statement statement, boolean inClosure) {
            if (!inClosure)
                return false;
            if (!(statement instanceof ReturnStatement)) {
                return false;
            }
            Expression inner = ((ReturnStatement) statement).getExpression();
            if (!(inner instanceof MethodCallExpression) && !(inner instanceof StaticMethodCallExpression)) {
                return false;
            }
            return isRecursiveIn(inner, method);
        }
    };
    Closure<Statement> replaceWithThrowLoopException = new Closure<Statement>(this, this) {

        public Statement doCall(ReturnStatement statement) {
            return new ReturnStatementToIterationConverter(AstHelper.recurByThrowStatement()).convert(statement, positionMapping);
        }
    };
    StatementReplacer replacer = new StatementReplacer(whenRecursiveReturn, replaceWithThrowLoopException);
    replacer.replaceIn(method.getCode());
}
Also used : Closure(groovy.lang.Closure) StaticMethodCallExpression(org.codehaus.groovy.ast.expr.StaticMethodCallExpression) MethodCallExpression(org.codehaus.groovy.ast.expr.MethodCallExpression) StaticMethodCallExpression(org.codehaus.groovy.ast.expr.StaticMethodCallExpression) MethodCallExpression(org.codehaus.groovy.ast.expr.MethodCallExpression) Expression(org.codehaus.groovy.ast.expr.Expression) VariableExpression(org.codehaus.groovy.ast.expr.VariableExpression) TernaryExpression(org.codehaus.groovy.ast.expr.TernaryExpression) Statement(org.codehaus.groovy.ast.stmt.Statement) ReturnStatement(org.codehaus.groovy.ast.stmt.ReturnStatement) BlockStatement(org.codehaus.groovy.ast.stmt.BlockStatement) ReturnStatement(org.codehaus.groovy.ast.stmt.ReturnStatement) StaticMethodCallExpression(org.codehaus.groovy.ast.expr.StaticMethodCallExpression)

Example 14 with StaticMethodCallExpression

use of org.codehaus.groovy.ast.expr.StaticMethodCallExpression in project groovy by apache.

the class TailRecursiveASTTransformation method replaceRecursiveReturnsOutsideClosures.

@SuppressWarnings("Instanceof")
private void replaceRecursiveReturnsOutsideClosures(final MethodNode method, final Map<Integer, Map<String, Object>> positionMapping) {
    Closure<Boolean> whenRecursiveReturn = new Closure<Boolean>(this, this) {

        public Boolean doCall(Statement statement, boolean inClosure) {
            if (inClosure)
                return false;
            if (!(statement instanceof ReturnStatement)) {
                return false;
            }
            Expression inner = ((ReturnStatement) statement).getExpression();
            if (!(inner instanceof MethodCallExpression) && !(inner instanceof StaticMethodCallExpression)) {
                return false;
            }
            return isRecursiveIn(inner, method);
        }
    };
    Closure<Statement> replaceWithContinueBlock = new Closure<Statement>(this, this) {

        public Statement doCall(ReturnStatement statement) {
            return new ReturnStatementToIterationConverter().convert(statement, positionMapping);
        }
    };
    StatementReplacer replacer = new StatementReplacer(whenRecursiveReturn, replaceWithContinueBlock);
    replacer.replaceIn(method.getCode());
}
Also used : Closure(groovy.lang.Closure) StaticMethodCallExpression(org.codehaus.groovy.ast.expr.StaticMethodCallExpression) MethodCallExpression(org.codehaus.groovy.ast.expr.MethodCallExpression) StaticMethodCallExpression(org.codehaus.groovy.ast.expr.StaticMethodCallExpression) MethodCallExpression(org.codehaus.groovy.ast.expr.MethodCallExpression) Expression(org.codehaus.groovy.ast.expr.Expression) VariableExpression(org.codehaus.groovy.ast.expr.VariableExpression) TernaryExpression(org.codehaus.groovy.ast.expr.TernaryExpression) Statement(org.codehaus.groovy.ast.stmt.Statement) ReturnStatement(org.codehaus.groovy.ast.stmt.ReturnStatement) BlockStatement(org.codehaus.groovy.ast.stmt.BlockStatement) ReturnStatement(org.codehaus.groovy.ast.stmt.ReturnStatement) StaticMethodCallExpression(org.codehaus.groovy.ast.expr.StaticMethodCallExpression)

Example 15 with StaticMethodCallExpression

use of org.codehaus.groovy.ast.expr.StaticMethodCallExpression in project groovy by apache.

the class GrabAnnotationTransformation method callGrabAsStaticInitIfNeeded.

private void callGrabAsStaticInitIfNeeded(ClassNode classNode, ClassNode grapeClassNode, Collection<Map<String, Object>> grabMapsInit, Collection<Map<String, Object>> grabExcludeMaps) {
    List<Statement> grabInitializers = new ArrayList<Statement>();
    MapExpression basicArgs = new MapExpression();
    if (autoDownload != null) {
        basicArgs.addMapEntryExpression(constX(AUTO_DOWNLOAD_SETTING), constX(autoDownload));
    }
    if (disableChecksums != null) {
        basicArgs.addMapEntryExpression(constX(DISABLE_CHECKSUMS_SETTING), constX(disableChecksums));
    }
    if (systemProperties != null && !systemProperties.isEmpty()) {
        BlockStatement block = new BlockStatement();
        for (Map.Entry<String, String> e : systemProperties.entrySet()) {
            block.addStatement(stmt(callX(SYSTEM_CLASSNODE, "setProperty", args(constX(e.getKey()), constX(e.getValue())))));
        }
        StaticMethodCallExpression enabled = callX(SYSTEM_CLASSNODE, "getProperty", args(constX("groovy.grape.enable"), constX("true")));
        grabInitializers.add(ifS(eqX(enabled, constX("true")), block));
    }
    if (!grabExcludeMaps.isEmpty()) {
        ListExpression list = new ListExpression();
        for (Map<String, Object> map : grabExcludeMaps) {
            Set<Map.Entry<String, Object>> entries = map.entrySet();
            MapExpression inner = new MapExpression();
            for (Map.Entry<String, Object> entry : entries) {
                inner.addMapEntryExpression(constX(entry.getKey()), constX(entry.getValue()));
            }
            list.addExpression(inner);
        }
        basicArgs.addMapEntryExpression(constX("excludes"), list);
    }
    List<Expression> argList = new ArrayList<Expression>();
    argList.add(basicArgs);
    if (grabMapsInit.isEmpty())
        return;
    for (Map<String, Object> grabMap : grabMapsInit) {
        // add Grape.grab(excludeArgs, [group:group, module:module, version:version, classifier:classifier])
        // or Grape.grab([group:group, module:module, version:version, classifier:classifier])
        MapExpression dependencyArg = new MapExpression();
        for (String s : GRAB_REQUIRED) {
            dependencyArg.addMapEntryExpression(constX(s), constX(grabMap.get(s)));
        }
        for (String s : GRAB_OPTIONAL) {
            if (grabMap.containsKey(s))
                dependencyArg.addMapEntryExpression(constX(s), constX(grabMap.get(s)));
        }
        argList.add(dependencyArg);
    }
    grabInitializers.add(stmt(callX(grapeClassNode, "grab", args(argList))));
    // insert at beginning so we have the classloader set up before the class is called
    classNode.addStaticInitializerStatements(grabInitializers, true);
}
Also used : MapExpression(org.codehaus.groovy.ast.expr.MapExpression) BlockStatement(org.codehaus.groovy.ast.stmt.BlockStatement) Statement(org.codehaus.groovy.ast.stmt.Statement) ListExpression(org.codehaus.groovy.ast.expr.ListExpression) ArrayList(java.util.ArrayList) StaticMethodCallExpression(org.codehaus.groovy.ast.expr.StaticMethodCallExpression) BlockStatement(org.codehaus.groovy.ast.stmt.BlockStatement) ListExpression(org.codehaus.groovy.ast.expr.ListExpression) MapExpression(org.codehaus.groovy.ast.expr.MapExpression) ConstantExpression(org.codehaus.groovy.ast.expr.ConstantExpression) StaticMethodCallExpression(org.codehaus.groovy.ast.expr.StaticMethodCallExpression) Expression(org.codehaus.groovy.ast.expr.Expression) Map(java.util.Map) HashMap(java.util.HashMap)

Aggregations

StaticMethodCallExpression (org.codehaus.groovy.ast.expr.StaticMethodCallExpression)30 MethodCallExpression (org.codehaus.groovy.ast.expr.MethodCallExpression)20 VariableExpression (org.codehaus.groovy.ast.expr.VariableExpression)20 ConstantExpression (org.codehaus.groovy.ast.expr.ConstantExpression)19 ArgumentListExpression (org.codehaus.groovy.ast.expr.ArgumentListExpression)18 ClassExpression (org.codehaus.groovy.ast.expr.ClassExpression)15 Expression (org.codehaus.groovy.ast.expr.Expression)15 BlockStatement (org.codehaus.groovy.ast.stmt.BlockStatement)13 Statement (org.codehaus.groovy.ast.stmt.Statement)13 MethodNode (org.codehaus.groovy.ast.MethodNode)12 ExpressionStatement (org.codehaus.groovy.ast.stmt.ExpressionStatement)12 BinaryExpression (org.codehaus.groovy.ast.expr.BinaryExpression)11 ConstructorCallExpression (org.codehaus.groovy.ast.expr.ConstructorCallExpression)11 ClassNode (org.codehaus.groovy.ast.ClassNode)10 Parameter (org.codehaus.groovy.ast.Parameter)10 ReturnStatement (org.codehaus.groovy.ast.stmt.ReturnStatement)10 CastExpression (org.codehaus.groovy.ast.expr.CastExpression)7 MapExpression (org.codehaus.groovy.ast.expr.MapExpression)7 PropertyExpression (org.codehaus.groovy.ast.expr.PropertyExpression)7 FieldNode (org.codehaus.groovy.ast.FieldNode)6