diff --git a/Sources/SourceKitLSP/SourceKitLSPServer.swift b/Sources/SourceKitLSP/SourceKitLSPServer.swift index fa1979c9f..bfb6345eb 100644 --- a/Sources/SourceKitLSP/SourceKitLSPServer.swift +++ b/Sources/SourceKitLSP/SourceKitLSPServer.swift @@ -2291,6 +2291,13 @@ extension SourceKitLSPServer { } .sorted(by: { $0.name < $1.name }) + if typeHierarchyItems.isEmpty { + // When returning an empty array, VS Code fails with the following two errors. Returning `nil` works around those + // VS Code-internal errors showing up + // - MISSING provider + // - Cannot read properties of null (reading 'kind') + return nil + } // Ideally, we should show multiple symbols. But VS Code fails to display type hierarchies with multiple root items, // failing with `Cannot read properties of undefined (reading 'map')`. Pick the first one. return Array(typeHierarchyItems.prefix(1)) diff --git a/Tests/SourceKitLSPTests/TypeHierarchyTests.swift b/Tests/SourceKitLSPTests/TypeHierarchyTests.swift index ed8a6e211..614fa9265 100644 --- a/Tests/SourceKitLSPTests/TypeHierarchyTests.swift +++ b/Tests/SourceKitLSPTests/TypeHierarchyTests.swift @@ -11,6 +11,7 @@ //===----------------------------------------------------------------------===// import ISDBTestSupport +import LSPTestSupport import LanguageServerProtocol import SKTestSupport import TSCBasic @@ -185,6 +186,28 @@ final class TypeHierarchyTests: XCTestCase { ] ) } + + func testTypeHierarchyForFileWithoutIndex() async throws { + let project = try await SwiftPMTestProject(files: [ + "Test.swift": """ + class MyClass {} + class 1️⃣MySubclass: MyClass {} + + let x = MySubclass() + """ + ]) + + let (uri, positions) = try project.openDocument("Test.swift") + + // We don't have the type hierarchy because the file hasn't been indexed yet. Returning an empty array makes VS Code + // fail with the following two errors, so we should return `nil` instead. + // - MISSING provider + // - Cannot read properties of null (reading 'kind') + let response = try await project.testClient.send( + TypeHierarchyPrepareRequest(textDocument: TextDocumentIdentifier(uri), position: positions["1️⃣"]) + ) + XCTAssertNil(response) + } } // MARK: - Utilities