[
https://issues.apache.org/jira/browse/GROOVY-12594?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=18135559#comment-18135559
]
ASF GitHub Bot commented on GROOVY-12594:
-----------------------------------------
codeconsole opened a new pull request, #3121:
URL: https://github.com/apache/groovy/pull/3121
Under `@TypeChecked` and `@CompileStatic`, trait code that reads or writes a
`@Virtual` static accessor with property syntax is rejected:
```groovy
import groovy.transform.Virtual
@groovy.transform.CompileStatic
trait T {
@Virtual static boolean isVr() { false }
static String sm() { vr ? 'yes' : 'no' }
}
class C implements T { static boolean isVr() { true } }
class D implements T { }
assert [C.sm(), D.sm()] == ['yes', 'no']
// [Static type checking] - No such property: vr for Class or static
property for class: T
```
The same happens in instance trait methods, for a `@Virtual` setter written
as `x = v`, `x += v` or `x++`, and for an accessor of a super trait. 6.0.0
fails the same way. The method form `isVr()` compiles, and dynamic Groovy runs
the code. A `@Virtual` static is deliberately not on the trait interface, so
the type checker finds no property for the `$self` / `$static$self` receiver
the trait transformation produces.
`TraitTypeCheckingExtension.handleUnresolvedProperty` now resolves `$self.x`
and `$static$self.x` to a `@Virtual` static `getX` / `isX` (or `setX` when the
property is assigned) of the trait or a super trait. It marks the property for
dynamic resolution with the accessor's type, as it already does for trait
static fields. Under static compilation the access goes through the
implementing class at run time, so an override on the implementing class is
used, as with `isVr()`.
## Tests
`VirtualAnnotationTest.virtualStaticAccessor_readAsProperty`,
`virtualStaticAccessor_writtenAsProperty` and
`virtualStaticAccessor_ofSuperTrait_readAsProperty` run dynamic, `@TypeChecked`
and `@CompileStatic`. The `@TypeChecked` and `@CompileStatic` variants of each
fail without the change. The `groovy.transform.stc`,
`org.codehaus.groovy.classgen.asm.sc`, `org.codehaus.groovy.transform.traitx`
and `gls` packages, `groovy.ThisAndSuperTest` and `TraitsSpecificationTest`
pass. The Checkstyle and CodeNarc gates pass.
> STC rejects a @Virtual trait static accessor read or written with property
> syntax
> ---------------------------------------------------------------------------------
>
> Key: GROOVY-12594
> URL: https://issues.apache.org/jira/browse/GROOVY-12594
> Project: Groovy
> Issue Type: Bug
> Affects Versions: 6.0.0
> Reporter: Scott Murphy Heiberg
> Priority: Major
>
> {code:groovy}
> import groovy.transform.Virtual
> @groovy.transform.CompileStatic
> trait T {
> @Virtual static boolean isVr() { false }
> static String sm() { vr ? 'yes' : 'no' }
> }
> class C implements T { static boolean isVr() { true } }
> class D implements T { }
> assert [C.sm(), D.sm()] == ['yes', 'no']
> {code}
> Actual: {{[Static type checking] - No such property: vr for Class or static
> property for class: T}} with {{@CompileStatic}} or {{@TypeChecked}}. The same
> error occurs in instance trait methods, for a @Virtual setter written as an
> assignment or compound assignment, and for a @Virtual accessor of a super
> trait. The method form {{isVr()}} compiles, and dynamic Groovy runs the
> script.
> Expected: the script compiles, and the property reads and writes dispatch
> through the implementing class like {{isVr()}} does, giving {{yes}} for {{C}}
> and {{no}} for {{D}}.
> A @Virtual static is not promoted to the trait interface, so the type checker
> finds no property on the trait for the receiver that the trait transformation
> produces. The method form is resolved through the trait type checking
> extension; the property form is not.
> Seen in 6.0.0 (the first version with @Virtual).
--
This message was sent by Atlassian Jira
(v10.3.26#10030026)