You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@groovy.apache.org by su...@apache.org on 2020/02/14 16:50:28 UTC

[groovy] 01/01: Try to address classnode position issue - 2

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

sunlan pushed a commit to branch danielsun/classnode-position-issue
in repository https://gitbox.apache.org/repos/asf/groovy.git

commit 157e6c14bba3e498ddf9e7bd84142d6b855c4eab
Author: Daniel Sun <su...@apache.org>
AuthorDate: Sat Feb 15 00:49:46 2020 +0800

    Try to address classnode position issue - 2
---
 .../java/org/codehaus/groovy/ast/ClassHelper.java  |  4 +-
 .../java/org/codehaus/groovy/ast/ClassNode.java    | 77 ++++++++++++++++++++--
 2 files changed, 73 insertions(+), 8 deletions(-)

diff --git a/src/main/java/org/codehaus/groovy/ast/ClassHelper.java b/src/main/java/org/codehaus/groovy/ast/ClassHelper.java
index 17bcc8d..648b484 100644
--- a/src/main/java/org/codehaus/groovy/ast/ClassHelper.java
+++ b/src/main/java/org/codehaus/groovy/ast/ClassHelper.java
@@ -175,11 +175,11 @@ public class ClassHelper {
 
     public static final String OBJECT = "java.lang.Object";
 
-    public static ClassNode makeCached(Class c) {
+    public static ClassNode makeCached(Class<?> c) {
         final SoftReference<ClassNode> classNodeSoftReference = ClassHelperCache.classCache.get(c);
         ClassNode classNode;
         if (classNodeSoftReference == null || (classNode = classNodeSoftReference.get()) == null) {
-            classNode = new ClassNode(c);
+            classNode = new ClassNode(c, false);
             ClassHelperCache.classCache.put(c, new SoftReference<ClassNode>(classNode));
             VMPluginFactory.getPlugin().setAdditionalClassInformation(classNode);
         }
diff --git a/src/main/java/org/codehaus/groovy/ast/ClassNode.java b/src/main/java/org/codehaus/groovy/ast/ClassNode.java
index 15f6eb0..3486d33 100644
--- a/src/main/java/org/codehaus/groovy/ast/ClassNode.java
+++ b/src/main/java/org/codehaus/groovy/ast/ClassNode.java
@@ -47,6 +47,8 @@ import java.util.ListIterator;
 import java.util.Map;
 import java.util.Optional;
 import java.util.Set;
+import java.util.logging.Level;
+import java.util.logging.Logger;
 import java.util.stream.Collectors;
 
 import static java.util.Arrays.stream;
@@ -109,6 +111,7 @@ import static java.util.stream.Collectors.joining;
  * @see org.codehaus.groovy.ast.ClassHelper
  */
 public class ClassNode extends AnnotatedNode implements Opcodes {
+    private static final Logger LOGGER = Logger.getLogger(ClassNode.class.getName());
 
     private static class MapOfLists {
         Map<Object, List<MethodNode>> map;
@@ -152,6 +155,7 @@ public class ClassNode extends AnnotatedNode implements Opcodes {
     private ClassNode superClass;
     protected boolean isPrimaryNode;
     protected List<InnerClassNode> innerClasses;
+    private boolean positionMutable = true;
 
     /**
      * The AST Transformations to be applied during compilation.
@@ -247,11 +251,8 @@ public class ClassNode extends AnnotatedNode implements Opcodes {
         this.componentType = componentType;
     }
 
-    /**
-     * Creates a non-primary {@code ClassNode} from a real class.
-     */
-    public ClassNode(Class<?> c) {
-        this(c.getName(), c.getModifiers(), null, null, MixinNode.EMPTY_ARRAY);
+    public ClassNode(Class<?> c, boolean positionMutable) {
+        this(c.getName(), c.getModifiers(), null, null, MixinNode.EMPTY_ARRAY, positionMutable);
         clazz = c;
         lazyInitDone = false;
         isPrimaryNode = false;
@@ -259,6 +260,13 @@ public class ClassNode extends AnnotatedNode implements Opcodes {
     }
 
     /**
+     * Creates a non-primary {@code ClassNode} from a real class.
+     */
+    public ClassNode(Class<?> c) {
+        this(c, true);
+    }
+
+    /**
      * The complete class structure will be initialized only when really needed
      * to avoid having too many objects during compilation.
      */
@@ -319,13 +327,15 @@ public class ClassNode extends AnnotatedNode implements Opcodes {
      * @param superClass the base class; use "java.lang.Object" if no direct base class
      * @param interfaces the interfaces for this class
      * @param mixins     the mixins for this class
+     * @param positionMutable     the node position is mutable or not
      */
-    public ClassNode(String name, int modifiers, ClassNode superClass, ClassNode[] interfaces, MixinNode[] mixins) {
+    public ClassNode(String name, int modifiers, ClassNode superClass, ClassNode[] interfaces, MixinNode[] mixins, boolean positionMutable) {
         this.name = name;
         this.modifiers = modifiers;
         this.superClass = superClass;
         this.interfaces = interfaces;
         this.mixins = mixins;
+        this.positionMutable = positionMutable;
 
         isPrimaryNode = true;
         if (superClass != null) {
@@ -339,6 +349,17 @@ public class ClassNode extends AnnotatedNode implements Opcodes {
     }
 
     /**
+     * @param name       the fully-qualified name of the class
+     * @param modifiers  the modifiers; see {@link org.objectweb.asm.Opcodes}
+     * @param superClass the base class; use "java.lang.Object" if no direct base class
+     * @param interfaces the interfaces for this class
+     * @param mixins     the mixins for this class
+     */
+    public ClassNode(String name, int modifiers, ClassNode superClass, ClassNode[] interfaces, MixinNode[] mixins) {
+        this(name, modifiers, superClass, interfaces, mixins, true);
+    }
+
+    /**
      * Sets the superclass of this {@code ClassNode}.
      */
     public void setSuperClass(ClassNode superClass) {
@@ -1539,4 +1560,48 @@ public class ClassNode extends AnnotatedNode implements Opcodes {
     public String getText() {
         return getName();
     }
+
+    @Override
+    public void setLineNumber(int lineNumber) {
+        if (!positionMutable) {
+            if (LOGGER.isLoggable(Level.WARNING)) {
+                LOGGER.warning("The node position of class node[" + this + "] is immutable, but `setLineNumber` is invoked, lineNumber: " + lineNumber);
+            }
+            return;
+        }
+        super.setLineNumber(lineNumber);
+    }
+
+    @Override
+    public void setColumnNumber(int columnNumber) {
+        if (!positionMutable) {
+            if (LOGGER.isLoggable(Level.WARNING)) {
+                LOGGER.warning("The node position of class node[" + this + "] is immutable, but `setColumnNumber` is invoked, columnNumber: " + columnNumber);
+            }
+            return;
+        }
+        super.setColumnNumber(columnNumber);
+    }
+
+    @Override
+    public void setLastLineNumber(int lastLineNumber) {
+        if (!positionMutable) {
+            if (LOGGER.isLoggable(Level.WARNING)) {
+                LOGGER.warning("The node position of class node[" + this + "] is immutable, but `setLastLineNumber` is invoked, lastLineNumber: " + lastLineNumber);
+            }
+            return;
+        }
+        super.setLastLineNumber(lastLineNumber);
+    }
+
+    @Override
+    public void setLastColumnNumber(int lastColumnNumber) {
+        if (!positionMutable) {
+            if (LOGGER.isLoggable(Level.WARNING)) {
+                LOGGER.warning("The node position of class node[" + this + "] is immutable, but `setLastColumnNumber` is invoked, lastColumnNumber: " + lastColumnNumber);
+            }
+            return;
+        }
+        super.setLastColumnNumber(lastColumnNumber);
+    }
 }