Search in sources :

Example 96 with Parameter

use of org.codehaus.groovy.ast.Parameter in project groovy by apache.

the class VariableScopeVisitor method visitConstructorOrMethod.

@Override
protected void visitConstructorOrMethod(final MethodNode node, final boolean isConstructor) {
    pushState(node.isStatic());
    inConstructor = isConstructor;
    node.setVariableScope(currentScope);
    visitAnnotations(node);
    for (Parameter parameter : node.getParameters()) {
        visitAnnotations(parameter);
    }
    // to prevent the use of parameters in annotation attributes
    for (Parameter parameter : node.getParameters()) {
        if (parameter.hasInitialExpression()) {
            parameter.getInitialExpression().visit(this);
        }
        declare(parameter, node);
    }
    visitClassCodeContainer(node.getCode());
    popState();
}
Also used : Parameter(org.codehaus.groovy.ast.Parameter)

Example 97 with Parameter

use of org.codehaus.groovy.ast.Parameter in project groovy by apache.

the class ClosureWriter method createClosureClass.

protected ClassNode createClosureClass(final ClosureExpression expression, final int modifiers) {
    ClassNode classNode = controller.getClassNode();
    ClassNode outerClass = controller.getOutermostClass();
    String name = genClosureClassName();
    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 = param(ClassHelper.OBJECT_TYPE, "it", nullX());
        parameters = new Parameter[] { it };
        Variable ref = expression.getVariableScope().getDeclaredVariable("it");
        if (ref != null)
            it.setClosureSharedVariable(ref.isClosureSharedVariable());
    }
    Parameter[] localVariableParams = getClosureSharedVariables(expression);
    removeInitialValues(localVariableParams);
    // GROOVY-9971: closure return type is mapped to Groovy cast by classgen
    ClassNode returnType = expression.getNodeMetaData(INFERRED_RETURN_TYPE);
    if (// not STC or unknown path
    returnType == null)
        // not STC or unknown path
        returnType = ClassHelper.OBJECT_TYPE;
    else if (returnType.isPrimaryClassNode())
        returnType = returnType.getPlainNodeReference();
    else if (ClassHelper.isPrimitiveType(returnType))
        returnType = ClassHelper.getWrapper(returnType);
    else if (GenericsUtils.hasUnresolvedGenerics(returnType))
        returnType = GenericsUtils.nonGeneric(returnType);
    InnerClassNode answer = new InnerClassNode(classNode, name, modifiers, ClassHelper.CLOSURE_TYPE.getPlainNodeReference());
    answer.setEnclosingMethod(controller.getMethodNode());
    answer.setScriptBody(controller.isInScriptBody());
    answer.setSourcePosition(expression);
    answer.setStaticClass(controller.isStaticMethod() || classNode.isStaticClass());
    answer.setSynthetic(true);
    answer.setUsingGenerics(outerClass.isUsingGenerics());
    MethodNode method = answer.addMethod("doCall", ACC_PUBLIC, returnType, 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 && !ClassHelper.OBJECT_TYPE.equals(parameters[0].getType()) && !ClassHelper.OBJECT_TYPE.equals(parameters[0].getType().getComponentType()))) {
        // let's add a typesafe call method
        MethodNode call = new MethodNode("call", ACC_PUBLIC, returnType, parameters, ClassNode.EMPTY_ARRAY, returnS(callThisX("doCall", args(parameters))));
        addGeneratedMethod(answer, call, true);
        call.setSourcePosition(expression);
    }
    // let's make the constructor
    BlockStatement block = createBlockStatementForConstructor(expression, outerClass, classNode);
    // let's assign all the parameter fields from the outer context
    addFieldsAndGettersForLocalVariables(answer, localVariableParams);
    addConstructor(expression, localVariableParams, answer, block);
    correctAccessedVariable(answer, expression);
    return answer;
}
Also used : InnerClassNode(org.codehaus.groovy.ast.InnerClassNode) ClassNode(org.codehaus.groovy.ast.ClassNode) Variable(org.codehaus.groovy.ast.Variable) MethodNode(org.codehaus.groovy.ast.MethodNode) Parameter(org.codehaus.groovy.ast.Parameter) BlockStatement(org.codehaus.groovy.ast.stmt.BlockStatement) InnerClassNode(org.codehaus.groovy.ast.InnerClassNode) VariableScope(org.codehaus.groovy.ast.VariableScope)

Example 98 with Parameter

use of org.codehaus.groovy.ast.Parameter in project groovy by apache.

the class ClosureWriter method addConstructor.

protected ConstructorNode addConstructor(final ClosureExpression expression, final Parameter[] localVariableParams, final InnerClassNode answer, final BlockStatement block) {
    Parameter[] params = new Parameter[2 + localVariableParams.length];
    params[0] = param(ClassHelper.OBJECT_TYPE, OUTER_INSTANCE);
    params[1] = param(ClassHelper.OBJECT_TYPE, THIS_OBJECT);
    System.arraycopy(localVariableParams, 0, params, 2, localVariableParams.length);
    ConstructorNode constructorNode = answer.addConstructor(ACC_PUBLIC, params, ClassNode.EMPTY_ARRAY, block);
    constructorNode.setSourcePosition(expression);
    return constructorNode;
}
Also used : ConstructorNode(org.codehaus.groovy.ast.ConstructorNode) Parameter(org.codehaus.groovy.ast.Parameter)

Example 99 with Parameter

use of org.codehaus.groovy.ast.Parameter in project groovy by apache.

the class ClosureWriter method addFieldsAndGettersForLocalVariables.

protected void addFieldsAndGettersForLocalVariables(final InnerClassNode answer, final Parameter[] localVariableParams) {
    for (Parameter param : localVariableParams) {
        String paramName = param.getName();
        ClassNode type = param.getType();
        VariableExpression initialValue = varX(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 = fieldX(paramField);
        markAsGenerated(answer, answer.addMethod("get" + methodName, ACC_PUBLIC, realType.getPlainNodeReference(), Parameter.EMPTY_ARRAY, ClassNode.EMPTY_ARRAY, returnS(fieldExp)), true);
    }
}
Also used : InnerClassNode(org.codehaus.groovy.ast.InnerClassNode) ClassNode(org.codehaus.groovy.ast.ClassNode) FieldNode(org.codehaus.groovy.ast.FieldNode) VariableExpression(org.codehaus.groovy.ast.expr.VariableExpression) FieldExpression(org.codehaus.groovy.ast.expr.FieldExpression) Expression(org.codehaus.groovy.ast.expr.Expression) ConstructorCallExpression(org.codehaus.groovy.ast.expr.ConstructorCallExpression) ClosureExpression(org.codehaus.groovy.ast.expr.ClosureExpression) ClassExpression(org.codehaus.groovy.ast.expr.ClassExpression) TupleExpression(org.codehaus.groovy.ast.expr.TupleExpression) Parameter(org.codehaus.groovy.ast.Parameter) VariableExpression(org.codehaus.groovy.ast.expr.VariableExpression)

Example 100 with Parameter

use of org.codehaus.groovy.ast.Parameter in project groovy by apache.

the class ClosureWriter method addGeneratedClosureConstructorCall.

public boolean addGeneratedClosureConstructorCall(final ConstructorCallExpression call) {
    ClassNode classNode = controller.getClassNode();
    if (!classNode.declaresInterface(ClassHelper.GENERATED_CLOSURE_Type))
        return false;
    AsmClassGenerator acg = controller.getAcg();
    OperandStack operandStack = controller.getOperandStack();
    MethodVisitor mv = controller.getMethodVisitor();
    mv.visitVarInsn(ALOAD, 0);
    ClassNode callNode = classNode.getSuperClass();
    TupleExpression arguments = (TupleExpression) call.getArguments();
    if (arguments.getExpressions().size() != 2)
        throw new GroovyBugError("expected 2 arguments for closure constructor super call, but got" + arguments.getExpressions().size());
    arguments.getExpression(0).visit(acg);
    operandStack.box();
    arguments.getExpression(1).visit(acg);
    operandStack.box();
    // TODO: replace with normal String, p not needed
    Parameter p = param(ClassHelper.OBJECT_TYPE, "_p");
    String descriptor = BytecodeHelper.getMethodDescriptor(ClassHelper.VOID_TYPE, new Parameter[] { p, p });
    mv.visitMethodInsn(INVOKESPECIAL, BytecodeHelper.getClassInternalName(callNode), "<init>", descriptor, false);
    operandStack.remove(2);
    return true;
}
Also used : InnerClassNode(org.codehaus.groovy.ast.InnerClassNode) ClassNode(org.codehaus.groovy.ast.ClassNode) TupleExpression(org.codehaus.groovy.ast.expr.TupleExpression) GroovyBugError(org.codehaus.groovy.GroovyBugError) Parameter(org.codehaus.groovy.ast.Parameter) AsmClassGenerator(org.codehaus.groovy.classgen.AsmClassGenerator) 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