Search in sources :

Example 26 with ConstructorCallExpression

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

the class ClosureWriter method createClosureClass.

protected ClassNode createClosureClass(ClosureExpression expression, int mods) {
    ClassNode classNode = controller.getClassNode();
    ClassNode outerClass = controller.getOutermostClass();
    MethodNode methodNode = controller.getMethodNode();
    String name = classNode.getName() + "$" + // add a more informative name
    controller.getContext().getNextClosureInnerName(outerClass, classNode, methodNode);
    boolean staticMethodOrInStaticClass = controller.isStaticMethod() || classNode.isStaticClass();
    Parameter[] parameters = expression.getParameters();
    if (parameters == null) {
        parameters = Parameter.EMPTY_ARRAY;
    } else if (parameters.length == 0) {
        // let's create a default 'it' parameter
        Parameter it = new Parameter(ClassHelper.OBJECT_TYPE, "it", ConstantExpression.NULL);
        parameters = new Parameter[] { it };
        Variable ref = expression.getVariableScope().getDeclaredVariable("it");
        if (ref != null)
            it.setClosureSharedVariable(ref.isClosureSharedVariable());
    }
    Parameter[] localVariableParams = getClosureSharedVariables(expression);
    removeInitialValues(localVariableParams);
    InnerClassNode answer = new InnerClassNode(classNode, name, mods, ClassHelper.CLOSURE_TYPE.getPlainNodeReference());
    answer.setEnclosingMethod(controller.getMethodNode());
    answer.setSynthetic(true);
    answer.setUsingGenerics(outerClass.isUsingGenerics());
    answer.setSourcePosition(expression);
    if (staticMethodOrInStaticClass) {
        answer.setStaticClass(true);
    }
    if (controller.isInScriptBody()) {
        answer.setScriptBody(true);
    }
    MethodNode method = answer.addMethod("doCall", ACC_PUBLIC, ClassHelper.OBJECT_TYPE, parameters, ClassNode.EMPTY_ARRAY, expression.getCode());
    method.setSourcePosition(expression);
    VariableScope varScope = expression.getVariableScope();
    if (varScope == null) {
        throw new RuntimeException("Must have a VariableScope by now! for expression: " + expression + " class: " + name);
    } else {
        method.setVariableScope(varScope.copy());
    }
    if (parameters.length > 1 || (parameters.length == 1 && parameters[0].getType() != null && parameters[0].getType() != ClassHelper.OBJECT_TYPE && !ClassHelper.OBJECT_TYPE.equals(parameters[0].getType().getComponentType()))) {
        // let's add a typesafe call method
        MethodNode call = answer.addMethod("call", ACC_PUBLIC, ClassHelper.OBJECT_TYPE, parameters, ClassNode.EMPTY_ARRAY, new ReturnStatement(new MethodCallExpression(VariableExpression.THIS_EXPRESSION, "doCall", new ArgumentListExpression(parameters))));
        call.setSourcePosition(expression);
    }
    // let's make the constructor
    BlockStatement block = new BlockStatement();
    // this block does not get a source position, because we don't
    // want this synthetic constructor to show up in corbertura reports
    VariableExpression outer = new VariableExpression("_outerInstance");
    outer.setSourcePosition(expression);
    block.getVariableScope().putReferencedLocalVariable(outer);
    VariableExpression thisObject = new VariableExpression("_thisObject");
    thisObject.setSourcePosition(expression);
    block.getVariableScope().putReferencedLocalVariable(thisObject);
    TupleExpression conArgs = new TupleExpression(outer, thisObject);
    block.addStatement(new ExpressionStatement(new ConstructorCallExpression(ClassNode.SUPER, conArgs)));
    // let's assign all the parameter fields from the outer context
    for (Parameter param : localVariableParams) {
        String paramName = param.getName();
        ClassNode type = param.getType();
        if (true) {
            VariableExpression initialValue = new VariableExpression(paramName);
            initialValue.setAccessedVariable(param);
            initialValue.setUseReferenceDirectly(true);
            ClassNode realType = type;
            type = ClassHelper.makeReference();
            param.setType(ClassHelper.makeReference());
            FieldNode paramField = answer.addField(paramName, ACC_PRIVATE | ACC_SYNTHETIC, type, initialValue);
            paramField.setOriginType(ClassHelper.getWrapper(param.getOriginType()));
            paramField.setHolder(true);
            String methodName = Verifier.capitalize(paramName);
            // let's add a getter & setter
            Expression fieldExp = new FieldExpression(paramField);
            answer.addMethod("get" + methodName, ACC_PUBLIC, realType.getPlainNodeReference(), Parameter.EMPTY_ARRAY, ClassNode.EMPTY_ARRAY, new ReturnStatement(fieldExp));
        }
    }
    Parameter[] params = new Parameter[2 + localVariableParams.length];
    params[0] = new Parameter(ClassHelper.OBJECT_TYPE, "_outerInstance");
    params[1] = new Parameter(ClassHelper.OBJECT_TYPE, "_thisObject");
    System.arraycopy(localVariableParams, 0, params, 2, localVariableParams.length);
    ASTNode sn = answer.addConstructor(ACC_PUBLIC, params, ClassNode.EMPTY_ARRAY, block);
    sn.setSourcePosition(expression);
    correctAccessedVariable(answer, expression);
    return answer;
}
Also used : ClassNode(org.codehaus.groovy.ast.ClassNode) InnerClassNode(org.codehaus.groovy.ast.InnerClassNode) Variable(org.codehaus.groovy.ast.Variable) FieldNode(org.codehaus.groovy.ast.FieldNode) ConstructorCallExpression(org.codehaus.groovy.ast.expr.ConstructorCallExpression) TupleExpression(org.codehaus.groovy.ast.expr.TupleExpression) ArgumentListExpression(org.codehaus.groovy.ast.expr.ArgumentListExpression) BlockStatement(org.codehaus.groovy.ast.stmt.BlockStatement) VariableExpression(org.codehaus.groovy.ast.expr.VariableExpression) InnerClassNode(org.codehaus.groovy.ast.InnerClassNode) FieldExpression(org.codehaus.groovy.ast.expr.FieldExpression) MethodNode(org.codehaus.groovy.ast.MethodNode) MethodCallExpression(org.codehaus.groovy.ast.expr.MethodCallExpression) ConstantExpression(org.codehaus.groovy.ast.expr.ConstantExpression) MethodCallExpression(org.codehaus.groovy.ast.expr.MethodCallExpression) 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) ClosureExpression(org.codehaus.groovy.ast.expr.ClosureExpression) ClassExpression(org.codehaus.groovy.ast.expr.ClassExpression) TupleExpression(org.codehaus.groovy.ast.expr.TupleExpression) FieldExpression(org.codehaus.groovy.ast.expr.FieldExpression) ExpressionStatement(org.codehaus.groovy.ast.stmt.ExpressionStatement) ReturnStatement(org.codehaus.groovy.ast.stmt.ReturnStatement) ASTNode(org.codehaus.groovy.ast.ASTNode) Parameter(org.codehaus.groovy.ast.Parameter) VariableScope(org.codehaus.groovy.ast.VariableScope)

Example 27 with ConstructorCallExpression

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

the class Verifier method getFirstIfSpecialConstructorCall.

private static ConstructorCallExpression getFirstIfSpecialConstructorCall(Statement code) {
    if (code == null || !(code instanceof ExpressionStatement))
        return null;
    Expression expression = ((ExpressionStatement) code).getExpression();
    if (!(expression instanceof ConstructorCallExpression))
        return null;
    ConstructorCallExpression cce = (ConstructorCallExpression) expression;
    if (cce.isSpecialCall())
        return cce;
    return null;
}
Also used : ConstantExpression(org.codehaus.groovy.ast.expr.ConstantExpression) VariableExpression(org.codehaus.groovy.ast.expr.VariableExpression) ArgumentListExpression(org.codehaus.groovy.ast.expr.ArgumentListExpression) BinaryExpression(org.codehaus.groovy.ast.expr.BinaryExpression) FieldExpression(org.codehaus.groovy.ast.expr.FieldExpression) CastExpression(org.codehaus.groovy.ast.expr.CastExpression) MethodCallExpression(org.codehaus.groovy.ast.expr.MethodCallExpression) Expression(org.codehaus.groovy.ast.expr.Expression) ConstructorCallExpression(org.codehaus.groovy.ast.expr.ConstructorCallExpression) DeclarationExpression(org.codehaus.groovy.ast.expr.DeclarationExpression) ClosureExpression(org.codehaus.groovy.ast.expr.ClosureExpression) ConstructorCallExpression(org.codehaus.groovy.ast.expr.ConstructorCallExpression) ExpressionStatement(org.codehaus.groovy.ast.stmt.ExpressionStatement)

Example 28 with ConstructorCallExpression

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

the class Verifier method addDefaultParameterConstructors.

protected void addDefaultParameterConstructors(final ClassNode node) {
    List methods = new ArrayList(node.getDeclaredConstructors());
    addDefaultParameters(methods, new DefaultArgsAction() {

        public void call(ArgumentListExpression arguments, Parameter[] newParams, MethodNode method) {
            ConstructorNode ctor = (ConstructorNode) method;
            ConstructorCallExpression expression = new ConstructorCallExpression(ClassNode.THIS, arguments);
            Statement code = new ExpressionStatement(expression);
            addConstructor(newParams, ctor, code, node);
        }
    });
}
Also used : ConstructorCallExpression(org.codehaus.groovy.ast.expr.ConstructorCallExpression) BlockStatement(org.codehaus.groovy.ast.stmt.BlockStatement) Statement(org.codehaus.groovy.ast.stmt.Statement) ExpressionStatement(org.codehaus.groovy.ast.stmt.ExpressionStatement) ReturnStatement(org.codehaus.groovy.ast.stmt.ReturnStatement) ExpressionStatement(org.codehaus.groovy.ast.stmt.ExpressionStatement) ArrayList(java.util.ArrayList) ArgumentListExpression(org.codehaus.groovy.ast.expr.ArgumentListExpression) List(java.util.List) ArrayList(java.util.ArrayList)

Example 29 with ConstructorCallExpression

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

the class Verifier method addGroovyObjectInterfaceAndMethods.

protected void addGroovyObjectInterfaceAndMethods(ClassNode node, final String classInternalName) {
    if (!node.isDerivedFromGroovyObject())
        node.addInterface(ClassHelper.make(GroovyObject.class));
    FieldNode metaClassField = getMetaClassField(node);
    if (!node.hasMethod("getMetaClass", Parameter.EMPTY_ARRAY)) {
        metaClassField = setMetaClassFieldIfNotExists(node, metaClassField);
        addMethod(node, !isAbstract(node.getModifiers()), "getMetaClass", ACC_PUBLIC, ClassHelper.METACLASS_TYPE, Parameter.EMPTY_ARRAY, ClassNode.EMPTY_ARRAY, new BytecodeSequence(new BytecodeInstruction() {

            public void visit(MethodVisitor mv) {
                Label nullLabel = new Label();
                /**
                             *  the code is:
                             *  if (this.metaClass==null) {
                             *      this.metaClass = this.$getStaticMetaClass
                             *      return this.metaClass
                             *  } else {
                             *      return this.metaClass
                             *  }
                             *  with the optimization that the result of the
                             *  first this.metaClass is duped on the operand
                             *  stack and reused for the return in the else part
                             */
                mv.visitVarInsn(ALOAD, 0);
                mv.visitFieldInsn(GETFIELD, classInternalName, "metaClass", "Lgroovy/lang/MetaClass;");
                mv.visitInsn(DUP);
                mv.visitJumpInsn(IFNULL, nullLabel);
                mv.visitInsn(ARETURN);
                mv.visitLabel(nullLabel);
                mv.visitInsn(POP);
                mv.visitVarInsn(ALOAD, 0);
                mv.visitInsn(DUP);
                mv.visitMethodInsn(INVOKEVIRTUAL, classInternalName, "$getStaticMetaClass", "()Lgroovy/lang/MetaClass;", false);
                mv.visitFieldInsn(PUTFIELD, classInternalName, "metaClass", "Lgroovy/lang/MetaClass;");
                mv.visitVarInsn(ALOAD, 0);
                mv.visitFieldInsn(GETFIELD, classInternalName, "metaClass", "Lgroovy/lang/MetaClass;");
                mv.visitInsn(ARETURN);
            }
        }));
    }
    Parameter[] parameters = new Parameter[] { new Parameter(ClassHelper.METACLASS_TYPE, "mc") };
    if (!node.hasMethod("setMetaClass", parameters)) {
        metaClassField = setMetaClassFieldIfNotExists(node, metaClassField);
        Statement setMetaClassCode;
        if (isFinal(metaClassField.getModifiers())) {
            ConstantExpression text = new ConstantExpression("cannot set read-only meta class");
            ConstructorCallExpression cce = new ConstructorCallExpression(ClassHelper.make(IllegalArgumentException.class), text);
            setMetaClassCode = new ExpressionStatement(cce);
        } else {
            List list = new ArrayList();
            list.add(new BytecodeInstruction() {

                public void visit(MethodVisitor mv) {
                    /**
                         * the code is (meta class is stored in 1):
                         * this.metaClass = <1>
                         */
                    mv.visitVarInsn(ALOAD, 0);
                    mv.visitVarInsn(ALOAD, 1);
                    mv.visitFieldInsn(PUTFIELD, classInternalName, "metaClass", "Lgroovy/lang/MetaClass;");
                    mv.visitInsn(RETURN);
                }
            });
            setMetaClassCode = new BytecodeSequence(list);
        }
        addMethod(node, !isAbstract(node.getModifiers()), "setMetaClass", ACC_PUBLIC, ClassHelper.VOID_TYPE, SET_METACLASS_PARAMS, ClassNode.EMPTY_ARRAY, setMetaClassCode);
    }
    if (!node.hasMethod("invokeMethod", INVOKE_METHOD_PARAMS)) {
        VariableExpression vMethods = new VariableExpression("method");
        VariableExpression vArguments = new VariableExpression("arguments");
        VariableScope blockScope = new VariableScope();
        blockScope.putReferencedLocalVariable(vMethods);
        blockScope.putReferencedLocalVariable(vArguments);
        addMethod(node, !isAbstract(node.getModifiers()), "invokeMethod", ACC_PUBLIC, ClassHelper.OBJECT_TYPE, INVOKE_METHOD_PARAMS, ClassNode.EMPTY_ARRAY, new BytecodeSequence(new BytecodeInstruction() {

            public void visit(MethodVisitor mv) {
                mv.visitVarInsn(ALOAD, 0);
                mv.visitMethodInsn(INVOKEVIRTUAL, classInternalName, "getMetaClass", "()Lgroovy/lang/MetaClass;", false);
                mv.visitVarInsn(ALOAD, 0);
                mv.visitVarInsn(ALOAD, 1);
                mv.visitVarInsn(ALOAD, 2);
                mv.visitMethodInsn(INVOKEINTERFACE, "groovy/lang/MetaClass", "invokeMethod", "(Ljava/lang/Object;Ljava/lang/String;Ljava/lang/Object;)Ljava/lang/Object;", true);
                mv.visitInsn(ARETURN);
            }
        }));
    }
    if (!node.hasMethod("getProperty", GET_PROPERTY_PARAMS)) {
        addMethod(node, !isAbstract(node.getModifiers()), "getProperty", ACC_PUBLIC, ClassHelper.OBJECT_TYPE, GET_PROPERTY_PARAMS, ClassNode.EMPTY_ARRAY, new BytecodeSequence(new BytecodeInstruction() {

            public void visit(MethodVisitor mv) {
                mv.visitVarInsn(ALOAD, 0);
                mv.visitMethodInsn(INVOKEVIRTUAL, classInternalName, "getMetaClass", "()Lgroovy/lang/MetaClass;", false);
                mv.visitVarInsn(ALOAD, 0);
                mv.visitVarInsn(ALOAD, 1);
                mv.visitMethodInsn(INVOKEINTERFACE, "groovy/lang/MetaClass", "getProperty", "(Ljava/lang/Object;Ljava/lang/String;)Ljava/lang/Object;", true);
                mv.visitInsn(ARETURN);
            }
        }));
    }
    if (!node.hasMethod("setProperty", SET_PROPERTY_PARAMS)) {
        addMethod(node, !isAbstract(node.getModifiers()), "setProperty", ACC_PUBLIC, ClassHelper.VOID_TYPE, SET_PROPERTY_PARAMS, ClassNode.EMPTY_ARRAY, new BytecodeSequence(new BytecodeInstruction() {

            public void visit(MethodVisitor mv) {
                mv.visitVarInsn(ALOAD, 0);
                mv.visitMethodInsn(INVOKEVIRTUAL, classInternalName, "getMetaClass", "()Lgroovy/lang/MetaClass;", false);
                mv.visitVarInsn(ALOAD, 0);
                mv.visitVarInsn(ALOAD, 1);
                mv.visitVarInsn(ALOAD, 2);
                mv.visitMethodInsn(INVOKEINTERFACE, "groovy/lang/MetaClass", "setProperty", "(Ljava/lang/Object;Ljava/lang/String;Ljava/lang/Object;)V", true);
                mv.visitInsn(RETURN);
            }
        }));
    }
}
Also used : BlockStatement(org.codehaus.groovy.ast.stmt.BlockStatement) Statement(org.codehaus.groovy.ast.stmt.Statement) ExpressionStatement(org.codehaus.groovy.ast.stmt.ExpressionStatement) ReturnStatement(org.codehaus.groovy.ast.stmt.ReturnStatement) ConstructorCallExpression(org.codehaus.groovy.ast.expr.ConstructorCallExpression) ConstantExpression(org.codehaus.groovy.ast.expr.ConstantExpression) Label(org.objectweb.asm.Label) ArrayList(java.util.ArrayList) VariableExpression(org.codehaus.groovy.ast.expr.VariableExpression) MethodVisitor(org.objectweb.asm.MethodVisitor) ExpressionStatement(org.codehaus.groovy.ast.stmt.ExpressionStatement) List(java.util.List) ArrayList(java.util.ArrayList)

Example 30 with ConstructorCallExpression

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

the class JavaAwareResolveVisitor method getConstructorCall.

private static Expression getConstructorCall(Statement code) {
    if (code == null)
        return null;
    if (code instanceof BlockStatement) {
        BlockStatement bs = (BlockStatement) code;
        if (bs.isEmpty())
            return null;
        return getConstructorCall(bs.getStatements().get(0));
    }
    if (!(code instanceof ExpressionStatement))
        return null;
    ExpressionStatement es = (ExpressionStatement) code;
    Expression exp = es.getExpression();
    if (!(exp instanceof ConstructorCallExpression))
        return null;
    ConstructorCallExpression cce = (ConstructorCallExpression) exp;
    if (!cce.isSpecialCall())
        return null;
    return cce;
}
Also used : ConstructorCallExpression(org.codehaus.groovy.ast.expr.ConstructorCallExpression) Expression(org.codehaus.groovy.ast.expr.Expression) ConstructorCallExpression(org.codehaus.groovy.ast.expr.ConstructorCallExpression) ExpressionStatement(org.codehaus.groovy.ast.stmt.ExpressionStatement) BlockStatement(org.codehaus.groovy.ast.stmt.BlockStatement)

Aggregations

ConstructorCallExpression (org.codehaus.groovy.ast.expr.ConstructorCallExpression)68 Expression (org.codehaus.groovy.ast.expr.Expression)45 VariableExpression (org.codehaus.groovy.ast.expr.VariableExpression)44 ExpressionStatement (org.codehaus.groovy.ast.stmt.ExpressionStatement)37 ArgumentListExpression (org.codehaus.groovy.ast.expr.ArgumentListExpression)35 BlockStatement (org.codehaus.groovy.ast.stmt.BlockStatement)32 ConstantExpression (org.codehaus.groovy.ast.expr.ConstantExpression)30 ClassExpression (org.codehaus.groovy.ast.expr.ClassExpression)28 ClosureExpression (org.codehaus.groovy.ast.expr.ClosureExpression)25 MethodCallExpression (org.codehaus.groovy.ast.expr.MethodCallExpression)25 ClassNode (org.codehaus.groovy.ast.ClassNode)24 Statement (org.codehaus.groovy.ast.stmt.Statement)24 TupleExpression (org.codehaus.groovy.ast.expr.TupleExpression)21 PropertyExpression (org.codehaus.groovy.ast.expr.PropertyExpression)18 ReturnStatement (org.codehaus.groovy.ast.stmt.ReturnStatement)16 ArrayList (java.util.ArrayList)15 BinaryExpression (org.codehaus.groovy.ast.expr.BinaryExpression)15 ListExpression (org.codehaus.groovy.ast.expr.ListExpression)15 InnerClassNode (org.codehaus.groovy.ast.InnerClassNode)13 DeclarationExpression (org.codehaus.groovy.ast.expr.DeclarationExpression)10