File tree Expand file tree Collapse file tree 6 files changed +118
-0
lines changed
Sources/UnusedImportFixtures Expand file tree Collapse file tree 6 files changed +118
-0
lines changed Original file line number Diff line number Diff line change @@ -17,6 +17,33 @@ var targets: [PackageDescription.Target] = [
1717 . target(
1818 name: " CrossModuleRetentionSupportFixtures "
1919 ) ,
20+ . target(
21+ name: " UnusedImportFixtureA " ,
22+ path: " Sources/UnusedImportFixtures/A "
23+ ) ,
24+ . target(
25+ name: " UnusedImportFixtureB " ,
26+ dependencies: [
27+ . target( name: " UnusedImportFixtureA " )
28+ ] ,
29+ path: " Sources/UnusedImportFixtures/B "
30+ ) ,
31+ . target(
32+ name: " UnusedImportFixtureC " ,
33+ dependencies: [
34+ . target( name: " UnusedImportFixtureA " )
35+ ] ,
36+ path: " Sources/UnusedImportFixtures/C "
37+ ) ,
38+ . target(
39+ name: " UnusedImportFixtureD " ,
40+ dependencies: [
41+ . target( name: " UnusedImportFixtureA " ) ,
42+ . target( name: " UnusedImportFixtureB " ) ,
43+ . target( name: " UnusedImportFixtureC " )
44+ ] ,
45+ path: " Sources/UnusedImportFixtures/D "
46+ ) ,
2047 . target(
2148 name: " RetentionFixtures " ,
2249 dependencies: [
Original file line number Diff line number Diff line change 1+ // Module A: Defines the base class and protocol
2+
3+ public protocol ConformanceProtocol {
4+ var conformanceProperty : Int { get }
5+ }
6+
7+ public class ConformanceClass {
8+ public init ( ) { }
9+ }
10+
Original file line number Diff line number Diff line change 1+ // Module B: Provides conformance for ConformanceClass to ConformanceProtocol
2+ // This module's import should NOT be flagged as unused when the conformance is used
3+
4+ import UnusedImportFixtureA
5+
6+ extension ConformanceClass : ConformanceProtocol {
7+ public var conformanceProperty : Int { 42 }
8+ }
9+
Original file line number Diff line number Diff line change 1+ // Module C: Provides the function that accepts ConformanceProtocol
2+
3+ import UnusedImportFixtureA
4+
5+ /// A function that accepts a ConformanceProtocol conforming type
6+ public func acceptConformingType( _ value: ConformanceProtocol ) -> Int {
7+ value. conformanceProperty
8+ }
9+
Original file line number Diff line number Diff line change 1+ // Module D: Unused import false-positive for module that provides a conformance
2+ //
3+ // This file imports:
4+ // - UnusedImportFixtureA: provides ConformanceClass and ConformanceProtocol
5+ // - UnusedImportFixtureB: provides ConformanceClass: ConformanceProtocol conformance
6+ // - UnusedImportFixtureC: provides acceptConformingType(_:)
7+ //
8+ // Module B's import is required because it provides the conformance, but no declarations from it
9+ // are directly referenced. Without this import, the call would fail to compile.
10+ //
11+ // The import should NOT be flagged as unused.
12+
13+ import UnusedImportFixtureA // Module A: type definitions
14+ import UnusedImportFixtureB // Module B: conformance (no direct references!)
15+ import UnusedImportFixtureC // Module C: function accepting protocol
16+
17+ // periphery:ignore
18+ public class UnusedImportConformanceTestRetainer {
19+ public func use( ) {
20+ // This call requires ConformanceClass to conform to ConformanceProtocol.
21+ // - ConformanceClass comes from Module A
22+ // - acceptConformingType comes from Module C
23+ // - The conformance is provided by Module B (no symbols directly referenced from B!)
24+ _ = acceptConformingType ( ConformanceClass ( ) )
25+ }
26+ }
27+
Original file line number Diff line number Diff line change 1+ import Configuration
2+ import SystemPackage
3+ @testable import TestShared
4+
5+ /// Tests for unused import detection.
6+ final class UnusedImportTest : SPMSourceGraphTestCase {
7+ override static func setUp( ) {
8+ super. setUp ( )
9+
10+ build ( projectPath: FixturesProjectPath)
11+ index ( configuration: Configuration ( ) )
12+ }
13+
14+ func testUnusedImportFalsePositiveForConformanceProvider( ) {
15+ // Module D imports A, B, C where:
16+ // - A provides ConformanceClass and ConformanceProtocol
17+ // - B provides the conformance (no direct references!)
18+ // - C provides acceptConformingType function
19+ //
20+ // Module B's import should NOT be flagged as unused since it provides the conformance.
21+ module ( " UnusedImportFixtureD " ) {
22+ self . assertReferenced ( . module( " UnusedImportFixtureA " ) )
23+ self . assertReferenced ( . module( " UnusedImportFixtureB " ) )
24+ self . assertReferenced ( . module( " UnusedImportFixtureC " ) )
25+ }
26+
27+ module ( " UnusedImportFixtureA " ) {
28+ self . assertReferenced ( . class( " ConformanceClass " ) )
29+ self . assertReferenced ( . protocol( " ConformanceProtocol " ) )
30+ }
31+
32+ module ( " UnusedImportFixtureC " ) {
33+ self . assertReferenced ( . functionFree( " acceptConformingType(_:) " ) )
34+ }
35+ }
36+ }
You can’t perform that action at this time.
0 commit comments