Search in sources :

Example 6 with FieldExpression

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

the class TraitReceiverTransformer method transform.

@Override
public Expression transform(final Expression exp) {
    ClassNode weavedType = weaved.getOriginType();
    if (exp instanceof BinaryExpression) {
        return transformBinaryExpression((BinaryExpression) exp, weavedType);
    } else if (exp instanceof StaticMethodCallExpression) {
        StaticMethodCallExpression call = (StaticMethodCallExpression) exp;
        ClassNode ownerType = call.getOwnerType();
        if (traitClass.equals(ownerType)) {
            MethodCallExpression result = new MethodCallExpression(new VariableExpression(weaved), call.getMethod(), transform(call.getArguments()));
            result.setSafe(false);
            result.setImplicitThis(false);
            result.setSpreadSafe(false);
            result.setSourcePosition(call);
            return result;
        }
    } else if (exp instanceof MethodCallExpression) {
        MethodCallExpression call = (MethodCallExpression) exp;
        Expression obj = call.getObjectExpression();
        if (call.isImplicitThis() || "this".equals(obj.getText())) {
            return transformMethodCallOnThis(call);
        } else if ("super".equals(obj.getText())) {
            return transformSuperMethodCall(call);
        }
    } else if (exp instanceof FieldExpression) {
        return transformFieldExpression((FieldExpression) exp);
    } else if (exp instanceof VariableExpression) {
        VariableExpression vexp = (VariableExpression) exp;
        Variable accessedVariable = vexp.getAccessedVariable();
        if (accessedVariable instanceof FieldNode) {
            FieldNode fn = (FieldNode) accessedVariable;
            Expression receiver = createFieldHelperReceiver();
            MethodCallExpression mce;
            boolean isStatic = fn.isStatic();
            if (isStatic) {
                receiver = createStaticReceiver(receiver);
            }
            mce = new MethodCallExpression(receiver, Traits.helperGetterName(fn), ArgumentListExpression.EMPTY_ARGUMENTS);
            mce.setSourcePosition(exp);
            mce.setImplicitThis(false);
            markDynamicCall(mce, fn, isStatic);
            return mce;
        } else if (accessedVariable instanceof PropertyNode) {
            String propName = accessedVariable.getName();
            if (knownFields.contains(propName)) {
                String method = Traits.helperGetterName(new FieldNode(propName, 0, ClassHelper.OBJECT_TYPE, weavedType, null));
                MethodCallExpression mce = new MethodCallExpression(createFieldHelperReceiver(), method, ArgumentListExpression.EMPTY_ARGUMENTS);
                mce.setSourcePosition(exp);
                mce.setImplicitThis(false);
                return mce;
            } else {
                return new PropertyExpression(new VariableExpression(weaved), accessedVariable.getName());
            }
        } else if (accessedVariable instanceof DynamicVariable) {
            return new PropertyExpression(new VariableExpression(weaved), accessedVariable.getName());
        }
        if (vexp.isThisExpression()) {
            VariableExpression res = new VariableExpression(weaved);
            res.setSourcePosition(exp);
            return res;
        }
        if (vexp.isSuperExpression()) {
            throwSuperError(vexp);
        }
    } else if (exp instanceof PropertyExpression) {
        PropertyExpression pexp = (PropertyExpression) exp;
        Expression object = pexp.getObjectExpression();
        if (pexp.isImplicitThis() || "this".equals(object.getText())) {
            String propName = pexp.getPropertyAsString();
            if (knownFields.contains(propName)) {
                String method = Traits.helperGetterName(new FieldNode(propName, 0, ClassHelper.OBJECT_TYPE, weavedType, null));
                MethodCallExpression mce = new MethodCallExpression(createFieldHelperReceiver(), method, ArgumentListExpression.EMPTY_ARGUMENTS);
                mce.setSourcePosition(exp);
                mce.setImplicitThis(false);
                return mce;
            }
        }
    } else if (exp instanceof ClosureExpression) {
        MethodCallExpression mce = new MethodCallExpression(exp, "rehydrate", new ArgumentListExpression(new VariableExpression(weaved), new VariableExpression(weaved), new VariableExpression(weaved)));
        mce.setImplicitThis(false);
        mce.setSourcePosition(exp);
        ((ClosureExpression) exp).getCode().visit(this);
        // The rewrite we do is causing some troubles with type checking, which will
        // not be able to perform closure parameter type inference
        // so we store the replacement, which will be done *after* type checking.
        exp.putNodeMetaData(TraitASTTransformation.POST_TYPECHECKING_REPLACEMENT, mce);
        return exp;
    }
    // todo: unary expressions (field++, field+=, ...)
    return super.transform(exp);
}
Also used : ClassNode(org.codehaus.groovy.ast.ClassNode) Variable(org.codehaus.groovy.ast.Variable) DynamicVariable(org.codehaus.groovy.ast.DynamicVariable) FieldNode(org.codehaus.groovy.ast.FieldNode) StaticMethodCallExpression(org.codehaus.groovy.ast.expr.StaticMethodCallExpression) ArgumentListExpression(org.codehaus.groovy.ast.expr.ArgumentListExpression) VariableExpression(org.codehaus.groovy.ast.expr.VariableExpression) FieldExpression(org.codehaus.groovy.ast.expr.FieldExpression) BinaryExpression(org.codehaus.groovy.ast.expr.BinaryExpression) StaticMethodCallExpression(org.codehaus.groovy.ast.expr.StaticMethodCallExpression) MethodCallExpression(org.codehaus.groovy.ast.expr.MethodCallExpression) BooleanExpression(org.codehaus.groovy.ast.expr.BooleanExpression) PropertyExpression(org.codehaus.groovy.ast.expr.PropertyExpression) StaticMethodCallExpression(org.codehaus.groovy.ast.expr.StaticMethodCallExpression) ConstantExpression(org.codehaus.groovy.ast.expr.ConstantExpression) MethodCallExpression(org.codehaus.groovy.ast.expr.MethodCallExpression) Expression(org.codehaus.groovy.ast.expr.Expression) VariableExpression(org.codehaus.groovy.ast.expr.VariableExpression) ArgumentListExpression(org.codehaus.groovy.ast.expr.ArgumentListExpression) DeclarationExpression(org.codehaus.groovy.ast.expr.DeclarationExpression) ClosureExpression(org.codehaus.groovy.ast.expr.ClosureExpression) ClassExpression(org.codehaus.groovy.ast.expr.ClassExpression) BinaryExpression(org.codehaus.groovy.ast.expr.BinaryExpression) FieldExpression(org.codehaus.groovy.ast.expr.FieldExpression) TernaryExpression(org.codehaus.groovy.ast.expr.TernaryExpression) CastExpression(org.codehaus.groovy.ast.expr.CastExpression) DynamicVariable(org.codehaus.groovy.ast.DynamicVariable) PropertyNode(org.codehaus.groovy.ast.PropertyNode) PropertyExpression(org.codehaus.groovy.ast.expr.PropertyExpression) ClosureExpression(org.codehaus.groovy.ast.expr.ClosureExpression)

Example 7 with FieldExpression

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

the class Verifier method addFieldInitialization.

// TODO: add generics to collections
protected void addFieldInitialization(final List list, final List staticList, final FieldNode fieldNode, final boolean isEnumClassNode, final List initStmtsAfterEnumValuesInit, final Set explicitStaticPropsInEnum) {
    Expression expression = fieldNode.getInitialExpression();
    if (expression != null) {
        final FieldExpression fe = fieldX(fieldNode);
        if (fieldNode.getType().equals(ClassHelper.REFERENCE_TYPE) && ((fieldNode.getModifiers() & ACC_SYNTHETIC) != 0)) {
            fe.setUseReferenceDirectly(true);
        }
        Statement statement = stmt(binX(fe, Token.newSymbol(Types.ASSIGN, fieldNode.getLineNumber(), fieldNode.getColumnNumber()), expression));
        if (fieldNode.isStatic()) {
            // GROOVY-3311: pre-defined constants added by groovy compiler for numbers/characters should be
            // initialized first so that code dependent on it does not see their values as empty
            Expression initialValueExpression = fieldNode.getInitialValueExpression();
            Expression transformed = transformInlineConstants(initialValueExpression, fieldNode.getType());
            if (transformed instanceof ConstantExpression) {
                ConstantExpression cexp = (ConstantExpression) transformed;
                cexp = transformToPrimitiveConstantIfPossible(cexp);
                if (fieldNode.isFinal() && ClassHelper.isStaticConstantInitializerType(cexp.getType()) && cexp.getType().equals(fieldNode.getType())) {
                    fieldNode.setInitialValueExpression(transformed);
                    // GROOVY-5150: primitive type constants will be initialized directly
                    return;
                }
                staticList.add(0, statement);
            } else {
                staticList.add(statement);
            }
            // to avoid double initialization in case of several constructors
            fieldNode.setInitialValueExpression(null);
            /*
                 * If it is a statement for an explicitly declared static field inside an enum, store its
                 * reference. For enums, they need to be handled differently as such init statements should
                 * come after the enum values have been initialized inside <clinit> block. GROOVY-3161.
                 */
            if (isEnumClassNode && explicitStaticPropsInEnum.contains(fieldNode.getName())) {
                initStmtsAfterEnumValuesInit.add(statement);
            }
        } else {
            list.add(statement);
        }
    }
}
Also used : VariableExpression(org.codehaus.groovy.ast.expr.VariableExpression) ArgumentListExpression(org.codehaus.groovy.ast.expr.ArgumentListExpression) CastExpression(org.codehaus.groovy.ast.expr.CastExpression) Expression(org.codehaus.groovy.ast.expr.Expression) ConstantExpression(org.codehaus.groovy.ast.expr.ConstantExpression) BinaryExpression(org.codehaus.groovy.ast.expr.BinaryExpression) FieldExpression(org.codehaus.groovy.ast.expr.FieldExpression) MethodCallExpression(org.codehaus.groovy.ast.expr.MethodCallExpression) ConstructorCallExpression(org.codehaus.groovy.ast.expr.ConstructorCallExpression) ClosureExpression(org.codehaus.groovy.ast.expr.ClosureExpression) ExpressionStatement(org.codehaus.groovy.ast.stmt.ExpressionStatement) ReturnStatement(org.codehaus.groovy.ast.stmt.ReturnStatement) BlockStatement(org.codehaus.groovy.ast.stmt.BlockStatement) Statement(org.codehaus.groovy.ast.stmt.Statement) ConstantExpression(org.codehaus.groovy.ast.expr.ConstantExpression) FieldExpression(org.codehaus.groovy.ast.expr.FieldExpression)

Example 8 with FieldExpression

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

the class BinaryExpressionHelper method execMethodAndStoreForSubscriptOperator.

private void execMethodAndStoreForSubscriptOperator(final int op, String method, final Expression expression, final VariableSlotLoader usesSubscript, final Expression orig) {
    writePostOrPrefixMethod(op, method, expression, orig);
    // we need special code for arrays to store the result (like for a[1]++)
    if (usesSubscript != null) {
        BinaryExpression be = (BinaryExpression) expression;
        CompileStack compileStack = controller.getCompileStack();
        OperandStack operandStack = controller.getOperandStack();
        ClassNode methodResultType = operandStack.getTopOperand();
        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, be.isSafe());
        compileStack.removeVar(resultIdx);
    } else if (expression instanceof VariableExpression || expression instanceof PropertyExpression || expression instanceof FieldExpression) {
        // here we handle a++ and a.b++
        controller.getOperandStack().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)

Example 9 with FieldExpression

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

the class ClosureWriter method loadReference.

public static void loadReference(final String name, final 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 : InnerClassNode(org.codehaus.groovy.ast.InnerClassNode) ClassNode(org.codehaus.groovy.ast.ClassNode) 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 10 with FieldExpression

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

the class StaticTypeCheckingVisitor method visitField.

@Override
public void visitField(final FieldNode node) {
    boolean osc = typeCheckingContext.isInStaticContext;
    try {
        typeCheckingContext.isInStaticContext = node.isInStaticContext();
        currentField = node;
        visitAnnotations(node);
        visitInitialExpression(node.getInitialExpression(), new FieldExpression(node), node);
    } finally {
        currentField = null;
        typeCheckingContext.isInStaticContext = osc;
    }
}
Also used : 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