Search in sources :

Example 1 with FieldExpression

use of org.codehaus.groovy.ast.expr.FieldExpression in project grails-core by grails.

the class TestMixinTransformation method weaveMixinIntoClass.

protected void weaveMixinIntoClass(final ClassNode classNode, final ClassNode mixinClassNode, final Junit3TestFixtureMethodHandler junit3MethodHandler, ClassNode applicationClassNode) {
    if (mixinClassNode.getName().equals(IntegrationTestMixin.class.getName())) {
        new IntegrationTestMixinTransformation().weaveIntegrationTestMixin(classNode, applicationClassNode);
        return;
    }
    final String fieldName = '$' + GrailsNameUtils.getPropertyName(mixinClassNode.getName());
    boolean implementsTestRuntimeAwareMixin = GrailsASTUtils.findInterface(mixinClassNode, ClassHelper.make(TestRuntimeAwareMixin.class)) != null;
    FieldNode mixinFieldNode;
    if (!implementsTestRuntimeAwareMixin) {
        mixinFieldNode = addLegacyMixinFieldIfNonExistent(classNode, mixinClassNode, fieldName);
    } else {
        mixinFieldNode = addTestRuntimeAwareMixinFieldIfNonExistent(classNode, mixinClassNode, fieldName);
    }
    // already woven
    if (mixinFieldNode == null)
        return;
    FieldExpression fieldReference = new FieldExpression(mixinFieldNode);
    ClassNode currentMixinClassNode = mixinClassNode;
    while (!currentMixinClassNode.getName().equals(GrailsASTUtils.OBJECT_CLASS)) {
        final List<MethodNode> mixinMethods = currentMixinClassNode.getMethods();
        for (MethodNode mixinMethod : mixinMethods) {
            if (!isCandidateMethod(mixinMethod) || hasDeclaredMethod(classNode, mixinMethod)) {
                continue;
            }
            MethodNode methodNode;
            if (mixinMethod.isStatic()) {
                methodNode = GrailsASTUtils.addDelegateStaticMethod(classNode, mixinMethod);
            } else {
                methodNode = GrailsASTUtils.addDelegateInstanceMethod(classNode, fieldReference, mixinMethod, false);
            }
            if (methodNode != null) {
                methodNode.addAnnotation(MIXIN_METHOD_ANNOTATION);
                GrailsASTUtils.addCompileStaticAnnotation(methodNode);
            }
            if (junit3MethodHandler != null) {
                junit3MethodHandler.handle(mixinMethod, methodNode);
            }
        }
        currentMixinClassNode = currentMixinClassNode.getSuperClass();
        if (junit3MethodHandler != null) {
            junit3MethodHandler.mixinSuperClassChanged();
        }
    }
}
Also used : ClassNode(org.codehaus.groovy.ast.ClassNode) FieldNode(org.codehaus.groovy.ast.FieldNode) MethodNode(org.codehaus.groovy.ast.MethodNode) IntegrationTestMixin(grails.test.mixin.integration.IntegrationTestMixin) FieldExpression(org.codehaus.groovy.ast.expr.FieldExpression)

Example 2 with FieldExpression

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

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 3 with FieldExpression

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

the class ClosureWriter method loadReference.

public static void loadReference(String name, WriterController controller) {
    CompileStack compileStack = controller.getCompileStack();
    MethodVisitor mv = controller.getMethodVisitor();
    ClassNode classNode = controller.getClassNode();
    AsmClassGenerator acg = controller.getAcg();
    // an already declared variable.
    if (!compileStack.containsVariable(name) && compileStack.getScope().isReferencedClassVariable(name)) {
        acg.visitFieldExpression(new FieldExpression(classNode.getDeclaredField(name)));
    } else {
        BytecodeVariable v = compileStack.getVariable(name, !classNodeUsesReferences(controller.getClassNode()));
        if (v == null) {
            // variable is not on stack because we are
            // inside a nested Closure and this variable
            // was not used before
            // then load it from the Closure field
            FieldNode field = classNode.getDeclaredField(name);
            mv.visitVarInsn(ALOAD, 0);
            mv.visitFieldInsn(GETFIELD, controller.getInternalClassName(), name, BytecodeHelper.getTypeDescription(field.getType()));
        } else {
            mv.visitVarInsn(ALOAD, v.getIndex());
        }
        controller.getOperandStack().push(ClassHelper.REFERENCE_TYPE);
    }
}
Also used : ClassNode(org.codehaus.groovy.ast.ClassNode) InnerClassNode(org.codehaus.groovy.ast.InnerClassNode) FieldNode(org.codehaus.groovy.ast.FieldNode) AsmClassGenerator(org.codehaus.groovy.classgen.AsmClassGenerator) MethodVisitor(org.objectweb.asm.MethodVisitor) FieldExpression(org.codehaus.groovy.ast.expr.FieldExpression)

Example 4 with FieldExpression

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

the class Verifier method moveOptimizedConstantsInitialization.

private boolean moveOptimizedConstantsInitialization(final ClassNode node) {
    if (node.isInterface() && !Traits.isTrait(node))
        return false;
    final int mods = Opcodes.ACC_STATIC | Opcodes.ACC_SYNTHETIC | Opcodes.ACC_PUBLIC;
    String name = SWAP_INIT;
    BlockStatement methodCode = new BlockStatement();
    methodCode.addStatement(new SwapInitStatement());
    boolean swapInitRequired = false;
    for (FieldNode fn : node.getFields()) {
        if (!fn.isStatic() || !fn.isSynthetic() || !fn.getName().startsWith("$const$"))
            continue;
        if (fn.getInitialExpression() == null)
            continue;
        final FieldExpression fe = new FieldExpression(fn);
        if (fn.getType().equals(ClassHelper.REFERENCE_TYPE))
            fe.setUseReferenceDirectly(true);
        ConstantExpression init = (ConstantExpression) fn.getInitialExpression();
        init = new ConstantExpression(init.getValue(), true);
        ExpressionStatement statement = new ExpressionStatement(new BinaryExpression(fe, Token.newSymbol(Types.EQUAL, fn.getLineNumber(), fn.getColumnNumber()), init));
        fn.setInitialValueExpression(null);
        methodCode.addStatement(statement);
        swapInitRequired = true;
    }
    if (swapInitRequired) {
        node.addSyntheticMethod(name, mods, ClassHelper.VOID_TYPE, Parameter.EMPTY_ARRAY, ClassNode.EMPTY_ARRAY, methodCode);
    }
    return swapInitRequired;
}
Also used : BinaryExpression(org.codehaus.groovy.ast.expr.BinaryExpression) ConstantExpression(org.codehaus.groovy.ast.expr.ConstantExpression) ExpressionStatement(org.codehaus.groovy.ast.stmt.ExpressionStatement) BlockStatement(org.codehaus.groovy.ast.stmt.BlockStatement) FieldExpression(org.codehaus.groovy.ast.expr.FieldExpression)

Example 5 with FieldExpression

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

the class BinaryExpressionHelper method execMethodAndStoreForSubscriptOperator.

private void execMethodAndStoreForSubscriptOperator(int op, String method, Expression expression, VariableSlotLoader usesSubscript, Expression orig) {
    final OperandStack operandStack = controller.getOperandStack();
    writePostOrPrefixMethod(op, method, expression, orig);
    // we need special code for arrays to store the result (like for a[1]++)
    if (usesSubscript != null) {
        CompileStack compileStack = controller.getCompileStack();
        BinaryExpression be = (BinaryExpression) expression;
        ClassNode methodResultType = operandStack.getTopOperand();
        final int resultIdx = compileStack.defineTemporaryVariable("postfix_" + method, methodResultType, true);
        BytecodeExpression methodResultLoader = new VariableSlotLoader(methodResultType, resultIdx, operandStack);
        // execute the assignment, this will leave the right side
        // (here the method call result) on the stack
        assignToArray(be, be.getLeftExpression(), usesSubscript, methodResultLoader);
        compileStack.removeVar(resultIdx);
    } else // here we handle a.b++ and a++
    if (expression instanceof VariableExpression || expression instanceof FieldExpression || expression instanceof PropertyExpression) {
        operandStack.dup();
        controller.getCompileStack().pushLHS(true);
        expression.visit(controller.getAcg());
        controller.getCompileStack().popLHS();
    }
// other cases don't need storing, so nothing to be done for them
}
Also used : ClassNode(org.codehaus.groovy.ast.ClassNode) BinaryExpression(org.codehaus.groovy.ast.expr.BinaryExpression) VariableExpression(org.codehaus.groovy.ast.expr.VariableExpression) PropertyExpression(org.codehaus.groovy.ast.expr.PropertyExpression) BytecodeExpression(org.codehaus.groovy.classgen.BytecodeExpression) FieldExpression(org.codehaus.groovy.ast.expr.FieldExpression)

Aggregations

FieldExpression (org.codehaus.groovy.ast.expr.FieldExpression)28 BinaryExpression (org.codehaus.groovy.ast.expr.BinaryExpression)17 VariableExpression (org.codehaus.groovy.ast.expr.VariableExpression)17 ConstantExpression (org.codehaus.groovy.ast.expr.ConstantExpression)16 MethodCallExpression (org.codehaus.groovy.ast.expr.MethodCallExpression)15 ExpressionStatement (org.codehaus.groovy.ast.stmt.ExpressionStatement)15 FieldNode (org.codehaus.groovy.ast.FieldNode)13 ArgumentListExpression (org.codehaus.groovy.ast.expr.ArgumentListExpression)13 BlockStatement (org.codehaus.groovy.ast.stmt.BlockStatement)13 ClassNode (org.codehaus.groovy.ast.ClassNode)12 StaticMethodCallExpression (org.codehaus.groovy.ast.expr.StaticMethodCallExpression)11 ReturnStatement (org.codehaus.groovy.ast.stmt.ReturnStatement)10 Statement (org.codehaus.groovy.ast.stmt.Statement)10 Expression (org.codehaus.groovy.ast.expr.Expression)8 ClassExpression (org.codehaus.groovy.ast.expr.ClassExpression)7 ClosureExpression (org.codehaus.groovy.ast.expr.ClosureExpression)7 ConstructorCallExpression (org.codehaus.groovy.ast.expr.ConstructorCallExpression)7 IfStatement (org.codehaus.groovy.ast.stmt.IfStatement)7 MethodNode (org.codehaus.groovy.ast.MethodNode)6 BooleanExpression (org.codehaus.groovy.ast.expr.BooleanExpression)6