[ 
https://issues.apache.org/jira/browse/GROOVY-12426?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
 ]

Paul King reassigned GROOVY-12426:
----------------------------------

    Assignee: Paul King

> @Delegate generates no methods returning a nested class of a joint-compiled 
> Java source, and breaks other implementors of the interface
> ---------------------------------------------------------------------------------------------------------------------------------------
>
>                 Key: GROOVY-12426
>                 URL: https://issues.apache.org/jira/browse/GROOVY-12426
>             Project: Groovy
>          Issue Type: Bug
>          Components: Compiler
>    Affects Versions: 6.0.0
>            Reporter: Mattias Reichel
>            Assignee: Paul King
>            Priority: Major
>
> In a joint compilation, if a Groovy interface declares methods whose return 
> type is a static nested class of a Java source in the same compilation, 
> {{@Delegate}} of that interface generates no delegate methods for them. The 
> class then fails the abstract-method check.
> After {{@Delegate}} has processed the interface, other classes in the same 
> compilation that implement the interface directly also fail the 
> abstract-method check, even though they implement the method.
> This compiles on Groovy 5.1.3 and fails on 6.0.0. {{@CompileStatic}} is not 
> needed. A top-level Java class, or a nested class declared in Groovy, works.
> h3. Steps to reproduce
> {code:title=src/Payload.java}
> public class Payload {
>     public static abstract class Result {
>         public abstract String text();
>     }
> }
> {code}
> {code:title=src/Renderer.groovy}
> interface Renderer {
>     Payload.Result render(Map arguments)
> }
> {code}
> {code:title=src/DelegatingRenderer.groovy}
> class DelegatingRenderer {
>     @Delegate final Renderer renderer
>     DelegatingRenderer(Renderer renderer) { this.renderer = renderer }
> }
> {code}
> {noformat}
> mkdir out
> java -cp groovy-6.0.0.jar org.codehaus.groovy.tools.FileSystemCompiler -d out 
> -j src/Payload.java src/Renderer.groovy src/DelegatingRenderer.groovy
> {noformat}
> h4. Expected
> Compilation succeeds, as on Groovy 5.1.3.
> h4. Actual
> {noformat}
> src/DelegatingRenderer.groovy: 1: Can't have an abstract method in a 
> non-abstract class. The class 'DelegatingRenderer' must be declared abstract 
> or the method 'Payload$Result render(java.util.Map)' must be implemented.
>  @ line 1, column 1.
>    class DelegatingRenderer {
>    ^
> 1 error
> {noformat}
> h3. Effect on other implementors of the interface
> When the {{@Delegate}} class declares the affected method itself, it 
> compiles, but a class that implements the interface directly then fails:
> {code:title=src/ForwardingRenderer.groovy}
> class ForwardingRenderer {
>     @Delegate final Renderer renderer
>     ForwardingRenderer(Renderer renderer) { this.renderer = renderer }
>     Payload.Result render(Map arguments) { renderer.render(arguments) }
> }
> {code}
> {code:title=src/DirectRenderer.groovy}
> class DirectRenderer implements Renderer {
>     Payload.Result render(Map arguments) { null }
> }
> {code}
> {noformat}
> mkdir out
> java -cp groovy-6.0.0.jar org.codehaus.groovy.tools.FileSystemCompiler -d out 
> -j src/Payload.java src/Renderer.groovy src/ForwardingRenderer.groovy 
> src/DirectRenderer.groovy
> {noformat}
> {noformat}
> src/DirectRenderer.groovy: 1: Can't have an abstract method in a non-abstract 
> class. The class 'DirectRenderer' must be declared abstract or the method 
> 'Payload$Result render(java.util.Map)' must be implemented.
> {noformat}
> {{DirectRenderer}} compiles on its own, and both files compile together on 
> 5.1.3.
> h3. Notes
> Found while moving Apache Grails to Groovy 6: {{grails-views-gson}} has 
> {{@Delegate GrailsJsonViewHelper}} in {{TemplateRenderer}}, and the 
> interface's {{render(...)}} methods return {{JsonOutput.JsonWritable}}, a 
> nested class of a Java source in the same module. That failed first in 
> {{TemplateRenderer}}, then in {{DefaultGrailsJsonViewHelper}}, which 
> implements the interface directly. The workaround is to write all forwarding 
> methods explicitly instead of using {{@Delegate}}.



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

Reply via email to