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)