Skip to content

Commit

Permalink
GROOVY-11302: retain method call type args in trait
Browse files Browse the repository at this point in the history
  • Loading branch information
eric-milles committed Jan 30, 2024
1 parent 710ff9e commit 2a6a60b
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 16 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -301,6 +301,7 @@ private Expression transformMethodCallOnThis(final MethodCallExpression call) {

// this.m(x) --> ($self or $static$self).m(x)
MethodCallExpression newCall = callX(inClosure ? thisExpr : weaved, method, transform(arguments));
newCall.setGenericsTypes(call.getGenericsTypes()); // GROOVY-11302: this.<T>m(x)
newCall.setImplicitThis(inClosure ? call.isImplicitThis() : false);
newCall.setSafe(inClosure ? call.isSafe() : false);
newCall.setSpreadSafe(call.isSpreadSafe());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3175,40 +3175,33 @@ final class TraitASTTransformationTest {
assertScript shell, '''
trait Configurable<ConfigObject> {
ConfigObject configObject
void configure(Closure<Void> configSpec) {
configSpec.resolveStrategy = Closure.DELEGATE_FIRST
configSpec.delegate = configObject
configSpec()
}
}
public <T,U extends Configurable<T>> U configure(Class<U> clazz, @DelegatesTo(type="T") Closure configSpec) {
def <T,U extends Configurable<T>> U configure(Class<U> clazz, @DelegatesTo(type="T") Closure configSpec) {
Configurable<T> obj = (Configurable<T>) clazz.newInstance()
obj.configure(configSpec)
obj
}
class Module implements Configurable<ModuleConfig> {
String value
Module(){
Module() {
configObject = new ModuleConfig()
}
@Override
void configure(Closure<Void> configSpec) {
Configurable.super.configure(configSpec)
value = "${configObject.name}-${configObject.version}"
}
}
class ModuleConfig {
String name
String version
}
def module = configure(Module) {
name = 'test'
version = '1.0'
Expand Down Expand Up @@ -3273,19 +3266,48 @@ final class TraitASTTransformationTest {
'''
}

// GROOVY-11302
@Test
void testTraitWithMethodGenericsSTC() {
assertScript shell, '''
trait T {
def <X> X m(x) {x}
@TypeChecked
def test() {
Number n = 1
n = this.<Number>m(n)
}
}
class C implements T {
}
new C().test()
'''

def err = shouldFail shell, '''
trait U {
def <X> X m(x) {x}
@TypeChecked
def test() {
Number n = 1
n = this.<Object>m(n)
}
}
'''
assert err =~ /Cannot assign value of type java.lang.Object to variable of type java.lang.Number/
}

// GROOVY-8281
@Test
void testFinalFieldsDependency() {
assertScript shell, '''
trait MyTrait {
trait T {
private final String foo = 'foo'
private final String foobar = foo.toUpperCase() + 'bar'
int foobarSize() { foobar.size() }
int test() { foobar.size() }
}
class Baz implements MyTrait {}
assert new Baz().foobarSize() == 6
class C implements T {
}
assert new C().test() == 6
'''
}

Expand Down

0 comments on commit 2a6a60b

Please sign in to comment.