Unable to get any results from IndexStoreDB

Hi all,

I'm trying to use IndexStoreDB to simply read some symbols from the index, however I've been unable to obtain any results at all.

let storePath = "/Users/ian/code/ileitch/inferno/.build/x86_64-apple-macosx/debug/index/store"
let dbPath = NSTemporaryDirectory() + "db"
let lib = try IndexStoreLibrary(dylibPath: "/Applications/Xcode11.3.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/libIndexStore.dylib")

let db = try IndexStoreDB(
    storePath: storePath,
    databasePath: dbPath,
    library: lib,
    listenToUnitEvents: false)

When I call e.g db.canonicalOccurrences(ofName: "SomeClass") it always returns an empty array.

I extended IndexStoreDB to get access to indexstoredb_index_symbol_names in an attempt to just list all available symbol names, yet that also returns nothing.

Some things I've tried:

  • IndexStoreDB master and switch-5.1-branch branches
  • Using an index store generated by swift build and also one generated by Xcode (i.e DerivedData/App-*/Index/DataStore)
  • Different versions of Xcode - 11.1 and 11.3

I'm sure I must be misunderstanding something pretty fundamental here. Any tips for debugging this?

listenToUnitEvents: false)

I'll update the documentation, but this should always be true except for during unit tests. If you set this to false, you will only get index data when you call pollForUnitChangesAndWait() explicitly.

Unfortunately changing that hasn't had any affect. The nature of that argument makes me believe I may not be using IndexStoreDB as intended. Is it expected that I can open a pre-built data store? Or is IndexStoreDB only intended for use where a build/indexing happens concurrently while another process listens for events?

I'm simply trying to read .build/x86_64-apple-macosx/debug/index/store produced by running swift build.

Ah, there's something else I forgot. Does it work if you sleep a second or two before making the query? Currently it's wired up not to wait for the initial scan of index data. If that's the issue, we have the right hook in the C++ already (waitUntilDoneInitializing) and we can provide a way to make the Swift initializer wait if desired.

Yes.

We support both :smile_cat:

Yep, that was it! Thank you. Exposing waitUntilDoneInitializing explicitly or implicitly via the initializer would great.

https://github.com/apple/indexstore-db/pull/60

3 Likes

I was hoping to use IndexStoreDB to retrieve type information about instance properties, though that information doesn't appear to be exposed in Swift. Does the underlying index actually store type info?

The USR of a property (and most other declarations) is derived from its mangled name, which contains the (canonical) type. For example,

public typealias Foo = Int
public var xyx: Foo = 0

The index has

2:12 | variable/Swift | s:1t3xyxSivp | Def | rel: 0
2:17 | type-alias/Swift | s:1t3Fooa | Ref | rel: 0

If you take the variable's USR and replace the prefix "s:" with the mangling prefix "$S" you can demangle it:

$ swift-demangle '$S1t3xyxSivp'
$S1t3xyxSivp ---> t.xyx : Swift.Int

which is using the canonical type (Int "$SSi") rather than the typealias (Foo "$S1t3Fooa").

Ah yes, of course. Thanks for pointing that out! Now I really wish [Returned for revision] SE-0262: Demangle function had been accepted :smile:

Hopefully my last IndexStoreDB question. Is it possible to obtain information about local variables within functions?

We don't currently index local variables. You could add a new compiler flag to enable that probably (if you search Swift for "indexLocals" you'll see how this would be enabled in the C++ code), but we wouldn't want to index locals by default without being really careful about the performance and space effects. We also haven't tested indexing locals except in narrow circumstances.

OK understood, thanks again.