micronaut-projects / micronaut-core

Micronaut Application Framework
http://micronaut.io
Apache License 2.0
6.01k stars 1.05k forks source link

Scala Support: Add a scala compiler plugin #675

Open graemerocher opened 5 years ago

graemerocher commented 5 years ago

Scala doesn't currently support Java's Annotation Processing API, instead they have a compiler plugin API.

The Micronaut team has no Scala experts as committers, this issue is here to track the fact this is a desired feature, that we are currently looking help for from the Scala community to implement.

For reference Groovy doesn't support APT either, only Kotlin and Java do. The Groovy implementation can be found at:

The Java/Kotlin implementation at:

Any takers?

shaneorama commented 4 years ago

Besides the Groovy and Java/Kotlin implementations, what other type of documentation is available that may be helpful?

graemerocher commented 4 years ago

Shamefully very little. I will try to describe how it works.

The first part is the TypeElementVisitor API which is powered by TypeElementVisitorProcessor for Java. This must run first and essentially visits classes of interest to Micronaut. See

https://github.com/micronaut-projects/micronaut-core/blob/3100d8ca8edbc2d0dbcfef593e2069f4ba5eff0c/inject-java/src/main/java/io/micronaut/annotation/processing/TypeElementVisitorProcessor.java#L101

It does this by looking at the annotation metadata which is built via JavaAnnotationMetadataBuilder so a first step would be needing a ScalaAnnotationMetadataBuilder. See JavaAnnotationMetadataBuilderSpec.

The next step once it is has found a candidate that can be visited is it visits the class, or method or field or whatever. This is done here:

https://github.com/micronaut-projects/micronaut-core/blob/3100d8ca8edbc2d0dbcfef593e2069f4ba5eff0c/inject-java/src/main/java/io/micronaut/annotation/processing/visitor/LoadedVisitor.java#L125

For this we would need to implement the io.micronaut.inject.ast API for Scala so that we have equivalents of FieldElement, MethodElement etc.

With this is all in place bean introspections and some parts of Micronaut will start working (but not DI). This is because DI is implemented separately as the final processor in the chain by BeanDefinitionInjectProcessor.

Really there is a fair amount of duplication between InjectTransform and BeanDefinitionInjectProcessor such that it would be better to refactor the latter so it is not coupled to the Java annotation processing API.

Nevertheless the implementations essentially visit all interesting classes and use the BeanDefinitionWriter API to build bean definitions

eugener commented 4 years ago

@graemerocher Can annotation processing for Micronaut be run on compiled .class files as post compilation step for Scala? This way Java based APT might work

CoderYellow commented 3 years ago

Quarkus has support for scala long time ago, may be your team should dig deeper into their implentation.

graemerocher commented 3 years ago

Quarkus processes the byte code generated by Scala after compilation as they implement two step compilation process. Micronaut processes source code via the language AST so looking at their implementation will not help in anyway whatsoever.

rom1dep commented 3 years ago

Scala doesn't currently support Java's Annotation Processing API

Could it be related to: https://github.com/scala/scala/commit/7e57bcc1818a402ad6ec32416af2b4522671f9ab ?

karlroberts commented 8 months ago

Is there any traction on this? Is there a repo building the stuff mentioned above?