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:54 UTC

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

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);