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

Annotations can't see nested classes added by ASTTs

Open chrylis opened this issue 2 years ago • 6 comments

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.

chrylis avatar Apr 18 '23 19:04 chrylis

see #175 and #421 and https://github.com/groovy/groovy-eclipse/tree/early-xforms

eric-milles avatar Apr 18 '23 19:04 eric-milles

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.

chrylis avatar Apr 18 '23 19:04 chrylis

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.

eric-milles avatar Apr 18 '23 19:04 eric-milles

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.

chrylis avatar Apr 18 '23 19:04 chrylis

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.

eric-milles avatar Apr 18 '23 20:04 eric-milles

Later on, GroovyClassScope fills in method definitions for things like properties. But it does not deal with inner types.

eric-milles avatar Apr 18 '23 20:04 eric-milles