Search in sources :

Example 6 with ClassExpression

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

the class StaticImportVisitor method transformMethodCallExpression.

protected Expression transformMethodCallExpression(MethodCallExpression mce) {
    Expression args = transform(mce.getArguments());
    Expression method = transform(mce.getMethod());
    Expression object = transform(mce.getObjectExpression());
    boolean isExplicitThisOrSuper = false;
    boolean isExplicitSuper = false;
    if (object instanceof VariableExpression) {
        VariableExpression ve = (VariableExpression) object;
        isExplicitThisOrSuper = !mce.isImplicitThis() && (ve.isThisExpression() || ve.isSuperExpression());
        isExplicitSuper = ve.isSuperExpression();
    }
    if (mce.isImplicitThis() || isExplicitThisOrSuper) {
        if (mce.isImplicitThis()) {
            Expression ret = findStaticMethodImportFromModule(method, args);
            if (ret != null) {
                setSourcePosition(ret, mce);
                return ret;
            }
            if (method instanceof ConstantExpression && !inLeftExpression) {
                // could be a closure field
                String methodName = (String) ((ConstantExpression) method).getValue();
                ret = findStaticFieldOrPropAccessorImportFromModule(methodName);
                if (ret != null) {
                    ret = new MethodCallExpression(ret, "call", args);
                    setSourcePosition(ret, mce);
                    return ret;
                }
            }
        } else if (currentMethod != null && currentMethod.isStatic() && isExplicitSuper) {
            MethodCallExpression ret = new MethodCallExpression(new ClassExpression(currentClass.getSuperClass()), method, args);
            setSourcePosition(ret, mce);
            return ret;
        }
        if (method instanceof ConstantExpression) {
            ConstantExpression ce = (ConstantExpression) method;
            Object value = ce.getValue();
            if (value instanceof String) {
                boolean foundInstanceMethod = false;
                String methodName = (String) value;
                boolean inInnerClass = isInnerClass(currentClass);
                if (currentMethod != null && !currentMethod.isStatic()) {
                    if (currentClass.hasPossibleMethod(methodName, args)) {
                        foundInstanceMethod = true;
                    }
                }
                boolean lookForPossibleStaticMethod = !methodName.equals("call");
                lookForPossibleStaticMethod &= !foundInstanceMethod;
                lookForPossibleStaticMethod |= inSpecialConstructorCall;
                lookForPossibleStaticMethod &= !inInnerClass;
                if (!inClosure && lookForPossibleStaticMethod && (hasPossibleStaticMethod(currentClass, methodName, args, true)) || hasPossibleStaticProperty(currentClass, methodName)) {
                    StaticMethodCallExpression smce = new StaticMethodCallExpression(currentClass, methodName, args);
                    setSourcePosition(smce, mce);
                    return smce;
                }
                if (!inClosure && inInnerClass && inSpecialConstructorCall && mce.isImplicitThis() && !foundInstanceMethod) {
                    if (currentClass.getOuterClass().hasPossibleMethod(methodName, args)) {
                        object = new PropertyExpression(new ClassExpression(currentClass.getOuterClass()), new ConstantExpression("this"));
                    } else if (hasPossibleStaticMethod(currentClass.getOuterClass(), methodName, args, true) || hasPossibleStaticProperty(currentClass.getOuterClass(), methodName)) {
                        StaticMethodCallExpression smce = new StaticMethodCallExpression(currentClass.getOuterClass(), methodName, args);
                        setSourcePosition(smce, mce);
                        return smce;
                    }
                }
            }
        }
    }
    MethodCallExpression result = new MethodCallExpression(object, method, args);
    result.setSafe(mce.isSafe());
    result.setImplicitThis(mce.isImplicitThis());
    result.setSpreadSafe(mce.isSpreadSafe());
    result.setMethodTarget(mce.getMethodTarget());
    // GROOVY-6757
    result.setGenericsTypes(mce.getGenericsTypes());
    setSourcePosition(result, mce);
    return result;
}
Also used : StaticMethodCallExpression(org.codehaus.groovy.ast.expr.StaticMethodCallExpression) MethodCallExpression(org.codehaus.groovy.ast.expr.MethodCallExpression) ListExpression(org.codehaus.groovy.ast.expr.ListExpression) PropertyExpression(org.codehaus.groovy.ast.expr.PropertyExpression) StaticMethodCallExpression(org.codehaus.groovy.ast.expr.StaticMethodCallExpression) ConstantExpression(org.codehaus.groovy.ast.expr.ConstantExpression) NamedArgumentListExpression(org.codehaus.groovy.ast.expr.NamedArgumentListExpression) MethodCallExpression(org.codehaus.groovy.ast.expr.MethodCallExpression) EmptyExpression(org.codehaus.groovy.ast.expr.EmptyExpression) Expression(org.codehaus.groovy.ast.expr.Expression) ConstructorCallExpression(org.codehaus.groovy.ast.expr.ConstructorCallExpression) VariableExpression(org.codehaus.groovy.ast.expr.VariableExpression) ArgumentListExpression(org.codehaus.groovy.ast.expr.ArgumentListExpression) AnnotationConstantExpression(org.codehaus.groovy.ast.expr.AnnotationConstantExpression) ClosureExpression(org.codehaus.groovy.ast.expr.ClosureExpression) ClassExpression(org.codehaus.groovy.ast.expr.ClassExpression) TupleExpression(org.codehaus.groovy.ast.expr.TupleExpression) BinaryExpression(org.codehaus.groovy.ast.expr.BinaryExpression) MapEntryExpression(org.codehaus.groovy.ast.expr.MapEntryExpression) ConstantExpression(org.codehaus.groovy.ast.expr.ConstantExpression) AnnotationConstantExpression(org.codehaus.groovy.ast.expr.AnnotationConstantExpression) StaticMethodCallExpression(org.codehaus.groovy.ast.expr.StaticMethodCallExpression) VariableExpression(org.codehaus.groovy.ast.expr.VariableExpression) ClassExpression(org.codehaus.groovy.ast.expr.ClassExpression) PropertyExpression(org.codehaus.groovy.ast.expr.PropertyExpression)

Example 7 with ClassExpression

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

the class InnerClassCompletionVisitor method addDefaultMethods.

private void addDefaultMethods(InnerClassNode node) {
    final boolean isStatic = isStatic(node);
    ClassNode outerClass = node.getOuterClass();
    final String classInternalName = org.codehaus.groovy.classgen.asm.BytecodeHelper.getClassInternalName(node);
    final String outerClassInternalName = getInternalName(outerClass, isStatic);
    final String outerClassDescriptor = getTypeDescriptor(outerClass, isStatic);
    final int objectDistance = getObjectDistance(outerClass);
    // add missing method dispatcher
    Parameter[] parameters = new Parameter[] { new Parameter(ClassHelper.STRING_TYPE, "name"), new Parameter(ClassHelper.OBJECT_TYPE, "args") };
    String methodName = "methodMissing";
    if (isStatic)
        addCompilationErrorOnCustomMethodNode(node, methodName, parameters);
    MethodNode method = node.addSyntheticMethod(methodName, Opcodes.ACC_PUBLIC, ClassHelper.OBJECT_TYPE, parameters, ClassNode.EMPTY_ARRAY, null);
    BlockStatement block = new BlockStatement();
    if (isStatic) {
        setMethodDispatcherCode(block, new ClassExpression(outerClass), parameters);
    } else {
        block.addStatement(new BytecodeSequence(new BytecodeInstruction() {

            public void visit(MethodVisitor mv) {
                getThis(mv, classInternalName, outerClassDescriptor, outerClassInternalName);
                mv.visitVarInsn(ALOAD, 1);
                mv.visitVarInsn(ALOAD, 2);
                mv.visitMethodInsn(INVOKEVIRTUAL, outerClassInternalName, "this$dist$invoke$" + objectDistance, "(Ljava/lang/String;Ljava/lang/Object;)Ljava/lang/Object;", false);
                mv.visitInsn(ARETURN);
            }
        }));
    }
    method.setCode(block);
    // add static missing method dispatcher
    methodName = "$static_methodMissing";
    if (isStatic)
        addCompilationErrorOnCustomMethodNode(node, methodName, parameters);
    method = node.addSyntheticMethod(methodName, Opcodes.ACC_PUBLIC | Opcodes.ACC_STATIC, ClassHelper.OBJECT_TYPE, parameters, ClassNode.EMPTY_ARRAY, null);
    block = new BlockStatement();
    setMethodDispatcherCode(block, new ClassExpression(outerClass), parameters);
    method.setCode(block);
    // add property setter dispatcher
    parameters = new Parameter[] { new Parameter(ClassHelper.STRING_TYPE, "name"), new Parameter(ClassHelper.OBJECT_TYPE, "val") };
    methodName = "propertyMissing";
    if (isStatic)
        addCompilationErrorOnCustomMethodNode(node, methodName, parameters);
    method = node.addSyntheticMethod(methodName, Opcodes.ACC_PUBLIC, ClassHelper.VOID_TYPE, parameters, ClassNode.EMPTY_ARRAY, null);
    block = new BlockStatement();
    if (isStatic) {
        setPropertySetterDispatcher(block, new ClassExpression(outerClass), parameters);
    } else {
        block.addStatement(new BytecodeSequence(new BytecodeInstruction() {

            public void visit(MethodVisitor mv) {
                getThis(mv, classInternalName, outerClassDescriptor, outerClassInternalName);
                mv.visitVarInsn(ALOAD, 1);
                mv.visitVarInsn(ALOAD, 2);
                mv.visitMethodInsn(INVOKEVIRTUAL, outerClassInternalName, "this$dist$set$" + objectDistance, "(Ljava/lang/String;Ljava/lang/Object;)V", false);
                mv.visitInsn(RETURN);
            }
        }));
    }
    method.setCode(block);
    // add static property missing setter dispatcher
    methodName = "$static_propertyMissing";
    if (isStatic)
        addCompilationErrorOnCustomMethodNode(node, methodName, parameters);
    method = node.addSyntheticMethod(methodName, Opcodes.ACC_PUBLIC | Opcodes.ACC_STATIC, ClassHelper.VOID_TYPE, parameters, ClassNode.EMPTY_ARRAY, null);
    block = new BlockStatement();
    setPropertySetterDispatcher(block, new ClassExpression(outerClass), parameters);
    method.setCode(block);
    // add property getter dispatcher
    parameters = new Parameter[] { new Parameter(ClassHelper.STRING_TYPE, "name") };
    methodName = "propertyMissing";
    if (isStatic)
        addCompilationErrorOnCustomMethodNode(node, methodName, parameters);
    method = node.addSyntheticMethod(methodName, Opcodes.ACC_PUBLIC, ClassHelper.OBJECT_TYPE, parameters, ClassNode.EMPTY_ARRAY, null);
    block = new BlockStatement();
    if (isStatic) {
        setPropertyGetterDispatcher(block, new ClassExpression(outerClass), parameters);
    } else {
        block.addStatement(new BytecodeSequence(new BytecodeInstruction() {

            public void visit(MethodVisitor mv) {
                getThis(mv, classInternalName, outerClassDescriptor, outerClassInternalName);
                mv.visitVarInsn(ALOAD, 1);
                mv.visitMethodInsn(INVOKEVIRTUAL, outerClassInternalName, "this$dist$get$" + objectDistance, "(Ljava/lang/String;)Ljava/lang/Object;", false);
                mv.visitInsn(ARETURN);
            }
        }));
    }
    method.setCode(block);
    // add static property missing getter dispatcher
    methodName = "$static_propertyMissing";
    if (isStatic)
        addCompilationErrorOnCustomMethodNode(node, methodName, parameters);
    method = node.addSyntheticMethod(methodName, Opcodes.ACC_PUBLIC | Opcodes.ACC_STATIC, ClassHelper.OBJECT_TYPE, parameters, ClassNode.EMPTY_ARRAY, null);
    block = new BlockStatement();
    setPropertyGetterDispatcher(block, new ClassExpression(outerClass), parameters);
    method.setCode(block);
}
Also used : ClassNode(org.codehaus.groovy.ast.ClassNode) InnerClassNode(org.codehaus.groovy.ast.InnerClassNode) MethodNode(org.codehaus.groovy.ast.MethodNode) Parameter(org.codehaus.groovy.ast.Parameter) BlockStatement(org.codehaus.groovy.ast.stmt.BlockStatement) ClassExpression(org.codehaus.groovy.ast.expr.ClassExpression) MethodVisitor(org.objectweb.asm.MethodVisitor)

Example 8 with ClassExpression

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

the class ClosureWriter method writeClosure.

public void writeClosure(ClosureExpression expression) {
    CompileStack compileStack = controller.getCompileStack();
    MethodVisitor mv = controller.getMethodVisitor();
    ClassNode classNode = controller.getClassNode();
    AsmClassGenerator acg = controller.getAcg();
    // generate closure as public class to make sure it can be properly invoked by classes of the
    // Groovy runtime without circumventing JVM access checks (see CachedMethod for example).
    int mods = ACC_PUBLIC;
    if (classNode.isInterface()) {
        mods |= ACC_STATIC;
    }
    ClassNode closureClass = getOrAddClosureClass(expression, mods);
    String closureClassinternalName = BytecodeHelper.getClassInternalName(closureClass);
    List constructors = closureClass.getDeclaredConstructors();
    ConstructorNode node = (ConstructorNode) constructors.get(0);
    Parameter[] localVariableParams = node.getParameters();
    mv.visitTypeInsn(NEW, closureClassinternalName);
    mv.visitInsn(DUP);
    if (controller.isStaticMethod() || compileStack.isInSpecialConstructorCall()) {
        (new ClassExpression(classNode)).visit(acg);
        (new ClassExpression(controller.getOutermostClass())).visit(acg);
    } else {
        mv.visitVarInsn(ALOAD, 0);
        controller.getOperandStack().push(ClassHelper.OBJECT_TYPE);
        loadThis();
    }
    // on the stack
    for (int i = 2; i < localVariableParams.length; i++) {
        Parameter param = localVariableParams[i];
        String name = param.getName();
        loadReference(name, controller);
        if (param.getNodeMetaData(ClosureWriter.UseExistingReference.class) == null) {
            param.setNodeMetaData(ClosureWriter.UseExistingReference.class, Boolean.TRUE);
        }
    }
    // we may need to pass in some other constructors
    //cv.visitMethodInsn(INVOKESPECIAL, innerClassinternalName, "<init>", prototype + ")V");
    mv.visitMethodInsn(INVOKESPECIAL, closureClassinternalName, "<init>", BytecodeHelper.getMethodDescriptor(ClassHelper.VOID_TYPE, localVariableParams), false);
    controller.getOperandStack().replace(ClassHelper.CLOSURE_TYPE, localVariableParams.length);
}
Also used : ClassNode(org.codehaus.groovy.ast.ClassNode) InnerClassNode(org.codehaus.groovy.ast.InnerClassNode) ClassExpression(org.codehaus.groovy.ast.expr.ClassExpression) AsmClassGenerator(org.codehaus.groovy.classgen.AsmClassGenerator) MethodVisitor(org.objectweb.asm.MethodVisitor) ConstructorNode(org.codehaus.groovy.ast.ConstructorNode) Parameter(org.codehaus.groovy.ast.Parameter) List(java.util.List)

Example 9 with ClassExpression

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

the class StaticImportVisitor method findStaticPropertyAccessor.

private Expression findStaticPropertyAccessor(ClassNode staticImportType, String propName) {
    String accessorName = getAccessorName(propName);
    Expression accessor = findStaticPropertyAccessorByFullName(staticImportType, accessorName);
    if (accessor == null && accessorName.startsWith("get")) {
        accessor = findStaticPropertyAccessorByFullName(staticImportType, "is" + accessorName.substring(3));
    }
    if (accessor == null && hasStaticProperty(staticImportType, propName)) {
        // args will be replaced
        if (inLeftExpression)
            accessor = new StaticMethodCallExpression(staticImportType, accessorName, ArgumentListExpression.EMPTY_ARGUMENTS);
        else
            accessor = new PropertyExpression(new ClassExpression(staticImportType), propName);
    }
    return accessor;
}
Also used : ListExpression(org.codehaus.groovy.ast.expr.ListExpression) PropertyExpression(org.codehaus.groovy.ast.expr.PropertyExpression) StaticMethodCallExpression(org.codehaus.groovy.ast.expr.StaticMethodCallExpression) ConstantExpression(org.codehaus.groovy.ast.expr.ConstantExpression) NamedArgumentListExpression(org.codehaus.groovy.ast.expr.NamedArgumentListExpression) MethodCallExpression(org.codehaus.groovy.ast.expr.MethodCallExpression) EmptyExpression(org.codehaus.groovy.ast.expr.EmptyExpression) Expression(org.codehaus.groovy.ast.expr.Expression) ConstructorCallExpression(org.codehaus.groovy.ast.expr.ConstructorCallExpression) VariableExpression(org.codehaus.groovy.ast.expr.VariableExpression) ArgumentListExpression(org.codehaus.groovy.ast.expr.ArgumentListExpression) AnnotationConstantExpression(org.codehaus.groovy.ast.expr.AnnotationConstantExpression) ClosureExpression(org.codehaus.groovy.ast.expr.ClosureExpression) ClassExpression(org.codehaus.groovy.ast.expr.ClassExpression) TupleExpression(org.codehaus.groovy.ast.expr.TupleExpression) BinaryExpression(org.codehaus.groovy.ast.expr.BinaryExpression) MapEntryExpression(org.codehaus.groovy.ast.expr.MapEntryExpression) StaticMethodCallExpression(org.codehaus.groovy.ast.expr.StaticMethodCallExpression) PropertyExpression(org.codehaus.groovy.ast.expr.PropertyExpression) ClassExpression(org.codehaus.groovy.ast.expr.ClassExpression)

Example 10 with ClassExpression

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

the class StaticImportVisitor method transformPropertyExpression.

protected Expression transformPropertyExpression(PropertyExpression pe) {
    if (currentMethod != null && currentMethod.isStatic() && pe.getObjectExpression() instanceof VariableExpression && ((VariableExpression) pe.getObjectExpression()).isSuperExpression()) {
        PropertyExpression pexp = new PropertyExpression(new ClassExpression(currentClass.getSuperClass()), transform(pe.getProperty()));
        pexp.setSourcePosition(pe);
        return pexp;
    }
    boolean oldInPropertyExpression = inPropertyExpression;
    Expression oldFoundArgs = foundArgs;
    Expression oldFoundConstant = foundConstant;
    inPropertyExpression = true;
    foundArgs = null;
    foundConstant = null;
    Expression objectExpression = transform(pe.getObjectExpression());
    boolean candidate = false;
    if (objectExpression instanceof MethodCallExpression) {
        candidate = ((MethodCallExpression) objectExpression).isImplicitThis();
    }
    if (foundArgs != null && foundConstant != null && candidate) {
        Expression result = findStaticMethodImportFromModule(foundConstant, foundArgs);
        if (result != null) {
            objectExpression = result;
            objectExpression.setSourcePosition(pe);
        }
    }
    inPropertyExpression = oldInPropertyExpression;
    foundArgs = oldFoundArgs;
    foundConstant = oldFoundConstant;
    pe.setObjectExpression(objectExpression);
    return pe;
}
Also used : StaticMethodCallExpression(org.codehaus.groovy.ast.expr.StaticMethodCallExpression) MethodCallExpression(org.codehaus.groovy.ast.expr.MethodCallExpression) ListExpression(org.codehaus.groovy.ast.expr.ListExpression) PropertyExpression(org.codehaus.groovy.ast.expr.PropertyExpression) StaticMethodCallExpression(org.codehaus.groovy.ast.expr.StaticMethodCallExpression) ConstantExpression(org.codehaus.groovy.ast.expr.ConstantExpression) NamedArgumentListExpression(org.codehaus.groovy.ast.expr.NamedArgumentListExpression) MethodCallExpression(org.codehaus.groovy.ast.expr.MethodCallExpression) EmptyExpression(org.codehaus.groovy.ast.expr.EmptyExpression) Expression(org.codehaus.groovy.ast.expr.Expression) ConstructorCallExpression(org.codehaus.groovy.ast.expr.ConstructorCallExpression) VariableExpression(org.codehaus.groovy.ast.expr.VariableExpression) ArgumentListExpression(org.codehaus.groovy.ast.expr.ArgumentListExpression) AnnotationConstantExpression(org.codehaus.groovy.ast.expr.AnnotationConstantExpression) ClosureExpression(org.codehaus.groovy.ast.expr.ClosureExpression) ClassExpression(org.codehaus.groovy.ast.expr.ClassExpression) TupleExpression(org.codehaus.groovy.ast.expr.TupleExpression) BinaryExpression(org.codehaus.groovy.ast.expr.BinaryExpression) MapEntryExpression(org.codehaus.groovy.ast.expr.MapEntryExpression) VariableExpression(org.codehaus.groovy.ast.expr.VariableExpression) PropertyExpression(org.codehaus.groovy.ast.expr.PropertyExpression) ClassExpression(org.codehaus.groovy.ast.expr.ClassExpression)

Aggregations

ClassExpression (org.codehaus.groovy.ast.expr.ClassExpression)89 Expression (org.codehaus.groovy.ast.expr.Expression)54 VariableExpression (org.codehaus.groovy.ast.expr.VariableExpression)52 ConstantExpression (org.codehaus.groovy.ast.expr.ConstantExpression)50 MethodCallExpression (org.codehaus.groovy.ast.expr.MethodCallExpression)47 ClassNode (org.codehaus.groovy.ast.ClassNode)44 ArgumentListExpression (org.codehaus.groovy.ast.expr.ArgumentListExpression)41 ListExpression (org.codehaus.groovy.ast.expr.ListExpression)35 PropertyExpression (org.codehaus.groovy.ast.expr.PropertyExpression)32 BinaryExpression (org.codehaus.groovy.ast.expr.BinaryExpression)28 ConstructorCallExpression (org.codehaus.groovy.ast.expr.ConstructorCallExpression)26 ClosureExpression (org.codehaus.groovy.ast.expr.ClosureExpression)21 MethodNode (org.codehaus.groovy.ast.MethodNode)18 StaticMethodCallExpression (org.codehaus.groovy.ast.expr.StaticMethodCallExpression)17 TupleExpression (org.codehaus.groovy.ast.expr.TupleExpression)17 AnnotationNode (org.codehaus.groovy.ast.AnnotationNode)15 FieldNode (org.codehaus.groovy.ast.FieldNode)14 Parameter (org.codehaus.groovy.ast.Parameter)14 BlockStatement (org.codehaus.groovy.ast.stmt.BlockStatement)14 ExpressionStatement (org.codehaus.groovy.ast.stmt.ExpressionStatement)14