[
https://issues.apache.org/jira/browse/GROOVY-12452?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=18131952#comment-18131952
]
ASF GitHub Bot commented on GROOVY-12452:
-----------------------------------------
paulk-asert commented on PR #3014:
URL: https://github.com/apache/groovy/pull/3014#issuecomment-6403054528
Thanks Daniel.
1. The guard only ever fires for record components.
`PropertyNode.getGetterName()` is null unless set explicitly, and the only
`setGetterName` callers in the codebase are `RecordTypeASTTransformation` and
`RecordBaseASTStubber`, both setting it to the component name. No other AST
shape sets an explicit getter name, so ordinary bean resolution is untouched.
2. Property-style reads (`flags.isActive`, `person.getName`, including
emulated records) and map-style construction go through the property path
rather than this accessor lookup, and they already worked before the fix
(checked on 6.0.0, which has the bug). The hunk only affects the method-call
form.
3. Agreed, precompiled records were never affected since the accessor is a
real method on the class. I'll leave the tests as they are, and add a javadoc
sentence to Groovy12452 before merging.
> STC cannot find the accessor of a record component whose name starts with
> "is" or "get" when called from the same compilation unit
> ----------------------------------------------------------------------------------------------------------------------------------
>
> Key: GROOVY-12452
> URL: https://issues.apache.org/jira/browse/GROOVY-12452
> Project: Groovy
> Issue Type: Bug
> Components: Static Type Checker
> Affects Versions: 4.0.31, 5.0.6, 5.1.3, 6.0.0
> Reporter: Mattias Reichel
> Priority: Major
>
> When a record component is named like a getter, for example {{isActive}} or
> {{{}getName{}}}, the static type checker cannot resolve the record's accessor
> method, {{isActive()}} or {{{}getName(){}}}, while the record is being
> compiled in the same compilation unit. The accessor does exist in the
> generated bytecode.
> {code:groovy}
> import groovy.transform.CompileStatic
> @CompileStatic
> record Flags(boolean isActive) {}
> @CompileStatic
> class Main {
> static void main(String[] args) {
> Flags flags = new Flags(true)
> assert flags.isActive()
> }
> }
> {code}
> {noformat}
> $ groovyc OneFile.groovy
> OneFile.groovy: 10: [Static type checking] - Cannot find matching method
> Flags#isActive(). Please check if the declared type is correct and if the
> method exists.
> @ line 10, column 16.
> assert flags.isActive()
> ^
> {noformat}
> The record itself compiles correctly:
> {noformat}
> $ javap Flags
> public final class Flags extends java.lang.Record {
> public Flags(boolean);
> public boolean isActive();
> ...
> {noformat}
> What I found:
> * The same call compiles when the caller is compiled separately against the
> record's class file.
> * It fails for any component type, e.g. {{{}record Flags(String
> isActive){}}}, and for the {{get}} prefix, e.g. {{record Flags(String
> getName)}} with {{{}flags.getName(){}}}.
> * It also fails inside the record itself, e.g. \{{boolean check() {
> isActive() }}}.
> * Property-style access ({{{}flags.isActive{}}}) compiles.
> * A component without such a prefix ({{{}record Flags(boolean active){}}}
> with {{{}flags.active(){}}}) compiles.
> * A method named {{isActive()}} on an ordinary {{@CompileStatic}} class
> compiles.
> * A dynamically compiled caller works at runtime.
> * It doesn't matter whether the record itself is {{{}@CompileStatic{}}}.
> Reproduced with 4.0.31, 5.0.6, 5.1.3 and 6.0.0 on JDK 21.
> Expected: {{flags.isActive()}} resolves to the record's accessor, as it does
> when the record is compiled separately and as it does in Java.
> Workaround: name the component without the prefix and declare the accessor by
> hand. That has to avoid the related problem where a hand-written {{isX()}}
> suppresses the accessor of component {{x}} (see issue GROOVY-12451).
--
This message was sent by Atlassian Jira
(v10.3.26#10030026)