Search in sources :

Example 56 with ExpressionStatement

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

the class ModuleNode method createStatementsClass.

protected ClassNode createStatementsClass() {
    ClassNode classNode = getScriptClassDummy();
    if (classNode.getName().endsWith("package-info")) {
        return classNode;
    }
    handleMainMethodIfPresent(methods);
    // return new Foo(new ShellContext(args)).run()
    classNode.addMethod(new MethodNode("main", ACC_PUBLIC | ACC_STATIC, ClassHelper.VOID_TYPE, new Parameter[] { new Parameter(ClassHelper.STRING_TYPE.makeArray(), "args") }, ClassNode.EMPTY_ARRAY, new ExpressionStatement(new MethodCallExpression(new ClassExpression(ClassHelper.make(InvokerHelper.class)), "runScript", new ArgumentListExpression(new ClassExpression(classNode), new VariableExpression("args"))))));
    MethodNode methodNode = new MethodNode("run", ACC_PUBLIC, ClassHelper.OBJECT_TYPE, Parameter.EMPTY_ARRAY, ClassNode.EMPTY_ARRAY, statementBlock);
    methodNode.setIsScriptBody();
    classNode.addMethod(methodNode);
    classNode.addConstructor(ACC_PUBLIC, Parameter.EMPTY_ARRAY, ClassNode.EMPTY_ARRAY, new BlockStatement());
    Statement stmt;
    // (like @BaseScript) that could change this.  But this is cautious and anticipates possible compiler changes.
    if (classNode.getSuperClass().getDeclaredConstructor(SCRIPT_CONTEXT_CTOR) != null) {
        stmt = new ExpressionStatement(new ConstructorCallExpression(ClassNode.SUPER, new ArgumentListExpression(new VariableExpression("context"))));
    } else {
        // Fallback for non-standard base "script" classes with no context (Binding) constructor.
        stmt = new ExpressionStatement(new MethodCallExpression(new VariableExpression("super"), "setBinding", new ArgumentListExpression(new VariableExpression("context"))));
    }
    classNode.addConstructor(ACC_PUBLIC, new Parameter[] { new Parameter(ClassHelper.make(Binding.class), "context") }, ClassNode.EMPTY_ARRAY, stmt);
    for (MethodNode node : methods) {
        int modifiers = node.getModifiers();
        if ((modifiers & ACC_ABSTRACT) != 0) {
            throw new RuntimeException("Cannot use abstract methods in a script, they are only available inside classes. Method: " + node.getName());
        }
        // br: the old logic seems to add static to all def f().... in a script, which makes enclosing
        // inner classes (including closures) in a def function difficult. Comment it out.
        node.setModifiers(modifiers);
        classNode.addMethod(node);
    }
    return classNode;
}
Also used : InvokerHelper(org.codehaus.groovy.runtime.InvokerHelper) Statement(org.codehaus.groovy.ast.stmt.Statement) ExpressionStatement(org.codehaus.groovy.ast.stmt.ExpressionStatement) BlockStatement(org.codehaus.groovy.ast.stmt.BlockStatement) ConstructorCallExpression(org.codehaus.groovy.ast.expr.ConstructorCallExpression) ArgumentListExpression(org.codehaus.groovy.ast.expr.ArgumentListExpression) ClassExpression(org.codehaus.groovy.ast.expr.ClassExpression) VariableExpression(org.codehaus.groovy.ast.expr.VariableExpression) BlockStatement(org.codehaus.groovy.ast.stmt.BlockStatement) MethodCallExpression(org.codehaus.groovy.ast.expr.MethodCallExpression) ExpressionStatement(org.codehaus.groovy.ast.stmt.ExpressionStatement)

Example 57 with ExpressionStatement

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

the class ConstructorNode method firstStatementIsSpecialConstructorCall.

public boolean firstStatementIsSpecialConstructorCall() {
    Statement code = getFirstStatement();
    if (code == null || !(code instanceof ExpressionStatement))
        return false;
    Expression expression = ((ExpressionStatement) code).getExpression();
    if (!(expression instanceof ConstructorCallExpression))
        return false;
    ConstructorCallExpression cce = (ConstructorCallExpression) expression;
    return cce.isSpecialCall();
}
Also used : ConstructorCallExpression(org.codehaus.groovy.ast.expr.ConstructorCallExpression) Expression(org.codehaus.groovy.ast.expr.Expression) Statement(org.codehaus.groovy.ast.stmt.Statement) ExpressionStatement(org.codehaus.groovy.ast.stmt.ExpressionStatement) ConstructorCallExpression(org.codehaus.groovy.ast.expr.ConstructorCallExpression) ExpressionStatement(org.codehaus.groovy.ast.stmt.ExpressionStatement)

Example 58 with ExpressionStatement

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

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 static 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());
    methods.addAll(node.getDeclaredConstructors());
    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());
            }
            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);
            }
            MethodNode bridge;
            if (method instanceof ConstructorNode) {
                // create constructor with a nested class as the first parameter, creating one if necessary
                ClassNode thatType = null;
                Iterator<InnerClassNode> innerClasses = node.getInnerClasses();
                if (innerClasses.hasNext()) {
                    thatType = innerClasses.next();
                } else {
                    thatType = new InnerClassNode(node.redirect(), node.getName() + "$1", ACC_STATIC | ACC_SYNTHETIC, ClassHelper.OBJECT_TYPE);
                    node.getModule().addClass(thatType);
                }
                newParams[0] = new Parameter(thatType.getPlainNodeReference(), "$that");
                Expression cce = new ConstructorCallExpression(ClassNode.THIS, arguments);
                Statement body = new ExpressionStatement(cce);
                bridge = node.addConstructor(ACC_SYNTHETIC, newParams, ClassNode.EMPTY_ARRAY, body);
            } else {
                newParams[0] = new Parameter(node.getPlainNodeReference(), "$that");
                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);
                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 : Statement(org.codehaus.groovy.ast.stmt.Statement) ExpressionStatement(org.codehaus.groovy.ast.stmt.ExpressionStatement) ForStatement(org.codehaus.groovy.ast.stmt.ForStatement) EmptyStatement(org.codehaus.groovy.ast.stmt.EmptyStatement) ExpressionStatement(org.codehaus.groovy.ast.stmt.ExpressionStatement)

Example 59 with ExpressionStatement

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

the class StaticCompilationVisitor method addPrivateFieldsAccessors.

/**
     * Adds special accessors and mutators for private fields so that inner classes can get/set them
     */
@SuppressWarnings("unchecked")
private static void addPrivateFieldsAccessors(ClassNode node) {
    Set<ASTNode> accessedFields = (Set<ASTNode>) node.getNodeMetaData(StaticTypesMarker.PV_FIELDS_ACCESS);
    Set<ASTNode> mutatedFields = (Set<ASTNode>) node.getNodeMetaData(StaticTypesMarker.PV_FIELDS_MUTATION);
    if (accessedFields == null && mutatedFields == null)
        return;
    Map<String, MethodNode> privateFieldAccessors = (Map<String, MethodNode>) node.getNodeMetaData(PRIVATE_FIELDS_ACCESSORS);
    Map<String, MethodNode> privateFieldMutators = (Map<String, MethodNode>) node.getNodeMetaData(PRIVATE_FIELDS_MUTATORS);
    if (privateFieldAccessors != null || privateFieldMutators != null) {
        // already added
        return;
    }
    int acc = -1;
    privateFieldAccessors = accessedFields != null ? new HashMap<String, MethodNode>() : null;
    privateFieldMutators = mutatedFields != null ? new HashMap<String, MethodNode>() : null;
    final int access = Opcodes.ACC_STATIC | Opcodes.ACC_PUBLIC | Opcodes.ACC_SYNTHETIC;
    for (FieldNode fieldNode : node.getFields()) {
        boolean generateAccessor = accessedFields != null && accessedFields.contains(fieldNode);
        boolean generateMutator = mutatedFields != null && mutatedFields.contains(fieldNode);
        if (generateAccessor) {
            acc++;
            Parameter param = new Parameter(node.getPlainNodeReference(), "$that");
            Expression receiver = fieldNode.isStatic() ? new ClassExpression(node) : new VariableExpression(param);
            Statement stmt = new ExpressionStatement(new PropertyExpression(receiver, fieldNode.getName()));
            MethodNode accessor = node.addMethod("pfaccess$" + acc, access, fieldNode.getOriginType(), new Parameter[] { param }, ClassNode.EMPTY_ARRAY, stmt);
            privateFieldAccessors.put(fieldNode.getName(), accessor);
        }
        if (generateMutator) {
            //increment acc if it hasn't been incremented in the current iteration
            if (!generateAccessor)
                acc++;
            Parameter param = new Parameter(node.getPlainNodeReference(), "$that");
            Expression receiver = fieldNode.isStatic() ? new ClassExpression(node) : new VariableExpression(param);
            Parameter value = new Parameter(fieldNode.getOriginType(), "$value");
            Statement stmt = GeneralUtils.assignS(new PropertyExpression(receiver, fieldNode.getName()), new VariableExpression(value));
            MethodNode mutator = node.addMethod("pfaccess$0" + acc, access, fieldNode.getOriginType(), new Parameter[] { param, value }, ClassNode.EMPTY_ARRAY, stmt);
            privateFieldMutators.put(fieldNode.getName(), mutator);
        }
    }
    if (privateFieldAccessors != null)
        node.setNodeMetaData(PRIVATE_FIELDS_ACCESSORS, privateFieldAccessors);
    if (privateFieldMutators != null)
        node.setNodeMetaData(PRIVATE_FIELDS_MUTATORS, privateFieldMutators);
}
Also used : Statement(org.codehaus.groovy.ast.stmt.Statement) ExpressionStatement(org.codehaus.groovy.ast.stmt.ExpressionStatement) ForStatement(org.codehaus.groovy.ast.stmt.ForStatement) EmptyStatement(org.codehaus.groovy.ast.stmt.EmptyStatement) ExpressionStatement(org.codehaus.groovy.ast.stmt.ExpressionStatement)

Example 60 with ExpressionStatement

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

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