Search in sources :

Example 1 with MethodCall

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

the class StaticTypeCheckingVisitor method getType.

protected ClassNode getType(final ASTNode exp) {
    ClassNode cn = exp.getNodeMetaData(INFERRED_TYPE);
    if (cn != null) {
        return cn;
    }
    if (exp instanceof ClassExpression) {
        ClassNode node = CLASS_Type.getPlainNodeReference();
        node.setGenericsTypes(new GenericsType[] { new GenericsType(((ClassExpression) exp).getType()) });
        return node;
    }
    if (exp instanceof VariableExpression) {
        VariableExpression vexp = (VariableExpression) exp;
        ClassNode selfTrait = isTraitSelf(vexp);
        if (selfTrait != null)
            return makeSelf(selfTrait);
        if (vexp.isThisExpression())
            return makeThis();
        if (vexp.isSuperExpression())
            return makeSuper();
        Variable variable = vexp.getAccessedVariable();
        if (variable instanceof FieldNode) {
            FieldNode fieldNode = (FieldNode) variable;
            ClassNode fieldType = fieldNode.getOriginType();
            if (!fieldNode.isStatic() && GenericsUtils.hasUnresolvedGenerics(fieldType)) {
                ClassNode declType = fieldNode.getDeclaringClass(), thisType = typeCheckingContext.getEnclosingClassNode();
                fieldType = resolveGenericsWithContext(extractPlaceHolders(thisType, declType), fieldType);
            }
            return fieldType;
        }
        if (variable != vexp && variable instanceof VariableExpression) {
            return getType((VariableExpression) variable);
        }
        if (variable instanceof Parameter) {
            Parameter parameter = (Parameter) variable;
            ClassNode type = null;
            // check if param part of control structure - but not if inside instanceof
            List<ClassNode> temporaryTypesForExpression = getTemporaryTypesForExpression(vexp);
            if (temporaryTypesForExpression == null || temporaryTypesForExpression.isEmpty()) {
                type = typeCheckingContext.controlStructureVariables.get(parameter);
            }
            // now check for closure override
            TypeCheckingContext.EnclosingClosure enclosingClosure = typeCheckingContext.getEnclosingClosure();
            if (type == null && enclosingClosure != null && temporaryTypesForExpression == null) {
                type = getTypeFromClosureArguments(parameter, enclosingClosure);
            }
            if (type != null) {
                storeType(vexp, type);
                return type;
            }
            return getType((Parameter) variable);
        }
        return vexp.getOriginType();
    }
    if (exp instanceof ListExpression) {
        return inferListExpressionType((ListExpression) exp);
    }
    if (exp instanceof MapExpression) {
        return inferMapExpressionType((MapExpression) exp);
    }
    if (exp instanceof ConstructorCallExpression) {
        return ((ConstructorCallExpression) exp).getType();
    }
    if (exp instanceof MethodNode) {
        if ((exp == GET_DELEGATE || exp == GET_OWNER || exp == GET_THISOBJECT) && typeCheckingContext.getEnclosingClosure() != null) {
            return typeCheckingContext.getEnclosingClassNode();
        }
        ClassNode ret = getInferredReturnType(exp);
        return ret != null ? ret : ((MethodNode) exp).getReturnType();
    }
    if (exp instanceof FieldNode || exp instanceof PropertyNode) {
        return ((Variable) exp).getOriginType();
    }
    if (exp instanceof RangeExpression) {
        ClassNode plain = RANGE_TYPE.getPlainNodeReference();
        RangeExpression re = (RangeExpression) exp;
        ClassNode fromType = getType(re.getFrom());
        ClassNode toType = getType(re.getTo());
        if (fromType.equals(toType)) {
            plain.setGenericsTypes(new GenericsType[] { new GenericsType(wrapTypeIfNecessary(fromType)) });
        } else {
            plain.setGenericsTypes(new GenericsType[] { new GenericsType(wrapTypeIfNecessary(lowestUpperBound(fromType, toType))) });
        }
        return plain;
    }
    if (exp instanceof UnaryPlusExpression) {
        return getType(((UnaryPlusExpression) exp).getExpression());
    }
    if (exp instanceof UnaryMinusExpression) {
        return getType(((UnaryMinusExpression) exp).getExpression());
    }
    if (exp instanceof BitwiseNegationExpression) {
        return getType(((BitwiseNegationExpression) exp).getExpression());
    }
    if (exp instanceof Parameter) {
        return ((Parameter) exp).getOriginType();
    }
    if (exp instanceof ClosureExpression) {
        ClassNode type = CLOSURE_TYPE.getPlainNodeReference();
        ClassNode returnType = getInferredReturnType(exp);
        if (returnType != null) {
            type.setGenericsTypes(new GenericsType[] { new GenericsType(wrapTypeIfNecessary(returnType)) });
        }
        Parameter[] parameters = ((ClosureExpression) exp).getParameters();
        int nParameters = parameters == null ? 0 : parameters.length == 0 ? -1 : parameters.length;
        type.putNodeMetaData(CLOSURE_ARGUMENTS, nParameters);
        return type;
    } else if (exp instanceof MethodCall) {
        MethodNode target = exp.getNodeMetaData(DIRECT_METHOD_CALL_TARGET);
        if (target != null) {
            return getType(target);
        }
    }
    return ((Expression) exp).getType();
}
Also used : MapExpression(org.codehaus.groovy.ast.expr.MapExpression) StaticTypeCheckingSupport.findDGMMethodsForClassNode(org.codehaus.groovy.transform.stc.StaticTypeCheckingSupport.findDGMMethodsForClassNode) ClassNode(org.codehaus.groovy.ast.ClassNode) InnerClassNode(org.codehaus.groovy.ast.InnerClassNode) DynamicVariable(org.codehaus.groovy.ast.DynamicVariable) Variable(org.codehaus.groovy.ast.Variable) StaticTypeCheckingSupport.findTargetVariable(org.codehaus.groovy.transform.stc.StaticTypeCheckingSupport.findTargetVariable) FieldNode(org.codehaus.groovy.ast.FieldNode) ConstructorCallExpression(org.codehaus.groovy.ast.expr.ConstructorCallExpression) ClosureListExpression(org.codehaus.groovy.ast.expr.ClosureListExpression) ArgumentListExpression(org.codehaus.groovy.ast.expr.ArgumentListExpression) ListExpression(org.codehaus.groovy.ast.expr.ListExpression) ClassExpression(org.codehaus.groovy.ast.expr.ClassExpression) VariableExpression(org.codehaus.groovy.ast.expr.VariableExpression) RangeExpression(org.codehaus.groovy.ast.expr.RangeExpression) BitwiseNegationExpression(org.codehaus.groovy.ast.expr.BitwiseNegationExpression) MethodCall(org.codehaus.groovy.ast.expr.MethodCall) ClosureSignatureHint(groovy.transform.stc.ClosureSignatureHint) MethodNode(org.codehaus.groovy.ast.MethodNode) UnaryMinusExpression(org.codehaus.groovy.ast.expr.UnaryMinusExpression) 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) PropertyNode(org.codehaus.groovy.ast.PropertyNode) GenericsType(org.codehaus.groovy.ast.GenericsType) StaticTypeCheckingSupport.getCombinedGenericsType(org.codehaus.groovy.transform.stc.StaticTypeCheckingSupport.getCombinedGenericsType) ClosureUtils.hasImplicitParameter(org.codehaus.groovy.ast.tools.ClosureUtils.hasImplicitParameter) Parameter(org.codehaus.groovy.ast.Parameter) UnaryPlusExpression(org.codehaus.groovy.ast.expr.UnaryPlusExpression) ClosureExpression(org.codehaus.groovy.ast.expr.ClosureExpression)

Example 2 with MethodCall

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

the class StaticTypeCheckingVisitor method disambiguateMethods.

private List<MethodNode> disambiguateMethods(List<MethodNode> methods, final ClassNode receiver, final ClassNode[] argTypes, final Expression call) {
    if (methods.size() > 1 && receiver != null && argTypes != null) {
        List<MethodNode> filteredWithGenerics = new LinkedList<>();
        for (MethodNode methodNode : methods) {
            if (typeCheckMethodsWithGenerics(receiver, argTypes, methodNode)) {
                if ((methodNode.getModifiers() & Opcodes.ACC_BRIDGE) == 0) {
                    filteredWithGenerics.add(methodNode);
                }
            }
        }
        if (filteredWithGenerics.size() == 1) {
            return filteredWithGenerics;
        }
        methods = extension.handleAmbiguousMethods(methods, call);
    }
    if (methods.size() > 1) {
        if (call instanceof MethodCall) {
            List<MethodNode> methodNodeList = new LinkedList<>();
            String methodName = ((MethodCall) call).getMethodAsString();
            for (MethodNode methodNode : methods) {
                if (!methodNode.getName().equals(methodName)) {
                    continue;
                }
                methodNodeList.add(methodNode);
            }
            methods = methodNodeList;
        }
    }
    return methods;
}
Also used : MethodNode(org.codehaus.groovy.ast.MethodNode) 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) MethodCall(org.codehaus.groovy.ast.expr.MethodCall) LinkedList(java.util.LinkedList)

Example 3 with MethodCall

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

the class StaticTypeCheckingVisitor method typeCheckMultipleAssignmentAndContinue.

private boolean typeCheckMultipleAssignmentAndContinue(final Expression leftExpression, Expression rightExpression) {
    if (rightExpression instanceof VariableExpression || rightExpression instanceof PropertyExpression || rightExpression instanceof MethodCall) {
        ClassNode inferredType = Optional.ofNullable(getType(rightExpression)).orElseGet(rightExpression::getType);
        GenericsType[] genericsTypes = inferredType.getGenericsTypes();
        ListExpression listExpression = new ListExpression();
        listExpression.setSourcePosition(rightExpression);
        // convert Tuple[1-16] bearing expressions to mock list for checking
        for (int n = TUPLE_TYPES.indexOf(inferredType), i = 0; i < n; i += 1) {
            ClassNode type = (genericsTypes != null ? genericsTypes[i].getType() : OBJECT_TYPE);
            listExpression.addExpression(varX("v" + (i + 1), type));
        }
        if (!listExpression.getExpressions().isEmpty()) {
            rightExpression = listExpression;
        }
    }
    if (!(rightExpression instanceof ListExpression)) {
        addStaticTypeError("Multiple assignments without list or tuple on the right-hand side are unsupported in static type checking mode", rightExpression);
        return false;
    }
    TupleExpression tuple = (TupleExpression) leftExpression;
    ListExpression values = (ListExpression) rightExpression;
    List<Expression> tupleExpressions = tuple.getExpressions();
    List<Expression> valueExpressions = values.getExpressions();
    if (tupleExpressions.size() > valueExpressions.size()) {
        addStaticTypeError("Incorrect number of values. Expected:" + tupleExpressions.size() + " Was:" + valueExpressions.size(), values);
        return false;
    }
    for (int i = 0, n = tupleExpressions.size(); i < n; i += 1) {
        ClassNode valueType = getType(valueExpressions.get(i));
        ClassNode targetType = getType(tupleExpressions.get(i));
        if (!isAssignableTo(valueType, targetType)) {
            addStaticTypeError("Cannot assign value of type " + prettyPrintType(valueType) + " to variable of type " + prettyPrintType(targetType), rightExpression);
            return false;
        }
        storeType(tupleExpressions.get(i), valueType);
    }
    return true;
}
Also used : StaticTypeCheckingSupport.findDGMMethodsForClassNode(org.codehaus.groovy.transform.stc.StaticTypeCheckingSupport.findDGMMethodsForClassNode) ClassNode(org.codehaus.groovy.ast.ClassNode) InnerClassNode(org.codehaus.groovy.ast.InnerClassNode) 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) ClosureListExpression(org.codehaus.groovy.ast.expr.ClosureListExpression) ArgumentListExpression(org.codehaus.groovy.ast.expr.ArgumentListExpression) ListExpression(org.codehaus.groovy.ast.expr.ListExpression) GenericsType(org.codehaus.groovy.ast.GenericsType) StaticTypeCheckingSupport.getCombinedGenericsType(org.codehaus.groovy.transform.stc.StaticTypeCheckingSupport.getCombinedGenericsType) TupleExpression(org.codehaus.groovy.ast.expr.TupleExpression) VariableExpression(org.codehaus.groovy.ast.expr.VariableExpression) PropertyExpression(org.codehaus.groovy.ast.expr.PropertyExpression) MethodCall(org.codehaus.groovy.ast.expr.MethodCall) ClosureSignatureHint(groovy.transform.stc.ClosureSignatureHint)

Aggregations

MethodCall (org.codehaus.groovy.ast.expr.MethodCall)3 ClosureSignatureHint (groovy.transform.stc.ClosureSignatureHint)2 ClassNode (org.codehaus.groovy.ast.ClassNode)2 GenericsType (org.codehaus.groovy.ast.GenericsType)2 InnerClassNode (org.codehaus.groovy.ast.InnerClassNode)2 MethodNode (org.codehaus.groovy.ast.MethodNode)2 AnnotationConstantExpression (org.codehaus.groovy.ast.expr.AnnotationConstantExpression)2 ArgumentListExpression (org.codehaus.groovy.ast.expr.ArgumentListExpression)2 ArrayExpression (org.codehaus.groovy.ast.expr.ArrayExpression)2 AttributeExpression (org.codehaus.groovy.ast.expr.AttributeExpression)2 BinaryExpression (org.codehaus.groovy.ast.expr.BinaryExpression)2 BitwiseNegationExpression (org.codehaus.groovy.ast.expr.BitwiseNegationExpression)2 CastExpression (org.codehaus.groovy.ast.expr.CastExpression)2 ClassExpression (org.codehaus.groovy.ast.expr.ClassExpression)2 ClosureExpression (org.codehaus.groovy.ast.expr.ClosureExpression)2 ClosureListExpression (org.codehaus.groovy.ast.expr.ClosureListExpression)2 ConstantExpression (org.codehaus.groovy.ast.expr.ConstantExpression)2 ConstructorCallExpression (org.codehaus.groovy.ast.expr.ConstructorCallExpression)2 DeclarationExpression (org.codehaus.groovy.ast.expr.DeclarationExpression)2 ElvisOperatorExpression (org.codehaus.groovy.ast.expr.ElvisOperatorExpression)2