Skip to content

Commit e37db10

Browse files
committed
GROOVY-6882
1 parent 542e5f1 commit e37db10

4 files changed

Lines changed: 86 additions & 4 deletions

File tree

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ public void testCompileStatic1() {
6969
"1. ERROR in Main.groovy (at line 5)\n" +
7070
"\tls.add('abc')\n" +
7171
"\t^^^^^^^^^^^^^\n" +
72-
"Groovy:[Static type checking] - Cannot call java.util.ArrayList <Integer>#add(java.lang.Integer) with arguments [java.lang.String] \n" +
72+
"Groovy:[Static type checking] - Cannot find matching method java.util.ArrayList#add(java.lang.String). Please check if the declared type is correct and if the method exists.\n" +
7373
"----------\n");
7474
}
7575

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

Lines changed: 35 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ public void testTypeChecked2() {
7373
"1. ERROR in Foo.groovy (at line 6)\n" +
7474
"\tls.add(\'abc\')\n" +
7575
"\t^^^^^^^^^^^^^\n" +
76-
"Groovy:[Static type checking] - Cannot call java.util.ArrayList <Integer>#add(java.lang.Integer) with arguments [java.lang.String] \n" +
76+
"Groovy:[Static type checking] - Cannot find matching method java.util.ArrayList#add(java.lang.String). Please check if the declared type is correct and if the method exists.\n" +
7777
"----------\n");
7878
}
7979

@@ -214,6 +214,40 @@ public void testTypeChecked9() {
214214
runNegativeTest(sources, "");
215215
}
216216

217+
@Test
218+
public void testTypeChecked6882() {
219+
//@formatter:off
220+
String[] sources = {
221+
"Main.groovy",
222+
"class B {\n" +
223+
" void m() {\n" +
224+
" print 'B'\n" +
225+
" }\n" +
226+
"}\n" +
227+
"@groovy.transform.TypeChecked\n" +
228+
"class C extends B {\n" +
229+
" @Override\n" +
230+
" void m() {\n" +
231+
" print 'C'\n" +
232+
" }\n" +
233+
" void test() {\n" +
234+
" def x = new Runnable() {\n" +
235+
" @Override\n" +
236+
" void run() {\n" +
237+
" m()\n" + // Reference to method is ambiguous. Cannot choose between [void C#m(), void B#m()]
238+
" }\n" +
239+
" }\n" +
240+
" x.run()\n" +
241+
" m()\n" +
242+
" }\n" +
243+
"}\n" +
244+
"new C().test()\n",
245+
};
246+
//@formatter:on
247+
248+
runConformTest(sources, "CC");
249+
}
250+
217251
@Test
218252
public void testTypeChecked7333() {
219253
//@formatter:off

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

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1103,7 +1103,7 @@ Person foo(B i){...}
11031103
Person p = foo(b)
11041104
*/
11051105

1106-
Map<GenericsType, GenericsType> declaringAndActualGenericsTypeMap = GenericsUtils.makeDeclaringAndActualGenericsTypeMap(declaringClassForDistance, actualReceiverForDistance);
1106+
Map<GenericsType, GenericsType> declaringAndActualGenericsTypeMap = GenericsUtils.makeDeclaringAndActualGenericsTypeMapOfExactType(declaringClassForDistance, actualReceiverForDistance);
11071107
Parameter[] params = makeRawTypes(safeNode.getParameters(), declaringAndActualGenericsTypeMap);
11081108
int dist = measureParametersAndArgumentsDistance(params, safeArgs);
11091109
if (dist >= 0) {
@@ -1238,7 +1238,12 @@ private static Collection<MethodNode> removeCovariantsAndInterfaceEquivalents(Co
12381238
MethodNode two = list.get(j);
12391239
if (toBeRemoved.contains(two)) continue;
12401240
if (one.getParameters().length == two.getParameters().length) {
1241+
/* GRECLIPSE edit -- GROOVY-6882, GROOVY-6970
12411242
if (areOverloadMethodsInSameClass(one, two)) {
1243+
*/
1244+
ClassNode oneDC = one.getDeclaringClass(), twoDC = two.getDeclaringClass();
1245+
if (oneDC == twoDC) {
1246+
// GRECLIPSE end
12421247
if (ParameterUtils.parametersEqual(one.getParameters(), two.getParameters())) {
12431248
removeMethodWithSuperReturnType(toBeRemoved, one, two);
12441249
} else {
@@ -1247,10 +1252,25 @@ private static Collection<MethodNode> removeCovariantsAndInterfaceEquivalents(Co
12471252
// in that case, Java marks the Object version as synthetic
12481253
removeSyntheticMethodIfOne(toBeRemoved, one, two);
12491254
}
1255+
/* GRECLIPSE edit -- GROOVY-6882, GROOVY-6970
12501256
} else if (areEquivalentInterfaceMethods(one, two)) {
12511257
// GROOVY-6970 choose between equivalent interface methods
12521258
removeMethodInSuperInterface(toBeRemoved, one, two);
12531259
}
1260+
*/
1261+
} else if (!oneDC.equals(twoDC)) {
1262+
if (ParameterUtils.parametersEqual(one.getParameters(), two.getParameters())) {
1263+
// GROOVY-6882, GROOVY-6970: drop overridden or interface equivalent method
1264+
if (twoDC.isInterface() ? oneDC.implementsInterface(twoDC)
1265+
: oneDC.isDerivedFrom(twoDC)) {
1266+
toBeRemoved.add(two);
1267+
} else if (oneDC.isInterface() ? twoDC.isInterface()
1268+
: twoDC.isDerivedFrom(oneDC)) {
1269+
toBeRemoved.add(one);
1270+
}
1271+
}
1272+
}
1273+
// GRECLIPSE end
12541274
}
12551275
}
12561276
}
@@ -1260,6 +1280,7 @@ private static Collection<MethodNode> removeCovariantsAndInterfaceEquivalents(Co
12601280
return result;
12611281
}
12621282

1283+
/* GRECLIPSE edit
12631284
private static void removeMethodInSuperInterface(List<MethodNode> toBeRemoved, MethodNode one, MethodNode two) {
12641285
ClassNode oneDC = one.getDeclaringClass();
12651286
ClassNode twoDC = two.getDeclaringClass();
@@ -1276,6 +1297,7 @@ private static boolean areEquivalentInterfaceMethods(MethodNode one, MethodNode
12761297
&& two.getDeclaringClass().isInterface()
12771298
&& ParameterUtils.parametersEqual(one.getParameters(), two.getParameters());
12781299
}
1300+
*/
12791301

12801302
private static void removeSyntheticMethodIfOne(List<MethodNode> toBeRemoved, MethodNode one, MethodNode two) {
12811303
if (one.isSynthetic() && !two.isSynthetic()) {
@@ -1302,9 +1324,11 @@ private static boolean isCovariant(ClassNode left, ClassNode right) {
13021324
return left.isDerivedFrom(right) || left.implementsInterface(right);
13031325
}
13041326

1327+
/* GRECLIPSE edit
13051328
private static boolean areOverloadMethodsInSameClass(MethodNode one, MethodNode two) {
13061329
return one.getName().equals(two.getName()) && one.getDeclaringClass() == two.getDeclaringClass();
13071330
}
1331+
*/
13081332

13091333
/**
13101334
* Given a receiver and a method node, parameterize the method arguments using

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

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1039,7 +1039,7 @@ Person foo(B i){...}
10391039
Person p = foo(b)
10401040
*/
10411041

1042-
Map<GenericsType, GenericsType> declaringAndActualGenericsTypeMap = GenericsUtils.makeDeclaringAndActualGenericsTypeMap(declaringClassForDistance, actualReceiverForDistance);
1042+
Map<GenericsType, GenericsType> declaringAndActualGenericsTypeMap = GenericsUtils.makeDeclaringAndActualGenericsTypeMapOfExactType(declaringClassForDistance, actualReceiverForDistance);
10431043
Parameter[] params = makeRawTypes(safeNode.getParameters(), declaringAndActualGenericsTypeMap);
10441044
int dist = measureParametersAndArgumentsDistance(params, safeArgs);
10451045
if (dist >= 0) {
@@ -1162,7 +1162,12 @@ private static Collection<MethodNode> removeCovariantsAndInterfaceEquivalents(fi
11621162
MethodNode two = list.get(j);
11631163
if (toBeRemoved.contains(two)) continue;
11641164
if (one.getParameters().length == two.getParameters().length) {
1165+
/* GRECLIPSE edit -- GROOVY-6882, GROOVY-6970
11651166
if (areOverloadMethodsInSameClass(one, two)) {
1167+
*/
1168+
ClassNode oneDC = one.getDeclaringClass(), twoDC = two.getDeclaringClass();
1169+
if (oneDC == twoDC) {
1170+
// GRECLIPSE end
11661171
if (ParameterUtils.parametersEqual(one.getParameters(), two.getParameters())) {
11671172
removeMethodWithSuperReturnType(toBeRemoved, one, two);
11681173
} else {
@@ -1171,10 +1176,25 @@ private static Collection<MethodNode> removeCovariantsAndInterfaceEquivalents(fi
11711176
// in that case, Java marks the Object version as synthetic
11721177
removeSyntheticMethodIfOne(toBeRemoved, one, two);
11731178
}
1179+
/* GRECLIPSE edit -- GROOVY-6882, GROOVY-6970
11741180
} else if (areEquivalentInterfaceMethods(one, two)) {
11751181
// GROOVY-6970: choose between equivalent interface methods
11761182
removeMethodInSuperInterface(toBeRemoved, one, two);
11771183
}
1184+
*/
1185+
} else if (!oneDC.equals(twoDC)) {
1186+
if (ParameterUtils.parametersEqual(one.getParameters(), two.getParameters())) {
1187+
// GROOVY-6882, GROOVY-6970: drop overridden or interface equivalent method
1188+
if (twoDC.isInterface() ? oneDC.implementsInterface(twoDC)
1189+
: oneDC.isDerivedFrom(twoDC)) {
1190+
toBeRemoved.add(two);
1191+
} else if (oneDC.isInterface() ? twoDC.isInterface()
1192+
: twoDC.isDerivedFrom(oneDC)) {
1193+
toBeRemoved.add(one);
1194+
}
1195+
}
1196+
}
1197+
// GRECLIPSE end
11781198
}
11791199
}
11801200
}
@@ -1184,6 +1204,7 @@ private static Collection<MethodNode> removeCovariantsAndInterfaceEquivalents(fi
11841204
return result;
11851205
}
11861206

1207+
/* GRECLIPSE edit
11871208
private static void removeMethodInSuperInterface(final List<MethodNode> toBeRemoved, final MethodNode one, final MethodNode two) {
11881209
ClassNode oneDC = one.getDeclaringClass();
11891210
ClassNode twoDC = two.getDeclaringClass();
@@ -1200,6 +1221,7 @@ private static boolean areEquivalentInterfaceMethods(final MethodNode one, final
12001221
&& two.getDeclaringClass().isInterface()
12011222
&& ParameterUtils.parametersEqual(one.getParameters(), two.getParameters()));
12021223
}
1224+
*/
12031225

12041226
private static void removeSyntheticMethodIfOne(final List<MethodNode> toBeRemoved, final MethodNode one, final MethodNode two) {
12051227
if (one.isSynthetic() && !two.isSynthetic()) {
@@ -1226,9 +1248,11 @@ private static boolean isCovariant(final ClassNode left, final ClassNode right)
12261248
return (left.isDerivedFrom(right) || left.implementsInterface(right));
12271249
}
12281250

1251+
/* GRECLIPSE edit
12291252
private static boolean areOverloadMethodsInSameClass(final MethodNode one, final MethodNode two) {
12301253
return (one.getName().equals(two.getName()) && one.getDeclaringClass() == two.getDeclaringClass());
12311254
}
1255+
*/
12321256

12331257
/**
12341258
* Given a receiver and a method node, parameterize the method arguments using

0 commit comments

Comments
 (0)