From a4e87e41855a47c18f1d43f3d49531df74d5ff2b Mon Sep 17 00:00:00 2001 From: Eric Milles Date: Mon, 11 Dec 2023 12:34:00 -0600 Subject: [PATCH] GROOVY-10328: STC: `List` dot get returns Object, not Type 3_0_X backport --- .../stc/StaticTypeCheckingSupport.java | 8 ++-- src/test/groovy/bugs/Groovy9074.groovy | 46 +++++++++---------- .../transform/stc/TypeInferenceSTCTest.groovy | 23 +++++++++- 3 files changed, 49 insertions(+), 28 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 a0543ee3b4b..9dc74dfe712 100644 --- a/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingSupport.java +++ b/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingSupport.java @@ -1918,11 +1918,11 @@ static ClassNode applyGenericsContext(final Map } static ClassNode getCombinedBoundType(final GenericsType genericsType) { - // TODO: this method should really return some kind of meta ClassNode - // representing the combination of all bounds. The code here, just picks - // something out to be able to proceed and is not actually correct + // TODO: This method should really return some kind of meta ClassNode + // representing the combination of all bounds. The code here just picks + // something out to be able to proceed and is not actually correct. if (hasNonTrivialBounds(genericsType)) { - if (genericsType.getLowerBound() != null) return genericsType.getLowerBound(); + if (genericsType.getLowerBound() != null) return OBJECT_TYPE; // GROOVY-10328 if (genericsType.getUpperBounds() != null) return genericsType.getUpperBounds()[0]; } return genericsType.getType(); diff --git a/src/test/groovy/bugs/Groovy9074.groovy b/src/test/groovy/bugs/Groovy9074.groovy index aac3c9cd218..f518ee5355e 100644 --- a/src/test/groovy/bugs/Groovy9074.groovy +++ b/src/test/groovy/bugs/Groovy9074.groovy @@ -29,7 +29,7 @@ final class Groovy9074 extends GroovyTestCase { void _FIXME_testWildcardCapture() { def err = shouldFail ''' - @groovy.transform.CompileStatic + @groovy.transform.TypeChecked class Main { private static Collection c = new ArrayList() static main(args) { @@ -46,20 +46,20 @@ final class Groovy9074 extends GroovyTestCase { def err = shouldFail ''' import java.awt.Canvas abstract class Shape { - abstract void draw(Canvas c) + abstract void draw(Canvas c) } class Circle extends Shape { - private int x, y, radius - @Override void draw(Canvas c) {} + private int x, y, radius + @Override void draw(Canvas c) {} } class Rectangle extends Shape { - private int x, y, width, height - @Override void draw(Canvas c) {} + private int x, y, width, height + @Override void draw(Canvas c) {} } - @groovy.transform.CompileStatic + @groovy.transform.TypeChecked void addRectangle(List shapes) { - shapes.add(0, new Rectangle()) // TODO: compile-time error! + shapes.add(0, new Rectangle()) // TODO: compile-time error! } ''' @@ -71,20 +71,20 @@ final class Groovy9074 extends GroovyTestCase { assertScript ''' import java.awt.Canvas abstract class Shape { - abstract void draw(Canvas c) + abstract void draw(Canvas c) } class Circle extends Shape { - private int x, y, radius - @Override void draw(Canvas c) {} + private int x, y, radius + @Override void draw(Canvas c) {} } class Rectangle extends Shape { - private int x, y, width, height - @Override void draw(Canvas c) {} + private int x, y, width, height + @Override void draw(Canvas c) {} } - @groovy.transform.CompileStatic + @groovy.transform.TypeChecked void addRectangle(List shapes) { - shapes.add(0, new Rectangle()) + shapes.add(0, new Rectangle()) } List list = [] @@ -99,12 +99,12 @@ final class Groovy9074 extends GroovyTestCase { new CompilationUnit().with { addSource 'Main.groovy', ''' class Factory { - def T make(Class type, ... args) {} + def T make(Class type, ... args) {} } - @groovy.transform.CompileStatic + @groovy.transform.TypeChecked void test(Factory fact, Rule rule) { - Type bean = fact.make(rule.type) + Type bean = fact.make(rule.type) } ''' @@ -124,16 +124,16 @@ final class Groovy9074 extends GroovyTestCase { } } - void _FIXME_testWildcardSuper2() { + void testWildcardSuper2() { new CompilationUnit().with { addSource 'Main.groovy', ''' class Factory { - def T make(Class type, ... args) {} + def T make(Class type, ... args) {} } - @groovy.transform.CompileStatic + @groovy.transform.TypeChecked void test(Factory fact, Rule rule) { - Type bean = fact.make(rule.type) // can't assign "? super Type" to "Type" + Type bean = fact.make(rule.type) // can't assign "? super Type" to "Type" } ''' @@ -152,7 +152,7 @@ final class Groovy9074 extends GroovyTestCase { def err = shouldFail { compile CLASS_GENERATION } - assert err =~ "cannot convert from capture#1-of ? super Type to Type" + assert err =~ 'Cannot assign value of type java.lang.Object to variable of type Type' } } } diff --git a/src/test/groovy/transform/stc/TypeInferenceSTCTest.groovy b/src/test/groovy/transform/stc/TypeInferenceSTCTest.groovy index b512e03aa4f..7254e4c21cc 100644 --- a/src/test/groovy/transform/stc/TypeInferenceSTCTest.groovy +++ b/src/test/groovy/transform/stc/TypeInferenceSTCTest.groovy @@ -225,7 +225,8 @@ class TypeInferenceSTCTest extends StaticTypeCheckingTestCase { ''' } - @NotYetImplemented // GROOVY-7971 + // GROOVY-7971 + @NotYetImplemented void testInstanceOf9() { assertScript ''' import groovy.json.JsonOutput @@ -1418,4 +1419,24 @@ class TypeInferenceSTCTest extends StaticTypeCheckingTestCase { test( [id:'x'] ) ''' } + + // GROOVY-10328 + void testInferredTypeForMapOrList() { + assertScript ''' + @ASTTest(phase=INSTRUCTION_SELECTION, value={ + for (decl in node.code.statements*.expression) { + assert decl.getNodeMetaData(INFERRED_TYPE) == OBJECT_TYPE + } + }) + void test(List list, Map map) { + def a = list.first() + def b = list.get(0) + def c = list[0] + + def x = map.get('foo') + def y = map['foo'] + def z = map.foo + } + ''' + } }