Mattias Reichel created GROOVY-12451:
----------------------------------------

             Summary: A record with a boolean component {{x}} and a 
hand-written {{isX()}} gets no {{x()}} accessor
                 Key: GROOVY-12451
                 URL: https://issues.apache.org/jira/browse/GROOVY-12451
             Project: Groovy
          Issue Type: Bug
          Components: Compiler
    Affects Versions: 6.0.0, 5.1.3, 5.0.6, 4.0.31
            Reporter: Mattias Reichel


If a record declares a method that looks like a getter for one of its boolean 
components, such as {{isDone()}} for component {{done}}, Groovy does not 
generate the component's accessor {{done()}}. Static compilation still accepts 
calls to {{done()}}, which then fail at runtime.

{code:groovy}
import groovy.transform.CompileStatic

@CompileStatic
record S8(boolean done) {
    boolean isDone() { done }
}

@CompileStatic
class M8 {
    static void main(String[] args) { println new S8(true).done() }
}
{code}

{noformat}
$ groovyc D.groovy && groovy M8
Exception in thread "main" java.lang.NoSuchMethodError: 'boolean S8.done()'
    at M8.main(D.groovy:7)

$ javap S8
public final class S8 extends java.lang.Record {
  public S8(boolean);
  public boolean isDone();
  public final boolean equals(java.lang.Object);
  ...
{noformat}

The class is still a record with one component, but that component has no 
accessor:

{code:java}
RecordComponent[] rc = S8.class.getRecordComponents();  // length 1
rc[0].getAccessor();                                    // null
{code}

So Java code calling {{s8.done()}} doesn't compile, and anything that reads 
records through their component accessors breaks, e.g. {{java.io}} 
serialization of a {{Serializable}} record or Jackson.

What I found:
* A dynamically compiled caller fails at runtime with 
{{MissingMethodException}}, listing {{isDone()}} as a possible solution.
* It happens with or without {{@CompileStatic}}.

Reproduced with 4.0.31, 5.0.6, 5.1.3 and 6.0.0 on JDK 21.

Expected: the accessor {{done()}} is always generated (JLS 8.10.3), and 
{{isDone()}} is an additional method. Otherwise compilation should fail, rather 
than produce a record without an accessor and accept calls to it



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

Reply via email to