You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@groovy.apache.org by em...@apache.org on 2021/12/19 20:49:48 UTC

[groovy] branch master updated: GROOVY-5736: xform loader for annotations and class loader for libraries

This is an automated email from the ASF dual-hosted git repository.

emilles pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/groovy.git


The following commit(s) were added to refs/heads/master by this push:
     new aadf2cc  GROOVY-5736: xform loader for annotations and class loader for libraries
aadf2cc is described below

commit aadf2cc3bcee94fa342f957c6afc85060ab55094
Author: Eric Milles <er...@thomsonreuters.com>
AuthorDate: Sun Dec 19 14:49:40 2021 -0600

    GROOVY-5736: xform loader for annotations and class loader for libraries
---
 .../groovy/transform/LogASTTransformation.java     | 95 ++++++++++++----------
 1 file changed, 50 insertions(+), 45 deletions(-)

diff --git a/src/main/java/org/codehaus/groovy/transform/LogASTTransformation.java b/src/main/java/org/codehaus/groovy/transform/LogASTTransformation.java
index 16a85f8..9400ff7 100644
--- a/src/main/java/org/codehaus/groovy/transform/LogASTTransformation.java
+++ b/src/main/java/org/codehaus/groovy/transform/LogASTTransformation.java
@@ -46,9 +46,11 @@ import org.codehaus.groovy.runtime.DefaultGroovyMethods;
 import java.lang.reflect.Method;
 import java.lang.reflect.Modifier;
 
-import org.objectweb.asm.Opcodes;
-
 import static org.apache.groovy.ast.tools.VisibilityUtils.getVisibility;
+import static org.objectweb.asm.Opcodes.ACC_FINAL;
+import static org.objectweb.asm.Opcodes.ACC_PRIVATE;
+import static org.objectweb.asm.Opcodes.ACC_STATIC;
+import static org.objectweb.asm.Opcodes.ACC_TRANSIENT;
 
 /**
  * This class provides an AST Transformation to add a log field to a class.
@@ -67,13 +69,17 @@ public class LogASTTransformation extends AbstractASTTransformation implements C
     private CompilationUnit compilationUnit;
 
     @Override
-    public void visit(ASTNode[] nodes, final SourceUnit source) {
-        init(nodes, source);
+    public void setCompilationUnit(final CompilationUnit compilationUnit) {
+        this.compilationUnit = compilationUnit;
+    }
+
+    @Override
+    public void visit(final ASTNode[] nodes, final SourceUnit sourceUnit) {
+        init(nodes, sourceUnit);
         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);
+        final LoggingStrategy loggingStrategy = createLoggingStrategy(logAnnotation, sourceUnit.getClassLoader(), compilationUnit.getTransformLoader());
         if (loggingStrategy == null) return;
 
         final String logFieldName = lookupLogFieldName(logAnnotation);
@@ -92,11 +98,11 @@ public class LogASTTransformation extends AbstractASTTransformation implements C
 
             @Override
             protected SourceUnit getSourceUnit() {
-                return source;
+                return sourceUnit;
             }
 
             @Override
-            public Expression transform(Expression exp) {
+            public Expression transform(final Expression exp) {
                 if (exp == null) return null;
                 if (exp instanceof MethodCallExpression) {
                     return transformMethodCallExpression(exp);
@@ -108,7 +114,7 @@ public class LogASTTransformation extends AbstractASTTransformation implements C
             }
 
             @Override
-            public void visitClass(ClassNode node) {
+            public void visitClass(final 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);
@@ -126,7 +132,7 @@ public class LogASTTransformation extends AbstractASTTransformation implements C
                 super.visitClass(node);
             }
 
-            private Expression transformClosureExpression(ClosureExpression exp) {
+            private Expression transformClosureExpression(final ClosureExpression exp) {
                 if (exp.getCode() instanceof BlockStatement) {
                     BlockStatement code = (BlockStatement) exp.getCode();
                     super.visitBlockStatement(code);
@@ -134,12 +140,12 @@ public class LogASTTransformation extends AbstractASTTransformation implements C
                 return exp;
             }
 
-            private Expression transformMethodCallExpression(Expression exp) {
+            private Expression transformMethodCallExpression(final Expression exp) {
                 Expression modifiedCall = addGuard((MethodCallExpression) exp);
                 return modifiedCall == null ? super.transform(exp) : modifiedCall;
             }
 
-            private Expression addGuard(MethodCallExpression mce) {
+            private Expression addGuard(final MethodCallExpression mce) {
                 // only add guard to methods of the form: logVar.logMethod(params)
                 if (!(mce.getObjectExpression() instanceof VariableExpression)) {
                     return null;
@@ -161,7 +167,7 @@ public class LogASTTransformation extends AbstractASTTransformation implements C
                 return loggingStrategy.wrapLoggingMethodCall(variableExpression, methodName, mce);
             }
 
-            private boolean usesSimpleMethodArgumentsOnly(MethodCallExpression mce) {
+            private boolean usesSimpleMethodArgumentsOnly(final MethodCallExpression mce) {
                 Expression arguments = mce.getArguments();
                 if (arguments instanceof TupleExpression) {
                     TupleExpression tuple = (TupleExpression) arguments;
@@ -173,7 +179,7 @@ public class LogASTTransformation extends AbstractASTTransformation implements C
                 return !isSimpleExpression(arguments);
             }
 
-            private boolean isSimpleExpression(Expression exp) {
+            private boolean isSimpleExpression(final Expression exp) {
                 if (exp instanceof ConstantExpression) return true;
                 if (exp instanceof VariableExpression) return true;
                 return false;
@@ -186,7 +192,7 @@ public class LogASTTransformation extends AbstractASTTransformation implements C
         new VariableScopeVisitor(sourceUnit, true).visitClass(classNode);
     }
 
-    private static String lookupLogFieldName(AnnotationNode logAnnotation) {
+    private static String lookupLogFieldName(final AnnotationNode logAnnotation) {
         Expression member = logAnnotation.getMember("value");
         if (member != null && member.getText() != null) {
             return member.getText();
@@ -195,7 +201,7 @@ public class LogASTTransformation extends AbstractASTTransformation implements C
         }
     }
 
-    private static String lookupCategoryName(AnnotationNode logAnnotation) {
+    private static String lookupCategoryName(final AnnotationNode logAnnotation) {
         Expression member = logAnnotation.getMember("category");
         if (member != null && member.getText() != null) {
             return member.getText();
@@ -203,65 +209,66 @@ public class LogASTTransformation extends AbstractASTTransformation implements C
         return DEFAULT_CATEGORY_NAME;
     }
 
-    private int lookupLogFieldModifiers(AnnotatedNode targetClass, AnnotationNode logAnnotation) {
-        int modifiers = getVisibility(logAnnotation, targetClass, ClassNode.class, Opcodes.ACC_PRIVATE);
-        return Opcodes.ACC_FINAL | Opcodes.ACC_TRANSIENT | Opcodes.ACC_STATIC | modifiers;
+    private int lookupLogFieldModifiers(final AnnotatedNode targetClass, final AnnotationNode logAnnotation) {
+        int modifiers = getVisibility(logAnnotation, targetClass, ClassNode.class, ACC_PRIVATE);
+        return ACC_FINAL | ACC_STATIC | ACC_TRANSIENT | modifiers;
     }
 
-    private static LoggingStrategy createLoggingStrategy(AnnotationNode logAnnotation, GroovyClassLoader loader) {
-
+    private static LoggingStrategy createLoggingStrategy(final AnnotationNode logAnnotation, final ClassLoader classLoader, final ClassLoader xformLoader) {
         String annotationName = logAnnotation.getClassNode().getName();
 
-        Class annotationClass;
+        Class<?> annotationClass;
         try {
-            annotationClass = Class.forName(annotationName, false, loader);
-        } catch (Throwable e) {
+            annotationClass = Class.forName(annotationName, false, xformLoader);
+        } catch (Throwable t) {
             throw new RuntimeException("Could not resolve class named " + annotationName);
         }
 
         Method annotationMethod;
         try {
             annotationMethod = annotationClass.getDeclaredMethod("loggingStrategy", (Class[]) null);
-        } catch (Throwable e) {
+        } catch (Throwable t) {
             throw new RuntimeException("Could not find method named loggingStrategy on class named " + annotationName);
         }
 
         Object defaultValue;
         try {
             defaultValue = annotationMethod.getDefaultValue();
-        } catch (Throwable e) {
+        } catch (Throwable t) {
             throw new RuntimeException("Could not find default value of method named loggingStrategy on class named " + annotationName);
         }
 
-        if (!LoggingStrategy.class.isAssignableFrom((Class) defaultValue)
-                && !LoggingStrategyV2.class.isAssignableFrom((Class) defaultValue)) {
+        if (!LoggingStrategy.class.isAssignableFrom((Class<?>) defaultValue)
+                && !LoggingStrategyV2.class.isAssignableFrom((Class<?>) defaultValue)) {
             throw new RuntimeException("Default loggingStrategy value on class named " + annotationName + " is not a LoggingStrategy");
         }
 
-        // try V2 configurable logging strategy
+        // try configurable logging strategy
         try {
             Class<? extends LoggingStrategyV2> strategyClass = (Class<? extends LoggingStrategyV2>) defaultValue;
             if (AbstractLoggingStrategy.class.isAssignableFrom(strategyClass)) {
-                return DefaultGroovyMethods.newInstance(strategyClass, new Object[]{loader});
+                return DefaultGroovyMethods.newInstance(strategyClass, new Object[]{classLoader});
             } else {
                 return strategyClass.getDeclaredConstructor().newInstance();
             }
-        } catch (Exception e) {
+        } catch (Exception ignore) {
         }
 
         // try legacy logging strategy
         try {
             Class<? extends LoggingStrategy> strategyClass = (Class<? extends LoggingStrategy>) defaultValue;
             if (AbstractLoggingStrategy.class.isAssignableFrom(strategyClass)) {
-                return DefaultGroovyMethods.newInstance(strategyClass, new Object[]{loader});
+                return DefaultGroovyMethods.newInstance(strategyClass, new Object[]{classLoader});
             } else {
                 return strategyClass.getDeclaredConstructor().newInstance();
             }
-        } catch (Exception e) {
-            return null;
+        } catch (Exception ignore) {
         }
+
+        return null;
     }
 
+    //--------------------------------------------------------------------------
 
     /**
      * A LoggingStrategy defines how to wire a new logger instance into an existing class.
@@ -307,6 +314,7 @@ public class LogASTTransformation extends AbstractASTTransformation implements C
     }
 
     public abstract static class AbstractLoggingStrategyV2 extends AbstractLoggingStrategy implements LoggingStrategyV2 {
+
         protected AbstractLoggingStrategyV2(final GroovyClassLoader loader) {
             super(loader);
         }
@@ -316,12 +324,13 @@ public class LogASTTransformation extends AbstractASTTransformation implements C
         }
 
         @Override
-        public FieldNode addLoggerFieldToClass(ClassNode classNode, String fieldName, String categoryName) {
+        public FieldNode addLoggerFieldToClass(final ClassNode classNode, final String fieldName, final String categoryName) {
             throw new UnsupportedOperationException("This logger requires a later version of Groovy");
         }
     }
 
     public abstract static class AbstractLoggingStrategy implements LoggingStrategy {
+
         protected final GroovyClassLoader loader;
 
         protected AbstractLoggingStrategy(final GroovyClassLoader loader) {
@@ -333,25 +342,21 @@ public class LogASTTransformation extends AbstractASTTransformation implements C
         }
 
         @Override
-        public String getCategoryName(ClassNode classNode, String categoryName) {
+        public String getCategoryName(final ClassNode classNode, final String categoryName) {
             if (categoryName.equals(DEFAULT_CATEGORY_NAME)) {
                 return classNode.getName();
             }
             return categoryName;
         }
 
-        protected ClassNode classNode(String name) {
-            ClassLoader cl = loader == null ? this.getClass().getClassLoader() : loader;
+        protected ClassNode classNode(final String name) {
+            ClassLoader cl = loader != null ? loader : getClass().getClassLoader();
             try {
-                return ClassHelper.make(Class.forName(name, false, cl));
+                Class<?> c = Class.forName(name, false, cl);
+                return ClassHelper.make(c);
             } catch (ClassNotFoundException e) {
-                throw new GroovyRuntimeException("Unable to load logging class", e);
+                throw new GroovyRuntimeException("Unable to load class: " + name, e);
             }
         }
     }
-
-    @Override
-    public void setCompilationUnit(final CompilationUnit unit) {
-        this.compilationUnit = unit;
-    }
 }