square / anvil

A Kotlin compiler plugin to make dependency injection with Dagger 2 easier.
Apache License 2.0
1.29k stars 75 forks source link

v2.5.0-beta05 breaks custom code generators #953

Open SteinerOk opened 3 months ago

SteinerOk commented 3 months ago

My project uses custom generators, which worked fine before updating to the version v2.5.0-beta05. After the update, some of them stopped working.

I conducted an analysis and discovered the following pattern: Generators that require annotated classes MergeSubcomponent (check via isAnnotatedWith(FqNames.mergeSubcomponent)) do not generate the required code.

In my code, I use ContributesSubcomponent in the base module and rely on the presence of generated classes with the MergeSubcomponent annotation in the application module, but it seems that custom generators are no longer called for the generated classes with annotation MergeSubcomponent.

To play repo: https://github.com/SteinerOk/sealant/tree/ik/sample

RBusarow commented 2 months ago

Thanks for the (extremely quick) report!

For reference, the generator that creates the @MergeSubcomponent interfaces is called ContributesSubcomponentHandlerGenerator.

The problem is one of sequencing. The ContributesSubcomponentHandlerGenerator is invoked after your custom generators have already finished. That change is new.

Prior to beta05, the ContributesSubcomponentHandlerGenerator was invoked in a batch with most of the other generators - including any custom ones. It was invoked last, but that entire batch of generators is invoked in a loop, so anything it generates is seen by the other generators in the subsequent loop. The problem with this approach was that the custom generators can also be generating @ContributesSubcomponent interfaces, where those new interfaces replace existing ones.

In your use-case, you're depending upon what is effectively an internal API. Are you able to get the information you need (the scope?) from something else upstream?

SteinerOk commented 2 months ago

@RBusarow Good evening, sorry for the wait.

Thanks for the clarification, I understand why this is happening now.

But, unfortunately, I don’t know what to do now, because this change breaks many of my code generators: in my main project the structure of subcomponents is described in the DI module (as light as possible with a minimum of dependencies), and the root component (skeleton component) in the application module, in which integrations for everything are already generated. This happens thanks to the annotation @ContributesSubcomponent for subcomponents and the use of generated components with annotation @MergeSubcomponent in custom generators

And so it turns out that the benefits of the annotation@ContributesSubcomponent are lost after these changes.

Maybe you can suggest something if this is not a bug but a feature?