Search in sources :

Example 6 with ClosureExpression

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

the class MapConstructorASTTransformation method visit.

//    private static final ClassNode CHECK_METHOD_TYPE = make(ImmutableASTTransformation.class);
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;
        boolean includeFields = memberHasValue(anno, "includeFields", true);
        boolean includeProperties = !memberHasValue(anno, "includeProperties", false);
        boolean includeSuperProperties = memberHasValue(anno, "includeSuperProperties", true);
        boolean useSetters = memberHasValue(anno, "useSetters", true);
        List<String> excludes = getMemberStringList(anno, "excludes");
        List<String> includes = getMemberStringList(anno, "includes");
        boolean allNames = memberHasValue(anno, "allNames", true);
        if (!checkIncludeExcludeUndefinedAware(anno, excludes, includes, MY_TYPE_NAME))
            return;
        if (!checkPropertyList(cNode, includes, "includes", anno, MY_TYPE_NAME, includeFields, includeSuperProperties, false))
            return;
        if (!checkPropertyList(cNode, excludes, "excludes", anno, MY_TYPE_NAME, includeFields, includeSuperProperties, false))
            return;
        // if @Immutable is found, let it pick up options and do work so we'll skip
        if (hasAnnotation(cNode, ImmutableASTTransformation.MY_TYPE))
            return;
        Expression pre = anno.getMember("pre");
        if (pre != null && !(pre instanceof ClosureExpression)) {
            addError("Expected closure value for annotation parameter 'pre'. Found " + pre, cNode);
            return;
        }
        Expression post = anno.getMember("post");
        if (post != null && !(post instanceof ClosureExpression)) {
            addError("Expected closure value for annotation parameter 'post'. Found " + post, cNode);
            return;
        }
        createConstructor(cNode, includeFields, includeProperties, includeSuperProperties, useSetters, excludes, includes, (ClosureExpression) pre, (ClosureExpression) post, source, allNames);
        if (pre != null) {
            anno.setMember("pre", new ClosureExpression(new Parameter[0], new EmptyStatement()));
        }
        if (post != null) {
            anno.setMember("post", 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) VariableExpression(org.codehaus.groovy.ast.expr.VariableExpression) ArgumentListExpression(org.codehaus.groovy.ast.expr.ArgumentListExpression) 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 7 with ClosureExpression

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

the class MarkupBuilderCodeTransformer method transformBinaryExpression.

private Expression transformBinaryExpression(final BinaryExpression bin) {
    Expression left = bin.getLeftExpression();
    Expression right = bin.getRightExpression();
    boolean assignment = bin.getOperation().getType() == Types.ASSIGN;
    if (assignment && left instanceof VariableExpression) {
        VariableExpression var = (VariableExpression) left;
        if (var.getAccessedVariable() instanceof DynamicVariable) {
            String varName = var.getName();
            if (!"modelTypes".equals(varName)) {
                MethodCallExpression callGetModel = new MethodCallExpression(new VariableExpression("this"), "getModel", ArgumentListExpression.EMPTY_ARGUMENTS);
                callGetModel.setImplicitThis(true);
                callGetModel.setSourcePosition(left);
                MethodCallExpression mce = new MethodCallExpression(callGetModel, "put", new ArgumentListExpression(new ConstantExpression(varName), right));
                mce.setSourcePosition(left);
                mce.setImplicitThis(false);
                return transform(mce);
            }
        }
    }
    if (assignment && left instanceof VariableExpression && right instanceof ClosureExpression) {
        VariableExpression var = (VariableExpression) left;
        if ("modelTypes".equals(var.getName())) {
            // template declaring its expected types from model directly
            // modelTypes = {
            //  List<String> items
            //  ...
            // }
            Map<String, ClassNode> modelTypes = extractModelTypesFromClosureExpression((ClosureExpression) right);
            Expression result = new EmptyExpression();
            result.setSourcePosition(bin);
            classNode.putNodeMetaData(MarkupTemplateEngine.MODELTYPES_ASTKEY, modelTypes);
            return result;
        }
    }
    return super.transform(bin);
}
Also used : ClassNode(org.codehaus.groovy.ast.ClassNode) MethodCallExpression(org.codehaus.groovy.ast.expr.MethodCallExpression) MapExpression(org.codehaus.groovy.ast.expr.MapExpression) ConstantExpression(org.codehaus.groovy.ast.expr.ConstantExpression) MethodCallExpression(org.codehaus.groovy.ast.expr.MethodCallExpression) EmptyExpression(org.codehaus.groovy.ast.expr.EmptyExpression) Expression(org.codehaus.groovy.ast.expr.Expression) VariableExpression(org.codehaus.groovy.ast.expr.VariableExpression) ArrayExpression(org.codehaus.groovy.ast.expr.ArrayExpression) ArgumentListExpression(org.codehaus.groovy.ast.expr.ArgumentListExpression) DeclarationExpression(org.codehaus.groovy.ast.expr.DeclarationExpression) ClosureExpression(org.codehaus.groovy.ast.expr.ClosureExpression) TupleExpression(org.codehaus.groovy.ast.expr.TupleExpression) BinaryExpression(org.codehaus.groovy.ast.expr.BinaryExpression) GStringExpression(org.codehaus.groovy.ast.expr.GStringExpression) MapEntryExpression(org.codehaus.groovy.ast.expr.MapEntryExpression) DynamicVariable(org.codehaus.groovy.ast.DynamicVariable) ConstantExpression(org.codehaus.groovy.ast.expr.ConstantExpression) ArgumentListExpression(org.codehaus.groovy.ast.expr.ArgumentListExpression) VariableExpression(org.codehaus.groovy.ast.expr.VariableExpression) ClosureExpression(org.codehaus.groovy.ast.expr.ClosureExpression) EmptyExpression(org.codehaus.groovy.ast.expr.EmptyExpression)

Example 8 with ClosureExpression

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

the class MarkupBuilderCodeTransformer method transformMethodCall.

private Expression transformMethodCall(final MethodCallExpression exp) {
    String name = exp.getMethodAsString();
    if (exp.isImplicitThis() && "include".equals(name)) {
        return tryTransformInclude(exp);
    } else if (exp.isImplicitThis() && name.startsWith(":")) {
        List<Expression> args;
        if (exp.getArguments() instanceof ArgumentListExpression) {
            args = ((ArgumentListExpression) exp.getArguments()).getExpressions();
        } else {
            args = Collections.singletonList(exp.getArguments());
        }
        Expression newArguments = transform(new ArgumentListExpression(new ConstantExpression(name.substring(1)), new ArrayExpression(ClassHelper.OBJECT_TYPE, args)));
        MethodCallExpression call = new MethodCallExpression(new VariableExpression("this"), "methodMissing", newArguments);
        call.setImplicitThis(true);
        call.setSafe(exp.isSafe());
        call.setSpreadSafe(exp.isSpreadSafe());
        call.setSourcePosition(exp);
        return call;
    } else if (name != null && name.startsWith("$")) {
        MethodCallExpression reformatted = new MethodCallExpression(exp.getObjectExpression(), name.substring(1), exp.getArguments());
        reformatted.setImplicitThis(exp.isImplicitThis());
        reformatted.setSafe(exp.isSafe());
        reformatted.setSpreadSafe(exp.isSpreadSafe());
        reformatted.setSourcePosition(exp);
        // wrap in a stringOf { ... } closure call
        ClosureExpression clos = new ClosureExpression(Parameter.EMPTY_ARRAY, new ExpressionStatement(reformatted));
        clos.setVariableScope(new VariableScope());
        MethodCallExpression stringOf = new MethodCallExpression(new VariableExpression("this"), "stringOf", clos);
        stringOf.setImplicitThis(true);
        stringOf.setSourcePosition(reformatted);
        return stringOf;
    }
    return super.transform(exp);
}
Also used : MethodCallExpression(org.codehaus.groovy.ast.expr.MethodCallExpression) MapExpression(org.codehaus.groovy.ast.expr.MapExpression) ConstantExpression(org.codehaus.groovy.ast.expr.ConstantExpression) MethodCallExpression(org.codehaus.groovy.ast.expr.MethodCallExpression) EmptyExpression(org.codehaus.groovy.ast.expr.EmptyExpression) Expression(org.codehaus.groovy.ast.expr.Expression) VariableExpression(org.codehaus.groovy.ast.expr.VariableExpression) ArrayExpression(org.codehaus.groovy.ast.expr.ArrayExpression) ArgumentListExpression(org.codehaus.groovy.ast.expr.ArgumentListExpression) DeclarationExpression(org.codehaus.groovy.ast.expr.DeclarationExpression) ClosureExpression(org.codehaus.groovy.ast.expr.ClosureExpression) TupleExpression(org.codehaus.groovy.ast.expr.TupleExpression) BinaryExpression(org.codehaus.groovy.ast.expr.BinaryExpression) GStringExpression(org.codehaus.groovy.ast.expr.GStringExpression) MapEntryExpression(org.codehaus.groovy.ast.expr.MapEntryExpression) ConstantExpression(org.codehaus.groovy.ast.expr.ConstantExpression) ExpressionStatement(org.codehaus.groovy.ast.stmt.ExpressionStatement) ArgumentListExpression(org.codehaus.groovy.ast.expr.ArgumentListExpression) ArrayExpression(org.codehaus.groovy.ast.expr.ArrayExpression) ArrayList(java.util.ArrayList) List(java.util.List) VariableExpression(org.codehaus.groovy.ast.expr.VariableExpression) ClosureExpression(org.codehaus.groovy.ast.expr.ClosureExpression) VariableScope(org.codehaus.groovy.ast.VariableScope)

Example 9 with ClosureExpression

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

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

the class StaticVerifier method visitConstructorOrMethod.

@Override
public void visitConstructorOrMethod(MethodNode node, boolean isConstructor) {
    MethodNode oldCurrentMethod = currentMethod;
    currentMethod = node;
    super.visitConstructorOrMethod(node, isConstructor);
    if (isConstructor) {
        final Set<String> exceptions = new HashSet<String>();
        for (final Parameter param : node.getParameters()) {
            exceptions.add(param.getName());
            if (param.hasInitialExpression()) {
                param.getInitialExpression().visit(new CodeVisitorSupport() {

                    @Override
                    public void visitVariableExpression(VariableExpression ve) {
                        if (exceptions.contains(ve.getName()))
                            return;
                        Variable av = ve.getAccessedVariable();
                        if (av instanceof DynamicVariable || !av.isInStaticContext()) {
                            addVariableError(ve);
                        }
                    }

                    @Override
                    public void visitMethodCallExpression(MethodCallExpression call) {
                        Expression objectExpression = call.getObjectExpression();
                        if (objectExpression instanceof VariableExpression) {
                            VariableExpression ve = (VariableExpression) objectExpression;
                            if (ve.isThisExpression()) {
                                addError("Can't access instance method '" + call.getMethodAsString() + "' for a constructor parameter default value", param);
                                return;
                            }
                        }
                        super.visitMethodCallExpression(call);
                    }

                    @Override
                    public void visitClosureExpression(ClosureExpression expression) {
                    //skip contents, because of dynamic scope
                    }
                });
            }
        }
    }
    currentMethod = oldCurrentMethod;
}
Also used : Variable(org.codehaus.groovy.ast.Variable) DynamicVariable(org.codehaus.groovy.ast.DynamicVariable) VariableExpression(org.codehaus.groovy.ast.expr.VariableExpression) CodeVisitorSupport(org.codehaus.groovy.ast.CodeVisitorSupport) ClassCodeVisitorSupport(org.codehaus.groovy.ast.ClassCodeVisitorSupport) MethodNode(org.codehaus.groovy.ast.MethodNode) MethodCallExpression(org.codehaus.groovy.ast.expr.MethodCallExpression) DynamicVariable(org.codehaus.groovy.ast.DynamicVariable) 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) MethodCallExpression(org.codehaus.groovy.ast.expr.MethodCallExpression) Expression(org.codehaus.groovy.ast.expr.Expression) Parameter(org.codehaus.groovy.ast.Parameter) ClosureExpression(org.codehaus.groovy.ast.expr.ClosureExpression) HashSet(java.util.HashSet)

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