@@ -335,6 +335,8 @@ fileprivate enum TaskMetadata: DependencyTracker {
335
335
self = . freestanding
336
336
case is WorkspaceSymbolsRequest :
337
337
self = . freestanding
338
+ case is WorkspaceTestsRequest :
339
+ self = . freestanding
338
340
default :
339
341
logger. error (
340
342
"""
@@ -836,6 +838,8 @@ extension SourceKitServer: MessageHandler {
836
838
await request. reply { try await shutdown ( request. params) }
837
839
case let request as RequestAndReply < WorkspaceSymbolsRequest > :
838
840
await request. reply { try await workspaceSymbols ( request. params) }
841
+ case let request as RequestAndReply < WorkspaceTestsRequest > :
842
+ await request. reply { try await workspaceTests ( request. params) }
839
843
case let request as RequestAndReply < PollIndexRequest > :
840
844
await request. reply { try await pollIndex ( request. params) }
841
845
case let request as RequestAndReply < BarrierRequest > :
@@ -1490,33 +1494,30 @@ extension SourceKitServer {
1490
1494
/// Handle a workspace/symbol request, returning the SymbolInformation.
1491
1495
/// - returns: An array with SymbolInformation for each matching symbol in the workspace.
1492
1496
func workspaceSymbols( _ req: WorkspaceSymbolsRequest ) async throws -> [ WorkspaceSymbolItem ] ? {
1493
- let symbols = findWorkspaceSymbols (
1494
- matching: req. query
1495
- ) . map ( { symbolOccurrence -> WorkspaceSymbolItem in
1496
- let symbolPosition = Position (
1497
- line: symbolOccurrence. location. line - 1 , // 1-based -> 0-based
1498
- // FIXME: we need to convert the utf8/utf16 column, which may require reading the file!
1499
- utf16index: symbolOccurrence. location. utf8Column - 1
1500
- )
1501
-
1502
- let symbolLocation = Location (
1503
- uri: DocumentURI ( URL ( fileURLWithPath: symbolOccurrence. location. path) ) ,
1504
- range: Range ( symbolPosition)
1505
- )
1506
-
1507
- return . symbolInformation(
1508
- SymbolInformation (
1509
- name: symbolOccurrence. symbol. name,
1510
- kind: symbolOccurrence. symbol. kind. asLspSymbolKind ( ) ,
1511
- deprecated: nil ,
1512
- location: symbolLocation,
1513
- containerName: symbolOccurrence. getContainerName ( )
1514
- )
1515
- )
1516
- } )
1497
+ let symbols = findWorkspaceSymbols ( matching: req. query) . map ( WorkspaceSymbolItem . init)
1517
1498
return symbols
1518
1499
}
1519
1500
1501
+ func workspaceTests( _ req: WorkspaceTestsRequest ) async throws -> [ WorkspaceSymbolItem ] ? {
1502
+ let testSymbols = workspaces. flatMap { ( workspace) -> [ SymbolOccurrence ] in
1503
+ guard let index = workspace. index else {
1504
+ return [ ]
1505
+ }
1506
+ let xctestSubclasses = index. occurrences ( ofUSR: " c:objc(cs)XCTest " , roles: [ . baseOf] )
1507
+ . flatMap ( \. relations)
1508
+ . filter { $0. roles. contains ( . baseOf) }
1509
+ . flatMap { index. occurrences ( ofUSR: $0. symbol. usr, roles: [ . definition] ) }
1510
+ let testMethods = xctestSubclasses. flatMap { xctestSubclass in
1511
+ index. occurrences ( relatedToUSR: xctestSubclass. symbol. usr, roles: [ . childOf] )
1512
+ } . filter { testMethodSymbol in
1513
+ return testMethodSymbol. symbol. kind == . instanceMethod && testMethodSymbol. symbol. name. starts ( with: " test " )
1514
+ && testMethodSymbol. roles. contains ( . definition)
1515
+ }
1516
+ return xctestSubclasses + testMethods
1517
+ }
1518
+ return testSymbols. map ( WorkspaceSymbolItem . init)
1519
+ }
1520
+
1520
1521
/// Forwards a SymbolInfoRequest to the appropriate toolchain service for this document.
1521
1522
func symbolInfo(
1522
1523
_ req: SymbolInfoRequest ,
@@ -2213,3 +2214,27 @@ fileprivate struct DocumentNotificationRequestQueue {
2213
2214
queue = [ ]
2214
2215
}
2215
2216
}
2217
+ fileprivate extension WorkspaceSymbolItem {
2218
+ init ( _ symbolOccurrence: SymbolOccurrence ) {
2219
+ let symbolPosition = Position (
2220
+ line: symbolOccurrence. location. line - 1 , // 1-based -> 0-based
2221
+ // FIXME: we need to convert the utf8/utf16 column, which may require reading the file!
2222
+ utf16index: symbolOccurrence. location. utf8Column - 1
2223
+ )
2224
+
2225
+ let symbolLocation = Location (
2226
+ uri: DocumentURI ( URL ( fileURLWithPath: symbolOccurrence. location. path) ) ,
2227
+ range: Range ( symbolPosition)
2228
+ )
2229
+
2230
+ self = . symbolInformation(
2231
+ SymbolInformation (
2232
+ name: symbolOccurrence. symbol. name,
2233
+ kind: symbolOccurrence. symbol. kind. asLspSymbolKind ( ) ,
2234
+ deprecated: nil ,
2235
+ location: symbolLocation,
2236
+ containerName: symbolOccurrence. getContainerName ( )
2237
+ )
2238
+ )
2239
+ }
2240
+ }
0 commit comments