apple/swift
IDE support and SourceKit
Active contributors: akyrtzi, ahoppen, bnbarham
Purpose
The compiler ships several IDE-facing capabilities:
lib/IDE/-- in-process code completion, signature help, hover info, semantic tokens. Uses Sema with a custom inspection-callbacks factory.lib/IDETool/-- shared tooling forswift-ide-test, refactoring drivers, batch-mode IDE operations.lib/Index/-- builds an index database (the same one consumed byindex-import/IndexStore) used for jump-to-definition and project-wide rename.lib/Refactoring/-- the kit of refactoring transformations (extract function, fill in protocol stubs, ...). Drives theswift-refactorCLI.tools/SourceKit/-- the out-of-process IDE service used by Xcode, Apple'ssourcekit-lsp, and command-line tools. Thelib/IDE/features are exposed via a JSON RPC-style protocol.
Together these are how IDE integrations get their Swift smarts.
Directory layout
lib/IDE/ (45 files)
├── CompletionLookup.cpp
├── CodeCompletion.cpp # the completion engine
├── CodeCompletionResult.cpp
├── CodeCompletionResultSink.cpp
├── ConformingMethodList.cpp
├── ImportDepth.cpp
├── REPLCodeCompletion.cpp
├── SyntaxHighlighting.cpp # semantic tokens
└── ...
lib/IDETool/ # shared tooling helpers
└── ...
lib/Index/ # index DB writers
├── Index.cpp
├── IndexRecord.cpp # writes index records (compatible with IndexStoreDB)
├── IndexSymbol.cpp
└── ...
lib/Refactoring/ (47 files)
├── Refactoring.cpp # entry point
├── RenameRefactoring.cpp
├── ExtractFunction.cpp
└── ... per-refactoring files
tools/SourceKit/ # the SourceKit service
├── lib/ # the C++ implementation
├── tools/ # sourcekitd-test, sourcekitd-repl
└── docs/Key abstractions
| Type | File | Description |
|---|---|---|
swift::ide::CodeCompletionContext |
include/swift/IDE/CodeCompletion.h |
The active completion request state. |
swift::ide::CodeCompletionResult |
include/swift/IDE/CodeCompletionResult.h |
One completion suggestion (label, type, kind, ...). |
swift::ide::IDEInspectionCallbacks |
include/swift/IDE/IDEInspectionCallbacks.h |
Sema feeds candidates here during constraint solving. |
swift::index::IndexUnitWriter |
include/swift/Index/IndexUnitWriter.h |
Writes per-translation-unit index records. |
swift::refactoring::Refactoring |
include/swift/Refactoring/Refactoring.h |
Base class for transformations. |
sourcekitd::Service |
tools/SourceKit/lib/SwiftLang/... |
The RPC entry point. |
How it works
Completion flow
sequenceDiagram
participant Client as Editor (Xcode / sourcekit-lsp)
participant SK as sourcekitd
participant Compiler as in-process Swift compiler
participant Sema
Client->>SK: codecomplete request (file, offset)
SK->>Compiler: setup CompilerInstance + IDEInspectionCallbacks
Compiler->>Sema: type-check up to offset
Sema->>Sema: constraint solve hits the inspection point
Sema-->>Compiler: candidate decls / types
Compiler-->>SK: CodeCompletionResult list
SK-->>Client: completions JSONThe trick is that Sema's constraint solver, when it reaches the user-provided "inspection point" (the cursor location), hands control to IDEInspectionCallbacks. The callbacks subclass records candidates without aborting the solve. This produces semantically aware completions (knowing the expected type, in-scope generics, available conformances, etc.).
Indexing
lib/Index/ walks the typed AST after a successful compile and emits index records to a per-TU file (.indexstore-record-format). The records are consumed by IndexStoreDB and index-import, which Xcode and sourcekit-lsp use for cross-file lookups (jump to definition, find call hierarchy, etc.).
Refactoring
Each refactoring (rename, extract function, fill protocol stubs, ...) is a lib/Refactoring/*.cpp file. They share a common RefactoringActionInfo model. Two front-ends:
swift-refactor(tools/swift-refactor/) -- a CLI that runs a single refactoring.- SourceKit -- exposes refactoring as
sourcekitdrequests; Xcode / sourcekit-lsp consume them.
SourceKit architecture
tools/SourceKit/ is its own mini-product. It runs as sourcekitd-inproc.framework (in-process for embedded clients) or as sourcekit (a daemon). It serializes requests as XPC dictionaries on Apple platforms or framed JSON-like blobs elsewhere.
Internally it spins up CompilerInstance objects for each open project, keeps them warm, and routes requests to:
lib/IDE/for completion / hover / type info.lib/Refactoring/for refactor actions.lib/Index/for indexing.lib/Markup/for doc-comment rendering.
See tools/SourceKit/docs/ for the request reference.
Integration points
- Sema is the workhorse of every IDE feature. The IDE asks Sema to do partial work via
IDEInspectionCallbacks. - Frontend (
lib/Frontend/CompilerInstance.cpp) supports IDE-like sessions where the compilation is not driven to a final artifact (no SILGen, no IRGen). - External tools --
sourcekit-lsp(separate repo) talks tosourcekitd; Xcode embeds it. swift-syntax-- some refactorings useswift-syntax(the Swift-implemented syntax library) directly to manipulate source text.
Entry points for modification
- Adding a refactoring: drop a file in
lib/Refactoring/, register it inRefactoringKinds.def, add aswift-refactortest undertest/refactoring/. - Improving a completion case: most logic lives in
lib/IDE/CompletionLookup.cppandlib/IDE/CodeCompletion.cpp. Tests intest/IDE/. - Adding a SourceKit request: extend the request schema in
tools/SourceKit/lib/SwiftLang/, then route it through tolib/IDE/orlib/Refactoring/.
Related pages
Built by Factory AutoWiki from public repository content. It is a generated preview for codebase exploration, not source-maintained documentation.