Search in sources :

Example 86 with ArgumentListExpression

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

the class Verifier method addDefaultParameterMethods.

/**
     * Creates a new helper method for each combination of default parameter expressions
     */
protected void addDefaultParameterMethods(final ClassNode node) {
    List methods = new ArrayList(node.getMethods());
    addDefaultParameters(methods, new DefaultArgsAction() {

        public void call(ArgumentListExpression arguments, Parameter[] newParams, MethodNode method) {
            final BlockStatement code = new BlockStatement();
            MethodNode newMethod = new MethodNode(method.getName(), method.getModifiers(), method.getReturnType(), newParams, method.getExceptions(), code);
            // GROOVY-5681 and GROOVY-5632
            for (Expression argument : arguments.getExpressions()) {
                if (argument instanceof CastExpression) {
                    argument = ((CastExpression) argument).getExpression();
                }
                if (argument instanceof ConstructorCallExpression) {
                    ClassNode type = argument.getType();
                    if (type instanceof InnerClassNode && ((InnerClassNode) type).isAnonymous()) {
                        type.setEnclosingMethod(newMethod);
                    }
                }
                // check whether closure shared variables refer to params with default values (GROOVY-5632)
                if (argument instanceof ClosureExpression) {
                    final List<Parameter> newMethodNodeParameters = Arrays.asList(newParams);
                    CodeVisitorSupport visitor = new CodeVisitorSupport() {

                        @Override
                        public void visitVariableExpression(VariableExpression expression) {
                            Variable v = expression.getAccessedVariable();
                            if (!(v instanceof Parameter))
                                return;
                            Parameter param = (Parameter) v;
                            if (param.hasInitialExpression() && code.getVariableScope().getDeclaredVariable(param.getName()) == null && !newMethodNodeParameters.contains(param)) {
                                VariableExpression localVariable = new VariableExpression(param.getName(), ClassHelper.makeReference());
                                DeclarationExpression declarationExpression = new DeclarationExpression(localVariable, Token.newSymbol(Types.EQUAL, -1, -1), new ConstructorCallExpression(ClassHelper.makeReference(), param.getInitialExpression()));
                                code.addStatement(new ExpressionStatement(declarationExpression));
                                code.getVariableScope().putDeclaredVariable(localVariable);
                            }
                        }
                    };
                    visitor.visitClosureExpression((ClosureExpression) argument);
                }
            }
            MethodCallExpression expression = new MethodCallExpression(VariableExpression.THIS_EXPRESSION, method.getName(), arguments);
            expression.setMethodTarget(method);
            expression.setImplicitThis(true);
            if (method.isVoidMethod()) {
                code.addStatement(new ExpressionStatement(expression));
            } else {
                code.addStatement(new ReturnStatement(expression));
            }
            List<AnnotationNode> annotations = method.getAnnotations();
            if (annotations != null) {
                newMethod.addAnnotations(annotations);
            }
            MethodNode oldMethod = node.getDeclaredMethod(method.getName(), newParams);
            if (oldMethod != null) {
                throw new RuntimeParserException("The method with default parameters \"" + method.getTypeDescriptor() + "\" defines a method \"" + newMethod.getTypeDescriptor() + "\" that is already defined.", method);
            }
            addPropertyMethod(newMethod);
            newMethod.setGenericsTypes(method.getGenericsTypes());
            newMethod.putNodeMetaData(DEFAULT_PARAMETER_GENERATED, true);
        }
    });
}
Also used : ConstructorCallExpression(org.codehaus.groovy.ast.expr.ConstructorCallExpression) DeclarationExpression(org.codehaus.groovy.ast.expr.DeclarationExpression) ArrayList(java.util.ArrayList) ArgumentListExpression(org.codehaus.groovy.ast.expr.ArgumentListExpression) BlockStatement(org.codehaus.groovy.ast.stmt.BlockStatement) VariableExpression(org.codehaus.groovy.ast.expr.VariableExpression) MethodCallExpression(org.codehaus.groovy.ast.expr.MethodCallExpression) ConstantExpression(org.codehaus.groovy.ast.expr.ConstantExpression) VariableExpression(org.codehaus.groovy.ast.expr.VariableExpression) ArgumentListExpression(org.codehaus.groovy.ast.expr.ArgumentListExpression) BinaryExpression(org.codehaus.groovy.ast.expr.BinaryExpression) FieldExpression(org.codehaus.groovy.ast.expr.FieldExpression) CastExpression(org.codehaus.groovy.ast.expr.CastExpression) MethodCallExpression(org.codehaus.groovy.ast.expr.MethodCallExpression) Expression(org.codehaus.groovy.ast.expr.Expression) ConstructorCallExpression(org.codehaus.groovy.ast.expr.ConstructorCallExpression) DeclarationExpression(org.codehaus.groovy.ast.expr.DeclarationExpression) ClosureExpression(org.codehaus.groovy.ast.expr.ClosureExpression) ExpressionStatement(org.codehaus.groovy.ast.stmt.ExpressionStatement) ReturnStatement(org.codehaus.groovy.ast.stmt.ReturnStatement) List(java.util.List) ArrayList(java.util.ArrayList) CastExpression(org.codehaus.groovy.ast.expr.CastExpression) ClosureExpression(org.codehaus.groovy.ast.expr.ClosureExpression) RuntimeParserException(org.codehaus.groovy.syntax.RuntimeParserException)

Example 87 with ArgumentListExpression

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

the class JavaStubGenerator method printSpecialConstructorArgs.

private void printSpecialConstructorArgs(PrintWriter out, ConstructorNode node, ConstructorCallExpression constrCall) {
    // Select a constructor from our class, or super-class which is legal to call,
    // then write out an invoke w/nulls using casts to avoid ambiguous crapo
    Parameter[] params = selectAccessibleConstructorFromSuper(node);
    if (params != null) {
        out.print("super (");
        for (int i = 0; i < params.length; i++) {
            printDefaultValue(out, params[i].getType());
            if (i + 1 < params.length) {
                out.print(", ");
            }
        }
        out.println(");");
        return;
    }
    // Otherwise try the older method based on the constructor's call expression
    Expression arguments = constrCall.getArguments();
    if (constrCall.isSuperCall()) {
        out.print("super(");
    } else {
        out.print("this(");
    }
    // Else try to render some arguments
    if (arguments instanceof ArgumentListExpression) {
        ArgumentListExpression argumentListExpression = (ArgumentListExpression) arguments;
        List<Expression> args = argumentListExpression.getExpressions();
        for (Expression arg : args) {
            if (arg instanceof ConstantExpression) {
                ConstantExpression expression = (ConstantExpression) arg;
                Object o = expression.getValue();
                if (o instanceof String) {
                    out.print("(String)null");
                } else {
                    out.print(expression.getText());
                }
            } else {
                ClassNode type = getConstructorArgumentType(arg, node);
                printDefaultValue(out, type);
            }
            if (arg != args.get(args.size() - 1)) {
                out.print(", ");
            }
        }
    }
    out.println(");");
}
Also used : ListExpression(org.codehaus.groovy.ast.expr.ListExpression) PropertyExpression(org.codehaus.groovy.ast.expr.PropertyExpression) ConstantExpression(org.codehaus.groovy.ast.expr.ConstantExpression) 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) ConstantExpression(org.codehaus.groovy.ast.expr.ConstantExpression) ArgumentListExpression(org.codehaus.groovy.ast.expr.ArgumentListExpression)

Example 88 with ArgumentListExpression

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

the class TraitASTTransformation method processField.

private void processField(final FieldNode field, final MethodNode initializer, final MethodNode staticInitializer, final ClassNode fieldHelper, final ClassNode helper, final ClassNode trait, final Set<String> knownFields) {
    if (field.isProtected()) {
        unit.addError(new SyntaxException("Cannot have protected field in a trait (" + trait.getName() + "#" + field.getName() + ")", field.getLineNumber(), field.getColumnNumber()));
        return;
    }
    Expression initialExpression = field.getInitialExpression();
    MethodNode selectedMethod = field.isStatic() ? staticInitializer : initializer;
    if (initialExpression != null) {
        if (field.isFinal()) {
            String baseName = field.isStatic() ? Traits.STATIC_INIT_METHOD : Traits.INIT_METHOD;
            MethodNode fieldInitializer = new MethodNode(baseName + Traits.remappedFieldName(trait, field.getName()), ACC_STATIC | ACC_PUBLIC | ACC_SYNTHETIC, field.getOriginType(), Parameter.EMPTY_ARRAY, ClassNode.EMPTY_ARRAY, returnS(initialExpression));
            helper.addMethod(fieldInitializer);
        }
        VariableExpression thisObject = new VariableExpression(selectedMethod.getParameters()[0]);
        ExpressionStatement initCode = new ExpressionStatement(initialExpression);
        processBody(thisObject, initCode, trait, helper, fieldHelper, knownFields);
        BlockStatement code = (BlockStatement) selectedMethod.getCode();
        MethodCallExpression mce;
        if (field.isStatic()) {
            mce = new MethodCallExpression(new ClassExpression(INVOKERHELPER_CLASSNODE), "invokeStaticMethod", new ArgumentListExpression(thisObject, new ConstantExpression(Traits.helperSetterName(field)), initCode.getExpression()));
        } else {
            mce = new MethodCallExpression(new CastExpression(createReceiverType(field.isStatic(), fieldHelper), thisObject), Traits.helperSetterName(field), new CastExpression(field.getOriginType(), initCode.getExpression()));
        }
        mce.setImplicitThis(false);
        mce.setSourcePosition(initialExpression);
        code.addStatement(new ExpressionStatement(mce));
    }
    // define setter/getter helper methods (setter added even for final fields for legacy compatibility)
    fieldHelper.addMethod(Traits.helperSetterName(field), ACC_PUBLIC | ACC_ABSTRACT, field.getOriginType(), new Parameter[] { new Parameter(field.getOriginType(), "val") }, ClassNode.EMPTY_ARRAY, null);
    fieldHelper.addMethod(Traits.helperGetterName(field), ACC_PUBLIC | ACC_ABSTRACT, field.getOriginType(), Parameter.EMPTY_ARRAY, ClassNode.EMPTY_ARRAY, null);
    // dummy fields are only used to carry annotations if instance field
    // and to differentiate from static fields otherwise
    int mods = field.getModifiers() & Traits.FIELD_PREFIX_MASK;
    String dummyFieldName = String.format("$0x%04x", mods) + Traits.remappedFieldName(field.getOwner(), field.getName());
    FieldNode dummyField = new FieldNode(dummyFieldName, ACC_STATIC | ACC_PUBLIC | ACC_FINAL | ACC_SYNTHETIC, field.getOriginType(), fieldHelper, field.isFinal() ? initialExpression : null);
    // copy annotations from field to dummy field
    List<AnnotationNode> copied = new LinkedList<AnnotationNode>();
    List<AnnotationNode> notCopied = new LinkedList<AnnotationNode>();
    GeneralUtils.copyAnnotatedNodeAnnotations(field, copied, notCopied);
    dummyField.addAnnotations(copied);
    fieldHelper.addField(dummyField);
    // retain legacy field (will be given lower precedence than above)
    dummyFieldName = (field.isStatic() ? Traits.STATIC_FIELD_PREFIX : Traits.FIELD_PREFIX) + (field.isPublic() ? Traits.PUBLIC_FIELD_PREFIX : Traits.PRIVATE_FIELD_PREFIX) + Traits.remappedFieldName(field.getOwner(), field.getName());
    dummyField = new FieldNode(dummyFieldName, ACC_STATIC | ACC_PUBLIC | ACC_FINAL | ACC_SYNTHETIC, field.getOriginType(), fieldHelper, null);
    // copy annotations from field to legacy dummy field
    copied = new LinkedList<AnnotationNode>();
    notCopied = new LinkedList<AnnotationNode>();
    GeneralUtils.copyAnnotatedNodeAnnotations(field, copied, notCopied);
    dummyField.addAnnotations(copied);
    fieldHelper.addField(dummyField);
}
Also used : FieldNode(org.codehaus.groovy.ast.FieldNode) ConstantExpression(org.codehaus.groovy.ast.expr.ConstantExpression) ArgumentListExpression(org.codehaus.groovy.ast.expr.ArgumentListExpression) VariableExpression(org.codehaus.groovy.ast.expr.VariableExpression) BlockStatement(org.codehaus.groovy.ast.stmt.BlockStatement) ClassExpression(org.codehaus.groovy.ast.expr.ClassExpression) LinkedList(java.util.LinkedList) MethodNode(org.codehaus.groovy.ast.MethodNode) MethodCallExpression(org.codehaus.groovy.ast.expr.MethodCallExpression) ConstantExpression(org.codehaus.groovy.ast.expr.ConstantExpression) VariableExpression(org.codehaus.groovy.ast.expr.VariableExpression) ArgumentListExpression(org.codehaus.groovy.ast.expr.ArgumentListExpression) BinaryExpression(org.codehaus.groovy.ast.expr.BinaryExpression) FieldExpression(org.codehaus.groovy.ast.expr.FieldExpression) CastExpression(org.codehaus.groovy.ast.expr.CastExpression) 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) SyntaxException(org.codehaus.groovy.syntax.SyntaxException) ExpressionStatement(org.codehaus.groovy.ast.stmt.ExpressionStatement) Parameter(org.codehaus.groovy.ast.Parameter) CastExpression(org.codehaus.groovy.ast.expr.CastExpression)

Example 89 with ArgumentListExpression

use of org.codehaus.groovy.ast.expr.ArgumentListExpression 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 90 with ArgumentListExpression

use of org.codehaus.groovy.ast.expr.ArgumentListExpression 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)

Aggregations

ArgumentListExpression (org.codehaus.groovy.ast.expr.ArgumentListExpression)108 MethodCallExpression (org.codehaus.groovy.ast.expr.MethodCallExpression)73 VariableExpression (org.codehaus.groovy.ast.expr.VariableExpression)72 ConstantExpression (org.codehaus.groovy.ast.expr.ConstantExpression)66 Expression (org.codehaus.groovy.ast.expr.Expression)61 ClassExpression (org.codehaus.groovy.ast.expr.ClassExpression)50 BinaryExpression (org.codehaus.groovy.ast.expr.BinaryExpression)49 ClassNode (org.codehaus.groovy.ast.ClassNode)38 ExpressionStatement (org.codehaus.groovy.ast.stmt.ExpressionStatement)38 ConstructorCallExpression (org.codehaus.groovy.ast.expr.ConstructorCallExpression)36 ClosureExpression (org.codehaus.groovy.ast.expr.ClosureExpression)34 StaticMethodCallExpression (org.codehaus.groovy.ast.expr.StaticMethodCallExpression)33 TupleExpression (org.codehaus.groovy.ast.expr.TupleExpression)32 BooleanExpression (org.codehaus.groovy.ast.expr.BooleanExpression)28 DeclarationExpression (org.codehaus.groovy.ast.expr.DeclarationExpression)28 BlockStatement (org.codehaus.groovy.ast.stmt.BlockStatement)28 PropertyExpression (org.codehaus.groovy.ast.expr.PropertyExpression)27 CastExpression (org.codehaus.groovy.ast.expr.CastExpression)26 MethodNode (org.codehaus.groovy.ast.MethodNode)23 ReturnStatement (org.codehaus.groovy.ast.stmt.ReturnStatement)22