You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@groovy.apache.org by pa...@apache.org on 2022/01/25 10:56:53 UTC

[groovy] branch GROOVY_4_0_X updated (59c15ca -> fb2754a)

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

paulk pushed a change to branch GROOVY_4_0_X
in repository https://gitbox.apache.org/repos/asf/groovy.git.


    from 59c15ca  GROOVY-10457: support `@CompileStatic` class with `@CompileDynamic` ctor
     new 700d264  GROOVY-10434: ClassNode isSealed() refactoring: hide implementation details about sealed native/annotation flags
     new fb2754a  GROOVY-10434: ClassNode isRecord() refactoring: additional clarification when information will be available

The 2 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 .../java/org/codehaus/groovy/ast/ClassNode.java    | 14 ++++++----
 .../groovy/classgen/AsmClassGenerator.java         |  8 +++---
 .../transform/RecordTypeASTTransformation.java     | 12 +++++++++
 .../groovy/transform/SealedASTTransformation.java  | 30 ++++++++++++++++++++--
 4 files changed, 53 insertions(+), 11 deletions(-)

[groovy] 01/02: GROOVY-10434: ClassNode isSealed() refactoring: hide implementation details about sealed native/annotation flags

Posted by pa...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

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

commit 700d26472d39b4b47eb2b976a2b10394c971790a
Author: Paul King <pa...@asert.com.au>
AuthorDate: Tue Jan 25 12:54:36 2022 +1000

    GROOVY-10434: ClassNode isSealed() refactoring: hide implementation details about sealed native/annotation flags
---
 .../groovy/classgen/AsmClassGenerator.java         |  8 +++---
 .../groovy/transform/SealedASTTransformation.java  | 30 ++++++++++++++++++++--
 2 files changed, 32 insertions(+), 6 deletions(-)

diff --git a/src/main/java/org/codehaus/groovy/classgen/AsmClassGenerator.java b/src/main/java/org/codehaus/groovy/classgen/AsmClassGenerator.java
index 32c9ce5..658c913 100644
--- a/src/main/java/org/codehaus/groovy/classgen/AsmClassGenerator.java
+++ b/src/main/java/org/codehaus/groovy/classgen/AsmClassGenerator.java
@@ -20,7 +20,6 @@ package org.codehaus.groovy.classgen;
 
 import groovy.lang.GroovyRuntimeException;
 import groovy.transform.Sealed;
-import groovy.transform.SealedMode;
 import org.apache.groovy.ast.tools.ExpressionUtils;
 import org.apache.groovy.io.StringBuilderWriter;
 import org.codehaus.groovy.GroovyBugError;
@@ -154,7 +153,8 @@ import static org.codehaus.groovy.ast.tools.GeneralUtils.fieldX;
 import static org.codehaus.groovy.ast.tools.GeneralUtils.maybeFallsThrough;
 import static org.codehaus.groovy.ast.tools.GeneralUtils.propX;
 import static org.codehaus.groovy.ast.tools.GeneralUtils.thisPropX;
-import static org.codehaus.groovy.transform.SealedASTTransformation.SEALED_ALWAYS_ANNOTATE;
+import static org.codehaus.groovy.transform.SealedASTTransformation.sealedNative;
+import static org.codehaus.groovy.transform.SealedASTTransformation.sealedSkipAnnotation;
 import static org.codehaus.groovy.transform.sc.StaticCompilationMetadataKeys.PROPERTY_OWNER;
 import static org.objectweb.asm.Opcodes.AASTORE;
 import static org.objectweb.asm.Opcodes.ACC_ENUM;
@@ -377,7 +377,7 @@ public class AsmClassGenerator extends ClassGenerator {
             for (Iterator<InnerClassNode> it = classNode.getInnerClasses(); it.hasNext(); ) {
                 makeInnerClassEntry(it.next());
             }
-            if (classNode.getNodeMetaData(SealedMode.class) == SealedMode.NATIVE) {
+            if (sealedNative(classNode)) {
                 for (ClassNode sub: classNode.getPermittedSubclasses()) {
                     classVisitor.visitPermittedSubclass(sub.getName());
                 }
@@ -1992,7 +1992,7 @@ public class AsmClassGenerator extends ClassGenerator {
             // skip built-in properties
             if (an.isBuiltIn()) continue;
             if (an.hasSourceRetention()) continue;
-            if (an.getClassNode().getName().equals(Sealed.class.getName()) && sourceNode.getNodeMetaData(SealedMode.class) == SealedMode.NATIVE && Boolean.FALSE.equals(sourceNode.getNodeMetaData(SEALED_ALWAYS_ANNOTATE))) continue;
+            if (an.getClassNode().getName().equals(Sealed.class.getName()) && sealedNative(sourceNode) && sealedSkipAnnotation(sourceNode)) continue;
 
             AnnotationVisitor av = getAnnotationVisitor(targetNode, an, visitor);
             visitAnnotationAttributes(an, av);
diff --git a/src/main/java/org/codehaus/groovy/transform/SealedASTTransformation.java b/src/main/java/org/codehaus/groovy/transform/SealedASTTransformation.java
index 31dee5e..5f38c68 100644
--- a/src/main/java/org/codehaus/groovy/transform/SealedASTTransformation.java
+++ b/src/main/java/org/codehaus/groovy/transform/SealedASTTransformation.java
@@ -21,6 +21,7 @@ package org.codehaus.groovy.transform;
 import groovy.transform.Sealed;
 import groovy.transform.SealedMode;
 import groovy.transform.SealedOptions;
+import org.apache.groovy.lang.annotation.Incubating;
 import org.codehaus.groovy.ast.ASTNode;
 import org.codehaus.groovy.ast.AnnotatedNode;
 import org.codehaus.groovy.ast.AnnotationNode;
@@ -46,7 +47,9 @@ public class SealedASTTransformation extends AbstractASTTransformation {
     private static final String SEALED_NAME = "@" + SEALED_CLASS.getSimpleName();
     private static final ClassNode SEALED_TYPE = make(SEALED_CLASS);
     private static final ClassNode SEALED_OPTIONS_TYPE = make(SealedOptions.class);
-    public static final String SEALED_ALWAYS_ANNOTATE = "groovy.transform.SealedOptions.alwaysAnnotate";
+    private static final String SEALED_ALWAYS_ANNOTATE_KEY = "groovy.transform.SealedOptions.alwaysAnnotate";
+    @Deprecated
+    public static final String SEALED_ALWAYS_ANNOTATE = SEALED_ALWAYS_ANNOTATE_KEY;
 
     @Override
     public void visit(ASTNode[] nodes, SourceUnit source) {
@@ -81,7 +84,7 @@ public class SealedASTTransformation extends AbstractASTTransformation {
 
             boolean isNative = isPostJDK17 && mode != SealedMode.EMULATE;
             if (doNotAnnotate) {
-                cNode.putNodeMetaData(SEALED_ALWAYS_ANNOTATE, Boolean.FALSE);
+                cNode.putNodeMetaData(SEALED_ALWAYS_ANNOTATE_KEY, Boolean.FALSE);
             }
             if (isNative) {
                 cNode.putNodeMetaData(SealedMode.class, SealedMode.NATIVE);
@@ -100,6 +103,29 @@ public class SealedASTTransformation extends AbstractASTTransformation {
         }
     }
 
+    /**
+     * Reports true if native sealed class information should be written into the bytecode.
+     * Will only ever return true after the SealedASTTransformation visit method has completed.
+     *
+     * @return true for a native sealed class
+     */
+    @Incubating
+    public static boolean sealedNative(AnnotatedNode node) {
+        return node.getNodeMetaData(SealedMode.class) == SealedMode.NATIVE;
+    }
+
+    /**
+     * Reports true if the {@code Sealed} annotation should be included in the bytecode for
+     * a sealed or emulated-sealed class.
+     * Will only ever return true after the SealedASTTransformation visit method has completed.
+     *
+     * @return true if a {@code Sealed} annotation is not required for this node
+     */
+    @Incubating
+    public static boolean sealedSkipAnnotation(AnnotatedNode node) {
+        return Boolean.FALSE.equals(node.getNodeMetaData(SEALED_ALWAYS_ANNOTATE_KEY));
+    }
+
     private static SealedMode getMode(AnnotationNode node, String name) {
         if (node != null) {
             final Expression member = node.getMember(name);

[groovy] 02/02: GROOVY-10434: ClassNode isRecord() refactoring: additional clarification when information will be available

Posted by pa...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

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

commit fb2754a404aaaa0d9f1a88744441df19c6db5ff8
Author: Paul King <pa...@asert.com.au>
AuthorDate: Tue Jan 25 20:15:45 2022 +1000

    GROOVY-10434: ClassNode isRecord() refactoring: additional clarification when information will be available
---
 src/main/java/org/codehaus/groovy/ast/ClassNode.java       | 14 +++++++++-----
 .../groovy/transform/RecordTypeASTTransformation.java      | 12 ++++++++++++
 .../codehaus/groovy/transform/SealedASTTransformation.java |  6 +++---
 3 files changed, 24 insertions(+), 8 deletions(-)

diff --git a/src/main/java/org/codehaus/groovy/ast/ClassNode.java b/src/main/java/org/codehaus/groovy/ast/ClassNode.java
index 0874d61..991a6a5 100644
--- a/src/main/java/org/codehaus/groovy/ast/ClassNode.java
+++ b/src/main/java/org/codehaus/groovy/ast/ClassNode.java
@@ -55,6 +55,7 @@ import static org.codehaus.groovy.ast.ClassHelper.SEALED_TYPE;
 import static org.codehaus.groovy.ast.ClassHelper.isObjectType;
 import static org.codehaus.groovy.ast.ClassHelper.isPrimitiveBoolean;
 import static org.codehaus.groovy.ast.ClassHelper.isPrimitiveVoid;
+import static org.codehaus.groovy.transform.RecordTypeASTTransformation.recordNative;
 import static org.objectweb.asm.Opcodes.ACC_ABSTRACT;
 import static org.objectweb.asm.Opcodes.ACC_ANNOTATION;
 import static org.objectweb.asm.Opcodes.ACC_ENUM;
@@ -1369,23 +1370,24 @@ public class ClassNode extends AnnotatedNode {
 
     /**
      * Checks if the {@link ClassNode} instance represents a native {@code record}.
-     * Check instead for the {@code RecordType} annotation if looking for records and record-like classes.
+     * Check instead for the {@code RecordBase} annotation if looking for records and
+     * record-like classes currently being compiled.
      *
      * @return {@code true} if the instance represents a native {@code record}
-     *
      * @since 4.0.0
      */
+    @Incubating
     public boolean isRecord() {
-        return getUnresolvedSuperClass() != null && "java.lang.Record".equals(getUnresolvedSuperClass().getName());
+        return recordNative(this);
     }
 
     /**
      * Gets the record components of record type.
      *
      * @return {@code RecordComponentNode} instances
-     *
      * @since 4.0.0
      */
+    @Incubating
     public List<RecordComponentNode> getRecordComponents() {
         if (redirect != null)
             return redirect.getRecordComponents();
@@ -1403,6 +1405,7 @@ public class ClassNode extends AnnotatedNode {
      *
      * @since 4.0.0
      */
+    @Incubating
     public void setRecordComponents(List<RecordComponentNode> recordComponents) {
         if (redirect != null) {
             redirect.setRecordComponents(recordComponents);
@@ -1421,7 +1424,8 @@ public class ClassNode extends AnnotatedNode {
     }
 
     /**
-     * @return true for native and emulated (annotation based) sealed classes
+     * @return {@code true} for native and emulated (annotation based) sealed classes
+     * @since 4.0.0
      */
     @Incubating
     public boolean isSealed() {
diff --git a/src/main/java/org/codehaus/groovy/transform/RecordTypeASTTransformation.java b/src/main/java/org/codehaus/groovy/transform/RecordTypeASTTransformation.java
index d47ed5b..e1bf231 100644
--- a/src/main/java/org/codehaus/groovy/transform/RecordTypeASTTransformation.java
+++ b/src/main/java/org/codehaus/groovy/transform/RecordTypeASTTransformation.java
@@ -26,6 +26,7 @@ import groovy.transform.RecordOptions;
 import groovy.transform.RecordTypeMode;
 import groovy.transform.options.PropertyHandler;
 import org.apache.groovy.ast.tools.MethodNodeUtils;
+import org.apache.groovy.lang.annotation.Incubating;
 import org.codehaus.groovy.ast.ASTNode;
 import org.codehaus.groovy.ast.AnnotatedNode;
 import org.codehaus.groovy.ast.AnnotationNode;
@@ -254,6 +255,17 @@ public class RecordTypeASTTransformation extends AbstractASTTransformation imple
         }
     }
 
+    /**
+     * Indicates that the given classnode is a native JVM record class.
+     * For classes being compiled, this will only be valid after the
+     * {@code RecordTypeASTTransformation} transform has been invoked.
+     */
+    @Incubating
+    public static boolean recordNative(ClassNode node) {
+        return node.getUnresolvedSuperClass() != null &&
+                "java.lang.Record".equals(node.getUnresolvedSuperClass().getName());
+    }
+
     private void createComponents(ClassNode cNode, List<PropertyNode> pList) {
         if (pList.size() > 16) { // Groovy currently only goes to Tuple16
             addError("Record has too many components for a components() method", cNode);
diff --git a/src/main/java/org/codehaus/groovy/transform/SealedASTTransformation.java b/src/main/java/org/codehaus/groovy/transform/SealedASTTransformation.java
index 5f38c68..9037670 100644
--- a/src/main/java/org/codehaus/groovy/transform/SealedASTTransformation.java
+++ b/src/main/java/org/codehaus/groovy/transform/SealedASTTransformation.java
@@ -115,9 +115,9 @@ public class SealedASTTransformation extends AbstractASTTransformation {
     }
 
     /**
-     * Reports true if the {@code Sealed} annotation should be included in the bytecode for
-     * a sealed or emulated-sealed class.
-     * Will only ever return true after the SealedASTTransformation visit method has completed.
+     * Reports true if the {@code Sealed} annotation should not be
+     * included in the bytecode for a sealed or emulated-sealed class.
+     * Will only ever return true after the {@code SealedASTTransformation} transform has been invoked.
      *
      * @return true if a {@code Sealed} annotation is not required for this node
      */