You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@groovy.apache.org by em...@apache.org on 2021/02/12 19:23:23 UTC
[groovy] 01/01: GROOVY-9891: return bound type for wildcard
GenericsType -> ClassNode
This is an automated email from the ASF dual-hosted git repository.
emilles pushed a commit to branch GROOVY-9891
in repository https://gitbox.apache.org/repos/asf/groovy.git
commit 57f502ee798cae7d12bffd14182b64f914a5aa19
Author: Eric Milles <er...@thomsonreuters.com>
AuthorDate: Fri Feb 12 13:23:03 2021 -0600
GROOVY-9891: return bound type for wildcard GenericsType -> ClassNode
---
.../codehaus/groovy/ast/tools/GenericsUtils.java | 5 ++
.../groovy/transform/stc/GenericsSTCTest.groovy | 54 ++++++++++++++++++++++
2 files changed, 59 insertions(+)
diff --git a/src/main/java/org/codehaus/groovy/ast/tools/GenericsUtils.java b/src/main/java/org/codehaus/groovy/ast/tools/GenericsUtils.java
index 709ac97..bea8533 100644
--- a/src/main/java/org/codehaus/groovy/ast/tools/GenericsUtils.java
+++ b/src/main/java/org/codehaus/groovy/ast/tools/GenericsUtils.java
@@ -411,6 +411,11 @@ public class GenericsUtils {
if (type.isPlaceholder()) {
String name = type.getName();
ret = genericsSpec.get(name);
+ } else if (type.isWildcard()) { // GROOVY-9891
+ ret = type.getLowerBound(); // use lower or upper
+ if (ret == null && type.getUpperBounds() != null) {
+ ret = type.getUpperBounds()[0]; // ? supports 1
+ }
}
if (ret == null) ret = type.getType();
return ret;
diff --git a/src/test/groovy/transform/stc/GenericsSTCTest.groovy b/src/test/groovy/transform/stc/GenericsSTCTest.groovy
index ba0e566..3e27826 100644
--- a/src/test/groovy/transform/stc/GenericsSTCTest.groovy
+++ b/src/test/groovy/transform/stc/GenericsSTCTest.groovy
@@ -2447,6 +2447,60 @@ class GenericsSTCTest extends StaticTypeCheckingTestCase {
'''
}
+ // GROOVY-9981
+ void testBoundedReturnTypeChecking3() {
+ assertScript '''
+ class Pogo {
+ Map<String, ? extends Number> map
+ }
+ def test(Pogo p) {
+ Collection<? extends Number> c = p.map.values()
+ Iterable<? extends Number> i = p.map.values()
+ i.iterator().next()
+ }
+ def n = test(new Pogo(map:[x:1,y:2.3]))
+ assert n == 1
+ '''
+
+ //
+
+ config.with {
+ targetDirectory = File.createTempDir()
+ jointCompilationOptions = [memStub: true]
+ }
+ File parentDir = File.createTempDir()
+ try {
+ def a = new File(parentDir, 'Pojo.java')
+ a.write '''
+ import java.util.Map;
+ class Pojo {
+ Map<String, ? extends Number> getMap() {
+ return map;
+ }
+ void setMap(Map<String, ? extends Number> map) {
+ this.map = map;
+ }
+ private Map<String, ? extends Number> map = null;
+ }
+ '''
+ def b = new File(parentDir, 'Script.groovy')
+ b.write '''
+ void test(Pojo p) {
+ Collection<? extends Number> c = p.map.values()
+ Iterable<? extends Number> i = p.map.values()
+ }
+ '''
+
+ def loader = new GroovyClassLoader(this.class.classLoader)
+ def cu = new JavaAwareCompilationUnit(config, loader)
+ cu.addSources(a, b)
+ cu.compile()
+ } finally {
+ parentDir.deleteDir()
+ config.targetDirectory.deleteDir()
+ }
+ }
+
// GROOVY-7804
void testParameterlessClosureToGenericSAMTypeArgumentCoercion() {
assertScript '''