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/11/02 17:14:45 UTC
[groovy] 01/02: GROOVY-10228: STC: diamond inference for method
call's object expression
This is an automated email from the ASF dual-hosted git repository.
emilles pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/groovy.git
commit fb1cac6334a1d6f338b499bf21a541be20c36579
Author: Eric Milles <er...@thomsonreuters.com>
AuthorDate: Tue Nov 2 11:27:49 2021 -0500
GROOVY-10228: STC: diamond inference for method call's object expression
---
.../transform/stc/StaticTypeCheckingVisitor.java | 37 +++++++++++++---------
.../groovy/transform/stc/GenericsSTCTest.groovy | 20 ++++++++++--
.../groovy/groovysh/util/PackageHelperImpl.groovy | 2 +-
3 files changed, 41 insertions(+), 18 deletions(-)
diff --git a/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java b/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java
index e4b753d..e47de5d 100644
--- a/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java
+++ b/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java
@@ -1106,22 +1106,26 @@ public class StaticTypeCheckingVisitor extends ClassCodeVisitorSupport {
}
}
- private void adjustGenerics(final ClassNode from, final ClassNode to) {
- GenericsType[] genericsTypes = from.getGenericsTypes();
- if (genericsTypes == null) {
- // case of: def foo = new HashMap<>()
- genericsTypes = to.redirect().getGenericsTypes();
- }
- GenericsType[] copy = new GenericsType[genericsTypes.length];
- for (int i = 0; i < genericsTypes.length; i++) {
- GenericsType genericsType = genericsTypes[i];
- copy[i] = new GenericsType(
- wrapTypeIfNecessary(genericsType.getType()),
- genericsType.getUpperBounds(),
- genericsType.getLowerBound()
- );
+ private void adjustGenerics(final ClassNode source, final ClassNode target) {
+ GenericsType[] genericsTypes = source.getGenericsTypes();
+ if (genericsTypes == null) { // Map foo = new HashMap<>()
+ genericsTypes = target.redirect().getGenericsTypes().clone();
+ for (int i = 0, n = genericsTypes.length; i < n; i += 1) {
+ GenericsType gt = genericsTypes[i];
+ // GROOVY-10055: handle diamond or raw
+ ClassNode cn = gt.getUpperBounds() != null
+ ? gt.getUpperBounds()[0] : gt.getType().redirect();
+ genericsTypes[i] = cn.getPlainNodeReference().asGenericsType();
+ }
+ } else {
+ genericsTypes = genericsTypes.clone();
+ for (int i = 0, n = genericsTypes.length; i < n; i += 1) {
+ GenericsType gt = genericsTypes[i];
+ genericsTypes[i] = new GenericsType(gt.getType(),
+ gt.getUpperBounds(), gt.getLowerBound());
+ }
}
- to.setGenericsTypes(copy);
+ target.setGenericsTypes(genericsTypes);
}
/**
@@ -3303,6 +3307,9 @@ public class StaticTypeCheckingVisitor extends ClassCodeVisitorSupport {
call.getMethod().visit(this);
ClassNode receiver = getType(objectExpression);
+ if (objectExpression instanceof ConstructorCallExpression) { // GROOVY-10228
+ inferDiamondType((ConstructorCallExpression) objectExpression, receiver.getPlainNodeReference());
+ }
if (call.isSpreadSafe()) { // make sure receiver is array or collection then check element type
if (!receiver.isArray() && !implementsInterfaceOrIsSubclassOf(receiver, Collection_TYPE)) {
addStaticTypeError("Spread operator can only be used on collection types", objectExpression);
diff --git a/src/test/groovy/transform/stc/GenericsSTCTest.groovy b/src/test/groovy/transform/stc/GenericsSTCTest.groovy
index 13b7d4c..c9d4477 100644
--- a/src/test/groovy/transform/stc/GenericsSTCTest.groovy
+++ b/src/test/groovy/transform/stc/GenericsSTCTest.groovy
@@ -1000,9 +1000,25 @@ class GenericsSTCTest extends StaticTypeCheckingTestCase {
'''
}
- // GROOVY-10323
+ // GROOVY-10228
void testDiamondInferrenceFromConstructor18() {
assertScript '''
+ @groovy.transform.TupleConstructor(defaults=false)
+ class C<T> {
+ T p
+ }
+ def m(Number n) {
+ 'works'
+ }
+ def x = 12345
+ x = m(new C<>(x).getP()) // Cannot find matching method
+ assert x == 'works'
+ '''
+ }
+
+ // GROOVY-10323
+ void testDiamondInferrenceFromConstructor19() {
+ assertScript '''
class C<T> {
}
def <T,T> T m(C<T> c) {
@@ -1012,7 +1028,7 @@ class GenericsSTCTest extends StaticTypeCheckingTestCase {
}
// GROOVY-10324
- void testDiamondInferrenceFromConstructor19() {
+ void testDiamondInferrenceFromConstructor20() {
assertScript '''
class C<T> {
}
diff --git a/subprojects/groovy-groovysh/src/main/groovy/org/apache/groovy/groovysh/util/PackageHelperImpl.groovy b/subprojects/groovy-groovysh/src/main/groovy/org/apache/groovy/groovysh/util/PackageHelperImpl.groovy
index cd4e85b..490f5c7 100644
--- a/subprojects/groovy-groovysh/src/main/groovy/org/apache/groovy/groovysh/util/PackageHelperImpl.groovy
+++ b/subprojects/groovy-groovysh/src/main/groovy/org/apache/groovy/groovysh/util/PackageHelperImpl.groovy
@@ -246,7 +246,7 @@ Files.walkFileTree(fs.getPath('modules'),
File urlFile = new File(URLDecoder.decode(url.file, 'UTF-8'))
if (urlFile.isDirectory()) {
- return new HashSet<>().tap {
+ return new HashSet<String>().tap {
collectPackageNamesFromFolderRecursive(urlFile, '', it)
}
}