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 2022/12/10 17:32:00 UTC
[groovy] branch master updated: GROOVY-7992: STC: strong witness overrides type witness for `? super T`
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
The following commit(s) were added to refs/heads/master by this push:
new 326bd57de3 GROOVY-7992: STC: strong witness overrides type witness for `? super T`
326bd57de3 is described below
commit 326bd57de38dce7d7221193ec4594ec6f637bc62
Author: Eric Milles <er...@thomsonreuters.com>
AuthorDate: Sat Dec 10 11:07:31 2022 -0600
GROOVY-7992: STC: strong witness overrides type witness for `? super T`
---
.../transform/stc/StaticTypeCheckingSupport.java | 26 ++++++++++++----------
.../stc/DefaultGroovyMethodsSTCTest.groovy | 4 +---
.../groovy/transform/stc/GenericsSTCTest.groovy | 23 +++++++++++++++----
.../groovy/groovysh/InteractiveShellRunner.groovy | 5 +++--
4 files changed, 37 insertions(+), 21 deletions(-)
diff --git a/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingSupport.java b/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingSupport.java
index 48cf4afe26..16a797db4c 100644
--- a/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingSupport.java
+++ b/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingSupport.java
@@ -1737,25 +1737,26 @@ public abstract class StaticTypeCheckingSupport {
// both have generics
for (int i = 0, n = usage.length; i < n; i += 1) {
GenericsType ui = usage[i], di = declaration[i];
- if (di.isPlaceholder()) {
+ if (di.isPlaceholder()) { // di like "T"
storeGenericsConnection(connections, di.getName(), ui);
- } else if (di.isWildcard()) {
+ } else if (di.isWildcard()) { // di like "?", "? super T", "? extends T", ...
ClassNode lowerBound = di.getLowerBound(), upperBounds[] = di.getUpperBounds();
- if (ui.isWildcard()) {
+ if (ui.isWildcard()) { // ui like "?", "? super Type" or "? extends Type"
extractGenericsConnections(connections, ui.getLowerBound(), lowerBound);
extractGenericsConnections(connections, ui.getUpperBounds(), upperBounds);
} else if (!isUnboundedWildcard(di)) {
ClassNode boundType = lowerBound != null ? lowerBound : upperBounds[0];
- if (boundType.isGenericsPlaceHolder() // GROOVY-9998
- && boundType != ui.getType()) { // GROOVY-10765
+ if (boundType.isGenericsPlaceHolder()) { // di like "? extends/super T"
+ // 6731,7992,8983,9998,10047,10499,10749,10765,...
+ ui = new GenericsType(ui.getType()); // erase type
+ if (lowerBound != null) ui.setWildcard(true); // weak
String placeholderName = boundType.getUnresolvedName();
- ui = new GenericsType(ui.getType()); ui.setWildcard(true);
storeGenericsConnection(connections, placeholderName, ui);
- } else { // di like "? super Collection<T>" and ui like "List<Type>"
+ } else { // di like "? extends Iterable<T>" and ui like "List<Type>"
extractGenericsConnections(connections, ui.getType(), boundType);
}
}
- } else {
+ } else { // di like "List<T>", "List<Type>", "List<? extends T>", ...
extractGenericsConnections(connections, ui.getType(), di.getType());
}
}
@@ -1908,10 +1909,11 @@ public abstract class StaticTypeCheckingSupport {
return genericsType.getType();
}
- static GenericsType getCombinedGenericsType(GenericsType gt1, GenericsType gt2) {
- // GROOVY-9998, GROOVY-10499: unpack "?" that is from "? extends T"
- if (isUnboundedWildcard(gt1)) gt1 = gt1.getType().asGenericsType();
- if (isUnboundedWildcard(gt2)) gt2 = gt2.getType().asGenericsType();
+ static GenericsType getCombinedGenericsType(final GenericsType gt1, final GenericsType gt2) {
+ // GROOVY-7992, GROOVY-10765: "? super T" for gt1 or gt2?
+ if (isUnboundedWildcard(gt1) != isUnboundedWildcard(gt2))
+ return isUnboundedWildcard(gt2) ? gt1 : gt2;
+ // GROOVY-10315, GROOVY-10317, GROOVY-10339, ...
ClassNode cn1 = GenericsUtils.makeClassSafe0(CLASS_Type, gt1);
ClassNode cn2 = GenericsUtils.makeClassSafe0(CLASS_Type, gt2);
ClassNode lub = lowestUpperBound(cn1, cn2);
diff --git a/src/test/groovy/transform/stc/DefaultGroovyMethodsSTCTest.groovy b/src/test/groovy/transform/stc/DefaultGroovyMethodsSTCTest.groovy
index ea46a0674c..4bb950a25f 100644
--- a/src/test/groovy/transform/stc/DefaultGroovyMethodsSTCTest.groovy
+++ b/src/test/groovy/transform/stc/DefaultGroovyMethodsSTCTest.groovy
@@ -18,8 +18,6 @@
*/
package groovy.transform.stc
-import groovy.test.NotYetImplemented
-
/**
* Unit tests for static type checking : default groovy methods.
*/
@@ -240,7 +238,7 @@ class DefaultGroovyMethodsSTCTest extends StaticTypeCheckingTestCase {
'''
}
- @NotYetImplemented // GROOVY-7992
+ // GROOVY-7992
void testMaxWithComparatorAcceptingSuperclass() {
assertScript '''
List<Number> numbers = [1,2,3]
diff --git a/src/test/groovy/transform/stc/GenericsSTCTest.groovy b/src/test/groovy/transform/stc/GenericsSTCTest.groovy
index 523f64790e..b30d8e8749 100644
--- a/src/test/groovy/transform/stc/GenericsSTCTest.groovy
+++ b/src/test/groovy/transform/stc/GenericsSTCTest.groovy
@@ -686,8 +686,23 @@ class GenericsSTCTest extends StaticTypeCheckingTestCase {
'''
}
- // GROOVY-10622
+ // GROOVY-7992
void testReturnTypeInferenceWithMethodGenerics26() {
+ assertScript '''
+ List<String> strings = ['foo','bar','baz']
+ Comparator<Object> cmp = { o1, o2 -> o1.toString() <=> o2.toString() }
+
+ @groovy.transform.ASTTest(phase=INSTRUCTION_SELECTION, value={
+ def type = node.getNodeMetaData(INFERRED_TYPE)
+ assert type.toString(false) == 'java.util.List<java.lang.String>'
+ })
+ def result = strings.sort(false, cmp) // List<T> sort(Iterable<T>,boolean,Comparator<? super T>)
+ assert result == ['bar', 'baz', 'foo']
+ '''
+ }
+
+ // GROOVY-10622
+ void testReturnTypeInferenceWithMethodGenerics27() {
String types = '''
@groovy.transform.TupleConstructor(defaults=false)
class A<X> {
@@ -720,7 +735,7 @@ class GenericsSTCTest extends StaticTypeCheckingTestCase {
}
// GROOVY-10637
- void testReturnTypeInferenceWithMethodGenerics27() {
+ void testReturnTypeInferenceWithMethodGenerics28() {
assertScript '''
class Outer extends groovy.transform.stc.MyBean<Inner> {
static class Inner {
@@ -737,7 +752,7 @@ class GenericsSTCTest extends StaticTypeCheckingTestCase {
}
// GROOVY-10646
- void testReturnTypeInferenceWithMethodGenerics28() {
+ void testReturnTypeInferenceWithMethodGenerics29() {
String types = '''
class Model {
}
@@ -778,7 +793,7 @@ class GenericsSTCTest extends StaticTypeCheckingTestCase {
}
// GROOVY-10749
- void testReturnTypeInferenceWithMethodGenerics29() {
+ void testReturnTypeInferenceWithMethodGenerics30() {
String named = 'class Named { String name }'
for (expr in ['Named.&getName', '{Named named -> named.getName()}', '(Named named) -> named.getName()']) {
diff --git a/subprojects/groovy-groovysh/src/main/groovy/org/apache/groovy/groovysh/InteractiveShellRunner.groovy b/subprojects/groovy-groovysh/src/main/groovy/org/apache/groovy/groovysh/InteractiveShellRunner.groovy
index ce1eca55c4..d5bea2bcf3 100644
--- a/subprojects/groovy-groovysh/src/main/groovy/org/apache/groovy/groovysh/InteractiveShellRunner.groovy
+++ b/subprojects/groovy-groovysh/src/main/groovy/org/apache/groovy/groovysh/InteractiveShellRunner.groovy
@@ -24,6 +24,7 @@ import groovy.transform.CompileStatic
import jline.console.ConsoleReader
import jline.console.completer.AggregateCompleter
import jline.console.completer.CandidateListCompletionHandler
+import jline.console.completer.Completer
import jline.console.completer.CompletionHandler
import jline.console.history.FileHistory
import org.apache.groovy.groovysh.completion.FileNameCompleter
@@ -162,9 +163,9 @@ class CommandsMultiCompleter extends AggregateCompleter {
protected final Logger log = Logger.create(getClass())
- List/*<Completer>*/ list = []
+ List<Completer> list = []
- private boolean dirty = false
+ private boolean dirty
def add(Command command) {
assert command