mobilenativefoundation/swift-index-store
`swift-index-store` is collection of libraries and tools for
Example Usage
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:
which discovers uses of @testable that aren't required based on the API being called by the importing file.
tycatwhich print the subtypes or supertypes of a
given type.
indexutil-annotatewhich outputs
the index information overlaid on the given source file for debugging unexpected index data.
Setup
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:
- Add the swift-index-store as a Package Dependency to your project (via File ▸ Add Packages…).
- Added the “IndexStore” library to your target's Frameworks and Libraries.
- Add
$(TOOLCHAIN_DIR)/usr/libto your target's Runpath Search Paths (LD_RUNPATH_SEARCH_PATHS) build setting. - Add
$(TOOLCHAIN_DIR)/usr/libto your target's Library Search Paths (LIBRARY_SEARCH_PATHS) build setting.
How it works
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:
- Adding Index-While-Building and Refactoring to Clang: <https://www.youtube.com/watch?v=jGJhnIT-D2M>
- High level design: <https://docs.google.com/document/d/1cH2sTpgSnJZCkZtJl1aY-rzy4uGPcrI-6RrUpdATO2Q/>
How does this differ from [indexstore-db][indexstore-db]
The 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][indexstore-db] provides more comprehensive support for querying index data as it changes across multiple builds.
[indexstore-db]: https://github.com/apple/indexstore-db
Package Metadata
Repository: mobilenativefoundation/swift-index-store
Default branch: main
README: README.md