samchon / samchon/compiler-knowledge-graph
[Bulk index][Swift] Freeze SourceKit index generations through IndexStoreDB
Nobody has claimed this yet.
- Dominant language
- TypeScript
- Stars
- 6
- Forks
- 3
- PR merge metrics
- No merged PRs in 30d
Description
Outcome
Export Swift facts from the compiler-generated index store already maintained by
SourceKit-LSP/build tooling, freeze an explicit set of output units as one graph
generation, and enrich each changed source once for spans/signatures/access/
attributes. Do not rely on a mutable store-wide scan or issue per-symbol
SourceKit requests.
Current master baseline
No Swift strict provider is registered. PR #147 intentionally withdrew the
placeholder because no compiled IndexStoreDB sidecar exists; Swift remains on
its ordinary SourceKit-LSP/static fallback and has no committed strict timing
cell.
The feasibility gate nevertheless passes:
- Swift/Clang emit index-unit and record files during compilation;
- IndexStoreDB provides efficient
symbol/occurrence/relation queries over that data; and - SourceKit-LSP already owns background target preparation, per-source indexing,
up-to-date tracking and scheduling.
The official
background-indexing design
states that cross-file references use the index store, that target preparation
performs minimal dependency-module work, and that unchanged source units can
take a fast path without launching the compiler.
Consistency finding
Individual index unit files are written atomically, so torn unit contents are
not the main hazard. The store is append-oriented and can contain stale units
from prior targets/builds. A mutable global query can also observe a different
unit set from the one preparation just completed.
IndexStoreDB's public explicit-output-unit mode is the generation primitive:
construct/read with useExplicitOutputUnits, name the exact output-unit paths,
wait for processing, and query only that set. workspace/synchronize is a
useful readiness fence but does not itself make the store immutable after the
request returns.
Decision: SourceKit-LSP hook preferred, standalone sidecar fallback
Resident preferred route
Add an upstreamable custom request or narrow pinned SourceKit-LSP extension in
the same process that owns SemanticIndexManager and its build system:
- resolve the exact target/build settings and expected output-unit paths;
- wait for target preparation and source indexing using existing scheduling;
- capture the explicit unit set and its build/source manifest under the
manager's serialized state; - query occurrences/relations for that frozen set;
- run one changed-source SourceKit/SwiftSyntax enrichment pass; and
- commit only if build settings, source hashes and unit set remain unchanged.
This route reuses the resident compiler/index caches and avoids reconstructing
the SwiftPM/Xcode build plan outside the owning server.
Standalone fallback
A compiled Swift sidecar linked to the toolchain-matching IndexStoreDB may read
an isolated store created by a completed swift build --enable-index-store, or
a caller-supplied explicit unit list. It is suitable for CI/batch operation but
must not claim resident incrementality without the SourceKit-LSP owner.
Pin IndexStoreDB by the branch and commit matching the Swift toolchain; it does
not offer a normal semver release line, and libIndexStore compatibility is a
hard gate.
Fact mapping
Index-store roles/relations directly support:
containsvia child/owner relations;callsvia call/called-by roles;accessesvia read/write/accessor roles;- direct base/conformance and override relations;
references;- construction from a constructor call; and
- type references filtered by compiler symbol kind.
Module-unit dependencies support imports; syntax enrichment provides exact
import statement spans. unitTests() can identify test symbols, while
test-to-subject needs a named call-graph/framework enricher.
The index lacks complete declaration spans, signatures, access levels and
attributes/property-wrapper detail. Enrich them in one per-source pass using
the same build settings and map them by Swift USR/source occurrence. Do not
call cursor-info once per symbol.
The dynamic role proves a call is dynamically dispatched, not which
implementation executes. Candidate overrides/conformances belong in unresolved
data. Emit exact dispatches only for a statically closed final target.
Identity and build universe
Swift USRs are the primary persistent identity and handle overloads, modules,
generics and extensions better than position-based schemes. Explicitly cover:
- locals, which require the compiler index-local option and a stable
owner/source namespace; - macro-generated declarations and source mappings;
- extensions and synthesized accessors;
- same symbol compiled for multiple triples/configurations; and
- Objective-C/C cross-language occurrences.
The universe includes toolchain/IndexStoreDB commit, package/Xcode/BSP target,
triple, SDK, configuration, Swift language/features, compiler flags, module
dependencies, package resolution, plugins/macros, generated sources and exact
output-unit set. Conditional compilation outside that universe is
conditional-build, not absent.
Incremental and performance behavior
Reuse SourceKit-LSP's status trackers and task scheduler:
- known up-to-date source/unit: immediate manifest/shard reuse;
- source edit: update only the affected compiler index unit and enrichment
shard; - public/module change: prepare/reindex the build-system-reported dependent
closure; - build settings/package/triple change: select a different universe;
- delete/rename: remove obsolete unit/source shards explicitly; and
- cancel/crash/unit-set movement: retain the prior graph.
Avoid a full filesystem pollForUnitChangesAndWait on every refresh; use it only
where the owning manager cannot name the changed unit set.
Cold overhead is compared with native SourceKit-LSP background indexing or the
same Swift build. Warm targets follow #63.
Implementation map
- Add #63's shard/coverage protocol.
- Build a toolchain-pinned Swift probe that proves explicit unit selection,
roles, relations, locals and stale-unit rejection. - Implement the standalone sidecar as the schema oracle.
- Add the SourceKit-LSP hook/custom request and compare exact output with the
oracle. - Register the preferred provider only on a matching toolchain/handshake;
otherwise decline. - Add SwiftPM and multi-target/configuration lifecycle fixtures before real
smoke/benchmark publication.
Acceptance
- Every graph generation names an explicit unit set; stale units in the
surrounding store cannot leak in. - Exact fixtures cover modules, extensions, protocols/conformance,
overrides, virtual calls, constructors, properties/accessors,
read/write roles, generics, async, macros, conditional compilation,
locals and tests. - USR identity and multi-triple separation are proven.
- One per-source enrichment pass supplies spans/signatures/access/attributes;
no per-symbol SourceKit fan-out occurs. - All 15 fact families have explicit coverage/unresolved rows.
- No-op, edit, API/module, create/delete/rename, package/build-setting/
triple/toolchain change, error, cancel, crash and retry are atomic. - Cold time is compared with native background indexing/build; no-op/edit
phases are measured separately. - macOS and Linux toolchain packaging is proven; unsupported platforms
decline explicitly. - SourceKit-LSP/static remain truthful fallbacks.
- Focused tests, Swift experiment,
pnpm build,pnpm test, and
pnpm coveragepass.
Primary references
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with #63's shard/coverage protocol, then read the SourceKit-LSP SemanticIndexManager and the IndexStoreDB explicit-output-unit mode described in the issue. Build the toolchain-pinned Swift probe first, followed by focused fixtures for stale-unit rejection and fact coverage; done requires the listed lifecycle tests, exact output comparison, and passing pnpm build, test, and coverage.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- swift, typescript
- Domain
- compilers, devtools
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100