Skip to content

Conversation

@DPrakashhh
Copy link

Trying new PR style.
Status: ✅ Ready for Review

Explanation:
Implements a new executable index-dump that allows dumping Unit and Record files from the Index Store using the IndexStore Swift library. This serves as a native Swift replacement for c-index-test (from LLVM), making it significantly easier to debug and inspect Index Store contents (modules, dependencies, symbols, occurrences) without needing to build the full LLVM project.

Scope:
This is Additive. It introduces a new executable target index-dump in Package.swift and does not modify existing IndexStoreDB logic.

Issues:
Fixes: Implement an executable to dump unit and record files #264

Risk:
Low/None. This is a standalone developer tool. It has no impact on the production runtime or the library itself.

Testing:
Verified manually by building the tool and running it against a local .build index store.

Verified unit mode:
1- Correctly lists Module, Main File, and Dependencies.
2- Verified record mode: Correctly lists Symbols and Occurrences.

(Please see attached screenshot for verification)
Screenshot 2025-12-23 at 12 11 06 PM

Reviewers: Suggested by @ahoppen . Open to review by anyone.

Copy link
Member

@ahoppen ahoppen left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice. Left a few general comments inline.

@DPrakashhh
Copy link
Author

DPrakashhh commented Dec 23, 2025

Nice. Left a few general comments inline.

Thanks for the review! On it :)

@DPrakashhh DPrakashhh force-pushed the feature/index-store-dumper branch 2 times, most recently from 790786c to e4a8f81 Compare December 23, 2025 09:49
@DPrakashhh
Copy link
Author

I have updated the implementation to address all feedback:

1- CLI Infrastructure: Migrated to swift-argument-parser for a more robust command-line interface and auto-generated help pages.
2- Mode Inference: Added logic to automatically detect if a file is a unit or record based on its directory path (checking for /units/ or /records/), while still allowing for a manual --mode override.
3- Output Refinement: Refactored the dumping logic to accumulate output into a string buffer, ensuring a single print call at the end of the operation.
4- Swift 6 Adoption: Enabled Swift 6 language mode and the requested upcoming feature flags in Package.swift.
5- API Fixes: Corrected the closure return types for the IndexStore iterators to return .continue.

Verified the build and functionality locally. Ready for another look!

@DPrakashhh DPrakashhh requested a review from ahoppen December 23, 2025 09:51
@DPrakashhh
Copy link
Author

On it sir :)

@DPrakashhh DPrakashhh force-pushed the feature/index-store-dumper branch from b729de4 to 590e4cd Compare January 3, 2026 14:08
@DPrakashhh
Copy link
Author

DPrakashhh commented Jan 3, 2026

I have updated the branch to address all your feedback. Here are the key changes:

Package.swift updates:
1- Restored Metadata: Restored the unintentionally removed comments and ensured a trailing newline.
2- Swift 6 Mode: Enabled Swift 6 language mode and upcoming features (omitting Lifetimes as suggested).
3- Local Dependencies: Updated the local dependency path for swift-argument-parser to use the relative parent directory.

main.swift updates:
1-Refactored Architecture: Factored out dumping into separate functions and switched to an exhaustive switch for mode handling.
2-Path Safety: Used pathComponents for mode and store inference to ensure full compatibility with Windows path separators.
3-Automatic Inference: Added logic to automatically infer the libIndexStore path from the toolchain and the store path from the file's location.
4-Exhaustive Output: Expanded the dump to include all properties for Units and Records, including system/module flags and correct occurrence positions.

All 45 tests are passing. Ready for another look!

@DPrakashhh DPrakashhh requested a review from ahoppen January 3, 2026 14:54
Copy link
Member

@ahoppen ahoppen left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A couple more comments inline.

@DPrakashhh
Copy link
Author

I have an exam in 2 days, so I will be back on January 7th to address the remaining feedback. Thank you so much for your patience and guidance!

@DPrakashhh
Copy link
Author

I have made changes based on the review you have gave to me
Please check :)
Sorry for addressing this 4 days later.

Copy link
Member

@ahoppen ahoppen left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Left a few more comments inline. I think we’re getting a lot closer 👍🏽

var nameOrPath: String

@Option(help: "Path to libIndexStore. Inferred if omitted.")
var libPath: String?
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let’s explicitly name this argument --lib-index-store

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done!

Copy link
Member

@ahoppen ahoppen Jan 11, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is still unresolved. To clarify, I mean setting name: .customLong("lib-index-store") in the @Option.

@Option(help: "Path to libIndexStore. Inferred if omitted.")
var libPath: String?

@Option(help: "Path to the index store directory. Inferred if omitted.")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let’s explicitly name this variable --index-store

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done!

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same here, still unresolved.

@DPrakashhh
Copy link
Author

On it :)

@DPrakashhh DPrakashhh force-pushed the feature/index-store-dumper branch from ceaa80f to 032d295 Compare January 9, 2026 15:36
@DPrakashhh DPrakashhh requested a review from ahoppen January 9, 2026 15:49
Copy link
Member

@ahoppen ahoppen left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A few more comments inline. Also, there’s a merge conflict now. Could you resolve this by rebasing your changes on top of the latest main and then also running swift-format -ipr . again?

@DPrakashhh
Copy link
Author

On it boss:)

@DPrakashhh
Copy link
Author

DPrakashhh commented Jan 9, 2026

A few more comments inline. Also, there’s a merge conflict now. Could you resolve this by rebasing your changes on top of the latest main and then also running swift-format -ipr . again?

Screenshot 2026-01-09 at 10 25 21 PM

I think i have done something wrong , i have done rebasing but after running swift-format -ipr this happened ? Sorry for disturbing but i think i messed up - I am asking this to be sure :(

@ahoppen
Copy link
Member

ahoppen commented Jan 9, 2026

Hmm, I cannot tell if that’s correct or not. Do you want to push your changes so I can check? We can always revert to a previous commit hash.

@DPrakashhh
Copy link
Author

Hmm, I cannot tell if that’s correct or not. Do you want to push your changes so I can check? We can always revert to a previous commit hash.

yes , please check !

@ahoppen
Copy link
Member

ahoppen commented Jan 9, 2026

OK, that does indeed look messed up. The problem is that you didn’t properly rebase the changes on top of main, I think. Here’s the steps I’d take to clean it up

# Remove your formatting commit
git reset --hard HEAD^
# Add remote to the upstream repo in swiftlang if you don’t have it yet
git remote add swiftlang https://github.com/swiftlang/indexstore-db.git
git fetch swiftlang
# Rebase changes on top of swiftlang/indexstore-db’s main branch
git rebase swiftlang/main
# Resolve merge conflicts and finish the rebase
# Run swift-format
swift format -ipr .
# Only commit the changes to the files you have touch, importantly don’t modify files in `INPUTS` or the generated test files.
# Force push your changes
git push -f

@DPrakashhh DPrakashhh force-pushed the feature/index-store-dumper branch from 0c18ea9 to d4aa158 Compare January 10, 2026 03:57
@DPrakashhh
Copy link
Author

DPrakashhh commented Jan 10, 2026

Thank you so much sir

OK, that does indeed look messed up. The problem is that you didn’t properly rebase the changes on top of main, I think. Here’s the steps I’d take to clean it up

# Remove your formatting commit
git reset --hard HEAD^
# Add remote to the upstream repo in swiftlang if you don’t have it yet
git remote add swiftlang https://github.com/swiftlang/indexstore-db.git
git fetch swiftlang
# Rebase changes on top of swiftlang/indexstore-db’s main branch
git rebase swiftlang/main
# Resolve merge conflicts and finish the rebase
# Run swift-format
swift format -ipr .
# Only commit the changes to the files you have touch, importantly don’t modify files in `INPUTS` or the generated test files.
# Force push your changes
git push -f

Huge thanks for the git help! The PR is now clean and rebased. I'm very happy to have this back on track! 😊
Now working on the review :)

@DPrakashhh DPrakashhh force-pushed the feature/index-store-dumper branch from 79e7080 to 7e18248 Compare January 10, 2026 04:56
@DPrakashhh DPrakashhh requested a review from ahoppen January 10, 2026 05:05
Copy link
Member

@ahoppen ahoppen left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This PR doesn’t build, nor does it pass the tests you added. Could you please ensure that it compiles and passes the tests before putting this up for review again?

"""
\(occurrence.position.line):\(occurrence.position.column) \
| \(occurrence.symbol.kind) \
| USR: \(occurrence.symbol.usr.string) \
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For anyone working on this, it’ll be obvious that this is a USR (kind of lesson number 1 you need to learn), so I’d omit that.

Suggested change
| USR: \(occurrence.symbol.usr.string) \
| \(occurrence.symbol.usr.string) \

extension IndexStoreRecord: CustomStringConvertible {
public var description: String {
let symbolLines = symbols.map { symbol in
"\(symbol.kind) | \(symbol.name.string) | USR: \(symbol.usr.string)"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
"\(symbol.kind) | \(symbol.name.string) | USR: \(symbol.usr.string)"
"\(symbol.kind) | \(symbol.name.string) | \(symbol.usr.string)"

Comment on lines +17 to +37
var result = """
Module: \(moduleName.string)
Has Main File: \(hasMainFile)
Main File: \(mainFile.string)
Output File: \(outputFile.string)
Target: \(target.string)
Sysroot: \(sysrootPath.string)
Working Directory: \(workingDirectory.string)
Is System: \(isSystemUnit)
Is Module: \(isModuleUnit)
Is Debug: \(isDebugCompilation)
Provider Identifier: \(providerIdentifier.string)
Provider Version: \(providerVersion.string)
Mod Date: \(modificationDate)
DEPENDENCIES START
\(dependencies.map { dep in
"\(String(describing: dep.kind).capitalized) | \(dep.name.string)"
}.joined(separator: "\n"))
DEPENDENCIES END
"""
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
var result = """
Module: \(moduleName.string)
Has Main File: \(hasMainFile)
Main File: \(mainFile.string)
Output File: \(outputFile.string)
Target: \(target.string)
Sysroot: \(sysrootPath.string)
Working Directory: \(workingDirectory.string)
Is System: \(isSystemUnit)
Is Module: \(isModuleUnit)
Is Debug: \(isDebugCompilation)
Provider Identifier: \(providerIdentifier.string)
Provider Version: \(providerVersion.string)
Mod Date: \(modificationDate)
DEPENDENCIES START
\(dependencies.map { dep in
"\(String(describing: dep.kind).capitalized) | \(dep.name.string)"
}.joined(separator: "\n"))
DEPENDENCIES END
"""
let dependenciesLines = dependencies.map { dep in
"\(String(describing: dep.kind).capitalized) | \(dep.name.string)"
}.joined(separator: "\n")
return """
Module: \(moduleName.string)
Has Main File: \(hasMainFile)
Main File: \(mainFile.string)
Output File: \(outputFile.string)
Target: \(target.string)
Sysroot: \(sysrootPath.string)
Working Directory: \(workingDirectory.string)
Is System: \(isSystemUnit)
Is Module: \(isModuleUnit)
Is Debug: \(isDebugCompilation)
Provider Identifier: \(providerIdentifier.string)
Provider Version: \(providerVersion.string)
Mod Date: \(modificationDate)
DEPENDENCIES START
\()
DEPENDENCIES END
"""

"""
])
try await project.withIndexStore { indexStore in
let unitName = try #require(indexStore.unitNames(sorted: false).map { $0.string }.only)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
let unitName = try #require(indexStore.unitNames(sorted: false).map { $0.string }.only)
let unitName = try #require(indexStore.unitNames(sorted: false).map(\.string).only)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants