Search in sources :

Example 6 with MethodCallExpression

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

the class LogASTTransformation method visit.

public void visit(ASTNode[] nodes, final SourceUnit source) {
    init(nodes, source);
    AnnotatedNode targetClass = (AnnotatedNode) nodes[1];
    AnnotationNode logAnnotation = (AnnotationNode) nodes[0];
    final GroovyClassLoader classLoader = compilationUnit != null ? compilationUnit.getTransformLoader() : source.getClassLoader();
    final LoggingStrategy loggingStrategy = createLoggingStrategy(logAnnotation, classLoader);
    if (loggingStrategy == null)
        return;
    final String logFieldName = lookupLogFieldName(logAnnotation);
    final String categoryName = lookupCategoryName(logAnnotation);
    if (!(targetClass instanceof ClassNode))
        throw new GroovyBugError("Class annotation " + logAnnotation.getClassNode().getName() + " annotated no Class, this must not happen.");
    final ClassNode classNode = (ClassNode) targetClass;
    ClassCodeExpressionTransformer transformer = new ClassCodeExpressionTransformer() {

        private FieldNode logNode;

        @Override
        protected SourceUnit getSourceUnit() {
            return source;
        }

        public Expression transform(Expression exp) {
            if (exp == null)
                return null;
            if (exp instanceof MethodCallExpression) {
                return transformMethodCallExpression(exp);
            }
            if (exp instanceof ClosureExpression) {
                return transformClosureExpression((ClosureExpression) exp);
            }
            return super.transform(exp);
        }

        @Override
        public void visitClass(ClassNode node) {
            FieldNode logField = node.getField(logFieldName);
            if (logField != null && logField.getOwner().equals(node)) {
                addError("Class annotated with Log annotation cannot have log field declared", logField);
            } else if (logField != null && !Modifier.isPrivate(logField.getModifiers())) {
                addError("Class annotated with Log annotation cannot have log field declared because the field exists in the parent class: " + logField.getOwner().getName(), logField);
            } else {
                logNode = loggingStrategy.addLoggerFieldToClass(node, logFieldName, categoryName);
            }
            super.visitClass(node);
        }

        private Expression transformClosureExpression(ClosureExpression exp) {
            if (exp.getCode() instanceof BlockStatement) {
                BlockStatement code = (BlockStatement) exp.getCode();
                super.visitBlockStatement(code);
            }
            return exp;
        }

        private Expression transformMethodCallExpression(Expression exp) {
            Expression modifiedCall = addGuard((MethodCallExpression) exp);
            return modifiedCall == null ? super.transform(exp) : modifiedCall;
        }

        private Expression addGuard(MethodCallExpression mce) {
            // only add guard to methods of the form: logVar.logMethod(params)
            if (!(mce.getObjectExpression() instanceof VariableExpression)) {
                return null;
            }
            VariableExpression variableExpression = (VariableExpression) mce.getObjectExpression();
            if (!variableExpression.getName().equals(logFieldName) || !(variableExpression.getAccessedVariable() instanceof DynamicVariable)) {
                return null;
            }
            String methodName = mce.getMethodAsString();
            if (methodName == null)
                return null;
            if (!loggingStrategy.isLoggingMethod(methodName))
                return null;
            // since there is no saving
            if (usesSimpleMethodArgumentsOnly(mce))
                return null;
            variableExpression.setAccessedVariable(logNode);
            return loggingStrategy.wrapLoggingMethodCall(variableExpression, methodName, mce);
        }

        private boolean usesSimpleMethodArgumentsOnly(MethodCallExpression mce) {
            Expression arguments = mce.getArguments();
            if (arguments instanceof TupleExpression) {
                TupleExpression tuple = (TupleExpression) arguments;
                for (Expression exp : tuple.getExpressions()) {
                    if (!isSimpleExpression(exp))
                        return false;
                }
                return true;
            }
            return !isSimpleExpression(arguments);
        }

        private boolean isSimpleExpression(Expression exp) {
            if (exp instanceof ConstantExpression)
                return true;
            if (exp instanceof VariableExpression)
                return true;
            return false;
        }
    };
    transformer.visitClass(classNode);
    // GROOVY-6373: references to 'log' field are normally already FieldNodes by now, so revisit scoping
    new VariableScopeVisitor(sourceUnit, true).visitClass(classNode);
}
Also used : ClassNode(org.codehaus.groovy.ast.ClassNode) FieldNode(org.codehaus.groovy.ast.FieldNode) AnnotatedNode(org.codehaus.groovy.ast.AnnotatedNode) ConstantExpression(org.codehaus.groovy.ast.expr.ConstantExpression) GroovyBugError(org.codehaus.groovy.GroovyBugError) TupleExpression(org.codehaus.groovy.ast.expr.TupleExpression) BlockStatement(org.codehaus.groovy.ast.stmt.BlockStatement) VariableExpression(org.codehaus.groovy.ast.expr.VariableExpression) GroovyClassLoader(groovy.lang.GroovyClassLoader) MethodCallExpression(org.codehaus.groovy.ast.expr.MethodCallExpression) AnnotationNode(org.codehaus.groovy.ast.AnnotationNode) ConstantExpression(org.codehaus.groovy.ast.expr.ConstantExpression) MethodCallExpression(org.codehaus.groovy.ast.expr.MethodCallExpression) Expression(org.codehaus.groovy.ast.expr.Expression) VariableExpression(org.codehaus.groovy.ast.expr.VariableExpression) ClosureExpression(org.codehaus.groovy.ast.expr.ClosureExpression) TupleExpression(org.codehaus.groovy.ast.expr.TupleExpression) DynamicVariable(org.codehaus.groovy.ast.DynamicVariable) ClosureExpression(org.codehaus.groovy.ast.expr.ClosureExpression) VariableScopeVisitor(org.codehaus.groovy.classgen.VariableScopeVisitor) ClassCodeExpressionTransformer(org.codehaus.groovy.ast.ClassCodeExpressionTransformer)

Example 7 with MethodCallExpression

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

the class MemoizedASTTransformation method visit.

public void visit(ASTNode[] nodes, final SourceUnit source) {
    init(nodes, source);
    AnnotationNode annotationNode = (AnnotationNode) nodes[0];
    AnnotatedNode annotatedNode = (AnnotatedNode) nodes[1];
    if (MY_TYPE.equals(annotationNode.getClassNode()) && annotatedNode instanceof MethodNode) {
        MethodNode methodNode = (MethodNode) annotatedNode;
        if (methodNode.isAbstract()) {
            addError("Annotation " + MY_TYPE_NAME + " cannot be used for abstract methods.", methodNode);
            return;
        }
        if (methodNode.isVoidMethod()) {
            addError("Annotation " + MY_TYPE_NAME + " cannot be used for void methods.", methodNode);
            return;
        }
        ClassNode ownerClassNode = methodNode.getDeclaringClass();
        MethodNode delegatingMethod = buildDelegatingMethod(methodNode, ownerClassNode);
        ownerClassNode.addMethod(delegatingMethod);
        int modifiers = FieldNode.ACC_PRIVATE | FieldNode.ACC_FINAL;
        if (methodNode.isStatic()) {
            modifiers = modifiers | FieldNode.ACC_STATIC;
        }
        int protectedCacheSize = getMemberIntValue(annotationNode, PROTECTED_CACHE_SIZE_NAME);
        int maxCacheSize = getMemberIntValue(annotationNode, MAX_CACHE_SIZE_NAME);
        MethodCallExpression memoizeClosureCallExpression = buildMemoizeClosureCallExpression(delegatingMethod, protectedCacheSize, maxCacheSize);
        String memoizedClosureFieldName = buildUniqueName(ownerClassNode, CLOSURE_LABEL, methodNode);
        FieldNode memoizedClosureField = new FieldNode(memoizedClosureFieldName, modifiers, newClass(ClassHelper.CLOSURE_TYPE), null, memoizeClosureCallExpression);
        ownerClassNode.addField(memoizedClosureField);
        BlockStatement newCode = new BlockStatement();
        MethodCallExpression closureCallExpression = callX(fieldX(memoizedClosureField), CLOSURE_CALL_METHOD_NAME, args(methodNode.getParameters()));
        closureCallExpression.setImplicitThis(false);
        newCode.addStatement(returnS(closureCallExpression));
        methodNode.setCode(newCode);
        VariableScopeVisitor visitor = new VariableScopeVisitor(source);
        visitor.visitClass(ownerClassNode);
    }
}
Also used : ClassNode(org.codehaus.groovy.ast.ClassNode) MethodNode(org.codehaus.groovy.ast.MethodNode) MethodCallExpression(org.codehaus.groovy.ast.expr.MethodCallExpression) FieldNode(org.codehaus.groovy.ast.FieldNode) AnnotationNode(org.codehaus.groovy.ast.AnnotationNode) AnnotatedNode(org.codehaus.groovy.ast.AnnotatedNode) BlockStatement(org.codehaus.groovy.ast.stmt.BlockStatement) VariableScopeVisitor(org.codehaus.groovy.classgen.VariableScopeVisitor)

Example 8 with MethodCallExpression

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

the class ToStringASTTransformation method appendS.

private static Statement appendS(Expression result, Expression expr) {
    MethodCallExpression append = callX(result, "append", expr);
    append.setImplicitThis(false);
    return stmt(append);
}
Also used : MethodCallExpression(org.codehaus.groovy.ast.expr.MethodCallExpression)

Example 9 with MethodCallExpression

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

the class NewifyASTTransformation method isNewMethodStyle.

private static boolean isNewMethodStyle(MethodCallExpression mce) {
    final Expression obj = mce.getObjectExpression();
    final Expression meth = mce.getMethod();
    return (obj instanceof ClassExpression && meth instanceof ConstantExpression && ((ConstantExpression) meth).getValue().equals("new"));
}
Also used : ListExpression(org.codehaus.groovy.ast.expr.ListExpression) 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) DeclarationExpression(org.codehaus.groovy.ast.expr.DeclarationExpression) ClosureExpression(org.codehaus.groovy.ast.expr.ClosureExpression) ClassExpression(org.codehaus.groovy.ast.expr.ClassExpression) ConstantExpression(org.codehaus.groovy.ast.expr.ConstantExpression) ClassExpression(org.codehaus.groovy.ast.expr.ClassExpression)

Example 10 with MethodCallExpression

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

Aggregations

MethodCallExpression (org.codehaus.groovy.ast.expr.MethodCallExpression)131 VariableExpression (org.codehaus.groovy.ast.expr.VariableExpression)89 ArgumentListExpression (org.codehaus.groovy.ast.expr.ArgumentListExpression)81 Expression (org.codehaus.groovy.ast.expr.Expression)77 ConstantExpression (org.codehaus.groovy.ast.expr.ConstantExpression)73 ClassExpression (org.codehaus.groovy.ast.expr.ClassExpression)59 BinaryExpression (org.codehaus.groovy.ast.expr.BinaryExpression)58 ClosureExpression (org.codehaus.groovy.ast.expr.ClosureExpression)51 ClassNode (org.codehaus.groovy.ast.ClassNode)43 TupleExpression (org.codehaus.groovy.ast.expr.TupleExpression)42 StaticMethodCallExpression (org.codehaus.groovy.ast.expr.StaticMethodCallExpression)40 MethodNode (org.codehaus.groovy.ast.MethodNode)36 PropertyExpression (org.codehaus.groovy.ast.expr.PropertyExpression)36 BlockStatement (org.codehaus.groovy.ast.stmt.BlockStatement)36 ConstructorCallExpression (org.codehaus.groovy.ast.expr.ConstructorCallExpression)35 ExpressionStatement (org.codehaus.groovy.ast.stmt.ExpressionStatement)35 DeclarationExpression (org.codehaus.groovy.ast.expr.DeclarationExpression)34 BooleanExpression (org.codehaus.groovy.ast.expr.BooleanExpression)31 FieldNode (org.codehaus.groovy.ast.FieldNode)26 Parameter (org.codehaus.groovy.ast.Parameter)23