Search in sources :

Example 91 with ExpressionStatement

use of org.codehaus.groovy.ast.stmt.ExpressionStatement in project groovy-core by groovy.

the class StaticCompilationVisitor method addPrivateBridgeMethods.

/**
     * This method is used to add "bridge" methods for private methods of an inner/outer
     * class, so that the outer class is capable of calling them. It does basically
     * the same job as access$000 like methods in Java.
     *
     * @param node an inner/outer class node for which to generate bridge methods
     */
@SuppressWarnings("unchecked")
private void addPrivateBridgeMethods(final ClassNode node) {
    Set<ASTNode> accessedMethods = (Set<ASTNode>) node.getNodeMetaData(StaticTypesMarker.PV_METHODS_ACCESS);
    if (accessedMethods == null)
        return;
    List<MethodNode> methods = new ArrayList<MethodNode>(node.getAllDeclaredMethods());
    Map<MethodNode, MethodNode> privateBridgeMethods = (Map<MethodNode, MethodNode>) node.getNodeMetaData(PRIVATE_BRIDGE_METHODS);
    if (privateBridgeMethods != null) {
        // private bridge methods already added
        return;
    }
    privateBridgeMethods = new HashMap<MethodNode, MethodNode>();
    int i = -1;
    final int access = Opcodes.ACC_STATIC | Opcodes.ACC_PUBLIC | Opcodes.ACC_SYNTHETIC;
    for (MethodNode method : methods) {
        if (accessedMethods.contains(method)) {
            List<String> methodSpecificGenerics = methodSpecificGenerics(method);
            i++;
            ClassNode declaringClass = method.getDeclaringClass();
            Map<String, ClassNode> genericsSpec = createGenericsSpec(node);
            genericsSpec = addMethodGenerics(method, genericsSpec);
            extractSuperClassGenerics(node, declaringClass, genericsSpec);
            Parameter[] methodParameters = method.getParameters();
            Parameter[] newParams = new Parameter[methodParameters.length + 1];
            for (int j = 1; j < newParams.length; j++) {
                Parameter orig = methodParameters[j - 1];
                newParams[j] = new Parameter(correctToGenericsSpecRecurse(genericsSpec, orig.getOriginType(), methodSpecificGenerics), orig.getName());
            }
            newParams[0] = new Parameter(node.getPlainNodeReference(), "$that");
            Expression arguments;
            if (method.getParameters() == null || method.getParameters().length == 0) {
                arguments = ArgumentListExpression.EMPTY_ARGUMENTS;
            } else {
                List<Expression> args = new LinkedList<Expression>();
                for (Parameter parameter : methodParameters) {
                    args.add(new VariableExpression(parameter));
                }
                arguments = new ArgumentListExpression(args);
            }
            Expression receiver = method.isStatic() ? new ClassExpression(node) : new VariableExpression(newParams[0]);
            MethodCallExpression mce = new MethodCallExpression(receiver, method.getName(), arguments);
            mce.setMethodTarget(method);
            ExpressionStatement returnStatement = new ExpressionStatement(mce);
            MethodNode bridge = node.addMethod("access$" + i, access, correctToGenericsSpecRecurse(genericsSpec, method.getReturnType(), methodSpecificGenerics), newParams, method.getExceptions(), returnStatement);
            GenericsType[] origGenericsTypes = method.getGenericsTypes();
            if (origGenericsTypes != null) {
                bridge.setGenericsTypes(applyGenericsContextToPlaceHolders(genericsSpec, origGenericsTypes));
            }
            privateBridgeMethods.put(method, bridge);
            bridge.addAnnotation(new AnnotationNode(COMPILESTATIC_CLASSNODE));
        }
    }
    if (!privateBridgeMethods.isEmpty()) {
        node.setNodeMetaData(PRIVATE_BRIDGE_METHODS, privateBridgeMethods);
    }
}
Also used : ExpressionStatement(org.codehaus.groovy.ast.stmt.ExpressionStatement)

Example 92 with ExpressionStatement

use of org.codehaus.groovy.ast.stmt.ExpressionStatement in project groovy-core by groovy.

the class CategoryASTTransformation method visit.

/**
     * Property invocations done on 'this' reference are transformed so that the invocations at runtime are
     * done on the additional parameter 'self'
     */
public void visit(ASTNode[] nodes, final SourceUnit source) {
    if (nodes.length != 2 || !(nodes[0] instanceof AnnotationNode) || !(nodes[1] instanceof ClassNode)) {
        source.getErrorCollector().addError(new SyntaxErrorMessage(new SyntaxException("@Category can only be added to a ClassNode but got: " + (nodes.length == 2 ? nodes[1] : "nothing"), nodes[0].getLineNumber(), nodes[0].getColumnNumber()), source));
    }
    AnnotationNode annotation = (AnnotationNode) nodes[0];
    ClassNode parent = (ClassNode) nodes[1];
    ClassNode targetClass = getTargetClass(source, annotation);
    thisExpression.setType(targetClass);
    final LinkedList<Set<String>> varStack = new LinkedList<Set<String>>();
    if (!ensureNoInstanceFieldOrProperty(source, parent))
        return;
    Set<String> names = new HashSet<String>();
    for (FieldNode field : parent.getFields()) {
        names.add(field.getName());
    }
    for (PropertyNode field : parent.getProperties()) {
        names.add(field.getName());
    }
    varStack.add(names);
    final Reference parameter = new Reference();
    final ClassCodeExpressionTransformer expressionTransformer = new ClassCodeExpressionTransformer() {

        protected SourceUnit getSourceUnit() {
            return source;
        }

        private void addVariablesToStack(Parameter[] params) {
            Set<String> names = new HashSet<String>();
            names.addAll(varStack.getLast());
            for (Parameter param : params) {
                names.add(param.getName());
            }
            varStack.add(names);
        }

        @Override
        public void visitCatchStatement(CatchStatement statement) {
            varStack.getLast().add(statement.getVariable().getName());
            super.visitCatchStatement(statement);
            varStack.getLast().remove(statement.getVariable().getName());
        }

        @Override
        public void visitMethod(MethodNode node) {
            addVariablesToStack(node.getParameters());
            super.visitMethod(node);
            varStack.removeLast();
        }

        @Override
        public void visitBlockStatement(BlockStatement block) {
            Set<String> names = new HashSet<String>();
            names.addAll(varStack.getLast());
            varStack.add(names);
            super.visitBlockStatement(block);
            varStack.remove(names);
        }

        @Override
        public void visitClosureExpression(ClosureExpression ce) {
            addVariablesToStack(ce.getParameters());
            super.visitClosureExpression(ce);
            varStack.removeLast();
        }

        @Override
        public void visitDeclarationExpression(DeclarationExpression expression) {
            if (expression.isMultipleAssignmentDeclaration()) {
                TupleExpression te = expression.getTupleExpression();
                List<Expression> list = te.getExpressions();
                for (Expression arg : list) {
                    VariableExpression ve = (VariableExpression) arg;
                    varStack.getLast().add(ve.getName());
                }
            } else {
                VariableExpression ve = expression.getVariableExpression();
                varStack.getLast().add(ve.getName());
            }
            super.visitDeclarationExpression(expression);
        }

        @Override
        public void visitForLoop(ForStatement forLoop) {
            Expression exp = forLoop.getCollectionExpression();
            exp.visit(this);
            Parameter loopParam = forLoop.getVariable();
            if (loopParam != null) {
                varStack.getLast().add(loopParam.getName());
            }
            super.visitForLoop(forLoop);
        }

        @Override
        public void visitExpressionStatement(ExpressionStatement es) {
            // GROOVY-3543: visit the declaration expressions so that declaration variables get added on the varStack
            Expression exp = es.getExpression();
            if (exp instanceof DeclarationExpression) {
                exp.visit(this);
            }
            super.visitExpressionStatement(es);
        }

        @Override
        public Expression transform(Expression exp) {
            if (exp instanceof VariableExpression) {
                VariableExpression ve = (VariableExpression) exp;
                if (ve.getName().equals("this"))
                    return thisExpression;
                else {
                    if (!varStack.getLast().contains(ve.getName())) {
                        return new PropertyExpression(thisExpression, ve.getName());
                    }
                }
            } else if (exp instanceof PropertyExpression) {
                PropertyExpression pe = (PropertyExpression) exp;
                if (pe.getObjectExpression() instanceof VariableExpression) {
                    VariableExpression vex = (VariableExpression) pe.getObjectExpression();
                    if (vex.isThisExpression()) {
                        pe.setObjectExpression(thisExpression);
                        return pe;
                    }
                }
            } else if (exp instanceof ClosureExpression) {
                ClosureExpression ce = (ClosureExpression) exp;
                ce.getVariableScope().putReferencedLocalVariable((Parameter) parameter.get());
                Parameter[] params = ce.getParameters();
                if (params == null) {
                    params = Parameter.EMPTY_ARRAY;
                } else if (params.length == 0) {
                    params = new Parameter[] { new Parameter(ClassHelper.OBJECT_TYPE, "it") };
                }
                addVariablesToStack(params);
                ce.getCode().visit(this);
                varStack.removeLast();
            }
            return super.transform(exp);
        }
    };
    for (MethodNode method : parent.getMethods()) {
        if (!method.isStatic()) {
            method.setModifiers(method.getModifiers() | Opcodes.ACC_STATIC);
            final Parameter[] origParams = method.getParameters();
            final Parameter[] newParams = new Parameter[origParams.length + 1];
            Parameter p = new Parameter(targetClass, "$this");
            p.setClosureSharedVariable(true);
            newParams[0] = p;
            parameter.set(p);
            System.arraycopy(origParams, 0, newParams, 1, origParams.length);
            method.setParameters(newParams);
            expressionTransformer.visitMethod(method);
        }
    }
    new VariableScopeVisitor(source, true).visitClass(parent);
}
Also used : HashSet(java.util.HashSet) Set(java.util.Set) TupleExpression(org.codehaus.groovy.ast.expr.TupleExpression) BlockStatement(org.codehaus.groovy.ast.stmt.BlockStatement) MethodNode(org.codehaus.groovy.ast.MethodNode) AnnotationNode(org.codehaus.groovy.ast.AnnotationNode) SyntaxException(org.codehaus.groovy.syntax.SyntaxException) PropertyNode(org.codehaus.groovy.ast.PropertyNode) PropertyExpression(org.codehaus.groovy.ast.expr.PropertyExpression) ClosureExpression(org.codehaus.groovy.ast.expr.ClosureExpression) ForStatement(org.codehaus.groovy.ast.stmt.ForStatement) HashSet(java.util.HashSet) ClassCodeExpressionTransformer(org.codehaus.groovy.ast.ClassCodeExpressionTransformer) ClassNode(org.codehaus.groovy.ast.ClassNode) FieldNode(org.codehaus.groovy.ast.FieldNode) SyntaxErrorMessage(org.codehaus.groovy.control.messages.SyntaxErrorMessage) Reference(groovy.lang.Reference) DeclarationExpression(org.codehaus.groovy.ast.expr.DeclarationExpression) VariableExpression(org.codehaus.groovy.ast.expr.VariableExpression) LinkedList(java.util.LinkedList) CatchStatement(org.codehaus.groovy.ast.stmt.CatchStatement) PropertyExpression(org.codehaus.groovy.ast.expr.PropertyExpression) Expression(org.codehaus.groovy.ast.expr.Expression) VariableExpression(org.codehaus.groovy.ast.expr.VariableExpression) DeclarationExpression(org.codehaus.groovy.ast.expr.DeclarationExpression) ClosureExpression(org.codehaus.groovy.ast.expr.ClosureExpression) ClassExpression(org.codehaus.groovy.ast.expr.ClassExpression) TupleExpression(org.codehaus.groovy.ast.expr.TupleExpression) ExpressionStatement(org.codehaus.groovy.ast.stmt.ExpressionStatement) Parameter(org.codehaus.groovy.ast.Parameter) VariableScopeVisitor(org.codehaus.groovy.classgen.VariableScopeVisitor)

Example 93 with ExpressionStatement

use of org.codehaus.groovy.ast.stmt.ExpressionStatement in project grails-core by grails.

the class TagLibraryTransformer method addAttributesAndStringBodyMethod.

private void addAttributesAndStringBodyMethod(ClassNode classNode, String tagName) {
    BlockStatement methodBody = new BlockStatement();
    ArgumentListExpression arguments = new ArgumentListExpression();
    ArgumentListExpression constructorArgs = new ArgumentListExpression();
    constructorArgs.addExpression(BODY_EXPRESSION);
    arguments.addExpression(new CastExpression(ClassHelper.make(Map.class), ATTRS_EXPRESSION)).addExpression(new ConstructorCallExpression(new ClassNode(TagOutput.ConstantClosure.class), constructorArgs));
    methodBody.addStatement(new ExpressionStatement(new MethodCallExpression(new VariableExpression("this"), tagName, arguments)));
    classNode.addMethod(new MethodNode(tagName, Modifier.PUBLIC, GrailsASTUtils.OBJECT_CLASS_NODE, MAP_CHARSEQUENCE_PARAMETERS, null, methodBody));
}
Also used : TagOutput(org.grails.taglib.TagOutput) ExpressionStatement(org.codehaus.groovy.ast.stmt.ExpressionStatement) BlockStatement(org.codehaus.groovy.ast.stmt.BlockStatement) Map(java.util.Map)

Example 94 with ExpressionStatement

use of org.codehaus.groovy.ast.stmt.ExpressionStatement in project groovy-core by groovy.

the class GrabAnnotationTransformation method addGrabResolverAsStaticInitIfNeeded.

private void addGrabResolverAsStaticInitIfNeeded(ClassNode grapeClassNode, AnnotationNode node, List<Statement> grabResolverInitializers, Map<String, Object> grabResolverMap) {
    if ((node.getMember("initClass") == null) || (node.getMember("initClass") == ConstantExpression.TRUE)) {
        MapExpression resolverArgs = new MapExpression();
        for (Map.Entry<String, Object> next : grabResolverMap.entrySet()) {
            resolverArgs.addMapEntryExpression(new ConstantExpression(next.getKey()), new ConstantExpression(next.getValue()));
        }
        grabResolverInitializers.add(new ExpressionStatement(new StaticMethodCallExpression(grapeClassNode, "addResolver", new ArgumentListExpression(resolverArgs))));
    }
}
Also used : MapExpression(org.codehaus.groovy.ast.expr.MapExpression) ConstantExpression(org.codehaus.groovy.ast.expr.ConstantExpression) ExpressionStatement(org.codehaus.groovy.ast.stmt.ExpressionStatement) StaticMethodCallExpression(org.codehaus.groovy.ast.expr.StaticMethodCallExpression) ArgumentListExpression(org.codehaus.groovy.ast.expr.ArgumentListExpression)

Example 95 with ExpressionStatement

use of org.codehaus.groovy.ast.stmt.ExpressionStatement in project groovy-core by groovy.

the class GrabAnnotationTransformation method addInitContextClassLoaderIfNeeded.

private void addInitContextClassLoaderIfNeeded(ClassNode classNode) {
    if (initContextClassLoader) {
        Statement initStatement = new ExpressionStatement(new MethodCallExpression(new StaticMethodCallExpression(THREAD_CLASSNODE, "currentThread", ArgumentListExpression.EMPTY_ARGUMENTS), "setContextClassLoader", new MethodCallExpression(new MethodCallExpression(VariableExpression.THIS_EXPRESSION, "getClass", MethodCallExpression.NO_ARGUMENTS), "getClassLoader", ArgumentListExpression.EMPTY_ARGUMENTS)));
        classNode.addObjectInitializerStatements(initStatement);
    }
}
Also used : StaticMethodCallExpression(org.codehaus.groovy.ast.expr.StaticMethodCallExpression) MethodCallExpression(org.codehaus.groovy.ast.expr.MethodCallExpression) Statement(org.codehaus.groovy.ast.stmt.Statement) ExpressionStatement(org.codehaus.groovy.ast.stmt.ExpressionStatement) ExpressionStatement(org.codehaus.groovy.ast.stmt.ExpressionStatement) StaticMethodCallExpression(org.codehaus.groovy.ast.expr.StaticMethodCallExpression)

Aggregations

ExpressionStatement (org.codehaus.groovy.ast.stmt.ExpressionStatement)122 BlockStatement (org.codehaus.groovy.ast.stmt.BlockStatement)78 VariableExpression (org.codehaus.groovy.ast.expr.VariableExpression)65 Statement (org.codehaus.groovy.ast.stmt.Statement)58 Expression (org.codehaus.groovy.ast.expr.Expression)54 ArgumentListExpression (org.codehaus.groovy.ast.expr.ArgumentListExpression)52 ConstantExpression (org.codehaus.groovy.ast.expr.ConstantExpression)51 ConstructorCallExpression (org.codehaus.groovy.ast.expr.ConstructorCallExpression)49 MethodCallExpression (org.codehaus.groovy.ast.expr.MethodCallExpression)44 BinaryExpression (org.codehaus.groovy.ast.expr.BinaryExpression)39 ReturnStatement (org.codehaus.groovy.ast.stmt.ReturnStatement)36 ClassExpression (org.codehaus.groovy.ast.expr.ClassExpression)35 Parameter (org.codehaus.groovy.ast.Parameter)30 MethodNode (org.codehaus.groovy.ast.MethodNode)29 ClosureExpression (org.codehaus.groovy.ast.expr.ClosureExpression)29 ClassNode (org.codehaus.groovy.ast.ClassNode)27 TupleExpression (org.codehaus.groovy.ast.expr.TupleExpression)26 IfStatement (org.codehaus.groovy.ast.stmt.IfStatement)26 ArrayList (java.util.ArrayList)25 BooleanExpression (org.codehaus.groovy.ast.expr.BooleanExpression)24