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

Lyuben Atanasov updated GROOVY-9807:
------------------------------------
    Description: 
I have encountered an issue when trying to generate code, containing chained 
method calls, at runtime (without source code) and compiling using 
CompileStatic.
What I am trying to achieve is produce code similar to:
{code:java}
public StringBuilder test()
{
    StringBuilder sb = new StringBuilder().append("testString");
    return sb;
}
{code}
I create the appropriate AST nodes, statements, expressions, etc.
Everything works fine if I add a method like the one shown in a top-level class 
(the class is also dynamically generated at runtime). However, if I try to add 
the exact same method to a nested class, it seems like the groovy compiler gets 
somehow confused and, judging by the decompiler output, produces something like:
{code:java}
public StringBuilder test()
{
    final StringBuilder sb = ((StringBuilder) ((Closure) 
this).getThisObject()).append("testString");
    return sb;
}
{code}
Naturally, this does not work.

Here's how I try to generate the method:
{code:java}
ClassNode topLevelClass = 
ClassHelper.make("com.example.groovycompiler.test.TopLevelClass");
InnerClassNode nestedClass = new InnerClassNode(topLevelClass, 
"com.example.groovycompiler.test.TopLevelClass$NestedClass", Opcodes.ACC_PUBLIC 
| Opcodes.ACC_STATIC, ClassHelper.OBJECT_TYPE);
ClassNode stringBuilderClass = ClassHelper.make(StringBuilder.class);
nestedClass.addMethod("test", Opcodes.ACC_PUBLIC, stringBuilderClass, 
Parameter.EMPTY_ARRAY, ClassNode.EMPTY_ARRAY, block(
    declS(varX("sb", stringBuilderClass), callX(ctorX(stringBuilderClass), 
"append", args(constX("testString")))),
    returnS(varX("sb", stringBuilderClass))
));
{code}

Perhaps I am missing something, in which case I will be very happy to receive 
some pointers.
I have created a github repo with a maven project containing a unit test that 
demonstrates the issue: 
https://github.com/l-atanasov/groovy-static-compile-issue
Note, that I have extended the CompilationUnit a little to allow to run the 
static compiler without source.

Also, if I am not using the static compiler, everything works as expected.

  was:
I have encountered an issue when trying to generate code, containing chained 
method calls, at runtime (without source code) and compiling using 
CompileStatic.
What I am trying to achieve is produce code similar to:
{code:java}
public StringBuilder test()
{
    StringBuilder sb = new StringBuilder().append("testString");
    return sb;
}
{code}
I create the appropriate AST nodes, statements, expressions, etc.
Everything works fine if I add a method like the one shown in a top-level class 
(the class is also dynamically generated at runtime). However, if I try to add 
the exact same method to a nested class, it seems like the groovy compiler gets 
somehow confused and, judging by the decompiler output, produces something like:
{code:java}
public StringBuilder test()
{
    final StringBuilder sb = ((StringBuilder) ((Closure) 
this).getThisObject()).append("testString");
    return sb;
}
{code}
Naturally, this does not work.

Here's how I try to generate the method:
{code:java}
ClassNode topLevelClass = 
ClassHelper.make("com.example.groovycompiler.test.TopLevelClass");
        InnerClassNode nestedClass = new InnerClassNode(topLevelClass, 
"com.example.groovycompiler.test.TopLevelClass$NestedClass", Opcodes.ACC_PUBLIC 
| Opcodes.ACC_STATIC, ClassHelper.OBJECT_TYPE);
        ClassNode stringBuilderClass = ClassHelper.make(StringBuilder.class);
        nestedClass.addMethod("test", Opcodes.ACC_PUBLIC, stringBuilderClass, 
Parameter.EMPTY_ARRAY, ClassNode.EMPTY_ARRAY, block(
                declS(varX("sb", stringBuilderClass), 
callX(ctorX(stringBuilderClass), "append", args(constX("testString")))),
                returnS(varX("sb", stringBuilderClass))
        ));
{code}

Perhaps I am missing something, in which case I will be very happy to receive 
some pointers.
I have created a github repo with a maven project containing a unit test that 
demonstrates the issue: 
https://github.com/l-atanasov/groovy-static-compile-issue
Note, that I have extended the CompilationUnit a little to allow to run the 
static compiler without source.


> Static compile of dynamically generated code produces different output in a 
> top-level class and a nested class
> --------------------------------------------------------------------------------------------------------------
>
>                 Key: GROOVY-9807
>                 URL: https://issues.apache.org/jira/browse/GROOVY-9807
>             Project: Groovy
>          Issue Type: Bug
>          Components: Static compilation
>    Affects Versions: 3.0.6
>         Environment: openjdk version "1.8.0_242"
> OpenJDK Runtime Environment (build 1.8.0_242-8u242-b08-0ubuntu3~18.04-b08)
> OpenJDK 64-Bit Server VM (build 25.242-b08, mixed mode)
>            Reporter: Lyuben Atanasov
>            Priority: Critical
>
> I have encountered an issue when trying to generate code, containing chained 
> method calls, at runtime (without source code) and compiling using 
> CompileStatic.
> What I am trying to achieve is produce code similar to:
> {code:java}
> public StringBuilder test()
> {
>     StringBuilder sb = new StringBuilder().append("testString");
>     return sb;
> }
> {code}
> I create the appropriate AST nodes, statements, expressions, etc.
> Everything works fine if I add a method like the one shown in a top-level 
> class (the class is also dynamically generated at runtime). However, if I try 
> to add the exact same method to a nested class, it seems like the groovy 
> compiler gets somehow confused and, judging by the decompiler output, 
> produces something like:
> {code:java}
> public StringBuilder test()
> {
>     final StringBuilder sb = ((StringBuilder) ((Closure) 
> this).getThisObject()).append("testString");
>     return sb;
> }
> {code}
> Naturally, this does not work.
> Here's how I try to generate the method:
> {code:java}
> ClassNode topLevelClass = 
> ClassHelper.make("com.example.groovycompiler.test.TopLevelClass");
> InnerClassNode nestedClass = new InnerClassNode(topLevelClass, 
> "com.example.groovycompiler.test.TopLevelClass$NestedClass", 
> Opcodes.ACC_PUBLIC | Opcodes.ACC_STATIC, ClassHelper.OBJECT_TYPE);
> ClassNode stringBuilderClass = ClassHelper.make(StringBuilder.class);
> nestedClass.addMethod("test", Opcodes.ACC_PUBLIC, stringBuilderClass, 
> Parameter.EMPTY_ARRAY, ClassNode.EMPTY_ARRAY, block(
>     declS(varX("sb", stringBuilderClass), callX(ctorX(stringBuilderClass), 
> "append", args(constX("testString")))),
>     returnS(varX("sb", stringBuilderClass))
> ));
> {code}
> Perhaps I am missing something, in which case I will be very happy to receive 
> some pointers.
> I have created a github repo with a maven project containing a unit test that 
> demonstrates the issue: 
> https://github.com/l-atanasov/groovy-static-compile-issue
> Note, that I have extended the CompilationUnit a little to allow to run the 
> static compiler without source.
> Also, if I am not using the static compiler, everything works as expected.



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

Reply via email to