Skip to content

Commit a08a8f2

Browse files
committed
GROOVY-10309, GROOVY-10315, GROOVY-10317
1 parent d1a6999 commit a08a8f2

File tree

3 files changed

+94
-4
lines changed

3 files changed

+94
-4
lines changed

base-test/org.eclipse.jdt.groovy.core.tests.compiler/src/org/eclipse/jdt/groovy/core/tests/xform/TypeCheckedTests.java

+73
Original file line numberDiff line numberDiff line change
@@ -4215,6 +4215,79 @@ public void testTypeChecked10306() {
42154215
runConformTest(sources, "1");
42164216
}
42174217

4218+
@Test
4219+
public void testTypeChecked10309() {
4220+
//@formatter:off
4221+
String[] sources = {
4222+
"Main.groovy",
4223+
"@groovy.transform.TupleConstructor(defaults=false)\n" +
4224+
"class A<T,T2> {\n" +
4225+
" T f1\n" +
4226+
" T2 f2\n" +
4227+
"}\n" +
4228+
"class C<T,X> {\n" +
4229+
" @groovy.transform.TypeChecked\n" +
4230+
" void test() {\n" +
4231+
" new A<X,T>((X)null, (T)null)\n" + // Cannot call A#<init>(X, T) with arguments [X, T]
4232+
" }\n" +
4233+
"}\n" +
4234+
"new C().test()",
4235+
};
4236+
//@formatter:on
4237+
4238+
runConformTest(sources);
4239+
}
4240+
4241+
@Test
4242+
public void testTypeChecked10315() {
4243+
for (String args : new String[] {"m2(), c.m()", "c.m(), m2()"}) {
4244+
//@formatter:off
4245+
String[] sources = {
4246+
"Main.groovy",
4247+
"class C<T> {\n" +
4248+
" def T m() {\n" +
4249+
" }\n" +
4250+
"}\n" +
4251+
"def <X> X m2() {\n" +
4252+
"}\n" +
4253+
"def <Y> void m3(Y y1, Y y2) {\n" +
4254+
"}\n" +
4255+
"@groovy.transform.TypeChecked\n" +
4256+
"def <Z> void test(C<Z> c) {\n" +
4257+
" m3(" + args + ")\n" +
4258+
"}\n",
4259+
};
4260+
//@formatter:on
4261+
4262+
runConformTest(sources);
4263+
}
4264+
}
4265+
4266+
@Test
4267+
public void testTypeChecked10317() {
4268+
//@formatter:off
4269+
String[] sources = {
4270+
"Main.groovy",
4271+
"class A<T1,T2> {\n" +
4272+
" @groovy.transform.TypeChecked\n" +
4273+
" void test(T2 t2) {\n" +
4274+
" def a = new A<T2,T2>()\n" +
4275+
" a.foo(new B().bar(t2))\n" + // Cannot call A#foo(T2) with arguments [#X]
4276+
" }\n" +
4277+
" void foo(T1 t1) {\n" +
4278+
" }\n" +
4279+
"}\n" +
4280+
"class B {\n" +
4281+
" def <X,Y> X bar(Y y) {\n" + // X is determined by target
4282+
" }\n" +
4283+
"}\n" +
4284+
"new A<Object,Number>().test(42)\n",
4285+
};
4286+
//@formatter:on
4287+
4288+
runConformTest(sources);
4289+
}
4290+
42184291
@Test
42194292
public void testTypeChecked10320() {
42204293
//@formatter:off

base/org.codehaus.groovy30/src/org/codehaus/groovy/transform/stc/StaticTypeCheckingSupport.java

+9-2
Original file line numberDiff line numberDiff line change
@@ -1719,8 +1719,15 @@ static void applyGenericsConnections(final Map<GenericsTypeName, GenericsType> c
17191719
GenericsTypeName name = new GenericsTypeName(oldValue.getName());
17201720
GenericsType newValue = connections.get(name); // find "V" in T=V
17211721
if (newValue == oldValue) continue;
1722-
// GRECLIPSE add -- GROOVY-10067
1723-
if (name.getName().charAt(0) == '#') continue;
1722+
// GRECLIPSE add -- GROOVY-10067, GROOVY-10315
1723+
if (newValue == null) {
1724+
newValue = connections.get(entry.getKey());
1725+
if (newValue != null) {
1726+
ClassNode o = GenericsUtils.makeClassSafe0(CLASS_Type, oldValue),
1727+
n = GenericsUtils.makeClassSafe0(CLASS_Type, newValue);
1728+
newValue = WideningCategories.lowestUpperBound(o,n).getGenericsTypes()[0];
1729+
}
1730+
}
17241731
// GRECLIPSE end
17251732
if (newValue == null) {
17261733
entry.setValue(newValue = applyGenericsContext(connections, oldValue));

base/org.codehaus.groovy40/src/org/codehaus/groovy/transform/stc/StaticTypeCheckingSupport.java

+12-2
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,7 @@
7777
import static org.apache.groovy.ast.tools.ExpressionUtils.isNullConstant;
7878
import static org.codehaus.groovy.ast.ClassHelper.BigInteger_TYPE;
7979
import static org.codehaus.groovy.ast.ClassHelper.Byte_TYPE;
80+
import static org.codehaus.groovy.ast.ClassHelper.CLASS_Type;
8081
import static org.codehaus.groovy.ast.ClassHelper.CLOSURE_TYPE;
8182
import static org.codehaus.groovy.ast.ClassHelper.COLLECTION_TYPE;
8283
import static org.codehaus.groovy.ast.ClassHelper.Character_TYPE;
@@ -118,6 +119,7 @@
118119
import static org.codehaus.groovy.ast.ClassHelper.makeWithoutCaching;
119120
import static org.codehaus.groovy.ast.ClassHelper.short_TYPE;
120121
import static org.codehaus.groovy.ast.ClassHelper.void_WRAPPER_TYPE;
122+
import static org.codehaus.groovy.ast.tools.GenericsUtils.makeClassSafe0;
121123
import static org.codehaus.groovy.ast.tools.WideningCategories.isBigIntCategory;
122124
import static org.codehaus.groovy.ast.tools.WideningCategories.isFloatingCategory;
123125
import static org.codehaus.groovy.ast.tools.WideningCategories.isNumberCategory;
@@ -1607,9 +1609,17 @@ static void applyGenericsConnections(final Map<GenericsTypeName, GenericsType> c
16071609
if (oldValue.isPlaceholder()) { // T=T or V, not T=String or ? ...
16081610
GenericsTypeName name = new GenericsTypeName(oldValue.getName());
16091611
GenericsType newValue = connections.get(name); // find "V" in T=V
1610-
if (newValue == oldValue || name.getName().charAt(0) == '#') continue;
1612+
if (newValue == oldValue) continue;
16111613
if (newValue == null) {
1612-
entry.setValue(newValue = applyGenericsContext(connections, oldValue));
1614+
newValue = connections.get(entry.getKey());
1615+
if (newValue != null) { // GROOVY-10315, GROOVY-10317
1616+
ClassNode o = makeClassSafe0(CLASS_Type, oldValue),
1617+
n = makeClassSafe0(CLASS_Type, newValue);
1618+
newValue = lowestUpperBound(o,n).getGenericsTypes()[0];
1619+
}
1620+
}
1621+
if (newValue == null) {
1622+
entry.setValue(newValue = applyGenericsContext(connections, oldValue));
16131623
if (!checkForMorePlaceholders) {
16141624
checkForMorePlaceholders = !equalIncludingGenerics(oldValue, newValue);
16151625
}

0 commit comments

Comments
 (0)