@Override public void visitAnnotations(AnnotatedNode node) { boolean oldInAnnotation = inAnnotation; inAnnotation = true; super.visitAnnotations(node); inAnnotation = oldInAnnotation; }
@Override public void visitMethod(MethodNode node) { if (node.isScriptBody()) super.visitMethod(node); }
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) { 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); }
@Override protected void visitConstructorOrMethod(MethodNode node, boolean isConstructor) { this.currentMethod = node; super.visitConstructorOrMethod(node, isConstructor); this.currentMethod = null; }
public void visitClass(ClassNode node, SourceUnit source) { this.currentClass = node; this.source = source; super.visitClass(node); }