[
https://issues.apache.org/jira/browse/GROOVY-12590?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
]
Scott Murphy Heiberg updated GROOVY-12590:
------------------------------------------
Description:
{code:groovy}
@groovy.transform.CompileStatic
trait T {
static boolean flag = true
static boolean isReady() { flag }
static String sm() { ready ? 'yes' : 'no' }
static Closure getG() { { -> flag } }
static Object sg() { g.call() }
}
class C implements T {}
assert C.sm() == 'yes'
assert C.sg() == true
{code}
Actual: groovy.lang.MissingMethodException: No signature of static method:
T__flag$get for class: T is applicable for argument types: () values: []
Expected: both assertions pass, as they do with @TypeChecked or without an
annotation, and as they do when the accessor is called directly ({{isReady()}},
{{getG()}}).
The same happens in instance trait methods, in closures and lambdas, and when a
static accessor is written with property syntax ({{cnt = 1}}, {{cnt += 1}},
{{cnt++}} for a static {{setCnt(int)}}), including for an accessor of a super
trait. Under static compilation the property resolves to the static method that
the trait interface declares, which forwards to the trait helper with the trait
itself as the receiver class, so the accessor cannot reach the implementing
class's trait state. The direct method call passes the implementing class to
the helper instead.
Seen in 6.0.0 and master. 5.0.8 rejects the code with "No such property: ready
for Class or static property for class: T", and 4.0.33 with "Access to T#ready
is forbidden".
PR: https://github.com/apache/groovy/pull/3115
was:
{code:groovy}
@groovy.transform.CompileStatic
trait T {
static boolean flag = true
static boolean isReady() { flag }
static String sm() { ready ? 'yes' : 'no' }
static Closure getG() { { -> flag } }
static Object sg() { g.call() }
}
class C implements T {}
assert C.sm() == 'yes'
assert C.sg() == true
{code}
Actual: groovy.lang.MissingMethodException: No signature of static method:
T__flag$get for class: T is applicable for argument types: () values: []
Expected: both assertions pass, as they do with @TypeChecked or without an
annotation, and as they do when the accessor is called directly ({{isReady()}},
{{getG()}}).
The same happens in instance trait methods, in closures and lambdas, and when a
static accessor is written with property syntax ({{cnt = 1}}, {{cnt += 1}},
{{cnt++}} for a static {{setCnt(int)}}), including for an accessor of a super
trait. Under static compilation the property resolves to the static method that
the trait interface declares, which forwards to the trait helper with the trait
itself as the receiver class, so the accessor cannot reach the implementing
class's trait state. The direct method call passes the implementing class to
the helper instead.
Seen in 6.0.0 and master. 5.0.8 rejects the code with "No such property: ready
for Class or static property for class: T", and 4.0.33 with "Access to T#ready
is forbidden".
> SC calls a trait's static accessor read as a property on the trait instead of
> the implementing class
> ----------------------------------------------------------------------------------------------------
>
> Key: GROOVY-12590
> URL: https://issues.apache.org/jira/browse/GROOVY-12590
> Project: Groovy
> Issue Type: Bug
> Affects Versions: 6.0.0
> Reporter: Scott Murphy Heiberg
> Priority: Major
>
> {code:groovy}
> @groovy.transform.CompileStatic
> trait T {
> static boolean flag = true
> static boolean isReady() { flag }
> static String sm() { ready ? 'yes' : 'no' }
> static Closure getG() { { -> flag } }
> static Object sg() { g.call() }
> }
> class C implements T {}
> assert C.sm() == 'yes'
> assert C.sg() == true
> {code}
> Actual: groovy.lang.MissingMethodException: No signature of static method:
> T__flag$get for class: T is applicable for argument types: () values: []
> Expected: both assertions pass, as they do with @TypeChecked or without an
> annotation, and as they do when the accessor is called directly
> ({{isReady()}}, {{getG()}}).
> The same happens in instance trait methods, in closures and lambdas, and when
> a static accessor is written with property syntax ({{cnt = 1}}, {{cnt += 1}},
> {{cnt++}} for a static {{setCnt(int)}}), including for an accessor of a super
> trait. Under static compilation the property resolves to the static method
> that the trait interface declares, which forwards to the trait helper with
> the trait itself as the receiver class, so the accessor cannot reach the
> implementing class's trait state. The direct method call passes the
> implementing class to the helper instead.
> Seen in 6.0.0 and master. 5.0.8 rejects the code with "No such property:
> ready for Class or static property for class: T", and 4.0.33 with "Access to
> T#ready is forbidden".
> PR: https://github.com/apache/groovy/pull/3115
--
This message was sent by Atlassian Jira
(v10.3.26#10030026)