Skip to content

Commit 677487b

Browse files
authored
Merge pull request #1390 from ahoppen/6.0/re-apply-1227
2 parents d69b762 + 38e2d01 commit 677487b

File tree

6 files changed

+509
-74
lines changed

6 files changed

+509
-74
lines changed

Sources/SourceKitLSP/LanguageService.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -200,7 +200,7 @@ public protocol LanguageService: AnyObject, Sendable {
200200
/// This is used as a fallback to show the test cases in a file if the index for a given file is not up-to-date.
201201
///
202202
/// A return value of `nil` indicates that this language service does not support syntactic test discovery.
203-
func syntacticDocumentTests(for uri: DocumentURI, in workspace: Workspace) async throws -> [TestItem]?
203+
func syntacticDocumentTests(for uri: DocumentURI, in workspace: Workspace) async throws -> [AnnotatedTestItem]?
204204

205205
/// Crash the language server. Should be used for crash recovery testing only.
206206
func _crash() async

Sources/SourceKitLSP/Swift/SwiftTestingScanner.swift

Lines changed: 35 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -177,9 +177,13 @@ final class SyntacticSwiftTestingTestScanner: SyntaxVisitor {
177177
private let parentTypeNames: [String]
178178

179179
/// The discovered test items.
180-
private var result: [TestItem] = []
180+
private var result: [AnnotatedTestItem] = []
181181

182-
private init(snapshot: DocumentSnapshot, allTestsDisabled: Bool, parentTypeNames: [String]) {
182+
private init(
183+
snapshot: DocumentSnapshot,
184+
allTestsDisabled: Bool,
185+
parentTypeNames: [String]
186+
) {
183187
self.snapshot = snapshot
184188
self.allTestsDisabled = allTestsDisabled
185189
self.parentTypeNames = parentTypeNames
@@ -190,7 +194,7 @@ final class SyntacticSwiftTestingTestScanner: SyntaxVisitor {
190194
public static func findTestSymbols(
191195
in snapshot: DocumentSnapshot,
192196
syntaxTreeManager: SyntaxTreeManager
193-
) async -> [TestItem] {
197+
) async -> [AnnotatedTestItem] {
194198
guard snapshot.text.contains("Suite") || snapshot.text.contains("Test") else {
195199
// If the file contains swift-testing tests, it must contain a `@Suite` or `@Test` attribute.
196200
// Only check for the attribute name because the attribute may be module qualified and contain an arbitrary amount
@@ -199,7 +203,11 @@ final class SyntacticSwiftTestingTestScanner: SyntaxVisitor {
199203
return []
200204
}
201205
let syntaxTree = await syntaxTreeManager.syntaxTree(for: snapshot)
202-
let visitor = SyntacticSwiftTestingTestScanner(snapshot: snapshot, allTestsDisabled: false, parentTypeNames: [])
206+
let visitor = SyntacticSwiftTestingTestScanner(
207+
snapshot: snapshot,
208+
allTestsDisabled: false,
209+
parentTypeNames: []
210+
)
203211
visitor.walk(syntaxTree)
204212
return visitor.result
205213
}
@@ -241,14 +249,18 @@ final class SyntacticSwiftTestingTestScanner: SyntaxVisitor {
241249
}
242250

243251
let range = snapshot.range(of: node.positionAfterSkippingLeadingTrivia..<node.endPositionBeforeTrailingTrivia)
244-
let testItem = TestItem(
245-
id: (parentTypeNames + typeNames).joined(separator: "/"),
246-
label: attributeData?.displayName ?? typeNames.last!,
247-
disabled: (attributeData?.isDisabled ?? false) || allTestsDisabled,
248-
style: TestStyle.swiftTesting,
249-
location: Location(uri: snapshot.uri, range: range),
250-
children: memberScanner.result,
251-
tags: attributeData?.tags.map(TestTag.init(id:)) ?? []
252+
// Members won't be extensions since extensions will only be at the top level.
253+
let testItem = AnnotatedTestItem(
254+
testItem: TestItem(
255+
id: (parentTypeNames + typeNames).joined(separator: "/"),
256+
label: attributeData?.displayName ?? typeNames.last!,
257+
disabled: (attributeData?.isDisabled ?? false) || allTestsDisabled,
258+
style: TestStyle.swiftTesting,
259+
location: Location(uri: snapshot.uri, range: range),
260+
children: memberScanner.result.map(\.testItem),
261+
tags: attributeData?.tags.map(TestTag.init(id:)) ?? []
262+
),
263+
isExtension: node.is(ExtensionDeclSyntax.self)
252264
)
253265
result.append(testItem)
254266
return .skipChildren
@@ -295,14 +307,17 @@ final class SyntacticSwiftTestingTestScanner: SyntaxVisitor {
295307
node.name.text + "(" + node.signature.parameterClause.parameters.map { "\($0.firstName.text):" }.joined() + ")"
296308

297309
let range = snapshot.range(of: node.positionAfterSkippingLeadingTrivia..<node.endPositionBeforeTrailingTrivia)
298-
let testItem = TestItem(
299-
id: (parentTypeNames + [name]).joined(separator: "/"),
300-
label: attributeData.displayName ?? name,
301-
disabled: attributeData.isDisabled || allTestsDisabled,
302-
style: TestStyle.swiftTesting,
303-
location: Location(uri: snapshot.uri, range: range),
304-
children: [],
305-
tags: attributeData.tags.map(TestTag.init(id:))
310+
let testItem = AnnotatedTestItem(
311+
testItem: TestItem(
312+
id: (parentTypeNames + [name]).joined(separator: "/"),
313+
label: attributeData.displayName ?? name,
314+
disabled: attributeData.isDisabled || allTestsDisabled,
315+
style: TestStyle.swiftTesting,
316+
location: Location(uri: snapshot.uri, range: range),
317+
children: [],
318+
tags: attributeData.tags.map(TestTag.init(id:))
319+
),
320+
isExtension: false
306321
)
307322
result.append(testItem)
308323
return .visitChildren

Sources/SourceKitLSP/Swift/SyntacticTestIndex.swift

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ fileprivate enum TaskMetadata: DependencyTracker, Equatable {
5151
/// Data from a syntactic scan of a source file for tests.
5252
fileprivate struct IndexedTests {
5353
/// The tests within the source file.
54-
let tests: [TestItem]
54+
let tests: [AnnotatedTestItem]
5555

5656
/// The modification date of the source file when it was scanned. A file won't get re-scanned if its modification date
5757
/// is older or the same as this date.
@@ -63,7 +63,7 @@ fileprivate struct IndexedTests {
6363
/// Does not write the results to the index.
6464
///
6565
/// The order of the returned tests is not defined. The results should be sorted before being returned to the editor.
66-
fileprivate func testItems(in url: URL) async -> [TestItem] {
66+
fileprivate func testItems(in url: URL) async -> [AnnotatedTestItem] {
6767
guard url.pathExtension == "swift" else {
6868
return []
6969
}
@@ -79,6 +79,7 @@ fileprivate func testItems(in url: URL) async -> [TestItem] {
7979
syntaxTreeManager: syntaxTreeManager
8080
)
8181
async let xcTests = SyntacticSwiftXCTestScanner.findTestSymbols(in: snapshot, syntaxTreeManager: syntaxTreeManager)
82+
8283
return await swiftTestingTests + xcTests
8384
}
8485

@@ -206,7 +207,7 @@ actor SyntacticTestIndex {
206207
/// Gets all the tests in the syntactic index.
207208
///
208209
/// This waits for any pending document updates to be indexed before returning a result.
209-
nonisolated func tests() async -> [TestItem] {
210+
nonisolated func tests() async -> [AnnotatedTestItem] {
210211
let readTask = indexingQueue.async(metadata: .read) {
211212
return await self.indexedTests.values.flatMap { $0.tests }
212213
}

0 commit comments

Comments
 (0)