Search in sources :

Example 46 with VariableExpression

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

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)

Example 47 with VariableExpression

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

the class InnerClassCompletionVisitor method addThisReference.

private void addThisReference(ConstructorNode node) {
    if (!shouldHandleImplicitThisForInnerClass(classNode))
        return;
    Statement code = node.getCode();
    // add "this$0" field init
    //add this parameter to node
    Parameter[] params = node.getParameters();
    Parameter[] newParams = new Parameter[params.length + 1];
    System.arraycopy(params, 0, newParams, 1, params.length);
    String name = getUniqueName(params, node);
    Parameter thisPara = new Parameter(classNode.getOuterClass().getPlainNodeReference(), name);
    newParams[0] = thisPara;
    node.setParameters(newParams);
    BlockStatement block = null;
    if (code == null) {
        block = new BlockStatement();
    } else if (!(code instanceof BlockStatement)) {
        block = new BlockStatement();
        block.addStatement(code);
    } else {
        block = (BlockStatement) code;
    }
    BlockStatement newCode = new BlockStatement();
    addFieldInit(thisPara, thisField, newCode);
    ConstructorCallExpression cce = getFirstIfSpecialConstructorCall(block);
    if (cce == null) {
        cce = new ConstructorCallExpression(ClassNode.SUPER, new TupleExpression());
        block.getStatements().add(0, new ExpressionStatement(cce));
    }
    if (shouldImplicitlyPassThisPara(cce)) {
        // add thisPara to this(...)
        TupleExpression args = (TupleExpression) cce.getArguments();
        List<Expression> expressions = args.getExpressions();
        VariableExpression ve = new VariableExpression(thisPara.getName());
        ve.setAccessedVariable(thisPara);
        expressions.add(0, ve);
    }
    if (cce.isSuperCall()) {
        // we have a call to super here, so we need to add
        // our code after that
        block.getStatements().add(1, newCode);
    }
    node.setCode(block);
}
Also used : ConstructorCallExpression(org.codehaus.groovy.ast.expr.ConstructorCallExpression) VariableExpression(org.codehaus.groovy.ast.expr.VariableExpression) ClassExpression(org.codehaus.groovy.ast.expr.ClassExpression) TupleExpression(org.codehaus.groovy.ast.expr.TupleExpression) Expression(org.codehaus.groovy.ast.expr.Expression) Statement(org.codehaus.groovy.ast.stmt.Statement) ExpressionStatement(org.codehaus.groovy.ast.stmt.ExpressionStatement) BlockStatement(org.codehaus.groovy.ast.stmt.BlockStatement) ConstructorCallExpression(org.codehaus.groovy.ast.expr.ConstructorCallExpression) ExpressionStatement(org.codehaus.groovy.ast.stmt.ExpressionStatement) TupleExpression(org.codehaus.groovy.ast.expr.TupleExpression) Parameter(org.codehaus.groovy.ast.Parameter) BlockStatement(org.codehaus.groovy.ast.stmt.BlockStatement) VariableExpression(org.codehaus.groovy.ast.expr.VariableExpression)

Example 48 with VariableExpression

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

the class InnerClassVisitor method visitConstructorCallExpression.

@Override
public void visitConstructorCallExpression(ConstructorCallExpression call) {
    super.visitConstructorCallExpression(call);
    if (!call.isUsingAnonymousInnerClass()) {
        passThisReference(call);
        return;
    }
    InnerClassNode innerClass = (InnerClassNode) call.getType();
    ClassNode outerClass = innerClass.getOuterClass();
    ClassNode superClass = innerClass.getSuperClass();
    if (superClass instanceof InnerClassNode && !superClass.isInterface() && !(superClass.isStaticClass() || ((superClass.getModifiers() & ACC_STATIC) == ACC_STATIC))) {
        insertThis0ToSuperCall(call, innerClass);
    }
    if (!innerClass.getDeclaredConstructors().isEmpty())
        return;
    if ((innerClass.getModifiers() & ACC_STATIC) != 0)
        return;
    VariableScope scope = innerClass.getVariableScope();
    if (scope == null)
        return;
    // expressions = constructor call arguments
    List<Expression> expressions = ((TupleExpression) call.getArguments()).getExpressions();
    // block = init code for the constructor we produce
    BlockStatement block = new BlockStatement();
    // parameters = parameters of the constructor
    final int additionalParamCount = 1 + scope.getReferencedLocalVariablesCount();
    List<Parameter> parameters = new ArrayList<Parameter>(expressions.size() + additionalParamCount);
    // superCallArguments = arguments for the super call == the constructor call arguments
    List<Expression> superCallArguments = new ArrayList<Expression>(expressions.size());
    // first we add a super() call for all expressions given in the 
    // constructor call expression
    int pCount = additionalParamCount;
    for (Expression expr : expressions) {
        pCount++;
        // add one parameter for each expression in the
        // constructor call
        Parameter param = new Parameter(ClassHelper.OBJECT_TYPE, "p" + pCount);
        parameters.add(param);
        // add to super call
        superCallArguments.add(new VariableExpression(param));
    }
    // add the super call
    ConstructorCallExpression cce = new ConstructorCallExpression(ClassNode.SUPER, new TupleExpression(superCallArguments));
    block.addStatement(new ExpressionStatement(cce));
    // we need to add "this" to access unknown methods/properties
    // this is saved in a field named this$0
    pCount = 0;
    expressions.add(pCount, VariableExpression.THIS_EXPRESSION);
    boolean isStatic = isStaticThis(innerClass, scope);
    ClassNode outerClassType = getClassNode(outerClass, isStatic);
    if (!isStatic && inClosure)
        outerClassType = ClassHelper.CLOSURE_TYPE;
    outerClassType = outerClassType.getPlainNodeReference();
    Parameter thisParameter = new Parameter(outerClassType, "p" + pCount);
    parameters.add(pCount, thisParameter);
    thisField = innerClass.addField("this$0", PUBLIC_SYNTHETIC, outerClassType, null);
    addFieldInit(thisParameter, thisField, block);
    // for each shared variable we add a reference and save it as field
    for (Iterator it = scope.getReferencedLocalVariablesIterator(); it.hasNext(); ) {
        pCount++;
        org.codehaus.groovy.ast.Variable var = (org.codehaus.groovy.ast.Variable) it.next();
        VariableExpression ve = new VariableExpression(var);
        ve.setClosureSharedVariable(true);
        ve.setUseReferenceDirectly(true);
        expressions.add(pCount, ve);
        ClassNode rawReferenceType = ClassHelper.REFERENCE_TYPE.getPlainNodeReference();
        Parameter p = new Parameter(rawReferenceType, "p" + pCount);
        parameters.add(pCount, p);
        p.setOriginType(var.getOriginType());
        final VariableExpression initial = new VariableExpression(p);
        initial.setSynthetic(true);
        initial.setUseReferenceDirectly(true);
        final FieldNode pField = innerClass.addFieldFirst(ve.getName(), PUBLIC_SYNTHETIC, rawReferenceType, initial);
        pField.setHolder(true);
        pField.setOriginType(ClassHelper.getWrapper(var.getOriginType()));
    }
    innerClass.addConstructor(ACC_SYNTHETIC, parameters.toArray(new Parameter[parameters.size()]), ClassNode.EMPTY_ARRAY, block);
}
Also used : ClassNode(org.codehaus.groovy.ast.ClassNode) InnerClassNode(org.codehaus.groovy.ast.InnerClassNode) FieldNode(org.codehaus.groovy.ast.FieldNode) ConstructorCallExpression(org.codehaus.groovy.ast.expr.ConstructorCallExpression) TupleExpression(org.codehaus.groovy.ast.expr.TupleExpression) ArrayList(java.util.ArrayList) BlockStatement(org.codehaus.groovy.ast.stmt.BlockStatement) VariableExpression(org.codehaus.groovy.ast.expr.VariableExpression) InnerClassNode(org.codehaus.groovy.ast.InnerClassNode) ConstructorCallExpression(org.codehaus.groovy.ast.expr.ConstructorCallExpression) PropertyExpression(org.codehaus.groovy.ast.expr.PropertyExpression) VariableExpression(org.codehaus.groovy.ast.expr.VariableExpression) ClosureExpression(org.codehaus.groovy.ast.expr.ClosureExpression) TupleExpression(org.codehaus.groovy.ast.expr.TupleExpression) Expression(org.codehaus.groovy.ast.expr.Expression) ExpressionStatement(org.codehaus.groovy.ast.stmt.ExpressionStatement) Iterator(java.util.Iterator) Parameter(org.codehaus.groovy.ast.Parameter) VariableScope(org.codehaus.groovy.ast.VariableScope)

Example 49 with VariableExpression

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

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 50 with VariableExpression

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

the class ClosureWriter method correctAccessedVariable.

private static void correctAccessedVariable(final InnerClassNode closureClass, ClosureExpression ce) {
    CodeVisitorSupport visitor = new CodeVisitorSupport() {

        @Override
        public void visitVariableExpression(VariableExpression expression) {
            Variable v = expression.getAccessedVariable();
            if (v == null)
                return;
            if (!(v instanceof FieldNode))
                return;
            String name = expression.getName();
            FieldNode fn = closureClass.getDeclaredField(name);
            if (fn != null) {
                // only overwrite if we find something more specific
                expression.setAccessedVariable(fn);
            }
        }
    };
    visitor.visitClosureExpression(ce);
}
Also used : CodeVisitorSupport(org.codehaus.groovy.ast.CodeVisitorSupport) Variable(org.codehaus.groovy.ast.Variable) FieldNode(org.codehaus.groovy.ast.FieldNode) VariableExpression(org.codehaus.groovy.ast.expr.VariableExpression)

Aggregations

VariableExpression (org.codehaus.groovy.ast.expr.VariableExpression)176 Expression (org.codehaus.groovy.ast.expr.Expression)86 MethodCallExpression (org.codehaus.groovy.ast.expr.MethodCallExpression)86 ArgumentListExpression (org.codehaus.groovy.ast.expr.ArgumentListExpression)77 ConstantExpression (org.codehaus.groovy.ast.expr.ConstantExpression)72 BinaryExpression (org.codehaus.groovy.ast.expr.BinaryExpression)67 ClassExpression (org.codehaus.groovy.ast.expr.ClassExpression)61 BlockStatement (org.codehaus.groovy.ast.stmt.BlockStatement)58 ClassNode (org.codehaus.groovy.ast.ClassNode)52 ExpressionStatement (org.codehaus.groovy.ast.stmt.ExpressionStatement)52 PropertyExpression (org.codehaus.groovy.ast.expr.PropertyExpression)49 ConstructorCallExpression (org.codehaus.groovy.ast.expr.ConstructorCallExpression)47 TupleExpression (org.codehaus.groovy.ast.expr.TupleExpression)47 ClosureExpression (org.codehaus.groovy.ast.expr.ClosureExpression)45 DeclarationExpression (org.codehaus.groovy.ast.expr.DeclarationExpression)41 Parameter (org.codehaus.groovy.ast.Parameter)40 MethodNode (org.codehaus.groovy.ast.MethodNode)37 FieldNode (org.codehaus.groovy.ast.FieldNode)36 BooleanExpression (org.codehaus.groovy.ast.expr.BooleanExpression)35 Statement (org.codehaus.groovy.ast.stmt.Statement)33