Search in sources :

Example 21 with CastExpression

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

the class TraitComposer method createSuperFallback.

private static Statement createSuperFallback(MethodNode forwarderMethod, ClassNode returnType) {
    ArgumentListExpression args = new ArgumentListExpression();
    Parameter[] forwarderMethodParameters = forwarderMethod.getParameters();
    for (final Parameter forwarderMethodParameter : forwarderMethodParameters) {
        args.addExpression(new VariableExpression(forwarderMethodParameter));
    }
    BinaryExpression instanceOfExpr = new BinaryExpression(new VariableExpression("this"), Token.newSymbol(Types.KEYWORD_INSTANCEOF, -1, -1), new ClassExpression(Traits.GENERATED_PROXY_CLASSNODE));
    MethodCallExpression superCall = new MethodCallExpression(new VariableExpression("super"), forwarderMethod.getName(), args);
    superCall.setImplicitThis(false);
    CastExpression proxyReceiver = new CastExpression(Traits.GENERATED_PROXY_CLASSNODE, new VariableExpression("this"));
    MethodCallExpression getProxy = new MethodCallExpression(proxyReceiver, "getProxyTarget", ArgumentListExpression.EMPTY_ARGUMENTS);
    getProxy.setImplicitThis(true);
    StaticMethodCallExpression proxyCall = new StaticMethodCallExpression(ClassHelper.make(InvokerHelper.class), "invokeMethod", new ArgumentListExpression(getProxy, new ConstantExpression(forwarderMethod.getName()), new ArrayExpression(ClassHelper.OBJECT_TYPE, args.getExpressions())));
    IfStatement stmt = new IfStatement(new BooleanExpression(instanceOfExpr), new ExpressionStatement(new CastExpression(returnType, proxyCall)), new ExpressionStatement(superCall));
    return stmt;
}
Also used : InvokerHelper(org.codehaus.groovy.runtime.InvokerHelper) ConstantExpression(org.codehaus.groovy.ast.expr.ConstantExpression) StaticMethodCallExpression(org.codehaus.groovy.ast.expr.StaticMethodCallExpression) ArgumentListExpression(org.codehaus.groovy.ast.expr.ArgumentListExpression) VariableExpression(org.codehaus.groovy.ast.expr.VariableExpression) ClassExpression(org.codehaus.groovy.ast.expr.ClassExpression) IfStatement(org.codehaus.groovy.ast.stmt.IfStatement) BooleanExpression(org.codehaus.groovy.ast.expr.BooleanExpression) BinaryExpression(org.codehaus.groovy.ast.expr.BinaryExpression) StaticMethodCallExpression(org.codehaus.groovy.ast.expr.StaticMethodCallExpression) MethodCallExpression(org.codehaus.groovy.ast.expr.MethodCallExpression) ExpressionStatement(org.codehaus.groovy.ast.stmt.ExpressionStatement) Parameter(org.codehaus.groovy.ast.Parameter) ArrayExpression(org.codehaus.groovy.ast.expr.ArrayExpression) CastExpression(org.codehaus.groovy.ast.expr.CastExpression)

Example 22 with CastExpression

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

the class TraitComposer method createForwarderMethod.

private static void createForwarderMethod(ClassNode trait, ClassNode targetNode, MethodNode helperMethod, MethodNode originalMethod, ClassNode helperClassNode, Map<String, ClassNode> genericsSpec, Parameter[] helperMethodParams, Parameter[] traitMethodParams, Parameter[] forwarderParams, ArgumentListExpression helperMethodArgList) {
    MethodCallExpression mce = new MethodCallExpression(new ClassExpression(helperClassNode), helperMethod.getName(), helperMethodArgList);
    mce.setImplicitThis(false);
    genericsSpec = GenericsUtils.addMethodGenerics(helperMethod, genericsSpec);
    ClassNode[] exceptionNodes = correctToGenericsSpecRecurse(genericsSpec, copyExceptions(helperMethod.getExceptions()));
    ClassNode fixedReturnType = correctToGenericsSpecRecurse(genericsSpec, helperMethod.getReturnType());
    boolean noCastRequired = genericsSpec.isEmpty() || fixedReturnType.getName().equals(ClassHelper.VOID_TYPE.getName());
    Expression forwardExpression = noCastRequired ? mce : new CastExpression(fixedReturnType, mce);
    int access = helperMethod.getModifiers();
    // we could rely on the first parameter name ($static$self) but that information is not
    // guaranteed to be always present
    boolean isHelperForStaticMethod = helperMethodParams[0].getOriginType().equals(ClassHelper.CLASS_Type);
    if (Modifier.isPrivate(access) && !isHelperForStaticMethod) {
        // see GROOVY-7213
        return;
    }
    if (!isHelperForStaticMethod) {
        access = access ^ Opcodes.ACC_STATIC;
    }
    MethodNode forwarder = new MethodNode(helperMethod.getName(), access, fixedReturnType, forwarderParams, exceptionNodes, new ExpressionStatement(forwardExpression));
    List<AnnotationNode> copied = new LinkedList<AnnotationNode>();
    // at this point, should *always* stay empty
    List<AnnotationNode> notCopied = Collections.emptyList();
    GeneralUtils.copyAnnotatedNodeAnnotations(helperMethod, copied, notCopied);
    if (!copied.isEmpty()) {
        forwarder.addAnnotations(copied);
    }
    if (originalMethod != null) {
        GenericsType[] newGt = GenericsUtils.applyGenericsContextToPlaceHolders(genericsSpec, originalMethod.getGenericsTypes());
        newGt = removeNonPlaceHolders(newGt);
        forwarder.setGenericsTypes(newGt);
    } else {
        // null indicates a static method which may still need generics correction
        GenericsType[] genericsTypes = helperMethod.getGenericsTypes();
        if (genericsTypes != null) {
            Map<String, ClassNode> methodSpec = new HashMap<String, ClassNode>();
            methodSpec = GenericsUtils.addMethodGenerics(helperMethod, methodSpec);
            GenericsType[] newGt = GenericsUtils.applyGenericsContextToPlaceHolders(methodSpec, helperMethod.getGenericsTypes());
            forwarder.setGenericsTypes(newGt);
        }
    }
    // add a helper annotation indicating that it is a bridge method
    AnnotationNode bridgeAnnotation = new AnnotationNode(Traits.TRAITBRIDGE_CLASSNODE);
    bridgeAnnotation.addMember("traitClass", new ClassExpression(trait));
    bridgeAnnotation.addMember("desc", new ConstantExpression(BytecodeHelper.getMethodDescriptor(helperMethod.getReturnType(), traitMethodParams)));
    forwarder.addAnnotation(bridgeAnnotation);
    if (!shouldSkipMethod(targetNode, forwarder.getName(), forwarderParams)) {
        targetNode.addMethod(forwarder);
    }
    createSuperForwarder(targetNode, forwarder, genericsSpec);
}
Also used : InnerClassNode(org.codehaus.groovy.ast.InnerClassNode) ClassNode(org.codehaus.groovy.ast.ClassNode) HashMap(java.util.HashMap) LinkedHashMap(java.util.LinkedHashMap) ConstantExpression(org.codehaus.groovy.ast.expr.ConstantExpression) ClassExpression(org.codehaus.groovy.ast.expr.ClassExpression) LinkedList(java.util.LinkedList) StaticMethodCallExpression(org.codehaus.groovy.ast.expr.StaticMethodCallExpression) MethodCallExpression(org.codehaus.groovy.ast.expr.MethodCallExpression) MethodNode(org.codehaus.groovy.ast.MethodNode) ConstantExpression(org.codehaus.groovy.ast.expr.ConstantExpression) VariableExpression(org.codehaus.groovy.ast.expr.VariableExpression) ArrayExpression(org.codehaus.groovy.ast.expr.ArrayExpression) ArgumentListExpression(org.codehaus.groovy.ast.expr.ArgumentListExpression) BinaryExpression(org.codehaus.groovy.ast.expr.BinaryExpression) CastExpression(org.codehaus.groovy.ast.expr.CastExpression) BooleanExpression(org.codehaus.groovy.ast.expr.BooleanExpression) StaticMethodCallExpression(org.codehaus.groovy.ast.expr.StaticMethodCallExpression) MethodCallExpression(org.codehaus.groovy.ast.expr.MethodCallExpression) Expression(org.codehaus.groovy.ast.expr.Expression) ClassExpression(org.codehaus.groovy.ast.expr.ClassExpression) AnnotationNode(org.codehaus.groovy.ast.AnnotationNode) ExpressionStatement(org.codehaus.groovy.ast.stmt.ExpressionStatement) GenericsType(org.codehaus.groovy.ast.GenericsType) CastExpression(org.codehaus.groovy.ast.expr.CastExpression)

Example 23 with CastExpression

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

the class CallSiteWriter method makeCallSite.

public void makeCallSite(Expression receiver, String message, Expression arguments, boolean safe, boolean implicitThis, boolean callCurrent, boolean callStatic) {
    prepareSiteAndReceiver(receiver, message, implicitThis);
    CompileStack compileStack = controller.getCompileStack();
    compileStack.pushImplicitThis(implicitThis);
    compileStack.pushLHS(false);
    boolean constructor = message.equals(CONSTRUCTOR);
    OperandStack operandStack = controller.getOperandStack();
    // arguments
    boolean containsSpreadExpression = AsmClassGenerator.containsSpreadExpression(arguments);
    int numberOfArguments = containsSpreadExpression ? -1 : AsmClassGenerator.argumentSize(arguments);
    int operandsToReplace = 1;
    if (numberOfArguments > MethodCallerMultiAdapter.MAX_ARGS || containsSpreadExpression) {
        ArgumentListExpression ae;
        if (arguments instanceof ArgumentListExpression) {
            ae = (ArgumentListExpression) arguments;
        } else if (arguments instanceof TupleExpression) {
            TupleExpression te = (TupleExpression) arguments;
            ae = new ArgumentListExpression(te.getExpressions());
        } else {
            ae = new ArgumentListExpression();
            ae.addExpression(arguments);
        }
        controller.getCompileStack().pushImplicitThis(false);
        if (containsSpreadExpression) {
            numberOfArguments = -1;
            controller.getAcg().despreadList(ae.getExpressions(), true);
        } else {
            numberOfArguments = ae.getExpressions().size();
            for (int i = 0; i < numberOfArguments; i++) {
                Expression argument = ae.getExpression(i);
                argument.visit(controller.getAcg());
                operandStack.box();
                if (argument instanceof CastExpression)
                    controller.getAcg().loadWrapper(argument);
            }
            operandsToReplace += numberOfArguments;
        }
        controller.getCompileStack().popImplicitThis();
    }
    controller.getCompileStack().popLHS();
    controller.getCompileStack().popImplicitThis();
    MethodVisitor mv = controller.getMethodVisitor();
    if (numberOfArguments > 4) {
        final String createArraySignature = getCreateArraySignature(numberOfArguments);
        mv.visitMethodInsn(INVOKESTATIC, "org/codehaus/groovy/runtime/ArrayUtil", "createArray", createArraySignature, false);
        //TODO: use pre-generated Object[]
        operandStack.replace(ClassHelper.OBJECT_TYPE.makeArray(), numberOfArguments);
        operandsToReplace = operandsToReplace - numberOfArguments + 1;
    }
    final String desc = getDescForParamNum(numberOfArguments);
    if (callStatic) {
        mv.visitMethodInsn(INVOKEINTERFACE, CALLSITE_CLASS, "callStatic", "(Ljava/lang/Class;" + desc, true);
    } else if (constructor) {
        mv.visitMethodInsn(INVOKEINTERFACE, CALLSITE_CLASS, "callConstructor", "(Ljava/lang/Object;" + desc, true);
    } else if (callCurrent) {
        mv.visitMethodInsn(INVOKEINTERFACE, CALLSITE_CLASS, "callCurrent", "(Lgroovy/lang/GroovyObject;" + desc, true);
    } else if (safe) {
        mv.visitMethodInsn(INVOKEINTERFACE, CALLSITE_CLASS, "callSafe", "(Ljava/lang/Object;" + desc, true);
    } else {
        mv.visitMethodInsn(INVOKEINTERFACE, CALLSITE_CLASS, "call", "(Ljava/lang/Object;" + desc, true);
    }
    operandStack.replace(ClassHelper.OBJECT_TYPE, operandsToReplace);
}
Also used : ArgumentListExpression(org.codehaus.groovy.ast.expr.ArgumentListExpression) ClassExpression(org.codehaus.groovy.ast.expr.ClassExpression) TupleExpression(org.codehaus.groovy.ast.expr.TupleExpression) CastExpression(org.codehaus.groovy.ast.expr.CastExpression) Expression(org.codehaus.groovy.ast.expr.Expression) TupleExpression(org.codehaus.groovy.ast.expr.TupleExpression) ArgumentListExpression(org.codehaus.groovy.ast.expr.ArgumentListExpression) CastExpression(org.codehaus.groovy.ast.expr.CastExpression) MethodVisitor(org.objectweb.asm.MethodVisitor)

Example 24 with CastExpression

use of org.codehaus.groovy.ast.expr.CastExpression in project gradle by gradle.

the class GradleResolveVisitor method transformBinaryExpression.

protected Expression transformBinaryExpression(BinaryExpression be) {
    Expression left = transform(be.getLeftExpression());
    int type = be.getOperation().getType();
    if ((type == Types.ASSIGNMENT_OPERATOR || type == Types.EQUAL) && left instanceof ClassExpression) {
        ClassExpression ce = (ClassExpression) left;
        String error = "you tried to assign a value to the class '" + ce.getType().getName() + "'";
        if (ce.getType().isScript()) {
            error += ". Do you have a script with this name?";
        }
        addError(error, be.getLeftExpression());
        return be;
    }
    if (left instanceof ClassExpression && isLeftSquareBracket(type)) {
        if (be.getRightExpression() instanceof ListExpression) {
            ListExpression list = (ListExpression) be.getRightExpression();
            if (list.getExpressions().isEmpty()) {
                // we have C[] if the list is empty -> should be an array then!
                final ClassExpression ce = new ClassExpression(left.getType().makeArray());
                ce.setSourcePosition(be);
                return ce;
            } else {
                // may be we have C[k1:v1, k2:v2] -> should become (C)([k1:v1, k2:v2])
                boolean map = true;
                for (Expression expression : list.getExpressions()) {
                    if (!(expression instanceof MapEntryExpression)) {
                        map = false;
                        break;
                    }
                }
                if (map) {
                    final MapExpression me = new MapExpression();
                    for (Expression expression : list.getExpressions()) {
                        me.addMapEntryExpression((MapEntryExpression) transform(expression));
                    }
                    me.setSourcePosition(list);
                    final CastExpression ce = new CastExpression(left.getType(), me);
                    ce.setSourcePosition(be);
                    return ce;
                }
            }
        } else if (be.getRightExpression() instanceof SpreadMapExpression) {
            // we have C[*:map] -> should become (C) map
            SpreadMapExpression mapExpression = (SpreadMapExpression) be.getRightExpression();
            Expression right = transform(mapExpression.getExpression());
            Expression ce = new CastExpression(left.getType(), right);
            ce.setSourcePosition(be);
            return ce;
        }
        if (be.getRightExpression() instanceof MapEntryExpression) {
            // may be we have C[k1:v1] -> should become (C)([k1:v1])
            final MapExpression me = new MapExpression();
            me.addMapEntryExpression((MapEntryExpression) transform(be.getRightExpression()));
            me.setSourcePosition(be.getRightExpression());
            final CastExpression ce = new CastExpression(left.getType(), me);
            ce.setSourcePosition(be);
            return ce;
        }
    }
    Expression right = transform(be.getRightExpression());
    be.setLeftExpression(left);
    be.setRightExpression(right);
    return be;
}
Also used : MapExpression(org.codehaus.groovy.ast.expr.MapExpression) SpreadMapExpression(org.codehaus.groovy.ast.expr.SpreadMapExpression) MapEntryExpression(org.codehaus.groovy.ast.expr.MapEntryExpression) ListExpression(org.codehaus.groovy.ast.expr.ListExpression) MapExpression(org.codehaus.groovy.ast.expr.MapExpression) ConstantExpression(org.codehaus.groovy.ast.expr.ConstantExpression) VariableExpression(org.codehaus.groovy.ast.expr.VariableExpression) BinaryExpression(org.codehaus.groovy.ast.expr.BinaryExpression) CastExpression(org.codehaus.groovy.ast.expr.CastExpression) PropertyExpression(org.codehaus.groovy.ast.expr.PropertyExpression) MethodCallExpression(org.codehaus.groovy.ast.expr.MethodCallExpression) Expression(org.codehaus.groovy.ast.expr.Expression) SpreadMapExpression(org.codehaus.groovy.ast.expr.SpreadMapExpression) ConstructorCallExpression(org.codehaus.groovy.ast.expr.ConstructorCallExpression) AnnotationConstantExpression(org.codehaus.groovy.ast.expr.AnnotationConstantExpression) DeclarationExpression(org.codehaus.groovy.ast.expr.DeclarationExpression) ClosureExpression(org.codehaus.groovy.ast.expr.ClosureExpression) ClassExpression(org.codehaus.groovy.ast.expr.ClassExpression) MapEntryExpression(org.codehaus.groovy.ast.expr.MapEntryExpression) ListExpression(org.codehaus.groovy.ast.expr.ListExpression) ClassExpression(org.codehaus.groovy.ast.expr.ClassExpression) CastExpression(org.codehaus.groovy.ast.expr.CastExpression) SpreadMapExpression(org.codehaus.groovy.ast.expr.SpreadMapExpression)

Aggregations

CastExpression (org.codehaus.groovy.ast.expr.CastExpression)24 ConstantExpression (org.codehaus.groovy.ast.expr.ConstantExpression)18 Expression (org.codehaus.groovy.ast.expr.Expression)16 ArgumentListExpression (org.codehaus.groovy.ast.expr.ArgumentListExpression)15 VariableExpression (org.codehaus.groovy.ast.expr.VariableExpression)14 ClassExpression (org.codehaus.groovy.ast.expr.ClassExpression)12 BinaryExpression (org.codehaus.groovy.ast.expr.BinaryExpression)10 MethodCallExpression (org.codehaus.groovy.ast.expr.MethodCallExpression)10 ExpressionStatement (org.codehaus.groovy.ast.stmt.ExpressionStatement)9 ArrayList (java.util.ArrayList)7 ClassNode (org.codehaus.groovy.ast.ClassNode)7 MethodNode (org.codehaus.groovy.ast.MethodNode)7 BlockStatement (org.codehaus.groovy.ast.stmt.BlockStatement)7 ArrayExpression (org.codehaus.groovy.ast.expr.ArrayExpression)6 ConstructorCallExpression (org.codehaus.groovy.ast.expr.ConstructorCallExpression)6 List (java.util.List)5 Parameter (org.codehaus.groovy.ast.Parameter)5 BooleanExpression (org.codehaus.groovy.ast.expr.BooleanExpression)5 StaticMethodCallExpression (org.codehaus.groovy.ast.expr.StaticMethodCallExpression)5 LinkedList (java.util.LinkedList)4