groovy-eclipse
groovy-eclipse copied to clipboard
Annotations can't see nested classes added by ASTTs
I'm aware this is a consequence of ASTT-phase limitations, but it would be nice if it worked, and the specific case might be relevant to any future updates in how ASTTs are processed.
I have an immutable class I would like to use as a DynamoDB immutable record. The @DynamoDbImmutable class annotation requires a Class builder parameter, so I added @Builder(builderClassName = 'Builder') to my record:
@Builder(builderClassName = 'Builder')
@DynamoDbImmutable(builder = MyRecord.Builder)
class MyRecord {}
This compiles correctly with groovyc, creating both MyRecord.class and MyRecord$Builder.class. However, compiling in Eclipse (even with a full batch, non-incremental build) results in a compilation error (Unresolved compilation problem and no $Builder.class present). This seems to be because the compiler (STC?) is attempting to resolve the parameter before the ASTT gets a chance to create it.
see #175 and #421 and https://github.com/groovy/groovy-eclipse/tree/early-xforms
Understood regarding the underlying sequence of events. I mentioned this case in case the "annotation exists in a scope technically outside the class" is a meaningful coverage case for any future enhancement.
Not sure what phase your transform runs in, but class resolution happens at the start of "semantic analysis" phase. Builder is a tough one because it creates an entire inner class. Usually for a method-based transform, you can create an interface so the java-side can see the forthcoming method through the interface. Not too surprising that ecj has a different disposition in this example because it needs to represent the class skeleton (including method annotations) in the java model.
The transform is groovy.transform.builder.Builder, which runs during semantic analysis. Unfortunately, a quick-and-dirty special-cased stub wouldn't be practical because it has a number of naming options and even non-sealed pluggable strategies.
The java model is built from a very simple processing of the source code. Transforms are disabled IIRC and processing proceeds through conversion only (see GroovyLanguageSupport#newCompilationUnitDeclaration). The early-xforms branch is an attempt to run more phases incl. transforms.
Later on, GroovyClassScope fills in method definitions for things like properties. But it does not deal with inner types.