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 179d193  GROOVY-8953: Imported enum causes compilation bug preventing 
tests from compiling (closes #885)
179d193 is described below

commit 179d193a5a5f7a58076f68ef737340f2e461fc7c
Author: Paul King <pa...@asert.com.au>
AuthorDate: Wed Feb 27 17:49:34 2019 +1000

    GROOVY-8953: Imported enum causes compilation bug preventing tests from 
compiling (closes #885)
---
 .../org/codehaus/groovy/vmplugin/v5/Java5.java     | 14 +++---
 src/test/groovy/bugs/Groovy8008Bug.java            | 57 +++++++++++++++++-----
 src/test/groovy/bugs/groovy8953/Enum8953.java      | 28 +++++++++++
 .../SyntheticParameterAnnotationsBug.groovy        | 32 ++++++++++++
 4 files changed, 113 insertions(+), 18 deletions(-)

diff --git a/src/main/java/org/codehaus/groovy/vmplugin/v5/Java5.java 
b/src/main/java/org/codehaus/groovy/vmplugin/v5/Java5.java
index b745405..44d18ee 100644
--- a/src/main/java/org/codehaus/groovy/vmplugin/v5/Java5.java
+++ b/src/main/java/org/codehaus/groovy/vmplugin/v5/Java5.java
@@ -450,18 +450,20 @@ public class Java5 implements VMPlugin {
         Annotation[][] annotations = constructor.getParameterAnnotations();
         int diff = parameterCount - annotations.length;
         if (diff > 0) {
-            // May happen on JDK8 and below, but we only expect to have to
-            // add a single element to the front of the array to account
-            // for the synthetic outer reference
-            if (diff > 1) {
+            // May happen on JDK8 and below. We add elements to the front of 
the array to account for the synthetic params:
+            // - for an inner class we expect one param to account for the 
synthetic outer reference
+            // - for an enum we expect two params to account for the synthetic 
name and ordinal
+            if ((!constructor.getDeclaringClass().isEnum() && diff > 1) || 
diff > 2) {
                 throw new GroovyBugError(
                         "Constructor parameter annotations length [" + 
annotations.length + "] " +
                         "does not match the parameter length: " + constructor
                 );
             }
             Annotation[][] adjusted = new Annotation[parameterCount][];
-            adjusted[0] = EMPTY_ANNOTATION_ARRAY;
-            System.arraycopy(annotations, 0, adjusted, 1, annotations.length);
+            for (int i = 0; i < diff; i++) {
+                adjusted[i] = EMPTY_ANNOTATION_ARRAY;
+            }
+            System.arraycopy(annotations, 0, adjusted, diff, 
annotations.length);
             return adjusted;
         }
         return annotations;
diff --git a/src/test/groovy/bugs/Groovy8008Bug.java 
b/src/test/groovy/bugs/Groovy8008Bug.java
index 84c1f86..94974ed 100644
--- a/src/test/groovy/bugs/Groovy8008Bug.java
+++ b/src/test/groovy/bugs/Groovy8008Bug.java
@@ -47,7 +47,7 @@ public class Groovy8008Bug extends TestCase {
         Class<Inner> innerClass = Inner.class;
         Constructor<Inner> ctor = 
innerClass.getDeclaredConstructor(Groovy8008Bug.class, String.class, 
Date.class, String.class);
 
-        assertEquals(4, ctor.getParameterTypes().length);       
//Groovy8008Bug,String,Date,String
+        assertEquals(4, ctor.getParameterTypes().length);
         // JDK 9 and above correctly report 4
         // assertEquals(3, ctor.getParameterAnnotations().length); 
//[],[@Anno1,@Anno2],[@Anno2]
 
@@ -58,24 +58,57 @@ public class Groovy8008Bug extends TestCase {
         assertEquals(1, ctors.size());
 
         Parameter[] params = ctors.get(0).getParameters();
+        checkOuterRef(params[0], Groovy8008Bug.class);
+        checkStringWithNoAnnos(params[1]);
+        checkDateWithTwoAnnos(params[2]);
+        checkStringWithOneAnno(params[3]);
 
-        assertEquals(Groovy8008Bug.class.getName(), 
params[0].getType().getName());
-        assertEquals(0, params[0].getAnnotations().size());
+        // do the same again for an inner inner class
+        Class<Inner.InnerInner> innerInnerClass = Inner.InnerInner.class;
+        Constructor<Inner.InnerInner> innerCtor = 
innerInnerClass.getDeclaredConstructor(Groovy8008Bug.Inner.class, String.class, 
Date.class, String.class);
+        assertEquals(4, innerCtor.getParameterTypes().length);
 
-        assertEquals(String.class.getName(), params[1].getType().getName());
-        assertEquals(0, params[1].getAnnotations().size());
+        cn = new ClassNode(innerInnerClass);
 
-        assertEquals(Date.class.getName(), params[2].getType().getName());
-        assertEquals(2, params[2].getAnnotations().size());
-        assertEquals(TestAnno1.class.getName(), 
params[2].getAnnotations().get(0).getClassNode().getName());
-        assertEquals(TestAnno2.class.getName(), 
params[2].getAnnotations().get(1).getClassNode().getName());
+        // trigger the call to 
VMPlugin#configureClassNode(CompileUnit,ClassNode)
+        ctors = cn.getDeclaredConstructors();
+        assertEquals(1, ctors.size());
+
+        params = ctors.get(0).getParameters();
+        checkOuterRef(params[0], Groovy8008Bug.Inner.class);
+        checkStringWithNoAnnos(params[1]);
+        checkDateWithTwoAnnos(params[2]);
+        checkStringWithOneAnno(params[3]);
+    }
+
+    private void checkOuterRef(Parameter param, Class outerClass) {
+        assertEquals(outerClass.getName(), param.getType().getName());
+        assertEquals(0, param.getAnnotations().size());
+    }
 
-        assertEquals(String.class.getName(), params[3].getType().getName());
-        assertEquals(1, params[3].getAnnotations().size());
-        assertEquals(TestAnno2.class.getName(), 
params[3].getAnnotations().get(0).getClassNode().getName());
+    private void checkStringWithOneAnno(Parameter param) {
+        assertEquals(String.class.getName(), param.getType().getName());
+        assertEquals(1, param.getAnnotations().size());
+        assertEquals(TestAnno2.class.getName(), 
param.getAnnotations().get(0).getClassNode().getName());
+    }
+
+    private void checkStringWithNoAnnos(Parameter param) {
+        assertEquals(String.class.getName(), param.getType().getName());
+        assertEquals(0, param.getAnnotations().size());
+    }
+
+    private void checkDateWithTwoAnnos(Parameter param2) {
+        assertEquals(Date.class.getName(), param2.getType().getName());
+        assertEquals(2, param2.getAnnotations().size());
+        assertEquals(TestAnno1.class.getName(), 
param2.getAnnotations().get(0).getClassNode().getName());
+        assertEquals(TestAnno2.class.getName(), 
param2.getAnnotations().get(1).getClassNode().getName());
     }
 
     private class Inner {
         private Inner(String arg1, @TestAnno1 @TestAnno2 Date arg2, @TestAnno2 
String arg3) { }
+
+        private class InnerInner {
+            private InnerInner(String arg1, @TestAnno1 @TestAnno2 Date arg2, 
@TestAnno2 String arg3) { }
+        }
     }
 }
diff --git a/src/test/groovy/bugs/groovy8953/Enum8953.java 
b/src/test/groovy/bugs/groovy8953/Enum8953.java
new file mode 100644
index 0000000..a40a098
--- /dev/null
+++ b/src/test/groovy/bugs/groovy8953/Enum8953.java
@@ -0,0 +1,28 @@
+/*
+ *  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.bugs.groovy8953;
+
+public enum Enum8953 {
+    A("value");
+    public String value;
+
+    Enum8953(@Deprecated final String value) {
+        this.value = value;
+    }
+}
diff --git 
a/src/test/groovy/bugs/groovy8953/SyntheticParameterAnnotationsBug.groovy 
b/src/test/groovy/bugs/groovy8953/SyntheticParameterAnnotationsBug.groovy
new file mode 100644
index 0000000..316e5b9
--- /dev/null
+++ b/src/test/groovy/bugs/groovy8953/SyntheticParameterAnnotationsBug.groovy
@@ -0,0 +1,32 @@
+/*
+ *  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.bugs.groovy8953
+
+class SyntheticParameterAnnotationsBug extends GroovyTestCase {
+    void testEnumConstructorWithSyntheticParamUsageWithAsmResolvingDisabled() {
+        assertScript '''
+            import org.codehaus.groovy.control.CompilerConfiguration
+
+            def script = "assert groovy.bugs.groovy8953.Enum8953.A.value == 
'value'"
+            def config = new CompilerConfiguration()
+            config.optimizationOptions.asmResolving = false
+            new GroovyShell(config).evaluate(script, 
"bug8953_dummyName.groovy")
+        '''
+    }
+}

Reply via email to