diff --git a/samples/feature/home/src/withStitch/kotlin/com/harrytmthy/stitch/feature/home/HomeActivity.kt b/samples/feature/home/src/withStitch/kotlin/com/harrytmthy/stitch/feature/home/HomeActivity.kt index 66e5e98..6bbe986 100644 --- a/samples/feature/home/src/withStitch/kotlin/com/harrytmthy/stitch/feature/home/HomeActivity.kt +++ b/samples/feature/home/src/withStitch/kotlin/com/harrytmthy/stitch/feature/home/HomeActivity.kt @@ -60,6 +60,9 @@ class HomeActivity : AppCompatActivity() { @Inject lateinit var homeServiceDevImpl: HomeServiceDev + @Inject + lateinit var homeTracker: HomeTracker + override fun onCreate(savedInstanceState: Bundle?) { val activityInjector = StitchInjector.getSingletonGraph() .createInjectorForChildScope("activity") diff --git a/samples/feature/home/src/withStitch/kotlin/com/harrytmthy/stitch/feature/home/HomeModule.kt b/samples/feature/home/src/withStitch/kotlin/com/harrytmthy/stitch/feature/home/HomeModule.kt new file mode 100644 index 0000000..63356f0 --- /dev/null +++ b/samples/feature/home/src/withStitch/kotlin/com/harrytmthy/stitch/feature/home/HomeModule.kt @@ -0,0 +1,38 @@ +/* + * Copyright 2026 Harry Timothy Tumalewa + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.harrytmthy.stitch.feature.home + +import com.harrytmthy.stitch.annotations.Binds +import com.harrytmthy.stitch.annotations.Provides +import com.harrytmthy.stitch.annotations.Singleton + +abstract class HomeModule { + + @Binds + abstract fun bindHomeTracker(impl: HomeTrackerImpl): HomeTracker + + companion object { + + @Singleton + @Provides + fun provideHomeTracker(): HomeTrackerImpl = HomeTrackerImpl() + } +} + +interface HomeTracker + +class HomeTrackerImpl : HomeTracker diff --git a/stitch-ksp/src/main/kotlin/com/harrytmthy/stitch/ksp/ScopedGraphGenerator.kt b/stitch-ksp/src/main/kotlin/com/harrytmthy/stitch/ksp/ScopedGraphGenerator.kt index 06c63bf..dbc9975 100644 --- a/stitch-ksp/src/main/kotlin/com/harrytmthy/stitch/ksp/ScopedGraphGenerator.kt +++ b/stitch-ksp/src/main/kotlin/com/harrytmthy/stitch/ksp/ScopedGraphGenerator.kt @@ -150,16 +150,15 @@ object ScopedGraphGenerator { if (binding.kind != BindingKind.PROVIDED_IN_CLASS) { continue } - val fqcn = "${binding.providerPackageName}.${binding.providerClassName}" - if (!seen.add(fqcn)) { + if (!seen.add(binding.providerClassName)) { continue } addProperty( PropertySpec.builder( - providerFieldName(binding), - ClassName.bestGuess(fqcn), + baseTypeName(binding.providerClassName), + ClassName.bestGuess(binding.providerClassName), KModifier.PRIVATE, - ).initializer("%T()", ClassName.bestGuess(fqcn)) + ).initializer("%T()", ClassName.bestGuess(binding.providerClassName)) .build(), ) } @@ -278,7 +277,7 @@ object ScopedGraphGenerator { CodeBlock.builder().apply { add( "%T.%N(", - ClassName.bestGuess("${binding.providerPackageName}.${binding.providerClassName}"), + ClassName.bestGuess(binding.providerClassName), binding.providerFunctionName, ) dependencyArgs.forEachIndexed { index, arg -> @@ -290,8 +289,9 @@ object ScopedGraphGenerator { } BindingKind.PROVIDED_IN_CLASS -> { + val formattedClassName = baseTypeName(binding.providerClassName) CodeBlock.builder().apply { - add("%N.%N(", providerFieldName(binding), binding.providerFunctionName) + add("%N.%N(", formattedClassName, binding.providerFunctionName) dependencyArgs.forEachIndexed { index, arg -> if (index > 0) add(", ") add("%L", arg) @@ -552,9 +552,6 @@ object ScopedGraphGenerator { } } - private fun providerFieldName(binding: ValidatedBinding): String = - binding.providerClassName.replaceFirstChar(Char::lowercase) - private fun baseTypeName(fqcn: String): String { val raw = fqcn.substringAfterLast('.').substringAfterLast('$') return sanitizeName(raw).replaceFirstChar(Char::lowercase) diff --git a/stitch-ksp/src/main/kotlin/com/harrytmthy/stitch/ksp/scanner/LocalAnnotationScanner.kt b/stitch-ksp/src/main/kotlin/com/harrytmthy/stitch/ksp/scanner/LocalAnnotationScanner.kt index c3827c0..a274c47 100644 --- a/stitch-ksp/src/main/kotlin/com/harrytmthy/stitch/ksp/scanner/LocalAnnotationScanner.kt +++ b/stitch-ksp/src/main/kotlin/com/harrytmthy/stitch/ksp/scanner/LocalAnnotationScanner.kt @@ -325,7 +325,7 @@ class LocalAnnotationScanner( kind = kind, providerPackageName = symbol.packageName.asString(), providerFunctionName = symbol.simpleName.asString(), - providerClassName = parentDeclaration?.simpleName?.asString().orEmpty(), + providerClassName = parentDeclaration?.qualifiedName?.asString().orEmpty(), ) // ProvidedBinding is keyed only by type + qualifier, allowing `providedBindings`