@@ -21,22 +21,6 @@ public enum TestStyle {
21
21
public static let swiftTesting = " swift-testing "
22
22
}
23
23
24
- public struct AnnotatedTestItem : Sendable {
25
- /// The test item to be annotated
26
- public var testItem : TestItem
27
-
28
- /// Whether the `TestItem` is an extension.
29
- public var isExtension : Bool
30
-
31
- public init (
32
- testItem: TestItem ,
33
- isExtension: Bool
34
- ) {
35
- self . testItem = testItem
36
- self . isExtension = isExtension
37
- }
38
- }
39
-
40
24
fileprivate extension SymbolOccurrence {
41
25
/// Assuming that this is a symbol occurrence returned by the index, return whether it can constitute the definition
42
26
/// of a test case.
@@ -352,117 +336,6 @@ extension SourceKitLSPServer {
352
336
}
353
337
}
354
338
355
- /// Scans a source file for `XCTestCase` classes and test methods.
356
- ///
357
- /// The syntax visitor scans from class and extension declarations that could be `XCTestCase` classes or extensions
358
- /// thereof. It then calls into `findTestMethods` to find the actual test methods.
359
- final class SyntacticSwiftXCTestScanner : SyntaxVisitor {
360
- /// The document snapshot of the syntax tree that is being walked.
361
- private var snapshot : DocumentSnapshot
362
-
363
- /// The workspace symbols representing the found `XCTestCase` subclasses and test methods.
364
- private var result : [ AnnotatedTestItem ] = [ ]
365
-
366
- private init ( snapshot: DocumentSnapshot ) {
367
- self . snapshot = snapshot
368
- super. init ( viewMode: . fixedUp)
369
- }
370
-
371
- public static func findTestSymbols(
372
- in snapshot: DocumentSnapshot ,
373
- syntaxTreeManager: SyntaxTreeManager
374
- ) async -> [ AnnotatedTestItem ] {
375
- guard snapshot. text. contains ( " XCTestCase " ) || snapshot. text. contains ( " test " ) else {
376
- // If the file contains tests that can be discovered syntactically, it needs to have a class inheriting from
377
- // `XCTestCase` or a function starting with `test`.
378
- // This is intended to filter out files that obviously do not contain tests.
379
- return [ ]
380
- }
381
- let syntaxTree = await syntaxTreeManager. syntaxTree ( for: snapshot)
382
- let visitor = SyntacticSwiftXCTestScanner ( snapshot: snapshot)
383
- visitor. walk ( syntaxTree)
384
- return visitor. result
385
- }
386
-
387
- private func findTestMethods( in members: MemberBlockItemListSyntax , containerName: String ) -> [ TestItem ] {
388
- return members. compactMap { ( member) -> TestItem ? in
389
- guard let function = member. decl. as ( FunctionDeclSyntax . self) else {
390
- return nil
391
- }
392
- guard function. name. text. starts ( with: " test " ) else {
393
- return nil
394
- }
395
- guard function. modifiers. map ( \. name. tokenKind) . allSatisfy ( { $0 != . keyword( . static) && $0 != . keyword( . class) } )
396
- else {
397
- // Test methods can't be static.
398
- return nil
399
- }
400
- guard function. signature. returnClause == nil , function. signature. parameterClause. parameters. isEmpty else {
401
- // Test methods can't have a return type or have parameters.
402
- // Technically we are also filtering out functions that have an explicit `Void` return type here but such
403
- // declarations are probably less common than helper functions that start with `test` and have a return type.
404
- return nil
405
- }
406
- let range = snapshot. absolutePositionRange (
407
- of: function. positionAfterSkippingLeadingTrivia..< function. endPositionBeforeTrailingTrivia
408
- )
409
-
410
- return TestItem (
411
- id: " \( containerName) / \( function. name. text) () " ,
412
- label: " \( function. name. text) () " ,
413
- disabled: false ,
414
- style: TestStyle . xcTest,
415
- location: Location ( uri: snapshot. uri, range: range) ,
416
- children: [ ] ,
417
- tags: [ ]
418
- )
419
- }
420
- }
421
-
422
- override func visit( _ node: ClassDeclSyntax ) -> SyntaxVisitorContinueKind {
423
- guard let inheritedTypes = node. inheritanceClause? . inheritedTypes, let superclass = inheritedTypes. first else {
424
- // The class has no superclass and thus can't inherit from XCTestCase.
425
- // Continue scanning its children in case it has a nested subclass that inherits from XCTestCase.
426
- return . visitChildren
427
- }
428
- let superclassName = superclass. type. as ( IdentifierTypeSyntax . self) ? . name. text
429
- if superclassName == " NSObject " {
430
- // We know that the class can't be an subclass of `XCTestCase` so don't visit it.
431
- // We can't explicitly check for the `XCTestCase` superclass because the class might inherit from a class that in
432
- // turn inherits from `XCTestCase`. Resolving that inheritance hierarchy would be semantic.
433
- return . visitChildren
434
- }
435
- let testMethods = findTestMethods ( in: node. memberBlock. members, containerName: node. name. text)
436
- guard !testMethods. isEmpty || superclassName == " XCTestCase " else {
437
- // Don't report a test class if it doesn't contain any test methods.
438
- return . visitChildren
439
- }
440
- let range = snapshot. absolutePositionRange (
441
- of: node. positionAfterSkippingLeadingTrivia..< node. endPositionBeforeTrailingTrivia
442
- )
443
- let testItem = AnnotatedTestItem (
444
- testItem: TestItem (
445
- id: node. name. text,
446
- label: node. name. text,
447
- disabled: false ,
448
- style: TestStyle . xcTest,
449
- location: Location ( uri: snapshot. uri, range: range) ,
450
- children: testMethods,
451
- tags: [ ]
452
- ) ,
453
- isExtension: false
454
- )
455
- result. append ( testItem)
456
- return . visitChildren
457
- }
458
-
459
- override func visit( _ node: ExtensionDeclSyntax ) -> SyntaxVisitorContinueKind {
460
- result += findTestMethods ( in: node. memberBlock. members, containerName: node. extendedType. trimmedDescription)
461
- . map { AnnotatedTestItem ( testItem: $0, isExtension: true ) }
462
- return . visitChildren
463
- }
464
- }
465
-
466
339
extension TestItem {
467
340
/// Use out-of-date semantic information to filter syntactic symbols.
468
341
///
@@ -506,7 +379,7 @@ extension AnnotatedTestItem {
506
379
}
507
380
}
508
381
509
- extension Array < AnnotatedTestItem > {
382
+ fileprivate extension Array < AnnotatedTestItem > {
510
383
/// When the test scanners discover tests in extensions they are captured in their own parent `TestItem`, not the
511
384
/// `TestItem` generated from the class/struct's definition. This is largely because of the syntatic nature of the
512
385
/// test scanners as they are today, which only know about tests within the context of the current file. Extensions
0 commit comments