Search in sources :

Example 11 with ClosureExpression

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

the class AutoImplementASTTransformation method visit.

public void visit(ASTNode[] nodes, SourceUnit source) {
    init(nodes, source);
    AnnotatedNode parent = (AnnotatedNode) nodes[1];
    AnnotationNode anno = (AnnotationNode) nodes[0];
    if (!MY_TYPE.equals(anno.getClassNode()))
        return;
    if (parent instanceof ClassNode) {
        ClassNode cNode = (ClassNode) parent;
        if (!checkNotInterface(cNode, MY_TYPE_NAME))
            return;
        ClassNode exception = getMemberClassValue(anno, "exception");
        if (exception != null && Undefined.isUndefinedException(exception)) {
            exception = null;
        }
        String message = getMemberStringValue(anno, "message");
        Expression code = anno.getMember("code");
        if (code != null && !(code instanceof ClosureExpression)) {
            addError("Expected closure value for annotation parameter 'code'. Found " + code, cNode);
            return;
        }
        createMethods(cNode, exception, message, (ClosureExpression) code);
        if (code != null) {
            anno.setMember("code", new ClosureExpression(new Parameter[0], new EmptyStatement()));
        }
    }
}
Also used : ClassNode(org.codehaus.groovy.ast.ClassNode) AnnotationNode(org.codehaus.groovy.ast.AnnotationNode) Expression(org.codehaus.groovy.ast.expr.Expression) ClosureExpression(org.codehaus.groovy.ast.expr.ClosureExpression) AnnotatedNode(org.codehaus.groovy.ast.AnnotatedNode) EmptyStatement(org.codehaus.groovy.ast.stmt.EmptyStatement) Parameter(org.codehaus.groovy.ast.Parameter) ClosureExpression(org.codehaus.groovy.ast.expr.ClosureExpression)

Example 12 with ClosureExpression

use of org.codehaus.groovy.ast.expr.ClosureExpression in project spock by spockframework.

the class AbstractDeepBlockRewriter method visitClosureExpression.

@Override
public final void visitClosureExpression(ClosureExpression expr) {
    ClosureExpression oldClosure = currClosure;
    currClosure = expr;
    boolean oldConditionFound = conditionFound;
    boolean oldGroupConditionFound = groupConditionFound;
    // any closure terminates conditionFound scope
    conditionFound = false;
    groupConditionFound = false;
    ISpecialMethodCall oldSpecialMethodCall = currSpecialMethodCall;
    if (!currSpecialMethodCall.isMatch(expr)) {
        // unrelated closure terminates currSpecialMethodCall scope
        currSpecialMethodCall = NoSpecialMethodCall.INSTANCE;
    }
    try {
        doVisitClosureExpression(expr);
    } finally {
        currClosure = oldClosure;
        conditionFound = oldConditionFound;
        groupConditionFound = oldGroupConditionFound;
        currSpecialMethodCall = oldSpecialMethodCall;
    }
}
Also used : ClosureExpression(org.codehaus.groovy.ast.expr.ClosureExpression)

Example 13 with ClosureExpression

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

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 14 with ClosureExpression

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

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());
        }
    });
}
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) 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) DeclarationExpression(org.codehaus.groovy.ast.expr.DeclarationExpression) ClosureExpression(org.codehaus.groovy.ast.expr.ClosureExpression) BinaryExpression(org.codehaus.groovy.ast.expr.BinaryExpression) FieldExpression(org.codehaus.groovy.ast.expr.FieldExpression) CastExpression(org.codehaus.groovy.ast.expr.CastExpression) ExpressionStatement(org.codehaus.groovy.ast.stmt.ExpressionStatement) ReturnStatement(org.codehaus.groovy.ast.stmt.ReturnStatement) ArrayList(java.util.ArrayList) List(java.util.List) CastExpression(org.codehaus.groovy.ast.expr.CastExpression) ClosureExpression(org.codehaus.groovy.ast.expr.ClosureExpression) RuntimeParserException(org.codehaus.groovy.syntax.RuntimeParserException)

Example 15 with ClosureExpression

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

the class DelegateAsyncTransformation method applyDelegateAsyncTransform.

private void applyDelegateAsyncTransform(ClassNode classNode, ClassNode targetApi, String fieldName) {
    List<MethodNode> methods = targetApi.getAllDeclaredMethods();
    ClassNode promisesClass = ClassHelper.make(Promises.class).getPlainNodeReference();
    MethodNode createPromiseMethodTargetWithDecorators = promisesClass.getDeclaredMethod("createPromise", new Parameter[] { new Parameter(new ClassNode(Closure.class), "c"), new Parameter(new ClassNode(List.class), "c") });
    DelegateAsyncTransactionalMethodTransformer delegateAsyncTransactionalMethodTransformer = lookupAsyncTransactionalMethodTransformer();
    for (MethodNode m : methods) {
        if (isCandidateMethod(m)) {
            MethodNode existingMethod = classNode.getMethod(m.getName(), m.getParameters());
            if (existingMethod == null) {
                ClassNode promiseNode = ClassHelper.make(Promise.class).getPlainNodeReference();
                ClassNode originalReturnType = m.getReturnType();
                if (!originalReturnType.getNameWithoutPackage().equals(VOID)) {
                    ClassNode returnType;
                    if (ClassHelper.isPrimitiveType(originalReturnType.redirect())) {
                        returnType = ClassHelper.getWrapper(originalReturnType.redirect());
                    } else {
                        returnType = alignReturnType(classNode, originalReturnType);
                    }
                    if (!OBJECT_CLASS_NODE.equals(returnType)) {
                        promiseNode.setGenericsTypes(new GenericsType[] { new GenericsType(returnType) });
                    }
                }
                final BlockStatement methodBody = new BlockStatement();
                final BlockStatement promiseBody = new BlockStatement();
                final ClosureExpression closureExpression = new ClosureExpression(new Parameter[0], promiseBody);
                VariableScope variableScope = new VariableScope();
                closureExpression.setVariableScope(variableScope);
                VariableExpression thisObject = new VariableExpression("this");
                ClassNode delegateAsyncUtilsClassNode = new ClassNode(DelegateAsyncUtils.class);
                MethodNode getPromiseDecoratorsMethodNode = delegateAsyncUtilsClassNode.getDeclaredMethods("getPromiseDecorators").get(0);
                ListExpression promiseDecorators = new ListExpression();
                ArgumentListExpression getPromiseDecoratorsArguments = new ArgumentListExpression(thisObject, promiseDecorators);
                delegateAsyncTransactionalMethodTransformer.transformTransactionalMethod(classNode, targetApi, m, promiseDecorators);
                MethodCallExpression getDecoratorsMethodCall = new MethodCallExpression(new ClassExpression(delegateAsyncUtilsClassNode), "getPromiseDecorators", getPromiseDecoratorsArguments);
                getDecoratorsMethodCall.setMethodTarget(getPromiseDecoratorsMethodNode);
                MethodCallExpression createPromiseWithDecorators = new MethodCallExpression(new ClassExpression(promisesClass), "createPromise", new ArgumentListExpression(closureExpression, getDecoratorsMethodCall));
                if (createPromiseMethodTargetWithDecorators != null) {
                    createPromiseWithDecorators.setMethodTarget(createPromiseMethodTargetWithDecorators);
                }
                methodBody.addStatement(new ExpressionStatement(createPromiseWithDecorators));
                final ArgumentListExpression arguments = new ArgumentListExpression();
                Parameter[] parameters = copyParameters(StaticTypeCheckingSupport.parameterizeArguments(classNode, m));
                for (Parameter p : parameters) {
                    p.setClosureSharedVariable(true);
                    variableScope.putReferencedLocalVariable(p);
                    VariableExpression ve = new VariableExpression(p);
                    ve.setClosureSharedVariable(true);
                    arguments.addExpression(ve);
                }
                MethodCallExpression delegateMethodCall = new MethodCallExpression(new VariableExpression(fieldName), m.getName(), arguments);
                promiseBody.addStatement(new ExpressionStatement(delegateMethodCall));
                MethodNode newMethodNode = new MethodNode(m.getName(), Modifier.PUBLIC, promiseNode, parameters, null, methodBody);
                classNode.addMethod(newMethodNode);
            }
        }
    }
}
Also used : ClassNode(org.codehaus.groovy.ast.ClassNode) Promises(grails.async.Promises) ListExpression(org.codehaus.groovy.ast.expr.ListExpression) ArgumentListExpression(org.codehaus.groovy.ast.expr.ArgumentListExpression) ArgumentListExpression(org.codehaus.groovy.ast.expr.ArgumentListExpression) BlockStatement(org.codehaus.groovy.ast.stmt.BlockStatement) VariableExpression(org.codehaus.groovy.ast.expr.VariableExpression) ClassExpression(org.codehaus.groovy.ast.expr.ClassExpression) Promise(grails.async.Promise) MethodNode(org.codehaus.groovy.ast.MethodNode) MethodCallExpression(org.codehaus.groovy.ast.expr.MethodCallExpression) ExpressionStatement(org.codehaus.groovy.ast.stmt.ExpressionStatement) GenericsType(org.codehaus.groovy.ast.GenericsType) Parameter(org.codehaus.groovy.ast.Parameter) ClosureExpression(org.codehaus.groovy.ast.expr.ClosureExpression) VariableScope(org.codehaus.groovy.ast.VariableScope)

Aggregations

ClosureExpression (org.codehaus.groovy.ast.expr.ClosureExpression)50 Expression (org.codehaus.groovy.ast.expr.Expression)39 VariableExpression (org.codehaus.groovy.ast.expr.VariableExpression)34 MethodCallExpression (org.codehaus.groovy.ast.expr.MethodCallExpression)33 ConstantExpression (org.codehaus.groovy.ast.expr.ConstantExpression)31 ArgumentListExpression (org.codehaus.groovy.ast.expr.ArgumentListExpression)28 ClassExpression (org.codehaus.groovy.ast.expr.ClassExpression)21 ClassNode (org.codehaus.groovy.ast.ClassNode)18 BlockStatement (org.codehaus.groovy.ast.stmt.BlockStatement)18 PropertyExpression (org.codehaus.groovy.ast.expr.PropertyExpression)17 BinaryExpression (org.codehaus.groovy.ast.expr.BinaryExpression)16 ConstructorCallExpression (org.codehaus.groovy.ast.expr.ConstructorCallExpression)16 DeclarationExpression (org.codehaus.groovy.ast.expr.DeclarationExpression)16 Parameter (org.codehaus.groovy.ast.Parameter)15 TupleExpression (org.codehaus.groovy.ast.expr.TupleExpression)15 ExpressionStatement (org.codehaus.groovy.ast.stmt.ExpressionStatement)13 FieldNode (org.codehaus.groovy.ast.FieldNode)10 ListExpression (org.codehaus.groovy.ast.expr.ListExpression)10 ArrayList (java.util.ArrayList)9 DynamicVariable (org.codehaus.groovy.ast.DynamicVariable)9