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 2020/09/11 03:26:58 UTC

[groovy] branch master updated: GROOVY-7492: Groovy should allow CompileStatic classes to not implement GroovyObject (closes #54)

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

paulk 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 61af653  GROOVY-7492: Groovy should allow CompileStatic classes to not implement GroovyObject (closes #54)
61af653 is described below

commit 61af653747d1cefdfaff2f96d646cba621b46a1f
Author: paulk <pa...@asert.com.au>
AuthorDate: Sun Jul 5 19:04:17 2015 +1000

    GROOVY-7492: Groovy should allow CompileStatic classes to not implement GroovyObject (closes #54)
---
 src/main/java/groovy/transform/stc/POJO.java       | 34 ++++++++++++++++
 .../org/codehaus/groovy/classgen/Verifier.java     | 18 ++++++---
 src/test/groovy/transform/stc/POJOTest.groovy      | 45 ++++++++++++++++++++++
 3 files changed, 91 insertions(+), 6 deletions(-)

diff --git a/src/main/java/groovy/transform/stc/POJO.java b/src/main/java/groovy/transform/stc/POJO.java
new file mode 100644
index 0000000..7f38e72
--- /dev/null
+++ b/src/main/java/groovy/transform/stc/POJO.java
@@ -0,0 +1,34 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements. See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership. The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License. You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied. See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+package groovy.transform.stc;
+
+import org.apache.groovy.lang.annotation.Incubating;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * Marker interface to indicate that the normal GroovyObject methods should not be added.
+ */
+@Incubating
+@Target(ElementType.TYPE)
+@Retention(RetentionPolicy.SOURCE)
+public @interface POJO { }
diff --git a/src/main/java/org/codehaus/groovy/classgen/Verifier.java b/src/main/java/org/codehaus/groovy/classgen/Verifier.java
index 6a97311..c6ad11e 100644
--- a/src/main/java/org/codehaus/groovy/classgen/Verifier.java
+++ b/src/main/java/org/codehaus/groovy/classgen/Verifier.java
@@ -22,8 +22,10 @@ import groovy.lang.GroovyClassLoader;
 import groovy.lang.GroovyObject;
 import groovy.lang.GroovyRuntimeException;
 import groovy.lang.MetaClass;
+import groovy.transform.CompileStatic;
 import groovy.transform.Generated;
 import groovy.transform.Internal;
+import groovy.transform.stc.POJO;
 import org.apache.groovy.ast.tools.ClassNodeUtils;
 import org.apache.groovy.util.BeanUtils;
 import org.codehaus.groovy.GroovyBugError;
@@ -202,6 +204,8 @@ public class Verifier implements GroovyClassVisitor, Opcodes {
 
     @Override
     public void visitClass(final ClassNode node) {
+        boolean skipGroovify = !node.getAnnotations(ClassHelper.make(CompileStatic.class)).isEmpty() &&
+                !node.getAnnotations(ClassHelper.make(POJO.class)).isEmpty();
         this.classNode = node;
 
         if (Traits.isTrait(node) // maybe possible to have this true in joint compilation mode
@@ -232,14 +236,16 @@ public class Verifier implements GroovyClassVisitor, Opcodes {
 
         final String classInternalName = BytecodeHelper.getClassInternalName(node);
 
-        addStaticMetaClassField(node, classInternalName);
+        if (!skipGroovify) {
+            addStaticMetaClassField(node, classInternalName);
 
-        boolean knownSpecialCase =
-                node.isDerivedFrom(ClassHelper.GSTRING_TYPE)
-                        || node.isDerivedFrom(ClassHelper.GROOVY_OBJECT_SUPPORT_TYPE);
+            boolean knownSpecialCase =
+                    node.isDerivedFrom(ClassHelper.GSTRING_TYPE)
+                            || node.isDerivedFrom(ClassHelper.GROOVY_OBJECT_SUPPORT_TYPE);
 
-        addFastPathHelperFieldsAndHelperMethod(node, classInternalName, knownSpecialCase);
-        if (!knownSpecialCase) addGroovyObjectInterfaceAndMethods(node, classInternalName);
+            addFastPathHelperFieldsAndHelperMethod(node, classInternalName, knownSpecialCase);
+            if (!knownSpecialCase) addGroovyObjectInterfaceAndMethods(node, classInternalName);
+        }
 
         addDefaultConstructor(node);
 
diff --git a/src/test/groovy/transform/stc/POJOTest.groovy b/src/test/groovy/transform/stc/POJOTest.groovy
new file mode 100644
index 0000000..28071b0
--- /dev/null
+++ b/src/test/groovy/transform/stc/POJOTest.groovy
@@ -0,0 +1,45 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements. See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership. The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License. You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied. See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+package groovy.transform.stc
+
+import groovy.test.GroovyTestCase
+
+/**
+ * Unit tests for POJO marker interface handling
+ */
+class POJOTest extends GroovyTestCase {
+
+    void testDelegateWithPOJO() {
+        assertScript '''
+            import groovy.transform.*
+            import groovy.transform.stc.POJO
+
+            @CompileStatic
+            @POJO
+            class Foo {
+                @Delegate List foo = ['bar']
+            }
+
+            def foo = new Foo()
+            foo.add('baz')
+            assert foo.size() == 2
+            assert !(foo instanceof GroovyObject)
+        '''
+    }
+}