From 3cccff87d4c6d6a5f01380a61aac52554508bd35 Mon Sep 17 00:00:00 2001 From: Ian Leitch Date: Sat, 26 Apr 2025 13:40:34 +0200 Subject: [PATCH] Fix possible concurrent mutation crash --- CHANGELOG.md | 1 + Package.swift | 1 + Sources/Configuration/Configuration.swift | 39 +------- .../RedundantPublicAccessibilityTest.swift | 80 ++++++++-------- .../CrossModuleRetentionTest.swift | 3 +- Tests/PeripheryTests/RetentionTest.swift | 95 ++++++++----------- Tests/SPMTests/SPMProjectTest.swift | 3 +- Tests/Shared/FixtureSourceGraphTestCase.swift | 21 +++- Tests/Shared/SPMSourceGraphTestCase.swift | 3 +- Tests/Shared/SourceGraphTestCase.swift | 18 ++-- Tests/XcodeTests/SwiftUIProjectTest.swift | 6 +- Tests/XcodeTests/UIKitProjectTest.swift | 6 +- .../XcodeTests/XcodeSourceGraphTestCase.swift | 3 +- baselines/linux.json | 2 +- 14 files changed, 130 insertions(+), 151 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 587dd43f2..2dd6e3211 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -25,6 +25,7 @@ - Fix inconsistent unused parameter results when the function is declared in a file that is a member of multiple targets. - Fix inconsistent results caused by identical extensions declared in different modules. - Static `@_dynamicReplacement` members are now retained. +- Fix possible concurrent mutation crash when accessing filename matching configuration options. ## 3.1.0 (2025-04-05) diff --git a/Package.swift b/Package.swift index 8644dac92..35e9da443 100644 --- a/Package.swift +++ b/Package.swift @@ -120,6 +120,7 @@ var targets: [PackageDescription.Target] = [ dependencies: [ .target(name: "PeripheryKit"), .target(name: "ProjectDrivers"), + .target(name: "Configuration"), ], path: "Tests/Shared" ), diff --git a/Sources/Configuration/Configuration.swift b/Sources/Configuration/Configuration.swift index 328ed8620..c900b79ac 100644 --- a/Sources/Configuration/Configuration.swift +++ b/Sources/Configuration/Configuration.swift @@ -172,10 +172,6 @@ public final class Configuration { } } - public func reset() { - settings.forEach { $0.reset() } - } - // MARK: - Helpers public func apply(_ path: KeyPath>, _ value: T) { @@ -186,35 +182,9 @@ public final class Configuration { } } - private var _indexExcludeMatchers: [FilenameMatcher]? - public var indexExcludeMatchers: [FilenameMatcher] { - if let _indexExcludeMatchers { - return _indexExcludeMatchers - } - - let matchers = buildFilenameMatchers(with: indexExclude) - _indexExcludeMatchers = matchers - return matchers - } - - private var _retainFilesMatchers: [FilenameMatcher]? - public var retainFilesMatchers: [FilenameMatcher] { - if let _retainFilesMatchers { - return _retainFilesMatchers - } - - let matchers = buildFilenameMatchers(with: retainFiles) - _retainFilesMatchers = matchers - return matchers - } - - public func resetMatchers() { - _indexExcludeMatchers = nil - _retainFilesMatchers = nil - } - + public lazy var indexExcludeMatchers: [FilenameMatcher] = buildFilenameMatchers(with: indexExclude) + public lazy var retainFilesMatchers: [FilenameMatcher] = buildFilenameMatchers(with: retainFiles) public lazy var reportExcludeMatchers: [FilenameMatcher] = buildFilenameMatchers(with: reportExclude) - public lazy var reportIncludeMatchers: [FilenameMatcher] = buildFilenameMatchers(with: reportInclude) // MARK: - Private @@ -255,7 +225,6 @@ protocol AbstractSetting { var hasNonDefaultValue: Bool { get } var wrappedValue: Value { get } - func reset() func assign(_ value: Any) } @@ -293,10 +262,6 @@ protocol AbstractSetting { public func assign(_ newValue: Any) { value = setter(newValue) ?? defaultValue } - - func reset() { - wrappedValue = defaultValue - } } private let filePathSetter: (Any) -> FilePath? = { value in diff --git a/Tests/AccessibilityTests/RedundantPublicAccessibilityTest.swift b/Tests/AccessibilityTests/RedundantPublicAccessibilityTest.swift index 61b0316db..5999430de 100644 --- a/Tests/AccessibilityTests/RedundantPublicAccessibilityTest.swift +++ b/Tests/AccessibilityTests/RedundantPublicAccessibilityTest.swift @@ -1,3 +1,4 @@ +import Configuration @testable import TestShared import XCTest @@ -9,7 +10,7 @@ class RedundantPublicAccessibilityTest: SPMSourceGraphTestCase { } func testRedundantPublicType() { - Self.index() + index() assertRedundantPublicAccessibility(.class("RedundantPublicType")) { self.assertRedundantPublicAccessibility(.functionMethodInstance("redundantPublicFunction()")) @@ -17,7 +18,7 @@ class RedundantPublicAccessibilityTest: SPMSourceGraphTestCase { } func testPublicDeclarationInInternalParent() { - Self.index() + index() assertNotRedundantPublicAccessibility(.class("PublicDeclarationInInternalParent")) { self.assertRedundantPublicAccessibility(.functionMethodInstance("somePublicFunc()")) @@ -25,14 +26,14 @@ class RedundantPublicAccessibilityTest: SPMSourceGraphTestCase { } func testPublicExtensionOnRedundantPublicKind() { - Self.index() + index() assertRedundantPublicAccessibility(.class("PublicExtensionOnRedundantPublicKind")) assertRedundantPublicAccessibility(.extensionClass("PublicExtensionOnRedundantPublicKind")) } func testPublicTypeUsedAsPublicPropertyType() { - Self.index() + index() assertNotRedundantPublicAccessibility(.class("PublicTypeUsedAsPublicPropertyType1")) assertNotRedundantPublicAccessibility(.class("PublicTypeUsedAsPublicPropertyType2")) @@ -44,20 +45,20 @@ class RedundantPublicAccessibilityTest: SPMSourceGraphTestCase { } func testPublicTypeUsedAsPublicPropertyInitializer() { - Self.index() + index() assertNotRedundantPublicAccessibility(.struct("PublicTypeUsedAsPublicPropertyInitializer_Simple")) assertNotRedundantPublicAccessibility(.struct("PublicTypeUsedAsPublicPropertyInitializer_GenericParameter")) } func testPublicTypeUsedAsPublicInitializerParameterType() { - Self.index() + index() assertNotRedundantPublicAccessibility(.class("PublicTypeUsedAsPublicInitializerParameterType")) } func testPublicTypeUsedAsPublicFunctionParameterType() { - Self.index() + index() assertNotRedundantPublicAccessibility(.class("PublicTypeUsedAsPublicFunctionParameterType")) assertNotRedundantPublicAccessibility(.class("PublicTypeUsedAsPublicFunctionParameterTypeClosureArgument")) @@ -65,7 +66,7 @@ class RedundantPublicAccessibilityTest: SPMSourceGraphTestCase { } func testPublicTypeUsedAsPublicFunctionParameterDefaultValue() { - Self.index() + index() assertNotRedundantPublicAccessibility(.struct("PublicTypeUsedAsPublicFunctionParameterDefaultValue")) { self.assertNotRedundantPublicAccessibility(.varStatic("somePublicValue")) @@ -73,7 +74,7 @@ class RedundantPublicAccessibilityTest: SPMSourceGraphTestCase { } func testPublicTypeUsedAsPublicFunctionReturnType() { - Self.index() + index() assertNotRedundantPublicAccessibility(.class("PublicTypeUsedAsPublicFunctionReturnType")) assertNotRedundantPublicAccessibility(.class("PublicTypeUsedAsPublicFunctionReturnTypeClosureArgument")) @@ -81,38 +82,38 @@ class RedundantPublicAccessibilityTest: SPMSourceGraphTestCase { } func testPublicTypeUsedAsPublicSubscriptParameterType() { - Self.index() + index() assertNotRedundantPublicAccessibility(.class("PublicTypeUsedAsPublicSubscriptParameterType")) } func testPublicTypeUsedAsPublicSubscriptReturnType() { - Self.index() + index() assertNotRedundantPublicAccessibility(.class("PublicTypeUsedAsPublicSubscriptReturnType")) } func testPublicTypeUsedInPublicFunctionBody() { - Self.index() + index() assertRedundantPublicAccessibility(.class("PublicTypeUsedInPublicFunctionBody")) } func testPublicClassInheritingPublicClass() { - Self.index() + index() assertNotRedundantPublicAccessibility(.class("PublicClassInheritingPublicClass_Superclass")) assertNotRedundantPublicAccessibility(.class("PublicClassInheritingPublicClass")) } func testPublicClassInheritingPublicExternalClass() { - Self.index() + index() assertRedundantPublicAccessibility(.class("PublicClassInheritingPublicExternalClass")) } func testPublicClassInheritingPublicClassWithGenericRequirement() { - Self.index() + index() assertNotRedundantPublicAccessibility(.struct("PublicClassInheritingPublicClassWithGenericParameter_GenericType")) assertNotRedundantPublicAccessibility(.class("PublicClassInheritingPublicClassWithGenericParameter_Superclass")) @@ -120,7 +121,7 @@ class RedundantPublicAccessibilityTest: SPMSourceGraphTestCase { } func testPublicClassAdoptingPublicProtocol() { - Self.index() + index() assertRedundantPublicAccessibility(.protocol("PublicClassAdoptingPublicProtocol_Protocol")) assertNotRedundantPublicAccessibility(.class("PublicClassAdoptingPublicProtocol")) @@ -128,8 +129,9 @@ class RedundantPublicAccessibilityTest: SPMSourceGraphTestCase { #if os(macOS) func testPublicClassAdoptingExternalProtocolObjcAccessible() { + let configuration = Configuration() configuration.retainObjcAccessible = true - Self.index() + Self.index(configuration: configuration) assertNotRedundantPublicAccessibility(.class("PublicClassAdoptingExternalProtocolObjcAccessible")) { self.assertNotRedundantPublicAccessibility(.functionMethodInstance("someExternalProtocolMethod()")) @@ -138,39 +140,39 @@ class RedundantPublicAccessibilityTest: SPMSourceGraphTestCase { #endif func testPublicClassAdoptingInternalProtocol() { - Self.index() + index() assertNotRedundantPublicAccessibility(.class("PublicClassAdoptingInternalProtocol")) } func testInternalClassAdoptingPublicProtocol() { - Self.index() + index() assertRedundantPublicAccessibility(.protocol("InternalClassAdoptingPublicProtocol_Protocol")) } func testPublicProtocolRefiningPublicProtocol() { - Self.index() + index() assertNotRedundantPublicAccessibility(.protocol("PublicProtocolRefiningPublicProtocol_Refined")) assertNotRedundantPublicAccessibility(.protocol("PublicProtocolRefiningPublicProtocol")) } func testInternalProtocolRefiningPublicProtocol() { - Self.index() + index() assertRedundantPublicAccessibility(.protocol("InternalProtocolRefiningPublicProtocol_Refined")) } func testIgnoreCommentCommands() { - Self.index() + index() assertNotRedundantPublicAccessibility(.class("IgnoreCommentCommand")) assertNotRedundantPublicAccessibility(.class("IgnoreAllCommentCommand")) } func testTestableImport() { - Self.index() + index() assertRedundantPublicAccessibility(.class("RedundantPublicTestableImportClass")) { self.assertRedundantPublicAccessibility(.varInstance("testableProperty")) @@ -179,33 +181,33 @@ class RedundantPublicAccessibilityTest: SPMSourceGraphTestCase { } func testFunctionGenericParameter() { - Self.index() + index() assertNotRedundantPublicAccessibility(.protocol("PublicTypeUsedAsPublicFunctionGenericParameter_ProtocolA")) assertNotRedundantPublicAccessibility(.protocol("PublicTypeUsedAsPublicFunctionGenericParameter_ProtocolB")) } func testFunctionGenericRequirement() { - Self.index() + index() assertNotRedundantPublicAccessibility(.protocol("PublicTypeUsedAsPublicFunctionGenericRequirement_Protocol")) } func testGenericClassParameter() { - Self.index() + index() assertNotRedundantPublicAccessibility(.protocol("PublicTypeUsedAsPublicClassGenericParameter_ProtocolA")) assertNotRedundantPublicAccessibility(.protocol("PublicTypeUsedAsPublicClassGenericParameter_ProtocolB")) } func testClassGenericRequirement() { - Self.index() + index() assertNotRedundantPublicAccessibility(.protocol("PublicTypeUsedAsPublicClassGenericRequirement_Protocol")) } func testEnumAssociatedValue() { - Self.index() + index() assertNotRedundantPublicAccessibility(.enum("PublicEnumWithAssociatedValue")) assertNotRedundantPublicAccessibility(.struct("PublicAssociatedValueA")) { @@ -217,7 +219,7 @@ class RedundantPublicAccessibilityTest: SPMSourceGraphTestCase { } func testEnumCaseWithParameter() { - Self.index() + index() assertNotRedundantPublicAccessibility(.class("PublicEnumCaseWithParameter_ParameterType")) assertNotRedundantPublicAccessibility(.class("PublicEnumCaseWithParameter_ParameterType_Outer")) { @@ -227,21 +229,21 @@ class RedundantPublicAccessibilityTest: SPMSourceGraphTestCase { } func testTypealiasWithClosureType() { - Self.index() + index() assertNotRedundantPublicAccessibility(.typealias("PublicTypealiasWithClosureType")) assertNotRedundantPublicAccessibility(.struct("PublicTypealiasStruct")) } func testPublicTypeUsedInPublicClosure() { - Self.index() + index() assertNotRedundantPublicAccessibility(.class("PublicTypeUsedInPublicClosureReturnType")) assertNotRedundantPublicAccessibility(.class("PublicTypeUsedInPublicClosureInputType")) } func testFunctionMetatypeParameterUsedAsGenericReturnType() { - Self.index() + index() assertNotRedundantPublicAccessibility(.protocol("PublicTypeUsedAsPublicFunctionMetatypeParameterWithGenericReturnType1")) assertNotRedundantPublicAccessibility(.protocol("PublicTypeUsedAsPublicFunctionMetatypeParameterWithGenericReturnType2")) @@ -275,7 +277,7 @@ class RedundantPublicAccessibilityTest: SPMSourceGraphTestCase { /// cls.someExtensionFunc() /// func testPublicProtocolIndirectlyReferencedByExtensionMember() { - Self.index() + index() assertNotRedundantPublicAccessibility(.protocol("ProtocolIndirectlyReferencedCrossModuleByExtensionMember")) assertNotRedundantPublicAccessibility(.extensionProtocol("ProtocolIndirectlyReferencedCrossModuleByExtensionMember")) { @@ -284,7 +286,7 @@ class RedundantPublicAccessibilityTest: SPMSourceGraphTestCase { } func testPublicActor() { - Self.index() + index() assertNotRedundantPublicAccessibility(.class("PublicActor")) { self.assertNotRedundantPublicAccessibility(.functionMethodInstance("someFunc()")) @@ -292,7 +294,7 @@ class RedundantPublicAccessibilityTest: SPMSourceGraphTestCase { } func testPublicWrappedProperty() { - Self.index() + index() assertNotRedundantPublicAccessibility(.struct("PublicWrapper")) { self.assertNotRedundantPublicAccessibility(.varInstance("wrappedValue")) @@ -305,26 +307,26 @@ class RedundantPublicAccessibilityTest: SPMSourceGraphTestCase { } func testPublicInlinableFunction() { - Self.index() + index() assertNotRedundantPublicAccessibility(.class("ClassReferencedFromPublicInlinableFunction")) assertNotRedundantPublicAccessibility(.class("ClassReferencedFromPublicInlinableFunction_UsableFromInline")) } func testPublicInheritedAssociatedType() { - Self.index() + index() assertNotRedundantPublicAccessibility(.protocol("PublicInheritedAssociatedType")) } func testPublicAssociatedTypeDefaultType() { - Self.index() + index() assertNotRedundantPublicAccessibility(.protocol("PublicInheritedAssociatedTypeDefaultType")) } func testPublicComparableOperatorFunction() { - Self.index() + index() assertNotRedundantPublicAccessibility(.functionOperatorInfix("<(_:_:)")) assertNotRedundantPublicAccessibility(.functionOperatorInfix("==(_:_:)")) diff --git a/Tests/PeripheryTests/CrossModuleRetentionTest.swift b/Tests/PeripheryTests/CrossModuleRetentionTest.swift index 3ce66115e..b9c28f925 100644 --- a/Tests/PeripheryTests/CrossModuleRetentionTest.swift +++ b/Tests/PeripheryTests/CrossModuleRetentionTest.swift @@ -1,3 +1,4 @@ +import Configuration import SystemPackage @testable import TestShared @@ -6,7 +7,7 @@ final class CrossModuleRetentionTest: SPMSourceGraphTestCase { super.setUp() build(projectPath: FixturesProjectPath) - index() + index(configuration: Configuration()) } func testCrossModuleInheritanceWithSameName() { diff --git a/Tests/PeripheryTests/RetentionTest.swift b/Tests/PeripheryTests/RetentionTest.swift index af256584c..2339629a9 100644 --- a/Tests/PeripheryTests/RetentionTest.swift +++ b/Tests/PeripheryTests/RetentionTest.swift @@ -442,9 +442,7 @@ final class RetentionTest: FixtureSourceGraphTestCase { } func testExternalXCTestCaseClass() { - configuration.externalTestCaseClasses = ["ExternalTestCase"] - - analyze { + analyze(externalTestCaseClasses: ["ExternalTestCase"]) { assertReferenced(.class("FixtureClass217")) { self.assertReferenced(.functionMethodInstance("testSomeTestCase()")) } @@ -506,9 +504,7 @@ final class RetentionTest: FixtureSourceGraphTestCase { } func testFunctionAccessorsRetainReferences() { - configuration.retainAssignOnlyProperties = true - - analyze(retainPublic: true) { + analyze(retainPublic: true, retainAssignOnlyProperties: true) { assertReferenced(.class("FixtureClass63")) { self.assertReferenced(.varInstance("referencedByGetter")) self.assertReferenced(.varInstance("referencedBySetter")) @@ -539,9 +535,7 @@ final class RetentionTest: FixtureSourceGraphTestCase { } func testInstanceVarReferencedInClosure() { - configuration.retainAssignOnlyProperties = true - - analyze(retainPublic: true) { + analyze(retainPublic: true, retainAssignOnlyProperties: true) { assertReferenced(.class("FixtureClass69")) { self.assertReferenced(.varInstance("someVar")) } @@ -549,11 +543,12 @@ final class RetentionTest: FixtureSourceGraphTestCase { } func testCodingKeyEnum() { - // CustomStringConvertible doesn't actually inherit Codable, we're just using it because we don't have an - // external module in which to declare our own type. - configuration.externalCodableProtocols = ["CustomStringConvertible"] - - analyze(retainPublic: true) { + analyze( + retainPublic: true, + // CustomStringConvertible doesn't actually inherit Codable, we're just using it because we don't have an + // external module in which to declare our own type. + externalCodableProtocols: ["CustomStringConvertible"] + ) { assertReferenced(.class("FixtureClass74")) { self.assertReferenced(.enum("CodingKeys")) } @@ -941,19 +936,21 @@ final class RetentionTest: FixtureSourceGraphTestCase { } func testRetainsCodableProperties() { - configuration.retainCodableProperties = false - configuration.retainAssignOnlyProperties = false - - analyze(retainPublic: true) { + analyze( + retainPublic: true, + retainCodableProperties: false, + retainAssignOnlyProperties: false + ) { assertReferenced(.struct("FixtureStruct14")) { self.assertNotReferenced(.functionConstructor("init(unused:)")) self.assertAssignOnlyProperty(.varInstance("unused")) } } - configuration.retainCodableProperties = true - - analyze(retainPublic: true) { + analyze( + retainPublic: true, + retainCodableProperties: true + ) { assertReferenced(.struct("FixtureStruct14")) { self.assertNotReferenced(.functionConstructor("init(unused:)")) self.assertReferenced(.varInstance("unused")) @@ -963,19 +960,21 @@ final class RetentionTest: FixtureSourceGraphTestCase { } func testRetainsEncodableProperties() { - configuration.retainEncodableProperties = false - configuration.retainAssignOnlyProperties = false - - analyze(retainPublic: true) { + analyze( + retainPublic: true, + retainEncodableProperties: false, + retainAssignOnlyProperties: false + ) { assertReferenced(.struct("FixtureStruct15")) { self.assertNotReferenced(.functionConstructor("init(unused:)")) self.assertAssignOnlyProperty(.varInstance("unused")) } } - configuration.retainEncodableProperties = true - - analyze(retainPublic: true) { + analyze( + retainPublic: true, + retainEncodableProperties: true + ) { assertReferenced(.struct("FixtureStruct15")) { self.assertNotReferenced(.functionConstructor("init(unused:)")) self.assertReferenced(.varInstance("unused")) @@ -985,15 +984,11 @@ final class RetentionTest: FixtureSourceGraphTestCase { } func testRetainsFilesOption() { - configuration.retainFiles = [testFixturePath.string] - - analyze { + analyze(retainFiles: [testFixturePath.string]) { assertReferenced(.class("FixtureClass100")) } - configuration.retainFiles = [] - - analyze { + analyze(retainFiles: []) { assertNotReferenced(.class("FixtureClass100")) } } @@ -1182,9 +1177,7 @@ final class RetentionTest: FixtureSourceGraphTestCase { // MARK: - Assign-only properties func testStructImplicitInitializer() { - configuration.retainAssignOnlyProperties = false - - analyze(retainPublic: true) { + analyze(retainPublic: true, retainAssignOnlyProperties: false) { assertReferenced(.struct("FixtureStruct13_Codable")) { self.assertAssignOnlyProperty(.varInstance("assignOnly")) } @@ -1194,9 +1187,7 @@ final class RetentionTest: FixtureSourceGraphTestCase { } } - configuration.retainAssignOnlyProperties = true - - analyze(retainPublic: true) { + analyze(retainPublic: true, retainAssignOnlyProperties: true) { assertReferenced(.struct("FixtureStruct13_Codable")) { self.assertReferenced(.varInstance("assignOnly")) self.assertNotAssignOnlyProperty(.varInstance("assignOnly")) @@ -1211,9 +1202,7 @@ final class RetentionTest: FixtureSourceGraphTestCase { } func testSimplePropertyAssignedButNeverRead() { - configuration.retainAssignOnlyProperties = false - - analyze(retainPublic: true) { + analyze(retainPublic: true, retainAssignOnlyProperties: false) { assertReferenced(.class("FixtureClass70")) { self.assertAssignOnlyProperty(.varInstance("simpleUnreadVar")) self.assertAssignOnlyProperty(.varInstance("simpleUnreadShadowedVar")) @@ -1234,9 +1223,7 @@ final class RetentionTest: FixtureSourceGraphTestCase { } } - configuration.retainAssignOnlyProperties = true - - analyze(retainPublic: true) { + analyze(retainPublic: true, retainAssignOnlyProperties: true) { assertReferenced(.class("FixtureClass70")) { self.assertReferenced(.varInstance("simpleUnreadVar")) self.assertNotAssignOnlyProperty(.varInstance("simpleUnreadVar")) @@ -1275,10 +1262,11 @@ final class RetentionTest: FixtureSourceGraphTestCase { } func testRetainsAssignOnlyPropertyTypes() { - configuration.retainAssignOnlyProperties = false - configuration.retainAssignOnlyPropertyTypes = ["CustomType", "(CustomType, String)", "Swift.Double"] - - analyze(retainPublic: true) { + analyze( + retainPublic: true, + retainAssignOnlyProperties: false, + retainAssignOnlyPropertyTypes: ["CustomType", "(CustomType, String)", "Swift.Double"] + ) { assertReferenced(.class("FixtureClass123")) { self.assertReferenced(.varInstance("retainedSimpleProperty")) self.assertNotAssignOnlyProperty(.varInstance("retainedSimpleProperty")) @@ -1459,9 +1447,10 @@ final class RetentionTest: FixtureSourceGraphTestCase { } func testRetainUnusedProtocolFuncParams() { - configuration.retainUnusedProtocolFuncParams = true - - analyze(retainPublic: true) { + analyze( + retainPublic: true, + retainUnusedProtocolFuncParams: true + ) { assertReferenced(.protocol("FixtureProtocol107")) { self.assertReferenced(.functionMethodInstance("myFunc(param:)")) { self.assertReferenced(.varParameter("param")) diff --git a/Tests/SPMTests/SPMProjectTest.swift b/Tests/SPMTests/SPMProjectTest.swift index 68cbc8c4b..511785522 100644 --- a/Tests/SPMTests/SPMProjectTest.swift +++ b/Tests/SPMTests/SPMProjectTest.swift @@ -1,3 +1,4 @@ +import Configuration @testable import TestShared import XCTest @@ -6,7 +7,7 @@ final class SPMProjectTest: SPMSourceGraphTestCase { super.setUp() build(projectPath: SPMProjectPath) - index() + index(configuration: Configuration()) } func testMainEntryFile() { diff --git a/Tests/Shared/FixtureSourceGraphTestCase.swift b/Tests/Shared/FixtureSourceGraphTestCase.swift index ccdaee13d..ca6fcb4d2 100644 --- a/Tests/Shared/FixtureSourceGraphTestCase.swift +++ b/Tests/Shared/FixtureSourceGraphTestCase.swift @@ -1,3 +1,4 @@ +import Configuration @testable import PeripheryKit import SystemPackage import XCTest @@ -15,20 +16,36 @@ class FixtureSourceGraphTestCase: SPMSourceGraphTestCase { retainObjcAccessible: Bool = false, retainObjcAnnotated: Bool = false, disableRedundantPublicAnalysis: Bool = false, + retainCodableProperties: Bool = false, + retainEncodableProperties: Bool = false, + retainUnusedProtocolFuncParams: Bool = false, + retainAssignOnlyProperties: Bool = false, + retainAssignOnlyPropertyTypes: [String] = [], + externalCodableProtocols: [String] = [], additionalFilesToIndex: [FilePath] = [], + externalTestCaseClasses: [String] = [], + retainFiles: [String] = [], testBlock: () throws -> Void ) rethrows -> [ScanResult] { + let configuration = Configuration() configuration.retainPublic = retainPublic configuration.retainObjcAccessible = retainObjcAccessible configuration.retainObjcAnnotated = retainObjcAnnotated + configuration.retainAssignOnlyProperties = retainAssignOnlyProperties configuration.disableRedundantPublicAnalysis = disableRedundantPublicAnalysis - configuration.resetMatchers() + configuration.externalCodableProtocols = externalCodableProtocols + configuration.retainCodableProperties = retainCodableProperties + configuration.retainEncodableProperties = retainEncodableProperties + configuration.retainUnusedProtocolFuncParams = retainUnusedProtocolFuncParams + configuration.retainAssignOnlyPropertyTypes = retainAssignOnlyPropertyTypes + configuration.externalTestCaseClasses = externalTestCaseClasses + configuration.retainFiles = retainFiles if !testFixturePath.exists { fatalError("\(testFixturePath.string) does not exist") } - Self.index(sourceFiles: [testFixturePath] + additionalFilesToIndex) + Self.index(sourceFiles: [testFixturePath] + additionalFilesToIndex, configuration: configuration) try testBlock() return Self.results } diff --git a/Tests/Shared/SPMSourceGraphTestCase.swift b/Tests/Shared/SPMSourceGraphTestCase.swift index f51069a33..df6f7b22a 100644 --- a/Tests/Shared/SPMSourceGraphTestCase.swift +++ b/Tests/Shared/SPMSourceGraphTestCase.swift @@ -1,9 +1,10 @@ +import Configuration import Foundation import ProjectDrivers import SystemPackage class SPMSourceGraphTestCase: SourceGraphTestCase { - static func build(projectPath: FilePath = ProjectRootPath) { + static func build(projectPath: FilePath = ProjectRootPath, configuration: Configuration = .init()) { projectPath.chdir { let driver = try! SPMProjectDriver(configuration: configuration, shell: shell, logger: logger) try! driver.build() diff --git a/Tests/Shared/SourceGraphTestCase.swift b/Tests/Shared/SourceGraphTestCase.swift index 18b81caa9..6cceed00e 100644 --- a/Tests/Shared/SourceGraphTestCase.swift +++ b/Tests/Shared/SourceGraphTestCase.swift @@ -9,7 +9,6 @@ import XCTest open class SourceGraphTestCase: XCTestCase { static var plan: IndexPlan! - static var configuration: Configuration! static var shell: Shell! static var logger: Logger! static var results: [ScanResult] = [] @@ -17,24 +16,17 @@ open class SourceGraphTestCase: XCTestCase { private static var graph: SourceGraph! private static var allIndexedDeclarations: Set = [] - var configuration: Configuration { Self.configuration } - private var scopeStack: [DeclarationScope] = [] override open class func setUp() { super.setUp() - configuration = Configuration() - configuration.quiet = true logger = Logger(quiet: true) shell = Shell(logger: logger) + let configuration = Configuration() + configuration.quiet = true graph = SourceGraph(configuration: configuration, logger: logger) } - override open func setUp() { - super.setUp() - configuration.reset() - } - override open func tearDown() { super.tearDown() @@ -45,7 +37,11 @@ open class SourceGraphTestCase: XCTestCase { } } - static func index(sourceFiles: [FilePath]? = nil) { + func index(sourceFiles: [FilePath]? = nil, configuration: Configuration = .init()) { + Self.index(sourceFiles: sourceFiles, configuration: configuration) + } + + static func index(sourceFiles: [FilePath]? = nil, configuration: Configuration) { var newPlan = plan! if let sourceFiles { diff --git a/Tests/XcodeTests/SwiftUIProjectTest.swift b/Tests/XcodeTests/SwiftUIProjectTest.swift index 5ffd96239..5b32bff75 100644 --- a/Tests/XcodeTests/SwiftUIProjectTest.swift +++ b/Tests/XcodeTests/SwiftUIProjectTest.swift @@ -1,13 +1,15 @@ +import Configuration @testable import TestShared final class SwiftUIProjectTest: XcodeSourceGraphTestCase { override static func setUp() { super.setUp() + let configuration = Configuration() configuration.schemes = ["SwiftUIProject"] - build(projectPath: SwiftUIProjectPath) - index() + build(projectPath: SwiftUIProjectPath, configuration: configuration) + index(configuration: configuration) } func testRetainsMainAppEntryPoint() { diff --git a/Tests/XcodeTests/UIKitProjectTest.swift b/Tests/XcodeTests/UIKitProjectTest.swift index 418753f93..842879d56 100644 --- a/Tests/XcodeTests/UIKitProjectTest.swift +++ b/Tests/XcodeTests/UIKitProjectTest.swift @@ -1,13 +1,15 @@ +import Configuration @testable import TestShared final class UIKitProjectTest: XcodeSourceGraphTestCase { override static func setUp() { super.setUp() + let configuration = Configuration() configuration.schemes = ["UIKitProject"] - build(projectPath: UIKitProjectPath) - index() + build(projectPath: UIKitProjectPath, configuration: configuration) + index(configuration: configuration) } func testRetainsMainAppEntryPoint() { diff --git a/Tests/XcodeTests/XcodeSourceGraphTestCase.swift b/Tests/XcodeTests/XcodeSourceGraphTestCase.swift index 104087cb5..6f0f96729 100644 --- a/Tests/XcodeTests/XcodeSourceGraphTestCase.swift +++ b/Tests/XcodeTests/XcodeSourceGraphTestCase.swift @@ -1,10 +1,11 @@ +import Configuration import Foundation import ProjectDrivers import SystemPackage @testable import TestShared class XcodeSourceGraphTestCase: SourceGraphTestCase { - static func build(projectPath: FilePath) { + static func build(projectPath: FilePath, configuration: Configuration) { projectPath.chdir { let driver = try! XcodeProjectDriver( projectPath: projectPath, diff --git a/baselines/linux.json b/baselines/linux.json index 65c6ebf7c..a8b35f576 100644 --- a/baselines/linux.json +++ b/baselines/linux.json @@ -1 +1 @@ -{"v1":{"usrs":["import-Configuration-Sources\/ProjectDrivers\/XcodeProjectDriver.swift:2:5","import-Indexer-Sources\/ProjectDrivers\/XcodeProjectDriver.swift:4:5","import-Logger-Sources\/ProjectDrivers\/XcodeProjectDriver.swift:5:5","import-Shared-Sources\/ProjectDrivers\/XcodeProjectDriver.swift:6:5","import-SourceGraph-Sources\/ProjectDrivers\/XcodeProjectDriver.swift:7:5","import-TestShared-Tests\/PeripheryTests\/ObjcAccessibleRetentionTest.swift:2:1","import-TestShared-Tests\/PeripheryTests\/ObjcAnnotatedRetentionTest.swift:2:1","s:11SourceGraph15ProjectFileKindO10extensionsSaySSGvp","s:13ConfigurationAAC20_retainFilesMatchers33_99B696DD1FA930EA831ABFF16BC88E61LLSay15FilenameMatcherAEVGSgvp","s:13ConfigurationAAC21_indexExcludeMatchers33_99B696DD1FA930EA831ABFF16BC88E61LLSay15FilenameMatcherAEVGSgvp","s:6Shared14SetupSelectionO","s:6Shared17SetupGuideHelpersC6select8multipleAA0B9SelectionOSaySSG_tF","s:8Frontend13UpdateCheckerC13latestVersion33_996BB8CE205CF54754BD877559C8CCFELLSSSgvp","s:8Frontend13UpdateCheckerC5error33_996BB8CE205CF54754BD877559C8CCFELLs5Error_pSgvp","s:SS10ExtensionsE17withEscapedQuotesSSvp","s:SS10ExtensionsE4djb2Sivp","s:SS10ExtensionsE7djb2HexSSvp"]}} \ No newline at end of file +{"v1":{"usrs":["import-Configuration-Sources\/ProjectDrivers\/XcodeProjectDriver.swift:2:5","import-Indexer-Sources\/ProjectDrivers\/XcodeProjectDriver.swift:4:5","import-Logger-Sources\/ProjectDrivers\/XcodeProjectDriver.swift:5:5","import-Shared-Sources\/ProjectDrivers\/XcodeProjectDriver.swift:6:5","import-SourceGraph-Sources\/ProjectDrivers\/XcodeProjectDriver.swift:7:5","import-TestShared-Tests\/PeripheryTests\/ObjcAccessibleRetentionTest.swift:2:1","import-TestShared-Tests\/PeripheryTests\/ObjcAnnotatedRetentionTest.swift:2:1","s:11SourceGraph15ProjectFileKindO10extensionsSaySSGvp","s:13ConfigurationAAC20_retainFilesMatchers33_99B696DD1FA930EA831ABFF16BC88E61LLSay15FilenameMatcherAEVGSgvp","s:13ConfigurationAAC21_indexExcludeMatchers33_99B696DD1FA930EA831ABFF16BC88E61LLSay15FilenameMatcherAEVGSgvp","s:6Shared14SetupSelectionO","s:6Shared17SetupGuideHelpersC6select8multipleAA0B9SelectionOSaySSG_tF","s:8Frontend13UpdateCheckerC13latestVersion33_996BB8CE205CF54754BD877559C8CCFELLSSSgvp","s:8Frontend13UpdateCheckerC5error33_996BB8CE205CF54754BD877559C8CCFELLs5Error_pSgvp","s:SS10ExtensionsE17withEscapedQuotesSSvp","s:SS10ExtensionsE4djb2Sivp","s:SS10ExtensionsE7djb2HexSSvp","import-Configuration-Tests\/AccessibilityTests\/RedundantPublicAccessibilityTest.swift:1:1"]}} \ No newline at end of file