Skip to content

Commit ef11788

Browse files
authored
Merge pull request #2264 from ahoppen/clang-type-hierarchy
Fix issue that causes type hierarchy to not work for clang files
2 parents dc13660 + d40ea83 commit ef11788

File tree

2 files changed

+62
-10
lines changed

2 files changed

+62
-10
lines changed

Sources/SourceKitLSP/SourceKitLSPServer.swift

Lines changed: 21 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2464,21 +2464,32 @@ extension SourceKitLSPServer {
24642464
guard let index = await workspaceForDocument(uri: req.textDocument.uri)?.index(checkedFor: .deletedFiles) else {
24652465
return nil
24662466
}
2467-
let usrs =
2468-
symbols
2469-
.filter {
2470-
// Only include references to type. For example, we don't want to find the type hierarchy of a constructor when
2471-
// starting the type hierarchy on `Foo()``.
2472-
switch $0.kind {
2473-
case .class, .enum, .interface, .struct: return true
2474-
default: return false
2475-
}
2467+
let usrs = symbols.filter {
2468+
// Only include references to type. For example, we don't want to find the type hierarchy of a constructor when
2469+
// starting the type hierarchy on `Foo()`.
2470+
// Consider a symbol a class if its kind is `nil`, eg. for a symbol returned by clang's SymbolInfo, which
2471+
// doesn't support the `kind` field.
2472+
switch $0.kind {
2473+
case .class, .enum, .interface, .struct, nil: return true
2474+
default: return false
24762475
}
2477-
.compactMap(\.usr)
2476+
}.compactMap(\.usr)
2477+
24782478
let typeHierarchyItems = usrs.compactMap { (usr) -> TypeHierarchyItem? in
24792479
guard let info = index.primaryDefinitionOrDeclarationOccurrence(ofUSR: usr) else {
24802480
return nil
24812481
}
2482+
// Filter symbols based on their kind in the index since the filter on the symbol info response might have
2483+
// returned `nil` for the kind, preventing us from doing any filtering there.
2484+
switch info.symbol.kind {
2485+
case .unknown, .macro, .function, .variable, .field, .enumConstant, .instanceMethod, .classMethod, .staticMethod,
2486+
.instanceProperty, .classProperty, .staticProperty, .constructor, .destructor, .conversionFunction, .parameter,
2487+
.concept, .commentTag:
2488+
return nil
2489+
case .module, .namespace, .namespaceAlias, .enum, .struct, .class, .protocol, .extension, .union, .typealias,
2490+
.using:
2491+
break
2492+
}
24822493
return self.indexToLSPTypeHierarchyItem(
24832494
definition: info,
24842495
moduleName: info.location.moduleName,

Tests/SourceKitLSPTests/TypeHierarchyTests.swift

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212

1313
import LanguageServerProtocol
1414
import SKTestSupport
15+
import SwiftExtensions
1516
import TSCBasic
1617
import XCTest
1718

@@ -248,6 +249,46 @@ final class TypeHierarchyTests: XCTestCase {
248249
]
249250
)
250251
}
252+
253+
func testClangTypeHierarchy() async throws {
254+
let project = try await SwiftPMTestProject(
255+
files: [
256+
"MyLibrary/include/empty.h": "",
257+
"MyLibrary/Test.cpp": """
258+
class Foo {};
259+
260+
class Bar: 1️⃣Foo {};
261+
""",
262+
],
263+
enableBackgroundIndexing: true
264+
)
265+
let (uri, positions) = try project.openDocument("Test.cpp", language: .cpp)
266+
let response = try await project.testClient.send(
267+
TypeHierarchyPrepareRequest(textDocument: TextDocumentIdentifier(uri), position: positions["1️⃣"])
268+
)
269+
XCTAssertEqual(response?.count, 1)
270+
}
271+
272+
func testClangTypeHierarchyInitiatedFromFunction() async throws {
273+
let project = try await SwiftPMTestProject(
274+
files: [
275+
"MyLibrary/include/empty.h": "",
276+
"MyLibrary/Test.cpp": """
277+
void hello() {}
278+
279+
void test() {
280+
1️⃣hello();
281+
}
282+
""",
283+
],
284+
enableBackgroundIndexing: true
285+
)
286+
let (uri, positions) = try project.openDocument("Test.cpp", language: .cpp)
287+
let response = try await project.testClient.send(
288+
TypeHierarchyPrepareRequest(textDocument: TextDocumentIdentifier(uri), position: positions["1️⃣"])
289+
)
290+
XCTAssertNil(response)
291+
}
251292
}
252293

253294
// MARK: - Utilities

0 commit comments

Comments
 (0)