Skip to content

Commit

Permalink
Support secondary constructors for injection (#1574)
Browse files Browse the repository at this point in the history
Previously we always assumed the primary constructor, which isn't
necessarily the case. Resolves #1572
  • Loading branch information
ZacSweers authored Aug 12, 2024
1 parent 747e382 commit 029d98e
Show file tree
Hide file tree
Showing 3 changed files with 57 additions and 1 deletion.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ Changelog
- **New**: Promote `NoOpRetainedStateRegistry` to public API for use in testing and previews.
- **New**: Add `CircuitPreview` helper function for composable previews that contain Circuit content.
- **Enhancement**: When running under `LocalInspectionMode`, Circuit's default `onUnavailableContent` now shows a simpler non-intrusive placeholder UI instead.
- **Enhancement**: Support secondary injected constructors in code gen.

0.23.0
------
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -439,7 +439,8 @@ private class CircuitSymbolProcessor(
return null
}
} else {
creatorOrConstructor = declaration.primaryConstructor
creatorOrConstructor =
declaration.findConstructorAnnotatedWith(INJECT) ?: declaration.primaryConstructor
targetClass = declaration
}
val useProvider =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -432,6 +432,60 @@ class CircuitSymbolProcessorTest {
)
}

@Test
fun uiClass_simpleInjection_secondaryConstructor() {
assertGeneratedFile(
sourceFile =
kotlin(
"TestUi.kt",
"""
package test
import com.slack.circuit.codegen.annotations.CircuitInject
import com.slack.circuit.runtime.ui.Ui
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import javax.inject.Inject
@CircuitInject(FavoritesScreen::class, AppScope::class)
class Favorites(val value: String) : Ui<FavoritesScreen.State> {
@Inject constructor() : this("injected")
@Composable
override fun Content(state: FavoritesScreen.State, modifier: Modifier) {
}
}
"""
.trimIndent(),
),
generatedFilePath = "test/FavoritesFactory.kt",
expectedContent =
"""
package test
import com.slack.circuit.runtime.CircuitContext
import com.slack.circuit.runtime.screen.Screen
import com.slack.circuit.runtime.ui.Ui
import com.squareup.anvil.annotations.ContributesMultibinding
import javax.inject.Inject
import javax.inject.Provider
@ContributesMultibinding(AppScope::class)
public class FavoritesFactory @Inject constructor(
private val provider: Provider<Favorites>,
) : Ui.Factory {
override fun create(screen: Screen, context: CircuitContext): Ui<*>? = when (screen) {
is FavoritesScreen -> provider.get()
else -> null
}
}
"""
.trimIndent(),
)
}

@Test
fun uiClass_assistedInjection() {
assertGeneratedFile(
Expand Down

0 comments on commit 029d98e

Please sign in to comment.