Search in sources :

Example 56 with ClassNode

use of org.codehaus.groovy.ast.ClassNode in project groovy-core by groovy.

the class StaticTypeCheckingVisitor method visitTernaryExpression.

@Override
public void visitTernaryExpression(final TernaryExpression expression) {
    Map<VariableExpression, List<ClassNode>> oldTracker = pushAssignmentTracking();
    // create a new temporary element in the if-then-else type info
    typeCheckingContext.pushTemporaryTypeInfo();
    expression.getBooleanExpression().visit(this);
    Expression trueExpression = expression.getTrueExpression();
    Expression falseExpression = expression.getFalseExpression();
    trueExpression.visit(this);
    // pop if-then-else temporary type info
    typeCheckingContext.popTemporaryTypeInfo();
    falseExpression.visit(this);
    ClassNode resultType;
    if (isNullConstant(trueExpression) || isNullConstant(falseExpression)) {
        BinaryExpression enclosingBinaryExpression = typeCheckingContext.getEnclosingBinaryExpression();
        if (enclosingBinaryExpression != null && enclosingBinaryExpression.getRightExpression() == expression) {
            resultType = getType(enclosingBinaryExpression.getLeftExpression());
        } else if (isNullConstant(trueExpression) && isNullConstant(falseExpression)) {
            resultType = OBJECT_TYPE;
        } else if (isNullConstant(trueExpression)) {
            resultType = wrapTypeIfNecessary(getType(falseExpression));
        } else {
            resultType = wrapTypeIfNecessary(getType(trueExpression));
        }
    } else {
        // store type information
        final ClassNode typeOfTrue = getType(trueExpression);
        final ClassNode typeOfFalse = getType(falseExpression);
        resultType = lowestUpperBound(typeOfTrue, typeOfFalse);
    }
    storeType(expression, resultType);
    popAssignmentTracking(oldTracker);
}
Also used : LowestUpperBoundClassNode(org.codehaus.groovy.ast.tools.WideningCategories.LowestUpperBoundClassNode) ClassNode(org.codehaus.groovy.ast.ClassNode) InnerClassNode(org.codehaus.groovy.ast.InnerClassNode) ArrayList(java.util.ArrayList) List(java.util.List) LinkedList(java.util.LinkedList)

Example 57 with ClassNode

use of org.codehaus.groovy.ast.ClassNode in project groovy-core by groovy.

the class StaticTypeCheckingVisitor method findMethod.

protected List<MethodNode> findMethod(ClassNode receiver, String name, ClassNode... args) {
    if (isPrimitiveType(receiver))
        receiver = getWrapper(receiver);
    List<MethodNode> methods;
    if (!receiver.isInterface() && "<init>".equals(name)) {
        methods = addGeneratedMethods(receiver, new ArrayList<MethodNode>(receiver.getDeclaredConstructors()));
        if (methods.isEmpty()) {
            MethodNode node = new ConstructorNode(Opcodes.ACC_PUBLIC, Parameter.EMPTY_ARRAY, ClassNode.EMPTY_ARRAY, GENERATED_EMPTY_STATEMENT);
            node.setDeclaringClass(receiver);
            return Collections.singletonList(node);
        }
    } else {
        methods = findMethodsWithGenerated(receiver, name);
        if (receiver.isInterface()) {
            collectAllInterfaceMethodsByName(receiver, name, methods);
            methods.addAll(OBJECT_TYPE.getMethods(name));
        }
        if (typeCheckingContext.getEnclosingClosure() == null) {
            // not in a closure
            ClassNode parent = receiver;
            while (parent instanceof InnerClassNode && !parent.isStaticClass()) {
                parent = parent.getOuterClass();
                methods.addAll(findMethodsWithGenerated(parent, name));
            }
        }
        if (methods.isEmpty()) {
            addArrayMethods(methods, receiver, name, args);
        }
        if (methods.isEmpty() && (args == null || args.length == 0)) {
            // check if it's a property
            String pname = extractPropertyNameFromMethodName("get", name);
            if (pname == null) {
                pname = extractPropertyNameFromMethodName("is", name);
            }
            if (pname != null) {
                // we don't use property exists there because findMethod is called on super clases recursively
                PropertyNode property = null;
                ClassNode curNode = receiver;
                while (property == null && curNode != null) {
                    property = curNode.getProperty(pname);
                    ClassNode svCur = curNode;
                    while (property == null && svCur instanceof InnerClassNode && !svCur.isStaticClass()) {
                        svCur = svCur.getOuterClass();
                        property = svCur.getProperty(pname);
                        if (property != null) {
                            receiver = svCur;
                            break;
                        }
                    }
                    curNode = curNode.getSuperClass();
                }
                if (property != null) {
                    MethodNode node = new MethodNode(name, Opcodes.ACC_PUBLIC, property.getType(), Parameter.EMPTY_ARRAY, ClassNode.EMPTY_ARRAY, GENERATED_EMPTY_STATEMENT);
                    if (property.isStatic()) {
                        node.setModifiers(Opcodes.ACC_PUBLIC + Opcodes.ACC_STATIC);
                    }
                    node.setDeclaringClass(receiver);
                    return Collections.singletonList(node);
                }
            }
        } else if (methods.isEmpty() && args != null && args.length == 1) {
            // maybe we are looking for a setter ?
            String pname = extractPropertyNameFromMethodName("set", name);
            if (pname != null) {
                ClassNode curNode = receiver;
                PropertyNode property = null;
                while (property == null && curNode != null) {
                    property = curNode.getProperty(pname);
                    curNode = curNode.getSuperClass();
                }
                if (property != null) {
                    ClassNode type = property.getOriginType();
                    if (implementsInterfaceOrIsSubclassOf(wrapTypeIfNecessary(args[0]), wrapTypeIfNecessary(type))) {
                        MethodNode node = new MethodNode(name, Opcodes.ACC_PUBLIC, VOID_TYPE, new Parameter[] { new Parameter(type, "arg") }, ClassNode.EMPTY_ARRAY, GENERATED_EMPTY_STATEMENT);
                        if (property.isStatic()) {
                            node.setModifiers(Opcodes.ACC_PUBLIC + Opcodes.ACC_STATIC);
                        }
                        node.setDeclaringClass(receiver);
                        return Collections.singletonList(node);
                    }
                }
            }
        }
    }
    if (methods.isEmpty()) {
        // look at the interfaces, there's a chance that a method is not implemented and we should not hide the
        // error from the compiler
        collectAllInterfaceMethodsByName(receiver, name, methods);
    }
    // lookup in DGM methods too
    findDGMMethodsByNameAndArguments(getTransformLoader(), receiver, name, args, methods);
    List<MethodNode> chosen = chooseBestMethod(receiver, methods, args);
    if (!chosen.isEmpty())
        return chosen;
    // GROOVY-5566
    if (receiver instanceof InnerClassNode && ((InnerClassNode) receiver).isAnonymous() && methods.size() == 1 && args != null && "<init>".equals(name)) {
        MethodNode constructor = methods.get(0);
        if (constructor.getParameters().length == args.length) {
            return methods;
        }
    }
    if (receiver.equals(CLASS_Type) && receiver.getGenericsTypes() != null) {
        List<MethodNode> result = findMethod(receiver.getGenericsTypes()[0].getType(), name, args);
        if (!result.isEmpty())
            return result;
    }
    if (ClassHelper.GSTRING_TYPE.equals(receiver))
        return findMethod(ClassHelper.STRING_TYPE, name, args);
    if (isBeingCompiled(receiver)) {
        chosen = findMethod(GROOVY_OBJECT_TYPE, name, args);
        if (!chosen.isEmpty())
            return chosen;
    }
    return EMPTY_METHODNODE_LIST;
}
Also used : LowestUpperBoundClassNode(org.codehaus.groovy.ast.tools.WideningCategories.LowestUpperBoundClassNode) ClassNode(org.codehaus.groovy.ast.ClassNode) InnerClassNode(org.codehaus.groovy.ast.InnerClassNode) MethodNode(org.codehaus.groovy.ast.MethodNode) ConstructorNode(org.codehaus.groovy.ast.ConstructorNode) PropertyNode(org.codehaus.groovy.ast.PropertyNode) ArrayList(java.util.ArrayList) Parameter(org.codehaus.groovy.ast.Parameter) InnerClassNode(org.codehaus.groovy.ast.InnerClassNode)

Example 58 with ClassNode

use of org.codehaus.groovy.ast.ClassNode in project groovy-core by groovy.

the class StaticTypeCheckingVisitor method getDeclaringClass.

private static ClassNode getDeclaringClass(MethodNode method, Expression arguments) {
    ClassNode declaringClass = method.getDeclaringClass();
    // correcting declaring class for extension methods:
    if (arguments instanceof ArgumentListExpression) {
        ArgumentListExpression al = (ArgumentListExpression) arguments;
        List<Expression> list = al.getExpressions();
        if (list.size() == 0)
            return declaringClass;
        Expression exp = list.get(0);
        ClassNode cn = exp.getNodeMetaData(ExtensionMethodDeclaringClass.class);
        if (cn != null)
            return cn;
    }
    return declaringClass;
}
Also used : LowestUpperBoundClassNode(org.codehaus.groovy.ast.tools.WideningCategories.LowestUpperBoundClassNode) ClassNode(org.codehaus.groovy.ast.ClassNode) InnerClassNode(org.codehaus.groovy.ast.InnerClassNode)

Example 59 with ClassNode

use of org.codehaus.groovy.ast.ClassNode in project groovy-core by groovy.

the class StaticTypeCheckingVisitor method storeTypeForThis.

private boolean storeTypeForThis(VariableExpression vexp) {
    if (vexp == VariableExpression.THIS_EXPRESSION)
        return true;
    if (!vexp.isThisExpression())
        return false;
    ClassNode enclosingClassNode = typeCheckingContext.getEnclosingClassNode();
    storeType(vexp, makeType(enclosingClassNode, typeCheckingContext.isInStaticContext));
    return true;
}
Also used : LowestUpperBoundClassNode(org.codehaus.groovy.ast.tools.WideningCategories.LowestUpperBoundClassNode) ClassNode(org.codehaus.groovy.ast.ClassNode) InnerClassNode(org.codehaus.groovy.ast.InnerClassNode)

Example 60 with ClassNode

use of org.codehaus.groovy.ast.ClassNode in project groovy-core by groovy.

the class StaticTypeCheckingVisitor method tryVariableExpressionAsProperty.

private boolean tryVariableExpressionAsProperty(final VariableExpression vexp, final String dynName) {
    VariableExpression implicitThis = new VariableExpression("this");
    PropertyExpression pe = new PropertyExpression(implicitThis, dynName);
    pe.setImplicitThis(true);
    if (visitPropertyExpressionSilent(pe, vexp)) {
        ClassNode previousIt = vexp.getNodeMetaData(StaticTypesMarker.INFERRED_TYPE);
        vexp.copyNodeMetaData(implicitThis);
        vexp.putNodeMetaData(StaticTypesMarker.INFERRED_TYPE, previousIt);
        storeType(vexp, getType(pe));
        Object val = pe.getNodeMetaData(StaticTypesMarker.READONLY_PROPERTY);
        if (val != null)
            vexp.putNodeMetaData(StaticTypesMarker.READONLY_PROPERTY, val);
        val = pe.getNodeMetaData(StaticTypesMarker.IMPLICIT_RECEIVER);
        if (val != null)
            vexp.putNodeMetaData(StaticTypesMarker.IMPLICIT_RECEIVER, val);
        return true;
    }
    return false;
}
Also used : LowestUpperBoundClassNode(org.codehaus.groovy.ast.tools.WideningCategories.LowestUpperBoundClassNode) ClassNode(org.codehaus.groovy.ast.ClassNode) InnerClassNode(org.codehaus.groovy.ast.InnerClassNode)

Aggregations

ClassNode (org.codehaus.groovy.ast.ClassNode)869 InnerClassNode (org.codehaus.groovy.ast.InnerClassNode)348 MethodNode (org.codehaus.groovy.ast.MethodNode)193 GenericsType (org.codehaus.groovy.ast.GenericsType)154 LowestUpperBoundClassNode (org.codehaus.groovy.ast.tools.WideningCategories.LowestUpperBoundClassNode)148 Expression (org.codehaus.groovy.ast.expr.Expression)146 Parameter (org.codehaus.groovy.ast.Parameter)135 FieldNode (org.codehaus.groovy.ast.FieldNode)126 VariableExpression (org.codehaus.groovy.ast.expr.VariableExpression)118 AnnotationNode (org.codehaus.groovy.ast.AnnotationNode)117 ConstantExpression (org.codehaus.groovy.ast.expr.ConstantExpression)113 ClassExpression (org.codehaus.groovy.ast.expr.ClassExpression)103 ArrayList (java.util.ArrayList)95 MethodCallExpression (org.codehaus.groovy.ast.expr.MethodCallExpression)92 PropertyExpression (org.codehaus.groovy.ast.expr.PropertyExpression)75 BlockStatement (org.codehaus.groovy.ast.stmt.BlockStatement)74 LinkedList (java.util.LinkedList)71 ArgumentListExpression (org.codehaus.groovy.ast.expr.ArgumentListExpression)71 BinaryExpression (org.codehaus.groovy.ast.expr.BinaryExpression)62 ListExpression (org.codehaus.groovy.ast.expr.ListExpression)61