Repository: groovy
Updated Branches:
  refs/heads/GROOVY_2_5_X 49f9111b1 -> 48807d5b1


GROOVY-6167: Generics: within a single declaration, generic type definition 
order matters

(cherry picked from commit ee5a07c)


Project: http://git-wip-us.apache.org/repos/asf/groovy/repo
Commit: http://git-wip-us.apache.org/repos/asf/groovy/commit/48807d5b
Tree: http://git-wip-us.apache.org/repos/asf/groovy/tree/48807d5b
Diff: http://git-wip-us.apache.org/repos/asf/groovy/diff/48807d5b

Branch: refs/heads/GROOVY_2_5_X
Commit: 48807d5b1ba094e2f0dc212b6c92b4b370fe8394
Parents: 49f9111
Author: sunlan <sun...@apache.org>
Authored: Fri May 18 00:52:34 2018 +0800
Committer: sunlan <sun...@apache.org>
Committed: Fri May 18 00:53:17 2018 +0800

----------------------------------------------------------------------
 .../codehaus/groovy/control/ResolveVisitor.java | 47 +++++++++++++++----
 src/test/groovy/bugs/Groovy6171Bug.groovy       | 48 ++++++++++++++++++++
 2 files changed, 87 insertions(+), 8 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/groovy/blob/48807d5b/src/main/java/org/codehaus/groovy/control/ResolveVisitor.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/codehaus/groovy/control/ResolveVisitor.java 
b/src/main/java/org/codehaus/groovy/control/ResolveVisitor.java
index 45ac027..9ceab30 100644
--- a/src/main/java/org/codehaus/groovy/control/ResolveVisitor.java
+++ b/src/main/java/org/codehaus/groovy/control/ResolveVisitor.java
@@ -1447,29 +1447,60 @@ public class ResolveVisitor extends 
ClassCodeExpressionTransformer {
     }
 
     private void resolveGenericsHeader(GenericsType[] types) {
+        resolveGenericsHeader(types, null, 0);
+    }
+
+    private void resolveGenericsHeader(GenericsType[] types, GenericsType 
rootType, int level) {
         if (types == null) return;
         currentClass.setUsingGenerics(true);
+        List<Tuple2<ClassNode, GenericsType>> upperBoundsWithGenerics = new 
LinkedList<>();
         for (GenericsType type : types) {
+            if (level > 0 && type.getName().equals(rootType.getName())) {
+                continue;
+            }
+
             ClassNode classNode = type.getType();
             String name = type.getName();
             ClassNode[] bounds = type.getUpperBounds();
+            boolean isWild = "?".equals(name);
+            boolean toDealWithGenerics = 0 == level || (level > 0 && null != 
genericParameterNames.get(name));
+
             if (bounds != null) {
                 boolean nameAdded = false;
                 for (ClassNode upperBound : bounds) {
-                    if (!nameAdded && upperBound != null || 
!resolve(classNode)) {
+                    if (!isWild) {
+                        if (!nameAdded && upperBound != null || 
!resolve(classNode)) {
+                            if (toDealWithGenerics) {
+                                genericParameterNames.put(name, type);
+                                type.setPlaceholder(true);
+                                classNode.setRedirect(upperBound);
+                                nameAdded = true;
+                            }
+
+                        }
+                        resolveOrFail(upperBound, classNode);
+                    }
+
+                    if (upperBound.isUsingGenerics()) {
+                        upperBoundsWithGenerics.add(new Tuple2<>(upperBound, 
type));
+                    }
+                }
+            } else {
+                if (!isWild) {
+                    if (toDealWithGenerics) {
                         genericParameterNames.put(name, type);
                         type.setPlaceholder(true);
-                        classNode.setRedirect(upperBound);
-                        nameAdded = true;
+                        classNode.setRedirect(ClassHelper.OBJECT_TYPE);
                     }
-                    resolveOrFail(upperBound, classNode);
                 }
-            } else {
-                genericParameterNames.put(name, type);
-                classNode.setRedirect(ClassHelper.OBJECT_TYPE);
-                type.setPlaceholder(true);
             }
         }
+
+        for (Tuple2<ClassNode, GenericsType> tp : upperBoundsWithGenerics) {
+            ClassNode upperBound = tp.getFirst();
+            GenericsType gt = tp.getSecond();
+            resolveGenericsHeader(upperBound.getGenericsTypes(), 0 == level ? 
gt : rootType, level + 1);
+        }
     }
 
     private boolean resolveGenericsType(GenericsType genericsType) {

http://git-wip-us.apache.org/repos/asf/groovy/blob/48807d5b/src/test/groovy/bugs/Groovy6171Bug.groovy
----------------------------------------------------------------------
diff --git a/src/test/groovy/bugs/Groovy6171Bug.groovy 
b/src/test/groovy/bugs/Groovy6171Bug.groovy
new file mode 100644
index 0000000..84c0fce
--- /dev/null
+++ b/src/test/groovy/bugs/Groovy6171Bug.groovy
@@ -0,0 +1,48 @@
+/*
+ *  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
+
+import gls.CompilableTestSupport
+
+class Groovy6171Bug extends CompilableTestSupport {
+    void testGroovy6171() {
+        shouldCompile '''
+        public class Foo<T extends List<X>, X extends Number> {}
+        '''
+    }
+
+    void test2() {
+        assertScript '''
+        @groovy.transform.CompileStatic
+        public class Foo<T extends List<X>, X extends Number> {
+            X getFirstElement(T t) {
+                X x = t.get(0)
+                return x
+            }
+            
+            static void main(String[] args) {
+                def f = new Foo<ArrayList<Integer>, Integer>()
+                def list = new ArrayList<Integer>()
+                list.add(123)
+                assert 123 == f.getFirstElement(list)
+            }
+        }
+        '''
+    }
+}

Reply via email to