Skip to content

Commit 3602002

Browse files
committed
GROOVY-9890
1 parent b362e63 commit 3602002

File tree

4 files changed

+89
-17
lines changed

4 files changed

+89
-17
lines changed

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

+29
Original file line numberDiff line numberDiff line change
@@ -5503,6 +5503,35 @@ public void testCompileStatic9885() {
55035503
runConformTest(sources, "C(x)C(y)C(123)");
55045504
}
55055505

5506+
@Test
5507+
public void testCompileStatic9890() {
5508+
//@formatter:off
5509+
String[] sources = {
5510+
"Main.groovy",
5511+
"class C implements I {\n" +
5512+
" void m(String s) {\n" +
5513+
" throw new Exception()\n" +
5514+
" }\n" +
5515+
"}\n" +
5516+
"@groovy.transform.CompileStatic\n" +
5517+
"void test() {\n" +
5518+
" new C().m(42L)\n" +
5519+
"}\n" +
5520+
"test()\n",
5521+
5522+
"I.java",
5523+
"public interface I {\n" +
5524+
" default void m(long n) {\n" +
5525+
" System.out.print(n);\n" +
5526+
" }\n" +
5527+
" void m(String s);\n" +
5528+
"}\n",
5529+
};
5530+
//@formatter:on
5531+
5532+
runConformTest(sources, "42");
5533+
}
5534+
55065535
@Test
55075536
public void testCompileStatic9892() {
55085537
//@formatter:off

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

+20-5
Original file line numberDiff line numberDiff line change
@@ -2629,7 +2629,9 @@ && getType(nameExpr).equals(STRING_TYPE)) {
26292629
ClassNode receiverType = wrapTypeIfNecessary(currentReceiver.getType());
26302630

26312631
candidates = findMethodsWithGenerated(receiverType, nameText);
2632+
/* GRECLIPSE edit -- GROOVY-9890
26322633
collectAllInterfaceMethodsByName(receiverType, nameText, candidates);
2634+
*/
26332635
if (isBeingCompiled(receiverType)) candidates.addAll(GROOVY_OBJECT_TYPE.getMethods(nameText));
26342636
candidates.addAll(StaticTypeCheckingSupport.findDGMMethodsForClassNode(getTransformLoader(), receiverType, nameText));
26352637
candidates = filterMethodsByVisibility(candidates);
@@ -4710,7 +4712,7 @@ private ClassNode inferSAMTypeGenericsInAssignment(ClassNode samUsage, MethodNod
47104712

47114713
// extract the generics from the return type
47124714
Map<GenericsTypeName, GenericsType> connections = new HashMap<GenericsTypeName, GenericsType>();
4713-
extractGenericsConnections(connections, getWrapper(getInferredReturnType(closureExpression)), sam.getReturnType());
4715+
extractGenericsConnections(connections, wrapTypeIfNecessary(getInferredReturnType(closureExpression)), sam.getReturnType());
47144716

47154717
// next we get the block parameter types and set the generics
47164718
// information just like before
@@ -4855,6 +4857,18 @@ protected boolean areCategoryMethodCalls(final List<MethodNode> foundMethods, fi
48554857
*/
48564858
protected List<MethodNode> findMethodsWithGenerated(ClassNode receiver, String name) {
48574859
List<MethodNode> methods = receiver.getMethods(name);
4860+
// GRECLIPSE add -- GROOVY-9890
4861+
if (receiver.isAbstract()) {
4862+
collectAllInterfaceMethodsByName(receiver, name, methods);
4863+
} else {
4864+
List<MethodNode> interfaceMethods = new ArrayList<>();
4865+
collectAllInterfaceMethodsByName(receiver, name, interfaceMethods);
4866+
interfaceMethods.stream().filter(MethodNode::isDefault).forEach(methods::add);
4867+
}
4868+
if (receiver.isInterface()) {
4869+
methods.addAll(OBJECT_TYPE.getMethods(name));
4870+
}
4871+
// GRECLIPSE end
48584872
if (methods.isEmpty() || receiver.isResolved()) return methods;
48594873
List<MethodNode> result = addGeneratedMethods(receiver, methods);
48604874

@@ -4917,8 +4931,7 @@ private static List<MethodNode> addGeneratedMethods(final ClassNode receiver, fi
49174931
return result;
49184932
}
49194933

4920-
protected List<MethodNode> findMethod(
4921-
ClassNode receiver, String name, ClassNode... args) {
4934+
protected List<MethodNode> findMethod(ClassNode receiver, final String name, final ClassNode... args) {
49224935
if (isPrimitiveType(receiver)) receiver = getWrapper(receiver);
49234936
List<MethodNode> methods;
49244937
if (!receiver.isInterface() && "<init>".equals(name)) {
@@ -4936,10 +4949,12 @@ protected List<MethodNode> findMethod(
49364949
}
49374950
} else {
49384951
methods = findMethodsWithGenerated(receiver, name);
4952+
/* GRECLIPSE edit -- GROOVY-9890
49394953
if (receiver.isInterface()) {
49404954
collectAllInterfaceMethodsByName(receiver, name, methods);
49414955
methods.addAll(OBJECT_TYPE.getMethods(name));
49424956
}
4957+
*/
49434958
// TODO: investigate the trait exclusion a bit further, needed otherwise
49444959
// CallMethodOfTraitInsideClosureAndClosureParamTypeInference fails saying
49454960
// not static method can't be called from a static context
@@ -5006,13 +5021,13 @@ protected List<MethodNode> findMethod(
50065021
}
50075022
}
50085023
}
5009-
5024+
/* GRECLIPSE edit -- GROOVY-9890
50105025
if (methods.isEmpty()) {
50115026
// look at the interfaces, there's a chance that a method is not implemented and we should not hide the
50125027
// error from the compiler
50135028
collectAllInterfaceMethodsByName(receiver, name, methods);
50145029
}
5015-
5030+
*/
50165031
// lookup in DGM methods too
50175032
// GRECLIPSE add
50185033
if (!"<init>".equals(name) && !"<clinit>".equals(name))

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

+20-6
Original file line numberDiff line numberDiff line change
@@ -2419,7 +2419,9 @@ && getType(nameExpr).equals(STRING_TYPE)) {
24192419
ClassNode receiverType = wrapTypeIfNecessary(currentReceiver.getType());
24202420

24212421
candidates = findMethodsWithGenerated(receiverType, nameText);
2422+
/* GRECLIPSE edit -- GROOVY-9890
24222423
collectAllInterfaceMethodsByName(receiverType, nameText, candidates);
2424+
*/
24232425
if (isBeingCompiled(receiverType)) candidates.addAll(GROOVY_OBJECT_TYPE.getMethods(nameText));
24242426
candidates.addAll(findDGMMethodsForClassNode(getTransformLoader(), receiverType, nameText));
24252427
candidates = filterMethodsByVisibility(candidates, typeCheckingContext.getEnclosingClassNode());
@@ -4484,7 +4486,7 @@ private ClassNode inferSAMTypeGenericsInAssignment(final ClassNode samType, fina
44844486

44854487
// extract the generics from the return type
44864488
Map<GenericsTypeName, GenericsType> connections = new HashMap<>();
4487-
extractGenericsConnections(connections, getWrapper(getInferredReturnType(closureExpression)), abstractMethod.getReturnType());
4489+
extractGenericsConnections(connections, wrapTypeIfNecessary(getInferredReturnType(closureExpression)), abstractMethod.getReturnType());
44884490

44894491
// next we get the block parameter types and set the generics
44904492
// information just like before
@@ -4645,6 +4647,18 @@ protected boolean areCategoryMethodCalls(final List<MethodNode> foundMethods, fi
46454647
*/
46464648
protected List<MethodNode> findMethodsWithGenerated(final ClassNode receiver, final String name) {
46474649
List<MethodNode> methods = receiver.getMethods(name);
4650+
// GRECLIPSE add -- GROOVY-9890
4651+
if (receiver.isAbstract()) {
4652+
collectAllInterfaceMethodsByName(receiver, name, methods);
4653+
} else {
4654+
List<MethodNode> interfaceMethods = new ArrayList<>();
4655+
collectAllInterfaceMethodsByName(receiver, name, interfaceMethods);
4656+
interfaceMethods.stream().filter(MethodNode::isDefault).forEach(methods::add);
4657+
}
4658+
if (receiver.isInterface()) {
4659+
methods.addAll(OBJECT_TYPE.getMethods(name));
4660+
}
4661+
// GRECLIPSE end
46484662
if (methods.isEmpty() || receiver.isResolved()) return methods;
46494663
return addGeneratedMethods(receiver, methods);
46504664
}
@@ -4724,16 +4738,16 @@ protected List<MethodNode> findMethod(ClassNode receiver, final String name, fin
47244738
} else {
47254739
methods = findMethodsWithGenerated(receiver, name);
47264740
if (receiver.isInterface()) {
4741+
/* GRECLIPSE edit -- GROOVY-9890
47274742
collectAllInterfaceMethodsByName(receiver, name, methods);
47284743
methods.addAll(OBJECT_TYPE.getMethods(name));
4729-
4744+
*/
47304745
if ("call".equals(name) && isFunctionalInterface(receiver)) {
47314746
MethodNode sam = findSAM(receiver);
47324747
MethodNode callMethodNode = new MethodNode("call", sam.getModifiers(), sam.getReturnType(), sam.getParameters(), sam.getExceptions(), sam.getCode());
47334748
callMethodNode.setDeclaringClass(sam.getDeclaringClass());
47344749
callMethodNode.setSourcePosition(sam);
4735-
4736-
methods.addAll(Collections.singletonList(callMethodNode));
4750+
methods.add(callMethodNode);
47374751
}
47384752
}
47394753
// TODO: investigate the trait exclusion a bit further, needed otherwise
@@ -4802,13 +4816,13 @@ protected List<MethodNode> findMethod(ClassNode receiver, final String name, fin
48024816
}
48034817
}
48044818
}
4805-
4819+
/* GRECLIPSE edit -- GROOVY-9890
48064820
if (methods.isEmpty()) {
48074821
// look at the interfaces, there's a chance that a method is not implemented and we should not hide the
48084822
// error from the compiler
48094823
collectAllInterfaceMethodsByName(receiver, name, methods);
48104824
}
4811-
4825+
*/
48124826
if (!"<init>".equals(name) && !"<clinit>".equals(name)) {
48134827
// lookup in DGM methods too
48144828
findDGMMethodsByNameAndArguments(getSourceUnit().getClassLoader(), receiver, name, args, methods);

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

+20-6
Original file line numberDiff line numberDiff line change
@@ -2406,7 +2406,9 @@ && getType(nameExpr).equals(STRING_TYPE)) {
24062406
ClassNode receiverType = wrapTypeIfNecessary(currentReceiver.getType());
24072407

24082408
candidates = findMethodsWithGenerated(receiverType, nameText);
2409+
/* GRECLIPSE edit -- GROOVY-9890
24092410
collectAllInterfaceMethodsByName(receiverType, nameText, candidates);
2411+
*/
24102412
if (isBeingCompiled(receiverType)) candidates.addAll(GROOVY_OBJECT_TYPE.getMethods(nameText));
24112413
candidates.addAll(findDGMMethodsForClassNode(getTransformLoader(), receiverType, nameText));
24122414
candidates = filterMethodsByVisibility(candidates, typeCheckingContext.getEnclosingClassNode());
@@ -4450,7 +4452,7 @@ private ClassNode inferSAMTypeGenericsInAssignment(final ClassNode samType, fina
44504452

44514453
// extract the generics from the return type
44524454
Map<GenericsTypeName, GenericsType> connections = new HashMap<>();
4453-
extractGenericsConnections(connections, getWrapper(getInferredReturnType(closureExpression)), abstractMethod.getReturnType());
4455+
extractGenericsConnections(connections, wrapTypeIfNecessary(getInferredReturnType(closureExpression)), abstractMethod.getReturnType());
44544456

44554457
// next we get the block parameter types and set the generics
44564458
// information just like before
@@ -4611,6 +4613,18 @@ protected boolean areCategoryMethodCalls(final List<MethodNode> foundMethods, fi
46114613
*/
46124614
protected List<MethodNode> findMethodsWithGenerated(final ClassNode receiver, final String name) {
46134615
List<MethodNode> methods = receiver.getMethods(name);
4616+
// GRECLIPSE add -- GROOVY-9890
4617+
if (receiver.isAbstract()) {
4618+
collectAllInterfaceMethodsByName(receiver, name, methods);
4619+
} else {
4620+
List<MethodNode> interfaceMethods = new ArrayList<>();
4621+
collectAllInterfaceMethodsByName(receiver, name, interfaceMethods);
4622+
interfaceMethods.stream().filter(MethodNode::isDefault).forEach(methods::add);
4623+
}
4624+
if (receiver.isInterface()) {
4625+
methods.addAll(OBJECT_TYPE.getMethods(name));
4626+
}
4627+
// GRECLIPSE end
46144628
if (methods.isEmpty() || receiver.isResolved()) return methods;
46154629
return addGeneratedMethods(receiver, methods);
46164630
}
@@ -4690,16 +4704,16 @@ protected List<MethodNode> findMethod(ClassNode receiver, final String name, fin
46904704
} else {
46914705
methods = findMethodsWithGenerated(receiver, name);
46924706
if (receiver.isInterface()) {
4707+
/* GRECLIPSE edit -- GROOVY-9890
46934708
collectAllInterfaceMethodsByName(receiver, name, methods);
46944709
methods.addAll(OBJECT_TYPE.getMethods(name));
4695-
4710+
*/
46964711
if ("call".equals(name) && isFunctionalInterface(receiver)) {
46974712
MethodNode sam = findSAM(receiver);
46984713
MethodNode callMethodNode = new MethodNode("call", sam.getModifiers(), sam.getReturnType(), sam.getParameters(), sam.getExceptions(), sam.getCode());
46994714
callMethodNode.setDeclaringClass(sam.getDeclaringClass());
47004715
callMethodNode.setSourcePosition(sam);
4701-
4702-
methods.addAll(Collections.singletonList(callMethodNode));
4716+
methods.add(callMethodNode);
47034717
}
47044718
}
47054719
// TODO: investigate the trait exclusion a bit further, needed otherwise
@@ -4768,13 +4782,13 @@ protected List<MethodNode> findMethod(ClassNode receiver, final String name, fin
47684782
}
47694783
}
47704784
}
4771-
4785+
/* GRECLIPSE edit -- GROOVY-9890
47724786
if (methods.isEmpty()) {
47734787
// look at the interfaces, there's a chance that a method is not implemented and we should not hide the
47744788
// error from the compiler
47754789
collectAllInterfaceMethodsByName(receiver, name, methods);
47764790
}
4777-
4791+
*/
47784792
if (!"<init>".equals(name) && !"<clinit>".equals(name)) {
47794793
// lookup in DGM methods too
47804794
findDGMMethodsByNameAndArguments(getSourceUnit().getClassLoader(), receiver, name, args, methods);

0 commit comments

Comments
 (0)