You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
* Fix Kotlin dead-code false positives: emit method-kind for members, receiver/property/callable-reference/outside-body call edges, and Groovy-namespace cross-module imports in the extractor, and exclude framework/DI/override/androidTest entry points in the orphan detector
* Kotlin/Java: make analyze_performance perf-facts precise — arity- and super-aware recursion detection, RxJava/Flow chains no longer counted as loops, and Retrofit/Room methods tagged performs_io (cacheVersion v57).
* fix(package-metrics): eliminate false positives on multi-module Kotlin/Java by resolving cross-module imports via a declared-package index, excluding test-support/DI/enum symbols from the population, and reclassifying data-holder packages instead of flagging them rigid
* Adding missing files
* Fixing lint
Copy file name to clipboardExpand all lines: internal/engine/cache.go
+50-3Lines changed: 50 additions & 3 deletions
Original file line number
Diff line number
Diff line change
@@ -65,7 +65,42 @@ import (
65
65
// v49: Swift models XcodeGen test-bundle targets (bundle.unit-test/bundle.ui-testing) as one module each, so a test bundle's files (e.g. Tests/Core/**) collapse into a single module instead of exploding into per-leaf-directory modules; and every module fact now carries a normalized `module_role` prop (production/test/tooling/unknown) — derived from the XcodeGen target type, the SPM target vs testTarget call, or a path heuristic for leaf-directory fallback — so package-metrics and other analyses can measure the production population without re-parsing manifests.
66
66
// v50: the `module_role` prop is now emitted by the Ruby extractor too (packwerk packages → production; leaf-directory modules → path heuristic), and the path heuristic was hoisted to facts.ModuleRoleForPath and broadened to common cross-language conventions (spec/test/tests + scripts/bin/fastlane/ci_scripts), so Ruby build-tooling modules (fastlane/, Scripts/) are classified as tooling rather than defaulting to the production population.
67
67
// v51: Swift no longer emits type-reference-derived module→module dependency edges for files that belong to a resolved SPM/XcodeGen target — those files' cross-module deps are captured completely by their `import X` statements plus the declared target graph, whereas the type-reference pass resolved bare short names through a collision-prone global index (Swift namespaces nested types, so names like Event/State/Coordinator recur across targets) and fabricated impossible back-edges (a Foundation-level target "importing" a feature target) that produced a false module cycle. For loose Swift projects (leaf-directory fallback, no target graph) the pass still runs but now skips any type name defined in more than one module. Fixes the false Swift dependency cycle.
68
-
constcacheVersion="v51"
68
+
// v52: Kotlin emits SymbolMethod (not SymbolFunc) for functions declared inside a class/object (parity with Go/Java), keeping member functions out of the high-confidence orphan bucket; records a short-name RelCalls edge for every navigation expression (receiver method call `repo.getUser()` and property/field access `slot.uniqueId`), which the short-name-matching dead-code detector needs to see live members as used; and tags `override` methods and Dagger/Hilt `@Provides`/`@Binds` methods with `override`/`di_provider` props so framework/DI entry points are excluded from orphan reporting. Fixes the mass Kotlin/Android dead-code false positives (thousands of live Retrofit/lifecycle/interface members reported as high-confidence orphans).
69
+
// v53: Kotlin base-package detection now matches Groovy build scripts (`namespace 'x'`, single quotes) in addition to Kotlin-DSL (`namespace = "x"`). A double-quote-only regex left the base package empty for `.gradle` (Groovy) projects, so every in-repo import resolved as external and bare calls to imported top-level/extension functions (`formatPrettyDate(...)`, `setMargin(...)`) emitted no call edge — reporting live utilities as high-confidence orphans.
70
+
// v54: Kotlin now walks calls that live OUTSIDE a function body — function default-parameter values (`fun f(x = helper())`) and supertype constructor-delegation arguments (`class NpeId(id) : Enrichment(npeEntity(id))`, and the object equivalent). These were previously skipped, so a helper/factory referenced only from a default value or a base-class initializer was mis-reported as a high-confidence orphan (e.g. Snowplow entity builders, Compose default-arg providers).
71
+
// v55: Kotlin captures callable references (`::foo`, `Type::foo`, e.g. `onClick = ::doNothing`, `.map(::helper)`) as short-name RelCalls edges. A function referenced only as a method reference (never called directly) was previously mis-reported as a high-confidence orphan.
72
+
// v56: Kotlin/Java perf-fact precision — (1) recursion (`recursive_self`) is now argument-count aware: a call sharing the enclosing function's name is only flagged recursion when its arg count matches the parameter count, so a call to a same-named overload (`updateItem(x)` → `updateItem(i, x)`, `onChangeStarted(2)` override → `onChangeStarted(3)`) is no longer read as self-recursion — the dominant Kotlin/Android recursion false positive (Conductor `onChange*` lifecycle). (2) Kotlin RxJava/coroutine-Flow chains no longer inflate loop_depth: in a reactive function (reactive return type Single/Observable/Maybe/Flowable/Completable/Flow, or body reactive operators subscribeOn/observeOn/applySchedulers/andThen/.subscribe/flowOn/.collect/…), the ambiguous operators (map/flatMap/filter/fold/reduce/onEach) are stream transforms, not per-element collection loops, so a `Single.flatMap { … .map { } }` is no longer a false O(n²)/O(n³). Fixes the analyze_performance false positives on this RxJava-heavy codebase.
73
+
// v57: Kotlin/Java recursion also clears the arity-matched case where an `override` delegates to a same-name, same-arity overload declared in a parent (invisible here): a body that calls `super.<self>()` marks the sibling `<self>(…)` call as delegation, not recursion (fixes the residual Conductor `onChangeEnded` false positives). And Kotlin methods now carry `io_direct`/`performs_io` when annotated as a Retrofit endpoint (@GET/@POST/@PUT/@DELETE/@PATCH/@HEAD/@OPTIONS/@HTTP) or a Room DAO op (@Query/@Insert/@Update/@Upsert/@Delete/@RawQuery) — a precise per-method I/O identity that lets analyze_performance flag a per-iteration call to a real network/DB method as a genuine N+1 (ranked high) without relying on the cross-language keyword guess.
74
+
// v58: Kotlin/Java multi-module import resolution — imports are now resolved via a
75
+
// cross-language declared-package→directory index (built from every non-test .kt AND
76
+
// .java file) instead of assuming a single global source root. In a multi-module
77
+
// Gradle project where several modules root packages at the same prefix (app/, api/,
78
+
// business/ all under de.foo.*), the old Kotlin resolver mapped every internal import
79
+
// under the single most common source root (the app module), collapsing all
80
+
// cross-module afferent coupling onto the app package (bogus Ca god-package) and
81
+
// starving library modules of Ca (falsely "useless" in package-metrics). Now an
82
+
// import resolves to the module that actually declares the package. The Java extractor
83
+
// seeds its FQN resolver with the same cross-language index so Java→Kotlin imports no
84
+
// longer drop. Kotlin & Java module facts now carry `module_role` (test for
85
+
// src/test & src/androidTest, else production) so package-metrics excludes test source
86
+
// sets; and Kotlin `sealed` classes are marked `abstract` so abstractness (A) counts
87
+
// them (they are non-instantiable), fixing inflated Distance / false "rigid" findings.
88
+
// v59: the package index now prefers a main source set (…/src/main/…) over a Gradle
89
+
// build-variant source set (src/debug, src/release, src/staging) when both declare the
90
+
// same package. An Android app's src/main and src/debug both declare the root
91
+
// application package; the v58 lexicographic tie-break wrongly mapped it to src/debug
92
+
// ('d' < 'm'), misrouting the whole app's afferent coupling onto the debug variant
93
+
// (a bogus Ca god-package). Imports of the root package now resolve to the main module.
94
+
// v60: package-metrics precision — (1) module_role now sub-token-matches compound test
95
+
// module names (split each path segment on -/_ and match an exact `test`/`tests` token),
96
+
// so Gradle test-automation modules that compile as src/main (release-tests, ui-test-utils,
97
+
// test-lab) are classified test rather than leaking into the production population, without
98
+
// misfiring on latest/contest/abtest. (2) Dagger/Hilt DI infrastructure is now tagged:
99
+
// @Component/@Subcomponent interfaces get `di_component`, @Module classes get `di_module`
100
+
// (Java & Kotlin); a Dagger @Component interface is no longer mislabeled a Spring component
101
+
// (disambiguated by interface-vs-class). Lets package-metrics exclude DI wiring from
102
+
// abstractness/type counts (a Dagger component package was falsely "useless").
103
+
constcacheVersion="v60"
69
104
70
105
// extractorCache holds per-extractor facts keyed by a content hash of the files
71
106
// the extractor depends on. It is loaded from disk at the start of a snapshot and
0 commit comments