Skip to content

Commit

Permalink
GROOVY-11383: STC: connect generics from primitive types to Comparable
Browse files Browse the repository at this point in the history
4_0_X backport
  • Loading branch information
eric-milles committed Jun 20, 2024
1 parent c9e9330 commit 011e5d8
Show file tree
Hide file tree
Showing 8 changed files with 31 additions and 13 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -1438,7 +1438,7 @@ && isClassType(receiver)
return typeCheckMethodsWithGenerics(receiver.getGenericsTypes()[0].getType(), argumentTypes, candidateMethod);
}

return typeCheckMethodsWithGenerics(receiver, argumentTypes, candidateMethod, false);
return typeCheckMethodsWithGenerics(StaticTypeCheckingVisitor.wrapTypeIfNecessary(receiver), argumentTypes, candidateMethod, false);
}

private static boolean typeCheckMethodsWithGenerics(final ClassNode receiver, final ClassNode[] argumentTypes, final MethodNode candidateMethod, final boolean isExtensionMethod) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5921,6 +5921,8 @@ protected boolean typeCheckMethodsWithGenericsOrFail(final ClassNode receiver, f
at = new ClassNode[arguments.length + 1];
at[0] = receiver; // object expression is first argument
System.arraycopy(arguments, 0, at, 1, arguments.length);
} else {
r = wrapTypeIfNecessary(r); // GROOVY-11383
}
Map<GenericsTypeName, GenericsType> spec = extractPlaceHoldersVisibleToDeclaration(r, m, null);
GenericsType[] gt = applyGenericsContext(spec, m.getGenericsTypes()); // class params in bounds
Expand Down Expand Up @@ -5998,7 +6000,7 @@ protected void addNoMatchingMethodError(final ClassNode receiver, final String n
if (receiver.isEnum() && args.length >= 2) args = Arrays.copyOfRange(args, 2, args.length);
error = "Cannot find matching constructor " + prettyPrintTypeName(receiver) + toMethodParametersString("", args);
} else {
ClassNode type = isClassClassNodeWrappingConcreteType(receiver) ? receiver.getGenericsTypes()[0].getType() : receiver;
ClassNode type = isClassClassNodeWrappingConcreteType(receiver) ? receiver.getGenericsTypes()[0].getType() : wrapTypeIfNecessary(receiver);
error = "Cannot find matching method " + prettyPrintTypeName(type) + "#" + toMethodParametersString(name, args) + ". Please check if the declared type is correct and if the method exists.";
}
addStaticTypeError(error, origin);
Expand Down
10 changes: 5 additions & 5 deletions src/test/groovy/transform/stc/BugsSTCTest.groovy
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ class BugsSTCTest extends StaticTypeCheckingTestCase {
def foo(Closure cls) {}
def bar() { foo { 2 / it } }
''',
'Cannot find matching method int#div(java.lang.Object)'
'Cannot find matching method java.lang.Integer#div(java.lang.Object)'
}
void testShouldNotAllowModOnUntypedVariable() {
shouldFailWithMessages '''
Expand All @@ -52,7 +52,7 @@ class BugsSTCTest extends StaticTypeCheckingTestCase {
def foo(Closure cls) {}
def bar() { foo { 2 % it } }
''',
'Cannot find matching method int#mod(java.lang.Object)'
'Cannot find matching method java.lang.Integer#mod(java.lang.Object)'
}
void testShouldNotAllowMulOnUntypedVariable() {
shouldFailWithMessages '''
Expand All @@ -66,7 +66,7 @@ class BugsSTCTest extends StaticTypeCheckingTestCase {
def foo(Closure cls) {}
def bar() { foo { 2 * it } }
''',
'Cannot find matching method int#multiply(java.lang.Object)'
'Cannot find matching method java.lang.Integer#multiply(java.lang.Object)'
}
void testShouldNotAllowPlusOnUntypedVariable() {
shouldFailWithMessages '''
Expand All @@ -80,7 +80,7 @@ class BugsSTCTest extends StaticTypeCheckingTestCase {
def foo(Closure cls) {}
def bar() { foo { 2 + it } }
''',
'Cannot find matching method int#plus(java.lang.Object)'
'Cannot find matching method java.lang.Integer#plus(java.lang.Object)'
}
void testShouldNotAllowMinusOnUntypedVariable() {
shouldFailWithMessages '''
Expand All @@ -94,7 +94,7 @@ class BugsSTCTest extends StaticTypeCheckingTestCase {
def foo(Closure cls) {}
def bar() { foo { 2 - it } }
''',
'Cannot find matching method int#minus(java.lang.Object)'
'Cannot find matching method java.lang.Integer#minus(java.lang.Object)'
}

// GROOVY-7929
Expand Down
15 changes: 15 additions & 0 deletions src/test/groovy/transform/stc/GenericsSTCTest.groovy
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,21 @@ class GenericsSTCTest extends StaticTypeCheckingTestCase {
'''
}

void testCompareToOnPrimitive() {
assertScript '''
int a = 1
assert (a < 2)
assert !(a < 1)
assert (a <= 1)
'''
// GROOVY-11383
shouldFailWithMessages '''
int a = 42
def b = (a < new Object())
''',
'Cannot find matching method java.lang.Integer#compareTo(java.lang.Object)'
}

void testReturnTypeInference1() {
assertScript '''
class Foo<U> {
Expand Down
4 changes: 2 additions & 2 deletions src/test/groovy/transform/stc/STCAssignmentTest.groovy
Original file line number Diff line number Diff line change
Expand Up @@ -146,15 +146,15 @@ class STCAssignmentTest extends StaticTypeCheckingTestCase {
int i = 0
i += new Object()
''',
'Cannot find matching method int#plus(java.lang.Object)'
'Cannot find matching method java.lang.Integer#plus(java.lang.Object)'
}

void testIntMinusEqualsObject() {
shouldFailWithMessages '''
int i = 0
i -= new Object()
''',
'Cannot find matching method int#minus(java.lang.Object)'
'Cannot find matching method java.lang.Integer#minus(java.lang.Object)'
}

void testStringPlusEqualsString() {
Expand Down
2 changes: 1 addition & 1 deletion src/test/groovy/transform/stc/STCnAryExpressionTest.groovy
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ class STCnAryExpressionTest extends StaticTypeCheckingTestCase {
int num = 2
num+obj
''',
'Cannot find matching method int#plus(java.lang.Object)'
'Cannot find matching method java.lang.Integer#plus(java.lang.Object)'
}

void testPrimitiveComparison() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -331,7 +331,7 @@ class TypeCheckingExtensionsTest extends StaticTypeCheckingTestCase {
Date y = new Date()
x+y
''',
'Cannot find matching method int#plus(java.util.Date)'
'Cannot find matching method java.lang.Integer#plus(java.util.Date)'

extension = 'groovy/transform/stc/BinaryOperatorTestExtension.groovy'
assertScript '''
Expand All @@ -350,7 +350,7 @@ class TypeCheckingExtensionsTest extends StaticTypeCheckingTestCase {
Date y = new Date()
x << y
''',
'Cannot find matching method int#leftShift(java.util.Date)'
'Cannot find matching method java.lang.Integer#leftShift(java.util.Date)'

extension = 'groovy/transform/stc/BinaryOperatorTestExtension.groovy'
assertScript '''
Expand Down
3 changes: 2 additions & 1 deletion src/test/groovy/transform/stc/TypeInferenceSTCTest.groovy
Original file line number Diff line number Diff line change
Expand Up @@ -889,7 +889,8 @@ class TypeInferenceSTCTest extends StaticTypeCheckingTestCase {
a.with {
method().toUpperCase()
}
''', 'Cannot find matching method int#toUpperCase()'
''',
'Cannot find matching method java.lang.Integer#toUpperCase()'
}

void testDeclarationTypeInference() {
Expand Down

0 comments on commit 011e5d8

Please sign in to comment.