Search in sources :

Example 11 with Token

use of org.codehaus.groovy.syntax.Token in project groovy-core by groovy.

the class SqlWhereVisitor method visitBinaryExpression.

public void visitBinaryExpression(BinaryExpression expression) {
    Expression left = expression.getLeftExpression();
    Expression right = expression.getRightExpression();
    boolean leaf = (right instanceof ConstantExpression || left instanceof ConstantExpression);
    if (!leaf)
        buffer.append("(");
    left.visit(this);
    buffer.append(" ");
    Token token = expression.getOperation();
    buffer.append(tokenAsSql(token));
    buffer.append(" ");
    right.visit(this);
    if (!leaf)
        buffer.append(")");
}
Also used : BooleanExpression(org.codehaus.groovy.ast.expr.BooleanExpression) PropertyExpression(org.codehaus.groovy.ast.expr.PropertyExpression) VariableExpression(org.codehaus.groovy.ast.expr.VariableExpression) ConstantExpression(org.codehaus.groovy.ast.expr.ConstantExpression) BinaryExpression(org.codehaus.groovy.ast.expr.BinaryExpression) Expression(org.codehaus.groovy.ast.expr.Expression) ConstantExpression(org.codehaus.groovy.ast.expr.ConstantExpression) Token(org.codehaus.groovy.syntax.Token)

Example 12 with Token

use of org.codehaus.groovy.syntax.Token in project groovy-cps by cloudbees.

the class CpsTransformer method visitMethod.

/**
     * Transforms asynchronous workflow method.
     *
     * From:
     *
     * ReturnT foo( T1 arg1, T2 arg2, ...) { ... body ... }
     *
     * To:
     *
     * private static CpsFunction ___cps___N = ___cps___N();
     *
     * private static final CpsFunction ___cps___N() { return new
     * CpsFunction(['arg1','arg2','arg3',...], CPS-transformed-method-body) }
     *
     * ReturnT foo( T1 arg1, T2 arg2, ...) { throw new
     * CpsCallableInvocation(___cps___N, this, new Object[] {arg1, arg2, ...}) }
     */
public void visitMethod(final MethodNode m) {
    if (!shouldBeTransformed(m)) {
        visitNontransformedMethod(m);
        return;
    }
    final AtomicReference<Expression> body = new AtomicReference<>();
    // transform the body
    parent = new ParentClosure() {

        @Override
        public void call(Expression e) {
            body.set(e);
            if (LOGGER.isLoggable(Level.FINEST)) {
                LOGGER.log(Level.FINEST, "in {0} transformed {1} to {2}", new Object[] { classNode.getName(), m.getTypeDescriptor(), e.getText() });
            }
        }
    };
    visitWithSafepoint(m.getCode());
    ListExpression params = new ListExpression();
    for (Parameter p : m.getParameters()) {
        params.addExpression(new ConstantExpression(p.getName()));
    }
    /*
              CpsFunction ___cps___N() {
                Builder b = new Builder(...);
                return new CpsFunction( << parameters >>, << body: AST tree building code >>);
              }
         */
    String cpsName = "___cps___" + iota.getAndIncrement();
    MethodNode builderMethod = m.getDeclaringClass().addMethod(cpsName, PRIVATE_STATIC_FINAL, FUNCTION_TYPE, new Parameter[0], new ClassNode[0], new BlockStatement(Arrays.asList(new ExpressionStatement(new DeclarationExpression(BUILDER, new Token(ASSIGN, "=", -1, -1), makeBuilder(m))), new ReturnStatement(new ConstructorCallExpression(FUNCTION_TYPE, new TupleExpression(params, body.get())))), new VariableScope()));
    builderMethod.addAnnotation(new AnnotationNode(WORKFLOW_TRANSFORMED_TYPE));
    FieldNode f = m.getDeclaringClass().addField(cpsName, PRIVATE_STATIC_FINAL, FUNCTION_TYPE, new StaticMethodCallExpression(m.getDeclaringClass(), cpsName, new TupleExpression()));
    //                new ConstructorCallExpression(FUNCTION_TYPE, new TupleExpression(params, body)));
    List<Expression> paramExpressions = new ArrayList<>();
    for (Parameter p : m.getParameters()) {
        paramExpressions.add(new VariableExpression(p));
    }
    ArrayExpression paramArray = new ArrayExpression(ClassHelper.OBJECT_TYPE, paramExpressions);
    TupleExpression args = new TupleExpression(new VariableExpression(f), THIS, paramArray);
    m.setCode(new ThrowStatement(new ConstructorCallExpression(CPSCALLINVK_TYPE, args)));
    m.addAnnotation(new AnnotationNode(WORKFLOW_TRANSFORMED_TYPE));
}
Also used : ArrayList(java.util.ArrayList) Token(org.codehaus.groovy.syntax.Token) AtomicReference(java.util.concurrent.atomic.AtomicReference) BytecodeExpression(org.codehaus.groovy.classgen.BytecodeExpression)

Example 13 with Token

use of org.codehaus.groovy.syntax.Token in project groovy-core by groovy.

the class EnumVisitor method addMethods.

private void addMethods(ClassNode enumClass, FieldNode values) {
    List<MethodNode> methods = enumClass.getMethods();
    boolean hasNext = false;
    boolean hasPrevious = false;
    for (MethodNode m : methods) {
        if (m.getName().equals("next") && m.getParameters().length == 0)
            hasNext = true;
        if (m.getName().equals("previous") && m.getParameters().length == 0)
            hasPrevious = true;
        if (hasNext && hasPrevious)
            break;
    }
    ClassNode enumRef = enumClass.getPlainNodeReference();
    {
        // create values() method
        MethodNode valuesMethod = new MethodNode("values", PUBLIC_FS, enumRef.makeArray(), Parameter.EMPTY_ARRAY, ClassNode.EMPTY_ARRAY, null);
        valuesMethod.setSynthetic(true);
        BlockStatement code = new BlockStatement();
        MethodCallExpression cloneCall = new MethodCallExpression(new FieldExpression(values), "clone", MethodCallExpression.NO_ARGUMENTS);
        cloneCall.setMethodTarget(values.getType().getMethod("clone", Parameter.EMPTY_ARRAY));
        code.addStatement(new ReturnStatement(cloneCall));
        valuesMethod.setCode(code);
        enumClass.addMethod(valuesMethod);
    }
    if (!hasNext) {
        // create next() method, code:
        //     Day next() {
        //        int ordinal = ordinal().next()
        //        if (ordinal >= values().size()) ordinal = 0
        //        return values()[ordinal]
        //     }
        Token assign = Token.newSymbol(Types.ASSIGN, -1, -1);
        Token ge = Token.newSymbol(Types.COMPARE_GREATER_THAN_EQUAL, -1, -1);
        MethodNode nextMethod = new MethodNode("next", Opcodes.ACC_PUBLIC | Opcodes.ACC_SYNTHETIC, enumRef, Parameter.EMPTY_ARRAY, ClassNode.EMPTY_ARRAY, null);
        nextMethod.setSynthetic(true);
        BlockStatement code = new BlockStatement();
        BlockStatement ifStatement = new BlockStatement();
        ifStatement.addStatement(new ExpressionStatement(new BinaryExpression(new VariableExpression("ordinal"), assign, new ConstantExpression(0))));
        code.addStatement(new ExpressionStatement(new DeclarationExpression(new VariableExpression("ordinal"), assign, new MethodCallExpression(new MethodCallExpression(VariableExpression.THIS_EXPRESSION, "ordinal", MethodCallExpression.NO_ARGUMENTS), "next", MethodCallExpression.NO_ARGUMENTS))));
        code.addStatement(new IfStatement(new BooleanExpression(new BinaryExpression(new VariableExpression("ordinal"), ge, new MethodCallExpression(new FieldExpression(values), "size", MethodCallExpression.NO_ARGUMENTS))), ifStatement, EmptyStatement.INSTANCE));
        code.addStatement(new ReturnStatement(new MethodCallExpression(new FieldExpression(values), "getAt", new VariableExpression("ordinal"))));
        nextMethod.setCode(code);
        enumClass.addMethod(nextMethod);
    }
    if (!hasPrevious) {
        // create previous() method, code:
        //    Day previous() {
        //        int ordinal = ordinal().previous()
        //        if (ordinal < 0) ordinal = values().size() - 1
        //        return values()[ordinal]
        //    }
        Token assign = Token.newSymbol(Types.ASSIGN, -1, -1);
        Token lt = Token.newSymbol(Types.COMPARE_LESS_THAN, -1, -1);
        MethodNode nextMethod = new MethodNode("previous", Opcodes.ACC_PUBLIC | Opcodes.ACC_SYNTHETIC, enumRef, Parameter.EMPTY_ARRAY, ClassNode.EMPTY_ARRAY, null);
        nextMethod.setSynthetic(true);
        BlockStatement code = new BlockStatement();
        BlockStatement ifStatement = new BlockStatement();
        ifStatement.addStatement(new ExpressionStatement(new BinaryExpression(new VariableExpression("ordinal"), assign, new MethodCallExpression(new MethodCallExpression(new FieldExpression(values), "size", MethodCallExpression.NO_ARGUMENTS), "minus", new ConstantExpression(1)))));
        code.addStatement(new ExpressionStatement(new DeclarationExpression(new VariableExpression("ordinal"), assign, new MethodCallExpression(new MethodCallExpression(VariableExpression.THIS_EXPRESSION, "ordinal", MethodCallExpression.NO_ARGUMENTS), "previous", MethodCallExpression.NO_ARGUMENTS))));
        code.addStatement(new IfStatement(new BooleanExpression(new BinaryExpression(new VariableExpression("ordinal"), lt, new ConstantExpression(0))), ifStatement, EmptyStatement.INSTANCE));
        code.addStatement(new ReturnStatement(new MethodCallExpression(new FieldExpression(values), "getAt", new VariableExpression("ordinal"))));
        nextMethod.setCode(code);
        enumClass.addMethod(nextMethod);
    }
    {
        // create valueOf
        Parameter stringParameter = new Parameter(ClassHelper.STRING_TYPE, "name");
        MethodNode valueOfMethod = new MethodNode("valueOf", PS, enumRef, new Parameter[] { stringParameter }, ClassNode.EMPTY_ARRAY, null);
        ArgumentListExpression callArguments = new ArgumentListExpression();
        callArguments.addExpression(new ClassExpression(enumClass));
        callArguments.addExpression(new VariableExpression("name"));
        BlockStatement code = new BlockStatement();
        code.addStatement(new ReturnStatement(new MethodCallExpression(new ClassExpression(ClassHelper.Enum_Type), "valueOf", callArguments)));
        valueOfMethod.setCode(code);
        valueOfMethod.setSynthetic(true);
        enumClass.addMethod(valueOfMethod);
    }
}
Also used : EnumConstantClassNode(org.codehaus.groovy.ast.EnumConstantClassNode) ClassNode(org.codehaus.groovy.ast.ClassNode) InnerClassNode(org.codehaus.groovy.ast.InnerClassNode) BlockStatement(org.codehaus.groovy.ast.stmt.BlockStatement) Token(org.codehaus.groovy.syntax.Token) IfStatement(org.codehaus.groovy.ast.stmt.IfStatement) MethodNode(org.codehaus.groovy.ast.MethodNode) ExpressionStatement(org.codehaus.groovy.ast.stmt.ExpressionStatement) ReturnStatement(org.codehaus.groovy.ast.stmt.ReturnStatement) Parameter(org.codehaus.groovy.ast.Parameter)

Example 14 with Token

use of org.codehaus.groovy.syntax.Token in project groovy-core by groovy.

the class EnumVisitor method addInit.

private void addInit(ClassNode enumClass, FieldNode minValue, FieldNode maxValue, FieldNode values, boolean isAic) {
    // constructor helper
    // This method is used instead of calling the constructor as
    // calling the constructor may require a table with MetaClass
    // selecting the constructor for each enum value. So instead we
    // use this method to have a central point for constructor selection
    // and only one table. The whole construction is needed because 
    // Reflection forbids access to the enum constructor.
    // code:
    // def $INIT(Object[] para) {
    //  return this(*para)
    // }
    ClassNode enumRef = enumClass.getPlainNodeReference();
    Parameter[] parameter = new Parameter[] { new Parameter(ClassHelper.OBJECT_TYPE.makeArray(), "para") };
    MethodNode initMethod = new MethodNode("$INIT", PUBLIC_FS | Opcodes.ACC_SYNTHETIC, enumRef, parameter, ClassNode.EMPTY_ARRAY, null);
    initMethod.setSynthetic(true);
    ConstructorCallExpression cce = new ConstructorCallExpression(ClassNode.THIS, new ArgumentListExpression(new SpreadExpression(new VariableExpression("para"))));
    BlockStatement code = new BlockStatement();
    code.addStatement(new ReturnStatement(cce));
    initMethod.setCode(code);
    enumClass.addMethod(initMethod);
    // static init
    List<FieldNode> fields = enumClass.getFields();
    List<Expression> arrayInit = new ArrayList<Expression>();
    int value = -1;
    Token assign = Token.newSymbol(Types.ASSIGN, -1, -1);
    List<Statement> block = new ArrayList<Statement>();
    FieldNode tempMin = null;
    FieldNode tempMax = null;
    for (FieldNode field : fields) {
        if ((field.getModifiers() & Opcodes.ACC_ENUM) == 0)
            continue;
        value++;
        if (tempMin == null)
            tempMin = field;
        tempMax = field;
        ClassNode enumBase = enumClass;
        ArgumentListExpression args = new ArgumentListExpression();
        args.addExpression(new ConstantExpression(field.getName()));
        args.addExpression(new ConstantExpression(value));
        if (field.getInitialExpression() == null) {
            if ((enumClass.getModifiers() & Opcodes.ACC_ABSTRACT) != 0) {
                addError(field, "The enum constant " + field.getName() + " must override abstract methods from " + enumBase.getName() + ".");
                continue;
            }
        } else {
            ListExpression oldArgs = (ListExpression) field.getInitialExpression();
            List<MapEntryExpression> savedMapEntries = new ArrayList<MapEntryExpression>();
            for (Expression exp : oldArgs.getExpressions()) {
                if (exp instanceof MapEntryExpression) {
                    savedMapEntries.add((MapEntryExpression) exp);
                    continue;
                }
                InnerClassNode inner = null;
                if (exp instanceof ClassExpression) {
                    ClassExpression clazzExp = (ClassExpression) exp;
                    ClassNode ref = clazzExp.getType();
                    if (ref instanceof EnumConstantClassNode) {
                        inner = (InnerClassNode) ref;
                    }
                }
                if (inner != null) {
                    List<MethodNode> baseMethods = enumBase.getMethods();
                    for (MethodNode methodNode : baseMethods) {
                        if (!methodNode.isAbstract())
                            continue;
                        MethodNode enumConstMethod = inner.getMethod(methodNode.getName(), methodNode.getParameters());
                        if (enumConstMethod == null || (enumConstMethod.getModifiers() & Opcodes.ACC_ABSTRACT) != 0) {
                            addError(field, "Can't have an abstract method in enum constant " + field.getName() + ". Implement method '" + methodNode.getTypeDescriptor() + "'.");
                        }
                    }
                    if (inner.getVariableScope() == null) {
                        enumBase = inner;
                        /*
                             * GROOVY-3985: Remove the final modifier from $INIT method in this case
                             * so that subclasses of enum generated for enum constants (aic) can provide
                             * their own $INIT method
                             */
                        initMethod.setModifiers(initMethod.getModifiers() & ~Opcodes.ACC_FINAL);
                        continue;
                    }
                }
                args.addExpression(exp);
            }
            if (savedMapEntries.size() > 0) {
                args.getExpressions().add(2, new MapExpression(savedMapEntries));
            }
        }
        field.setInitialValueExpression(null);
        block.add(new ExpressionStatement(new BinaryExpression(new FieldExpression(field), assign, new StaticMethodCallExpression(enumBase, "$INIT", args))));
        arrayInit.add(new FieldExpression(field));
    }
    if (!isAic) {
        if (tempMin != null) {
            block.add(new ExpressionStatement(new BinaryExpression(new FieldExpression(minValue), assign, new FieldExpression(tempMin))));
            block.add(new ExpressionStatement(new BinaryExpression(new FieldExpression(maxValue), assign, new FieldExpression(tempMax))));
            enumClass.addField(minValue);
            enumClass.addField(maxValue);
        }
        block.add(new ExpressionStatement(new BinaryExpression(new FieldExpression(values), assign, new ArrayExpression(enumClass, arrayInit))));
        enumClass.addField(values);
    }
    enumClass.addStaticInitializerStatements(block, true);
}
Also used : EnumConstantClassNode(org.codehaus.groovy.ast.EnumConstantClassNode) ArrayList(java.util.ArrayList) BlockStatement(org.codehaus.groovy.ast.stmt.BlockStatement) Token(org.codehaus.groovy.syntax.Token) MethodNode(org.codehaus.groovy.ast.MethodNode) ReturnStatement(org.codehaus.groovy.ast.stmt.ReturnStatement) EnumConstantClassNode(org.codehaus.groovy.ast.EnumConstantClassNode) ClassNode(org.codehaus.groovy.ast.ClassNode) InnerClassNode(org.codehaus.groovy.ast.InnerClassNode) FieldNode(org.codehaus.groovy.ast.FieldNode) Statement(org.codehaus.groovy.ast.stmt.Statement) ExpressionStatement(org.codehaus.groovy.ast.stmt.ExpressionStatement) ReturnStatement(org.codehaus.groovy.ast.stmt.ReturnStatement) EmptyStatement(org.codehaus.groovy.ast.stmt.EmptyStatement) IfStatement(org.codehaus.groovy.ast.stmt.IfStatement) BlockStatement(org.codehaus.groovy.ast.stmt.BlockStatement) InnerClassNode(org.codehaus.groovy.ast.InnerClassNode) ExpressionStatement(org.codehaus.groovy.ast.stmt.ExpressionStatement) Parameter(org.codehaus.groovy.ast.Parameter)

Example 15 with Token

use of org.codehaus.groovy.syntax.Token in project groovy-core by groovy.

the class BinaryExpression method newAssignmentExpression.

/**
     * Creates an assignment expression in which the specified expression
     * is written into the specified variable name.
     */
public static BinaryExpression newAssignmentExpression(Variable variable, Expression rhs) {
    VariableExpression lhs = new VariableExpression(variable);
    Token operator = Token.newPlaceholder(Types.ASSIGN);
    return new BinaryExpression(lhs, operator, rhs);
}
Also used : Token(org.codehaus.groovy.syntax.Token)

Aggregations

Token (org.codehaus.groovy.syntax.Token)25 ClassNode (org.codehaus.groovy.ast.ClassNode)7 BinaryExpression (org.codehaus.groovy.ast.expr.BinaryExpression)7 BooleanExpression (org.codehaus.groovy.ast.expr.BooleanExpression)7 ConstantExpression (org.codehaus.groovy.ast.expr.ConstantExpression)7 Expression (org.codehaus.groovy.ast.expr.Expression)7 PropertyExpression (org.codehaus.groovy.ast.expr.PropertyExpression)7 VariableExpression (org.codehaus.groovy.ast.expr.VariableExpression)7 ArrayList (java.util.ArrayList)6 MethodNode (org.codehaus.groovy.ast.MethodNode)6 ExpressionStatement (org.codehaus.groovy.ast.stmt.ExpressionStatement)6 SyntaxException (org.codehaus.groovy.syntax.SyntaxException)6 EnumConstantClassNode (org.codehaus.groovy.ast.EnumConstantClassNode)5 InnerClassNode (org.codehaus.groovy.ast.InnerClassNode)5 ArgumentListExpression (org.codehaus.groovy.ast.expr.ArgumentListExpression)5 ClassExpression (org.codehaus.groovy.ast.expr.ClassExpression)5 DeclarationExpression (org.codehaus.groovy.ast.expr.DeclarationExpression)5 MethodCallExpression (org.codehaus.groovy.ast.expr.MethodCallExpression)5 TernaryExpression (org.codehaus.groovy.ast.expr.TernaryExpression)5 BlockStatement (org.codehaus.groovy.ast.stmt.BlockStatement)5