fix: don't flag Kotlin delegation/destructuring imports as unused - #676
Open
tallclouds wants to merge 1 commit into
Open
fix: don't flag Kotlin delegation/destructuring imports as unused#676tallclouds wants to merge 1 commit into
tallclouds wants to merge 1 commit into
Conversation
Kotlin resolves some imports by convention rather than by name, so the imported
symbol never appears in the file body:
import androidx.compose.runtime.getValue
import androidx.compose.runtime.setValue
...
var expanded by remember { mutableStateOf(false) }
The identifier search in detect_unused_imports never sees "getValue", so every
Compose file using property delegation is reported as having 2 unused imports.
Acting on the finding breaks the build. On a Compose Multiplatform project this
was 37 of 73 unused-import findings — over half the detector's output.
Adds a TreeSitterLangSpec.implicit_import_uses field: (name_pattern, body_pattern)
pairs declaring per-language conventions where a matching body pattern means the
import is used. Kotlin declares getValue/setValue/provideDelegate (guarded on the
`by` keyword) and componentN (guarded on destructuring declarations). Other
languages are unaffected — the field defaults to empty.
Genuinely dead delegation imports are still flagged: the guard requires the
convention's syntax to actually be present in the file.
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.
Problem
Kotlin resolves some imports by convention rather than by name, so the imported symbol never appears in the file body. The most common case is property delegation:
getValue/setValueare required forbyto compile, but neither name is ever written out.detect_unused_importsdoes a plain identifier search, so it reports both as unused in every Compose file.37 of those 73 findings were this false positive — over half the detector's output for that language. Acting on them breaks the build:
Destructuring has the same shape:
val (lat, lon) = pointcallscomponent1()/component2()without naming them.Fix
Adds
TreeSitterLangSpec.implicit_import_uses— a tuple of(name_pattern, body_pattern)pairs. When an import's simple name matchesname_patternandbody_patternis found in the file body, the import counts as used.Kotlin declares two conventions:
getValue|setValue|provideDelegate, guarded on thebykeywordcomponentN, guarded on a destructuring declarationThe guards matter: an unused
getValueimport in a file with no delegation is still reported, so real dead imports aren't hidden. The(?<![\w.])lookbehind keeps identifiers likenearbyfrom masking them.The field defaults to
(), so every other language is unaffected. The lookup usesgetattrso duck-typed spec stubs in the existing tests keep working.Verification
desloppify/tests/lang/common/test_kotlin_unused_imports.py(5 cases, covering both the false positives and the negative cases that must still be flagged).5816 passed, 4 skipped.🤖 Generated with Claude Code
https://claude.ai/code/session_01PCWKUYMUFfgPFW9brzaPVn