Search in sources :

Example 11 with Expression

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

the class ClassCompletionVerifier method checkFinalFieldAccess.

private void checkFinalFieldAccess(Expression expression) {
    if (!(expression instanceof VariableExpression) && !(expression instanceof PropertyExpression))
        return;
    Variable v = null;
    if (expression instanceof VariableExpression) {
        VariableExpression ve = (VariableExpression) expression;
        v = ve.getAccessedVariable();
    } else {
        PropertyExpression propExp = ((PropertyExpression) expression);
        Expression objectExpression = propExp.getObjectExpression();
        if (objectExpression instanceof VariableExpression) {
            VariableExpression varExp = (VariableExpression) objectExpression;
            if (varExp.isThisExpression()) {
                v = currentClass.getDeclaredField(propExp.getPropertyAsString());
            }
        }
    }
    if (v instanceof FieldNode) {
        FieldNode fn = (FieldNode) v;
        /*
             *  if it is static final but not accessed inside a static constructor, or,
             *  if it is an instance final but not accessed inside a instance constructor, it is an error
             */
        boolean isFinal = fn.isFinal();
        boolean isStatic = fn.isStatic();
        boolean error = isFinal && ((isStatic && !inStaticConstructor) || (!isStatic && !inConstructor));
        if (error)
            addError("cannot modify" + (isStatic ? " static" : "") + " final field '" + fn.getName() + "' outside of " + (isStatic ? "static initialization block." : "constructor."), expression);
    }
}
Also used : PropertyExpression(org.codehaus.groovy.ast.expr.PropertyExpression) VariableExpression(org.codehaus.groovy.ast.expr.VariableExpression) ConstantExpression(org.codehaus.groovy.ast.expr.ConstantExpression) DeclarationExpression(org.codehaus.groovy.ast.expr.DeclarationExpression) TupleExpression(org.codehaus.groovy.ast.expr.TupleExpression) BinaryExpression(org.codehaus.groovy.ast.expr.BinaryExpression) GStringExpression(org.codehaus.groovy.ast.expr.GStringExpression) MethodCallExpression(org.codehaus.groovy.ast.expr.MethodCallExpression) Expression(org.codehaus.groovy.ast.expr.Expression) MapEntryExpression(org.codehaus.groovy.ast.expr.MapEntryExpression) VariableExpression(org.codehaus.groovy.ast.expr.VariableExpression) PropertyExpression(org.codehaus.groovy.ast.expr.PropertyExpression)

Example 12 with Expression

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

the class BinaryExpressionMultiTypeDispatcher method evaluateBinaryExpression.

@Override
protected void evaluateBinaryExpression(final String message, BinaryExpression binExp) {
    int operation = removeAssignment(binExp.getOperation().getType());
    ClassNode current = getController().getClassNode();
    Expression leftExp = binExp.getLeftExpression();
    ClassNode leftTypeOrig = getController().getTypeChooser().resolveType(leftExp, current);
    ClassNode leftType = leftTypeOrig;
    Expression rightExp = binExp.getRightExpression();
    ClassNode rightType = getController().getTypeChooser().resolveType(rightExp, current);
    AsmClassGenerator acg = getController().getAcg();
    OperandStack os = getController().getOperandStack();
    if (operation == LEFT_SQUARE_BRACKET) {
        leftType = leftTypeOrig.getComponentType();
        int operationType = getOperandType(leftType);
        BinaryExpressionWriter bew = binExpWriter[operationType];
        if (leftTypeOrig.isArray() && isIntCastableType(rightExp) && bew.arrayGet(operation, true)) {
            leftExp.visit(acg);
            os.doGroovyCast(leftTypeOrig);
            rightExp.visit(acg);
            os.doGroovyCast(int_TYPE);
            bew.arrayGet(operation, false);
            os.replace(bew.getArrayGetResultType(), 2);
        } else {
            super.evaluateBinaryExpression(message, binExp);
        }
    } else if (operation == DIVIDE) {
        int operationType = getOperandType(getController().getTypeChooser().resolveType(binExp, current));
        BinaryExpressionWriter bew = binExpWriter[operationType];
        if (bew.writeDivision(true)) {
            leftExp.visit(acg);
            os.doGroovyCast(bew.getDevisionOpResultType());
            rightExp.visit(acg);
            os.doGroovyCast(bew.getDevisionOpResultType());
            bew.writeDivision(false);
        } else {
            super.evaluateBinaryExpression(message, binExp);
        }
    } else {
        int operationType = getOperandConversionType(leftType, rightType);
        BinaryExpressionWriter bew = binExpWriter[operationType];
        if (isShiftOperation(operation) && isIntCastableType(rightExp) && bew.write(operation, true)) {
            leftExp.visit(acg);
            os.doGroovyCast(bew.getNormalOpResultType());
            rightExp.visit(acg);
            os.doGroovyCast(int_TYPE);
            bew.write(operation, false);
        } else if (bew.write(operation, true)) {
            leftExp.visit(acg);
            os.doGroovyCast(bew.getNormalOpResultType());
            rightExp.visit(acg);
            os.doGroovyCast(bew.getNormalOpResultType());
            bew.write(operation, false);
        } else {
            super.evaluateBinaryExpression(message, binExp);
        }
    }
}
Also used : ClassNode(org.codehaus.groovy.ast.ClassNode) PropertyExpression(org.codehaus.groovy.ast.expr.PropertyExpression) VariableExpression(org.codehaus.groovy.ast.expr.VariableExpression) BinaryExpression(org.codehaus.groovy.ast.expr.BinaryExpression) Expression(org.codehaus.groovy.ast.expr.Expression) AsmClassGenerator(org.codehaus.groovy.classgen.AsmClassGenerator)

Example 13 with Expression

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

the class BinaryExpressionMultiTypeDispatcher method isAssignmentToArray.

private boolean isAssignmentToArray(BinaryExpression binExp) {
    Expression leftExpression = binExp.getLeftExpression();
    if (!(leftExpression instanceof BinaryExpression))
        return false;
    BinaryExpression leftBinExpr = (BinaryExpression) leftExpression;
    if (leftBinExpr.getOperation().getType() != LEFT_SQUARE_BRACKET)
        return false;
    return true;
}
Also used : BinaryExpression(org.codehaus.groovy.ast.expr.BinaryExpression) PropertyExpression(org.codehaus.groovy.ast.expr.PropertyExpression) VariableExpression(org.codehaus.groovy.ast.expr.VariableExpression) BinaryExpression(org.codehaus.groovy.ast.expr.BinaryExpression) Expression(org.codehaus.groovy.ast.expr.Expression)

Example 14 with Expression

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

the class BinaryExpressionMultiTypeDispatcher method evaluateCompareExpression.

@Override
protected void evaluateCompareExpression(final MethodCaller compareMethod, BinaryExpression binExp) {
    ClassNode current = getController().getClassNode();
    TypeChooser typeChooser = getController().getTypeChooser();
    int operation = binExp.getOperation().getType();
    Expression leftExp = binExp.getLeftExpression();
    ClassNode leftType = typeChooser.resolveType(leftExp, current);
    Expression rightExp = binExp.getRightExpression();
    ClassNode rightType = typeChooser.resolveType(rightExp, current);
    if (!doPrimitiveCompare(leftType, rightType, binExp)) {
        super.evaluateCompareExpression(compareMethod, binExp);
    }
}
Also used : ClassNode(org.codehaus.groovy.ast.ClassNode) PropertyExpression(org.codehaus.groovy.ast.expr.PropertyExpression) VariableExpression(org.codehaus.groovy.ast.expr.VariableExpression) BinaryExpression(org.codehaus.groovy.ast.expr.BinaryExpression) Expression(org.codehaus.groovy.ast.expr.Expression)

Example 15 with Expression

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

the class BinaryExpressionMultiTypeDispatcher method doAssignmentToArray.

private boolean doAssignmentToArray(BinaryExpression binExp) {
    if (!isAssignmentToArray(binExp))
        return false;
    // we need to handle only assignment to arrays combined with an operation
    // special here. e.g x[a] += b
    int operation = removeAssignment(binExp.getOperation().getType());
    ClassNode current = getController().getClassNode();
    Expression leftExp = binExp.getLeftExpression();
    ClassNode leftType = getController().getTypeChooser().resolveType(leftExp, current);
    Expression rightExp = binExp.getRightExpression();
    ClassNode rightType = getController().getTypeChooser().resolveType(rightExp, current);
    int operationType = getOperandType(leftType);
    BinaryExpressionWriter bew = binExpWriter[operationType];
    boolean simulationSuccess = bew.arrayGet(LEFT_SQUARE_BRACKET, true);
    simulationSuccess = simulationSuccess && bew.write(operation, true);
    simulationSuccess = simulationSuccess && bew.arraySet(true);
    if (!simulationSuccess)
        return false;
    AsmClassGenerator acg = getController().getAcg();
    OperandStack operandStack = getController().getOperandStack();
    CompileStack compileStack = getController().getCompileStack();
    // for x[a] += b we have the structure:
    //   x = left(left(binExp))), b = right(binExp), a = right(left(binExp)))
    // for array set we need these values on stack: array, index, right 
    // for array get we need these values on stack: array, index
    // to eval the expression we need x[a] = x[a]+b
    // -> arraySet(x,a, x[a]+b) 
    // -> arraySet(x,a, arrayGet(x,a,b))
    // --> x,a, x,a, b as operands
    // --> load x, load a, DUP2, call arrayGet, load b, call operation,call arraySet
    // since we cannot DUP2 here easily we will save the subscript and DUP x
    // --> sub=a, load x, DUP, load sub, call arrayGet, load b, call operation, load sub, call arraySet
    BinaryExpression arrayWithSubscript = (BinaryExpression) leftExp;
    Expression subscript = arrayWithSubscript.getRightExpression();
    // load array index: sub=a [load x, DUP, load sub, call arrayGet, load b, call operation, load sub, call arraySet]
    subscript.visit(acg);
    operandStack.doGroovyCast(int_TYPE);
    int subscriptValueId = compileStack.defineTemporaryVariable("$sub", ClassHelper.int_TYPE, true);
    // load array: load x and DUP [load sub, call arrayGet, load b, call operation, load sub, call arraySet] 
    arrayWithSubscript.getLeftExpression().visit(acg);
    operandStack.doGroovyCast(leftType.makeArray());
    operandStack.dup();
    // array get: load sub, call arrayGet [load b, call operation, load sub, call arraySet]
    operandStack.load(ClassHelper.int_TYPE, subscriptValueId);
    bew.arrayGet(LEFT_SQUARE_BRACKET, false);
    operandStack.replace(leftType, 2);
    // complete rhs: load b, call operation [load sub, call arraySet]
    binExp.getRightExpression().visit(acg);
    if (!(bew instanceof BinaryObjectExpressionHelper)) {
        // in primopts we convert to the left type for supported binary operations
        operandStack.doGroovyCast(leftType);
    }
    bew.write(operation, false);
    // let us save that value for the return
    operandStack.dup();
    int resultValueId = compileStack.defineTemporaryVariable("$result", rightType, true);
    // array set: load sub, call arraySet []
    operandStack.load(ClassHelper.int_TYPE, subscriptValueId);
    operandStack.swap();
    bew.arraySet(false);
    // 3 operands, the array, the index and the value!
    operandStack.remove(3);
    // load return value
    operandStack.load(rightType, resultValueId);
    // cleanup
    compileStack.removeVar(resultValueId);
    compileStack.removeVar(subscriptValueId);
    return true;
}
Also used : ClassNode(org.codehaus.groovy.ast.ClassNode) BinaryExpression(org.codehaus.groovy.ast.expr.BinaryExpression) PropertyExpression(org.codehaus.groovy.ast.expr.PropertyExpression) VariableExpression(org.codehaus.groovy.ast.expr.VariableExpression) BinaryExpression(org.codehaus.groovy.ast.expr.BinaryExpression) Expression(org.codehaus.groovy.ast.expr.Expression) AsmClassGenerator(org.codehaus.groovy.classgen.AsmClassGenerator)

Aggregations

Expression (org.codehaus.groovy.ast.expr.Expression)369 VariableExpression (org.codehaus.groovy.ast.expr.VariableExpression)257 ConstantExpression (org.codehaus.groovy.ast.expr.ConstantExpression)244 ClassExpression (org.codehaus.groovy.ast.expr.ClassExpression)187 MethodCallExpression (org.codehaus.groovy.ast.expr.MethodCallExpression)187 ArgumentListExpression (org.codehaus.groovy.ast.expr.ArgumentListExpression)152 PropertyExpression (org.codehaus.groovy.ast.expr.PropertyExpression)151 BinaryExpression (org.codehaus.groovy.ast.expr.BinaryExpression)149 ClassNode (org.codehaus.groovy.ast.ClassNode)146 ListExpression (org.codehaus.groovy.ast.expr.ListExpression)134 ClosureExpression (org.codehaus.groovy.ast.expr.ClosureExpression)130 ConstructorCallExpression (org.codehaus.groovy.ast.expr.ConstructorCallExpression)113 TupleExpression (org.codehaus.groovy.ast.expr.TupleExpression)103 BlockStatement (org.codehaus.groovy.ast.stmt.BlockStatement)95 DeclarationExpression (org.codehaus.groovy.ast.expr.DeclarationExpression)84 EmptyExpression (org.codehaus.groovy.ast.expr.EmptyExpression)78 CastExpression (org.codehaus.groovy.ast.expr.CastExpression)63 ExpressionStatement (org.codehaus.groovy.ast.stmt.ExpressionStatement)63 Statement (org.codehaus.groovy.ast.stmt.Statement)63 MapExpression (org.codehaus.groovy.ast.expr.MapExpression)61