How to debug sourcekit-lsp not finding symbol across module

Hi,

I'm using emacs for a swift project but haven't configured sourcekit-lsp properly to make jump-to-definition work across module. Say the project root is /Foo and I want to jump to definition of Bar:

swift build log shows indexes are generated w/ the following flag:
-index-store-path /Foo/.build/x86_64-apple-macosx/debug/index/store
And I see both records and units directories have an entry about Bar.

In emacs, the lsp workspace has rootPath set to /Foo, but it seems the server couldn't find the symbol Bar when querying from another module Baz.swift
[Trace - 10:06:25 AM] Received notification 'window/logMessage'. Params: { "message": "SourceKitServer: Request<textDocument/codeAction>(\n id: 13,\n clientID: ObjectIdentifier(0x00007fd8edc15520),\n params: CodeActionRequest(_range: LanguageServerProtocol.CustomCodable<LanguageServerProtocol.PositionRange>(wrappedValue: Range(LanguageServerProtocol.Position(line: 155, utf16index: 33)..<LanguageServerProtocol.Position(line: 155, utf16index: 33))), context: LanguageServerProtocol.CodeActionContext(diagnostics: [LanguageServerProtocol.Diagnostic(_range: LanguageServerProtocol.CustomCodable<LanguageServerProtocol.PositionRange>(wrappedValue: Range(LanguageServerProtocol.Position(line: 155, utf16index: 30)..<LanguageServerProtocol.Position(line: 155, utf16index: 30))), severity: Optional(LanguageServerProtocol.DiagnosticSeverity.error), code: nil, source: Optional(\"sourcekitd\"), message: \"cannot find \\'Bar\\' in scope\", relatedInformation: Optional([]), codeActions: nil)], only: nil), textDocument: LanguageServerProtocol.TextDocumentIdentifier(uri: LanguageServerProtocol.DocumentURI(storage: file:///Foo/.../Baz.swift)))\n)", "type": 4 }

Any advice on how to debug further

This shows that the module containing Bar was not imported - assuming you have the right import statements in this file, probably it is failing to find the .swiftmodule file. Either that module hasn't been built or there is some problem calculating compiler arguments that prevents sourcekit-lsp from looking in the right place.

If you run with environment SOURCEKIT_LOGGING=1 sourcekitd should print the compiler arguments that are being passed in as part of the log. There should be a search path for the build directory of the form "-I", "/Foo/.build/<platform>/debug" and that directory should contain the .swiftmodule file if everything is working correctly.

Thanks Ben. The .swiftmodule is present in the debug folder with non-zero size.

The sourcekit-ls does log to stderr with compiler flags but it doesn't seem to contain the build directory. Here's the beginning of the log:

sourcekit: [2:sourcekitd_initialize:4355: 0.0000] initializingsourcekit: [2:sourcekitd_send_request_sync-before:4611: 0.0170] {
  key.request: source.request.editor.open,
  key.name: "/Foo/Baz.swift",
  key.compilerargs: [
    "-sdk",  
    "/Applications/Xcode_12.0.0_beta_6_xxx.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX11.0.sdk",
    "/Foo/Baz.swift"
  ],
  key.sourcetext: ...
}sourcekit: [2:sourcekitd_send_request_sync-after:4611: 0.0450] sourcekit: [2:sourcekitd_send_request-before:4611: 0.0464] {
...
$ xcrun -f swift
/Applications/Xcode_12.0.0_beta_6_xxx.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/swift

The sourcekit-lsp comes from Xcode and seems to be invoked by Emacs automatically when I load the swift file Baz.swift.

(setq lsp-sourcekit-executable "/Applications/Xcode_12.0.0_beta_6_xxx.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/sourcekit-lsp")

The compiler arguments you see here (-sdk <sdk> Baz.swift) are coming from our "fallback" provider. This indicates that we failed to find or process the Package.swift file or else that the file "Baz.swift" was not considered part of this package. There may be some log messages about this if there was a failure to load - they would probably be earlier in the log, after the "initialize" request.

Does sourcekit-lsp support invoking swift build with --disable-sandbox?

As you put it, the problem was that sourcekit-lsp failed to process the Package.swift. The package file attempts to create a file that is later used in the build process. On mac it would report error "Operation not permitted" unless I run swift build with --disable-sandbox. Have a workaround but curious if sourcekit-lsp could be invoked with similar option?

We do not currently support --disable-sandbox in sourcekit-lsp. We could potentially add such an option as a command-line flag for sourcekit-lsp, but I would want to get the opinion of the swiftpm folks on that before doing so. In technical terms I think it would just mean passing isManifestSandboxEnabled: true/false when we create the ManifestLoader if you wanted to play with it.

1 Like