/** * #869 measure-gated spike: a deterministic, zero-LLM symbol-usage signal for * Swift/XCTest test association. * * Swift test files import their subject as a whole module (`import * Alamofire`, `@testable import Alamofire`) rather than a specific file or * symbol path (see `LanguageDefinition.wholeModuleImports`), so import-based * matching (`findTestAssociationsFromChunks`) is structurally blind for this * entire language family — every test file in a module carries the identical * bare-module import string. This module recovers a DIFFERENT, non-import * signal already sitting in the indexed chunk store: a test chunk's own * `callSites` (the AST-extracted symbols it references) versus which single * source file uniquely DEFINES that symbol. * * Association rule (test T -> source S): T's chunk references a symbol X via * `callSites` such that: * 1. X passes `isDistinctiveSwiftSymbol` — the shipped `isUnambiguousIdentifierShape` * gate AND this module's own, stricter `isMultiSegmentIdentifier` gate * (see that function's doc for why the shipped gate alone passes nearly * every ordinary English word and is insufficient here). * 2. X is defined in EXACTLY ONE non-test Swift file project-wide (S) — see * `buildSwiftDefinitionMap`, which also excludes `extension ` * declarations from counting as a definition (see its doc for why). * 3. S !== T. * 4. The (S, T) EDGE has at least one driving symbol that also passes * `isTypeShapedIdentifier` (see its doc) — a purely method-driven edge * is demoted even if every individual symbol independently passed * gates 1-3. * * Gate 4 is a post-ship hardening, added after adversarial re-verification * found that gates 1-3 alone are insufficient: "unique in this project's own * indexed files" does not imply "this call resolves to that declaration", * because Swift lets a bare method name collide with something the indexer * never sees at all — a stdlib protocol witness, a stdlib type's own * extension overload, or an external package's free function of the same * name. Confirmed real false positives across Alamofire/vapor/swift- * composable-architecture: `singleValueContainer`, `asURL`, `addTask`, * `flatMap`, `withDependencies` — every one a lowercase-only edge with no * type-shaped co-driver (see `isTypeShapedIdentifier`'s doc, and the * regression tests in `swift-symbol-usage-signals.test.ts`). * * Measured on real clones (see #869's PR thread for the full tables, * including the pre-hardening numbers and the confirmed false positives * above): gate 4 brings measured precision to 100% on all three calibration * repos, at a substantial recall cost — roughly half of the pre-hardening * edges are lost project-wide, including EVERY edge to Alamofire's own * `Request.swift` (the file that originally motivated this investigation): * `Request` itself is single-segment and can never serve as a type-shaped * driver, and none of its distinctively-named methods (`prepareForRetry`, * `cURLDescription`, ...) have a type-shaped symbol alongside them in the * tests that call them. * * This is a strictly ADDITIVE, lower-confidence THIRD tier — never merged * into the confident import-based association * (`findTestAssociationsFromChunks`) or Go's same-directory tier 2 * (`go-same-directory-tests.ts`). Mirrors that same tier's discipline: kept * out of `get_files_context`, `@liendev/review`'s gap detection, and * `verify-tests`'s ledger/scope-matching — surfaced only via `lien annotate` * (see `annotate-cmd.ts`'s `computeSwiftSymbolUsageFallback`, the sole * caller). */ import type { CodeChunk } from './types.js'; /** * True iff `token` has AT LEAST 2 camelCase/PascalCase/underscore segments — * the shape that separates a real, collision-resistant identifier * (`TypeMap`, `getStatusCode`, `RetryMiddleware`, `HTTPHeaders`) from a single * ordinary Capitalized English word (`Get`, `Run`, `Map`, `Session`, `Client`). * * Measured necessity (#869 design comment): the shipped * `isUnambiguousIdentifierShape` (docRefs' gate) passes EVERY single * Capitalized word trivially — its case-transition check is satisfied by the * very first two characters of any Capitalized word (`Ge` in `Get`, `Se` in * `Session`), which was never a problem for its original prose-vs-code * distinction but makes it useless as a COLLISION-resistance gate here. A * single Capitalized common word is exactly the shape most likely to also be * a stdlib/Foundation type or an unrelated project symbol — this gate must * reject those outright, never leaving it to the uniqueness check alone. * Deliberately does NOT touch or weaken `isUnambiguousIdentifierShape` itself * (docRefs' prose-vs-code distinction is a different property) — this is an * additional, stricter helper applied only by this signal. Exposed for * testing. */ export declare function isMultiSegmentIdentifier(token: string): boolean; /** * True iff `token` reads as a TYPE reference — leading-uppercase (allowing * Swift's `_`-prefixed SPI/implementation-detail naming convention, e.g. * `_CancelID`, `_EffectPublisher` — the underscore itself carries no case * information) AND multi-segment — rather than a method/property name. * * Hardening (post-#869-ship, adversarial re-verification): a bare lowercase * METHOD name, even when uniquely DECLARED in-project, is not reliable * evidence a given call site actually resolves to that declaration. Swift * lets many independent, uninexed things share one method name — a stdlib * protocol witness (`Decoder.singleValueContainer()`, satisfied by every * conforming type, including ones outside this project entirely), a stdlib * TYPE extension overload (`TaskGroup.addTask(name:...)` shimming the * built-in `addTask`), or a same-named free function from an external * package dependency (`swift-dependencies`' own top-level * `withDependencies(_:operation:)`) — and the indexer only ever sees this * project's own files, so "unique in this project" silently ignores every * one of those. Measured on real Alamofire/vapor/swift-composable-architecture * clones: every confirmed false positive (`singleValueContainer`, `asURL`, * `addTask`, `flatMap`, `withDependencies`) was a lowercase-only edge with NO * type-shaped co-driver. A PascalCase, multi-segment symbol referenced via a * bare call (`Foo(...)`, Swift's constructor-call spelling) doesn't have this * problem: it names this project's own type directly, and if a same-named * external type existed unqualified in the same file the compiler would * refuse to build over the ambiguity, not silently pick one. * * Deliberately NOT a hardcoded list of risky method names (that would be a * denylist, and a new unindexed collision would always be one method name * away) — this is a structural, method-name-agnostic shape check. Exposed * for testing. */ export declare function isTypeShapedIdentifier(token: string): boolean; /** * Find Swift test files whose `callSites` reference a distinctive symbol * uniquely owned by one of `filepaths`. Returns `Map` * — the same shape as `findTestAssociationsFromChunks`, so callers can slot * it in identically (see `computeSwiftSymbolUsageFallback` in * `annotate-cmd.ts` for the sole caller). Only ever meaningful for Swift; * non-Swift chunks are ignored on both the definition and usage side (the * design's explicit "same language" gate). * * An edge is kept only when AT LEAST ONE of its driving symbols is * `isTypeShapedIdentifier` — see that function's doc for why a purely * method-driven edge isn't reliable evidence on its own (adversarial * re-verification post-ship found 5 confirmed false positives across * Alamofire/TCA, every one lowercase-method-only). * * `chunks` should be the FULL project chunk set — uniqueness is a * project-wide property, not scoped to `filepaths`. */ export declare function findSwiftSymbolUsageAssociations(filepaths: string[], chunks: CodeChunk[]): Map; //# sourceMappingURL=swift-symbol-usage-signals.d.ts.map