Search in sources :

Example 56 with Parameter

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

the class StaticTypesClosureWriter method createDirectCallMethod.

private void createDirectCallMethod(final ClassNode closureClass, final MethodNode doCallMethod) {
    // in case there is no "call" method on the closure, we can create a "fast invocation" paths
    // to avoid going through ClosureMetaClass by call(Object...) method
    // we can't have a specialized version of call(Object...) because the dispatch logic in ClosureMetaClass
    // is too complex!
    // call(Object)
    Parameter args = new Parameter(ClassHelper.OBJECT_TYPE, "args");
    MethodCallExpression doCall1arg = new MethodCallExpression(new VariableExpression("this", closureClass), "doCall", new ArgumentListExpression(new VariableExpression(args)));
    doCall1arg.setImplicitThis(true);
    doCall1arg.setMethodTarget(doCallMethod);
    closureClass.addMethod(new MethodNode("call", Opcodes.ACC_PUBLIC, ClassHelper.OBJECT_TYPE, new Parameter[] { args }, ClassNode.EMPTY_ARRAY, new ReturnStatement(doCall1arg)));
    // call()
    MethodCallExpression doCallNoArgs = new MethodCallExpression(new VariableExpression("this", closureClass), "doCall", new ArgumentListExpression(new ConstantExpression(null)));
    doCallNoArgs.setImplicitThis(true);
    doCallNoArgs.setMethodTarget(doCallMethod);
    closureClass.addMethod(new MethodNode("call", Opcodes.ACC_PUBLIC, ClassHelper.OBJECT_TYPE, Parameter.EMPTY_ARRAY, ClassNode.EMPTY_ARRAY, new ReturnStatement(doCallNoArgs)));
}
Also used : MethodCallExpression(org.codehaus.groovy.ast.expr.MethodCallExpression) MethodNode(org.codehaus.groovy.ast.MethodNode) ConstantExpression(org.codehaus.groovy.ast.expr.ConstantExpression) ReturnStatement(org.codehaus.groovy.ast.stmt.ReturnStatement) Parameter(org.codehaus.groovy.ast.Parameter) ArgumentListExpression(org.codehaus.groovy.ast.expr.ArgumentListExpression) VariableExpression(org.codehaus.groovy.ast.expr.VariableExpression)

Example 57 with Parameter

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

the class StaticTypesTypeChooser method resolveType.

@Override
public ClassNode resolveType(final Expression exp, final ClassNode current) {
    ASTNode target = exp instanceof VariableExpression ? getTarget((VariableExpression) exp) : exp;
    ClassNode inferredType = (ClassNode) target.getNodeMetaData(StaticTypesMarker.DECLARATION_INFERRED_TYPE);
    if (inferredType == null) {
        inferredType = (ClassNode) target.getNodeMetaData(StaticTypesMarker.INFERRED_TYPE);
        if (inferredType == null && target instanceof VariableExpression && ((VariableExpression) target).getAccessedVariable() instanceof Parameter) {
            target = (Parameter) ((VariableExpression) target).getAccessedVariable();
            inferredType = ((Parameter) target).getOriginType();
        }
    }
    if (inferredType != null) {
        if (ClassHelper.VOID_TYPE == inferredType) {
            // we are in a case of a type inference failure, probably because code was generated
            // it is better to avoid using this
            inferredType = super.resolveType(exp, current);
        }
        return inferredType;
    }
    if (target instanceof VariableExpression && ((VariableExpression) target).isThisExpression()) {
        // AsmClassGenerator may create "this" expressions that the type checker knows nothing about
        return current;
    }
    return super.resolveType(exp, current);
}
Also used : ClassNode(org.codehaus.groovy.ast.ClassNode) ASTNode(org.codehaus.groovy.ast.ASTNode) Parameter(org.codehaus.groovy.ast.Parameter) VariableExpression(org.codehaus.groovy.ast.expr.VariableExpression)

Example 58 with Parameter

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

the class StatementWriter method writeTryCatchFinally.

public void writeTryCatchFinally(TryCatchStatement statement) {
    controller.getAcg().onLineNumber(statement, "visitTryCatchFinally");
    writeStatementLabel(statement);
    MethodVisitor mv = controller.getMethodVisitor();
    CompileStack compileStack = controller.getCompileStack();
    OperandStack operandStack = controller.getOperandStack();
    Statement tryStatement = statement.getTryStatement();
    final Statement finallyStatement = statement.getFinallyStatement();
    // start try block, label needed for exception table
    Label tryStart = new Label();
    mv.visitLabel(tryStart);
    BlockRecorder tryBlock = makeBlockRecorder(finallyStatement);
    tryBlock.startRange(tryStart);
    tryStatement.visit(controller.getAcg());
    // goto finally part
    Label finallyStart = new Label();
    mv.visitJumpInsn(GOTO, finallyStart);
    Label tryEnd = new Label();
    mv.visitLabel(tryEnd);
    tryBlock.closeRange(tryEnd);
    // pop for "makeBlockRecorder(finallyStatement)"
    controller.getCompileStack().pop();
    BlockRecorder catches = makeBlockRecorder(finallyStatement);
    for (CatchStatement catchStatement : statement.getCatchStatements()) {
        ClassNode exceptionType = catchStatement.getExceptionType();
        String exceptionTypeInternalName = BytecodeHelper.getClassInternalName(exceptionType);
        // start catch block, label needed for exception table
        Label catchStart = new Label();
        mv.visitLabel(catchStart);
        catches.startRange(catchStart);
        // create exception variable and store the exception
        Parameter exceptionVariable = catchStatement.getVariable();
        compileStack.pushState();
        compileStack.defineVariable(exceptionVariable, true);
        // handle catch body
        catchStatement.visit(controller.getAcg());
        // place holder to avoid problems with empty catch blocks
        mv.visitInsn(NOP);
        // pop for the variable
        controller.getCompileStack().pop();
        // end of catch
        Label catchEnd = new Label();
        mv.visitLabel(catchEnd);
        catches.closeRange(catchEnd);
        // goto finally start
        mv.visitJumpInsn(GOTO, finallyStart);
        compileStack.writeExceptionTable(tryBlock, catchStart, exceptionTypeInternalName);
    }
    // Label used to handle exceptions in catches and regularly
    // visited finals.
    Label catchAny = new Label();
    // add "catch any" block to exception table for try part we do this
    // after the exception blocks, because else this one would supersede
    // any of those otherwise
    compileStack.writeExceptionTable(tryBlock, catchAny, null);
    // same for the catch parts
    compileStack.writeExceptionTable(catches, catchAny, null);
    // pop for "makeBlockRecorder(catches)"
    compileStack.pop();
    // start finally
    mv.visitLabel(finallyStart);
    finallyStatement.visit(controller.getAcg());
    // **
    mv.visitInsn(NOP);
    // goto after all-catching block
    Label skipCatchAll = new Label();
    mv.visitJumpInsn(GOTO, skipCatchAll);
    // start a block catching any Exception
    mv.visitLabel(catchAny);
    // store exception
    // TODO: maybe define a Throwable and use it here instead of Object
    operandStack.push(ClassHelper.OBJECT_TYPE);
    int anyExceptionIndex = compileStack.defineTemporaryVariable("exception", true);
    finallyStatement.visit(controller.getAcg());
    // load the exception and rethrow it
    mv.visitVarInsn(ALOAD, anyExceptionIndex);
    mv.visitInsn(ATHROW);
    mv.visitLabel(skipCatchAll);
}
Also used : BlockRecorder(org.codehaus.groovy.classgen.asm.CompileStack.BlockRecorder) ClassNode(org.codehaus.groovy.ast.ClassNode) CatchStatement(org.codehaus.groovy.ast.stmt.CatchStatement) TryCatchStatement(org.codehaus.groovy.ast.stmt.TryCatchStatement) 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) CaseStatement(org.codehaus.groovy.ast.stmt.CaseStatement) DoWhileStatement(org.codehaus.groovy.ast.stmt.DoWhileStatement) ContinueStatement(org.codehaus.groovy.ast.stmt.ContinueStatement) ForStatement(org.codehaus.groovy.ast.stmt.ForStatement) BreakStatement(org.codehaus.groovy.ast.stmt.BreakStatement) ReturnStatement(org.codehaus.groovy.ast.stmt.ReturnStatement) CatchStatement(org.codehaus.groovy.ast.stmt.CatchStatement) SynchronizedStatement(org.codehaus.groovy.ast.stmt.SynchronizedStatement) EmptyStatement(org.codehaus.groovy.ast.stmt.EmptyStatement) SwitchStatement(org.codehaus.groovy.ast.stmt.SwitchStatement) IfStatement(org.codehaus.groovy.ast.stmt.IfStatement) AssertStatement(org.codehaus.groovy.ast.stmt.AssertStatement) BlockStatement(org.codehaus.groovy.ast.stmt.BlockStatement) TryCatchStatement(org.codehaus.groovy.ast.stmt.TryCatchStatement) Label(org.objectweb.asm.Label) Parameter(org.codehaus.groovy.ast.Parameter) MethodVisitor(org.objectweb.asm.MethodVisitor)

Example 59 with Parameter

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

the class StaticTypesStatementWriter method writeForInLoop.

@Override
protected void writeForInLoop(final ForStatement loop) {
    controller.getAcg().onLineNumber(loop, "visitForLoop");
    writeStatementLabel(loop);
    CompileStack compileStack = controller.getCompileStack();
    MethodVisitor mv = controller.getMethodVisitor();
    OperandStack operandStack = controller.getOperandStack();
    compileStack.pushLoop(loop.getVariableScope(), loop.getStatementLabels());
    // Identify type of collection
    TypeChooser typeChooser = controller.getTypeChooser();
    Expression collectionExpression = loop.getCollectionExpression();
    ClassNode collectionType = typeChooser.resolveType(collectionExpression, controller.getClassNode());
    Parameter loopVariable = loop.getVariable();
    int size = operandStack.getStackLength();
    if (collectionType.isArray() && loopVariable.getOriginType().equals(collectionType.getComponentType())) {
        writeOptimizedForEachLoop(compileStack, operandStack, mv, loop, collectionExpression, collectionType, loopVariable);
    } else if (ENUMERATION_CLASSNODE.equals(collectionType)) {
        writeEnumerationBasedForEachLoop(compileStack, operandStack, mv, loop, collectionExpression, collectionType, loopVariable);
    } else {
        writeIteratorBasedForEachLoop(compileStack, operandStack, mv, loop, collectionExpression, collectionType, loopVariable);
    }
    operandStack.popDownTo(size);
    compileStack.pop();
}
Also used : ClassNode(org.codehaus.groovy.ast.ClassNode) ArgumentListExpression(org.codehaus.groovy.ast.expr.ArgumentListExpression) MethodCallExpression(org.codehaus.groovy.ast.expr.MethodCallExpression) Expression(org.codehaus.groovy.ast.expr.Expression) Parameter(org.codehaus.groovy.ast.Parameter) MethodVisitor(org.objectweb.asm.MethodVisitor)

Example 60 with Parameter

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

the class MopWriter method generateMopCalls.

/**
 * generates a Meta Object Protocol method, that is used to call a non public
 * method, or to make a call to super.
 *
 * @param mopCalls list of methods a mop call method should be generated for
 * @param useThis  true if "this" should be used for the naming
 */
protected void generateMopCalls(LinkedList<MethodNode> mopCalls, boolean useThis) {
    for (MethodNode method : mopCalls) {
        String name = getMopMethodName(method, useThis);
        Parameter[] parameters = method.getParameters();
        String methodDescriptor = BytecodeHelper.getMethodDescriptor(method.getReturnType(), method.getParameters());
        MethodVisitor mv = controller.getClassVisitor().visitMethod(ACC_PUBLIC | ACC_SYNTHETIC, name, methodDescriptor, null, null);
        controller.setMethodVisitor(mv);
        mv.visitVarInsn(ALOAD, 0);
        int newRegister = 1;
        OperandStack operandStack = controller.getOperandStack();
        for (Parameter parameter : parameters) {
            ClassNode type = parameter.getType();
            operandStack.load(parameter.getType(), newRegister);
            // increment to next register, double/long are using two places
            newRegister++;
            if (type == ClassHelper.double_TYPE || type == ClassHelper.long_TYPE)
                newRegister++;
        }
        operandStack.remove(parameters.length);
        ClassNode declaringClass = method.getDeclaringClass();
        // JDK 8 support for default methods in interfaces
        // this should probably be strenghtened when we support the A.super.foo() syntax
        int opcode = declaringClass.isInterface() ? INVOKEINTERFACE : INVOKESPECIAL;
        mv.visitMethodInsn(opcode, BytecodeHelper.getClassInternalName(declaringClass), method.getName(), methodDescriptor, opcode == INVOKEINTERFACE);
        BytecodeHelper.doReturn(mv, method.getReturnType());
        mv.visitMaxs(0, 0);
        mv.visitEnd();
        controller.getClassNode().addMethod(name, ACC_PUBLIC | ACC_SYNTHETIC, method.getReturnType(), parameters, null, null);
    }
}
Also used : ClassNode(org.codehaus.groovy.ast.ClassNode) MethodNode(org.codehaus.groovy.ast.MethodNode) Parameter(org.codehaus.groovy.ast.Parameter) MethodVisitor(org.objectweb.asm.MethodVisitor)

Aggregations

Parameter (org.codehaus.groovy.ast.Parameter)342 ClassNode (org.codehaus.groovy.ast.ClassNode)202 MethodNode (org.codehaus.groovy.ast.MethodNode)135 InnerClassNode (org.codehaus.groovy.ast.InnerClassNode)117 BlockStatement (org.codehaus.groovy.ast.stmt.BlockStatement)111 VariableExpression (org.codehaus.groovy.ast.expr.VariableExpression)102 Expression (org.codehaus.groovy.ast.expr.Expression)98 MethodCallExpression (org.codehaus.groovy.ast.expr.MethodCallExpression)90 ArgumentListExpression (org.codehaus.groovy.ast.expr.ArgumentListExpression)75 FieldNode (org.codehaus.groovy.ast.FieldNode)71 ExpressionStatement (org.codehaus.groovy.ast.stmt.ExpressionStatement)71 ClassExpression (org.codehaus.groovy.ast.expr.ClassExpression)69 ConstantExpression (org.codehaus.groovy.ast.expr.ConstantExpression)68 ConstructorNode (org.codehaus.groovy.ast.ConstructorNode)66 ConstructorCallExpression (org.codehaus.groovy.ast.expr.ConstructorCallExpression)66 Statement (org.codehaus.groovy.ast.stmt.Statement)66 ArrayList (java.util.ArrayList)62 ClosureExpression (org.codehaus.groovy.ast.expr.ClosureExpression)56 BinaryExpression (org.codehaus.groovy.ast.expr.BinaryExpression)52 PropertyExpression (org.codehaus.groovy.ast.expr.PropertyExpression)51