swift-index-store is collection of libraries and tools for
programmatically reading the source code index produced by swiftc and
clang.
The IndexStore library is the primary entrypoint. For example if you
want to print all the classes defined in a specific file:
let storePath = // path/to/DerivedData/index/store
let sourceFile = // path/to/interesting/source/file
// Load the index store produced by swiftc
let store = try IndexStore(path: storePath)
for unit in store.units {
// Find the unit that corresponds to the source file we're interested in
guard unit.mainFile == sourceFile, let recordName = unit.recordName else {
continue
}
let recordReader = try RecordReader(indexStore: store, recordName: recordName)
recordReader.forEach { symbolOccurrence in
// Print class definitions in the source file
if symbolOccurrence.roles.contains(.definition) && symbolOccurrence.symbol.kind == .class {
print(symbolOccurrence.symbol.name)
}
}
}
For more examples see:
unnecessary-testable
which discovers uses of @testable that aren't required based on the
API being called by the importing file.tycat which print the subtypes or supertypes of a
given type.indexutil-annotate which outputs
the index information overlaid on the given source file for debugging
unexpected index data.Swift Package Manager:
let package = Package(
// ...
dependencies: [
.package(url: "https://github.com/lyft/swift-index-store", from: "1.0.0"),
],
targets: [
.executableTarget(name: "<command-line-tool>", dependencies: [
.product(name: "IndexStore", package: "swift-index-store"),
]),
]
)
Bazel:
Add the following to your WORKSPACE file:
SWIFT_INDEX_STORE_VERSION = "1.1.0"
http_archive(
name = "IndexStore",
sha256 = "b9c7dbcf100783c55d2c24e491feab943a489b485b016016dcd3f3d568836b3b",
strip_prefix = "swift-index-store-%s" % SWIFT_INDEX_STORE_VERSION,
url = "https://github.com/lyft/swift-index-store/archive/refs/tags/%s.tar.gz" % SWIFT_INDEX_STORE_VERSION,
)
load(
"@IndexStore//:repositories.bzl",
"swift_index_store_dependencies",
)
swift_index_store_dependencies()
then you can consume the target like so:
deps = [
"@IndexStore",
]
Xcode:
$(TOOLCHAIN_DIR)/usr/lib to your target's Runpath Search Paths (LD_RUNPATH_SEARCH_PATHS) build setting.$(TOOLCHAIN_DIR)/usr/lib to your target's Library Search Paths (LIBRARY_SEARCH_PATHS) build setting.During compilation, both swiftc and clang can generate a detailed
source code index by providing the -index-store-path flag. The data
model of the index is public, just not well known or well documented.
IndexStore is a Swift wrapper over the first party libIndexStore C
library which is part of LLVM. Xcode and Swift for Linux contain
libIndexStore, but its header is found separately in
apple/llvm-project's
indexstore.h.
For more details on the index store's data model, see:
indexstore-dbThe goal of this library is to provide a thin Swift layer on top of the
C library for one shot tools that manage the structure of the index data
themselves. indexstore-db provides more comprehensive
support for querying index data as it changes across multiple builds.
Library to read from Swift / clang source code indexes
@MobileNativeFoundation/swift-index-store