-
Notifications
You must be signed in to change notification settings - Fork 65
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add codegen mode to support both Anvil and Hilt #963
Add codegen mode to support both Anvil and Hilt #963
Conversation
Thanks for the contribution! Before we can merge this, we need @jamiesanson to sign the Salesforce Inc. Contributor License Agreement. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Given there's another request for supporting kotlin-inject, let's make this a "mode" instead. Then it becomes trivial to add new types that support this kind of injection
circuit.codegen.mode=anvil
where options are anvil
and hilt
for now. Can stick 'em in an enum that maybe holds information about the contributor annotation type and param?
enum class Mode {
ANVIL {
override fun annotateFactory(...) {
...
}
},
HILT {
override fun annotateFactory(...) {
...
}
};
fun annotateFactory(builder: TypeSpec.Factory, scope: ClassName)
}
Sounds like a plan! Given your suggestion on naming of the option being codegen mode, what are your thoughts on me pulling in my Hilt module generation changes too? I'd prefer to have this in circuit rather than living in my own third-party artefact, but also get it if you're not keen to take on that much scope |
As long as it's simple it's fine with me. Seems like it's trivial to add in hilt's case |
Just got around to adding the Hilt codegen mode option as suggested. Tested against a seperate project with a local version and it's working as expected! Docs-wise, is there anything to contribute to? |
The argument "circuit.generate-anvil-bindings" defaults to true, and can be configured via the KSP gradle DSL: ksp { arg("circuit.generate-anvil-bindings", "false") }
The argument "circuit.generate-anvil-bindings" has been renamed to "circuit.codegen.mode", with support for Hilt added by generating additional files implementing dagger modules
circuit-codegen/src/main/kotlin/com/slack/circuit/codegen/CircuitSymbolProcessorProvider.kt
Show resolved
Hide resolved
circuit-codegen/src/main/kotlin/com/slack/circuit/codegen/CircuitSymbolProcessorProvider.kt
Outdated
Show resolved
Hide resolved
circuit-codegen/src/main/kotlin/com/slack/circuit/codegen/CircuitSymbolProcessorProvider.kt
Outdated
Show resolved
Hide resolved
…licable generated modules in Hilt codegen mode; Add platform support check to Codegen modes
Apologies for the delay on this, been AFK for a while due to travelling. The recent commits I've pushed have added in documentation, tidied up errors, and implemented the remaining Hilt functionality with |
…t incremental KSP compilations
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd like to avoid imposing the hilt dependency on annotations, is it not possible to do that?
api(libs.anvil.annotations) | ||
api(libs.dagger) | ||
api(libs.hilt) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's actually remove all three of these dependencies now since we don't want to impose a specific framework anymore
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if the hilt meta-annotation is required for CircuitInject
, would compileOnly()
for the hilt dependency work?
I know for the JVM annotations don't actually need to be on the classpath at runtime
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That could work, though still not thrilled about requiring this at all. Could you or @jamiesanson explain it a bit more? I don't know that much about Hilt these days
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The GeneratesRootInput
annotation exists for repeatability and correctness when using Hilt, due to how it detects modules. It allows the Hilt compiler to see that other processors are going to produce input for it, meaning it can wait until other codegen steps complete before it wires up its own dagger components. Hilt won't necessary mess things up if this annotation isn't there, but it's not reliable without it. Docs for hilt extensions are here if you're interested in a quick browse: https://dagger.dev/hilt/creating-extensions.html
It's definitely not needed at runtime, and is retained at class-level, so should be fine making this compileOnly
* For more general information about this annotation, see | ||
* [com.slack.circuit.codegen.annotations.CircuitInject] | ||
*/ | ||
@GeneratesRootInput |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this required for hilt to work? I'm not sure I'm comfortable imposing the dependency on anyone using this artifact
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It is, however as mentioned compileOnly
should do the trick. If you're not comfortable with this constraint on dependency here, happy to discuss potentially creating a new optional module for hilt-specific annotation. That'll also introduce a nitpick-y improvement in that we can rename the scope
parameter to component
to tie in to Dagger vocabulary, so maybe worth doing anyway
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If it works with compileOnly
we're all good, do like the idea of keeping all the codegen together given the current overlap.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Awesome work. There's a few followups I think we'll want to make, but don't want to keep you attending to this as we've taken awhile to review this. Very much appreciate you taking the time and the patience!
This PR implements a KSP argument for
CircuitSymbolProcessor
which allows a consumer to skip emission of Anvil annotations. One use case of this is to allow for generated binding support for other DI frameworks, such as Hilt.The argument "circuit.generate-anvil-bindings" defaults to true, and can be configured via the KSP gradle DSL: