Search in sources :

Example 76 with MethodCallExpression

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

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);
            }
            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 transformMethodCallExpression(Expression exp) {
            MethodCallExpression mce = (MethodCallExpression) exp;
            if (!(mce.getObjectExpression() instanceof VariableExpression)) {
                return exp;
            }
            VariableExpression variableExpression = (VariableExpression) mce.getObjectExpression();
            if (!variableExpression.getName().equals(logFieldName) || !(variableExpression.getAccessedVariable() instanceof DynamicVariable)) {
                return exp;
            }
            String methodName = mce.getMethodAsString();
            if (methodName == null)
                return exp;
            if (usesSimpleMethodArgumentsOnly(mce))
                return exp;
            variableExpression.setAccessedVariable(logNode);
            if (!loggingStrategy.isLoggingMethod(methodName))
                return exp;
            return loggingStrategy.wrapLoggingMethodCall(variableExpression, methodName, exp);
        }

        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) VariableExpression(org.codehaus.groovy.ast.expr.VariableExpression) GroovyClassLoader(groovy.lang.GroovyClassLoader) MethodCallExpression(org.codehaus.groovy.ast.expr.MethodCallExpression) AnnotationNode(org.codehaus.groovy.ast.AnnotationNode) VariableExpression(org.codehaus.groovy.ast.expr.VariableExpression) ConstantExpression(org.codehaus.groovy.ast.expr.ConstantExpression) TupleExpression(org.codehaus.groovy.ast.expr.TupleExpression) MethodCallExpression(org.codehaus.groovy.ast.expr.MethodCallExpression) Expression(org.codehaus.groovy.ast.expr.Expression) DynamicVariable(org.codehaus.groovy.ast.DynamicVariable) VariableScopeVisitor(org.codehaus.groovy.classgen.VariableScopeVisitor) ClassCodeExpressionTransformer(org.codehaus.groovy.ast.ClassCodeExpressionTransformer)

Example 77 with MethodCallExpression

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

the class NewifyASTTransformation method transform.

public Expression transform(Expression expr) {
    if (expr == null)
        return null;
    if (expr instanceof MethodCallExpression && candidate == null) {
        MethodCallExpression mce = (MethodCallExpression) expr;
        Expression args = transform(mce.getArguments());
        if (isNewifyCandidate(mce)) {
            Expression transformed = transformMethodCall(mce, args);
            transformed.setSourcePosition(mce);
            return transformed;
        }
        Expression method = transform(mce.getMethod());
        Expression object = transform(mce.getObjectExpression());
        MethodCallExpression transformed = callX(object, method, args);
        transformed.setSourcePosition(mce);
        return transformed;
    } else if (expr instanceof ClosureExpression) {
        ClosureExpression ce = (ClosureExpression) expr;
        ce.getCode().visit(this);
    } else if (expr instanceof ConstructorCallExpression) {
        ConstructorCallExpression cce = (ConstructorCallExpression) expr;
        if (cce.isUsingAnonymousInnerClass()) {
            cce.getType().visitContents(this);
        }
    } else if (expr instanceof DeclarationExpression) {
        DeclarationExpression de = (DeclarationExpression) expr;
        if (de == candidate || auto) {
            candidate = null;
            Expression left = de.getLeftExpression();
            Expression right = transform(de.getRightExpression());
            DeclarationExpression newDecl = new DeclarationExpression(left, de.getOperation(), right);
            newDecl.addAnnotations(de.getAnnotations());
            return newDecl;
        }
        return de;
    }
    return expr.transformExpression(this);
}
Also used : MethodCallExpression(org.codehaus.groovy.ast.expr.MethodCallExpression) 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) ConstructorCallExpression(org.codehaus.groovy.ast.expr.ConstructorCallExpression) DeclarationExpression(org.codehaus.groovy.ast.expr.DeclarationExpression) ClosureExpression(org.codehaus.groovy.ast.expr.ClosureExpression)

Example 78 with MethodCallExpression

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

the class AutoCloneASTTransformation method createCloneSerialization.

private void createCloneSerialization(ClassNode cNode) {
    final BlockStatement body = new BlockStatement();
    // def baos = new ByteArrayOutputStream()
    final Expression baos = varX("baos");
    body.addStatement(declS(baos, ctorX(BAOS_TYPE)));
    // baos.withObjectOutputStream{ it.writeObject(this) }
    MethodCallExpression writeObject = callX(castX(OOS_TYPE, varX("it")), "writeObject", varX("this"));
    writeObject.setImplicitThis(false);
    ClosureExpression writeClos = closureX(block(stmt(writeObject)));
    writeClos.setVariableScope(new VariableScope());
    body.addStatement(stmt(callX(baos, "withObjectOutputStream", args(writeClos))));
    // def bais = new ByteArrayInputStream(baos.toByteArray())
    final Expression bais = varX("bais");
    body.addStatement(declS(bais, ctorX(BAIS_TYPE, args(callX(baos, "toByteArray")))));
    // return bais.withObjectInputStream(getClass().classLoader){ (<type>) it.readObject() }
    MethodCallExpression readObject = callX(castX(OIS_TYPE, varX("it")), "readObject");
    readObject.setImplicitThis(false);
    ClosureExpression readClos = closureX(block(stmt(castX(GenericsUtils.nonGeneric(cNode), readObject))));
    readClos.setVariableScope(new VariableScope());
    Expression classLoader = callX(callThisX("getClass"), "getClassLoader");
    body.addStatement(returnS(callX(bais, "withObjectInputStream", args(classLoader, readClos))));
    new VariableScopeVisitor(sourceUnit, true).visitClass(cNode);
    ClassNode[] exceptions = { make(CloneNotSupportedException.class) };
    cNode.addMethod("clone", ACC_PUBLIC, GenericsUtils.nonGeneric(cNode), Parameter.EMPTY_ARRAY, exceptions, body);
}
Also used : ClassNode(org.codehaus.groovy.ast.ClassNode) MethodCallExpression(org.codehaus.groovy.ast.expr.MethodCallExpression) PropertyExpression(org.codehaus.groovy.ast.expr.PropertyExpression) ConstantExpression(org.codehaus.groovy.ast.expr.ConstantExpression) MethodCallExpression(org.codehaus.groovy.ast.expr.MethodCallExpression) Expression(org.codehaus.groovy.ast.expr.Expression) ClosureExpression(org.codehaus.groovy.ast.expr.ClosureExpression) ClassExpression(org.codehaus.groovy.ast.expr.ClassExpression) BlockStatement(org.codehaus.groovy.ast.stmt.BlockStatement) ClosureExpression(org.codehaus.groovy.ast.expr.ClosureExpression) VariableScopeVisitor(org.codehaus.groovy.classgen.VariableScopeVisitor) VariableScope(org.codehaus.groovy.ast.VariableScope)

Example 79 with MethodCallExpression

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

the class ToStringASTTransformation method calculateToStringStatements.

private static Expression calculateToStringStatements(ClassNode cNode, boolean includeSuper, boolean includeFields, List<String> excludes, List<String> includes, boolean includeNames, boolean ignoreNulls, boolean includePackage, boolean includeSuperProperties, BlockStatement body) {
    // def _result = new StringBuilder()
    final Expression result = varX("_result");
    body.addStatement(declS(result, ctorX(STRINGBUILDER_TYPE)));
    // def $toStringFirst = true
    final VariableExpression first = varX("$toStringFirst");
    body.addStatement(declS(first, constX(Boolean.TRUE)));
    // <class_name>(
    String className = (includePackage) ? cNode.getName() : cNode.getNameWithoutPackage();
    body.addStatement(appendS(result, constX(className + "(")));
    // append properties
    List<PropertyNode> pList;
    if (includeSuperProperties) {
        pList = getAllProperties(cNode);
        Iterator<PropertyNode> pIterator = pList.iterator();
        while (pIterator.hasNext()) {
            if (pIterator.next().isStatic()) {
                pIterator.remove();
            }
        }
    } else {
        pList = getInstanceProperties(cNode);
    }
    for (PropertyNode pNode : pList) {
        if (shouldSkip(pNode.getName(), excludes, includes))
            continue;
        Expression getter = getterX(cNode, pNode);
        appendValue(body, result, first, getter, pNode.getName(), includeNames, ignoreNulls);
    }
    // append fields if needed
    if (includeFields) {
        List<FieldNode> fList = new ArrayList<FieldNode>();
        fList.addAll(getInstanceNonPropertyFields(cNode));
        for (FieldNode fNode : fList) {
            if (shouldSkip(fNode.getName(), excludes, includes))
                continue;
            appendValue(body, result, first, varX(fNode), fNode.getName(), includeNames, ignoreNulls);
        }
    }
    // append super if needed
    if (includeSuper) {
        appendCommaIfNotFirst(body, result, first);
        appendPrefix(body, result, "super", includeNames);
        // not through MOP to avoid infinite recursion
        body.addStatement(appendS(result, callSuperX("toString")));
    }
    // wrap up
    body.addStatement(appendS(result, constX(")")));
    MethodCallExpression toString = callX(result, "toString");
    toString.setImplicitThis(false);
    return toString;
}
Also used : FieldNode(org.codehaus.groovy.ast.FieldNode) MethodCallExpression(org.codehaus.groovy.ast.expr.MethodCallExpression) VariableExpression(org.codehaus.groovy.ast.expr.VariableExpression) ConstantExpression(org.codehaus.groovy.ast.expr.ConstantExpression) MethodCallExpression(org.codehaus.groovy.ast.expr.MethodCallExpression) Expression(org.codehaus.groovy.ast.expr.Expression) PropertyNode(org.codehaus.groovy.ast.PropertyNode) ArrayList(java.util.ArrayList) VariableExpression(org.codehaus.groovy.ast.expr.VariableExpression) ToString(groovy.transform.ToString)

Example 80 with MethodCallExpression

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

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)

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