James Fredley created GROOVY-12106:
--------------------------------------

             Summary: STC cannot resolve inherited static trait method from 
sub-trait body
                 Key: GROOVY-12106
                 URL: https://issues.apache.org/jira/browse/GROOVY-12106
             Project: Groovy
          Issue Type: Bug
          Components: Static Type Checker
    Affects Versions: 5.0.7
            Reporter: James Fredley


h2. Summary

Groovy 5 static type checking does not resolve a static method declared by a 
parent trait when the method is called from a sub-trait body.

This is independent of Grails and can be reproduced with plain Groovy traits 
under @CompileStatic.

This was re-tested on Groovy 5.0.7-SNAPSHOT. Both an unqualified call and a 
qualified call fail static type checking:

{code:groovy}
inheritedStaticMethod(value)
{code}

{code:groovy}
ParentTrait.inheritedStaticMethod(value)
{code}

The failure is distinct from GROOVY-11985, which fixed 
static-override-via-this. This issue is about resolving a parent trait's static 
method from a sub-trait body.

h2. Standalone reproducer

{code:groovy}
import groovy.transform.CompileStatic

@CompileStatic
trait ParentTrait {
    static void configure(Closure closure, Object target) {
        if (closure != null) {
            closure.delegate = target
            closure.resolveStrategy = Closure.DELEGATE_ONLY
            closure.call()
        }
    }
}

@CompileStatic
trait ChildTrait extends ParentTrait {
    void applyConfig(Closure closure, Object target) {
        configure(closure, target)
    }
}

@CompileStatic
class Example implements ChildTrait {
}
{code}

h2. Expected result

The code should pass static type checking. A sub-trait should be able to 
resolve a static method declared by a parent trait.

h2. Actual result

Static type checking fails on the call from the sub-trait body:

{code}
Cannot find matching method ChildTrait#configure(groovy.lang.Closure, 
java.lang.Object)
{code}

Using a qualified call also fails:

{code:groovy}
ParentTrait.configure(closure, target)
{code}

h2. Real-world use case

Apache Grails has the same pattern in the GraphQL DSL helper traits.

Parent trait method:

{code}
grails-data-graphql/core/src/main/groovy/org/grails/gorm/graphql/entity/dsl/helpers/ExecutesClosures.groovy
line 34
{code}

{code:groovy}
@CompileStatic
trait ExecutesClosures {
    static void withDelegate(@DelegatesTo(strategy = Closure.DELEGATE_ONLY) 
Closure closure, Object delegate) {
        ...
    }
}
{code}

Sub-traits that should be able to call the inherited helper:

{code}
grails-data-graphql/core/src/main/groovy/org/grails/gorm/graphql/entity/dsl/helpers/Arguable.groovy
grails-data-graphql/core/src/main/groovy/org/grails/gorm/graphql/entity/dsl/helpers/ComplexTyped.groovy
{code}

Grails currently works around this by inlining the parent trait helper body 
into each sub-trait. Once this Groovy STC issue is fixed, that inline 
workaround can be removed.

h2. Workaround

Inline the static helper body in each sub-trait, or avoid calling the inherited 
static trait method from the sub-trait.



--
This message was sent by Atlassian Jira
(v8.20.10#820010)

Reply via email to