Search in sources :

Example 51 with Statement

use of org.codehaus.groovy.ast.stmt.Statement in project groovy by apache.

the class Verifier method visitMethod.

public void visitMethod(MethodNode node) {
    //GROOVY-3712 - if it's an MOP method, it's an error as they aren't supposed to exist before ACG is invoked
    if (MopWriter.isMopMethod(node.getName())) {
        throw new RuntimeParserException("Found unexpected MOP methods in the class node for " + classNode.getName() + "(" + node.getName() + ")", classNode);
    }
    this.methodNode = node;
    adjustTypesIfStaticMainMethod(node);
    addReturnIfNeeded(node);
    Statement statement;
    statement = node.getCode();
    if (statement != null)
        statement.visit(new VerifierCodeVisitor(this));
}
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) RuntimeParserException(org.codehaus.groovy.syntax.RuntimeParserException)

Example 52 with Statement

use of org.codehaus.groovy.ast.stmt.Statement 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 53 with Statement

use of org.codehaus.groovy.ast.stmt.Statement 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 54 with Statement

use of org.codehaus.groovy.ast.stmt.Statement in project groovy by apache.

the class AsmClassGenerator method visitConstructorOrMethod.

protected void visitConstructorOrMethod(MethodNode node, boolean isConstructor) {
    controller.resetLineNumber();
    Parameter[] parameters = node.getParameters();
    String methodType = BytecodeHelper.getMethodDescriptor(node.getReturnType(), parameters);
    String signature = BytecodeHelper.getGenericsMethodSignature(node);
    int modifiers = node.getModifiers();
    if (isVargs(node.getParameters()))
        modifiers |= Opcodes.ACC_VARARGS;
    MethodVisitor mv = cv.visitMethod(modifiers, node.getName(), methodType, signature, buildExceptions(node.getExceptions()));
    controller.setMethodVisitor(mv);
    visitAnnotations(node, mv);
    for (int i = 0; i < parameters.length; i++) {
        visitParameterAnnotations(parameters[i], i, mv);
    }
    // Add parameter names to the MethodVisitor (jdk8+ only)
    if (getCompileUnit().getConfig().getParameters()) {
        for (int i = 0; i < parameters.length; i++) {
            // TODO handle ACC_SYNTHETIC for enum method parameters?
            mv.visitParameter(parameters[i].getName(), 0);
        }
    }
    if (controller.getClassNode().isAnnotationDefinition() && !node.isStaticConstructor()) {
        visitAnnotationDefault(node, mv);
    } else if (!node.isAbstract()) {
        Statement code = node.getCode();
        mv.visitCode();
        // fast path for getter/setters etc.
        if (code instanceof BytecodeSequence && ((BytecodeSequence) code).getInstructions().size() == 1 && ((BytecodeSequence) code).getInstructions().get(0) instanceof BytecodeInstruction) {
            ((BytecodeInstruction) ((BytecodeSequence) code).getInstructions().get(0)).visit(mv);
        } else {
            visitStdMethod(node, isConstructor, parameters, code);
        }
        //mv.visitInsn(NOP);
        try {
            mv.visitMaxs(0, 0);
        } catch (Exception e) {
            throw new GroovyRuntimeException("ASM reporting processing error for " + controller.getClassNode() + "#" + node.getName() + " with signature " + node.getTypeDescriptor() + " in " + sourceFile + ":" + node.getLineNumber(), e);
        }
    }
    mv.visitEnd();
}
Also used : CaseStatement(org.codehaus.groovy.ast.stmt.CaseStatement) ForStatement(org.codehaus.groovy.ast.stmt.ForStatement) CatchStatement(org.codehaus.groovy.ast.stmt.CatchStatement) IfStatement(org.codehaus.groovy.ast.stmt.IfStatement) AssertStatement(org.codehaus.groovy.ast.stmt.AssertStatement) BlockStatement(org.codehaus.groovy.ast.stmt.BlockStatement) Statement(org.codehaus.groovy.ast.stmt.Statement) WhileStatement(org.codehaus.groovy.ast.stmt.WhileStatement) ExpressionStatement(org.codehaus.groovy.ast.stmt.ExpressionStatement) ThrowStatement(org.codehaus.groovy.ast.stmt.ThrowStatement) DoWhileStatement(org.codehaus.groovy.ast.stmt.DoWhileStatement) ContinueStatement(org.codehaus.groovy.ast.stmt.ContinueStatement) BreakStatement(org.codehaus.groovy.ast.stmt.BreakStatement) ReturnStatement(org.codehaus.groovy.ast.stmt.ReturnStatement) SynchronizedStatement(org.codehaus.groovy.ast.stmt.SynchronizedStatement) SwitchStatement(org.codehaus.groovy.ast.stmt.SwitchStatement) TryCatchStatement(org.codehaus.groovy.ast.stmt.TryCatchStatement) GroovyRuntimeException(groovy.lang.GroovyRuntimeException) Parameter(org.codehaus.groovy.ast.Parameter) GroovyRuntimeException(groovy.lang.GroovyRuntimeException) RuntimeParserException(org.codehaus.groovy.syntax.RuntimeParserException) MethodVisitor(org.objectweb.asm.MethodVisitor)

Example 55 with Statement

use of org.codehaus.groovy.ast.stmt.Statement in project groovy by apache.

the class AsmClassGenerator method visitClosureListExpression.

public void visitClosureListExpression(ClosureListExpression expression) {
    MethodVisitor mv = controller.getMethodVisitor();
    controller.getCompileStack().pushVariableScope(expression.getVariableScope());
    List<Expression> expressions = expression.getExpressions();
    final int size = expressions.size();
    // init declarations
    LinkedList<DeclarationExpression> declarations = new LinkedList<DeclarationExpression>();
    for (int i = 0; i < size; i++) {
        Expression expr = expressions.get(i);
        if (expr instanceof DeclarationExpression) {
            declarations.add((DeclarationExpression) expr);
            DeclarationExpression de = (DeclarationExpression) expr;
            BinaryExpression be = new BinaryExpression(de.getLeftExpression(), de.getOperation(), de.getRightExpression());
            expressions.set(i, be);
            de.setRightExpression(ConstantExpression.NULL);
            visitDeclarationExpression(de);
        }
    }
    LinkedList instructions = new LinkedList();
    BytecodeSequence seq = new BytecodeSequence(instructions);
    BlockStatement bs = new BlockStatement();
    bs.addStatement(seq);
    Parameter closureIndex = new Parameter(ClassHelper.int_TYPE, "__closureIndex");
    ClosureExpression ce = new ClosureExpression(new Parameter[] { closureIndex }, bs);
    ce.setVariableScope(expression.getVariableScope());
    // to keep stack height put a null on stack
    instructions.add(ConstantExpression.NULL);
    // init table
    final Label dflt = new Label();
    final Label tableEnd = new Label();
    final Label[] labels = new Label[size];
    instructions.add(new BytecodeInstruction() {

        public void visit(MethodVisitor mv) {
            mv.visitVarInsn(ILOAD, 1);
            mv.visitTableSwitchInsn(0, size - 1, dflt, labels);
        }
    });
    // visit cases
    for (int i = 0; i < size; i++) {
        final Label label = new Label();
        Object expr = expressions.get(i);
        final boolean isStatement = expr instanceof Statement;
        labels[i] = label;
        instructions.add(new BytecodeInstruction() {

            public void visit(MethodVisitor mv) {
                mv.visitLabel(label);
                // so expressions need to pop the alibi null
                if (!isStatement)
                    mv.visitInsn(POP);
            }
        });
        instructions.add(expr);
        instructions.add(new BytecodeInstruction() {

            public void visit(MethodVisitor mv) {
                mv.visitJumpInsn(GOTO, tableEnd);
            }
        });
    }
    // default case
    {
        instructions.add(new BytecodeInstruction() {

            public void visit(MethodVisitor mv) {
                mv.visitLabel(dflt);
            }
        });
        ConstantExpression text = new ConstantExpression("invalid index for closure");
        ConstructorCallExpression cce = new ConstructorCallExpression(ClassHelper.make(IllegalArgumentException.class), text);
        ThrowStatement ts = new ThrowStatement(cce);
        instructions.add(ts);
    }
    // return
    instructions.add(new BytecodeInstruction() {

        public void visit(MethodVisitor mv) {
            mv.visitLabel(tableEnd);
            mv.visitInsn(ARETURN);
        }
    });
    // load main Closure
    visitClosureExpression(ce);
    // we need later an array to store the curried
    // closures, so we create it here and ave it
    // in a temporary variable
    BytecodeHelper.pushConstant(mv, size);
    mv.visitTypeInsn(ANEWARRAY, "java/lang/Object");
    int listArrayVar = controller.getCompileStack().defineTemporaryVariable("_listOfClosures", true);
    // add curried versions
    for (int i = 0; i < size; i++) {
        // stack: closure
        // we need to create a curried closure version
        // so we store the type on stack
        mv.visitTypeInsn(NEW, "org/codehaus/groovy/runtime/CurriedClosure");
        // stack: closure, type
        // for a constructor call we need the type two times
        // and the closure after them
        mv.visitInsn(DUP2);
        mv.visitInsn(SWAP);
        // stack: closure,type,type,closure
        // so we can create the curried closure
        mv.visitInsn(ICONST_1);
        mv.visitTypeInsn(ANEWARRAY, "java/lang/Object");
        mv.visitInsn(DUP);
        mv.visitInsn(ICONST_0);
        mv.visitLdcInsn(i);
        mv.visitMethodInsn(INVOKESTATIC, "java/lang/Integer", "valueOf", "(I)Ljava/lang/Integer;", false);
        mv.visitInsn(AASTORE);
        mv.visitMethodInsn(INVOKESPECIAL, "org/codehaus/groovy/runtime/CurriedClosure", "<init>", "(Lgroovy/lang/Closure;[Ljava/lang/Object;)V", false);
        // stack: closure,curriedClosure
        // we need to save the result
        mv.visitVarInsn(ALOAD, listArrayVar);
        mv.visitInsn(SWAP);
        BytecodeHelper.pushConstant(mv, i);
        mv.visitInsn(SWAP);
        mv.visitInsn(AASTORE);
    // stack: closure
    }
    // we don't need the closure any longer, so remove it
    mv.visitInsn(POP);
    // we load the array and create a list from it
    mv.visitVarInsn(ALOAD, listArrayVar);
    createListMethod.call(mv);
    // remove the temporary variable to keep the
    // stack clean
    controller.getCompileStack().removeVar(listArrayVar);
    controller.getOperandStack().pop();
}
Also used : CaseStatement(org.codehaus.groovy.ast.stmt.CaseStatement) ForStatement(org.codehaus.groovy.ast.stmt.ForStatement) CatchStatement(org.codehaus.groovy.ast.stmt.CatchStatement) IfStatement(org.codehaus.groovy.ast.stmt.IfStatement) AssertStatement(org.codehaus.groovy.ast.stmt.AssertStatement) BlockStatement(org.codehaus.groovy.ast.stmt.BlockStatement) Statement(org.codehaus.groovy.ast.stmt.Statement) WhileStatement(org.codehaus.groovy.ast.stmt.WhileStatement) ExpressionStatement(org.codehaus.groovy.ast.stmt.ExpressionStatement) ThrowStatement(org.codehaus.groovy.ast.stmt.ThrowStatement) DoWhileStatement(org.codehaus.groovy.ast.stmt.DoWhileStatement) ContinueStatement(org.codehaus.groovy.ast.stmt.ContinueStatement) BreakStatement(org.codehaus.groovy.ast.stmt.BreakStatement) ReturnStatement(org.codehaus.groovy.ast.stmt.ReturnStatement) SynchronizedStatement(org.codehaus.groovy.ast.stmt.SynchronizedStatement) SwitchStatement(org.codehaus.groovy.ast.stmt.SwitchStatement) TryCatchStatement(org.codehaus.groovy.ast.stmt.TryCatchStatement) Label(org.objectweb.asm.Label) BlockStatement(org.codehaus.groovy.ast.stmt.BlockStatement) LinkedList(java.util.LinkedList) MethodVisitor(org.objectweb.asm.MethodVisitor) Parameter(org.codehaus.groovy.ast.Parameter) ThrowStatement(org.codehaus.groovy.ast.stmt.ThrowStatement)

Aggregations

Statement (org.codehaus.groovy.ast.stmt.Statement)205 BlockStatement (org.codehaus.groovy.ast.stmt.BlockStatement)167 ExpressionStatement (org.codehaus.groovy.ast.stmt.ExpressionStatement)121 ReturnStatement (org.codehaus.groovy.ast.stmt.ReturnStatement)90 EmptyStatement (org.codehaus.groovy.ast.stmt.EmptyStatement)79 IfStatement (org.codehaus.groovy.ast.stmt.IfStatement)71 Expression (org.codehaus.groovy.ast.expr.Expression)63 VariableExpression (org.codehaus.groovy.ast.expr.VariableExpression)57 CatchStatement (org.codehaus.groovy.ast.stmt.CatchStatement)55 ConstantExpression (org.codehaus.groovy.ast.expr.ConstantExpression)54 ForStatement (org.codehaus.groovy.ast.stmt.ForStatement)53 ThrowStatement (org.codehaus.groovy.ast.stmt.ThrowStatement)53 ClassNode (org.codehaus.groovy.ast.ClassNode)50 TryCatchStatement (org.codehaus.groovy.ast.stmt.TryCatchStatement)50 ClassExpression (org.codehaus.groovy.ast.expr.ClassExpression)40 ConstructorCallExpression (org.codehaus.groovy.ast.expr.ConstructorCallExpression)39 WhileStatement (org.codehaus.groovy.ast.stmt.WhileStatement)39 CaseStatement (org.codehaus.groovy.ast.stmt.CaseStatement)38 SwitchStatement (org.codehaus.groovy.ast.stmt.SwitchStatement)38 SynchronizedStatement (org.codehaus.groovy.ast.stmt.SynchronizedStatement)38