* feat(kotlin): bind Spring @Value and ConfigurationProperties consumers
Kotlin sources were skipping the Java-only config-binding attach path, so mixed JVM apps under-reported blast radius for Kotlin placeholders. Capture from the live AST, serialize on the existing side channel, and reuse the shared binder. (U1-U4)
Co-authored-by: Cursor <cursoragent@cursor.com>
* fix(review): require exact Spring annotation FQNs and skip raw-string escapes
Reject similarly named third-party imports and leave Kotlin triple-quoted bodies undecoded so capture stays fail-closed.
Co-authored-by: Cursor <cursoragent@cursor.com>
* fix(kotlin): use only grammar-valid Kotlin string and class-name nodes
The coverage shard failed the #1920 literal gate on invented string node types and a Java-style name field.
Co-authored-by: Cursor <cursoragent@cursor.com>
* fix(kotlin): fail closed on non-literal prefixes and persist unresolved config markers
Reject constant and boolean @ConfigurationProperties arguments, scope nested Value shadows to their owner, and rewrite drifted consumer files when a config key is deleted.
Co-authored-by: Cursor <cursoragent@cursor.com>
* test(kotlin): add config-consumer capture benchmark and fix JVM feature stamps
The Kotlin capture path had no performance or behavior guard: a file-wide
lexical shadow regression silently dropped two of every three facts. The new
bench arm fingerprints @Value / @ConfigurationProperties facts from an
explicit-import control against a wildcard-import corpus whose files each
declare a sibling nested `Value` type, so parity between the arms is the
regression gate, and CI runs it with scaling + widening budgets.
Broadening spring.config-bindings to .kt also means Kotlin-only JVM repos now
stamp the feature, which the two exact-map orchestration expectations still
denied.
Co-authored-by: Cursor <cursoragent@cursor.com>
* fix(kotlin): let an explicit import shadow the Spring wildcard import
importedAs accepted a star import of the Spring package even when the same
simple name was explicitly bound to another type, so a file importing
com.example.Value alongside the Spring annotation package emitted a false
@Value consumer fact. Kotlin resolves the explicit import first, so the
wildcard branch now only applies when the name is otherwise unbound.
Co-authored-by: Cursor <cursoragent@cursor.com>
---------
Co-authored-by: Gergo Magyar <gergomagyar0@gmail.com>
Co-authored-by: Cursor <cursoragent@cursor.com>