square / anvil

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

@ContributesMultibinding codegen missing imports for synthesized annotation constants #938

Closed bubenheimer closed 6 months ago

bubenheimer commented 6 months ago

Code like this fails to build in 2.5.0-beta04, works in prior versions:

import somewhere.OTHER_CONSTANT

private const val CONSTANT = "$OTHER_CONSTANT.foo"

@ContributesMultibinding(MyScope::class)
@StringKey(CONSTANT)
class SomeClass @Inject constructor() : Base

The build fails in this case because the generated code (below) fails to carry over the import statement for OTHER_CONSTANT:

//...
@StringKey(value = "$OTHER_CONSTANT.foo")
//...
ZacSweers commented 6 months ago

That's strange, we should be inlining the constant value, not using the import 🤔

RBusarow commented 6 months ago

Yeah, we can't just re-use the imports since they may not be visible to the generated modules. We didn't actually intend to use the imports, though -- it just looks that way.

The logic for parsing those const arguments into their raw values was just giving up too soon. As soon as it saw a String initializer for the constant ("$OTHER_CONSTANT.foo"), it would just pass that string literal as though it's the value.

So when you see this:

@StringKey(value = "$OTHER_CONSTANT.foo")

...it's not actually a property reference without an import. It's more like a String literal where we failed to escape the dollar sign.

Anyways, the fix is up: https://github.com/square/anvil/pull/940 :)

bubenheimer commented 6 months ago

Thank you for the prompt fix!