You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@groovy.apache.org by "Eric Milles (Jira)" <ji...@apache.org> on 2019/10/21 18:14:00 UTC

[jira] [Commented] (GROOVY-9283) Nested closures run on wrong delegate

    [ https://issues.apache.org/jira/browse/GROOVY-9283?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=16956348#comment-16956348 ] 

Eric Milles commented on GROOVY-9283:
-------------------------------------

There are other bugs that reference a similar issue.  The static compiler must make some educated guesses in the case of delegated closures.  In your case, you have not indicated a resolve strategy in your DelegatesTo annotations, so OWNER_FIRST is used.  I think if you set a resolve strategy of DELEGATE_FIRST or DELEGATE_ONLY and set it on the closure when called as well, you may get a better result.

Some of the owner and delegate issues from 2.5.7 and 2.5.8 have been fixed already.  Are you able to test using the latest snapshot build of Groovy 2.5?

> Nested closures run on wrong delegate
> -------------------------------------
>
>                 Key: GROOVY-9283
>                 URL: https://issues.apache.org/jira/browse/GROOVY-9283
>             Project: Groovy
>          Issue Type: Bug
>          Components: Static compilation
>    Affects Versions: 2.5.7, 3.0.0-beta-3
>         Environment: CentOS Linux release 7.7.1908 (Core), openjdk 12.0.2 2019-07-16
>            Reporter: Ivan Kuznetsov
>            Priority: Critical
>
> We use Groovy to write DSL scripts for our project, and the only version we can use now is 2.5.6 because of bug with {{\@CompileStatic}} wich is reproducible with the following code:
> {code:java}
> package test;
> import groovy.lang.Closure;
> import groovy.lang.DelegatesTo;
> import groovy.lang.GroovyClassLoader;
> import groovy.transform.CompileStatic;
> import org.codehaus.groovy.control.CompilerConfiguration;
> import org.codehaus.groovy.control.customizers.ASTTransformationCustomizer;
> import org.codehaus.groovy.runtime.InvokerHelper;
> public class Main {
>     private static final String script = "" +
>             "import test.Main\n" +
>             "\n" +
>             "new Main().enter {\n" +
>             "    nest {\n" +
>             "        nest {\n" +
>             "            nest {\n" +
>             "                println(\"REACHED\")\n" +
>             "            }\n" +
>             "        }\n" +
>             "    }\n" +
>             "}\n";
>     public static void main(String[] args) {
>         CompilerConfiguration config = new CompilerConfiguration();
>         config.addCompilationCustomizers(new ASTTransformationCustomizer(CompileStatic.class));
>         GroovyClassLoader loader = new GroovyClassLoader(Main.class.getClassLoader(), config);
>         Class<?> cls = loader.parseClass(script, "file");
>         InvokerHelper.runScript(cls, new String[0]);
>     }
>     public void enter(@DelegatesTo(Root.class) Closure<?> closure) {
>         Root scope = new Root();
>         closure.setDelegate(scope);
>         closure.run();
>     }
>     public static class Outer extends Main {
>         private final Main parent;
>         Outer() {
>             this.parent = null;
>         }
>         Outer(Outer parent) {
>             this.parent = parent;
>         }
>         public void nest(@DelegatesTo(Inner.class) Closure<?> closure) {
>             closure.setDelegate(new Inner(this));
>             closure.run();
>             System.out.println(this + ": " + parent);
>         }
>     }
>     public static class Inner extends Outer {
>         public Inner(Outer parent) {
>             super(parent);
>         }
>     }
>     public static class Root extends Outer {
>         Root() {
>         }
>     }
> }
> {code}
> till version 2.5.6 it prints:
> {noformat}
> REACHED
> test.Main$Inner@7582ff54: test.Main$Inner@67545b57
> test.Main$Inner@67545b57: test.Main$Root@6c2c1385
> test.Main$Root@6c2c1385: null
> {noformat}
> but starting with 2.5.7 it prints:
> {noformat}
> REACHED
> test.Main$Root@2f67b837: null
> test.Main$Root@2f67b837: null
> test.Main$Root@2f67b837: null
> {noformat}
> The workaround is to turn off static compilation, but it degrades performance because some handles are defined using this DSL and they are called very often.
> Thanks in advance!



--
This message was sent by Atlassian Jira
(v8.3.4#803005)