groovy-eclipse icon indicating copy to clipboard operation
groovy-eclipse copied to clipboard

Properties added by AST transform not visible even after compilation

Open chrylis opened this issue 5 years ago • 9 comments

This is probably related to #421 but is a distinct failure case.

I have a small utility library called GroovyBeans Toolkit (updated name as I finally got it pushed to Central). One of the features is a @GbtId annotation that inserts a JPA ID property with all the usual boilerplate, similar to the built-in @Slf4j. This annotation is working correctly with the Groovy-Eclipse plugin, and javap reports this on the class file:

public java.util.UUID getId();
public void setId(java.util.UUID);
public java.time.Instant getVersion();
public void setVersion(java.time.Instant);

So far, so good. However, the plugin itself fails to resolve these visible methods when compiling Java source code; this happens both in the editor and in Maven batch mode.

        p.setId(UUID.randomUUID());
          ^^^^^
The method setId(UUID) is undefined for the type Person

I understand the limitations of editor visibility, but seems to be more fundamental--valid joint code refuses to compile.

I have had this exact construction working before, but reverting the Maven GEP to 2.9.2-01 does not resolve it.

chrylis avatar Sep 05 '18 11:09 chrylis

This is a function of how joint compilation works. Even though the compiled class file contains all the fields and methods, Java compiles against a data-structure created from a parse result of your Groovy sources (before AST transforms have been applied). There are several other open issues related to this, namely: #175, #421, #548.

I do find the joint compilation provided by Groovyc and Groovy-Eclipse to be non-intuitive as well. I have been running some experiments and prototypes over the past several months to try and improve the situation. I am currently stuck on circular dependencies between classes.

There are a couple workarounds that exist in Eclipse today:

  1. You can place your JPA beans in one source folder and place the code that consumes it in another and mark the latter as "contains test sources". This will cause 2 phase compilation and so the class files will be used instead of the stubs.
  2. You can place your JPA beans in one project and your consumer code in another. This is similar to the above but a bit more overhead/boilerplate.
  3. You can create an interface that has the extra methods on it and implement it within each type you add @GbtId to. This will enhance the stubs created for each bean and should not cause any errors since the AST transform is providing the implementations.

eric-milles avatar Sep 05 '18 14:09 eric-milles

You can place your JPA beans in one project and your consumer code in another. This is similar to the above but a bit more overhead/boilerplate.

I expected this to work, and it's what I'm using because it does make CLI compilation succeed, but the Eclipse editors still show the errors.

chrylis avatar Sep 06 '18 15:09 chrylis

Can you attach or link to a small sample project? I may be missing some details of your scenario. There are times when the editor can see the source and uses that instead of any compiled result, thus AST transforms enhancements are missed.

eric-milles avatar Sep 06 '18 15:09 eric-milles

That's it; closing the module containing the Groovy domain objects clears the editor error. Additionally, implementing Identifiable from Spring HATEOAS (which I'm probably going to use) does the same. There are still some spurious editor errors regarding inter-class dependencies in the Groovy classes, but nothing that escapes to the Package Explorer markers.

chrylis avatar Sep 07 '18 13:09 chrylis

I'm still a little unclear on why transforms like @Slf4j, which also run during SEMANTIC_ANALYSIS, don't produce this problem.

chrylis avatar Sep 07 '18 13:09 chrylis

Logging transforms (and many others) work because they are localized to a particular class (or source file). When a source file is opened in the Groovy Editor, it it processed through all compiler phases (but no class file is written). This is why @Slf4j for example is recognized. However, any source types that the file refers to are only processed thorough CONVERSION. This is why you would not be seeing any of their AST transform results and the editor probably shows unknown (underlined) or error (red squiggly underline) for @ComplieStatic or @TypedChecked.

There have been efforts in the past to spot add methods when certain AST transform annotations are detected. However, this solution was limited to methods, not fields or properties or inner types; and it did not account for removed or altered members. So I have removed most or all of this sort of thing.

What I have been experimenting with is running additional compiler phases on referred to source types. This has proved successful for resolving things like @Canonical and probably your @GbtId transform, as well as fixing some issues for traits. But it gets tripped up by circular dependencies, incremental compilation and a few other detials; so I haven't been able to put out even a partial solution for Groovy-to-Groovy references.

eric-milles avatar Sep 07 '18 14:09 eric-milles

Hi,

Just wanted to check on the status of this issue, where a second transformation's code still will not be reflected on the generated .class file when building via the normal compile process. I am running a groovy gradle setup with groovy and java code where I have 2 transformations taking place, but the transformations code (adding annotations and a method) is not reflected in the .class files. In my situation, I have the BaseScript running as well as another transformation Apologies for asking on such an old post, I am just struggling to get to a point when I know its either me doing something dumb ( :-) highly possible ) or that there is a limitation

moeniebdavids avatar Jan 21 '21 16:01 moeniebdavids

@moeniebdavids Please create a new issue with a minimal recreation script or project.

eric-milles avatar Jan 21 '21 16:01 eric-milles

@moeniebdavids Please create a new issue with a minimal recreation script or project.

Hi @eric-milles . Thanks for listening :-) After playing a bit more and understanding the compiler and (groovy + java) project, i realised that I needed to add my annotation and transformer to another jar and just add the jar as a dependency. All is now 100% working. In short, I was writing a transformer to convert a specifically annotated script file to a JUnit 5 test. Tings running smoothly now. On to the next thing, allure reports :-)

moeniebdavids avatar Jan 30 '21 18:01 moeniebdavids