Fix incremental factory generation - #189
Merged
Merged
Conversation
KSP can invoke process() in multiple rounds within a single build when another aggregating processor (e.g. Koin compiler) generates files that trigger a new round. Without a guard, ComponentFactoryProcessor attempted to recreate already-generated factory files in round 2+, causing FileAlreadyExistsException. Fix 1: Add invoked guard so the processor exits early on subsequent rounds. Fix 2: Change aggregating=true to aggregating=false — each *ComponentFactory is derived solely from its own source class, so treating it as an aggregating output was semantically incorrect and caused unnecessary full regeneration on every incremental build. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
matejsemancik
marked this pull request as draft
May 6, 2026 08:03
Fixes KSP-based koin annotations bug with component validation related to context parameters execution
matejsemancik
marked this pull request as ready for review
May 11, 2026 18:05
Syntey
approved these changes
May 13, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
This PR fixes unstable incremental KSP generation in
decompose-processor. The processor generates one*ComponentFactory.ktfile per@GenerateFactorycomponent, but the generated files were not explicitly associated with the source file that produced them. Although the files were marked as isolating, KSP had no originatingKSFilemetadata for the outputs, so incremental builds could lose the relationship between an annotated component and its generated factory.In a consuming KMP project this showed up as nondeterministic rebuild failures. A clean build generated all factories, but subsequent incremental runs could pass only a subset of annotated components to the processor. KSP then regenerated only that subset and removed the factories for unchanged components, causing unresolved references such as
FirstComponentFactoryorLoginComponentFactoryuntil a clean build was run again.Fix
Each generated factory is now explicitly registered with the annotated component's containing source file via
addOriginatingKSFile(factoryComponent.containingFile). The generated file remains isolating (aggregating = false), which matches the actual dependency model: one factory depends on one component source file.The previous one-shot
invokedguard was removed so the processor can participate correctly in KSP rounds. With proper originating-file metadata, KSP can safely decide which factories to keep, remove, or regenerate during incremental processing instead of relying on skipping later rounds.Test plan
./gradlew :decompose-processor:compileKotlinJvm:shared:feature:clean :shared:feature:compileCommonMainKotlinMetadata --refresh-dependencies --no-build-cache --no-configuration-cache:shared:feature:compileCommonMainKotlinMetadatarebuild keeps all generated factories