From 650231045b776a11842284e47e2aea6f3b555e6d Mon Sep 17 00:00:00 2001 From: Dan Federman Date: Sun, 29 Mar 2026 14:43:39 -0700 Subject: [PATCH 1/6] Bump to v2.0.0, require Swift 6.3, remove CSV config support MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Version 1.5.4 → 2.0.0 - swift-tools-version 6.0 → 6.3 - swift-syntax range 600..<604 → 603..<605 - Remove deprecated CSV configuration file support (replaced by @SafeDIConfiguration macro) - Update CI to macOS-26 runner with Xcode 26.4, swift:6.3 container - Update SwiftFormat to 0.60.1, add trailing-commas and test-case-name-format options - Update README with v2.0 dependency examples and Swift 6.3 requirement note Co-Authored-By: Claude Opus 4.6 (1M context) --- .github/workflows/ci.yml | 63 ++++++++++--------- .github/workflows/codeql.yml | 6 +- .github/workflows/publish.yml | 4 +- .swiftformat | 7 ++- CLI/Package.resolved | 6 +- CLI/Package.swift | 2 +- .../Package.resolved | 6 +- .../Example Package Integration/Package.swift | 2 +- .../Package.swift | 2 +- .../Package.swift | 2 +- .../ExampleProjectIntegration/Package.swift | 2 +- Package.swift | 4 +- .../SafeDIGenerateDependencyTree.swift | 46 +------------- .../SafeDIGenerateDependencyTree.swift | 46 +------------- Plugins/Shared.swift | 2 +- README.md | 8 ++- SafeDI.podspec | 2 +- Sources/SafeDI/Decorators/Instantiable.swift | 25 ++------ Sources/SafeDICore/Visitors/FileVisitor.swift | 4 ++ Sources/SafeDITool/SafeDITool.swift | 55 ++-------------- .../Helpers/SafeDIToolTestExecution.swift | 11 +--- .../SafeDIToolCodeGenerationErrorTests.swift | 30 +-------- .../SafeDIToolVersionTests.swift | 2 - 23 files changed, 85 insertions(+), 252 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 6e56e1eb..251df922 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -22,8 +22,8 @@ jobs: run: ./Scripts/check-version-consistency.sh xcodebuild: - name: Build with xcodebuild on Xcode 16 - runs-on: macos-15 + name: Build with xcodebuild on Xcode 26 + runs-on: macos-26 strategy: matrix: platforms: [ @@ -40,54 +40,55 @@ jobs: - name: Checkout Repo uses: actions/checkout@v6 - name: Select Xcode Version - run: sudo xcode-select --switch /Applications/Xcode_16.4.app/Contents/Developer - - name: Download visionOS - if: matrix.platforms == 'generic/platform=visionos' + run: sudo xcode-select --switch /Applications/Xcode_26.4.app/Contents/Developer + - name: Download Platform + if: matrix.platforms != 'platform=macOS' run: | sudo xcodebuild -runFirstLaunch sudo xcrun simctl list - sudo xcodebuild -downloadPlatform visionOS + PLATFORM=$(echo "${{ matrix.platforms }}" | sed 's|generic/platform=||') + sudo xcodebuild -downloadPlatform "$PLATFORM" - name: Build Framework run: xcrun xcodebuild -skipMacroValidation -skipPackagePluginValidation build -scheme SafeDI-Package -destination ${{ matrix.platforms }} spm-package-integration: - name: Build Package Integration on Xcode 16 - runs-on: macos-15 + name: Build Package Integration on Xcode 26 + runs-on: macos-26 permissions: contents: read steps: - name: Checkout Repo uses: actions/checkout@v6 - name: Select Xcode Version - run: sudo xcode-select --switch /Applications/Xcode_16.app/Contents/Developer + run: sudo xcode-select --switch /Applications/Xcode_26.4.app/Contents/Developer - name: Build Package Integration run: xcrun swift build --package-path "Examples/Example Package Integration" spm-prebuilt-package-integration: - name: Build Prebuilt Package Integration on Xcode 16 - runs-on: macos-15 + name: Build Prebuilt Package Integration on Xcode 26 + runs-on: macos-26 permissions: contents: read steps: - name: Checkout Repo uses: actions/checkout@v6 - name: Select Xcode Version - run: sudo xcode-select --switch /Applications/Xcode_16.app/Contents/Developer + run: sudo xcode-select --switch /Applications/Xcode_26.4.app/Contents/Developer - name: Build Package Integration run: | xcrun swift package --package-path Examples/ExamplePrebuiltPackageIntegration --allow-network-connections all --allow-writing-to-package-directory safedi-release-install xcrun swift build --package-path Examples/ExamplePrebuiltPackageIntegration spm-project-integration: - name: Build Project Integration on Xcode 16 - runs-on: macos-15 + name: Build Project Integration on Xcode 26 + runs-on: macos-26 permissions: contents: read steps: - name: Checkout Repo uses: actions/checkout@v6 - name: Select Xcode Version - run: sudo xcode-select --switch /Applications/Xcode_16.app/Contents/Developer + run: sudo xcode-select --switch /Applications/Xcode_26.4.app/Contents/Developer - name: Replace 'main' branch with the current branch if: github.event.pull_request.head.repo.full_name == github.repository # Only do this if the branch is from our repo. run: sed -i '' "s#branch = main;#branch = ${{ github.head_ref || github.ref_name }};#" "Examples/ExampleProjectIntegration/ExampleProjectIntegration.xcodeproj/project.pbxproj" @@ -95,15 +96,15 @@ jobs: run: pushd Examples/ExampleProjectIntegration; xcrun xcodebuild build -skipPackagePluginValidation -skipMacroValidation -scheme ExampleProjectIntegration; popd spm-multi-project-integration: - name: Build Multi Project Integration on Xcode 16 - runs-on: macos-15 + name: Build Multi Project Integration on Xcode 26 + runs-on: macos-26 permissions: contents: read steps: - name: Checkout Repo uses: actions/checkout@v6 - name: Select Xcode Version - run: sudo xcode-select --switch /Applications/Xcode_16.app/Contents/Developer + run: sudo xcode-select --switch /Applications/Xcode_26.4.app/Contents/Developer - name: Replace 'main' branch with the current branch if: github.event.pull_request.head.repo.full_name == github.repository # Only do this if the branch is from our repo. run: sed -i '' "s#branch = main;#branch = ${{ github.head_ref || github.ref_name }};#" "Examples/ExampleMultiProjectIntegration/ExampleMultiProjectIntegration.xcodeproj/project.pbxproj" @@ -111,8 +112,8 @@ jobs: run: pushd Examples/ExampleMultiProjectIntegration; xcrun xcodebuild build -skipPackagePluginValidation -skipMacroValidation -scheme ExampleMultiProjectIntegration; popd pod-project-integration: - name: Build CocoaPods Integration on Xcode 16 - runs-on: macos-15 + name: Build CocoaPods Integration on Xcode 26 + runs-on: macos-26 permissions: contents: read steps: @@ -123,27 +124,27 @@ jobs: ruby-version: '3.3.5' bundler-cache: true - name: Select Xcode Version - run: sudo xcode-select --switch /Applications/Xcode_16.4.0.app/Contents/Developer + run: sudo xcode-select --switch /Applications/Xcode_26.4.app/Contents/Developer - name: Install Pod run: bundle exec pod install --project-directory=Examples/ExampleCocoaPodsIntegration - name: Download iOS run: | sudo xcodebuild -runFirstLaunch sudo xcrun simctl list - sudo xcodebuild -downloadPlatform iOS -buildVersion 22F77 + sudo xcodebuild -downloadPlatform iOS - name: Build CocoaPods Integration - run: xcrun xcodebuild build -scheme ExampleCocoaPodsIntegration -configuration Debug -workspace Examples/ExampleCocoaPodsIntegration/ExampleCocoaPodsIntegration.xcworkspace -destination 'platform=iOS Simulator,OS=18.5,name=iPad (10th generation)' # Explicitly test the Debug build. Our pod lint jobs are already testing the Release build. + run: xcrun xcodebuild build -scheme ExampleCocoaPodsIntegration -configuration Debug -workspace Examples/ExampleCocoaPodsIntegration/ExampleCocoaPodsIntegration.xcworkspace -destination 'platform=iOS Simulator,OS=26.2,name=iPad (A16)' # Explicitly test the Debug build. Our pod lint jobs are already testing the Release build. spm: - name: Build and Test on Xcode 16 - runs-on: macos-15 + name: Build and Test on Xcode 26 + runs-on: macos-26 permissions: contents: read steps: - name: Checkout Repo uses: actions/checkout@v6 - name: Select Xcode Version - run: sudo xcode-select --switch /Applications/Xcode_16.3.app/Contents/Developer + run: sudo xcode-select --switch /Applications/Xcode_26.4.app/Contents/Developer - name: Build and Test Framework run: | for i in {1..5}; do # Run tests a few times to ensure code-gen is stable. @@ -161,7 +162,7 @@ jobs: pod-lint: name: Pod Lint - runs-on: macos-15 + runs-on: macos-26 strategy: matrix: platforms: [ @@ -182,7 +183,7 @@ jobs: ruby-version: '3.3.5' bundler-cache: true - name: Select Xcode Version - run: sudo xcode-select --switch /Applications/Xcode_16.4.app/Contents/Developer + run: sudo xcode-select --switch /Applications/Xcode_26.4.app/Contents/Developer - name: Download Simulator if: matrix.platforms != 'macos' run: | @@ -190,12 +191,12 @@ jobs: sudo xcrun simctl list sudo xcodebuild -downloadPlatform ${{ matrix.platforms }} - name: Lint Podspec - run: bundle exec pod lib lint --verbose --fail-fast --swift-version=6.0 --platforms=${{ matrix.platforms }} + run: bundle exec pod lib lint --verbose --fail-fast --swift-version=6.3 --platforms=${{ matrix.platforms }} linux: name: Build and Test on Linux runs-on: ubuntu-latest - container: swift:6.1 + container: swift:6.3 permissions: contents: read steps: @@ -232,7 +233,7 @@ jobs: lint-swift: name: Lint Swift runs-on: ubuntu-latest - container: swift:6.1 + container: swift:6.3 permissions: contents: read steps: diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index 37852731..153b0270 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -11,7 +11,7 @@ on: jobs: analyze: name: Analyze (${{ matrix.language }}) - runs-on: macOS-15 + runs-on: macos-26 permissions: security-events: write packages: read @@ -40,7 +40,7 @@ jobs: - name: Checkout repository uses: actions/checkout@v6 - name: Select Xcode Version - run: sudo xcode-select --switch /Applications/Xcode_16.4.app/Contents/Developer + run: sudo xcode-select --switch /Applications/Xcode_26.4.app/Contents/Developer # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL @@ -57,7 +57,7 @@ jobs: - if: matrix.language == 'swift' run: | - sudo xcode-select --switch /Applications/Xcode_16.4.app/Contents/Developer + sudo xcode-select --switch /Applications/Xcode_26.4.app/Contents/Developer xcrun swift build -c release - name: Perform CodeQL Analysis diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 3a489576..2b0e2483 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -7,7 +7,7 @@ on: jobs: build-release-cli: name: Build Release CLI - runs-on: macos-15 + runs-on: macos-26 strategy: matrix: architecture: [ @@ -21,7 +21,7 @@ jobs: - name: Checkout Repo uses: actions/checkout@v6 - name: Select Xcode Version - run: sudo xcode-select --switch /Applications/Xcode_16.app/Contents/Developer + run: sudo xcode-select --switch /Applications/Xcode_26.4.app/Contents/Developer - name: Build SafeDITool run: xcrun swift build -c release --product SafeDITool --arch ${{ matrix.architecture }} - name: Give SafeDITool executable permissions diff --git a/.swiftformat b/.swiftformat index 5d331ad9..1719a8c5 100644 --- a/.swiftformat +++ b/.swiftformat @@ -12,6 +12,9 @@ --storedvarattrs same-line --hexgrouping none --decimalgrouping 3 +--trailing-commas always +--test-case-name-format standard-identifiers +--import-grouping access-control,alpha,testable-last # rules --enable isEmpty @@ -19,6 +22,8 @@ --enable wrapMultilineStatementBraces --disable consistentSwitchCaseSpacing --disable blankLineAfterSwitchCase +--disable hoistTry +--disable docComments # global ---swiftversion 6.0 +--swiftversion 6.3 diff --git a/CLI/Package.resolved b/CLI/Package.resolved index 84c1abe7..817b01d4 100644 --- a/CLI/Package.resolved +++ b/CLI/Package.resolved @@ -1,13 +1,13 @@ { - "originHash" : "def16a3b3824702b1335e832aead6f3b3d9a533438e56cf66e53483b67414cf7", + "originHash" : "790e76fdbbd629679e2e6f8bf5cf83a28a83c63c2b2ce42872a6a2120ff0b895", "pins" : [ { "identity" : "swiftformat", "kind" : "remoteSourceControl", "location" : "https://github.com/nicklockwood/SwiftFormat", "state" : { - "revision" : "9c82dcb15307ba06795d31788d3467d9a375e3e7", - "version" : "0.58.5" + "revision" : "c8e50ff2cfc2eab46246c072a9ae25ab656c6ec3", + "version" : "0.60.1" } } ], diff --git a/CLI/Package.swift b/CLI/Package.swift index 5129fcbc..36311c48 100644 --- a/CLI/Package.swift +++ b/CLI/Package.swift @@ -10,7 +10,7 @@ let package = Package( ], products: [], dependencies: [ - .package(url: "https://github.com/nicklockwood/SwiftFormat", from: "0.56.1"), + .package(url: "https://github.com/nicklockwood/SwiftFormat", from: "0.60.1"), ], targets: [] ) diff --git a/Examples/Example Package Integration/Package.resolved b/Examples/Example Package Integration/Package.resolved index a643bed6..bf19fbda 100644 --- a/Examples/Example Package Integration/Package.resolved +++ b/Examples/Example Package Integration/Package.resolved @@ -1,5 +1,5 @@ { - "originHash" : "9e7a2f5ac146d16b990a70a956bfcc1b8bca5ac63442e5e4b8abbe121add4603", + "originHash" : "6e4bae606942f77564af916adc00d5f58f679520e83fb0dee76eec55cb3d4b32", "pins" : [ { "identity" : "swift-argument-parser", @@ -24,8 +24,8 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/swiftlang/swift-syntax.git", "state" : { - "revision" : "0687f71944021d616d34d922343dcef086855920", - "version" : "600.0.1" + "revision" : "2b59c0c741e9184ab057fd22950b491076d42e91", + "version" : "603.0.0" } } ], diff --git a/Examples/Example Package Integration/Package.swift b/Examples/Example Package Integration/Package.swift index ee80bb1d..4d113da8 100644 --- a/Examples/Example Package Integration/Package.swift +++ b/Examples/Example Package Integration/Package.swift @@ -1,4 +1,4 @@ -// swift-tools-version: 6.0 +// swift-tools-version: 6.3 // The swift-tools-version declares the minimum version of Swift required to build this package. import PackageDescription diff --git a/Examples/ExampleMultiProjectIntegration/Package.swift b/Examples/ExampleMultiProjectIntegration/Package.swift index fc7ee9f8..a4b0ff28 100644 --- a/Examples/ExampleMultiProjectIntegration/Package.swift +++ b/Examples/ExampleMultiProjectIntegration/Package.swift @@ -1,4 +1,4 @@ -// swift-tools-version: 6.0 +// swift-tools-version: 6.3 // The swift-tools-version declares the minimum version of Swift required to build this package. import PackageDescription diff --git a/Examples/ExamplePrebuiltPackageIntegration/Package.swift b/Examples/ExamplePrebuiltPackageIntegration/Package.swift index c55dda8c..0aba458c 100644 --- a/Examples/ExamplePrebuiltPackageIntegration/Package.swift +++ b/Examples/ExamplePrebuiltPackageIntegration/Package.swift @@ -1,4 +1,4 @@ -// swift-tools-version: 6.0 +// swift-tools-version: 6.3 // The swift-tools-version declares the minimum version of Swift required to build this package. import PackageDescription diff --git a/Examples/ExampleProjectIntegration/Package.swift b/Examples/ExampleProjectIntegration/Package.swift index fc7ee9f8..a4b0ff28 100644 --- a/Examples/ExampleProjectIntegration/Package.swift +++ b/Examples/ExampleProjectIntegration/Package.swift @@ -1,4 +1,4 @@ -// swift-tools-version: 6.0 +// swift-tools-version: 6.3 // The swift-tools-version declares the minimum version of Swift required to build this package. import PackageDescription diff --git a/Package.swift b/Package.swift index 75a2b1ec..a9d6b86d 100644 --- a/Package.swift +++ b/Package.swift @@ -1,4 +1,4 @@ -// swift-tools-version: 6.0 +// swift-tools-version: 6.3 // The swift-tools-version declares the minimum version of Swift required to build this package. import CompilerPluginSupport @@ -38,7 +38,7 @@ let package = Package( dependencies: [ .package(url: "https://github.com/apple/swift-argument-parser.git", from: "1.2.0"), .package(url: "https://github.com/apple/swift-collections.git", from: "1.0.0"), - .package(url: "https://github.com/swiftlang/swift-syntax.git", "600.0.0"..<"604.0.0"), + .package(url: "https://github.com/swiftlang/swift-syntax.git", "603.0.0"..<"605.0.0"), ], targets: [ // Macros diff --git a/Plugins/SafeDIGenerator/SafeDIGenerateDependencyTree.swift b/Plugins/SafeDIGenerator/SafeDIGenerateDependencyTree.swift index 4e0bb9c2..4b65b377 100644 --- a/Plugins/SafeDIGenerator/SafeDIGenerateDependencyTree.swift +++ b/Plugins/SafeDIGenerator/SafeDIGenerateDependencyTree.swift @@ -55,32 +55,11 @@ struct SafeDIGenerateDependencyTree: BuildToolPlugin { encoding: .utf8 ) - // TODO: Delete CSV support in version 2.0. Use @SafeDIConfiguration instead. - let includeCSV = context.safediFolder.appending(components: "configuration", "include.csv") - let includeArguments: [String] = if FileManager.default.fileExists(atPath: includeCSV.path(percentEncoded: false)) { - [ - "--include-file-path", - includeCSV.path(percentEncoded: false), - ] - } else { - [] - } - // TODO: Delete CSV support in version 2.0. Use @SafeDIConfiguration instead. - let additionalImportedModulesCSV = context.safediFolder.appending(components: "configuration", "additionalImportedModules.csv") - let additionalImportedModulesArguments: [String] = if FileManager.default.fileExists(atPath: additionalImportedModulesCSV.path(percentEncoded: false)) { - [ - "--additional-imported-modules-file-path", - additionalImportedModulesCSV.path(percentEncoded: false), - ] - } else { - [] - } - let arguments = [ inputSourcesFile.path(percentEncoded: false), "--dependency-tree-output", outputSwiftFile.path(percentEncoded: false), - ] + includeArguments + additionalImportedModulesArguments + ] let downloadedToolLocation = context.downloadedToolLocation let safeDIVersion = context.safeDIVersion @@ -174,32 +153,11 @@ extension Target { encoding: .utf8 ) - // TODO: Delete CSV support in version 2.0. Use @SafeDIConfiguration instead. - let includeCSV = context.safediFolder.appending(components: "configuration", "include.csv") - let includeArguments: [String] = if FileManager.default.fileExists(atPath: includeCSV.path(percentEncoded: false)) { - [ - "--include-file-path", - includeCSV.path(percentEncoded: false), - ] - } else { - [] - } - // TODO: Delete CSV support in version 2.0. Use @SafeDIConfiguration instead. - let additionalImportedModulesCSV = context.safediFolder.appending(components: "configuration", "additionalImportedModules.csv") - let additionalImportedModulesArguments: [String] = if FileManager.default.fileExists(atPath: additionalImportedModulesCSV.path(percentEncoded: false)) { - [ - "--additional-imported-modules-file-path", - additionalImportedModulesCSV.path(percentEncoded: false), - ] - } else { - [] - } - let arguments = [ inputSourcesFile.path(percentEncoded: false), "--dependency-tree-output", outputSwiftFile.path(percentEncoded: false), - ] + includeArguments + additionalImportedModulesArguments + ] let downloadedToolLocation = context.downloadedToolLocation if downloadedToolLocation == nil { diff --git a/Plugins/SafeDIPrebuiltGenerator/SafeDIGenerateDependencyTree.swift b/Plugins/SafeDIPrebuiltGenerator/SafeDIGenerateDependencyTree.swift index a3137d9a..13c4eb38 100644 --- a/Plugins/SafeDIPrebuiltGenerator/SafeDIGenerateDependencyTree.swift +++ b/Plugins/SafeDIPrebuiltGenerator/SafeDIGenerateDependencyTree.swift @@ -55,32 +55,11 @@ struct SafeDIGenerateDependencyTree: BuildToolPlugin { encoding: .utf8 ) - // TODO: Delete CSV support in version 2.0. Use @SafeDIConfiguration instead. - let includeCSV = context.safediFolder.appending(components: "configuration", "include.csv") - let includeArguments: [String] = if FileManager.default.fileExists(atPath: includeCSV.path(percentEncoded: false)) { - [ - "--include-file-path", - includeCSV.path(percentEncoded: false), - ] - } else { - [] - } - // TODO: Delete CSV support in version 2.0. Use @SafeDIConfiguration instead. - let additionalImportedModulesCSV = context.safediFolder.appending(components: "configuration", "additionalImportedModules.csv") - let additionalImportedModulesArguments: [String] = if FileManager.default.fileExists(atPath: additionalImportedModulesCSV.path(percentEncoded: false)) { - [ - "--additional-imported-modules-file-path", - additionalImportedModulesCSV.path(percentEncoded: false), - ] - } else { - [] - } - let arguments = [ inputSourcesFile.path(percentEncoded: false), "--dependency-tree-output", outputSwiftFile.path(percentEncoded: false), - ] + includeArguments + additionalImportedModulesArguments + ] let downloadedToolLocation = context.downloadedToolLocation let safeDIVersion = context.safeDIVersion @@ -184,32 +163,11 @@ extension Target { encoding: .utf8 ) - // TODO: Delete CSV support in version 2.0. Use @SafeDIConfiguration instead. - let includeCSV = context.safediFolder.appending(components: "configuration", "include.csv") - let includeArguments: [String] = if FileManager.default.fileExists(atPath: includeCSV.path(percentEncoded: false)) { - [ - "--include-file-path", - includeCSV.path(percentEncoded: false), - ] - } else { - [] - } - // TODO: Delete CSV support in version 2.0. Use @SafeDIConfiguration instead. - let additionalImportedModulesCSV = context.safediFolder.appending(components: "configuration", "additionalImportedModules.csv") - let additionalImportedModulesArguments: [String] = if FileManager.default.fileExists(atPath: additionalImportedModulesCSV.path(percentEncoded: false)) { - [ - "--additional-imported-modules-file-path", - additionalImportedModulesCSV.path(percentEncoded: false), - ] - } else { - [] - } - let arguments = [ inputSourcesFile.path(percentEncoded: false), "--dependency-tree-output", outputSwiftFile.path(percentEncoded: false), - ] + includeArguments + additionalImportedModulesArguments + ] let downloadedToolLocation = context.downloadedToolLocation let toolLocation = if let downloadedToolLocation { diff --git a/Plugins/Shared.swift b/Plugins/Shared.swift index e7800df5..cb619358 100644 --- a/Plugins/Shared.swift +++ b/Plugins/Shared.swift @@ -29,7 +29,7 @@ import PackagePlugin // As of Xcode 15.0, Xcode command plugins have no way to read the package manifest, therefore we must hardcode the version number. // It is okay for this number to be behind the most current release if the inputs and outputs to SafeDITool have not changed. // Unlike SPM plugins, Xcode plugins can not determine the current version number, so we must hardcode it. - "1.5.4" + "2.0.0" } var safeDIOrigin: URL { diff --git a/README.md b/README.md index bc61692e..2f2ec665 100644 --- a/README.md +++ b/README.md @@ -78,10 +78,12 @@ To add the SafeDI framework as a dependency to a package utilizing [Swift Packag ```swift dependencies: [ - .package(url: "https://github.com/dfed/SafeDI.git", from: "1.0.0"), + .package(url: "https://github.com/dfed/SafeDI.git", from: "2.0.0"), ] ``` +> **Note:** SafeDI 2.x requires Swift 6.3 or later. Projects using an earlier Swift version should use SafeDI 1.x. + To install the SafeDI framework into an Xcode project with Swift Package Manager, follow [Apple’s instructions](https://developer.apple.com/documentation/xcode/adding-package-dependencies-to-your-app) to add `https://github.com/dfed/SafeDI.git` as a dependency. #### CocoaPods @@ -89,7 +91,7 @@ To install the SafeDI framework into an Xcode project with Swift Package Manager To add the SafeDI framework as a dependency to a package utilizing [CocoaPods](https://blog.cocoapods.org/CocoaPods-Specs-Repo), add the following to your `Podfile`: ```ruby -pod 'SafeDI', '~> 1.0.0' +pod ‘SafeDI’, ‘~> 2.0.0’ ``` ### Generating your dependency tree @@ -147,7 +149,7 @@ enum MySafeDIConfiguration { ##### Unlocking faster builds with Swift Package Manager plugins -SafeDI vends a `SafeDIPrebuiltGenerator` plugin for both Xcode and Swift package manager. This plugin utilizes a prebuilt binary for dependency tree generation and does not require compiling `SwiftSyntax`. Integrating this plugin will guide you through the one-step process of downloading the binary to the expected location. Note that avoiding compiling SwiftSyntax requires [some additional configuration](https://forums.swift.org/t/preview-swift-syntax-prebuilts-for-macros/80202) when using a Swift compiler version below 6.2. +SafeDI vends a `SafeDIPrebuiltGenerator` plugin for both Xcode and Swift package manager. This plugin utilizes a prebuilt binary for dependency tree generation and does not require compiling `SwiftSyntax`. Integrating this plugin will guide you through the one-step process of downloading the binary to the expected location. #### CocoaPods diff --git a/SafeDI.podspec b/SafeDI.podspec index 1a56688d..a575f89c 100644 --- a/SafeDI.podspec +++ b/SafeDI.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = 'SafeDI' - s.version = '1.5.4' + s.version = '2.0.0' s.summary = 'Compile-time-safe dependency injection' s.homepage = 'https://github.com/dfed/SafeDI' s.license = 'MIT' diff --git a/Sources/SafeDI/Decorators/Instantiable.swift b/Sources/SafeDI/Decorators/Instantiable.swift index e028e020..e7fb2da4 100644 --- a/Sources/SafeDI/Decorators/Instantiable.swift +++ b/Sources/SafeDI/Decorators/Instantiable.swift @@ -60,22 +60,9 @@ public macro Instantiable( conformsElsewhere: Bool = false ) = #externalMacro(module: "SafeDIMacros", type: "InstantiableMacro") -#if swift(>=6.2) - - /// A type that can be instantiated with runtime-injected properties. - public protocol Instantiable: SendableMetatype { - /// The forwarded properties required to instantiate the type. - /// Defaults to `Void`. - associatedtype ForwardedProperties = Void - } - -#else - - /// A type that can be instantiated with runtime-injected properties. - public protocol Instantiable { - /// The forwarded properties required to instantiate the type. - /// Defaults to `Void`. - associatedtype ForwardedProperties = Void - } - -#endif +/// A type that can be instantiated with runtime-injected properties. +public protocol Instantiable: SendableMetatype { + /// The forwarded properties required to instantiate the type. + /// Defaults to `Void`. + associatedtype ForwardedProperties = Void +} diff --git a/Sources/SafeDICore/Visitors/FileVisitor.swift b/Sources/SafeDICore/Visitors/FileVisitor.swift index b29861e0..c02d4a39 100644 --- a/Sources/SafeDICore/Visitors/FileVisitor.swift +++ b/Sources/SafeDICore/Visitors/FileVisitor.swift @@ -117,6 +117,10 @@ public final class FileVisitor: SyntaxVisitor { parentType = nil } + // SwiftSyntax 602 and prior could not recover from certain parse errors, causing the remainder + // of a file to be unparseable. This led to SafeDI emitting bogus "missing type" errors before + // the compiler had a chance to surface the real build error. Detecting unexpected nodes and + // bailing out avoids this class of false-positive diagnostics. public override func visit(_: UnexpectedNodesSyntax) -> SyntaxVisitorContinueKind { encounteredUnexpectedNodesSyntax = true return .skipChildren diff --git a/Sources/SafeDITool/SafeDITool.swift b/Sources/SafeDITool/SafeDITool.swift index d6d5482a..7b515d23 100644 --- a/Sources/SafeDITool/SafeDITool.swift +++ b/Sources/SafeDITool/SafeDITool.swift @@ -33,12 +33,8 @@ struct SafeDITool: AsyncParsableCommand, Sendable { @Option(parsing: .upToNextOption, help: "Directories containing Swift files to include, relative to the executing directory.") var include: [String] = [] - @Option(help: "A path to a CSV file comprising directories containing Swift files to include, relative to the executing directory.") var includeFilePath: String? - @Option(parsing: .upToNextOption, help: "The names of modules to import in the generated dependency tree. This list is in addition to the import statements found in files that declare @Instantiable types.") var additionalImportedModules: [String] = [] - @Option(help: "A path to a CSV file comprising the names of modules to import in the generated dependency tree. This list is in addition to the import statements found in files that declare @Instantiable types.") var additionalImportedModulesFilePath: String? - @Option(help: "The desired output location of a file a SafeDI representation of this module. Only include this option when running on a project‘s non-root module. Must have a `.safedi` suffix.") var moduleInfoOutput: String? @Option(help: "A path to a CSV file containing paths of SafeDI representations of other modules to parse.") var dependentModuleInfoFilePath: String? @@ -50,7 +46,7 @@ struct SafeDITool: AsyncParsableCommand, Sendable { // MARK: Internal static var currentVersion: String { - "1.5.4" + "2.0.0" } func run() async throws { @@ -59,8 +55,8 @@ struct SafeDITool: AsyncParsableCommand, Sendable { return } - if swiftSourcesFilePath == nil, include.isEmpty, includeFilePath == nil { - throw ValidationError("Must provide 'swift-sources-file-path', '--include', or '--include-file-path'.") + if swiftSourcesFilePath == nil, include.isEmpty { + throw ValidationError("Must provide 'swift-sources-file-path' or '--include'.") } async let existingGeneratedCode: String? = Task.detached { @@ -83,16 +79,10 @@ struct SafeDITool: AsyncParsableCommand, Sendable { dependentModuleInfo.flatMap(\.configurations).first } - // TODO: Delete CSV support in version 2.0. - let hasCSVConfiguration = includeFilePath != nil || additionalImportedModulesFilePath != nil - if sourceConfiguration != nil, hasCSVConfiguration { - throw ConfigurationError.csvAndSourceConfigurationConflict - } - let resolvedAdditionalImportedModules: [String] = if let sourceConfiguration { additionalImportedModules + sourceConfiguration.additionalImportedModules } else { - try allAdditionalImportedModules + additionalImportedModules } // If the source configuration specifies additional directories to include, @@ -219,8 +209,7 @@ struct SafeDITool: AsyncParsableCommand, Sendable { // MARK: Private private func findSwiftFiles() async throws -> Set { - // TODO: Delete CSV support in version 2.0. - try await findSwiftFiles(additionalDirectories: allDirectoriesToIncludes) + try await findSwiftFiles(additionalDirectories: include) } private func findSwiftFiles(additionalDirectories: [String]) async throws -> Set { @@ -337,30 +326,6 @@ struct SafeDITool: AsyncParsableCommand, Sendable { try await Self.parseSwiftFiles(findSwiftFiles()) } - private var allDirectoriesToIncludes: [String] { - get throws { - if let includeFilePath { - try include + String(contentsOfFile: includeFilePath, encoding: .utf8) - .components(separatedBy: CharacterSet(arrayLiteral: ",")) - .removingEmpty() - } else { - include - } - } - } - - private var allAdditionalImportedModules: [String] { - get throws { - if let additionalImportedModulesFilePath { - try additionalImportedModules + String(contentsOfFile: additionalImportedModulesFilePath, encoding: .utf8) - .components(separatedBy: CharacterSet(arrayLiteral: ",")) - .removingEmpty() - } else { - additionalImportedModules - } - } - } - private var moduleInfoURLs: Set { get throws { if let dependentModuleInfoFilePath { @@ -423,16 +388,6 @@ struct SafeDITool: AsyncParsableCommand, Sendable { } } - private enum ConfigurationError: Error, CustomStringConvertible { - case csvAndSourceConfigurationConflict - - var description: String { - switch self { - case .csvAndSourceConfigurationConflict: - "Found both a @\(SafeDIConfigurationVisitor.macroName)-decorated type and .safedi/configuration/ CSV files. Remove the CSV files and use @\(SafeDIConfigurationVisitor.macroName) instead." - } - } - } } extension Data { diff --git a/Tests/SafeDIToolTests/Helpers/SafeDIToolTestExecution.swift b/Tests/SafeDIToolTests/Helpers/SafeDIToolTestExecution.swift index ada6f6fa..e0a7e139 100644 --- a/Tests/SafeDIToolTests/Helpers/SafeDIToolTestExecution.swift +++ b/Tests/SafeDIToolTests/Helpers/SafeDIToolTestExecution.swift @@ -54,19 +54,12 @@ func executeSafeDIToolTest( let dependencyTreeOutput = URL.temporaryFile.appendingPathExtension("swift") let dotTreeOutput = URL.temporaryFile.appendingPathExtension("dot") - let includeFile = URL.temporaryFile.appendingPathExtension("include.csv") - try includeFolders.joined(separator: ",").write(to: includeFile, atomically: true, encoding: .utf8) - let additionalImportedModulesFile = URL.temporaryFile.appendingPathExtension("additionalImportedModules.csv") - try additionalImportedModules.joined(separator: ",").write(to: additionalImportedModulesFile, atomically: true, encoding: .utf8) - return try await SafeDITool.$fileFinder.withValue(StubFileFinder(files: swiftFiles)) { // Successfully execute the file finder code path. var tool = SafeDITool() tool.swiftSourcesFilePath = swiftFileCSV.relativePath tool.showVersion = false - tool.include = [] - tool.includeFilePath = !includeFolders.isEmpty ? includeFile.relativePath : nil - tool.additionalImportedModules = [] - tool.additionalImportedModulesFilePath = !additionalImportedModules.isEmpty ? additionalImportedModulesFile.relativePath : nil + tool.include = includeFolders + tool.additionalImportedModules = additionalImportedModules tool.moduleInfoOutput = moduleInfoOutput.relativePath tool.dependentModuleInfoFilePath = dependentModuleInfoPaths.isEmpty ? nil : dependentModuleInfoFileCSV.relativePath tool.dependencyTreeOutput = buildDependencyTreeOutput ? dependencyTreeOutput.relativePath : nil diff --git a/Tests/SafeDIToolTests/SafeDIToolCodeGenerationErrorTests.swift b/Tests/SafeDIToolTests/SafeDIToolCodeGenerationErrorTests.swift index c0674186..c66ff847 100644 --- a/Tests/SafeDIToolTests/SafeDIToolCodeGenerationErrorTests.swift +++ b/Tests/SafeDIToolTests/SafeDIToolCodeGenerationErrorTests.swift @@ -1935,9 +1935,7 @@ struct SafeDIToolCodeGenerationErrorTests: ~Copyable { tool.swiftSourcesFilePath = nil tool.showVersion = false tool.include = ["Fake"] - tool.includeFilePath = nil tool.additionalImportedModules = [] - tool.additionalImportedModulesFilePath = nil tool.moduleInfoOutput = nil tool.dependentModuleInfoFilePath = nil tool.dependencyTreeOutput = nil @@ -1954,42 +1952,16 @@ struct SafeDIToolCodeGenerationErrorTests: ~Copyable { tool.swiftSourcesFilePath = nil tool.showVersion = false tool.include = [] - tool.includeFilePath = nil tool.additionalImportedModules = [] - tool.additionalImportedModulesFilePath = nil tool.moduleInfoOutput = nil tool.dependentModuleInfoFilePath = nil tool.dependencyTreeOutput = nil tool.dotFileOutput = nil - await assertThrowsError("Must provide 'swift-sources-file-path', '--include', or '--include-file-path'.") { + await assertThrowsError("Must provide 'swift-sources-file-path' or '--include'.") { try await tool.run() } } - // MARK: @SafeDIConfiguration Error Tests - - @Test - mutating func run_throwsErrorWhenCSVAndSourceConfigurationBothPresent() async { - await assertThrowsError( - "Found both a @SafeDIConfiguration-decorated type and .safedi/configuration/ CSV files. Remove the CSV files and use @SafeDIConfiguration instead." - ) { - try await executeSafeDIToolTest( - swiftFileContent: [ - """ - @SafeDIConfiguration - enum MyConfiguration { - static let additionalImportedModules: [StaticString] = ["TestModule"] - static let additionalDirectoriesToInclude: [StaticString] = [] - } - """, - ], - additionalImportedModules: ["ConflictingModule"], - buildDependencyTreeOutput: true, - filesToDelete: &filesToDelete - ) - } - } - // MARK: Private private var filesToDelete = [URL]() diff --git a/Tests/SafeDIToolTests/SafeDIToolVersionTests.swift b/Tests/SafeDIToolTests/SafeDIToolVersionTests.swift index 74283568..071a1d54 100644 --- a/Tests/SafeDIToolTests/SafeDIToolVersionTests.swift +++ b/Tests/SafeDIToolTests/SafeDIToolVersionTests.swift @@ -37,9 +37,7 @@ struct SafeDIToolVersionTests { tool.swiftSourcesFilePath = nil tool.showVersion = true tool.include = [] - tool.includeFilePath = nil tool.additionalImportedModules = [] - tool.additionalImportedModulesFilePath = nil tool.moduleInfoOutput = nil tool.dependentModuleInfoFilePath = nil tool.dependencyTreeOutput = nil From 6b4cb9ef3f881eb587f74ae467bff66276253150 Mon Sep 17 00:00:00 2001 From: Dan Federman Date: Sun, 29 Mar 2026 16:02:11 -0700 Subject: [PATCH 2/6] Run linter --- CLI/Package.swift | 2 +- .../Example Package Integration/Package.swift | 16 +- .../Views/ExampleApp.swift | 2 +- .../Views/NameEntryView.swift | 2 +- .../Views/NoteView.swift | 2 +- .../Views/ExampleApp.swift | 2 +- .../Views/NameEntryView.swift | 2 +- .../Views/NoteView.swift | 2 +- .../Package.swift | 16 +- .../Views/ExampleApp.swift | 2 +- .../Views/NameEntryView.swift | 2 +- .../Views/NoteView.swift | 2 +- Package.swift | 36 +- .../InstallCLIPluginCommand.swift | 24 +- .../SafeDIGenerateDependencyTree.swift | 12 +- .../SafeDIGenerateDependencyTree.swift | 12 +- Plugins/Shared.swift | 24 +- Sources/SafeDI/Decorators/Instantiable.swift | 2 +- Sources/SafeDI/Decorators/Instantiated.swift | 2 +- Sources/SafeDI/Decorators/Received.swift | 2 +- .../Extensions/DiagnosticExtensions.swift | 6 +- .../ImportDeclSyntaxExtensions.swift | 2 +- .../Generators/DependencyTreeGenerator.swift | 40 +- .../Generators/ScopeGenerator.swift | 42 +- .../Models/ConcreteDeclSyntaxProtocol.swift | 12 +- Sources/SafeDICore/Models/Dependency.swift | 8 +- .../SafeDICore/Models/ImportStatement.swift | 2 +- Sources/SafeDICore/Models/Initializer.swift | 32 +- .../Models/InstantiableStruct.swift | 2 +- Sources/SafeDICore/Models/Property.swift | 42 +- .../Models/SafeDIConfiguration.swift | 2 +- Sources/SafeDICore/Models/Scope.swift | 10 +- .../SafeDICore/Models/TypeDescription.swift | 38 +- .../Models/UnorderedEquatingCollection.swift | 15 +- Sources/SafeDICore/Visitors/FileVisitor.swift | 4 +- .../Visitors/InstantiableVisitor.swift | 70 +- .../Visitors/SafeDIConfigurationVisitor.swift | 2 +- .../SafeDIMacros/Macros/InjectableMacro.swift | 14 +- .../Macros/InstantiableMacro.swift | 136 +- .../Macros/SafeDIConfigurationMacro.swift | 12 +- Sources/SafeDITool/SafeDITool.swift | 43 +- Tests/SafeDICoreTests/FileVisitorTests.swift | 141 +- Tests/SafeDICoreTests/InitializerTests.swift | 79 +- .../TypeDescriptionTests.swift | 25 +- .../UnorderedEquatingCollectionTests.swift | 3 +- .../AssertMacroExpansion.swift | 8 +- .../InjectableMacroTests.swift | 69 +- .../InstantiableMacroTests.swift | 353 +- .../SafeDIConfigurationMacroTests.swift | 41 +- .../SafeDITests/ErasedInstantiatorTests.swift | 5 +- Tests/SafeDITests/InstantiatorTests.swift | 5 +- .../SendableErasedInstantiatorTests.swift | 1 - .../SendableInstantiatorTests.swift | 1 - .../Helpers/SafeDIToolTestExecution.swift | 9 +- .../SafeDIToolCodeGenerationErrorTests.swift | 193 +- .../SafeDIToolCodeGenerationTests.swift | 3156 ++++++++--------- .../SafeDIToolDOTGenerationTests.swift | 537 ++- 57 files changed, 2607 insertions(+), 2719 deletions(-) diff --git a/CLI/Package.swift b/CLI/Package.swift index 36311c48..cb7e4773 100644 --- a/CLI/Package.swift +++ b/CLI/Package.swift @@ -12,5 +12,5 @@ let package = Package( dependencies: [ .package(url: "https://github.com/nicklockwood/SwiftFormat", from: "0.60.1"), ], - targets: [] + targets: [], ) diff --git a/Examples/Example Package Integration/Package.swift b/Examples/Example Package Integration/Package.swift index 4d113da8..82f30b3a 100644 --- a/Examples/Example Package Integration/Package.swift +++ b/Examples/Example Package Integration/Package.swift @@ -16,7 +16,7 @@ let package = Package( // Products define the executables and libraries a package produces, making them visible to other packages. .library( name: "ExamplePackageIntegration", - targets: ["RootModule"] + targets: ["RootModule"], ), ], dependencies: [ @@ -39,7 +39,7 @@ let package = Package( ], plugins: [ .plugin(name: "SafeDIGenerator", package: "SafeDI"), - ] + ], ), .target( name: "ChildAModule", @@ -50,7 +50,7 @@ let package = Package( ], swiftSettings: [ .swiftLanguageMode(.v6), - ] + ], ), .target( name: "ChildBModule", @@ -61,7 +61,7 @@ let package = Package( ], swiftSettings: [ .swiftLanguageMode(.v6), - ] + ], ), .target( name: "ChildCModule", @@ -72,7 +72,7 @@ let package = Package( ], swiftSettings: [ .swiftLanguageMode(.v6), - ] + ], ), .target( name: "GrandchildrenModule", @@ -82,14 +82,14 @@ let package = Package( ], swiftSettings: [ .swiftLanguageMode(.v6), - ] + ], ), .target( name: "SharedModule", dependencies: ["SafeDI"], swiftSettings: [ .swiftLanguageMode(.v6), - ] + ], ), - ] + ], ) diff --git a/Examples/ExampleCocoaPodsIntegration/ExampleCocoaPodsIntegration/Views/ExampleApp.swift b/Examples/ExampleCocoaPodsIntegration/ExampleCocoaPodsIntegration/Views/ExampleApp.swift index 375e50d7..69c2a7ca 100644 --- a/Examples/ExampleCocoaPodsIntegration/ExampleCocoaPodsIntegration/Views/ExampleApp.swift +++ b/Examples/ExampleCocoaPodsIntegration/ExampleCocoaPodsIntegration/Views/ExampleApp.swift @@ -45,7 +45,7 @@ public struct NotesApp: Instantiable, App { userService: AnyUserService, stringStorage: StringStorage, nameEntryViewBuilder: Instantiator, - noteViewBuilder: Instantiator + noteViewBuilder: Instantiator, ) { self.userService = userService self.stringStorage = stringStorage diff --git a/Examples/ExampleCocoaPodsIntegration/ExampleCocoaPodsIntegration/Views/NameEntryView.swift b/Examples/ExampleCocoaPodsIntegration/ExampleCocoaPodsIntegration/Views/NameEntryView.swift index 3ebcba7e..b4e0d1c3 100644 --- a/Examples/ExampleCocoaPodsIntegration/ExampleCocoaPodsIntegration/Views/NameEntryView.swift +++ b/Examples/ExampleCocoaPodsIntegration/ExampleCocoaPodsIntegration/Views/NameEntryView.swift @@ -33,7 +33,7 @@ public struct NameEntryView: Instantiable, View { TextField( text: $name, prompt: Text("Enter your name"), - label: {} + label: {}, ) Button(action: { userService.userName = name diff --git a/Examples/ExampleCocoaPodsIntegration/ExampleCocoaPodsIntegration/Views/NoteView.swift b/Examples/ExampleCocoaPodsIntegration/ExampleCocoaPodsIntegration/Views/NoteView.swift index 87ed1768..d270a4a6 100644 --- a/Examples/ExampleCocoaPodsIntegration/ExampleCocoaPodsIntegration/Views/NoteView.swift +++ b/Examples/ExampleCocoaPodsIntegration/ExampleCocoaPodsIntegration/Views/NoteView.swift @@ -58,6 +58,6 @@ public struct NoteView: Instantiable, View { NoteView( userName: "dfed", userService: .init(DefaultUserService(stringStorage: UserDefaults.standard)), - stringStorage: UserDefaults.standard + stringStorage: UserDefaults.standard, ) } diff --git a/Examples/ExampleMultiProjectIntegration/ExampleMultiProjectIntegration/Views/ExampleApp.swift b/Examples/ExampleMultiProjectIntegration/ExampleMultiProjectIntegration/Views/ExampleApp.swift index cca8f864..9e0879ec 100644 --- a/Examples/ExampleMultiProjectIntegration/ExampleMultiProjectIntegration/Views/ExampleApp.swift +++ b/Examples/ExampleMultiProjectIntegration/ExampleMultiProjectIntegration/Views/ExampleApp.swift @@ -46,7 +46,7 @@ public struct NotesApp: Instantiable, App { userService: AnyUserService, stringStorage: StringStorage, nameEntryViewBuilder: Instantiator, - noteViewBuilder: Instantiator + noteViewBuilder: Instantiator, ) { self.userService = userService self.stringStorage = stringStorage diff --git a/Examples/ExampleMultiProjectIntegration/ExampleMultiProjectIntegration/Views/NameEntryView.swift b/Examples/ExampleMultiProjectIntegration/ExampleMultiProjectIntegration/Views/NameEntryView.swift index 8b024fe6..64e05a5f 100644 --- a/Examples/ExampleMultiProjectIntegration/ExampleMultiProjectIntegration/Views/NameEntryView.swift +++ b/Examples/ExampleMultiProjectIntegration/ExampleMultiProjectIntegration/Views/NameEntryView.swift @@ -34,7 +34,7 @@ public struct NameEntryView: Instantiable, View { TextField( text: $name, prompt: Text("Enter your name"), - label: {} + label: {}, ) Button(action: { userService.userName = name diff --git a/Examples/ExampleMultiProjectIntegration/ExampleMultiProjectIntegration/Views/NoteView.swift b/Examples/ExampleMultiProjectIntegration/ExampleMultiProjectIntegration/Views/NoteView.swift index cd165d32..92aadb0f 100644 --- a/Examples/ExampleMultiProjectIntegration/ExampleMultiProjectIntegration/Views/NoteView.swift +++ b/Examples/ExampleMultiProjectIntegration/ExampleMultiProjectIntegration/Views/NoteView.swift @@ -59,6 +59,6 @@ public struct NoteView: Instantiable, View { NoteView( userName: "dfed", userService: .init(DefaultUserService(stringStorage: UserDefaults.standard)), - stringStorage: UserDefaults.standard + stringStorage: UserDefaults.standard, ) } diff --git a/Examples/ExamplePrebuiltPackageIntegration/Package.swift b/Examples/ExamplePrebuiltPackageIntegration/Package.swift index 0aba458c..592e1947 100644 --- a/Examples/ExamplePrebuiltPackageIntegration/Package.swift +++ b/Examples/ExamplePrebuiltPackageIntegration/Package.swift @@ -16,7 +16,7 @@ let package = Package( // Products define the executables and libraries a package produces, making them visible to other packages. .library( name: "ExamplePackageIntegration", - targets: ["RootModule"] + targets: ["RootModule"], ), ], dependencies: [ @@ -39,7 +39,7 @@ let package = Package( ], plugins: [ .plugin(name: "SafeDIPrebuiltGenerator", package: "SafeDI"), - ] + ], ), .target( name: "ChildAModule", @@ -50,7 +50,7 @@ let package = Package( ], swiftSettings: [ .swiftLanguageMode(.v6), - ] + ], ), .target( name: "ChildBModule", @@ -61,7 +61,7 @@ let package = Package( ], swiftSettings: [ .swiftLanguageMode(.v6), - ] + ], ), .target( name: "ChildCModule", @@ -72,7 +72,7 @@ let package = Package( ], swiftSettings: [ .swiftLanguageMode(.v6), - ] + ], ), .target( name: "GrandchildrenModule", @@ -82,14 +82,14 @@ let package = Package( ], swiftSettings: [ .swiftLanguageMode(.v6), - ] + ], ), .target( name: "SharedModule", dependencies: ["SafeDI"], swiftSettings: [ .swiftLanguageMode(.v6), - ] + ], ), - ] + ], ) diff --git a/Examples/ExampleProjectIntegration/ExampleProjectIntegration/Views/ExampleApp.swift b/Examples/ExampleProjectIntegration/ExampleProjectIntegration/Views/ExampleApp.swift index 375e50d7..69c2a7ca 100644 --- a/Examples/ExampleProjectIntegration/ExampleProjectIntegration/Views/ExampleApp.swift +++ b/Examples/ExampleProjectIntegration/ExampleProjectIntegration/Views/ExampleApp.swift @@ -45,7 +45,7 @@ public struct NotesApp: Instantiable, App { userService: AnyUserService, stringStorage: StringStorage, nameEntryViewBuilder: Instantiator, - noteViewBuilder: Instantiator + noteViewBuilder: Instantiator, ) { self.userService = userService self.stringStorage = stringStorage diff --git a/Examples/ExampleProjectIntegration/ExampleProjectIntegration/Views/NameEntryView.swift b/Examples/ExampleProjectIntegration/ExampleProjectIntegration/Views/NameEntryView.swift index 3ebcba7e..b4e0d1c3 100644 --- a/Examples/ExampleProjectIntegration/ExampleProjectIntegration/Views/NameEntryView.swift +++ b/Examples/ExampleProjectIntegration/ExampleProjectIntegration/Views/NameEntryView.swift @@ -33,7 +33,7 @@ public struct NameEntryView: Instantiable, View { TextField( text: $name, prompt: Text("Enter your name"), - label: {} + label: {}, ) Button(action: { userService.userName = name diff --git a/Examples/ExampleProjectIntegration/ExampleProjectIntegration/Views/NoteView.swift b/Examples/ExampleProjectIntegration/ExampleProjectIntegration/Views/NoteView.swift index 87ed1768..d270a4a6 100644 --- a/Examples/ExampleProjectIntegration/ExampleProjectIntegration/Views/NoteView.swift +++ b/Examples/ExampleProjectIntegration/ExampleProjectIntegration/Views/NoteView.swift @@ -58,6 +58,6 @@ public struct NoteView: Instantiable, View { NoteView( userName: "dfed", userService: .init(DefaultUserService(stringStorage: UserDefaults.standard)), - stringStorage: UserDefaults.standard + stringStorage: UserDefaults.standard, ) } diff --git a/Package.swift b/Package.swift index a9d6b86d..d45710fa 100644 --- a/Package.swift +++ b/Package.swift @@ -18,21 +18,21 @@ let package = Package( /// A library containing SafeDI macros, property wrappers, and types. .library( name: "SafeDI", - targets: ["SafeDI"] + targets: ["SafeDI"], ), /// A SafeDI plugin that must be run on the root source module in a project. .plugin( name: "SafeDIGenerator", - targets: ["SafeDIGenerator"] + targets: ["SafeDIGenerator"], ), /// A SafeDI plugin that must be run on the root source module in a project that does not build SwiftSyntax from source. .plugin( name: "SafeDIPrebuiltGenerator", - targets: ["SafeDIPrebuiltGenerator"] + targets: ["SafeDIPrebuiltGenerator"], ), .plugin( name: "InstallSafeDITool", - targets: ["InstallSafeDITool"] + targets: ["InstallSafeDITool"], ), ], dependencies: [ @@ -47,7 +47,7 @@ let package = Package( dependencies: ["SafeDIMacros"], swiftSettings: [ .swiftLanguageMode(.v6), - ] + ], ), .testTarget( name: "SafeDITests", @@ -57,7 +57,7 @@ let package = Package( ], swiftSettings: [ .swiftLanguageMode(.v6), - ] + ], ), .macro( name: "SafeDIMacros", @@ -71,7 +71,7 @@ let package = Package( ], swiftSettings: [ .swiftLanguageMode(.v6), - ] + ], ), .testTarget( name: "SafeDIMacrosTests", @@ -82,7 +82,7 @@ let package = Package( ], swiftSettings: [ .swiftLanguageMode(.v6), - ] + ], ), // Plugins @@ -91,20 +91,20 @@ let package = Package( capability: .command( intent: .custom( verb: "safedi-release-install", - description: "Installs a release version of the SafeDITool build plugin executable." + description: "Installs a release version of the SafeDITool build plugin executable.", ), permissions: [ .writeToPackageDirectory(reason: "Downloads the SafeDI release build plugin executable into your project directory."), .allowNetworkConnections(scope: .all(ports: []), reason: "Downloads the SafeDI release build plugin executable from GitHub."), - ] + ], ), - dependencies: [] + dependencies: [], ), .plugin( name: "SafeDIGenerator", capability: .buildTool(), - dependencies: ["SafeDITool"] + dependencies: ["SafeDITool"], ), .executableTarget( name: "SafeDITool", @@ -115,7 +115,7 @@ let package = Package( ], swiftSettings: [ .swiftLanguageMode(.v6), - ] + ], ), .testTarget( name: "SafeDIToolTests", @@ -125,13 +125,13 @@ let package = Package( ], swiftSettings: [ .swiftLanguageMode(.v6), - ] + ], ), .plugin( name: "SafeDIPrebuiltGenerator", capability: .buildTool(), - dependencies: [] + dependencies: [], ), // Core @@ -145,14 +145,14 @@ let package = Package( ], swiftSettings: [ .swiftLanguageMode(.v6), - ] + ], ), .testTarget( name: "SafeDICoreTests", dependencies: ["SafeDICore"], swiftSettings: [ .swiftLanguageMode(.v6), - ] + ], ), - ] + ], ) diff --git a/Plugins/InstallSafeDITool/InstallCLIPluginCommand.swift b/Plugins/InstallSafeDITool/InstallCLIPluginCommand.swift index af4ff67c..641396fc 100644 --- a/Plugins/InstallSafeDITool/InstallCLIPluginCommand.swift +++ b/Plugins/InstallSafeDITool/InstallCLIPluginCommand.swift @@ -28,7 +28,7 @@ import PackagePlugin struct InstallSafeDITool: CommandPlugin { func performCommand( context: PackagePlugin.PluginContext, - arguments _: [String] + arguments _: [String], ) async throws { guard let safeDIOrigin = context.package.dependencies.first(where: { $0.package.displayName == "SafeDI" })?.package.origin else { Diagnostics.error("No package origin found for SafeDI package") @@ -62,10 +62,10 @@ struct InstallSafeDITool: CommandPlugin { components: "releases", "download", version, - toolName + toolName, ) let (downloadedURL, _) = try await URLSession.shared.download( - for: URLRequest(url: githubDownloadURL) + for: URLRequest(url: githubDownloadURL), ) let downloadedFileAttributes = try FileManager.default.attributesOfItem(atPath: downloadedURL.path(percentEncoded: false)) guard let currentPermissions = downloadedFileAttributes[.posixPermissions] as? NSNumber, @@ -77,14 +77,14 @@ struct InstallSafeDITool: CommandPlugin { } try FileManager.default.createDirectory( at: expectedToolFolder, - withIntermediateDirectories: true + withIntermediateDirectories: true, ) if FileManager.default.fileExists(atPath: expectedToolLocation.path(percentEncoded: false)) { try FileManager.default.removeItem(at: expectedToolLocation) } try FileManager.default.moveItem( at: downloadedURL, - to: expectedToolLocation + to: expectedToolLocation, ) let gitIgnoreLocation = context.safediFolder.appending(component: ".gitignore") if !FileManager.default.fileExists(atPath: gitIgnoreLocation.path(percentEncoded: false)) { @@ -93,7 +93,7 @@ struct InstallSafeDITool: CommandPlugin { """.write( to: gitIgnoreLocation, atomically: true, - encoding: .utf8 + encoding: .utf8, ) } @@ -113,7 +113,7 @@ struct InstallSafeDITool: CommandPlugin { extension InstallSafeDITool: XcodeCommandPlugin { func performCommand( context: XcodeProjectPlugin.XcodePluginContext, - arguments _: [String] + arguments _: [String], ) throws { let version = context.safeDIVersion let safediFolder = context.safediFolder @@ -133,7 +133,7 @@ struct InstallSafeDITool: CommandPlugin { components: "releases", "download", version, - toolName + toolName, ) let dispatchGroup = DispatchGroup() @@ -141,7 +141,7 @@ struct InstallSafeDITool: CommandPlugin { Task.detached { defer { dispatchGroup.leave() } let (downloadedURL, _) = try await URLSession.shared.download( - for: URLRequest(url: githubDownloadURL) + for: URLRequest(url: githubDownloadURL), ) let downloadedFileAttributes = try FileManager.default.attributesOfItem(atPath: downloadedURL.path(percentEncoded: false)) guard let currentPermissions = downloadedFileAttributes[.posixPermissions] as? NSNumber, @@ -153,14 +153,14 @@ struct InstallSafeDITool: CommandPlugin { } try FileManager.default.createDirectory( at: expectedToolFolder, - withIntermediateDirectories: true + withIntermediateDirectories: true, ) if FileManager.default.fileExists(atPath: expectedToolLocation.path(percentEncoded: false)) { try FileManager.default.removeItem(at: expectedToolLocation) } try FileManager.default.moveItem( at: downloadedURL, - to: expectedToolLocation + to: expectedToolLocation, ) let gitIgnoreLocation = safediFolder.appending(component: ".gitignore") if !FileManager.default.fileExists(atPath: gitIgnoreLocation.path(percentEncoded: false)) { @@ -169,7 +169,7 @@ struct InstallSafeDITool: CommandPlugin { """.write( to: gitIgnoreLocation, atomically: true, - encoding: .utf8 + encoding: .utf8, ) } } diff --git a/Plugins/SafeDIGenerator/SafeDIGenerateDependencyTree.swift b/Plugins/SafeDIGenerator/SafeDIGenerateDependencyTree.swift index 4b65b377..1ff2d3c3 100644 --- a/Plugins/SafeDIGenerator/SafeDIGenerateDependencyTree.swift +++ b/Plugins/SafeDIGenerator/SafeDIGenerateDependencyTree.swift @@ -25,7 +25,7 @@ import PackagePlugin struct SafeDIGenerateDependencyTree: BuildToolPlugin { func createBuildCommands( context: PluginContext, - target: Target + target: Target, ) async throws -> [Command] { guard let sourceTarget = target as? SourceModuleTarget else { return [] @@ -52,7 +52,7 @@ struct SafeDIGenerateDependencyTree: BuildToolPlugin { .write( to: inputSourcesFile, atomically: true, - encoding: .utf8 + encoding: .utf8, ) let arguments = [ @@ -85,7 +85,7 @@ struct SafeDIGenerateDependencyTree: BuildToolPlugin { arguments: arguments, environment: [:], inputFiles: targetSwiftFiles + dependenciesSourceFiles, - outputFiles: [outputSwiftFile] + outputFiles: [outputSwiftFile], ), ] } @@ -124,7 +124,7 @@ extension Target { extension SafeDIGenerateDependencyTree: XcodeBuildToolPlugin { func createBuildCommands( context: XcodeProjectPlugin.XcodePluginContext, - target: XcodeProjectPlugin.XcodeTarget + target: XcodeProjectPlugin.XcodeTarget, ) throws -> [PackagePlugin.Command] { // As of Xcode 15.0.1, Swift Package Plugins in Xcode are unable // to inspect target dependencies. As a result, this Xcode plugin @@ -150,7 +150,7 @@ extension Target { .write( to: inputSourcesFile, atomically: true, - encoding: .utf8 + encoding: .utf8, ) let arguments = [ @@ -180,7 +180,7 @@ extension Target { arguments: arguments, environment: [:], inputFiles: inputSwiftFiles, - outputFiles: [outputSwiftFile] + outputFiles: [outputSwiftFile], ), ] } diff --git a/Plugins/SafeDIPrebuiltGenerator/SafeDIGenerateDependencyTree.swift b/Plugins/SafeDIPrebuiltGenerator/SafeDIGenerateDependencyTree.swift index 13c4eb38..4d4ba618 100644 --- a/Plugins/SafeDIPrebuiltGenerator/SafeDIGenerateDependencyTree.swift +++ b/Plugins/SafeDIPrebuiltGenerator/SafeDIGenerateDependencyTree.swift @@ -25,7 +25,7 @@ import PackagePlugin struct SafeDIGenerateDependencyTree: BuildToolPlugin { func createBuildCommands( context: PluginContext, - target: Target + target: Target, ) async throws -> [Command] { guard let sourceTarget = target as? SourceModuleTarget else { return [] @@ -52,7 +52,7 @@ struct SafeDIGenerateDependencyTree: BuildToolPlugin { .write( to: inputSourcesFile, atomically: true, - encoding: .utf8 + encoding: .utf8, ) let arguments = [ @@ -95,7 +95,7 @@ struct SafeDIGenerateDependencyTree: BuildToolPlugin { arguments: arguments, environment: [:], inputFiles: targetSwiftFiles + dependenciesSourceFiles, - outputFiles: [outputSwiftFile] + outputFiles: [outputSwiftFile], ), ] } @@ -134,7 +134,7 @@ extension Target { extension SafeDIGenerateDependencyTree: XcodeBuildToolPlugin { func createBuildCommands( context: XcodeProjectPlugin.XcodePluginContext, - target: XcodeProjectPlugin.XcodeTarget + target: XcodeProjectPlugin.XcodeTarget, ) throws -> [PackagePlugin.Command] { // As of Xcode 15.0.1, Swift Package Plugins in Xcode are unable // to inspect target dependencies. As a result, this Xcode plugin @@ -160,7 +160,7 @@ extension Target { .write( to: inputSourcesFile, atomically: true, - encoding: .utf8 + encoding: .utf8, ) let arguments = [ @@ -188,7 +188,7 @@ extension Target { arguments: arguments, environment: [:], inputFiles: inputSwiftFiles, - outputFiles: [outputSwiftFile] + outputFiles: [outputSwiftFile], ), ] } diff --git a/Plugins/Shared.swift b/Plugins/Shared.swift index cb619358..dc3d23b3 100644 --- a/Plugins/Shared.swift +++ b/Plugins/Shared.swift @@ -40,22 +40,20 @@ import PackagePlugin var safediFolder: URL { xcodeProject.directoryURL.appending( - component: ".safedi" + component: ".safedi", ) } var expectedToolFolder: URL { - let location = safediFolder.appending( - component: safeDIVersion + safediFolder.appending( + component: safeDIVersion, ) - return location } var expectedToolLocation: URL { - let location = expectedToolFolder.appending( - component: "safeditool" + expectedToolFolder.appending( + component: "safeditool", ) - return location } var downloadedToolLocation: URL? { @@ -89,24 +87,22 @@ extension PackagePlugin.PluginContext { var safediFolder: URL { package.directoryURL.appending( - component: ".safedi" + component: ".safedi", ) } var expectedToolFolder: URL? { guard let safeDIVersion else { return nil } - let location = safediFolder.appending( - component: safeDIVersion + return safediFolder.appending( + component: safeDIVersion, ) - return location } var expectedToolLocation: URL? { guard let expectedToolFolder else { return nil } - let location = expectedToolFolder.appending( - component: "safeditool" + return expectedToolFolder.appending( + component: "safeditool", ) - return location } var downloadedToolLocation: URL? { diff --git a/Sources/SafeDI/Decorators/Instantiable.swift b/Sources/SafeDI/Decorators/Instantiable.swift index e7fb2da4..d2ee8da5 100644 --- a/Sources/SafeDI/Decorators/Instantiable.swift +++ b/Sources/SafeDI/Decorators/Instantiable.swift @@ -57,7 +57,7 @@ public macro Instantiable( isRoot: Bool = false, fulfillingAdditionalTypes additionalTypes: [Any.Type] = [], - conformsElsewhere: Bool = false + conformsElsewhere: Bool = false, ) = #externalMacro(module: "SafeDIMacros", type: "InstantiableMacro") /// A type that can be instantiated with runtime-injected properties. diff --git a/Sources/SafeDI/Decorators/Instantiated.swift b/Sources/SafeDI/Decorators/Instantiated.swift index 1eb9a9d6..23334a7b 100644 --- a/Sources/SafeDI/Decorators/Instantiated.swift +++ b/Sources/SafeDI/Decorators/Instantiated.swift @@ -46,5 +46,5 @@ public macro Instantiated() = #externalMacro(module: "SafeDIMacros", type: "Inje @attached(peer) public macro Instantiated( fulfilledByType concreteTypeName: StaticString, - erasedToConcreteExistential: Bool = false + erasedToConcreteExistential: Bool = false, ) = #externalMacro(module: "SafeDIMacros", type: "InjectableMacro") diff --git a/Sources/SafeDI/Decorators/Received.swift b/Sources/SafeDI/Decorators/Received.swift index 99757355..cc837994 100644 --- a/Sources/SafeDI/Decorators/Received.swift +++ b/Sources/SafeDI/Decorators/Received.swift @@ -55,5 +55,5 @@ public macro Received( fulfilledByDependencyNamed: StaticString, ofType concreteType: T.Type, erasedToConcreteExistential: Bool = false, - onlyIfAvailable: Bool = false + onlyIfAvailable: Bool = false, ) = #externalMacro(module: "SafeDIMacros", type: "InjectableMacro") diff --git a/Sources/SafeDICore/Extensions/DiagnosticExtensions.swift b/Sources/SafeDICore/Extensions/DiagnosticExtensions.swift index fe5dc94a..eab652bb 100644 --- a/Sources/SafeDICore/Extensions/DiagnosticExtensions.swift +++ b/Sources/SafeDICore/Extensions/DiagnosticExtensions.swift @@ -28,7 +28,7 @@ extension Diagnostic { error: some DiagnosticError, highlights: [Syntax]? = nil, notes: [Note] = [], - changes: [FixIt.Change] + changes: [FixIt.Change], ) { self.init( node: node, @@ -39,9 +39,9 @@ extension Diagnostic { fixIts: [ FixIt( message: error.fixIt, - changes: changes + changes: changes, ), - ] + ], ) } } diff --git a/Sources/SafeDICore/Extensions/ImportDeclSyntaxExtensions.swift b/Sources/SafeDICore/Extensions/ImportDeclSyntaxExtensions.swift index d632464c..53241f03 100644 --- a/Sources/SafeDICore/Extensions/ImportDeclSyntaxExtensions.swift +++ b/Sources/SafeDICore/Extensions/ImportDeclSyntaxExtensions.swift @@ -31,7 +31,7 @@ extension ImportDeclSyntax { type: path .map(\.name.text) .dropFirst() - .joined(separator: ".") + .joined(separator: "."), ) } diff --git a/Sources/SafeDICore/Generators/DependencyTreeGenerator.swift b/Sources/SafeDICore/Generators/DependencyTreeGenerator.swift index cf480a1d..43c867cf 100644 --- a/Sources/SafeDICore/Generators/DependencyTreeGenerator.swift +++ b/Sources/SafeDICore/Generators/DependencyTreeGenerator.swift @@ -25,7 +25,7 @@ public actor DependencyTreeGenerator { public init( importStatements: [ImportStatement], - typeDescriptionToFulfillingInstantiableMap: [TypeDescription: Instantiable] + typeDescriptionToFulfillingInstantiableMap: [TypeDescription: Instantiable], ) { self.importStatements = importStatements self.typeDescriptionToFulfillingInstantiableMap = typeDescriptionToFulfillingInstantiableMap @@ -38,7 +38,7 @@ public actor DependencyTreeGenerator { let dependencyTree = try await withThrowingTaskGroup( of: String.self, - returning: String.self + returning: String.self, ) { taskGroup in for rootScopeGenerator in rootScopeGenerators { taskGroup.addTask { try await rootScopeGenerator.generateCode() } @@ -65,7 +65,7 @@ public actor DependencyTreeGenerator { let dependencyTree = try await withThrowingTaskGroup( of: String.self, - returning: String.self + returning: String.self, ) { taskGroup in for rootScopeGenerator in rootScopeGenerators { taskGroup.addTask { try await rootScopeGenerator.generateDOT() } @@ -178,7 +178,7 @@ public actor DependencyTreeGenerator { for: nil, propertyStack: [], receivableProperties: [], - erasedToConcreteExistential: false + erasedToConcreteExistential: false, ) } }() @@ -219,7 +219,7 @@ public actor DependencyTreeGenerator { typeDescriptionToFulfillingInstantiableMap .values .filter(\.isRoot) - .map(\.concreteInstantiable) + .map(\.concreteInstantiable), ) /// A collection of `@Instantiable`-decorated types that are instantiated by at least one other @@ -284,14 +284,14 @@ public actor DependencyTreeGenerator { .instantiableHasForwardedProperty( property: dependency.property, instantiableWithForwardedProperty: instantiable, - parent: scope.instantiable + parent: scope.instantiable, ) } } scope.propertiesToGenerate.append(.instantiated( dependency.property, instantiatedScope, - erasedToConcreteExistential: erasedToConcreteExistential + erasedToConcreteExistential: erasedToConcreteExistential, )) } case let .aliased(fulfillingProperty, erasedToConcreteExistential, onlyIfAvailable): @@ -299,7 +299,7 @@ public actor DependencyTreeGenerator { dependency.property, fulfilledBy: fulfillingProperty, erasedToConcreteExistential: erasedToConcreteExistential, - onlyIfAvailable: onlyIfAvailable + onlyIfAvailable: onlyIfAvailable, )) case .forwarded, .received: continue @@ -316,19 +316,19 @@ public actor DependencyTreeGenerator { receivableProperties: Set, property: Property?, propertyStack: OrderedSet, - root: TypeDescription + root: TypeDescription, ) throws { if let property { func validateNoCycleInReceivedProperties( scope: Scope, receivedPropertyStack: OrderedSet, - instantiationStack: OrderedSet + instantiationStack: OrderedSet, ) throws { for childProperty in scope.requiredReceivedProperties { guard childProperty != property else { throw DependencyTreeGeneratorError.receivedConstantCycleDetected( instantiated: property, - receivedPropertyChain: receivedPropertyStack + [childProperty] + receivedPropertyChain: receivedPropertyStack + [childProperty], ) } guard !receivedPropertyStack.contains(childProperty) else { @@ -340,7 +340,7 @@ public actor DependencyTreeGenerator { let typesInCycle = ( [childProperty] + receivedPropertyStack.reversed() - + instantiationProperties + + instantiationProperties, ).map(\.typeDescription) switch childProperty.propertyType { case .instantiator, @@ -350,7 +350,7 @@ public actor DependencyTreeGenerator { throw DependencyTreeGeneratorError.receivedInstantiatorDependencyCycleDetected( property: childProperty, directParent: scope.instantiable.concreteInstantiable, - cycle: typesInCycle + cycle: typesInCycle, ) case .constant: throw DependencyTreeGeneratorError.constantDependencyCycleDetected(typesInCycle) @@ -361,7 +361,7 @@ public actor DependencyTreeGenerator { try validateNoCycleInReceivedProperties( scope: receivedPropertyScope, receivedPropertyStack: childPropertyStack, - instantiationStack: instantiationStack + instantiationStack: instantiationStack, ) } } @@ -371,7 +371,7 @@ public actor DependencyTreeGenerator { try validateNoCycleInReceivedProperties( scope: scope, receivedPropertyStack: [], - instantiationStack: instantiationStack + instantiationStack: instantiationStack, ) } @@ -388,7 +388,7 @@ public actor DependencyTreeGenerator { suggestedAlternatives: receivableProperties.filter { receivedProperty.typeDescription.leastQualifiedTypeDescription == $0.typeDescription.leastQualifiedTypeDescription || receivedProperty.label == $0.label - }.sorted() + }.sorted(), )) } } @@ -406,7 +406,7 @@ public actor DependencyTreeGenerator { } let typesInCycle = ( [propertyForDependency] - + childPropertyStack.elements[0...cycleIndex] + + childPropertyStack.elements[0...cycleIndex], ).map(\.typeDescription) if propertyForDependency.propertyType.isConstant { // We can break a constant dependency cycle if there's lazy instantiation in the tree. @@ -417,7 +417,7 @@ public actor DependencyTreeGenerator { throw DependencyTreeGeneratorError.receivedInstantiatorDependencyCycleDetected( property: propertyForDependency, directParent: scope.instantiable.concreteInstantiable, - cycle: typesInCycle + cycle: typesInCycle, ) } } @@ -436,7 +436,7 @@ public actor DependencyTreeGenerator { .removing(childProperty), property: childProperty, propertyStack: childPropertyStack, - root: root + root: root, ) case .aliased: break @@ -450,7 +450,7 @@ public actor DependencyTreeGenerator { receivableProperties: Set(rootScope.properties), property: nil, propertyStack: [], - root: rootScope.instantiable.concreteInstantiable + root: rootScope.instantiable.concreteInstantiable, ) } diff --git a/Sources/SafeDICore/Generators/ScopeGenerator.swift b/Sources/SafeDICore/Generators/ScopeGenerator.swift index 0843d363..8ebae564 100644 --- a/Sources/SafeDICore/Generators/ScopeGenerator.swift +++ b/Sources/SafeDICore/Generators/ScopeGenerator.swift @@ -30,7 +30,7 @@ actor ScopeGenerator: CustomStringConvertible, Sendable { propertiesToGenerate: [ScopeGenerator], unavailableOptionalProperties: Set, erasedToConcreteExistential: Bool, - isPropertyCycle: Bool + isPropertyCycle: Bool, ) { if let property { scopeData = .property( @@ -40,10 +40,10 @@ actor ScopeGenerator: CustomStringConvertible, Sendable { instantiable .dependencies .filter { $0.source == .forwarded } - .map(\.property) + .map(\.property), ), erasedToConcreteExistential: erasedToConcreteExistential, - isPropertyCycle: isPropertyCycle + isPropertyCycle: isPropertyCycle, ) description = instantiable.concreteInstantiable.asSource } else { @@ -62,7 +62,7 @@ actor ScopeGenerator: CustomStringConvertible, Sendable { .subtracting(propertiesToDeclare) // Minus the properties we forward. .subtracting(scopeData.forwardedProperties) - } + }, ) // Unioned with the properties we require to fulfill our own dependencies. .union( @@ -77,14 +77,14 @@ actor ScopeGenerator: CustomStringConvertible, Sendable { case let .aliased(fulfillingProperty, _, _): fulfillingProperty } - } + }, ) onlyIfAvailableUnwrappedReceivedProperties = Set( propertiesToGenerate.flatMap { [propertiesToDeclare, scopeData] propertyToGenerate in propertyToGenerate.onlyIfAvailableUnwrappedReceivedProperties .subtracting(propertiesToDeclare) .subtracting(scopeData.forwardedProperties) - } + }, ) .union( instantiable @@ -106,7 +106,7 @@ actor ScopeGenerator: CustomStringConvertible, Sendable { nil } } - } + }, ) } @@ -115,13 +115,13 @@ actor ScopeGenerator: CustomStringConvertible, Sendable { fulfillingProperty: Property, unavailableOptionalProperties: Set, erasedToConcreteExistential: Bool, - onlyIfAvailable: Bool + onlyIfAvailable: Bool, ) { scopeData = .alias( property: property, fulfillingProperty: fulfillingProperty, erasedToConcreteExistential: erasedToConcreteExistential, - onlyIfAvailable: onlyIfAvailable + onlyIfAvailable: onlyIfAvailable, ) receivedProperties = [fulfillingProperty] onlyIfAvailableUnwrappedReceivedProperties = if onlyIfAvailable { @@ -144,7 +144,7 @@ actor ScopeGenerator: CustomStringConvertible, Sendable { func generateCode( propertiesAlreadyGeneratedAtThisScope: Set = [], - leadingWhitespace: String = "" + leadingWhitespace: String = "", ) async throws -> String { let generatedCode: String let unavailableProperties = unavailableOptionalProperties @@ -176,10 +176,10 @@ actor ScopeGenerator: CustomStringConvertible, Sendable { property, forwardedProperties, erasedToConcreteExistential, - isPropertyCycle + isPropertyCycle, ): let argumentList = try instantiable.generateArgumentList( - unavailableProperties: unavailableProperties + unavailableProperties: unavailableProperties, ) let concreteTypeName = instantiable.concreteInstantiable.asSource let instantiationDeclaration = if instantiable.declarationType.isExtension { @@ -204,7 +204,7 @@ actor ScopeGenerator: CustomStringConvertible, Sendable { { throw GenerationError.erasedInstantiatorGenericDoesNotMatch( property: property, - instantiable: instantiable + instantiable: instantiable, ) } @@ -364,20 +364,20 @@ actor ScopeGenerator: CustomStringConvertible, Sendable { // MARK: Private - private enum ScopeData: Sendable { + private enum ScopeData { case root(instantiable: Instantiable) case property( instantiable: Instantiable, property: Property, forwardedProperties: Set, erasedToConcreteExistential: Bool, - isPropertyCycle: Bool + isPropertyCycle: Bool, ) case alias( property: Property, fulfillingProperty: Property, erasedToConcreteExistential: Bool, - onlyIfAvailable: Bool + onlyIfAvailable: Bool, ) var forwardedProperties: Set { @@ -436,7 +436,7 @@ actor ScopeGenerator: CustomStringConvertible, Sendable { .keys .intersection( scope.receivedProperties - .union(scope.onlyIfAvailableUnwrappedReceivedProperties) + .union(scope.onlyIfAvailableUnwrappedReceivedProperties), ) .compactMap { propertyToUnfulfilledScopeMap[$0] } // Fulfill the scopes we depend upon. @@ -460,8 +460,8 @@ actor ScopeGenerator: CustomStringConvertible, Sendable { try await generatedProperties.append( childGenerator.generateCode( propertiesAlreadyGeneratedAtThisScope: .init(orderedPropertiesToGenerate[0..? = nil + unavailableProperties: Set? = nil, ) throws -> String { try initializer? .createInitializerArgumentList( given: dependencies, - unavailableProperties: unavailableProperties + unavailableProperties: unavailableProperties, ) ?? "/* @Instantiable type is incorrectly configured. Fix errors from @Instantiable macro to fix this error. */" } } diff --git a/Sources/SafeDICore/Models/ConcreteDeclSyntaxProtocol.swift b/Sources/SafeDICore/Models/ConcreteDeclSyntaxProtocol.swift index 24eb6b99..2ab134bf 100644 --- a/Sources/SafeDICore/Models/ConcreteDeclSyntaxProtocol.swift +++ b/Sources/SafeDICore/Models/ConcreteDeclSyntaxProtocol.swift @@ -39,7 +39,9 @@ extension ActorDeclSyntax: ConcreteDeclSyntaxProtocol { } } - public var declType: ConcreteDeclType { .actorType } + public var declType: ConcreteDeclType { + .actorType + } } extension ClassDeclSyntax: ConcreteDeclSyntaxProtocol { @@ -52,7 +54,9 @@ extension ClassDeclSyntax: ConcreteDeclSyntaxProtocol { } } - public var declType: ConcreteDeclType { .classType } + public var declType: ConcreteDeclType { + .classType + } } extension StructDeclSyntax: ConcreteDeclSyntaxProtocol { @@ -65,5 +69,7 @@ extension StructDeclSyntax: ConcreteDeclSyntaxProtocol { } } - public var declType: ConcreteDeclType { .structType } + public var declType: ConcreteDeclType { + .structType + } } diff --git a/Sources/SafeDICore/Models/Dependency.swift b/Sources/SafeDICore/Models/Dependency.swift index ebe29740..fcc7d751 100644 --- a/Sources/SafeDICore/Models/Dependency.swift +++ b/Sources/SafeDICore/Models/Dependency.swift @@ -27,7 +27,7 @@ public struct Dependency: Codable, Hashable, Sendable { public init( property: Property, - source: Dependency.Source + source: Dependency.Source, ) { self.property = property self.source = source @@ -60,7 +60,7 @@ public struct Dependency: Codable, Hashable, Sendable { if let instantiatedMacro = node.instantiatedMacro { self = .instantiated( fulfillingTypeDescription: instantiatedMacro.fulfillingTypeDescription, - erasedToConcreteExistential: instantiatedMacro.erasedToConcreteExistentialValue + erasedToConcreteExistential: instantiatedMacro.erasedToConcreteExistentialValue, ) } else if let receivedMacro = node.receivedMacro { if let fulfillingPropertyName = receivedMacro.fulfillingPropertyName, @@ -69,10 +69,10 @@ public struct Dependency: Codable, Hashable, Sendable { self = .aliased( fulfillingProperty: Property( label: fulfillingPropertyName, - typeDescription: fulfillingTypeDescription + typeDescription: fulfillingTypeDescription, ), erasedToConcreteExistential: receivedMacro.erasedToConcreteExistentialValue, - onlyIfAvailable: receivedMacro.onlyIfAvailableValue + onlyIfAvailable: receivedMacro.onlyIfAvailableValue, ) } else { self = .received(onlyIfAvailable: receivedMacro.onlyIfAvailableValue) diff --git a/Sources/SafeDICore/Models/ImportStatement.swift b/Sources/SafeDICore/Models/ImportStatement.swift index de999a19..99678e34 100644 --- a/Sources/SafeDICore/Models/ImportStatement.swift +++ b/Sources/SafeDICore/Models/ImportStatement.swift @@ -25,7 +25,7 @@ public struct ImportStatement: Codable, Hashable, Sendable { attribute: String = "", kind: String = "", moduleName: String, - type: String = "" + type: String = "", ) { self.attribute = attribute self.kind = kind diff --git a/Sources/SafeDICore/Models/Initializer.swift b/Sources/SafeDICore/Models/Initializer.swift index f3753491..673716bb 100644 --- a/Sources/SafeDICore/Models/Initializer.swift +++ b/Sources/SafeDICore/Models/Initializer.swift @@ -60,7 +60,7 @@ public struct Initializer: Codable, Hashable, Sendable { doesThrow: Bool = false, hasGenericParameter: Bool = false, hasGenericWhereClause: Bool = false, - arguments: [Initializer.Argument] + arguments: [Initializer.Argument], ) { self.isPublicOrOpen = isPublicOrOpen self.isOptional = isOptional @@ -144,14 +144,14 @@ public struct Initializer: Codable, Hashable, Sendable { doesThrow: doesThrow, hasGenericParameter: hasGenericParameter, hasGenericWhereClause: hasGenericWhereClause, - arguments: arguments.map(transform) + arguments: arguments.map(transform), ) } public static func generateRequiredInitializer( for dependencies: [Dependency], declarationType: ConcreteDeclType, - andAdditionalPropertiesWithLabels additionalPropertyLabels: [String] = [] + andAdditionalPropertiesWithLabels additionalPropertyLabels: [String] = [], ) -> InitializerDeclSyntax { InitializerDeclSyntax( modifiers: declarationType.initializerModifiers, @@ -170,9 +170,9 @@ public struct Initializer: Codable, Hashable, Sendable { }) { functionParameter } - }) + }), ), - trailingTrivia: .space + trailingTrivia: .space, ), bodyBuilder: { for dependency in dependencies { @@ -186,19 +186,19 @@ public struct Initializer: Codable, Hashable, Sendable { + (index == 0 ? [ .lineComment("// The following properties are not decorated with the @\(Dependency.Source.instantiatedRawValue), @\(Dependency.Source.receivedRawValue), or @\(Dependency.Source.forwardedRawValue) macros, do not have default values, and are not computed properties."), TriviaPiece.newlines(1), - ] : []) + ] : []), ), leftOperand: DeclReferenceExprSyntax(baseName: TokenSyntax.identifier(additionalPropertyLabel)), operator: AssignmentExprSyntax( leadingTrivia: .space, - trailingTrivia: .space + trailingTrivia: .space, ), rightOperand: DeclReferenceExprSyntax(baseName: TokenSyntax.identifier("<#T##assign_\(additionalPropertyLabel)#>")), - trailingTrivia: additionalPropertyLabel == additionalPropertyLabels.last ? .newline : nil - ))) + trailingTrivia: additionalPropertyLabel == additionalPropertyLabels.last ? .newline : nil, + ))), ) } - } + }, ) } @@ -224,7 +224,7 @@ public struct Initializer: Codable, Hashable, Sendable { func createInitializerArgumentList( given dependencies: [Dependency], - unavailableProperties: Set? = nil + unavailableProperties: Set? = nil, ) throws(GenerationError) -> String { try createDependencyAndArgumentBinding(given: dependencies) .map { @@ -272,7 +272,7 @@ public struct Initializer: Codable, Hashable, Sendable { public var asProperty: Property { Property( label: innerLabel, - typeDescription: typeDescription + typeDescription: typeDescription, ) } @@ -300,7 +300,7 @@ public struct Initializer: Codable, Hashable, Sendable { outerLabel: outerLabel, innerLabel: innerLabel, typeDescription: typeDescription, - hasDefaultValue: hasDefaultValue + hasDefaultValue: hasDefaultValue, ) } @@ -316,10 +316,10 @@ extension ConcreteDeclType { arrayLiteral: DeclModifierSyntax( name: TokenSyntax( TokenKind.keyword(.public), - presence: .present + presence: .present, ), - trailingTrivia: .space - ) + trailingTrivia: .space, + ), ) } } diff --git a/Sources/SafeDICore/Models/InstantiableStruct.swift b/Sources/SafeDICore/Models/InstantiableStruct.swift index 0c0d298a..c733e2aa 100644 --- a/Sources/SafeDICore/Models/InstantiableStruct.swift +++ b/Sources/SafeDICore/Models/InstantiableStruct.swift @@ -27,7 +27,7 @@ public struct Instantiable: Codable, Hashable, Sendable { initializer: Initializer?, additionalInstantiables: [TypeDescription]?, dependencies: [Dependency], - declarationType: DeclarationType + declarationType: DeclarationType, ) { instantiableTypes = [instantiableType] + (additionalInstantiables ?? []) self.isRoot = isRoot diff --git a/Sources/SafeDICore/Models/Property.swift b/Sources/SafeDICore/Models/Property.swift index 5265cde6..3e905956 100644 --- a/Sources/SafeDICore/Models/Property.swift +++ b/Sources/SafeDICore/Models/Property.swift @@ -23,16 +23,6 @@ import SwiftSyntax /// A representation of a property. /// e.g. `let myProperty: MyProperty` public struct Property: Codable, Hashable, Comparable, Sendable { - // MARK: Initialization - - init( - label: String, - typeDescription: TypeDescription - ) { - self.label = label - self.typeDescription = typeDescription - } - // MARK: Public /// The label by which the property is referenced. @@ -43,7 +33,7 @@ public struct Property: Codable, Hashable, Comparable, Sendable { public func withUpdatedTypeDescription(_ typeDescription: TypeDescription) -> Self { .init( label: label, - typeDescription: typeDescription + typeDescription: typeDescription, ) } @@ -63,7 +53,7 @@ public struct Property: Codable, Hashable, Comparable, Sendable { public var asFunctionParamter: Property { .init( label: label, - typeDescription: typeDescription.asFunctionParameter + typeDescription: typeDescription.asFunctionParameter, ) } @@ -78,11 +68,11 @@ public struct Property: Codable, Hashable, Comparable, Sendable { attributes: AttributeListSyntax { AttributeSyntax(attributeName: IdentifierTypeSyntax( name: "escaping", - trailingTrivia: .space + trailingTrivia: .space, )) }, - baseType: IdentifierTypeSyntax(name: .identifier(typeDescription.asSource)) - ) + baseType: IdentifierTypeSyntax(name: .identifier(typeDescription.asSource)), + ), ) case let .attributed(typeDescription, _, attributes): FunctionParameterSyntax( @@ -94,19 +84,19 @@ public struct Property: Codable, Hashable, Comparable, Sendable { attributes: AttributeListSyntax { AttributeSyntax(attributeName: IdentifierTypeSyntax( name: "escaping", - trailingTrivia: .space + trailingTrivia: .space, )) if let attributes { for attribute in attributes { AttributeSyntax( attributeName: IdentifierTypeSyntax(name: .identifier(attribute)), - trailingTrivia: .space + trailingTrivia: .space, ) } } }, - baseType: IdentifierTypeSyntax(name: .identifier(typeDescription.asSource)) - ) + baseType: IdentifierTypeSyntax(name: .identifier(typeDescription.asSource)), + ), ) case .simple, .nested, @@ -124,7 +114,7 @@ public struct Property: Codable, Hashable, Comparable, Sendable { FunctionParameterSyntax( firstName: .identifier(label), colon: .colonToken(trailingTrivia: .space), - type: IdentifierTypeSyntax(name: .identifier(typeDescription.asSource)) + type: IdentifierTypeSyntax(name: .identifier(typeDescription.asSource)), ) } } @@ -135,17 +125,17 @@ public struct Property: Codable, Hashable, Comparable, Sendable { leadingTrivia: .newline, leftOperand: MemberAccessExprSyntax( base: DeclReferenceExprSyntax(baseName: TokenSyntax.keyword(.`self`)), - name: TokenSyntax.identifier(label) + name: TokenSyntax.identifier(label), ), operator: AssignmentExprSyntax( leadingTrivia: .space, - trailingTrivia: .space + trailingTrivia: .space, ), rightOperand: DeclReferenceExprSyntax( baseName: TokenSyntax.identifier(label), - trailingTrivia: trailingNewline ? .newline : nil - ) - ))) + trailingTrivia: trailingNewline ? .newline : nil, + ), + ))), ) } @@ -155,7 +145,7 @@ public struct Property: Codable, Hashable, Comparable, Sendable { TupleTypeElementSyntax( firstName: .identifier(label), colon: .colonToken(), - type: IdentifierTypeSyntax(name: .identifier(typeDescription.asSource)) + type: IdentifierTypeSyntax(name: .identifier(typeDescription.asSource)), ) } diff --git a/Sources/SafeDICore/Models/SafeDIConfiguration.swift b/Sources/SafeDICore/Models/SafeDIConfiguration.swift index 07fbd1b0..807df2c4 100644 --- a/Sources/SafeDICore/Models/SafeDIConfiguration.swift +++ b/Sources/SafeDICore/Models/SafeDIConfiguration.swift @@ -24,7 +24,7 @@ public struct SafeDIConfiguration: Codable, Equatable, Sendable { public init( additionalImportedModules: [String], - additionalDirectoriesToInclude: [String] + additionalDirectoriesToInclude: [String], ) { self.additionalImportedModules = additionalImportedModules self.additionalDirectoriesToInclude = additionalDirectoriesToInclude diff --git a/Sources/SafeDICore/Models/Scope.swift b/Sources/SafeDICore/Models/Scope.swift index 203edf91..90b81c5c 100644 --- a/Sources/SafeDICore/Models/Scope.swift +++ b/Sources/SafeDICore/Models/Scope.swift @@ -74,7 +74,7 @@ final class Scope: Hashable { false } } - .map(\.property) + .map(\.property), ) var requiredReceivedProperties: [Property] { @@ -105,7 +105,7 @@ final class Scope: Hashable { for property: Property?, propertyStack: OrderedSet, receivableProperties: Set, - erasedToConcreteExistential: Bool + erasedToConcreteExistential: Bool, ) throws -> ScopeGenerator { var childPropertyStack = propertyStack let isPropertyCycle: Bool @@ -149,7 +149,7 @@ final class Scope: Hashable { for: property, propertyStack: childPropertyStack, receivableProperties: receivableProperties, - erasedToConcreteExistential: erasedToConcreteExistential + erasedToConcreteExistential: erasedToConcreteExistential, ) case let .aliased(property, fulfillingProperty, erasedToConcreteExistential, onlyIfAvailable): ScopeGenerator( @@ -157,13 +157,13 @@ final class Scope: Hashable { fulfillingProperty: fulfillingProperty, unavailableOptionalProperties: unavailableOptionalProperties, erasedToConcreteExistential: erasedToConcreteExistential, - onlyIfAvailable: onlyIfAvailable + onlyIfAvailable: onlyIfAvailable, ) } }, unavailableOptionalProperties: unavailableOptionalProperties, erasedToConcreteExistential: erasedToConcreteExistential, - isPropertyCycle: isPropertyCycle + isPropertyCycle: isPropertyCycle, ) Task.detached { // Kick off code generation. diff --git a/Sources/SafeDICore/Models/TypeDescription.swift b/Sources/SafeDICore/Models/TypeDescription.swift index 685fa054..8b4e253b 100644 --- a/Sources/SafeDICore/Models/TypeDescription.swift +++ b/Sources/SafeDICore/Models/TypeDescription.swift @@ -71,13 +71,13 @@ public enum TypeDescription: Codable, Hashable, Comparable, Sendable { .nested( name: simpleNameAndGenerics.name, parentType: zip(outer: outer, inner: innerParent), - generics: simpleNameAndGenerics.generics + generics: simpleNameAndGenerics.generics, ) } else { .nested( name: simpleNameAndGenerics.name, parentType: outer, - generics: simpleNameAndGenerics.generics + generics: simpleNameAndGenerics.generics, ) } } else { @@ -397,7 +397,7 @@ extension TypeSyntax { } else { return .simple( name: typeIdentifier.name.text, - generics: genericTypeVisitor.genericArguments + generics: genericTypeVisitor.genericArguments, ) } @@ -409,7 +409,7 @@ extension TypeSyntax { return .nested( name: typeIdentifier.name.text, parentType: typeIdentifier.baseType.typeDescription, - generics: genericTypeVisitor.genericArguments + generics: genericTypeVisitor.genericArguments, ) } else if let typeIdentifiers = CompositionTypeSyntax(self) { @@ -431,7 +431,7 @@ extension TypeSyntax { } else if let typeIdentifier = MetatypeTypeSyntax(self) { return .metatype( typeIdentifier.baseType.typeDescription, - isType: typeIdentifier.metatypeSpecifier.text == "Type" + isType: typeIdentifier.metatypeSpecifier.text == "Type", ) } else if let typeIdentifier = AttributedTypeSyntax(self) { @@ -441,7 +441,7 @@ extension TypeSyntax { return .attributed( typeIdentifier.baseType.typeDescription, specifiers: typeIdentifier.specifiers.textRepresentation, - attributes: attributes.isEmpty ? nil : attributes + attributes: attributes.isEmpty ? nil : attributes, ) } else if let typeIdentifier = ArrayTypeSyntax(self) { @@ -450,14 +450,14 @@ extension TypeSyntax { } else if let typeIdentifier = DictionaryTypeSyntax(self) { return .dictionary( key: typeIdentifier.key.typeDescription, - value: typeIdentifier.value.typeDescription + value: typeIdentifier.value.typeDescription, ) } else if let typeIdentifier = TupleTypeSyntax(self) { let elements = typeIdentifier.elements.map { TypeDescription.TupleElement( label: $0.secondName?.text ?? $0.firstName?.text, - $0.type.typeDescription + $0.type.typeDescription, ) } if elements.isEmpty { @@ -480,7 +480,7 @@ extension TypeSyntax { arguments: typeIdentifier.parameters.map(\.type.typeDescription), isAsync: typeIdentifier.effectSpecifiers?.asyncSpecifier != nil, doesThrow: typeIdentifier.effectSpecifiers?.throwsClause?.throwsSpecifier != nil, - returnType: typeIdentifier.returnClause.type.typeDescription + returnType: typeIdentifier.returnClause.type.typeDescription, ) } else { @@ -500,8 +500,8 @@ extension ExprSyntax { return TypeSyntax( IdentifierTypeSyntax( name: declReferenceExpr.baseName, - genericArgumentClause: nil - ) + genericArgumentClause: nil, + ), ).typeDescription } else if let memberAccessExpr = MemberAccessExprSyntax(self), let base = memberAccessExpr.base { let declName = memberAccessExpr.declName.baseName.text @@ -515,7 +515,7 @@ extension ExprSyntax { .nested( name: declName, parentType: base.typeDescription, - generics: [] + generics: [], ) } } else if let genericExpr = GenericSpecializationExprSyntax(self) { @@ -525,12 +525,12 @@ extension ExprSyntax { case let .simple(name, _): .simple( name: name, - generics: genericTypeVisitor.genericArguments + generics: genericTypeVisitor.genericArguments, ) case let .nested(name, parentType, _): .nested( name: name, - parentType: parentType, generics: genericTypeVisitor.genericArguments + parentType: parentType, generics: genericTypeVisitor.genericArguments, ) case .any, .array, .attributed, .closure, .composition, .dictionary, .implicitlyUnwrappedOptional, .metatype, .optional, .some, .tuple, .unknown, .void: .unknown(text: trimmedDescription) @@ -549,7 +549,7 @@ extension ExprSyntax { .tuple(tupleElements.map { TypeDescription.TupleElement( label: $0.label?.text, - $0.expression.typeDescription + $0.expression.typeDescription, ) }) } @@ -559,12 +559,12 @@ extension ExprSyntax { sequenceExpr .elements .filter { BinaryOperatorExprSyntax($0) == nil } - .map(\.typeDescription) + .map(\.typeDescription), )) } else if sequenceExpr.elements.count == 3, let arguments = TupleExprSyntax(sequenceExpr.elements.first), let arrow = ArrowExprSyntax(sequenceExpr.elements[ - sequenceExpr.elements.index(after: sequenceExpr.elements.startIndex) + sequenceExpr.elements.index(after: sequenceExpr.elements.startIndex), ]), let returnType = sequenceExpr.elements.last { @@ -572,7 +572,7 @@ extension ExprSyntax { arguments: arguments.elements.map(\.expression.typeDescription), isAsync: arrow.effectSpecifiers?.asyncSpecifier != nil, doesThrow: arrow.effectSpecifiers?.throwsClause?.throwsSpecifier != nil, - returnType: returnType.typeDescription + returnType: returnType.typeDescription, ) } } else if let optionalChainingExpr = OptionalChainingExprSyntax(self) { @@ -589,7 +589,7 @@ extension ExprSyntax { { return .dictionary( key: onlyElement.key.typeDescription, - value: onlyElement.value.typeDescription + value: onlyElement.value.typeDescription, ) } return .unknown(text: trimmedDescription) diff --git a/Sources/SafeDICore/Models/UnorderedEquatingCollection.swift b/Sources/SafeDICore/Models/UnorderedEquatingCollection.swift index 51c382ba..0740c28e 100644 --- a/Sources/SafeDICore/Models/UnorderedEquatingCollection.swift +++ b/Sources/SafeDICore/Models/UnorderedEquatingCollection.swift @@ -40,9 +40,18 @@ public struct UnorderedEquatingCollection: Hashable, Collecti // MARK: Collection - public func makeIterator() -> IndexingIterator<[Element]> { array.makeIterator() } - public var startIndex: Int { array.startIndex } - public var endIndex: Int { array.endIndex } + public func makeIterator() -> IndexingIterator<[Element]> { + array.makeIterator() + } + + public var startIndex: Int { + array.startIndex + } + + public var endIndex: Int { + array.endIndex + } + public func index(after i: Int) -> Int { array.index(after: i) } diff --git a/Sources/SafeDICore/Visitors/FileVisitor.swift b/Sources/SafeDICore/Visitors/FileVisitor.swift index c02d4a39..f163ca02 100644 --- a/Sources/SafeDICore/Visitors/FileVisitor.swift +++ b/Sources/SafeDICore/Visitors/FileVisitor.swift @@ -98,7 +98,7 @@ public final class FileVisitor: SyntaxVisitor { public override func visit(_ node: ExtensionDeclSyntax) -> SyntaxVisitorContinueKind { let instantiableVisitor = InstantiableVisitor( declarationType: .extensionDecl, - parentType: nil + parentType: nil, ) instantiableVisitor.walk(node) for instantiable in instantiableVisitor.instantiables { @@ -140,7 +140,7 @@ public final class FileVisitor: SyntaxVisitor { private func visitDecl(_ node: some ConcreteDeclSyntaxProtocol) -> SyntaxVisitorContinueKind { let instantiableVisitor = InstantiableVisitor( declarationType: .concreteDecl, - parentType: parentType + parentType: parentType, ) instantiableVisitor.walk(node) for instantiable in instantiableVisitor.instantiables { diff --git a/Sources/SafeDICore/Visitors/InstantiableVisitor.swift b/Sources/SafeDICore/Visitors/InstantiableVisitor.swift index e2b61a40..bafa414b 100644 --- a/Sources/SafeDICore/Visitors/InstantiableVisitor.swift +++ b/Sources/SafeDICore/Visitors/InstantiableVisitor.swift @@ -26,7 +26,7 @@ public final class InstantiableVisitor: SyntaxVisitor { public init( declarationType: DeclarationType, - parentType: TypeDescription? = nil + parentType: TypeDescription? = nil, ) { self.declarationType = declarationType self.parentType = parentType @@ -50,9 +50,9 @@ public final class InstantiableVisitor: SyntaxVisitor { changes: [ .replace( oldNode: Syntax(node.attributes), - newNode: Syntax(dependencySources[0].node) + newNode: Syntax(dependencySources[0].node), ), - ] + ], )) } guard let dependencySource = dependencySources.first?.source else { @@ -86,9 +86,9 @@ public final class InstantiableVisitor: SyntaxVisitor { changes: [ .replace( oldNode: Syntax(binding), - newNode: Syntax(bindingWithoutInitializer) + newNode: Syntax(bindingWithoutInitializer), ), - ] + ], )) } @@ -99,10 +99,10 @@ public final class InstantiableVisitor: SyntaxVisitor { Dependency( property: Property( label: label, - typeDescription: typeDescription + typeDescription: typeDescription, ), - source: dependencySource - ) + source: dependencySource, + ), ) } } @@ -166,13 +166,13 @@ public final class InstantiableVisitor: SyntaxVisitor { modifiedSignature.returnClause = ReturnClauseSyntax( arrow: .arrowToken( leadingTrivia: returnClause.arrow.leadingTrivia, - trailingTrivia: returnClause.arrow.trailingTrivia + trailingTrivia: returnClause.arrow.trailingTrivia, ), type: IdentifierTypeSyntax( leadingTrivia: node.signature.leadingTrivia, name: .identifier(instantiableType.strippingGenerics.asSource), - trailingTrivia: node.signature.trailingTrivia - ) + trailingTrivia: node.signature.trailingTrivia, + ), ) diagnostics.append(Diagnostic( node: node, @@ -180,9 +180,9 @@ public final class InstantiableVisitor: SyntaxVisitor { changes: [ .replace( oldNode: Syntax(node.signature), - newNode: Syntax(modifiedSignature) + newNode: Syntax(modifiedSignature), ), - ] + ], )) } @@ -196,10 +196,10 @@ public final class InstantiableVisitor: SyntaxVisitor { dependencies: initializer.arguments.map { Dependency( property: $0.asProperty, - source: .received(onlyIfAvailable: false) + source: .received(onlyIfAvailable: false), ) }, - declarationType: .extensionType + declarationType: .extensionType, )) } @@ -211,17 +211,17 @@ public final class InstantiableVisitor: SyntaxVisitor { name: TokenSyntax( TokenKind.keyword(.public), leadingTrivia: node.modifiers.first?.leadingTrivia ?? node.funcKeyword.leadingTrivia, - presence: .present - ) + presence: .present, + ), ), DeclModifierSyntax( name: TokenSyntax( TokenKind.keyword(.static), leadingTrivia: .space, trailingTrivia: .space, - presence: .present - ) - ) + presence: .present, + ), + ), ) modifiedNode.funcKeyword.leadingTrivia = [] diagnostics.append(Diagnostic( @@ -230,9 +230,9 @@ public final class InstantiableVisitor: SyntaxVisitor { changes: [ .replace( oldNode: Syntax(node), - newNode: Syntax(modifiedNode) + newNode: Syntax(modifiedNode), ), - ] + ], )) } if initializer.isAsync || initializer.doesThrow { @@ -244,9 +244,9 @@ public final class InstantiableVisitor: SyntaxVisitor { changes: [ .replace( oldNode: Syntax(node.signature), - newNode: Syntax(modifiedSignature) + newNode: Syntax(modifiedSignature), ), - ] + ], )) } if initializer.hasGenericParameter { @@ -258,9 +258,9 @@ public final class InstantiableVisitor: SyntaxVisitor { changes: [ .replace( oldNode: Syntax(node), - newNode: Syntax(modifiedNode) + newNode: Syntax(modifiedNode), ), - ] + ], )) } if initializer.hasGenericWhereClause { @@ -272,9 +272,9 @@ public final class InstantiableVisitor: SyntaxVisitor { changes: [ .replace( oldNode: Syntax(node), - newNode: Syntax(modifiedNode) + newNode: Syntax(modifiedNode), ), - ] + ], )) } @@ -341,7 +341,7 @@ public final class InstantiableVisitor: SyntaxVisitor { initializer: initializers.first(where: { $0.isValid(forFulfilling: dependencies) }), additionalInstantiables: additionalInstantiables, dependencies: dependencies, - declarationType: instantiableDeclarationType.asDeclarationType + declarationType: instantiableDeclarationType.asDeclarationType, ), ] } else { @@ -366,7 +366,7 @@ public final class InstantiableVisitor: SyntaxVisitor { let nodeDeclarationType: TypeDescription = if let parentType { .nested( name: node.name.text, - parentType: parentType + parentType: parentType, ) } else { .simple(name: node.name.text) @@ -426,15 +426,15 @@ public final class InstantiableVisitor: SyntaxVisitor { TokenKind.keyword(.public), leadingTrivia: node.modifiers.first?.leadingTrivia ?? .newline, trailingTrivia: node.modifiers.first?.trailingTrivia ?? .space, - presence: .present - ) + presence: .present, + ), ) var modifiedNode = node if var firstModifier = modifiedNode.modifiers.first { firstModifier.name.leadingTrivia = [] modifiedNode.modifiers.replaceSubrange( modifiedNode.modifiers.startIndex.. [DeclSyntax] { @@ -109,14 +109,14 @@ public struct InjectableMacro: PeerMacro { $0.with(\.type, { TypeSyntax(OptionalTypeSyntax( wrappedType: $0.type, - questionMark: .postfixQuestionMarkToken() + questionMark: .postfixQuestionMarkToken(), )) }($0)) }) } - })) + })), ), - ] + ], )) } } @@ -134,10 +134,10 @@ public struct InjectableMacro: PeerMacro { newNode: Syntax(TokenSyntax.keyword( .let, leadingTrivia: .space, - trailingTrivia: .space - )) + trailingTrivia: .space, + )), ), - ] + ], )) } diff --git a/Sources/SafeDIMacros/Macros/InstantiableMacro.swift b/Sources/SafeDIMacros/Macros/InstantiableMacro.swift index b5cd0fcf..e515a265 100644 --- a/Sources/SafeDIMacros/Macros/InstantiableMacro.swift +++ b/Sources/SafeDIMacros/Macros/InstantiableMacro.swift @@ -29,7 +29,7 @@ public struct InstantiableMacro: MemberMacro { of node: AttributeSyntax, providingMembersOf declaration: some DeclGroupSyntax, conformingTo _: [TypeSyntax], - in context: some MacroExpansionContext + in context: some MacroExpansionContext, ) throws -> [DeclSyntax] { if let fulfillingAdditionalTypesArgument = declaration .attributes @@ -65,7 +65,7 @@ public struct InstantiableMacro: MemberMacro { if mustExtendInstantiable, !extendsInstantiable { var modifiedDeclaration = concreteDeclaration var inheritedType = InheritedTypeSyntax( - type: IdentifierTypeSyntax(name: .identifier("Instantiable")) + type: IdentifierTypeSyntax(name: .identifier("Instantiable")), ) if let existingInheritanceClause = modifiedDeclaration.inheritanceClause { inheritedType.trailingTrivia = .space @@ -82,9 +82,9 @@ public struct InstantiableMacro: MemberMacro { modifiedDeclaration.inheritanceClause = InheritanceClauseSyntax( colon: .colonToken(trailingTrivia: .space), inheritedTypes: InheritedTypeListSyntax(arrayLiteral: InheritedTypeSyntax( - type: IdentifierTypeSyntax(name: .identifier("Instantiable")) + type: IdentifierTypeSyntax(name: .identifier("Instantiable")), )), - trailingTrivia: .space + trailingTrivia: .space, ) } context.diagnose(Diagnostic( @@ -93,9 +93,9 @@ public struct InstantiableMacro: MemberMacro { changes: [ .replace( oldNode: Syntax(concreteDeclaration), - newNode: Syntax(modifiedDeclaration) + newNode: Syntax(modifiedDeclaration), ), - ] + ], )) } @@ -120,7 +120,7 @@ public struct InstantiableMacro: MemberMacro { guard inheritedDependencies.isEmpty else { throw InstantiableError.cannotBeRoot( instantiableType, - violatingDependencies: inheritedDependencies + violatingDependencies: inheritedDependencies, ) } } @@ -201,11 +201,11 @@ public struct InstantiableMacro: MemberMacro { let functionParameterProperty = property.asFunctionParamter if let existingParameter = existingParameters[functionParameterProperty] { fixedSyntax.signature.parameterClause.parameters.append( - normalizeFunctionParameter(existingParameter, for: functionParameterProperty) + normalizeFunctionParameter(existingParameter, for: functionParameterProperty), ) } else { fixedSyntax.signature.parameterClause.parameters.append( - normalizeFunctionParameter(property.asFunctionParamterSyntax, for: functionParameterProperty) + normalizeFunctionParameter(property.asFunctionParamterSyntax, for: functionParameterProperty), ) } existingParameters[functionParameterProperty] = nil @@ -217,8 +217,8 @@ public struct InstantiableMacro: MemberMacro { existingParameter, at: fixedSyntax.signature.parameterClause.parameters.index( priorIndex, - offsetBy: priorIndex == syntaxToFix.signature.parameterClause.parameters.startIndex ? 0 : missingArguments.count - ) + offsetBy: priorIndex == syntaxToFix.signature.parameterClause.parameters.startIndex ? 0 : missingArguments.count, + ), ) } } @@ -290,9 +290,9 @@ public struct InstantiableMacro: MemberMacro { changes: [ .replace( oldNode: Syntax(syntaxToFix), - newNode: Syntax(fixedSyntax) + newNode: Syntax(fixedSyntax), ), - ] + ], )) case .inaccessibleInitializer: @@ -309,9 +309,9 @@ public struct InstantiableMacro: MemberMacro { leadingTrivia: $0.leadingTrivia, name: TokenSyntax( TokenKind.keyword(.public), - presence: .present + presence: .present, ), - trailingTrivia: $0.trailingTrivia + trailingTrivia: $0.trailingTrivia, ) } else { $0 @@ -325,9 +325,9 @@ public struct InstantiableMacro: MemberMacro { leadingTrivia: fixedSyntax.modifiers.isEmpty ? .newline : [], name: TokenSyntax( TokenKind.keyword(.public), - presence: .present + presence: .present, ), - trailingTrivia: .space + trailingTrivia: .space, ), at: fixedSyntax.modifiers.startIndex) } if let firstModifier = syntaxToFix.modifiers.first { @@ -342,9 +342,9 @@ public struct InstantiableMacro: MemberMacro { changes: [ .replace( oldNode: Syntax(syntaxToFix), - newNode: Syntax(fixedSyntax) + newNode: Syntax(fixedSyntax), ), - ] + ], )) } } else { @@ -355,11 +355,11 @@ public struct InstantiableMacro: MemberMacro { decl: Initializer.generateRequiredInitializer( for: visitor.dependencies, declarationType: concreteDeclaration.declType, - andAdditionalPropertiesWithLabels: visitor.uninitializedNonOptionalPropertyNames + andAdditionalPropertiesWithLabels: visitor.uninitializedNonOptionalPropertyNames, ), - trailingTrivia: .newline + trailingTrivia: .newline, ), - at: declarationWithInitializer.memberBlock.members.startIndex + at: declarationWithInitializer.memberBlock.members.startIndex, ) let errorType: FixableInstantiableError.MissingInitializer = if visitor.uninitializedNonOptionalPropertyNames.isEmpty { .hasOnlyInjectableProperties @@ -374,9 +374,9 @@ public struct InstantiableMacro: MemberMacro { changes: [ .replace( oldNode: Syntax(declaration), - newNode: Syntax(declarationWithInitializer) + newNode: Syntax(declarationWithInitializer), ), - ] + ], )) } return [] @@ -396,7 +396,7 @@ public struct InstantiableMacro: MemberMacro { if mustExtendInstantiable, !extendsInstantiable { var modifiedDeclaration = extensionDeclaration var inheritedType = InheritedTypeSyntax( - type: IdentifierTypeSyntax(name: .identifier("Instantiable")) + type: IdentifierTypeSyntax(name: .identifier("Instantiable")), ) if let existingInheritanceClause = modifiedDeclaration.inheritanceClause { inheritedType.trailingTrivia = .space @@ -413,9 +413,9 @@ public struct InstantiableMacro: MemberMacro { modifiedDeclaration.inheritanceClause = InheritanceClauseSyntax( colon: .colonToken(trailingTrivia: .space), inheritedTypes: InheritedTypeListSyntax(arrayLiteral: InheritedTypeSyntax( - type: IdentifierTypeSyntax(name: .identifier("Instantiable")) + type: IdentifierTypeSyntax(name: .identifier("Instantiable")), )), - trailingTrivia: .space + trailingTrivia: .space, ) } context.diagnose(Diagnostic( @@ -424,9 +424,9 @@ public struct InstantiableMacro: MemberMacro { changes: [ .replace( oldNode: Syntax(extensionDeclaration), - newNode: Syntax(modifiedDeclaration) + newNode: Syntax(modifiedDeclaration), ), - ] + ], )) } if extensionDeclaration.genericWhereClause != nil { @@ -438,9 +438,9 @@ public struct InstantiableMacro: MemberMacro { changes: [ .replace( oldNode: Syntax(extensionDeclaration), - newNode: Syntax(modifiedDeclaration) + newNode: Syntax(modifiedDeclaration), ), - ] + ], )) } @@ -454,7 +454,7 @@ public struct InstantiableMacro: MemberMacro { guard visitor.instantiables.flatMap(\.dependencies).isEmpty else { throw InstantiableError.cannotBeRoot( instantiableType, - violatingDependencies: visitor.instantiables.flatMap(\.dependencies) + violatingDependencies: visitor.instantiables.flatMap(\.dependencies), ) } } @@ -480,58 +480,58 @@ public struct InstantiableMacro: MemberMacro { arrayLiteral: DeclModifierSyntax( name: TokenSyntax( TokenKind.keyword(.public), - presence: .present + presence: .present, ), - trailingTrivia: .space + trailingTrivia: .space, ), DeclModifierSyntax( name: TokenSyntax( TokenKind.keyword(.static), - presence: .present + presence: .present, ), - trailingTrivia: .space - ) + trailingTrivia: .space, + ), ), name: TokenSyntax( TokenKind.identifier(InstantiableVisitor.instantiateMethodName), leadingTrivia: .space, - presence: .present + presence: .present, ), signature: FunctionSignatureSyntax( parameterClause: FunctionParameterClauseSyntax( - parameters: FunctionParameterListSyntax([]) + parameters: FunctionParameterListSyntax([]), ), returnClause: ReturnClauseSyntax( arrow: .arrowToken( leadingTrivia: .space, - trailingTrivia: .space + trailingTrivia: .space, ), type: IdentifierTypeSyntax( - name: .identifier(extendedTypeName) - ) - ) + name: .identifier(extendedTypeName), + ), + ), ), body: CodeBlockSyntax( leadingTrivia: .newline, statements: CodeBlockItemListSyntax([]), - trailingTrivia: .newline - ) + trailingTrivia: .newline, + ), ), - trailingTrivia: .newline + trailingTrivia: .newline, ), - at: membersWithInitializer.startIndex + at: membersWithInitializer.startIndex, ) context.diagnose(Diagnostic( node: Syntax(extensionDeclaration.memberBlock.members), error: FixableInstantiableError.missingRequiredInstantiateMethod( - typeName: extendedTypeName + typeName: extendedTypeName, ), changes: [ .replace( oldNode: Syntax(declaration.memberBlock.members), - newNode: Syntax(membersWithInitializer) + newNode: Syntax(membersWithInitializer), ), - ] + ], )) } return [] @@ -541,7 +541,7 @@ public struct InstantiableMacro: MemberMacro { } private static func generateForwardedProperties( - from forwardedProperties: [Property] + from forwardedProperties: [Property], ) -> [DeclSyntax] { if forwardedProperties.isEmpty { [] @@ -553,18 +553,18 @@ public struct InstantiableMacro: MemberMacro { arrayLiteral: DeclModifierSyntax( name: TokenSyntax( TokenKind.keyword(.public), - presence: .present + presence: .present, ), - trailingTrivia: .space - ) + trailingTrivia: .space, + ), ), name: .identifier("ForwardedProperties"), initializer: TypeInitializerClauseSyntax( value: IdentifierTypeSyntax( - name: .identifier(forwardedProperty.typeDescription.asSource) - ) - ) - ) + name: .identifier(forwardedProperty.typeDescription.asSource), + ), + ), + ), ), ] } else { @@ -575,14 +575,14 @@ public struct InstantiableMacro: MemberMacro { arrayLiteral: DeclModifierSyntax( name: TokenSyntax( TokenKind.keyword(.public), - presence: .present + presence: .present, ), - trailingTrivia: .space - ) + trailingTrivia: .space, + ), ), name: .identifier("ForwardedProperties"), - initializer: TypeInitializerClauseSyntax(value: forwardedProperties.asTuple) - ) + initializer: TypeInitializerClauseSyntax(value: forwardedProperties.asTuple), + ), ), ] } @@ -626,20 +626,20 @@ extension TypeDescription { self == .simple(name: "Instantiable") || self == .nested( name: "Instantiable", - parentType: .simple(name: "SafeDI") + parentType: .simple(name: "SafeDI"), ) || self == .attributed( .simple(name: "Instantiable"), specifiers: nil, - attributes: ["retroactive"] + attributes: ["retroactive"], ) || self == .nested( name: "Instantiable", parentType: .attributed( .simple(name: "SafeDI"), specifiers: nil, - attributes: ["retroactive"] - ) + attributes: ["retroactive"], + ), ) } } @@ -647,7 +647,7 @@ extension TypeDescription { // MARK: Initializer extension Initializer { - fileprivate enum FixableError: Comparable, Hashable, Sendable { + fileprivate enum FixableError: Comparable, Hashable { case inaccessibleInitializer case missingArguments([Property]) indirect case multiple([FixableError]) diff --git a/Sources/SafeDIMacros/Macros/SafeDIConfigurationMacro.swift b/Sources/SafeDIMacros/Macros/SafeDIConfigurationMacro.swift index a517c407..bc0f2cdd 100644 --- a/Sources/SafeDIMacros/Macros/SafeDIConfigurationMacro.swift +++ b/Sources/SafeDIMacros/Macros/SafeDIConfigurationMacro.swift @@ -27,7 +27,7 @@ public struct SafeDIConfigurationMacro: PeerMacro { public static func expansion( of _: AttributeSyntax, providingPeersOf declaration: some DeclSyntaxProtocol, - in context: some MacroExpansionContext + in context: some MacroExpansionContext, ) throws -> [DeclSyntax] { guard let enumDecl = EnumDeclSyntax(declaration) else { throw SafeDIConfigurationError.decoratingNonEnum @@ -60,7 +60,7 @@ public struct SafeDIConfigurationMacro: PeerMacro { /// The names of modules to import in the generated dependency tree. /// This list is in addition to the import statements found in files that declare @Instantiable types. static let \(raw: SafeDIConfigurationVisitor.additionalImportedModulesPropertyName): [StaticString] = [] - """) + """), )) } if !visitor.foundAdditionalDirectoriesToInclude { @@ -70,13 +70,13 @@ public struct SafeDIConfigurationMacro: PeerMacro { /// Directories containing Swift files to include, relative to the executing directory. /// This property only applies to SafeDI repos that utilize the SPM plugin via an Xcode project. static let \(raw: SafeDIConfigurationVisitor.additionalDirectoriesToIncludePropertyName): [StaticString] = [] - """) + """), )) } for member in membersToInsert.reversed() { modifiedDecl.memberBlock.members.insert( member, - at: modifiedDecl.memberBlock.members.startIndex + at: modifiedDecl.memberBlock.members.startIndex, ) } let missingPropertyError: FixableSafeDIConfigurationError = if !visitor.foundAdditionalImportedModules { @@ -90,9 +90,9 @@ public struct SafeDIConfigurationMacro: PeerMacro { changes: [ .replace( oldNode: Syntax(enumDecl), - newNode: Syntax(modifiedDecl) + newNode: Syntax(modifiedDecl), ), - ] + ], )) } diff --git a/Sources/SafeDITool/SafeDITool.swift b/Sources/SafeDITool/SafeDITool.swift index 7b515d23..b6d4cc99 100644 --- a/Sources/SafeDITool/SafeDITool.swift +++ b/Sources/SafeDITool/SafeDITool.swift @@ -24,7 +24,7 @@ import SafeDICore import SwiftParser @main -struct SafeDITool: AsyncParsableCommand, Sendable { +struct SafeDITool: AsyncParsableCommand { // MARK: Arguments @Argument(help: "A path to a CSV file containing paths of Swift files to parse.") var swiftSourcesFilePath: String? @@ -69,7 +69,7 @@ struct SafeDITool: AsyncParsableCommand, Sendable { let (dependentModuleInfo, initialModule) = try await ( loadSafeDIModuleInfo(), - parsedModule() + parsedModule(), ) // Prefer the root module's configuration. If none, fall back to dependent modules' configurations. @@ -95,7 +95,7 @@ struct SafeDITool: AsyncParsableCommand, Sendable { imports: initialModule.imports + additionalModule.imports, instantiables: initialModule.instantiables + additionalModule.instantiables, configurations: initialModule.configurations, - filesWithUnexpectedNodes: initialModule.filesWithUnexpectedNodes.map { $0 + (additionalModule.filesWithUnexpectedNodes ?? []) } ?? additionalModule.filesWithUnexpectedNodes + filesWithUnexpectedNodes: initialModule.filesWithUnexpectedNodes.map { $0 + (additionalModule.filesWithUnexpectedNodes ?? []) } ?? additionalModule.filesWithUnexpectedNodes, ) } else { module = initialModule @@ -105,11 +105,11 @@ struct SafeDITool: AsyncParsableCommand, Sendable { let instantiableTypes = Set(unnormalizedInstantiables.flatMap(\.instantiableTypes)) let normalizedInstantiables = unnormalizedInstantiables.map { unnormalizedInstantiable in let unnormalizedToNormalizedTypeMap = unnormalizedInstantiable.dependencies.reduce( - into: [TypeDescription: TypeDescription]() + into: [TypeDescription: TypeDescription](), ) { partialResult, nextDependency in if let bestTypeDescription = TypeDescription.nestedOptions( referencedType: nextDependency.property.typeDescription, - within: unnormalizedInstantiable.concreteInstantiable + within: unnormalizedInstantiable.concreteInstantiable, ).first(where: { instantiableTypes.contains($0) }) { partialResult[nextDependency.property.typeDescription] = bestTypeDescription } @@ -119,7 +119,7 @@ struct SafeDITool: AsyncParsableCommand, Sendable { if let bestTypeDescription = unnormalizedToNormalizedTypeMap[$0.property.typeDescription] { Dependency( property: $0.property.withUpdatedTypeDescription(bestTypeDescription), - source: $0.source + source: $0.source, ) } else { // Default to what was in the code – we'll probably error later @@ -133,7 +133,7 @@ struct SafeDITool: AsyncParsableCommand, Sendable { if let enclosingType = unnormalizedInstantiable.concreteInstantiable.popNested, let bestTypeDescription = TypeDescription.nestedOptions( referencedType: $0, - within: enclosingType + within: enclosingType, ).first(where: { instantiableTypes.contains($0) }) { bestTypeDescription @@ -148,14 +148,14 @@ struct SafeDITool: AsyncParsableCommand, Sendable { initializer: normalizedInitializer, additionalInstantiables: normalizedAdditionalInstantiables, dependencies: normalizedDependencies, - declarationType: unnormalizedInstantiable.declarationType + declarationType: unnormalizedInstantiable.declarationType, ) } let generator = try DependencyTreeGenerator( importStatements: dependentModuleInfo.flatMap(\.imports) + resolvedAdditionalImportedModules.map { ImportStatement(moduleName: $0) } + module.imports, typeDescriptionToFulfillingInstantiableMap: resolveSafeDIFulfilledTypes( - instantiables: normalizedInstantiables - ) + instantiables: normalizedInstantiables, + ), ) async let generatedCode: String? = try dependencyTreeOutput != nil ? generator.generateCodeTree() @@ -197,7 +197,7 @@ struct SafeDITool: AsyncParsableCommand, Sendable { } } - struct ModuleInfo: Codable, Sendable { + struct ModuleInfo: Codable { let imports: [ImportStatement] let instantiables: [Instantiable] let configurations: [SafeDIConfiguration] @@ -226,7 +226,7 @@ struct SafeDITool: AsyncParsableCommand, Sendable { private static func findSwiftFiles(inDirectories directories: [String]) async throws -> Set { try await withThrowingTaskGroup( of: [String].self, - returning: Set.self + returning: Set.self, ) { taskGroup in for included in directories { taskGroup.addTask { @@ -236,7 +236,7 @@ struct SafeDITool: AsyncParsableCommand, Sendable { at: includedURL, includingPropertiesForKeys: nil, options: [.skipsHiddenFiles], - errorHandler: nil + errorHandler: nil, ) guard let files = includedFileEnumerator?.compactMap({ $0 as? URL }) else { struct CouldNotEnumerateDirectoryError: Error, CustomStringConvertible { @@ -273,9 +273,9 @@ struct SafeDITool: AsyncParsableCommand, Sendable { imports: [ImportStatement], instantiables: [Instantiable], configurations: [SafeDIConfiguration], - encounteredUnexpectedNodeInFile: String? + encounteredUnexpectedNodeInFile: String?, )?.self, - returning: ModuleInfo.self + returning: ModuleInfo.self, ) { taskGroup in var imports = [ImportStatement]() var instantiables = [Instantiable]() @@ -297,7 +297,7 @@ struct SafeDITool: AsyncParsableCommand, Sendable { imports: fileVisitor.imports, instantiables: fileVisitor.instantiables, configurations: fileVisitor.configurations, - encounteredUnexpectedNodeInFile: fileVisitor.encounteredUnexpectedNodesSyntax ? filePath : nil + encounteredUnexpectedNodeInFile: fileVisitor.encounteredUnexpectedNodesSyntax ? filePath : nil, ) } } @@ -317,7 +317,7 @@ struct SafeDITool: AsyncParsableCommand, Sendable { imports: imports, instantiables: instantiables, configurations: configurations, - filesWithUnexpectedNodes: filesWithUnexpectedNodes.isEmpty ? nil : filesWithUnexpectedNodes + filesWithUnexpectedNodes: filesWithUnexpectedNodes.isEmpty ? nil : filesWithUnexpectedNodes, ) } } @@ -333,7 +333,7 @@ struct SafeDITool: AsyncParsableCommand, Sendable { String(contentsOfFile: dependentModuleInfoFilePath, encoding: .utf8) .components(separatedBy: CharacterSet(arrayLiteral: ",")) .removingEmpty() - .map(\.asFileURL) + .map(\.asFileURL), ) } else { [] @@ -344,7 +344,7 @@ struct SafeDITool: AsyncParsableCommand, Sendable { private func loadSafeDIModuleInfo() async throws -> [ModuleInfo] { try await withThrowingTaskGroup( of: ModuleInfo.self, - returning: [ModuleInfo].self + returning: [ModuleInfo].self, ) { taskGroup in let moduleInfoURLs = try moduleInfoURLs guard !moduleInfoURLs.isEmpty else { return [] } @@ -352,7 +352,7 @@ struct SafeDITool: AsyncParsableCommand, Sendable { taskGroup.addTask { try JSONDecoder().decode( ModuleInfo.self, - from: Data(contentsOf: moduleInfoURL) + from: Data(contentsOf: moduleInfoURL), ) } } @@ -387,7 +387,6 @@ struct SafeDITool: AsyncParsableCommand, Sendable { } } } - } extension Data { @@ -418,7 +417,7 @@ protocol FileFinder: Sendable { at url: URL, includingPropertiesForKeys keys: [URLResourceKey]?, options mask: FileManager.DirectoryEnumerationOptions, - errorHandler handler: ((URL, any Error) -> Bool)? + errorHandler handler: ((URL, any Error) -> Bool)?, ) -> FileManager.DirectoryEnumerator? } diff --git a/Tests/SafeDICoreTests/FileVisitorTests.swift b/Tests/SafeDICoreTests/FileVisitorTests.swift index a708980c..b0c0d7bb 100644 --- a/Tests/SafeDICoreTests/FileVisitorTests.swift +++ b/Tests/SafeDICoreTests/FileVisitorTests.swift @@ -21,7 +21,6 @@ import SwiftParser import SwiftSyntax import Testing - @testable import SafeDICore struct FileVisitorTests { @@ -51,33 +50,33 @@ struct FileVisitorTests { .init( innerLabel: "user", typeDescription: .simple(name: "User"), - hasDefaultValue: false + hasDefaultValue: false, ), .init( innerLabel: "networkService", typeDescription: .simple(name: "NetworkService"), - hasDefaultValue: false + hasDefaultValue: false, ), - ] + ], ), additionalInstantiables: nil, dependencies: [ Dependency( property: Property( label: "user", - typeDescription: .simple(name: "User") + typeDescription: .simple(name: "User"), ), - source: .forwarded + source: .forwarded, ), Dependency( property: Property( label: "networkService", - typeDescription: .simple(name: "NetworkService") + typeDescription: .simple(name: "NetworkService"), ), - source: .received(onlyIfAvailable: false) + source: .received(onlyIfAvailable: false), ), ], - declarationType: .classType + declarationType: .classType, ), ]) } @@ -111,33 +110,33 @@ struct FileVisitorTests { .init( innerLabel: "user", typeDescription: .simple(name: "User"), - hasDefaultValue: false + hasDefaultValue: false, ), .init( innerLabel: "networkService", typeDescription: .simple(name: "NetworkService"), - hasDefaultValue: false + hasDefaultValue: false, ), - ] + ], ), additionalInstantiables: nil, dependencies: [ Dependency( property: Property( label: "user", - typeDescription: .simple(name: "User") + typeDescription: .simple(name: "User"), ), - source: .forwarded + source: .forwarded, ), Dependency( property: Property( label: "networkService", - typeDescription: .simple(name: "NetworkService") + typeDescription: .simple(name: "NetworkService"), ), - source: .received(onlyIfAvailable: false) + source: .received(onlyIfAvailable: false), ), ], - declarationType: .classType + declarationType: .classType, ), Instantiable( instantiableType: .simple(name: "SomeOtherInstantiable"), @@ -145,7 +144,7 @@ struct FileVisitorTests { initializer: Initializer(arguments: []), additionalInstantiables: nil, dependencies: [], - declarationType: .structType + declarationType: .structType, ), ]) } @@ -173,7 +172,7 @@ struct FileVisitorTests { .simple(name: "SomeProtocol"), ], dependencies: [], - declarationType: .structType + declarationType: .structType, ), Instantiable( instantiableType: .nested(name: "InnerLevel", parentType: .simple(name: "OuterLevel")), @@ -181,7 +180,7 @@ struct FileVisitorTests { initializer: Initializer(arguments: []), additionalInstantiables: [], dependencies: [], - declarationType: .structType + declarationType: .structType, ), ]) } @@ -206,7 +205,7 @@ struct FileVisitorTests { initializer: Initializer(arguments: []), additionalInstantiables: [], dependencies: [], - declarationType: .extensionType + declarationType: .extensionType, ), Instantiable( instantiableType: .nested(name: "InnerLevel", parentType: .simple(name: "OuterLevel")), @@ -214,7 +213,7 @@ struct FileVisitorTests { initializer: Initializer(arguments: []), additionalInstantiables: [], dependencies: [], - declarationType: .structType + declarationType: .structType, ), ]) } @@ -250,7 +249,7 @@ struct FileVisitorTests { initializer: Initializer(arguments: []), additionalInstantiables: [], dependencies: [], - declarationType: .extensionType + declarationType: .extensionType, ), Instantiable( instantiableType: .nested(name: "InnerLevel1", parentType: .simple(name: "OuterLevel")), @@ -258,7 +257,7 @@ struct FileVisitorTests { initializer: Initializer(arguments: []), additionalInstantiables: [], dependencies: [], - declarationType: .actorType + declarationType: .actorType, ), Instantiable( instantiableType: .nested(name: "InnerLevel2", parentType: .simple(name: "OuterLevel")), @@ -266,7 +265,7 @@ struct FileVisitorTests { initializer: Initializer(arguments: []), additionalInstantiables: [], dependencies: [], - declarationType: .classType + declarationType: .classType, ), Instantiable( instantiableType: .nested(name: "InnerLevel3", parentType: .simple(name: "OuterLevel")), @@ -274,7 +273,7 @@ struct FileVisitorTests { initializer: Initializer(arguments: []), additionalInstantiables: [], dependencies: [], - declarationType: .structType + declarationType: .structType, ), ]) } @@ -297,7 +296,7 @@ struct FileVisitorTests { initializer: Initializer(arguments: []), additionalInstantiables: [], dependencies: [], - declarationType: .structType + declarationType: .structType, ), ]) } @@ -315,7 +314,7 @@ struct FileVisitorTests { #expect(fileVisitor.configurations == [ SafeDIConfiguration( additionalImportedModules: ["ModuleA", "ModuleB"], - additionalDirectoriesToInclude: ["DirA"] + additionalDirectoriesToInclude: ["DirA"], ), ]) #expect(fileVisitor.instantiables.isEmpty) @@ -334,7 +333,7 @@ struct FileVisitorTests { #expect(fileVisitor.configurations == [ SafeDIConfiguration( additionalImportedModules: [], - additionalDirectoriesToInclude: [] + additionalDirectoriesToInclude: [], ), ]) } @@ -353,7 +352,7 @@ struct FileVisitorTests { #expect(fileVisitor.configurations == [ SafeDIConfiguration( additionalImportedModules: [], - additionalDirectoriesToInclude: [] + additionalDirectoriesToInclude: [], ), ]) } @@ -371,7 +370,7 @@ struct FileVisitorTests { #expect(fileVisitor.configurations == [ SafeDIConfiguration( additionalImportedModules: [], - additionalDirectoriesToInclude: [] + additionalDirectoriesToInclude: [], ), ]) } @@ -394,7 +393,7 @@ struct FileVisitorTests { #expect(fileVisitor.configurations == [ SafeDIConfiguration( additionalImportedModules: ["ModuleA"], - additionalDirectoriesToInclude: [] + additionalDirectoriesToInclude: [], ), ]) #expect(fileVisitor.instantiables == [ @@ -404,7 +403,7 @@ struct FileVisitorTests { initializer: Initializer(arguments: []), additionalInstantiables: nil, dependencies: [], - declarationType: .structType + declarationType: .structType, ), ]) } @@ -521,11 +520,11 @@ struct FileVisitorTests { doesThrow: false, hasGenericParameter: false, hasGenericWhereClause: false, - arguments: [] + arguments: [], ), additionalInstantiables: [], dependencies: [], - declarationType: .structType + declarationType: .structType, ), Instantiable( instantiableType: .nested(name: "Nested", parentType: .nested(name: "Nested", parentType: .simple(name: "Nested"))), @@ -537,11 +536,11 @@ struct FileVisitorTests { doesThrow: false, hasGenericParameter: false, hasGenericWhereClause: false, - arguments: [] + arguments: [], ), additionalInstantiables: [], dependencies: [], - declarationType: .actorType + declarationType: .actorType, ), Instantiable( instantiableType: .nested(name: "Nested", parentType: .nested(name: "Nested", parentType: .nested(name: "Nested", parentType: .simple(name: "Nested")))), @@ -553,11 +552,11 @@ struct FileVisitorTests { doesThrow: false, hasGenericParameter: false, hasGenericWhereClause: false, - arguments: [] + arguments: [], ), additionalInstantiables: [], dependencies: [], - declarationType: .classType + declarationType: .classType, ), Instantiable( instantiableType: .nested(name: "Nested", parentType: .nested(name: "Nested", parentType: .nested(name: "Nested", parentType: .nested(name: "Nested", parentType: .simple(name: "Nested"))))), @@ -569,11 +568,11 @@ struct FileVisitorTests { doesThrow: false, hasGenericParameter: false, hasGenericWhereClause: false, - arguments: [] + arguments: [], ), additionalInstantiables: [], dependencies: [], - declarationType: .actorType + declarationType: .actorType, ), Instantiable( instantiableType: .nested(name: "Nested", parentType: .nested(name: "Nested", parentType: .nested(name: "Nested", parentType: .nested(name: "Nested", parentType: .nested(name: "Nested", parentType: .simple(name: "Nested")))))), @@ -585,11 +584,11 @@ struct FileVisitorTests { doesThrow: false, hasGenericParameter: false, hasGenericWhereClause: false, - arguments: [] + arguments: [], ), additionalInstantiables: [], dependencies: [], - declarationType: .classType + declarationType: .classType, ), Instantiable( instantiableType: .nested(name: "Nested", parentType: .nested(name: "Nested", parentType: .nested(name: "Nested", parentType: .nested(name: "Nested", parentType: .nested(name: "Nested", parentType: .nested(name: "Nested", parentType: .simple(name: "Nested"))))))), @@ -601,11 +600,11 @@ struct FileVisitorTests { doesThrow: false, hasGenericParameter: false, hasGenericWhereClause: false, - arguments: [] + arguments: [], ), additionalInstantiables: [], dependencies: [], - declarationType: .structType + declarationType: .structType, ), Instantiable( instantiableType: .nested(name: "Nested", parentType: .nested(name: "Nested", parentType: .nested(name: "Nested", parentType: .nested(name: "Nested", parentType: .nested(name: "Nested", parentType: .nested(name: "Nested", parentType: .nested(name: "Nested", parentType: .simple(name: "Nested")))))))), @@ -617,11 +616,11 @@ struct FileVisitorTests { doesThrow: false, hasGenericParameter: false, hasGenericWhereClause: false, - arguments: [] + arguments: [], ), additionalInstantiables: [], dependencies: [], - declarationType: .classType + declarationType: .classType, ), Instantiable( instantiableType: .nested(name: "Nested", parentType: .nested(name: "Nested", parentType: .nested(name: "Nested", parentType: .nested(name: "Nested", parentType: .nested(name: "Nested", parentType: .nested(name: "Nested", parentType: .nested(name: "Nested", parentType: .nested(name: "Nested", parentType: .simple(name: "Nested"))))))))), @@ -633,11 +632,11 @@ struct FileVisitorTests { doesThrow: false, hasGenericParameter: false, hasGenericWhereClause: false, - arguments: [] + arguments: [], ), additionalInstantiables: [], dependencies: [], - declarationType: .actorType + declarationType: .actorType, ), Instantiable( instantiableType: .nested(name: "Nested", parentType: .nested(name: "Nested", parentType: .nested(name: "Nested", parentType: .nested(name: "Nested", parentType: .nested(name: "Nested", parentType: .nested(name: "Nested", parentType: .nested(name: "Nested", parentType: .nested(name: "Nested", parentType: .nested(name: "Nested", parentType: .simple(name: "Nested")))))))))), @@ -649,11 +648,11 @@ struct FileVisitorTests { doesThrow: false, hasGenericParameter: false, hasGenericWhereClause: false, - arguments: [] + arguments: [], ), additionalInstantiables: [], dependencies: [], - declarationType: .actorType + declarationType: .actorType, ), Instantiable( instantiableType: .nested(name: "Nested", parentType: .nested(name: "Nested", parentType: .nested(name: "Nested", parentType: .nested(name: "Nested", parentType: .nested(name: "Nested", parentType: .nested(name: "Nested", parentType: .nested(name: "Nested", parentType: .nested(name: "Nested", parentType: .nested(name: "Nested", parentType: .nested(name: "Nested", parentType: .simple(name: "Nested"))))))))))), @@ -665,11 +664,11 @@ struct FileVisitorTests { doesThrow: false, hasGenericParameter: false, hasGenericWhereClause: false, - arguments: [] + arguments: [], ), additionalInstantiables: [], dependencies: [], - declarationType: .structType + declarationType: .structType, ), Instantiable( instantiableType: .nested(name: "Nested", parentType: .nested(name: "Nested", parentType: .nested(name: "Nested", parentType: .nested(name: "Nested", parentType: .nested(name: "Nested", parentType: .nested(name: "Nested", parentType: .nested(name: "Nested", parentType: .nested(name: "Nested", parentType: .nested(name: "Nested", parentType: .nested(name: "Nested", parentType: .nested(name: "Nested", parentType: .simple(name: "Nested")))))))))))), @@ -681,11 +680,11 @@ struct FileVisitorTests { doesThrow: false, hasGenericParameter: false, hasGenericWhereClause: false, - arguments: [] + arguments: [], ), additionalInstantiables: [], dependencies: [], - declarationType: .structType + declarationType: .structType, ), Instantiable( instantiableType: .nested(name: "Nested", parentType: .nested(name: "Nested", parentType: .nested(name: "Nested", parentType: .nested(name: "Nested", parentType: .nested(name: "Nested", parentType: .nested(name: "Nested", parentType: .nested(name: "Nested", parentType: .nested(name: "Nested", parentType: .nested(name: "Nested", parentType: .nested(name: "Nested", parentType: .nested(name: "Nested", parentType: .nested(name: "Nested", parentType: .simple(name: "Nested"))))))))))))), @@ -697,11 +696,11 @@ struct FileVisitorTests { doesThrow: false, hasGenericParameter: false, hasGenericWhereClause: false, - arguments: [] + arguments: [], ), additionalInstantiables: [], dependencies: [], - declarationType: .classType + declarationType: .classType, ), Instantiable( instantiableType: .nested(name: "Nested", parentType: .nested(name: "Nested", parentType: .nested(name: "Nested", parentType: .nested(name: "Nested", parentType: .nested(name: "Nested", parentType: .nested(name: "Nested", parentType: .nested(name: "Nested", parentType: .nested(name: "Nested", parentType: .nested(name: "Nested", parentType: .nested(name: "Nested", parentType: .nested(name: "Nested", parentType: .nested(name: "Nested", parentType: .nested(name: "Nested", parentType: .simple(name: "Nested")))))))))))))), @@ -713,11 +712,11 @@ struct FileVisitorTests { doesThrow: false, hasGenericParameter: false, hasGenericWhereClause: false, - arguments: [] + arguments: [], ), additionalInstantiables: [], dependencies: [], - declarationType: .classType + declarationType: .classType, ), Instantiable( instantiableType: .nested(name: "Nested", parentType: .nested(name: "Nested", parentType: .nested(name: "Nested", parentType: .nested(name: "Nested", parentType: .nested(name: "Nested", parentType: .nested(name: "Nested", parentType: .nested(name: "Nested", parentType: .nested(name: "Nested", parentType: .nested(name: "Nested", parentType: .nested(name: "Nested", parentType: .nested(name: "Nested", parentType: .nested(name: "Nested", parentType: .nested(name: "Nested", parentType: .nested(name: "Nested", parentType: .simple(name: "Nested"))))))))))))))), @@ -729,11 +728,11 @@ struct FileVisitorTests { doesThrow: false, hasGenericParameter: false, hasGenericWhereClause: false, - arguments: [] + arguments: [], ), additionalInstantiables: [], dependencies: [], - declarationType: .classType + declarationType: .classType, ), Instantiable( instantiableType: .nested(name: "Nested", parentType: .nested(name: "Nested", parentType: .nested(name: "Nested", parentType: .nested(name: "Nested", parentType: .nested(name: "Nested", parentType: .nested(name: "Nested", parentType: .nested(name: "Nested", parentType: .nested(name: "Nested", parentType: .nested(name: "Nested", parentType: .nested(name: "Nested", parentType: .nested(name: "Nested", parentType: .nested(name: "Nested", parentType: .nested(name: "Nested", parentType: .nested(name: "Nested", parentType: .nested(name: "Nested", parentType: .simple(name: "Nested")))))))))))))))), @@ -745,11 +744,11 @@ struct FileVisitorTests { doesThrow: false, hasGenericParameter: false, hasGenericWhereClause: false, - arguments: [] + arguments: [], ), additionalInstantiables: [], dependencies: [], - declarationType: .classType + declarationType: .classType, ), Instantiable( instantiableType: .nested(name: "Nested", parentType: .nested(name: "Nested", parentType: .nested(name: "Nested", parentType: .nested(name: "Nested", parentType: .nested(name: "Nested", parentType: .nested(name: "Nested", parentType: .nested(name: "Nested", parentType: .nested(name: "Nested", parentType: .nested(name: "Nested", parentType: .nested(name: "Nested", parentType: .nested(name: "Nested", parentType: .nested(name: "Nested", parentType: .nested(name: "Nested", parentType: .nested(name: "Nested", parentType: .nested(name: "Nested", parentType: .nested(name: "Nested", parentType: .simple(name: "Nested"))))))))))))))))), @@ -761,11 +760,11 @@ struct FileVisitorTests { doesThrow: false, hasGenericParameter: false, hasGenericWhereClause: false, - arguments: [] + arguments: [], ), additionalInstantiables: [], dependencies: [], - declarationType: .classType + declarationType: .classType, ), Instantiable( instantiableType: .nested(name: "Nested", parentType: .nested(name: "Nested", parentType: .nested(name: "Nested", parentType: .nested(name: "Nested", parentType: .nested(name: "Nested", parentType: .nested(name: "Nested", parentType: .nested(name: "Nested", parentType: .nested(name: "Nested", parentType: .nested(name: "Nested", parentType: .nested(name: "Nested", parentType: .nested(name: "Nested", parentType: .nested(name: "Nested", parentType: .nested(name: "Nested", parentType: .nested(name: "Nested", parentType: .nested(name: "Nested", parentType: .nested(name: "Nested", parentType: .nested(name: "Nested", parentType: .simple(name: "Nested")))))))))))))))))), @@ -777,11 +776,11 @@ struct FileVisitorTests { doesThrow: false, hasGenericParameter: false, hasGenericWhereClause: false, - arguments: [] + arguments: [], ), additionalInstantiables: [], dependencies: [], - declarationType: .classType + declarationType: .classType, ), Instantiable( instantiableType: .nested(name: "Nested", parentType: .nested(name: "Nested", parentType: .nested(name: "Nested", parentType: .nested(name: "Nested", parentType: .nested(name: "Nested", parentType: .nested(name: "Nested", parentType: .nested(name: "Nested", parentType: .nested(name: "Nested", parentType: .nested(name: "Nested", parentType: .nested(name: "Nested", parentType: .nested(name: "Nested", parentType: .nested(name: "Nested", parentType: .nested(name: "Nested", parentType: .nested(name: "Nested", parentType: .nested(name: "Nested", parentType: .nested(name: "Nested", parentType: .nested(name: "Nested", parentType: .nested(name: "Nested", parentType: .simple(name: "Nested"))))))))))))))))))), @@ -793,11 +792,11 @@ struct FileVisitorTests { doesThrow: false, hasGenericParameter: false, hasGenericWhereClause: false, - arguments: [] + arguments: [], ), additionalInstantiables: [], dependencies: [], - declarationType: .classType + declarationType: .classType, ), Instantiable( instantiableType: .nested(name: "Nested", parentType: .nested(name: "Nested", parentType: .nested(name: "Nested", parentType: .nested(name: "Nested", parentType: .nested(name: "Nested", parentType: .nested(name: "Nested", parentType: .nested(name: "Nested", parentType: .nested(name: "Nested", parentType: .nested(name: "Nested", parentType: .nested(name: "Nested", parentType: .nested(name: "Nested", parentType: .nested(name: "Nested", parentType: .nested(name: "Nested", parentType: .nested(name: "Nested", parentType: .nested(name: "Nested", parentType: .nested(name: "Nested", parentType: .nested(name: "Nested", parentType: .nested(name: "Nested", parentType: .nested(name: "Nested", parentType: .simple(name: "Nested")))))))))))))))))))), @@ -809,11 +808,11 @@ struct FileVisitorTests { doesThrow: false, hasGenericParameter: false, hasGenericWhereClause: false, - arguments: [] + arguments: [], ), additionalInstantiables: [], dependencies: [], - declarationType: .classType + declarationType: .classType, ), ]) } diff --git a/Tests/SafeDICoreTests/InitializerTests.swift b/Tests/SafeDICoreTests/InitializerTests.swift index b4df6295..8d55e89e 100644 --- a/Tests/SafeDICoreTests/InitializerTests.swift +++ b/Tests/SafeDICoreTests/InitializerTests.swift @@ -19,15 +19,14 @@ // SOFTWARE. import Testing - @testable import SafeDICore struct InitializerTests { @Test - func generateSafeDIInitializer_throwsWhenInitializerIsNotPublicOrOpen() throws { + func generateSafeDIInitializer_throwsWhenInitializerIsNotPublicOrOpen() { let initializer = Initializer( isPublicOrOpen: false, - arguments: [] + arguments: [], ) #expect(throws: Initializer.GenerationError.inaccessibleInitializer, performing: { @@ -36,10 +35,10 @@ struct InitializerTests { } @Test - func generateSafeDIInitializer_throwsWhenInitializerIsOptional() throws { + func generateSafeDIInitializer_throwsWhenInitializerIsOptional() { let initializer = Initializer( isOptional: true, - arguments: [] + arguments: [], ) #expect(throws: Initializer.GenerationError.optionalInitializer, performing: { @@ -48,10 +47,10 @@ struct InitializerTests { } @Test - func generateSafeDIInitializer_throwsWhenInitializerIsAsync() throws { + func generateSafeDIInitializer_throwsWhenInitializerIsAsync() { let initializer = Initializer( isAsync: true, - arguments: [] + arguments: [], ) #expect(throws: Initializer.GenerationError.asyncInitializer, performing: { @@ -60,10 +59,10 @@ struct InitializerTests { } @Test - func generateSafeDIInitializer_throwsWhenInitializerThrows() throws { + func generateSafeDIInitializer_throwsWhenInitializerThrows() { let initializer = Initializer( doesThrow: true, - arguments: [] + arguments: [], ) #expect(throws: Initializer.GenerationError.throwingInitializer, performing: { @@ -72,16 +71,16 @@ struct InitializerTests { } @Test - func generateSafeDIInitializer_throwsWhenInitializerHasGenericParameters() throws { + func generateSafeDIInitializer_throwsWhenInitializerHasGenericParameters() { let initializer = Initializer( hasGenericParameter: true, arguments: [ .init( innerLabel: "variant", typeDescription: .simple(name: "Variant"), - hasDefaultValue: false + hasDefaultValue: false, ), - ] + ], ) #expect(throws: Initializer.GenerationError.genericParameterInInitializer, performing: { @@ -90,26 +89,26 @@ struct InitializerTests { .init( property: .init( label: "variant", - typeDescription: .simple(name: "Variant") + typeDescription: .simple(name: "Variant"), ), - source: .forwarded + source: .forwarded, ), - ] + ], ) }) } @Test - func generateSafeDIInitializer_throwsWhenInitializerHasGenericWhereClause() throws { + func generateSafeDIInitializer_throwsWhenInitializerHasGenericWhereClause() { let initializer = Initializer( hasGenericWhereClause: true, arguments: [ .init( innerLabel: "variant", typeDescription: .simple(name: "Variant"), - hasDefaultValue: false + hasDefaultValue: false, ), - ] + ], ) #expect(throws: Initializer.GenerationError.whereClauseOnInitializer, performing: { @@ -118,25 +117,25 @@ struct InitializerTests { .init( property: .init( label: "variant", - typeDescription: .simple(name: "Variant") + typeDescription: .simple(name: "Variant"), ), - source: .forwarded + source: .forwarded, ), - ] + ], ) }) } @Test - func generateSafeDIInitializer_throwsWhenInitializerHasUnexpectedArgument() throws { + func generateSafeDIInitializer_throwsWhenInitializerHasUnexpectedArgument() { let initializer = Initializer( arguments: [ .init( innerLabel: "variant", typeDescription: .simple(name: "Variant"), - hasDefaultValue: false + hasDefaultValue: false, ), - ] + ], ) #expect(throws: Initializer.GenerationError.unexpectedArgument("variant: Variant"), performing: { @@ -145,7 +144,7 @@ struct InitializerTests { } @Test - func generateSafeDIInitializer_throwsWhenInitializerIsMissingArgumentsAndDependenciesExist() throws { + func generateSafeDIInitializer_throwsWhenInitializerIsMissingArgumentsAndDependenciesExist() { let initializer = Initializer(arguments: []) #expect(throws: Initializer.GenerationError.missingArguments([.init(label: "variant", typeDescription: .simple(name: "Variant"))]), performing: { @@ -154,25 +153,25 @@ struct InitializerTests { .init( property: .init( label: "variant", - typeDescription: .simple(name: "Variant") + typeDescription: .simple(name: "Variant"), ), - source: .forwarded + source: .forwarded, ), - ] + ], ) }) } @Test - func generateSafeDIInitializer_throwsWhenInitializerIsMissingArgumentLabel() throws { + func generateSafeDIInitializer_throwsWhenInitializerIsMissingArgumentLabel() { let initializer = Initializer( arguments: [ .init( innerLabel: "someVariant", typeDescription: .simple(name: "Variant"), - hasDefaultValue: false + hasDefaultValue: false, ), - ] + ], ) #expect(throws: Initializer.GenerationError.unexpectedArgument("someVariant: Variant"), performing: { @@ -181,25 +180,25 @@ struct InitializerTests { .init( property: .init( label: "variant", - typeDescription: .simple(name: "Variant") + typeDescription: .simple(name: "Variant"), ), - source: .forwarded + source: .forwarded, ), - ] + ], ) }) } @Test - func generateSafeDIInitializer_throwsWhenInitializerIsMissingArgumentType() throws { + func generateSafeDIInitializer_throwsWhenInitializerIsMissingArgumentType() { let initializer = Initializer( arguments: [ .init( innerLabel: "variant", typeDescription: .simple(name: "NotThatVariant"), - hasDefaultValue: false + hasDefaultValue: false, ), - ] + ], ) #expect(throws: Initializer.GenerationError.unexpectedArgument("variant: NotThatVariant"), performing: { @@ -208,11 +207,11 @@ struct InitializerTests { .init( property: .init( label: "variant", - typeDescription: .simple(name: "Variant") + typeDescription: .simple(name: "Variant"), ), - source: .forwarded + source: .forwarded, ), - ] + ], ) }) } diff --git a/Tests/SafeDICoreTests/TypeDescriptionTests.swift b/Tests/SafeDICoreTests/TypeDescriptionTests.swift index ade87f7e..2e6e6ccb 100644 --- a/Tests/SafeDICoreTests/TypeDescriptionTests.swift +++ b/Tests/SafeDICoreTests/TypeDescriptionTests.swift @@ -22,7 +22,6 @@ import Foundation import SwiftParser import SwiftSyntax import Testing - @testable import SafeDICore struct TypeDescriptionTests { @@ -737,19 +736,19 @@ struct TypeDescriptionTests { arguments: [.void(.tuple)], isAsync: false, doesThrow: false, - returnType: .void(.identifier) + returnType: .void(.identifier), ), specifiers: nil, - attributes: ["autoclosure", "escaping"] + attributes: ["autoclosure", "escaping"], ).asFunctionParameter == TypeDescription.attributed( .closure( arguments: [.void(.tuple)], isAsync: false, doesThrow: false, - returnType: .void(.identifier) + returnType: .void(.identifier), ), specifiers: nil, - attributes: ["autoclosure", "escaping"] + attributes: ["autoclosure", "escaping"], )) } @@ -760,19 +759,19 @@ struct TypeDescriptionTests { arguments: [.void(.tuple)], isAsync: false, doesThrow: false, - returnType: .void(.identifier) + returnType: .void(.identifier), ), specifiers: nil, - attributes: ["escaping", "autoclosure"] + attributes: ["escaping", "autoclosure"], ).asFunctionParameter == TypeDescription.attributed( .closure( arguments: [.void(.tuple)], isAsync: false, doesThrow: false, - returnType: .void(.identifier) + returnType: .void(.identifier), ), specifiers: nil, - attributes: ["escaping", "autoclosure"] + attributes: ["escaping", "autoclosure"], )) } @@ -783,19 +782,19 @@ struct TypeDescriptionTests { arguments: [.void(.tuple)], isAsync: false, doesThrow: false, - returnType: .void(.identifier) + returnType: .void(.identifier), ), specifiers: nil, - attributes: nil + attributes: nil, ).asFunctionParameter == TypeDescription.attributed( .closure( arguments: [.void(.tuple)], isAsync: false, doesThrow: false, - returnType: .void(.identifier) + returnType: .void(.identifier), ), specifiers: nil, - attributes: ["escaping"] + attributes: ["escaping"], )) } diff --git a/Tests/SafeDICoreTests/UnorderedEquatingCollectionTests.swift b/Tests/SafeDICoreTests/UnorderedEquatingCollectionTests.swift index 1818c352..52a1b28b 100644 --- a/Tests/SafeDICoreTests/UnorderedEquatingCollectionTests.swift +++ b/Tests/SafeDICoreTests/UnorderedEquatingCollectionTests.swift @@ -20,7 +20,6 @@ import Foundation import Testing - @testable import SafeDICore struct UnorderedEquatingCollectionTests { @@ -48,7 +47,7 @@ struct UnorderedEquatingCollectionTests { let originalCollection = UnorderedEquatingCollection([1, 2, 3]) let decodedCollection = try JSONDecoder().decode( UnorderedEquatingCollection.self, - from: JSONEncoder().encode(originalCollection) + from: JSONEncoder().encode(originalCollection), ) #expect(originalCollection == decodedCollection) } diff --git a/Tests/SafeDIMacrosTests/AssertMacroExpansion.swift b/Tests/SafeDIMacrosTests/AssertMacroExpansion.swift index 28572e7b..8d643cd8 100644 --- a/Tests/SafeDIMacrosTests/AssertMacroExpansion.swift +++ b/Tests/SafeDIMacrosTests/AssertMacroExpansion.swift @@ -35,7 +35,7 @@ func assertMacroExpansion( fileID: StaticString = #fileID, filePath: StaticString = #filePath, line: UInt = #line, - column: UInt = #column + column: UInt = #column, ) { let specs = macros.mapValues { MacroSpec(type: $0) } SwiftSyntaxMacrosGenericTestSupport.assertMacroExpansion( @@ -52,13 +52,13 @@ func assertMacroExpansion( fileID: String(describing: spec.location.fileID), filePath: String(describing: spec.location.filePath), line: Int(spec.location.line), - column: Int(spec.location.column) - ) + column: Int(spec.location.column), + ), ) }, fileID: fileID, filePath: filePath, line: line, - column: column + column: column, ) } diff --git a/Tests/SafeDIMacrosTests/InjectableMacroTests.swift b/Tests/SafeDIMacrosTests/InjectableMacroTests.swift index 1f8d38e7..dabd79ab 100644 --- a/Tests/SafeDIMacrosTests/InjectableMacroTests.swift +++ b/Tests/SafeDIMacrosTests/InjectableMacroTests.swift @@ -18,12 +18,11 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. +import SafeDICore import SwiftSyntaxMacros import SwiftSyntaxMacrosGenericTestSupport import Testing -import SafeDICore - #if canImport(SafeDIMacros) @testable import SafeDIMacros @@ -54,7 +53,7 @@ import SafeDICore let something: Something } """, - macros: injectableTestMacros + macros: injectableTestMacros, ) } @@ -79,7 +78,7 @@ import SafeDICore let instantiatedA: InstantiatedA } """, - macros: injectableTestMacros + macros: injectableTestMacros, ) } @@ -98,7 +97,7 @@ import SafeDICore let receivedA: AnyReceivedA? } """, - macros: injectableTestMacros + macros: injectableTestMacros, ) } @@ -117,7 +116,7 @@ import SafeDICore let receivedA: AnyReceivedA?? } """, - macros: injectableTestMacros + macros: injectableTestMacros, ) } @@ -150,7 +149,7 @@ import SafeDICore line: 6, column: 19, severity: .error, - fixIts: [FixItSpec(message: "Replace `var` with `let`")] + fixIts: [FixItSpec(message: "Replace `var` with `let`")], ), ], macros: injectableTestMacros, @@ -163,7 +162,7 @@ import SafeDICore @Instantiated let instantiatedA: InstantiatedA } - """ + """, ) } @@ -202,7 +201,7 @@ import SafeDICore } } """#, - macros: injectableTestMacros + macros: injectableTestMacros, ) } @@ -226,10 +225,10 @@ import SafeDICore message: "The argument `fulfilledByType` can not be used on an `Instantiator` or `SendableInstantiator`. Use an `ErasedInstantiator` or `SendableErasedInstantiator` instead", line: 2, column: 5, - severity: .error + severity: .error, ), ], - macros: injectableTestMacros + macros: injectableTestMacros, ) } @@ -251,10 +250,10 @@ import SafeDICore message: "`ErasedInstantiator` and `SendableErasedInstantiator` require use of the argument `fulfilledByType`", line: 2, column: 5, - severity: .error + severity: .error, ), ], - macros: injectableTestMacros + macros: injectableTestMacros, ) } @@ -284,10 +283,10 @@ import SafeDICore message: "This macro can not decorate `static` variables", line: 6, column: 5, - severity: .error + severity: .error, ), ], - macros: injectableTestMacros + macros: injectableTestMacros, ) } @@ -306,10 +305,10 @@ import SafeDICore message: "This macro must decorate a instance variable", line: 1, column: 1, - severity: .error + severity: .error, ), ], - macros: injectableTestMacros + macros: injectableTestMacros, ) } @@ -341,10 +340,10 @@ import SafeDICore message: "The argument `fulfilledByType` must be a string literal", line: 7, column: 5, - severity: .error + severity: .error, ), ], - macros: injectableTestMacros + macros: injectableTestMacros, ) } @@ -376,10 +375,10 @@ import SafeDICore message: "The argument `fulfilledByType` must be a string literal", line: 7, column: 5, - severity: .error + severity: .error, ), ], - macros: injectableTestMacros + macros: injectableTestMacros, ) } @@ -409,10 +408,10 @@ import SafeDICore message: "The argument `fulfilledByType` must refer to a simple type", line: 6, column: 5, - severity: .error + severity: .error, ), ], - macros: injectableTestMacros + macros: injectableTestMacros, ) } @@ -442,10 +441,10 @@ import SafeDICore message: "The argument `fulfilledByType` must refer to a simple type", line: 6, column: 5, - severity: .error + severity: .error, ), ], - macros: injectableTestMacros + macros: injectableTestMacros, ) } @@ -471,10 +470,10 @@ import SafeDICore message: "The argument `fulfilledByDependencyNamed` must be a string literal", line: 4, column: 5, - severity: .error + severity: .error, ), ], - macros: injectableTestMacros + macros: injectableTestMacros, ) } @@ -498,10 +497,10 @@ import SafeDICore message: "The argument `ofType` must be a type literal", line: 3, column: 5, - severity: .error + severity: .error, ), ], - macros: injectableTestMacros + macros: injectableTestMacros, ) } @@ -527,10 +526,10 @@ import SafeDICore message: "The argument `erasedToConcreteExistential` must be a bool literal", line: 4, column: 5, - severity: .error + severity: .error, ), ], - macros: injectableTestMacros + macros: injectableTestMacros, ) } @@ -556,10 +555,10 @@ import SafeDICore message: "The argument `onlyIfAvailable` must be a type literal", line: 4, column: 2, - severity: .error + severity: .error, ), ], - macros: injectableTestMacros + macros: injectableTestMacros, ) } @@ -584,7 +583,7 @@ import SafeDICore line: 3, column: 39, severity: .error, - fixIts: [FixItSpec(message: "Mark the type as optional using `?`")] + fixIts: [FixItSpec(message: "Mark the type as optional using `?`")], ), ], macros: injectableTestMacros, @@ -594,7 +593,7 @@ import SafeDICore public struct ExampleService { @Received(onlyIfAvailable: true) let receivedA: AnyReceivedA? } - """ + """, ) } } diff --git a/Tests/SafeDIMacrosTests/InstantiableMacroTests.swift b/Tests/SafeDIMacrosTests/InstantiableMacroTests.swift index 030c21b1..95eebfcd 100644 --- a/Tests/SafeDIMacrosTests/InstantiableMacroTests.swift +++ b/Tests/SafeDIMacrosTests/InstantiableMacroTests.swift @@ -18,12 +18,11 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. +import SafeDICore import SwiftSyntaxMacros import SwiftSyntaxMacrosGenericTestSupport import Testing -import SafeDICore - #if canImport(SafeDIMacros) @testable import SafeDIMacros @@ -56,7 +55,7 @@ import SafeDICore public init() {} } """, - macros: instantiableTestMacros + macros: instantiableTestMacros, ) } @@ -78,7 +77,7 @@ import SafeDICore public var description: String { "ExampleService" } } """, - macros: instantiableTestMacros + macros: instantiableTestMacros, ) } @@ -99,10 +98,10 @@ import SafeDICore message: "@Instantiable must decorate an extension on a type or a class, struct, or actor declaration", line: 1, column: 1, - severity: .error + severity: .error, ), ], - macros: instantiableTestMacros + macros: instantiableTestMacros, ) } @@ -121,10 +120,10 @@ import SafeDICore message: "@Instantiable must decorate an extension on a type or a class, struct, or actor declaration", line: 1, column: 1, - severity: .error + severity: .error, ), ], - macros: instantiableTestMacros + macros: instantiableTestMacros, ) } @@ -143,10 +142,10 @@ import SafeDICore message: "The argument `fulfillingAdditionalTypes` must not include optionals", line: 1, column: 1, - severity: .error + severity: .error, ), ], - macros: instantiableTestMacros + macros: instantiableTestMacros, ) } @@ -167,10 +166,10 @@ import SafeDICore message: "The argument `fulfillingAdditionalTypes` must be an inlined array", line: 2, column: 1, - severity: .error + severity: .error, ), ], - macros: instantiableTestMacros + macros: instantiableTestMacros, ) } @@ -189,10 +188,10 @@ import SafeDICore message: "The argument `fulfillingAdditionalTypes` must be an inlined array", line: 1, column: 1, - severity: .error + severity: .error, ), ], - macros: instantiableTestMacros + macros: instantiableTestMacros, ) } @@ -222,7 +221,7 @@ import SafeDICore private let renamed2Dependency: Dependency } """, - macros: instantiableTestMacros + macros: instantiableTestMacros, ) } @@ -258,10 +257,10 @@ import SafeDICore """, line: 1, column: 1, - severity: .error + severity: .error, ), ], - macros: instantiableTestMacros + macros: instantiableTestMacros, ) } @@ -297,10 +296,10 @@ import SafeDICore """, line: 1, column: 1, - severity: .error + severity: .error, ), ], - macros: instantiableTestMacros + macros: instantiableTestMacros, ) } @@ -325,10 +324,10 @@ import SafeDICore message: "The argument `fulfillingAdditionalTypes` must be an inlined array", line: 2, column: 1, - severity: .error + severity: .error, ), ], - macros: instantiableTestMacros + macros: instantiableTestMacros, ) } @@ -351,10 +350,10 @@ import SafeDICore message: "The argument `fulfillingAdditionalTypes` must be an inlined array", line: 1, column: 1, - severity: .error + severity: .error, ), ], - macros: instantiableTestMacros + macros: instantiableTestMacros, ) } @@ -379,10 +378,10 @@ import SafeDICore message: "@Instantiable-decorated extension must have a single `instantiate(…)` method that returns `ExampleService`", line: 1, column: 1, - severity: .error + severity: .error, ), ], - macros: instantiableTestMacros + macros: instantiableTestMacros, ) } @@ -400,7 +399,7 @@ import SafeDICore public static func instantiate() -> Foo { fatalError() } } """, - macros: instantiableTestMacros + macros: instantiableTestMacros, ) } @@ -428,10 +427,10 @@ import SafeDICore """, line: 1, column: 1, - severity: .error + severity: .error, ), ], - macros: instantiableTestMacros + macros: instantiableTestMacros, ) } @@ -457,7 +456,7 @@ import SafeDICore severity: .error, fixIts: [ FixItSpec(message: "Add required initializer"), - ] + ], ), ], macros: instantiableTestMacros, @@ -470,7 +469,7 @@ import SafeDICore public init() {} } - """ + """, ) } @@ -494,7 +493,7 @@ import SafeDICore severity: .error, fixIts: [ FixItSpec(message: "Add required initializer"), - ] + ], ), ], macros: instantiableTestMacros, @@ -507,7 +506,7 @@ import SafeDICore public init() {} } - """ + """, ) } @@ -531,7 +530,7 @@ import SafeDICore severity: .error, fixIts: [ FixItSpec(message: "Add required initializer"), - ] + ], ), ], macros: instantiableTestMacros, @@ -544,7 +543,7 @@ import SafeDICore public init() {} } - """ + """, ) } @@ -562,7 +561,7 @@ import SafeDICore public init() {} } """, - macros: instantiableTestMacros + macros: instantiableTestMacros, ) } @@ -588,7 +587,7 @@ import SafeDICore severity: .error, fixIts: [ FixItSpec(message: "Add required initializer"), - ] + ], ), ], macros: instantiableTestMacros, @@ -602,7 +601,7 @@ import SafeDICore var initializedVariable = "test" } - """ + """, ) } @@ -628,7 +627,7 @@ import SafeDICore severity: .error, fixIts: [ FixItSpec(message: "Add required initializer"), - ] + ], ), ], macros: instantiableTestMacros, @@ -642,7 +641,7 @@ import SafeDICore var initializedVariable { "test" } } - """ + """, ) } @@ -668,7 +667,7 @@ import SafeDICore severity: .error, fixIts: [ FixItSpec(message: "Add required initializer"), - ] + ], ), ], macros: instantiableTestMacros, @@ -684,7 +683,7 @@ import SafeDICore @Instantiated @Unknown let instantiatedA: InstantiatedA } - """ + """, ) } @@ -717,7 +716,7 @@ import SafeDICore severity: .error, fixIts: [ FixItSpec(message: "Add required initializer"), - ] + ], ), ], macros: instantiableTestMacros, @@ -737,7 +736,7 @@ import SafeDICore #endif let instantiatedA: InstantiatedA } - """ + """, ) } @@ -763,7 +762,7 @@ import SafeDICore } } """, - macros: instantiableTestMacros + macros: instantiableTestMacros, ) } @@ -789,7 +788,7 @@ import SafeDICore public typealias ForwardedProperties = () -> Void } """, - macros: instantiableTestMacros + macros: instantiableTestMacros, ) } @@ -815,7 +814,7 @@ import SafeDICore public typealias ForwardedProperties = @Sendable () -> Void } """, - macros: instantiableTestMacros + macros: instantiableTestMacros, ) } @@ -841,7 +840,7 @@ import SafeDICore public typealias ForwardedProperties = @Sendable () -> Void } """, - macros: instantiableTestMacros + macros: instantiableTestMacros, ) } @@ -871,7 +870,7 @@ import SafeDICore public typealias ForwardedProperties = (userID: String, userName: String) } """, - macros: instantiableTestMacros + macros: instantiableTestMacros, ) } @@ -897,7 +896,7 @@ import SafeDICore } } """, - macros: instantiableTestMacros + macros: instantiableTestMacros, ) } @@ -929,7 +928,7 @@ import SafeDICore } } """, - macros: instantiableTestMacros + macros: instantiableTestMacros, ) } @@ -955,7 +954,7 @@ import SafeDICore severity: .error, fixIts: [ FixItSpec(message: "Add required initializer"), - ] + ], ), ], macros: instantiableTestMacros, @@ -971,7 +970,7 @@ import SafeDICore @Instantiated let instantiatedA: InstantiatedA } - """ + """, ) } @@ -1025,7 +1024,7 @@ import SafeDICore severity: .error, fixIts: [ FixItSpec(message: "Add required initializer"), - ] + ], ), ], macros: instantiableTestMacros, @@ -1055,7 +1054,7 @@ import SafeDICore let uninitializedProperty: Any } } - """ + """, ) } @@ -1085,7 +1084,7 @@ import SafeDICore severity: .error, fixIts: [ FixItSpec(message: "Add required initializer"), - ] + ], ), ], macros: instantiableTestMacros, @@ -1103,7 +1102,7 @@ import SafeDICore let initializedProperty = 5 } - """ + """, ) } @@ -1133,7 +1132,7 @@ import SafeDICore severity: .error, fixIts: [ FixItSpec(message: "Add required initializer"), - ] + ], ), ], macros: instantiableTestMacros, @@ -1151,7 +1150,7 @@ import SafeDICore let initializedProperty: Int = 5 } - """ + """, ) } @@ -1181,7 +1180,7 @@ import SafeDICore severity: .error, fixIts: [ FixItSpec(message: "Add required initializer"), - ] + ], ), ], macros: instantiableTestMacros, @@ -1199,7 +1198,7 @@ import SafeDICore var optionalProperty: Int? } - """ + """, ) } @@ -1231,7 +1230,7 @@ import SafeDICore severity: .error, fixIts: [ FixItSpec(message: "Add required initializer"), - ] + ], ), ], macros: instantiableTestMacros, @@ -1250,7 +1249,7 @@ import SafeDICore // This won't compile but we should still generate an initializer. public static let staticProperty: Int } - """ + """, ) } @@ -1284,7 +1283,7 @@ import SafeDICore severity: .error, fixIts: [ FixItSpec(message: "Add arguments for receivedA: ReceivedA"), - ] + ], ), ], macros: instantiableTestMacros, @@ -1301,7 +1300,7 @@ import SafeDICore @Received let receivedA: ReceivedA } - """ + """, ) } @@ -1339,7 +1338,7 @@ import SafeDICore severity: .error, fixIts: [ FixItSpec(message: "Add arguments for receivedB: ReceivedB"), - ] + ], ), ], macros: instantiableTestMacros, @@ -1361,7 +1360,7 @@ import SafeDICore @Received let receivedA: ReceivedA @Received let receivedB: ReceivedB } - """ + """, ) } @@ -1403,7 +1402,7 @@ import SafeDICore severity: .error, fixIts: [ FixItSpec(message: "Add arguments for receivedB: ReceivedB"), - ] + ], ), ], macros: instantiableTestMacros, @@ -1425,7 +1424,7 @@ import SafeDICore @Received let receivedA: ReceivedA @Received let receivedB: ReceivedB } - """ + """, ) } @@ -1465,7 +1464,7 @@ import SafeDICore severity: .error, fixIts: [ FixItSpec(message: "Add arguments for forwardedA: ForwardedA"), - ] + ], ), ], macros: instantiableTestMacros, @@ -1485,7 +1484,7 @@ import SafeDICore @Received let receivedA: ReceivedA @Received let receivedB: ReceivedB } - """ + """, ) } @@ -1525,7 +1524,7 @@ import SafeDICore severity: .error, fixIts: [ FixItSpec(message: "Add arguments for receivedA: ReceivedA"), - ] + ], ), ], macros: instantiableTestMacros, @@ -1545,7 +1544,7 @@ import SafeDICore @Received let receivedA: ReceivedA @Received let receivedB: ReceivedB } - """ + """, ) } @@ -1587,7 +1586,7 @@ import SafeDICore severity: .error, fixIts: [ FixItSpec(message: "Add arguments for receivedA: ReceivedA"), - ] + ], ), ], macros: instantiableTestMacros, @@ -1607,7 +1606,7 @@ import SafeDICore @Received let receivedA: ReceivedA @Received let receivedB: ReceivedB } - """ + """, ) } @@ -1653,7 +1652,7 @@ import SafeDICore severity: .error, fixIts: [ FixItSpec(message: "Add arguments for receivedB: ReceivedB"), - ] + ], ), ], macros: instantiableTestMacros, @@ -1677,7 +1676,7 @@ import SafeDICore @Received let receivedA: ReceivedA @Received let receivedB: ReceivedB } - """ + """, ) } @@ -1717,7 +1716,7 @@ import SafeDICore severity: .error, fixIts: [ FixItSpec(message: "Add arguments for forwardedA: ForwardedA"), - ] + ], ), ], macros: instantiableTestMacros, @@ -1737,7 +1736,7 @@ import SafeDICore @Received let receivedA: ReceivedA @Received let receivedB: ReceivedB } - """ + """, ) } @@ -1785,7 +1784,7 @@ import SafeDICore severity: .error, fixIts: [ FixItSpec(message: "Add arguments for receivedA: ReceivedA"), - ] + ], ), ], macros: instantiableTestMacros, @@ -1810,7 +1809,7 @@ import SafeDICore @Received let receivedA: ReceivedA @Received let receivedB: ReceivedB } - """ + """, ) } @@ -1850,7 +1849,7 @@ import SafeDICore severity: .error, fixIts: [ FixItSpec(message: "Add arguments for receivedB: ReceivedB"), - ] + ], ), ], macros: instantiableTestMacros, @@ -1870,7 +1869,7 @@ import SafeDICore @Received let receivedA: ReceivedA @Received let receivedB: ReceivedB } - """ + """, ) } @@ -1914,7 +1913,7 @@ import SafeDICore severity: .error, fixIts: [ FixItSpec(message: "Add arguments for receivedB: ReceivedB"), - ] + ], ), ], macros: instantiableTestMacros, @@ -1936,7 +1935,7 @@ import SafeDICore @Received let receivedA: ReceivedA @Received let receivedB: ReceivedB } - """ + """, ) } @@ -1972,7 +1971,7 @@ import SafeDICore severity: .error, fixIts: [ FixItSpec(message: "Add arguments for received: Received, instantiated: Instantiated, forwarded: Forwarded"), - ] + ], ), ], macros: instantiableTestMacros, @@ -1996,7 +1995,7 @@ import SafeDICore @Instantiated let instantiated: Instantiated @Forwarded let forwarded: Forwarded } - """ + """, ) } @@ -2076,7 +2075,7 @@ import SafeDICore severity: .error, fixIts: [ FixItSpec(message: "Add `public` modifier"), - ] + ], ), ], macros: instantiableTestMacros, @@ -2115,7 +2114,7 @@ import SafeDICore @Received let receivedA: ReceivedA @Received let receivedB: ReceivedB } - """ + """, ) } @@ -2185,7 +2184,7 @@ import SafeDICore severity: .error, fixIts: [ FixItSpec(message: "Add arguments for forwardedA: ForwardedA"), - ] + ], ), ], macros: instantiableTestMacros, @@ -2220,7 +2219,7 @@ import SafeDICore @Received let receivedA: ReceivedA @Received let receivedB: ReceivedB } - """ + """, ) } @@ -2260,7 +2259,7 @@ import SafeDICore severity: .error, fixIts: [ FixItSpec(message: "Add arguments for forwardedA: ForwardedA"), - ] + ], ), ], macros: instantiableTestMacros, @@ -2280,7 +2279,7 @@ import SafeDICore @Received let receivedA: ReceivedA @Received let receivedB: ReceivedB } - """ + """, ) } @@ -2310,7 +2309,7 @@ import SafeDICore severity: .error, fixIts: [ FixItSpec(message: "Add required initializer"), - ] + ], ), ], macros: instantiableTestMacros, @@ -2332,7 +2331,7 @@ import SafeDICore @Forwarded let userName: String } - """ + """, ) } @@ -2358,7 +2357,7 @@ import SafeDICore severity: .error, fixIts: [ FixItSpec(message: "Add required initializer"), - ] + ], ), ], macros: instantiableTestMacros, @@ -2374,7 +2373,7 @@ import SafeDICore @Forwarded let closure: () -> Void } - """ + """, ) } @@ -2400,7 +2399,7 @@ import SafeDICore severity: .error, fixIts: [ FixItSpec(message: "Add required initializer"), - ] + ], ), ], macros: instantiableTestMacros, @@ -2416,7 +2415,7 @@ import SafeDICore @Forwarded let closure: @Sendable () -> Void } - """ + """, ) } @@ -2442,7 +2441,7 @@ import SafeDICore severity: .error, fixIts: [ FixItSpec(message: "Add required initializer"), - ] + ], ), ], macros: instantiableTestMacros, @@ -2458,7 +2457,7 @@ import SafeDICore @Instantiated private let instantiatableAInstantiator: Instantiator } - """ + """, ) } @@ -2500,7 +2499,7 @@ import SafeDICore severity: .error, fixIts: [ FixItSpec(message: "Add `public` modifier"), - ] + ], ), ], macros: instantiableTestMacros, @@ -2520,7 +2519,7 @@ import SafeDICore @Instantiated let b: B @Forwarded let c: C } - """ + """, ) } @@ -2562,7 +2561,7 @@ import SafeDICore severity: .error, fixIts: [ FixItSpec(message: "Add `public` modifier"), - ] + ], ), ], macros: instantiableTestMacros, @@ -2582,7 +2581,7 @@ import SafeDICore @Instantiated let b: B @Forwarded let c: C } - """ + """, ) } @@ -2624,7 +2623,7 @@ import SafeDICore severity: .error, fixIts: [ FixItSpec(message: "Add `public` modifier"), - ] + ], ), ], macros: instantiableTestMacros, @@ -2644,7 +2643,7 @@ import SafeDICore @Instantiated let b: B @Forwarded let c: C } - """ + """, ) } @@ -2686,7 +2685,7 @@ import SafeDICore severity: .error, fixIts: [ FixItSpec(message: "Add `public` modifier"), - ] + ], ), ], macros: instantiableTestMacros, @@ -2706,7 +2705,7 @@ import SafeDICore @Instantiated let b: B @Forwarded let c: C } - """ + """, ) } @@ -2748,7 +2747,7 @@ import SafeDICore severity: .error, fixIts: [ FixItSpec(message: "Add `public` modifier"), - ] + ], ), ], macros: instantiableTestMacros, @@ -2768,7 +2767,7 @@ import SafeDICore @Instantiated let b: B @Forwarded let c: C } - """ + """, ) } @@ -2822,7 +2821,7 @@ import SafeDICore severity: .error, fixIts: [ FixItSpec(message: "Add `public` modifier"), - ] + ], ), ], macros: instantiableTestMacros, @@ -2848,7 +2847,7 @@ import SafeDICore @Instantiated let b: B @Forwarded let c: C } - """ + """, ) } @@ -2904,7 +2903,7 @@ import SafeDICore severity: .error, fixIts: [ FixItSpec(message: "Add `public` modifier"), - ] + ], ), ], macros: instantiableTestMacros, @@ -2931,7 +2930,7 @@ import SafeDICore @Instantiated let b: B @Forwarded let c: C } - """ + """, ) } @@ -2959,7 +2958,7 @@ import SafeDICore } } """, - macros: instantiableTestMacros + macros: instantiableTestMacros, ) } @@ -2981,7 +2980,7 @@ import SafeDICore } } """, - macros: instantiableTestMacros + macros: instantiableTestMacros, ) } @@ -3007,7 +3006,7 @@ import SafeDICore severity: .error, fixIts: [ FixItSpec(message: "Declare conformance to `Instantiable`"), - ] + ], ), ], macros: instantiableTestMacros, @@ -3019,7 +3018,7 @@ import SafeDICore public final class ExampleService: Instantiable { public init() {} } - """ + """, ) } @@ -3047,7 +3046,7 @@ import SafeDICore severity: .error, fixIts: [ FixItSpec(message: "Declare conformance to `Instantiable`"), - ] + ], ), ], macros: instantiableTestMacros, @@ -3060,7 +3059,7 @@ import SafeDICore public init() {} public var description: String { "ExampleService" } } - """ + """, ) } @@ -3088,7 +3087,7 @@ import SafeDICore severity: .error, fixIts: [ FixItSpec(message: "Declare conformance to `Instantiable`"), - ] + ], ), ], macros: instantiableTestMacros, @@ -3101,7 +3100,7 @@ import SafeDICore public init() {} public var description: String { "ExampleService" } } - """ + """, ) } @@ -3121,7 +3120,7 @@ import SafeDICore public var description: String { "ExampleService" } } """, - macros: instantiableTestMacros + macros: instantiableTestMacros, ) } @@ -3155,7 +3154,7 @@ import SafeDICore severity: .error, fixIts: [ FixItSpec(message: "Remove excessive attached macros"), - ] + ], ), ], macros: instantiableTestMacros, @@ -3171,7 +3170,7 @@ import SafeDICore @Received let receivedA: ReceivedA } - """ + """, ) } @@ -3205,7 +3204,7 @@ import SafeDICore severity: .error, fixIts: [ FixItSpec(message: "Remove initializer"), - ] + ], ), ], macros: instantiableTestMacros, @@ -3221,7 +3220,7 @@ import SafeDICore @Instantiated let receivedA: ReceivedA } - """ + """, ) } @@ -3255,7 +3254,7 @@ import SafeDICore severity: .error, fixIts: [ FixItSpec(message: "Add `public` modifier"), - ] + ], ), ], macros: instantiableTestMacros, @@ -3271,7 +3270,7 @@ import SafeDICore @Instantiated let receivedA: ReceivedA } - """ + """, ) } @@ -3305,7 +3304,7 @@ import SafeDICore severity: .error, fixIts: [ FixItSpec(message: "Add `public` modifier"), - ] + ], ), ], macros: instantiableTestMacros, @@ -3321,7 +3320,7 @@ import SafeDICore @Instantiated let receivedA: ReceivedA } - """ + """, ) } @@ -3355,7 +3354,7 @@ import SafeDICore severity: .error, fixIts: [ FixItSpec(message: "Add `public` modifier"), - ] + ], ), ], macros: instantiableTestMacros, @@ -3371,7 +3370,7 @@ import SafeDICore @Instantiated let receivedA: ReceivedA } - """ + """, ) } @@ -3405,7 +3404,7 @@ import SafeDICore severity: .error, fixIts: [ FixItSpec(message: "Add `public` modifier"), - ] + ], ), ], macros: instantiableTestMacros, @@ -3421,7 +3420,7 @@ import SafeDICore @Instantiated let receivedA: ReceivedA } - """ + """, ) } @@ -3455,7 +3454,7 @@ import SafeDICore severity: .error, fixIts: [ FixItSpec(message: "Add `public` modifier"), - ] + ], ), ], macros: instantiableTestMacros, @@ -3471,7 +3470,7 @@ import SafeDICore @Instantiated let receivedA: ReceivedA } - """ + """, ) } @@ -3505,7 +3504,7 @@ import SafeDICore severity: .error, fixIts: [ FixItSpec(message: "Add `public` modifier"), - ] + ], ), ], macros: instantiableTestMacros, @@ -3521,7 +3520,7 @@ import SafeDICore @Instantiated let receivedA: ReceivedA } - """ + """, ) } @@ -3555,7 +3554,7 @@ import SafeDICore severity: .error, fixIts: [ FixItSpec(message: "Add `public` modifier"), - ] + ], ), ], macros: instantiableTestMacros, @@ -3571,7 +3570,7 @@ import SafeDICore @Instantiated let receivedA: ReceivedA } - """ + """, ) } @@ -3597,7 +3596,7 @@ import SafeDICore severity: .error, fixIts: [ FixItSpec(message: "Add required initializer"), - ] + ], ), ], macros: instantiableTestMacros, @@ -3614,7 +3613,7 @@ import SafeDICore let uninitializedProperty: Int } - """ + """, ) } @@ -3644,7 +3643,7 @@ import SafeDICore severity: .error, fixIts: [ FixItSpec(message: "Add required initializer"), - ] + ], ), ], macros: instantiableTestMacros, @@ -3665,7 +3664,7 @@ import SafeDICore let uninitializedProperty: Int } - """ + """, ) } @@ -3699,7 +3698,7 @@ import SafeDICore severity: .error, fixIts: [ FixItSpec(message: "Add required initializer"), - ] + ], ), ], macros: instantiableTestMacros, @@ -3725,7 +3724,7 @@ import SafeDICore let uninitializedProperty2: Int, uninitializedProperty3: Int, initializedProperty = "init" let (uninitializedProperty4, uninitializedProperty5): (Int, Int) } - """ + """, ) } @@ -3751,7 +3750,7 @@ import SafeDICore severity: .error, fixIts: [ FixItSpec(message: "Declare conformance to `Instantiable`"), - ] + ], ), ], macros: instantiableTestMacros, @@ -3763,7 +3762,7 @@ import SafeDICore extension ExampleService: Instantiable { public static func instantiate() -> ExampleService { fatalError() } } - """ + """, ) } @@ -3793,7 +3792,7 @@ import SafeDICore severity: .error, fixIts: [ FixItSpec(message: "Declare conformance to `Instantiable`"), - ] + ], ), ], macros: instantiableTestMacros, @@ -3807,7 +3806,7 @@ import SafeDICore public var description: String { "ExampleService" } } - """ + """, ) } @@ -3837,7 +3836,7 @@ import SafeDICore severity: .error, fixIts: [ FixItSpec(message: "Declare conformance to `Instantiable`"), - ] + ], ), ], macros: instantiableTestMacros, @@ -3851,7 +3850,7 @@ import SafeDICore public var description: String { "ExampleService" } } - """ + """, ) } @@ -3875,7 +3874,7 @@ import SafeDICore severity: .error, fixIts: [ FixItSpec(message: "Add `public static func instantiate() -> ExampleService` method"), - ] + ], ), ], macros: instantiableTestMacros, @@ -3890,7 +3889,7 @@ import SafeDICore } - """ + """, ) } @@ -3916,7 +3915,7 @@ import SafeDICore severity: .error, fixIts: [ FixItSpec(message: "Set `public static` modifiers"), - ] + ], ), ], macros: instantiableTestMacros, @@ -3928,7 +3927,7 @@ import SafeDICore extension ExampleService: Instantiable { public static func instantiate() -> ExampleService { fatalError() } } - """ + """, ) } @@ -3954,7 +3953,7 @@ import SafeDICore severity: .error, fixIts: [ FixItSpec(message: "Set `public static` modifiers"), - ] + ], ), ], macros: instantiableTestMacros, @@ -3966,7 +3965,7 @@ import SafeDICore extension ExampleService: Instantiable { public static func instantiate() -> ExampleService { fatalError() } } - """ + """, ) } @@ -3992,7 +3991,7 @@ import SafeDICore severity: .error, fixIts: [ FixItSpec(message: "Set `public static` modifiers"), - ] + ], ), ], macros: instantiableTestMacros, @@ -4004,7 +4003,7 @@ import SafeDICore extension ExampleService: Instantiable { public static func instantiate() -> ExampleService { fatalError() } } - """ + """, ) } @@ -4030,7 +4029,7 @@ import SafeDICore severity: .error, fixIts: [ FixItSpec(message: "Make `instantiate()`’s return type the same base type as the extended type"), - ] + ], ), ], macros: instantiableTestMacros, @@ -4042,7 +4041,7 @@ import SafeDICore extension ExampleService: Instantiable { public static func instantiate() -> ExampleService { fatalError() } } - """ + """, ) } @@ -4068,7 +4067,7 @@ import SafeDICore severity: .error, fixIts: [ FixItSpec(message: "Make `instantiate()`’s return type the same base type as the extended type"), - ] + ], ), ], macros: instantiableTestMacros, @@ -4080,7 +4079,7 @@ import SafeDICore extension ExampleService: Instantiable { public static func instantiate() -> ExampleService { fatalError() } } - """ + """, ) } @@ -4106,7 +4105,7 @@ import SafeDICore severity: .error, fixIts: [ FixItSpec(message: "Remove effect specifiers"), - ] + ], ), ], macros: instantiableTestMacros, @@ -4118,7 +4117,7 @@ import SafeDICore extension ExampleService: Instantiable { public static func instantiate() -> ExampleService { fatalError() } } - """ + """, ) } @@ -4144,7 +4143,7 @@ import SafeDICore severity: .error, fixIts: [ FixItSpec(message: "Remove effect specifiers"), - ] + ], ), ], macros: instantiableTestMacros, @@ -4156,7 +4155,7 @@ import SafeDICore extension ExampleService: Instantiable { public static func instantiate() -> ExampleService { fatalError() } } - """ + """, ) } @@ -4182,7 +4181,7 @@ import SafeDICore severity: .error, fixIts: [ FixItSpec(message: "Remove effect specifiers"), - ] + ], ), ], macros: instantiableTestMacros, @@ -4194,7 +4193,7 @@ import SafeDICore extension ExampleService: Instantiable { public static func instantiate() -> ExampleService { fatalError() } } - """ + """, ) } @@ -4220,7 +4219,7 @@ import SafeDICore severity: .error, fixIts: [ FixItSpec(message: "Remove generic parameter"), - ] + ], ), ], macros: instantiableTestMacros, @@ -4232,7 +4231,7 @@ import SafeDICore extension ExampleService: Instantiable { public static func instantiate() -> ExampleService { fatalError() } } - """ + """, ) } @@ -4258,7 +4257,7 @@ import SafeDICore severity: .error, fixIts: [ FixItSpec(message: "Remove generic `where` clause"), - ] + ], ), ], macros: instantiableTestMacros, @@ -4270,7 +4269,7 @@ import SafeDICore extension Array: Instantiable { public static func instantiate() -> Array { fatalError() } } - """ + """, ) } @@ -4296,7 +4295,7 @@ import SafeDICore severity: .error, fixIts: [ FixItSpec(message: "Remove generic `where` clause"), - ] + ], ), ], macros: instantiableTestMacros, @@ -4308,7 +4307,7 @@ import SafeDICore extension Array: Instantiable { public static func instantiate() -> Array { fatalError() } } - """ + """, ) } } diff --git a/Tests/SafeDIMacrosTests/SafeDIConfigurationMacroTests.swift b/Tests/SafeDIMacrosTests/SafeDIConfigurationMacroTests.swift index 083aefc4..beff0e0c 100644 --- a/Tests/SafeDIMacrosTests/SafeDIConfigurationMacroTests.swift +++ b/Tests/SafeDIMacrosTests/SafeDIConfigurationMacroTests.swift @@ -18,12 +18,11 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. +import SafeDICore import SwiftSyntaxMacros import SwiftSyntaxMacrosGenericTestSupport import Testing -import SafeDICore - #if canImport(SafeDIMacros) @testable import SafeDIMacros @@ -55,7 +54,7 @@ import SafeDICore static let additionalDirectoriesToInclude: [StaticString] = [] } """, - macros: safeDIConfigurationTestMacros + macros: safeDIConfigurationTestMacros, ) } @@ -75,7 +74,7 @@ import SafeDICore static let additionalDirectoriesToInclude: [StaticString] = [] } """, - macros: safeDIConfigurationTestMacros + macros: safeDIConfigurationTestMacros, ) } @@ -95,7 +94,7 @@ import SafeDICore static let additionalDirectoriesToInclude: [StaticString] = ["DirA", "DirB"] } """, - macros: safeDIConfigurationTestMacros + macros: safeDIConfigurationTestMacros, ) } @@ -121,10 +120,10 @@ import SafeDICore DiagnosticSpec( message: "@SafeDIConfiguration must decorate an enum", line: 1, - column: 1 + column: 1, ), ], - macros: safeDIConfigurationTestMacros + macros: safeDIConfigurationTestMacros, ) } @@ -148,10 +147,10 @@ import SafeDICore DiagnosticSpec( message: "@SafeDIConfiguration must decorate an enum", line: 1, - column: 1 + column: 1, ), ], - macros: safeDIConfigurationTestMacros + macros: safeDIConfigurationTestMacros, ) } @@ -175,10 +174,10 @@ import SafeDICore DiagnosticSpec( message: "The `additionalImportedModules` property must be initialized with an array of string literals", line: 1, - column: 1 + column: 1, ), ], - macros: safeDIConfigurationTestMacros + macros: safeDIConfigurationTestMacros, ) } @@ -202,10 +201,10 @@ import SafeDICore DiagnosticSpec( message: "The `additionalDirectoriesToInclude` property must be initialized with an array of string literals", line: 1, - column: 1 + column: 1, ), ], - macros: safeDIConfigurationTestMacros + macros: safeDIConfigurationTestMacros, ) } @@ -229,10 +228,10 @@ import SafeDICore DiagnosticSpec( message: "The `additionalImportedModules` property must be initialized with an array of string literals", line: 1, - column: 1 + column: 1, ), ], - macros: safeDIConfigurationTestMacros + macros: safeDIConfigurationTestMacros, ) } @@ -257,7 +256,7 @@ import SafeDICore column: 22, fixIts: [ FixItSpec(message: "Add `static let additionalImportedModules: [StaticString]` property"), - ] + ], ), ], macros: safeDIConfigurationTestMacros, @@ -274,7 +273,7 @@ import SafeDICore /// This property only applies to SafeDI repos that utilize the SPM plugin via an Xcode project. static let additionalDirectoriesToInclude: [StaticString] = [] } - """ + """, ) } @@ -299,7 +298,7 @@ import SafeDICore column: 22, fixIts: [ FixItSpec(message: "Add `static let additionalDirectoriesToInclude: [StaticString]` property"), - ] + ], ), ], macros: safeDIConfigurationTestMacros, @@ -314,7 +313,7 @@ import SafeDICore static let additionalDirectoriesToInclude: [StaticString] = [] static let additionalImportedModules: [StaticString] = [] } - """ + """, ) } @@ -339,7 +338,7 @@ import SafeDICore column: 22, fixIts: [ FixItSpec(message: "Add `static let additionalImportedModules: [StaticString]` property"), - ] + ], ), ], macros: safeDIConfigurationTestMacros, @@ -354,7 +353,7 @@ import SafeDICore static let additionalImportedModules: [StaticString] = [] static let additionalDirectoriesToInclude: [StaticString] = [] } - """ + """, ) } } diff --git a/Tests/SafeDITests/ErasedInstantiatorTests.swift b/Tests/SafeDITests/ErasedInstantiatorTests.swift index 4872fbd9..bbde9c45 100644 --- a/Tests/SafeDITests/ErasedInstantiatorTests.swift +++ b/Tests/SafeDITests/ErasedInstantiatorTests.swift @@ -20,12 +20,11 @@ import Foundation import Testing - @testable import SafeDI struct ErasedInstantiatorTests { @Test @MainActor - func instantiate_returnsNewObjectEachTime() async { + func instantiate_returnsNewObjectEachTime() { let systemUnderTest = ErasedInstantiator() { BuiltProduct() } let firstBuiltProduct = systemUnderTest.instantiate() let secondBuiltProduct = systemUnderTest.instantiate() @@ -33,7 +32,7 @@ struct ErasedInstantiatorTests { } @Test @MainActor - func instantiate_withForwardedArgument_returnsNewObjectEachTime() async { + func instantiate_withForwardedArgument_returnsNewObjectEachTime() { let systemUnderTest = ErasedInstantiator { id in BuiltProductWithForwardedArgument(id: id) } let id = UUID().uuidString let firstBuiltProduct = systemUnderTest.instantiate(id) diff --git a/Tests/SafeDITests/InstantiatorTests.swift b/Tests/SafeDITests/InstantiatorTests.swift index 19cc5a87..18b89c0c 100644 --- a/Tests/SafeDITests/InstantiatorTests.swift +++ b/Tests/SafeDITests/InstantiatorTests.swift @@ -20,12 +20,11 @@ import Foundation import Testing - @testable import SafeDI struct InstantiatorTests { @Test @MainActor - func instantiate_returnsNewObjectEachTime() async { + func instantiate_returnsNewObjectEachTime() { let systemUnderTest = Instantiator { BuiltProduct() } let firstBuiltProduct = systemUnderTest.instantiate() let secondBuiltProduct = systemUnderTest.instantiate() @@ -33,7 +32,7 @@ struct InstantiatorTests { } @Test @MainActor - func instantiate_withForwardedArgument_returnsNewObjectEachTime() async { + func instantiate_withForwardedArgument_returnsNewObjectEachTime() { let systemUnderTest = Instantiator { id in BuiltProductWithForwardedArgument(id: id) } let id = UUID().uuidString let firstBuiltProduct = systemUnderTest.instantiate(id) diff --git a/Tests/SafeDITests/SendableErasedInstantiatorTests.swift b/Tests/SafeDITests/SendableErasedInstantiatorTests.swift index 6fbe0122..55a78ff3 100644 --- a/Tests/SafeDITests/SendableErasedInstantiatorTests.swift +++ b/Tests/SafeDITests/SendableErasedInstantiatorTests.swift @@ -20,7 +20,6 @@ import Foundation import Testing - @testable import SafeDI struct SendableErasedInstantiatorTests { diff --git a/Tests/SafeDITests/SendableInstantiatorTests.swift b/Tests/SafeDITests/SendableInstantiatorTests.swift index 7097911a..6c8e2196 100644 --- a/Tests/SafeDITests/SendableInstantiatorTests.swift +++ b/Tests/SafeDITests/SendableInstantiatorTests.swift @@ -20,7 +20,6 @@ import Foundation import Testing - @testable import SafeDI struct SendableInstantiatorTests { diff --git a/Tests/SafeDIToolTests/Helpers/SafeDIToolTestExecution.swift b/Tests/SafeDIToolTests/Helpers/SafeDIToolTestExecution.swift index e0a7e139..6f931ea7 100644 --- a/Tests/SafeDIToolTests/Helpers/SafeDIToolTestExecution.swift +++ b/Tests/SafeDIToolTests/Helpers/SafeDIToolTestExecution.swift @@ -21,7 +21,6 @@ import Foundation import SafeDICore import Testing - @testable import SafeDITool func executeSafeDIToolTest( @@ -31,7 +30,7 @@ func executeSafeDIToolTest( buildDependencyTreeOutput: Bool = false, buildDOTFileOutput: Bool = false, filesToDelete: inout [URL], - includeFolders: [String] = [] + includeFolders: [String] = [], ) async throws -> TestOutput { let swiftFileCSV = URL.temporaryFile let swiftFiles = try swiftFileContent @@ -80,7 +79,7 @@ func executeSafeDIToolTest( moduleInfo: JSONDecoder().decode(SafeDITool.ModuleInfo.self, from: Data(contentsOf: moduleInfoOutput)), moduleInfoOutputPath: moduleInfoOutput.relativePath, dependencyTree: buildDependencyTreeOutput ? String(data: Data(contentsOf: dependencyTreeOutput), encoding: .utf8) : nil, - dotTree: buildDOTFileOutput ? String(data: Data(contentsOf: dotTreeOutput), encoding: .utf8) : nil + dotTree: buildDOTFileOutput ? String(data: Data(contentsOf: dotTreeOutput), encoding: .utf8) : nil, ) } } @@ -110,7 +109,7 @@ struct StubFileFinder: FileFinder { at _: URL, includingPropertiesForKeys _: [URLResourceKey]?, options _: FileManager.DirectoryEnumerationOptions, - errorHandler _: ((URL, any Error) -> Bool)? + errorHandler _: ((URL, any Error) -> Bool)?, ) -> FileManager.DirectoryEnumerator? { StubDirectoryEnumerator(files: files) } @@ -139,7 +138,7 @@ struct StubFileFinder: FileFinder { func assertThrowsError( _ errorDescription: String, sourceLocation: SourceLocation = #_sourceLocation, - block: () async throws -> some Sendable + block: () async throws -> some Sendable, ) async { do { _ = try await block() diff --git a/Tests/SafeDIToolTests/SafeDIToolCodeGenerationErrorTests.swift b/Tests/SafeDIToolTests/SafeDIToolCodeGenerationErrorTests.swift index c66ff847..4a8c774c 100644 --- a/Tests/SafeDIToolTests/SafeDIToolCodeGenerationErrorTests.swift +++ b/Tests/SafeDIToolTests/SafeDIToolCodeGenerationErrorTests.swift @@ -21,7 +21,6 @@ import Foundation import SafeDICore import Testing - @testable import SafeDITool struct SafeDIToolCodeGenerationErrorTests: ~Copyable { @@ -44,7 +43,7 @@ struct SafeDIToolCodeGenerationErrorTests: ~Copyable { await assertThrowsError( """ No `@Instantiable`-decorated type or extension found to fulfill `@Instantiated`-decorated property with type `DoesNotExist` - """ + """, ) { try await executeSafeDIToolTest( swiftFileContent: [ @@ -59,7 +58,7 @@ struct SafeDIToolCodeGenerationErrorTests: ~Copyable { """, ], buildDependencyTreeOutput: true, - filesToDelete: &filesToDelete + filesToDelete: &filesToDelete, ) } } @@ -73,7 +72,7 @@ struct SafeDIToolCodeGenerationErrorTests: ~Copyable { Did you mean one of the following available properties? \t`value: Grandchild.NestedType` - """ + """, ) { try await executeSafeDIToolTest( swiftFileContent: [ @@ -105,7 +104,7 @@ struct SafeDIToolCodeGenerationErrorTests: ~Copyable { """, ], buildDependencyTreeOutput: true, - filesToDelete: &filesToDelete + filesToDelete: &filesToDelete, ) } } @@ -119,7 +118,7 @@ struct SafeDIToolCodeGenerationErrorTests: ~Copyable { Did you mean one of the following available properties? \t`value: NestedType` - """ + """, ) { try await executeSafeDIToolTest( swiftFileContent: [ @@ -151,7 +150,7 @@ struct SafeDIToolCodeGenerationErrorTests: ~Copyable { """, ], buildDependencyTreeOutput: true, - filesToDelete: &filesToDelete + filesToDelete: &filesToDelete, ) } } @@ -161,7 +160,7 @@ struct SafeDIToolCodeGenerationErrorTests: ~Copyable { await assertThrowsError( """ @Instantiable-decorated types and extensions must have globally unique type names and fulfill globally unqiue types. Found multiple types or extensions fulfilling `Container` - """ + """, ) { try await executeSafeDIToolTest( swiftFileContent: [ @@ -186,7 +185,7 @@ struct SafeDIToolCodeGenerationErrorTests: ~Copyable { """, ], buildDependencyTreeOutput: true, - filesToDelete: &filesToDelete + filesToDelete: &filesToDelete, ) } } @@ -196,7 +195,7 @@ struct SafeDIToolCodeGenerationErrorTests: ~Copyable { await assertThrowsError( """ @Instantiable-decorated types and extensions must have globally unique type names and fulfill globally unqiue types. Found multiple types or extensions fulfilling `Container` - """ + """, ) { try await executeSafeDIToolTest( swiftFileContent: [ @@ -221,7 +220,7 @@ struct SafeDIToolCodeGenerationErrorTests: ~Copyable { """, ], buildDependencyTreeOutput: true, - filesToDelete: &filesToDelete + filesToDelete: &filesToDelete, ) } } @@ -231,7 +230,7 @@ struct SafeDIToolCodeGenerationErrorTests: ~Copyable { await assertThrowsError( """ No `@Instantiable`-decorated type or extension found to fulfill `@Instantiated`-decorated property with type `URLSession` - """ + """, ) { try await executeSafeDIToolTest( swiftFileContent: [ @@ -255,7 +254,7 @@ struct SafeDIToolCodeGenerationErrorTests: ~Copyable { """, ], buildDependencyTreeOutput: true, - filesToDelete: &filesToDelete + filesToDelete: &filesToDelete, ) } } @@ -266,7 +265,7 @@ struct SafeDIToolCodeGenerationErrorTests: ~Copyable { """ @Received property `urlSession: URLSession` is not @Instantiated or @Forwarded in chain: \tRootViewController -> DefaultNetworkService - """ + """, ) { try await executeSafeDIToolTest( swiftFileContent: [ @@ -290,7 +289,7 @@ struct SafeDIToolCodeGenerationErrorTests: ~Copyable { """, ], buildDependencyTreeOutput: true, - filesToDelete: &filesToDelete + filesToDelete: &filesToDelete, ) } } @@ -304,7 +303,7 @@ struct SafeDIToolCodeGenerationErrorTests: ~Copyable { Did you mean one of the following available properties? \t`erasedType: ErasedType` - """ + """, ) { try await executeSafeDIToolTest( swiftFileContent: [ @@ -335,7 +334,7 @@ struct SafeDIToolCodeGenerationErrorTests: ~Copyable { """, ], buildDependencyTreeOutput: true, - filesToDelete: &filesToDelete + filesToDelete: &filesToDelete, ) } } @@ -349,7 +348,7 @@ struct SafeDIToolCodeGenerationErrorTests: ~Copyable { Did you mean one of the following available properties? \t`erasedType: any ErasedType` - """ + """, ) { try await executeSafeDIToolTest( swiftFileContent: [ @@ -380,7 +379,7 @@ struct SafeDIToolCodeGenerationErrorTests: ~Copyable { """, ], buildDependencyTreeOutput: true, - filesToDelete: &filesToDelete + filesToDelete: &filesToDelete, ) } } @@ -394,7 +393,7 @@ struct SafeDIToolCodeGenerationErrorTests: ~Copyable { Did you mean one of the following available properties? \t`thing: Thing` - """ + """, ) { try await executeSafeDIToolTest( swiftFileContent: [ @@ -423,7 +422,7 @@ struct SafeDIToolCodeGenerationErrorTests: ~Copyable { """, ], buildDependencyTreeOutput: true, - filesToDelete: &filesToDelete + filesToDelete: &filesToDelete, ) } } @@ -437,7 +436,7 @@ struct SafeDIToolCodeGenerationErrorTests: ~Copyable { Did you mean one of the following available properties? \t`thing: Thing!` - """ + """, ) { try await executeSafeDIToolTest( swiftFileContent: [ @@ -466,7 +465,7 @@ struct SafeDIToolCodeGenerationErrorTests: ~Copyable { """, ], buildDependencyTreeOutput: true, - filesToDelete: &filesToDelete + filesToDelete: &filesToDelete, ) } } @@ -479,7 +478,7 @@ struct SafeDIToolCodeGenerationErrorTests: ~Copyable { \tRoot -> Child The non-optional `thing: Thing` is available in chain. Did you mean to decorate this property with `@Received(onlyIfAvailable: true)`? - """ + """, ) { try await executeSafeDIToolTest( swiftFileContent: [ @@ -508,7 +507,7 @@ struct SafeDIToolCodeGenerationErrorTests: ~Copyable { """, ], buildDependencyTreeOutput: true, - filesToDelete: &filesToDelete + filesToDelete: &filesToDelete, ) } } @@ -522,7 +521,7 @@ struct SafeDIToolCodeGenerationErrorTests: ~Copyable { Did you mean one of the following available properties? \t`thing: Thing?` - """ + """, ) { try await executeSafeDIToolTest( swiftFileContent: [ @@ -551,7 +550,7 @@ struct SafeDIToolCodeGenerationErrorTests: ~Copyable { """, ], buildDependencyTreeOutput: true, - filesToDelete: &filesToDelete + filesToDelete: &filesToDelete, ) } } @@ -565,7 +564,7 @@ struct SafeDIToolCodeGenerationErrorTests: ~Copyable { Did you mean one of the following available properties? \t`thing: Thing` - """ + """, ) { try await executeSafeDIToolTest( swiftFileContent: [ @@ -597,7 +596,7 @@ struct SafeDIToolCodeGenerationErrorTests: ~Copyable { """, ], buildDependencyTreeOutput: true, - filesToDelete: &filesToDelete + filesToDelete: &filesToDelete, ) } } @@ -612,7 +611,7 @@ struct SafeDIToolCodeGenerationErrorTests: ~Copyable { Did you mean one of the following available properties? \t`otherThing: OtherThing` \t`thing: Thing` - """ + """, ) { try await executeSafeDIToolTest( swiftFileContent: [ @@ -645,7 +644,7 @@ struct SafeDIToolCodeGenerationErrorTests: ~Copyable { """, ], buildDependencyTreeOutput: true, - filesToDelete: &filesToDelete + filesToDelete: &filesToDelete, ) } } @@ -655,7 +654,7 @@ struct SafeDIToolCodeGenerationErrorTests: ~Copyable { await assertThrowsError( """ Property `networkService: NetworkService` on RootViewController has at least one @Forwarded property. Property should instead be of type `Instantiator`. - """ + """, ) { try await executeSafeDIToolTest( swiftFileContent: [ @@ -679,7 +678,7 @@ struct SafeDIToolCodeGenerationErrorTests: ~Copyable { """, ], buildDependencyTreeOutput: true, - filesToDelete: &filesToDelete + filesToDelete: &filesToDelete, ) } } @@ -690,7 +689,7 @@ struct SafeDIToolCodeGenerationErrorTests: ~Copyable { """ @Received property `blankie: Blankie` is not @Instantiated or @Forwarded in chain: \tRoot -> ChildB -> Grandchild - """ + """, ) { try await executeSafeDIToolTest( swiftFileContent: [ @@ -726,7 +725,7 @@ struct SafeDIToolCodeGenerationErrorTests: ~Copyable { """, ], buildDependencyTreeOutput: true, - filesToDelete: &filesToDelete + filesToDelete: &filesToDelete, ) } } @@ -746,7 +745,7 @@ struct SafeDIToolCodeGenerationErrorTests: ~Copyable { @Received property `blankie: Blankie` is not @Instantiated or @Forwarded in chain: \tRoot -> ChildB -> Grandchild - """ + """, ) { try await executeSafeDIToolTest( swiftFileContent: [ @@ -783,18 +782,18 @@ struct SafeDIToolCodeGenerationErrorTests: ~Copyable { """, ], buildDependencyTreeOutput: true, - filesToDelete: &filesToDelete + filesToDelete: &filesToDelete, ) } } @Test - mutating func run_onCodeWithInstantiatedPropertyThatRefersToCurrentInstantiable_throwsError() async throws { + mutating func run_onCodeWithInstantiatedPropertyThatRefersToCurrentInstantiable_throwsError() async { await assertThrowsError( """ Dependency cycle detected: \tAuthService -> AuthService - """ + """, ) { try await executeSafeDIToolTest( swiftFileContent: [ @@ -841,18 +840,18 @@ struct SafeDIToolCodeGenerationErrorTests: ~Copyable { """, ], buildDependencyTreeOutput: true, - filesToDelete: &filesToDelete + filesToDelete: &filesToDelete, ) } } @Test - mutating func run_onCodeWithReceivedPropertyThatRefersToCurrentInstantiable_throwsError() async throws { + mutating func run_onCodeWithReceivedPropertyThatRefersToCurrentInstantiable_throwsError() async { await assertThrowsError( """ Dependency received in same chain it is instantiated: \t@Instantiated authService: AuthService -> @Received authService: AuthService - """ + """, ) { try await executeSafeDIToolTest( swiftFileContent: [ @@ -899,7 +898,7 @@ struct SafeDIToolCodeGenerationErrorTests: ~Copyable { """, ], buildDependencyTreeOutput: true, - filesToDelete: &filesToDelete + filesToDelete: &filesToDelete, ) } } @@ -913,7 +912,7 @@ struct SafeDIToolCodeGenerationErrorTests: ~Copyable { Did you mean one of the following available properties? \t`networkService: NetworkService` - """ + """, ) { try await executeSafeDIToolTest( swiftFileContent: [ @@ -953,7 +952,7 @@ struct SafeDIToolCodeGenerationErrorTests: ~Copyable { """, ], buildDependencyTreeOutput: true, - filesToDelete: &filesToDelete + filesToDelete: &filesToDelete, ) } } @@ -967,7 +966,7 @@ struct SafeDIToolCodeGenerationErrorTests: ~Copyable { Did you mean one of the following available properties? \t`networkService: NetworkService` - """ + """, ) { try await executeSafeDIToolTest( swiftFileContent: [ @@ -1007,18 +1006,18 @@ struct SafeDIToolCodeGenerationErrorTests: ~Copyable { """, ], buildDependencyTreeOutput: true, - filesToDelete: &filesToDelete + filesToDelete: &filesToDelete, ) } } @Test - mutating func run_onCodeWhereAliasedReceivedPropertyRefersToCurrentInstantiable_throwsError() async throws { + mutating func run_onCodeWhereAliasedReceivedPropertyRefersToCurrentInstantiable_throwsError() async { await assertThrowsError( """ Dependency received in same chain it is instantiated: \t@Instantiated authService: AuthService -> @Received authService: AuthService - """ + """, ) { try await executeSafeDIToolTest( swiftFileContent: [ @@ -1065,7 +1064,7 @@ struct SafeDIToolCodeGenerationErrorTests: ~Copyable { """, ], buildDependencyTreeOutput: true, - filesToDelete: &filesToDelete + filesToDelete: &filesToDelete, ) } } @@ -1076,7 +1075,7 @@ struct SafeDIToolCodeGenerationErrorTests: ~Copyable { """ @Received property `urlSession: URLSession` is not @Instantiated or @Forwarded in chain: \tRootViewController -> URLSessionWrapper - """ + """, ) { try await executeSafeDIToolTest( swiftFileContent: [ @@ -1100,7 +1099,7 @@ struct SafeDIToolCodeGenerationErrorTests: ~Copyable { """, ], buildDependencyTreeOutput: true, - filesToDelete: &filesToDelete + filesToDelete: &filesToDelete, ) } } @@ -1110,7 +1109,7 @@ struct SafeDIToolCodeGenerationErrorTests: ~Copyable { await assertThrowsError( """ @Instantiable-decorated types and extensions must have globally unique type names and fulfill globally unqiue types. Found multiple types or extensions fulfilling `RootViewController` - """ + """, ) { try await executeSafeDIToolTest( swiftFileContent: [ @@ -1128,7 +1127,7 @@ struct SafeDIToolCodeGenerationErrorTests: ~Copyable { """, ], buildDependencyTreeOutput: true, - filesToDelete: &filesToDelete + filesToDelete: &filesToDelete, ) } } @@ -1138,7 +1137,7 @@ struct SafeDIToolCodeGenerationErrorTests: ~Copyable { await assertThrowsError( """ @Instantiable-decorated types and extensions must have globally unique type names and fulfill globally unqiue types. Found multiple types or extensions fulfilling `RootViewController` - """ + """, ) { try await executeSafeDIToolTest( swiftFileContent: [ @@ -1156,7 +1155,7 @@ struct SafeDIToolCodeGenerationErrorTests: ~Copyable { """, ], buildDependencyTreeOutput: true, - filesToDelete: &filesToDelete + filesToDelete: &filesToDelete, ) } } @@ -1166,7 +1165,7 @@ struct SafeDIToolCodeGenerationErrorTests: ~Copyable { await assertThrowsError( """ @Instantiable-decorated types and extensions must have globally unique type names and fulfill globally unqiue types. Found multiple types or extensions fulfilling `RootViewController` - """ + """, ) { try await executeSafeDIToolTest( swiftFileContent: [ @@ -1188,7 +1187,7 @@ struct SafeDIToolCodeGenerationErrorTests: ~Copyable { """, ], buildDependencyTreeOutput: true, - filesToDelete: &filesToDelete + filesToDelete: &filesToDelete, ) } } @@ -1198,7 +1197,7 @@ struct SafeDIToolCodeGenerationErrorTests: ~Copyable { await assertThrowsError( """ @Instantiable-decorated types and extensions must have globally unique type names and fulfill globally unqiue types. Found multiple types or extensions fulfilling `RootViewController` - """ + """, ) { try await executeSafeDIToolTest( swiftFileContent: [ @@ -1220,7 +1219,7 @@ struct SafeDIToolCodeGenerationErrorTests: ~Copyable { """, ], buildDependencyTreeOutput: true, - filesToDelete: &filesToDelete + filesToDelete: &filesToDelete, ) } } @@ -1230,7 +1229,7 @@ struct SafeDIToolCodeGenerationErrorTests: ~Copyable { await assertThrowsError( """ @Instantiable-decorated types and extensions must have globally unique type names and fulfill globally unqiue types. Found multiple types or extensions fulfilling `RootViewController` - """ + """, ) { try await executeSafeDIToolTest( swiftFileContent: [ @@ -1252,7 +1251,7 @@ struct SafeDIToolCodeGenerationErrorTests: ~Copyable { """, ], buildDependencyTreeOutput: true, - filesToDelete: &filesToDelete + filesToDelete: &filesToDelete, ) } } @@ -1262,7 +1261,7 @@ struct SafeDIToolCodeGenerationErrorTests: ~Copyable { await assertThrowsError( """ @Instantiable-decorated types and extensions must have globally unique type names and fulfill globally unqiue types. Found multiple types or extensions fulfilling `UserDefaults` - """ + """, ) { try await executeSafeDIToolTest( swiftFileContent: [ @@ -1288,7 +1287,7 @@ struct SafeDIToolCodeGenerationErrorTests: ~Copyable { """, ], buildDependencyTreeOutput: true, - filesToDelete: &filesToDelete + filesToDelete: &filesToDelete, ) } } @@ -1298,7 +1297,7 @@ struct SafeDIToolCodeGenerationErrorTests: ~Copyable { await assertThrowsError( """ @Instantiable-decorated types and extensions must have globally unique type names and fulfill globally unqiue types. Found multiple types or extensions fulfilling `UIViewController` - """ + """, ) { try await executeSafeDIToolTest( swiftFileContent: [ @@ -1316,7 +1315,7 @@ struct SafeDIToolCodeGenerationErrorTests: ~Copyable { """, ], buildDependencyTreeOutput: true, - filesToDelete: &filesToDelete + filesToDelete: &filesToDelete, ) } } @@ -1327,7 +1326,7 @@ struct SafeDIToolCodeGenerationErrorTests: ~Copyable { """ Dependency cycle detected: \tA -> B -> C -> A - """ + """, ) { try await executeSafeDIToolTest( swiftFileContent: [ @@ -1357,18 +1356,18 @@ struct SafeDIToolCodeGenerationErrorTests: ~Copyable { """, ], buildDependencyTreeOutput: true, - filesToDelete: &filesToDelete + filesToDelete: &filesToDelete, ) } } @Test - mutating func run_onCodeWithCircularPropertyDependenciesImmediatelyInitializedWithMixOfReceivedAndInstantiated_throwsError() async throws { + mutating func run_onCodeWithCircularPropertyDependenciesImmediatelyInitializedWithMixOfReceivedAndInstantiated_throwsError() async { await assertThrowsError( """ Dependency cycle detected: \tA -> C -> B -> A - """ + """, ) { try await executeSafeDIToolTest( swiftFileContent: [ @@ -1396,7 +1395,7 @@ struct SafeDIToolCodeGenerationErrorTests: ~Copyable { """, ], buildDependencyTreeOutput: true, - filesToDelete: &filesToDelete + filesToDelete: &filesToDelete, ) } } @@ -1407,7 +1406,7 @@ struct SafeDIToolCodeGenerationErrorTests: ~Copyable { """ Dependency cycle detected: \tA -> B -> C -> A - """ + """, ) { try await executeSafeDIToolTest( swiftFileContent: [ @@ -1437,18 +1436,18 @@ struct SafeDIToolCodeGenerationErrorTests: ~Copyable { """, ], buildDependencyTreeOutput: true, - filesToDelete: &filesToDelete + filesToDelete: &filesToDelete, ) } } @Test - mutating func run_onCodeWithCircularPropertyDependenciesLazyInitializedAndReceived_throwsError() async throws { + mutating func run_onCodeWithCircularPropertyDependenciesLazyInitializedAndReceived_throwsError() async { await assertThrowsError( """ Dependency cycle detected! @Instantiated `aBuilder: Instantiator` is @Received in tree created by @Instantiated `aBuilder: Instantiator`. Declare @Received `aBuilder: Instantiator` on `C` as @Instantiated to fix. Full cycle: \tInstantiator -> Instantiator -> Instantiator -> Instantiator - """ + """, ) { try await executeSafeDIToolTest( swiftFileContent: [ @@ -1478,18 +1477,18 @@ struct SafeDIToolCodeGenerationErrorTests: ~Copyable { """, ], buildDependencyTreeOutput: true, - filesToDelete: &filesToDelete + filesToDelete: &filesToDelete, ) } } @Test - mutating func run_onCodeWithCircularPropertyDependenciesLazyInitializedAndOnlyIfAvailableReceived_throwsError() async throws { + mutating func run_onCodeWithCircularPropertyDependenciesLazyInitializedAndOnlyIfAvailableReceived_throwsError() async { await assertThrowsError( """ Dependency cycle detected! @Instantiated `aBuilder: Instantiator?` is @Received in tree created by @Instantiated `aBuilder: Instantiator?`. Declare @Received `aBuilder: Instantiator?` on `C` as @Instantiated to fix. Full cycle: \tInstantiator? -> Instantiator -> Instantiator -> Instantiator? - """ + """, ) { try await executeSafeDIToolTest( swiftFileContent: [ @@ -1519,7 +1518,7 @@ struct SafeDIToolCodeGenerationErrorTests: ~Copyable { """, ], buildDependencyTreeOutput: true, - filesToDelete: &filesToDelete + filesToDelete: &filesToDelete, ) } } @@ -1530,7 +1529,7 @@ struct SafeDIToolCodeGenerationErrorTests: ~Copyable { """ Dependency cycle detected: \tB -> C -> A -> B - """ + """, ) { try await executeSafeDIToolTest( swiftFileContent: [ @@ -1560,7 +1559,7 @@ struct SafeDIToolCodeGenerationErrorTests: ~Copyable { """, ], buildDependencyTreeOutput: true, - filesToDelete: &filesToDelete + filesToDelete: &filesToDelete, ) } } @@ -1571,7 +1570,7 @@ struct SafeDIToolCodeGenerationErrorTests: ~Copyable { """ Dependency received in same chain it is instantiated: \t@Instantiated a: A -> @Received b: B -> @Received c: C -> @Received a: A - """ + """, ) { try await executeSafeDIToolTest( swiftFileContent: [ @@ -1603,7 +1602,7 @@ struct SafeDIToolCodeGenerationErrorTests: ~Copyable { """, ], buildDependencyTreeOutput: true, - filesToDelete: &filesToDelete + filesToDelete: &filesToDelete, ) } } @@ -1614,7 +1613,7 @@ struct SafeDIToolCodeGenerationErrorTests: ~Copyable { """ Dependency received in same chain it is instantiated: \t@Instantiated a: A -> @Received renamedB: B -> @Received c: C -> @Received a: A - """ + """, ) { try await executeSafeDIToolTest( swiftFileContent: [ @@ -1647,7 +1646,7 @@ struct SafeDIToolCodeGenerationErrorTests: ~Copyable { """, ], buildDependencyTreeOutput: true, - filesToDelete: &filesToDelete + filesToDelete: &filesToDelete, ) } } @@ -1658,7 +1657,7 @@ struct SafeDIToolCodeGenerationErrorTests: ~Copyable { """ Dependency received in same chain it is instantiated: \t@Instantiated c: C -> @Received renamedB: B -> @Received c: C - """ + """, ) { try await executeSafeDIToolTest( swiftFileContent: [ @@ -1690,18 +1689,18 @@ struct SafeDIToolCodeGenerationErrorTests: ~Copyable { """, ], buildDependencyTreeOutput: true, - filesToDelete: &filesToDelete + filesToDelete: &filesToDelete, ) } } @Test - mutating func run_OnCodeWithOptionalPropertyAliasAndMarkedOnlyIfAvailableAndItIsOnlyAvialableViaCircularDependency_throws_error() async throws { + mutating func run_OnCodeWithOptionalPropertyAliasAndMarkedOnlyIfAvailableAndItIsOnlyAvialableViaCircularDependency_throws_error() async { await assertThrowsError( """ Dependency cycle detected: C -> B -> C - """ + """, ) { try await executeSafeDIToolTest( swiftFileContent: [ @@ -1747,17 +1746,17 @@ struct SafeDIToolCodeGenerationErrorTests: ~Copyable { """, ], buildDependencyTreeOutput: true, - filesToDelete: &filesToDelete + filesToDelete: &filesToDelete, ) } } @Test - mutating func run_onCodeWithIncorrectErasedInstantiatorFirstGeneric_whenInstantiableHasSingleForwardedProperty_throwsError() async throws { + mutating func run_onCodeWithIncorrectErasedInstantiatorFirstGeneric_whenInstantiableHasSingleForwardedProperty_throwsError() async { await assertThrowsError( """ Property `loggedInViewControllerBuilder: ErasedInstantiator` on LoggedInViewController incorrectly configured. Property should instead be of type `ErasedInstantiator`. - """ + """, ) { try await executeSafeDIToolTest( swiftFileContent: [ @@ -1828,17 +1827,17 @@ struct SafeDIToolCodeGenerationErrorTests: ~Copyable { """, ], buildDependencyTreeOutput: true, - filesToDelete: &filesToDelete + filesToDelete: &filesToDelete, ) } } @Test - mutating func run_onCodeWithIncorrectErasedInstantiatorFirstGeneric_whenInstantiableHasMultipleForwardedProperty_throwsError() async throws { + mutating func run_onCodeWithIncorrectErasedInstantiatorFirstGeneric_whenInstantiableHasMultipleForwardedProperty_throwsError() async { await assertThrowsError( """ Property `loggedInViewControllerBuilder: ErasedInstantiator` on LoggedInViewController incorrectly configured. Property should instead be of type `ErasedInstantiator`. - """ + """, ) { try await executeSafeDIToolTest( swiftFileContent: [ @@ -1911,7 +1910,7 @@ struct SafeDIToolCodeGenerationErrorTests: ~Copyable { """, ], buildDependencyTreeOutput: true, - filesToDelete: &filesToDelete + filesToDelete: &filesToDelete, ) } } @@ -1925,7 +1924,7 @@ struct SafeDIToolCodeGenerationErrorTests: ~Copyable { at _: URL, includingPropertiesForKeys _: [URLResourceKey]?, options _: FileManager.DirectoryEnumerationOptions, - errorHandler _: ((URL, any Error) -> Bool)? + errorHandler _: ((URL, any Error) -> Bool)?, ) -> FileManager.DirectoryEnumerator? { nil } diff --git a/Tests/SafeDIToolTests/SafeDIToolCodeGenerationTests.swift b/Tests/SafeDIToolTests/SafeDIToolCodeGenerationTests.swift index 5c0fede8..fc86afca 100644 --- a/Tests/SafeDIToolTests/SafeDIToolCodeGenerationTests.swift +++ b/Tests/SafeDIToolTests/SafeDIToolCodeGenerationTests.swift @@ -21,7 +21,6 @@ import Foundation import SafeDICore import Testing - @testable import SafeDITool struct SafeDIToolCodeGenerationTests: ~Copyable { @@ -44,17 +43,16 @@ struct SafeDIToolCodeGenerationTests: ~Copyable { let output = try await executeSafeDIToolTest( swiftFileContent: [], buildDependencyTreeOutput: true, - filesToDelete: &filesToDelete + filesToDelete: &filesToDelete, ) #expect(try #require(output.dependencyTree) == """ - // This file was generated by the SafeDIGenerateDependencyTree build tool plugin. - // Any modifications made to this file will be overwritten on subsequent builds. - // Please refrain from editing this file directly. + // This file was generated by the SafeDIGenerateDependencyTree build tool plugin. + // Any modifications made to this file will be overwritten on subsequent builds. + // Please refrain from editing this file directly. - // No root @Instantiable-decorated types found, or root types already had a `public init()` method. - """ - ) + // No root @Instantiable-decorated types found, or root types already had a `public init()` method. + """) } @Test @@ -73,21 +71,20 @@ struct SafeDIToolCodeGenerationTests: ~Copyable { """, ], buildDependencyTreeOutput: true, - filesToDelete: &filesToDelete + filesToDelete: &filesToDelete, ) #expect(try #require(output.dependencyTree) == """ - // This file was generated by the SafeDIGenerateDependencyTree build tool plugin. - // Any modifications made to this file will be overwritten on subsequent builds. - // Please refrain from editing this file directly. + // This file was generated by the SafeDIGenerateDependencyTree build tool plugin. + // Any modifications made to this file will be overwritten on subsequent builds. + // Please refrain from editing this file directly. - #if canImport(Foundation) - import Foundation - #endif + #if canImport(Foundation) + import Foundation + #endif - // No root @Instantiable-decorated types found, or root types already had a `public init()` method. - """ - ) + // No root @Instantiable-decorated types found, or root types already had a `public init()` method. + """) } @Test @@ -118,26 +115,25 @@ struct SafeDIToolCodeGenerationTests: ~Copyable { """, ], buildDependencyTreeOutput: true, - filesToDelete: &filesToDelete + filesToDelete: &filesToDelete, ) #expect(try #require(output.dependencyTree) == """ - // This file was generated by the SafeDIGenerateDependencyTree build tool plugin. - // Any modifications made to this file will be overwritten on subsequent builds. - // Please refrain from editing this file directly. - - #if canImport(Foundation) - import Foundation - #endif - - extension RootViewController { - public convenience init() { - let networkService: NetworkService = DefaultNetworkService() - self.init(networkService: networkService) - } - } - """ - ) + // This file was generated by the SafeDIGenerateDependencyTree build tool plugin. + // Any modifications made to this file will be overwritten on subsequent builds. + // Please refrain from editing this file directly. + + #if canImport(Foundation) + import Foundation + #endif + + extension RootViewController { + public convenience init() { + let networkService: NetworkService = DefaultNetworkService() + self.init(networkService: networkService) + } + } + """) } @Test @@ -168,26 +164,25 @@ struct SafeDIToolCodeGenerationTests: ~Copyable { """, ], buildDependencyTreeOutput: true, - filesToDelete: &filesToDelete + filesToDelete: &filesToDelete, ) #expect(try #require(output.dependencyTree) == """ - // This file was generated by the SafeDIGenerateDependencyTree build tool plugin. - // Any modifications made to this file will be overwritten on subsequent builds. - // Please refrain from editing this file directly. - - #if canImport(Foundation) - import class Foundation.URLSession - #endif - - extension Root { - public init() { - let networkService: NetworkService = DefaultNetworkService() - self.init(networkService: networkService) - } - } - """ - ) + // This file was generated by the SafeDIGenerateDependencyTree build tool plugin. + // Any modifications made to this file will be overwritten on subsequent builds. + // Please refrain from editing this file directly. + + #if canImport(Foundation) + import class Foundation.URLSession + #endif + + extension Root { + public init() { + let networkService: NetworkService = DefaultNetworkService() + self.init(networkService: networkService) + } + } + """) } @Test @@ -218,26 +213,25 @@ struct SafeDIToolCodeGenerationTests: ~Copyable { """, ], buildDependencyTreeOutput: true, - filesToDelete: &filesToDelete + filesToDelete: &filesToDelete, ) #expect(try #require(output.dependencyTree) == """ - // This file was generated by the SafeDIGenerateDependencyTree build tool plugin. - // Any modifications made to this file will be overwritten on subsequent builds. - // Please refrain from editing this file directly. - - #if canImport(Foundation) - import Foundation - #endif - - extension Root { - public init() { - let networkService: NetworkService = DefaultNetworkService() - self.init(networkService: networkService) - } - } - """ - ) + // This file was generated by the SafeDIGenerateDependencyTree build tool plugin. + // Any modifications made to this file will be overwritten on subsequent builds. + // Please refrain from editing this file directly. + + #if canImport(Foundation) + import Foundation + #endif + + extension Root { + public init() { + let networkService: NetworkService = DefaultNetworkService() + self.init(networkService: networkService) + } + } + """) } @Test @@ -278,33 +272,32 @@ struct SafeDIToolCodeGenerationTests: ~Copyable { """, ], buildDependencyTreeOutput: true, - filesToDelete: &filesToDelete + filesToDelete: &filesToDelete, ) #expect(try #require(output.dependencyTree) == """ - // This file was generated by the SafeDIGenerateDependencyTree build tool plugin. - // Any modifications made to this file will be overwritten on subsequent builds. - // Please refrain from editing this file directly. - - #if canImport(Foundation) - import Foundation - #endif - - extension Root1 { - public init() { - let networkService: NetworkService = DefaultNetworkService() - self.init(networkService: networkService) - } - } - - extension Root2 { - public init() { - let networkService: NetworkService = DefaultNetworkService() - self.init(networkService: networkService) - } - } - """ - ) + // This file was generated by the SafeDIGenerateDependencyTree build tool plugin. + // Any modifications made to this file will be overwritten on subsequent builds. + // Please refrain from editing this file directly. + + #if canImport(Foundation) + import Foundation + #endif + + extension Root1 { + public init() { + let networkService: NetworkService = DefaultNetworkService() + self.init(networkService: networkService) + } + } + + extension Root2 { + public init() { + let networkService: NetworkService = DefaultNetworkService() + self.init(networkService: networkService) + } + } + """) } @Test @@ -337,26 +330,25 @@ struct SafeDIToolCodeGenerationTests: ~Copyable { """, ], buildDependencyTreeOutput: true, - filesToDelete: &filesToDelete + filesToDelete: &filesToDelete, ) #expect(try #require(output.dependencyTree) == """ - // This file was generated by the SafeDIGenerateDependencyTree build tool plugin. - // Any modifications made to this file will be overwritten on subsequent builds. - // Please refrain from editing this file directly. - - #if canImport(Foundation) - import Foundation - #endif - - extension Root { - public init() { - let userService: any UserService = DefaultUserService() - self.init(userService: userService) - } - } - """ - ) + // This file was generated by the SafeDIGenerateDependencyTree build tool plugin. + // Any modifications made to this file will be overwritten on subsequent builds. + // Please refrain from editing this file directly. + + #if canImport(Foundation) + import Foundation + #endif + + extension Root { + public init() { + let userService: any UserService = DefaultUserService() + self.init(userService: userService) + } + } + """) } @Test @@ -391,22 +383,21 @@ struct SafeDIToolCodeGenerationTests: ~Copyable { """, ], buildDependencyTreeOutput: true, - filesToDelete: &filesToDelete + filesToDelete: &filesToDelete, ) #expect(try #require(output.dependencyTree) == """ - // This file was generated by the SafeDIGenerateDependencyTree build tool plugin. - // Any modifications made to this file will be overwritten on subsequent builds. - // Please refrain from editing this file directly. - - extension SomeInstantiated { - public convenience init() { - let someClass: any SomeProtocol = SomeClass() - self.init(someClass: someClass) - } - } - """ - ) + // This file was generated by the SafeDIGenerateDependencyTree build tool plugin. + // Any modifications made to this file will be overwritten on subsequent builds. + // Please refrain from editing this file directly. + + extension SomeInstantiated { + public convenience init() { + let someClass: any SomeProtocol = SomeClass() + self.init(someClass: someClass) + } + } + """) } @Test @@ -439,26 +430,25 @@ struct SafeDIToolCodeGenerationTests: ~Copyable { """, ], buildDependencyTreeOutput: true, - filesToDelete: &filesToDelete + filesToDelete: &filesToDelete, ) #expect(try #require(output.dependencyTree) == """ - // This file was generated by the SafeDIGenerateDependencyTree build tool plugin. - // Any modifications made to this file will be overwritten on subsequent builds. - // Please refrain from editing this file directly. - - #if canImport(Foundation) - import Foundation - #endif - - extension Root { - public init() { - let userService: UserService? = DefaultUserService() - self.init(userService: userService) - } - } - """ - ) + // This file was generated by the SafeDIGenerateDependencyTree build tool plugin. + // Any modifications made to this file will be overwritten on subsequent builds. + // Please refrain from editing this file directly. + + #if canImport(Foundation) + import Foundation + #endif + + extension Root { + public init() { + let userService: UserService? = DefaultUserService() + self.init(userService: userService) + } + } + """) } @Test @@ -540,33 +530,32 @@ struct SafeDIToolCodeGenerationTests: ~Copyable { """, ], buildDependencyTreeOutput: true, - filesToDelete: &filesToDelete + filesToDelete: &filesToDelete, ) #expect(try #require(output.dependencyTree) == """ - // This file was generated by the SafeDIGenerateDependencyTree build tool plugin. - // Any modifications made to this file will be overwritten on subsequent builds. - // Please refrain from editing this file directly. - - #if canImport(UIKit) - import UIKit - #endif - - extension RootViewController { - public convenience init() { - let networkService: NetworkService = DefaultNetworkService() - let authService: AuthService = DefaultAuthService(networkService: networkService) - func __safeDI_loggedInViewControllerBuilder(user: User) -> LoggedInViewController { - LoggedInViewController(user: user, networkService: networkService) - } - let loggedInViewControllerBuilder = ErasedInstantiator { - __safeDI_loggedInViewControllerBuilder(user: $0) - } - self.init(authService: authService, networkService: networkService, loggedInViewControllerBuilder: loggedInViewControllerBuilder) - } - } - """ - ) + // This file was generated by the SafeDIGenerateDependencyTree build tool plugin. + // Any modifications made to this file will be overwritten on subsequent builds. + // Please refrain from editing this file directly. + + #if canImport(UIKit) + import UIKit + #endif + + extension RootViewController { + public convenience init() { + let networkService: NetworkService = DefaultNetworkService() + let authService: AuthService = DefaultAuthService(networkService: networkService) + func __safeDI_loggedInViewControllerBuilder(user: User) -> LoggedInViewController { + LoggedInViewController(user: user, networkService: networkService) + } + let loggedInViewControllerBuilder = ErasedInstantiator { + __safeDI_loggedInViewControllerBuilder(user: $0) + } + self.init(authService: authService, networkService: networkService, loggedInViewControllerBuilder: loggedInViewControllerBuilder) + } + } + """) } @Test @@ -659,34 +648,33 @@ struct SafeDIToolCodeGenerationTests: ~Copyable { """, ], buildDependencyTreeOutput: true, - filesToDelete: &filesToDelete + filesToDelete: &filesToDelete, ) #expect(try #require(output.dependencyTree) == """ - // This file was generated by the SafeDIGenerateDependencyTree build tool plugin. - // Any modifications made to this file will be overwritten on subsequent builds. - // Please refrain from editing this file directly. - - #if canImport(UIKit) - import UIKit - #endif - - extension RootViewController { - public convenience init() { - let networkService: NetworkService = DefaultNetworkService() - let authService: AuthService = DefaultAuthService(networkService: networkService) - func __safeDI_loggedInViewControllerBuilder(user: User) -> LoggedInViewController { - let userService = UserService(user: user) - return LoggedInViewController(user: user, networkService: networkService, userService: userService) - } - let loggedInViewControllerBuilder = Instantiator { - __safeDI_loggedInViewControllerBuilder(user: $0) - } - self.init(authService: authService, networkService: networkService, loggedInViewControllerBuilder: loggedInViewControllerBuilder) - } - } - """ - ) + // This file was generated by the SafeDIGenerateDependencyTree build tool plugin. + // Any modifications made to this file will be overwritten on subsequent builds. + // Please refrain from editing this file directly. + + #if canImport(UIKit) + import UIKit + #endif + + extension RootViewController { + public convenience init() { + let networkService: NetworkService = DefaultNetworkService() + let authService: AuthService = DefaultAuthService(networkService: networkService) + func __safeDI_loggedInViewControllerBuilder(user: User) -> LoggedInViewController { + let userService = UserService(user: user) + return LoggedInViewController(user: user, networkService: networkService, userService: userService) + } + let loggedInViewControllerBuilder = Instantiator { + __safeDI_loggedInViewControllerBuilder(user: $0) + } + self.init(authService: authService, networkService: networkService, loggedInViewControllerBuilder: loggedInViewControllerBuilder) + } + } + """) } @Test @@ -718,31 +706,30 @@ struct SafeDIToolCodeGenerationTests: ~Copyable { """, ], buildDependencyTreeOutput: true, - filesToDelete: &filesToDelete + filesToDelete: &filesToDelete, ) #expect(try #require(output.dependencyTree) == """ - // This file was generated by the SafeDIGenerateDependencyTree build tool plugin. - // Any modifications made to this file will be overwritten on subsequent builds. - // Please refrain from editing this file directly. - - #if canImport(UIKit) - import UIKit - #endif - - extension RootViewController { - public convenience init() { - func __safeDI_networkServiceBuilder(fetchAuthToken: @escaping () -> Void) -> NetworkService { - NetworkService(fetchAuthToken: fetchAuthToken) - } - let networkServiceBuilder = Instantiator { - __safeDI_networkServiceBuilder(fetchAuthToken: $0) - } - self.init(networkServiceBuilder: networkServiceBuilder) - } - } - """ - ) + // This file was generated by the SafeDIGenerateDependencyTree build tool plugin. + // Any modifications made to this file will be overwritten on subsequent builds. + // Please refrain from editing this file directly. + + #if canImport(UIKit) + import UIKit + #endif + + extension RootViewController { + public convenience init() { + func __safeDI_networkServiceBuilder(fetchAuthToken: @escaping () -> Void) -> NetworkService { + NetworkService(fetchAuthToken: fetchAuthToken) + } + let networkServiceBuilder = Instantiator { + __safeDI_networkServiceBuilder(fetchAuthToken: $0) + } + self.init(networkServiceBuilder: networkServiceBuilder) + } + } + """) } @Test @@ -843,34 +830,33 @@ struct SafeDIToolCodeGenerationTests: ~Copyable { """, ], buildDependencyTreeOutput: true, - filesToDelete: &filesToDelete + filesToDelete: &filesToDelete, ) #expect(try #require(output.dependencyTree) == """ - // This file was generated by the SafeDIGenerateDependencyTree build tool plugin. - // Any modifications made to this file will be overwritten on subsequent builds. - // Please refrain from editing this file directly. - - #if canImport(UIKit) - import UIKit - #endif - - extension RootViewController { - public convenience init() { - let networkService: NetworkService = DefaultNetworkService() - let authService: AuthService = DefaultAuthService(networkService: networkService) - func __safeDI_loggedInViewControllerBuilder(userID: String, userName: String) -> LoggedInViewController { - let userService = UserService(userName: userName, userID: userID) - return LoggedInViewController(userName: userName, userID: userID, networkService: networkService, userService: userService) - } - let loggedInViewControllerBuilder = ErasedInstantiator<(userID: String, userName: String), UIViewController> { - __safeDI_loggedInViewControllerBuilder(userID: $0.userID, userName: $0.userName) - } - self.init(authService: authService, networkService: networkService, loggedInViewControllerBuilder: loggedInViewControllerBuilder) - } - } - """ - ) + // This file was generated by the SafeDIGenerateDependencyTree build tool plugin. + // Any modifications made to this file will be overwritten on subsequent builds. + // Please refrain from editing this file directly. + + #if canImport(UIKit) + import UIKit + #endif + + extension RootViewController { + public convenience init() { + let networkService: NetworkService = DefaultNetworkService() + let authService: AuthService = DefaultAuthService(networkService: networkService) + func __safeDI_loggedInViewControllerBuilder(userID: String, userName: String) -> LoggedInViewController { + let userService = UserService(userName: userName, userID: userID) + return LoggedInViewController(userName: userName, userID: userID, networkService: networkService, userService: userService) + } + let loggedInViewControllerBuilder = ErasedInstantiator<(userID: String, userName: String), UIViewController> { + __safeDI_loggedInViewControllerBuilder(userID: $0.userID, userName: $0.userName) + } + self.init(authService: authService, networkService: networkService, loggedInViewControllerBuilder: loggedInViewControllerBuilder) + } + } + """) } @Test @@ -971,34 +957,33 @@ struct SafeDIToolCodeGenerationTests: ~Copyable { """, ], buildDependencyTreeOutput: true, - filesToDelete: &filesToDelete + filesToDelete: &filesToDelete, ) #expect(try #require(output.dependencyTree) == """ - // This file was generated by the SafeDIGenerateDependencyTree build tool plugin. - // Any modifications made to this file will be overwritten on subsequent builds. - // Please refrain from editing this file directly. - - #if canImport(UIKit) - import UIKit - #endif - - extension RootViewController { - public convenience init() { - let networkService: NetworkService = DefaultNetworkService() - let authService: AuthService = DefaultAuthService(networkService: networkService) - func __safeDI_loggedInViewControllerBuilder(userID: String, userName: String) -> LoggedInViewController { - let userService = UserService(userName: userName, userID: userID) - return LoggedInViewController(userName: userName, userID: userID, networkService: networkService, userService: userService) - } - let loggedInViewControllerBuilder = ErasedInstantiator { - __safeDI_loggedInViewControllerBuilder(userID: $0.userID, userName: $0.userName) - } - self.init(authService: authService, networkService: networkService, loggedInViewControllerBuilder: loggedInViewControllerBuilder) - } - } - """ - ) + // This file was generated by the SafeDIGenerateDependencyTree build tool plugin. + // Any modifications made to this file will be overwritten on subsequent builds. + // Please refrain from editing this file directly. + + #if canImport(UIKit) + import UIKit + #endif + + extension RootViewController { + public convenience init() { + let networkService: NetworkService = DefaultNetworkService() + let authService: AuthService = DefaultAuthService(networkService: networkService) + func __safeDI_loggedInViewControllerBuilder(userID: String, userName: String) -> LoggedInViewController { + let userService = UserService(userName: userName, userID: userID) + return LoggedInViewController(userName: userName, userID: userID, networkService: networkService, userService: userService) + } + let loggedInViewControllerBuilder = ErasedInstantiator { + __safeDI_loggedInViewControllerBuilder(userID: $0.userID, userName: $0.userName) + } + self.init(authService: authService, networkService: networkService, loggedInViewControllerBuilder: loggedInViewControllerBuilder) + } + } + """) } @Test @@ -1031,26 +1016,25 @@ struct SafeDIToolCodeGenerationTests: ~Copyable { """, ], buildDependencyTreeOutput: true, - filesToDelete: &filesToDelete + filesToDelete: &filesToDelete, ) #expect(try #require(output.dependencyTree) == """ - // This file was generated by the SafeDIGenerateDependencyTree build tool plugin. - // Any modifications made to this file will be overwritten on subsequent builds. - // Please refrain from editing this file directly. - - #if canImport(SwiftUI) - import SwiftUI - #endif - - extension RootView { - public init() { - let splashScreenView = AnyView(SplashScreenView()) - self.init(splashScreenView: splashScreenView) - } - } - """ - ) + // This file was generated by the SafeDIGenerateDependencyTree build tool plugin. + // Any modifications made to this file will be overwritten on subsequent builds. + // Please refrain from editing this file directly. + + #if canImport(SwiftUI) + import SwiftUI + #endif + + extension RootView { + public init() { + let splashScreenView = AnyView(SplashScreenView()) + self.init(splashScreenView: splashScreenView) + } + } + """) } @Test @@ -1083,31 +1067,30 @@ struct SafeDIToolCodeGenerationTests: ~Copyable { """, ], buildDependencyTreeOutput: true, - filesToDelete: &filesToDelete + filesToDelete: &filesToDelete, ) #expect(try #require(output.dependencyTree) == """ - // This file was generated by the SafeDIGenerateDependencyTree build tool plugin. - // Any modifications made to this file will be overwritten on subsequent builds. - // Please refrain from editing this file directly. - - #if canImport(SwiftUI) - import SwiftUI - #endif - - extension RootView { - public init() { - func __safeDI_splashScreenViewBuilder() -> SplashScreenView { - SplashScreenView() - } - let splashScreenViewBuilder = ErasedInstantiator<(), AnyView> { - AnyView(__safeDI_splashScreenViewBuilder()) - } - self.init(splashScreenViewBuilder: splashScreenViewBuilder) - } - } - """ - ) + // This file was generated by the SafeDIGenerateDependencyTree build tool plugin. + // Any modifications made to this file will be overwritten on subsequent builds. + // Please refrain from editing this file directly. + + #if canImport(SwiftUI) + import SwiftUI + #endif + + extension RootView { + public init() { + func __safeDI_splashScreenViewBuilder() -> SplashScreenView { + SplashScreenView() + } + let splashScreenViewBuilder = ErasedInstantiator<(), AnyView> { + AnyView(__safeDI_splashScreenViewBuilder()) + } + self.init(splashScreenViewBuilder: splashScreenViewBuilder) + } + } + """) } @Test @@ -1201,34 +1184,33 @@ struct SafeDIToolCodeGenerationTests: ~Copyable { """, ], buildDependencyTreeOutput: true, - filesToDelete: &filesToDelete + filesToDelete: &filesToDelete, ) #expect(try #require(output.dependencyTree) == """ - // This file was generated by the SafeDIGenerateDependencyTree build tool plugin. - // Any modifications made to this file will be overwritten on subsequent builds. - // Please refrain from editing this file directly. - - #if canImport(UIKit) - import UIKit - #endif - - extension RootViewController { - public convenience init() { - let networkService: NetworkService = DefaultNetworkService() - let authService: AuthService = DefaultAuthService(networkService: networkService) - func __safeDI_loggedInViewControllerBuilder(user: User) -> LoggedInViewController { - let userService = UserService(user: user, networkService: networkService) - return LoggedInViewController(user: user, userService: userService) - } - let loggedInViewControllerBuilder = Instantiator { - __safeDI_loggedInViewControllerBuilder(user: $0) - } - self.init(authService: authService, networkService: networkService, loggedInViewControllerBuilder: loggedInViewControllerBuilder) - } - } - """ - ) + // This file was generated by the SafeDIGenerateDependencyTree build tool plugin. + // Any modifications made to this file will be overwritten on subsequent builds. + // Please refrain from editing this file directly. + + #if canImport(UIKit) + import UIKit + #endif + + extension RootViewController { + public convenience init() { + let networkService: NetworkService = DefaultNetworkService() + let authService: AuthService = DefaultAuthService(networkService: networkService) + func __safeDI_loggedInViewControllerBuilder(user: User) -> LoggedInViewController { + let userService = UserService(user: user, networkService: networkService) + return LoggedInViewController(user: user, userService: userService) + } + let loggedInViewControllerBuilder = Instantiator { + __safeDI_loggedInViewControllerBuilder(user: $0) + } + self.init(authService: authService, networkService: networkService, loggedInViewControllerBuilder: loggedInViewControllerBuilder) + } + } + """) } @Test @@ -1321,37 +1303,36 @@ struct SafeDIToolCodeGenerationTests: ~Copyable { """, ], buildDependencyTreeOutput: true, - filesToDelete: &filesToDelete + filesToDelete: &filesToDelete, ) #expect(try #require(output.dependencyTree) == """ - // This file was generated by the SafeDIGenerateDependencyTree build tool plugin. - // Any modifications made to this file will be overwritten on subsequent builds. - // Please refrain from editing this file directly. - - #if canImport(UIKit) - import UIKit - #endif - - extension RootViewController { - public convenience init() { - let networkService: NetworkService = DefaultNetworkService() - let authService: AuthService = DefaultAuthService(networkService: networkService) - func __safeDI_loggedInViewControllerBuilder(user: User) -> LoggedInViewController { - func __safeDI_userServiceInstantiator() -> UserService { - UserService(user: user, networkService: networkService) - } - let userServiceInstantiator = Instantiator(__safeDI_userServiceInstantiator) - return LoggedInViewController(user: user, userServiceInstantiator: userServiceInstantiator) - } - let loggedInViewControllerBuilder = Instantiator { - __safeDI_loggedInViewControllerBuilder(user: $0) - } - self.init(authService: authService, networkService: networkService, loggedInViewControllerBuilder: loggedInViewControllerBuilder) - } - } - """ - ) + // This file was generated by the SafeDIGenerateDependencyTree build tool plugin. + // Any modifications made to this file will be overwritten on subsequent builds. + // Please refrain from editing this file directly. + + #if canImport(UIKit) + import UIKit + #endif + + extension RootViewController { + public convenience init() { + let networkService: NetworkService = DefaultNetworkService() + let authService: AuthService = DefaultAuthService(networkService: networkService) + func __safeDI_loggedInViewControllerBuilder(user: User) -> LoggedInViewController { + func __safeDI_userServiceInstantiator() -> UserService { + UserService(user: user, networkService: networkService) + } + let userServiceInstantiator = Instantiator(__safeDI_userServiceInstantiator) + return LoggedInViewController(user: user, userServiceInstantiator: userServiceInstantiator) + } + let loggedInViewControllerBuilder = Instantiator { + __safeDI_loggedInViewControllerBuilder(user: $0) + } + self.init(authService: authService, networkService: networkService, loggedInViewControllerBuilder: loggedInViewControllerBuilder) + } + } + """) } @Test @@ -1386,26 +1367,25 @@ struct SafeDIToolCodeGenerationTests: ~Copyable { """, ], buildDependencyTreeOutput: true, - filesToDelete: &filesToDelete + filesToDelete: &filesToDelete, ) #expect(try #require(output.dependencyTree) == """ - // This file was generated by the SafeDIGenerateDependencyTree build tool plugin. - // Any modifications made to this file will be overwritten on subsequent builds. - // Please refrain from editing this file directly. - - extension Root { - public convenience init() { - func __safeDI_child() -> Child { - let grandchild = Grandchild() - return Child(/* @Instantiable type is incorrectly configured. Fix errors from @Instantiable macro to fix this error. */) - } - let child: Child = __safeDI_child() - self.init(child: child) - } - } - """ - ) + // This file was generated by the SafeDIGenerateDependencyTree build tool plugin. + // Any modifications made to this file will be overwritten on subsequent builds. + // Please refrain from editing this file directly. + + extension Root { + public convenience init() { + func __safeDI_child() -> Child { + let grandchild = Grandchild() + return Child(/* @Instantiable type is incorrectly configured. Fix errors from @Instantiable macro to fix this error. */) + } + let child: Child = __safeDI_child() + self.init(child: child) + } + } + """) } @Test @@ -1443,26 +1423,25 @@ struct SafeDIToolCodeGenerationTests: ~Copyable { """, ], buildDependencyTreeOutput: true, - filesToDelete: &filesToDelete + filesToDelete: &filesToDelete, ) #expect(try #require(output.dependencyTree) == """ - // This file was generated by the SafeDIGenerateDependencyTree build tool plugin. - // Any modifications made to this file will be overwritten on subsequent builds. - // Please refrain from editing this file directly. - - extension Root { - public convenience init() { - func __safeDI_child() -> Child { - let grandchild = Grandchild() - return Child(grandchild: grandchild) - } - let child: Child = __safeDI_child() - self.init(child: child) - } - } - """ - ) + // This file was generated by the SafeDIGenerateDependencyTree build tool plugin. + // Any modifications made to this file will be overwritten on subsequent builds. + // Please refrain from editing this file directly. + + extension Root { + public convenience init() { + func __safeDI_child() -> Child { + let grandchild = Grandchild() + return Child(grandchild: grandchild) + } + let child: Child = __safeDI_child() + self.init(child: child) + } + } + """) } @Test @@ -1497,26 +1476,25 @@ struct SafeDIToolCodeGenerationTests: ~Copyable { """, ], buildDependencyTreeOutput: true, - filesToDelete: &filesToDelete + filesToDelete: &filesToDelete, ) #expect(try #require(output.dependencyTree) == """ - // This file was generated by the SafeDIGenerateDependencyTree build tool plugin. - // Any modifications made to this file will be overwritten on subsequent builds. - // Please refrain from editing this file directly. - - extension Root { - public convenience init() { - func __safeDI_child() -> Child { - let grandchild = Grandchild() - return Child(grandchild: grandchild) - } - let child: Child = __safeDI_child() - self.init(child: child) - } - } - """ - ) + // This file was generated by the SafeDIGenerateDependencyTree build tool plugin. + // Any modifications made to this file will be overwritten on subsequent builds. + // Please refrain from editing this file directly. + + extension Root { + public convenience init() { + func __safeDI_child() -> Child { + let grandchild = Grandchild() + return Child(grandchild: grandchild) + } + let child: Child = __safeDI_child() + self.init(child: child) + } + } + """) } @Test @@ -1551,26 +1529,25 @@ struct SafeDIToolCodeGenerationTests: ~Copyable { """, ], buildDependencyTreeOutput: true, - filesToDelete: &filesToDelete + filesToDelete: &filesToDelete, ) #expect(try #require(output.dependencyTree) == """ - // This file was generated by the SafeDIGenerateDependencyTree build tool plugin. - // Any modifications made to this file will be overwritten on subsequent builds. - // Please refrain from editing this file directly. - - extension Root { - public convenience init() { - func __safeDI_child() -> Child { - let grandchild = Grandchild() - return Child(grandchild: grandchild) - } - let child: Child = __safeDI_child() - self.init(child: child) - } - } - """ - ) + // This file was generated by the SafeDIGenerateDependencyTree build tool plugin. + // Any modifications made to this file will be overwritten on subsequent builds. + // Please refrain from editing this file directly. + + extension Root { + public convenience init() { + func __safeDI_child() -> Child { + let grandchild = Grandchild() + return Child(grandchild: grandchild) + } + let child: Child = __safeDI_child() + self.init(child: child) + } + } + """) } @Test @@ -1660,34 +1637,33 @@ struct SafeDIToolCodeGenerationTests: ~Copyable { ], buildDependencyTreeOutput: true, - filesToDelete: &filesToDelete + filesToDelete: &filesToDelete, ) #expect(try #require(output.dependencyTree) == """ - // This file was generated by the SafeDIGenerateDependencyTree build tool plugin. - // Any modifications made to this file will be overwritten on subsequent builds. - // Please refrain from editing this file directly. - - extension Root { - public convenience init() { - let greatGrandchild = GreatGrandchild() - func __safeDI_childA() -> ChildA { - let grandchildAA = GrandchildAA(greatGrandchild: greatGrandchild) - let grandchildAB = GrandchildAB(greatGrandchild: greatGrandchild) - return ChildA(grandchildAA: grandchildAA, grandchildAB: grandchildAB) - } - let childA: ChildA = __safeDI_childA() - func __safeDI_childB() -> ChildB { - let grandchildBA = GrandchildBA(greatGrandchild: greatGrandchild) - let grandchildBB = GrandchildBB(greatGrandchild: greatGrandchild) - return ChildB(grandchildBA: grandchildBA, grandchildBB: grandchildBB) - } - let childB: ChildB = __safeDI_childB() - self.init(childA: childA, childB: childB, greatGrandchild: greatGrandchild) - } - } - """ - ) + // This file was generated by the SafeDIGenerateDependencyTree build tool plugin. + // Any modifications made to this file will be overwritten on subsequent builds. + // Please refrain from editing this file directly. + + extension Root { + public convenience init() { + let greatGrandchild = GreatGrandchild() + func __safeDI_childA() -> ChildA { + let grandchildAA = GrandchildAA(greatGrandchild: greatGrandchild) + let grandchildAB = GrandchildAB(greatGrandchild: greatGrandchild) + return ChildA(grandchildAA: grandchildAA, grandchildAB: grandchildAB) + } + let childA: ChildA = __safeDI_childA() + func __safeDI_childB() -> ChildB { + let grandchildBA = GrandchildBA(greatGrandchild: greatGrandchild) + let grandchildBB = GrandchildBB(greatGrandchild: greatGrandchild) + return ChildB(grandchildBA: grandchildBA, grandchildBB: grandchildBB) + } + let childB: ChildB = __safeDI_childB() + self.init(childA: childA, childB: childB, greatGrandchild: greatGrandchild) + } + } + """) } @Test @@ -1778,35 +1754,34 @@ struct SafeDIToolCodeGenerationTests: ~Copyable { ], buildDependencyTreeOutput: true, - filesToDelete: &filesToDelete + filesToDelete: &filesToDelete, ) #expect(try #require(output.dependencyTree) == """ - // This file was generated by the SafeDIGenerateDependencyTree build tool plugin. - // Any modifications made to this file will be overwritten on subsequent builds. - // Please refrain from editing this file directly. - - extension Root { - public convenience init() { - func __safeDI_childA() -> ChildA { - let greatGrandchild = GreatGrandchild() - let grandchildAA = GrandchildAA(greatGrandchild: greatGrandchild) - let grandchildAB = GrandchildAB(greatGrandchild: greatGrandchild) - return ChildA(grandchildAA: grandchildAA, grandchildAB: grandchildAB, greatGrandchild: greatGrandchild) - } - let childA: ChildA = __safeDI_childA() - func __safeDI_childB() -> ChildB { - let greatGrandchild = GreatGrandchild() - let grandchildBA = GrandchildBA(greatGrandchild: greatGrandchild) - let grandchildBB = GrandchildBB(greatGrandchild: greatGrandchild) - return ChildB(grandchildBA: grandchildBA, grandchildBB: grandchildBB, greatGrandchild: greatGrandchild) - } - let childB: ChildB = __safeDI_childB() - self.init(childA: childA, childB: childB) - } - } - """ - ) + // This file was generated by the SafeDIGenerateDependencyTree build tool plugin. + // Any modifications made to this file will be overwritten on subsequent builds. + // Please refrain from editing this file directly. + + extension Root { + public convenience init() { + func __safeDI_childA() -> ChildA { + let greatGrandchild = GreatGrandchild() + let grandchildAA = GrandchildAA(greatGrandchild: greatGrandchild) + let grandchildAB = GrandchildAB(greatGrandchild: greatGrandchild) + return ChildA(grandchildAA: grandchildAA, grandchildAB: grandchildAB, greatGrandchild: greatGrandchild) + } + let childA: ChildA = __safeDI_childA() + func __safeDI_childB() -> ChildB { + let greatGrandchild = GreatGrandchild() + let grandchildBA = GrandchildBA(greatGrandchild: greatGrandchild) + let grandchildBB = GrandchildBB(greatGrandchild: greatGrandchild) + return ChildB(grandchildBA: grandchildBA, grandchildBB: grandchildBB, greatGrandchild: greatGrandchild) + } + let childB: ChildB = __safeDI_childB() + self.init(childA: childA, childB: childB) + } + } + """) } @Test @@ -1864,32 +1839,31 @@ struct SafeDIToolCodeGenerationTests: ~Copyable { ], buildDependencyTreeOutput: true, - filesToDelete: &filesToDelete + filesToDelete: &filesToDelete, ) #expect(try #require(output.dependencyTree) == """ - // This file was generated by the SafeDIGenerateDependencyTree build tool plugin. - // Any modifications made to this file will be overwritten on subsequent builds. - // Please refrain from editing this file directly. - - extension Root { - public convenience init() { - func __safeDI_child() -> Child { - func __safeDI_grandchild() -> Grandchild { - let recreated = Recreated() - let greatGrandchild = GreatGrandchild(recreated: recreated) - return Grandchild(greatGrandchild: greatGrandchild, recreated: recreated) - } - let grandchild: Grandchild = __safeDI_grandchild() - let recreated = Recreated() - return Child(grandchild: grandchild, recreated: recreated) - } - let child: Child = __safeDI_child() - self.init(child: child) - } - } - """ - ) + // This file was generated by the SafeDIGenerateDependencyTree build tool plugin. + // Any modifications made to this file will be overwritten on subsequent builds. + // Please refrain from editing this file directly. + + extension Root { + public convenience init() { + func __safeDI_child() -> Child { + func __safeDI_grandchild() -> Grandchild { + let recreated = Recreated() + let greatGrandchild = GreatGrandchild(recreated: recreated) + return Grandchild(greatGrandchild: greatGrandchild, recreated: recreated) + } + let grandchild: Grandchild = __safeDI_grandchild() + let recreated = Recreated() + return Child(grandchild: grandchild, recreated: recreated) + } + let child: Child = __safeDI_child() + self.init(child: child) + } + } + """) } @Test @@ -1946,35 +1920,34 @@ struct SafeDIToolCodeGenerationTests: ~Copyable { """, ], buildDependencyTreeOutput: true, - filesToDelete: &filesToDelete + filesToDelete: &filesToDelete, ) #expect(try #require(output.dependencyTree) == """ - // This file was generated by the SafeDIGenerateDependencyTree build tool plugin. - // Any modifications made to this file will be overwritten on subsequent builds. - // Please refrain from editing this file directly. - - extension Root { - public convenience init() { - let recreated = Recreated() - func __safeDI_child() -> Child { - func __safeDI_grandchild() -> Grandchild { - func __safeDI_greatGrandchild() -> GreatGrandchild { - let recreated = Recreated() - return GreatGrandchild(recreated: recreated) - } - let greatGrandchild: GreatGrandchild = __safeDI_greatGrandchild() - return Grandchild(greatGrandchild: greatGrandchild) - } - let grandchild: Grandchild = __safeDI_grandchild() - return Child(grandchild: grandchild, recreated: recreated) - } - let child: Child = __safeDI_child() - self.init(child: child, recreated: recreated) - } - } - """ - ) + // This file was generated by the SafeDIGenerateDependencyTree build tool plugin. + // Any modifications made to this file will be overwritten on subsequent builds. + // Please refrain from editing this file directly. + + extension Root { + public convenience init() { + let recreated = Recreated() + func __safeDI_child() -> Child { + func __safeDI_grandchild() -> Grandchild { + func __safeDI_greatGrandchild() -> GreatGrandchild { + let recreated = Recreated() + return GreatGrandchild(recreated: recreated) + } + let greatGrandchild: GreatGrandchild = __safeDI_greatGrandchild() + return Grandchild(greatGrandchild: greatGrandchild) + } + let grandchild: Grandchild = __safeDI_grandchild() + return Child(grandchild: grandchild, recreated: recreated) + } + let child: Child = __safeDI_child() + self.init(child: child, recreated: recreated) + } + } + """) } @Test @@ -2041,39 +2014,38 @@ struct SafeDIToolCodeGenerationTests: ~Copyable { """, ], buildDependencyTreeOutput: true, - filesToDelete: &filesToDelete + filesToDelete: &filesToDelete, ) #expect(try #require(output.dependencyTree) == """ - // This file was generated by the SafeDIGenerateDependencyTree build tool plugin. - // Any modifications made to this file will be overwritten on subsequent builds. - // Please refrain from editing this file directly. - - extension Root { - public convenience init() { - let recreated = Recreated() - func __safeDI_child() -> Child { - func __safeDI_grandchild() -> Grandchild { - func __safeDI_greatGrandchild() -> GreatGrandchild { - func __safeDI_greatGreatGrandchild() -> GreatGreatGrandchild { - let recreated = Recreated() - return GreatGreatGrandchild(recreated: recreated) - } - let greatGreatGrandchild: GreatGreatGrandchild = __safeDI_greatGreatGrandchild() - return GreatGrandchild(greatGreatGrandchild: greatGreatGrandchild, recreated: recreated) - } - let greatGrandchild: GreatGrandchild = __safeDI_greatGrandchild() - return Grandchild(greatGrandchild: greatGrandchild) - } - let grandchild: Grandchild = __safeDI_grandchild() - return Child(grandchild: grandchild) - } - let child: Child = __safeDI_child() - self.init(child: child, recreated: recreated) - } - } - """ - ) + // This file was generated by the SafeDIGenerateDependencyTree build tool plugin. + // Any modifications made to this file will be overwritten on subsequent builds. + // Please refrain from editing this file directly. + + extension Root { + public convenience init() { + let recreated = Recreated() + func __safeDI_child() -> Child { + func __safeDI_grandchild() -> Grandchild { + func __safeDI_greatGrandchild() -> GreatGrandchild { + func __safeDI_greatGreatGrandchild() -> GreatGreatGrandchild { + let recreated = Recreated() + return GreatGreatGrandchild(recreated: recreated) + } + let greatGreatGrandchild: GreatGreatGrandchild = __safeDI_greatGreatGrandchild() + return GreatGrandchild(greatGreatGrandchild: greatGreatGrandchild, recreated: recreated) + } + let greatGrandchild: GreatGrandchild = __safeDI_greatGrandchild() + return Grandchild(greatGrandchild: greatGrandchild) + } + let grandchild: Grandchild = __safeDI_grandchild() + return Child(grandchild: grandchild) + } + let child: Child = __safeDI_child() + self.init(child: child, recreated: recreated) + } + } + """) } @Test @@ -2151,48 +2123,47 @@ struct SafeDIToolCodeGenerationTests: ~Copyable { """, ], buildDependencyTreeOutput: true, - filesToDelete: &filesToDelete + filesToDelete: &filesToDelete, ) #expect(try #require(output.dependencyTree) == """ - // This file was generated by the SafeDIGenerateDependencyTree build tool plugin. - // Any modifications made to this file will be overwritten on subsequent builds. - // Please refrain from editing this file directly. - - extension Root { - public convenience init() { - func __safeDI_child() -> Child { - let recreated = Recreated() - func __safeDI_grandchild() -> Grandchild { - func __safeDI_greatGrandchildA() -> GreatGrandchildA { - func __safeDI_greatGreatGrandchild() -> GreatGreatGrandchild { - let recreated = Recreated() - return GreatGreatGrandchild(recreated: recreated) - } - let greatGreatGrandchild: GreatGreatGrandchild = __safeDI_greatGreatGrandchild() - return GreatGrandchildA(greatGreatGrandchild: greatGreatGrandchild, recreated: recreated) - } - let greatGrandchildA: GreatGrandchildA = __safeDI_greatGrandchildA() - func __safeDI_greatGrandchildB() -> GreatGrandchildB { - func __safeDI_greatGreatGrandchild() -> GreatGreatGrandchild { - let recreated = Recreated() - return GreatGreatGrandchild(recreated: recreated) - } - let greatGreatGrandchild: GreatGreatGrandchild = __safeDI_greatGreatGrandchild() - return GreatGrandchildB(greatGreatGrandchild: greatGreatGrandchild) - } - let greatGrandchildB: GreatGrandchildB = __safeDI_greatGrandchildB() - return Grandchild(greatGrandchildA: greatGrandchildA, greatGrandchildB: greatGrandchildB) - } - let grandchild: Grandchild = __safeDI_grandchild() - return Child(grandchild: grandchild, recreated: recreated) - } - let child: Child = __safeDI_child() - self.init(child: child) - } - } - """ - ) + // This file was generated by the SafeDIGenerateDependencyTree build tool plugin. + // Any modifications made to this file will be overwritten on subsequent builds. + // Please refrain from editing this file directly. + + extension Root { + public convenience init() { + func __safeDI_child() -> Child { + let recreated = Recreated() + func __safeDI_grandchild() -> Grandchild { + func __safeDI_greatGrandchildA() -> GreatGrandchildA { + func __safeDI_greatGreatGrandchild() -> GreatGreatGrandchild { + let recreated = Recreated() + return GreatGreatGrandchild(recreated: recreated) + } + let greatGreatGrandchild: GreatGreatGrandchild = __safeDI_greatGreatGrandchild() + return GreatGrandchildA(greatGreatGrandchild: greatGreatGrandchild, recreated: recreated) + } + let greatGrandchildA: GreatGrandchildA = __safeDI_greatGrandchildA() + func __safeDI_greatGrandchildB() -> GreatGrandchildB { + func __safeDI_greatGreatGrandchild() -> GreatGreatGrandchild { + let recreated = Recreated() + return GreatGreatGrandchild(recreated: recreated) + } + let greatGreatGrandchild: GreatGreatGrandchild = __safeDI_greatGreatGrandchild() + return GreatGrandchildB(greatGreatGrandchild: greatGreatGrandchild) + } + let greatGrandchildB: GreatGrandchildB = __safeDI_greatGrandchildB() + return Grandchild(greatGrandchildA: greatGrandchildA, greatGrandchildB: greatGrandchildB) + } + let grandchild: Grandchild = __safeDI_grandchild() + return Child(grandchild: grandchild, recreated: recreated) + } + let child: Child = __safeDI_child() + self.init(child: child) + } + } + """) } @Test @@ -2275,54 +2246,53 @@ struct SafeDIToolCodeGenerationTests: ~Copyable { """, ], buildDependencyTreeOutput: true, - filesToDelete: &filesToDelete + filesToDelete: &filesToDelete, ) #expect(try #require(output.dependencyTree) == """ - // This file was generated by the SafeDIGenerateDependencyTree build tool plugin. - // Any modifications made to this file will be overwritten on subsequent builds. - // Please refrain from editing this file directly. - - extension Root { - public convenience init() { - @Sendable func __safeDI_childABuilder(recreated: Recreated) -> ChildA { - func __safeDI_grandchildA() -> GrandchildA { - let recreated = Recreated() - let greatGrandchild = GreatGrandchild(recreated: recreated) - return GrandchildA(greatGrandchild: greatGrandchild, recreated: recreated) - } - let grandchildA: GrandchildA = __safeDI_grandchildA() - func __safeDI_grandchildB() -> GrandchildB { - let greatGrandchild = GreatGrandchild(recreated: recreated) - return GrandchildB(greatGrandchild: greatGrandchild) - } - let grandchildB: GrandchildB = __safeDI_grandchildB() - return ChildA(grandchildA: grandchildA, grandchildB: grandchildB, recreated: recreated) - } - let childABuilder = SendableErasedInstantiator { - __safeDI_childABuilder(recreated: $0) - } - let recreated = Recreated() - func __safeDI_childB() -> ChildB { - func __safeDI_grandchildA() -> GrandchildA { - let recreated = Recreated() - let greatGrandchild = GreatGrandchild(recreated: recreated) - return GrandchildA(greatGrandchild: greatGrandchild, recreated: recreated) - } - let grandchildA: GrandchildA = __safeDI_grandchildA() - func __safeDI_grandchildB() -> GrandchildB { - let greatGrandchild = GreatGrandchild(recreated: recreated) - return GrandchildB(greatGrandchild: greatGrandchild) - } - let grandchildB: GrandchildB = __safeDI_grandchildB() - return ChildB(grandchildA: grandchildA, grandchildB: grandchildB, recreated: recreated) - } - let childB: ChildB = __safeDI_childB() - self.init(childABuilder: childABuilder, childB: childB, recreated: recreated) - } - } - """ - ) + // This file was generated by the SafeDIGenerateDependencyTree build tool plugin. + // Any modifications made to this file will be overwritten on subsequent builds. + // Please refrain from editing this file directly. + + extension Root { + public convenience init() { + @Sendable func __safeDI_childABuilder(recreated: Recreated) -> ChildA { + func __safeDI_grandchildA() -> GrandchildA { + let recreated = Recreated() + let greatGrandchild = GreatGrandchild(recreated: recreated) + return GrandchildA(greatGrandchild: greatGrandchild, recreated: recreated) + } + let grandchildA: GrandchildA = __safeDI_grandchildA() + func __safeDI_grandchildB() -> GrandchildB { + let greatGrandchild = GreatGrandchild(recreated: recreated) + return GrandchildB(greatGrandchild: greatGrandchild) + } + let grandchildB: GrandchildB = __safeDI_grandchildB() + return ChildA(grandchildA: grandchildA, grandchildB: grandchildB, recreated: recreated) + } + let childABuilder = SendableErasedInstantiator { + __safeDI_childABuilder(recreated: $0) + } + let recreated = Recreated() + func __safeDI_childB() -> ChildB { + func __safeDI_grandchildA() -> GrandchildA { + let recreated = Recreated() + let greatGrandchild = GreatGrandchild(recreated: recreated) + return GrandchildA(greatGrandchild: greatGrandchild, recreated: recreated) + } + let grandchildA: GrandchildA = __safeDI_grandchildA() + func __safeDI_grandchildB() -> GrandchildB { + let greatGrandchild = GreatGrandchild(recreated: recreated) + return GrandchildB(greatGrandchild: greatGrandchild) + } + let grandchildB: GrandchildB = __safeDI_grandchildB() + return ChildB(grandchildA: grandchildA, grandchildB: grandchildB, recreated: recreated) + } + let childB: ChildB = __safeDI_childB() + self.init(childABuilder: childABuilder, childB: childB, recreated: recreated) + } + } + """) } @Test @@ -2411,49 +2381,48 @@ struct SafeDIToolCodeGenerationTests: ~Copyable { ], buildDependencyTreeOutput: true, - filesToDelete: &filesToDelete + filesToDelete: &filesToDelete, ) #expect(try #require(output.dependencyTree) == """ - // This file was generated by the SafeDIGenerateDependencyTree build tool plugin. - // Any modifications made to this file will be overwritten on subsequent builds. - // Please refrain from editing this file directly. - - extension Root { - public convenience init() { - func __safeDI_childA() -> ChildA { - func __safeDI_grandchildAA() -> GrandchildAA { - let greatGrandchild = GreatGrandchild() - return GrandchildAA(greatGrandchild: greatGrandchild) - } - let grandchildAA: GrandchildAA = __safeDI_grandchildAA() - func __safeDI_grandchildAB() -> GrandchildAB { - let greatGrandchild = GreatGrandchild() - return GrandchildAB(greatGrandchild: greatGrandchild) - } - let grandchildAB: GrandchildAB = __safeDI_grandchildAB() - return ChildA(grandchildAA: grandchildAA, grandchildAB: grandchildAB) - } - let childA: ChildA = __safeDI_childA() - func __safeDI_childB() -> ChildB { - func __safeDI_grandchildBA() -> GrandchildBA { - let greatGrandchild = GreatGrandchild() - return GrandchildBA(greatGrandchild: greatGrandchild) - } - let grandchildBA: GrandchildBA = __safeDI_grandchildBA() - func __safeDI_grandchildBB() -> GrandchildBB { - let greatGrandchild = GreatGrandchild() - return GrandchildBB(greatGrandchild: greatGrandchild) - } - let grandchildBB: GrandchildBB = __safeDI_grandchildBB() - return ChildB(grandchildBA: grandchildBA, grandchildBB: grandchildBB) - } - let childB: ChildB = __safeDI_childB() - self.init(childA: childA, childB: childB) - } - } - """ - ) + // This file was generated by the SafeDIGenerateDependencyTree build tool plugin. + // Any modifications made to this file will be overwritten on subsequent builds. + // Please refrain from editing this file directly. + + extension Root { + public convenience init() { + func __safeDI_childA() -> ChildA { + func __safeDI_grandchildAA() -> GrandchildAA { + let greatGrandchild = GreatGrandchild() + return GrandchildAA(greatGrandchild: greatGrandchild) + } + let grandchildAA: GrandchildAA = __safeDI_grandchildAA() + func __safeDI_grandchildAB() -> GrandchildAB { + let greatGrandchild = GreatGrandchild() + return GrandchildAB(greatGrandchild: greatGrandchild) + } + let grandchildAB: GrandchildAB = __safeDI_grandchildAB() + return ChildA(grandchildAA: grandchildAA, grandchildAB: grandchildAB) + } + let childA: ChildA = __safeDI_childA() + func __safeDI_childB() -> ChildB { + func __safeDI_grandchildBA() -> GrandchildBA { + let greatGrandchild = GreatGrandchild() + return GrandchildBA(greatGrandchild: greatGrandchild) + } + let grandchildBA: GrandchildBA = __safeDI_grandchildBA() + func __safeDI_grandchildBB() -> GrandchildBB { + let greatGrandchild = GreatGrandchild() + return GrandchildBB(greatGrandchild: greatGrandchild) + } + let grandchildBB: GrandchildBB = __safeDI_grandchildBB() + return ChildB(grandchildBA: grandchildBA, grandchildBB: grandchildBB) + } + let childB: ChildB = __safeDI_childB() + self.init(childA: childA, childB: childB) + } + } + """) } @Test @@ -2505,27 +2474,26 @@ struct SafeDIToolCodeGenerationTests: ~Copyable { """, ], buildDependencyTreeOutput: true, - filesToDelete: &filesToDelete + filesToDelete: &filesToDelete, ) #expect(try #require(output.dependencyTree) == """ - // This file was generated by the SafeDIGenerateDependencyTree build tool plugin. - // Any modifications made to this file will be overwritten on subsequent builds. - // Please refrain from editing this file directly. - - #if canImport(Foundation) - import Foundation - #endif - - extension Root { - public convenience init() { - let keyValueStore: KeyValueStore = UserDefaults.instantiate() - let child = Child(keyValueStore: keyValueStore) - self.init(child: child, keyValueStore: keyValueStore) - } - } - """ - ) + // This file was generated by the SafeDIGenerateDependencyTree build tool plugin. + // Any modifications made to this file will be overwritten on subsequent builds. + // Please refrain from editing this file directly. + + #if canImport(Foundation) + import Foundation + #endif + + extension Root { + public convenience init() { + let keyValueStore: KeyValueStore = UserDefaults.instantiate() + let child = Child(keyValueStore: keyValueStore) + self.init(child: child, keyValueStore: keyValueStore) + } + } + """) } @Test @@ -2626,37 +2594,36 @@ struct SafeDIToolCodeGenerationTests: ~Copyable { """, ], buildDependencyTreeOutput: true, - filesToDelete: &filesToDelete + filesToDelete: &filesToDelete, ) #expect(try #require(output.dependencyTree) == """ - // This file was generated by the SafeDIGenerateDependencyTree build tool plugin. - // Any modifications made to this file will be overwritten on subsequent builds. - // Please refrain from editing this file directly. - - #if canImport(Foundation) - import Foundation - #endif - #if canImport(UIKit) - import UIKit - #endif - - extension RootViewController { - public convenience init() { - let networkService: NetworkService = DefaultNetworkService() - let authService: AuthService = DefaultAuthService(networkService: networkService) - func __safeDI_loggedInViewControllerBuilder(user: User) -> LoggedInViewController { - let keyValueStore: KeyValueStore = UserDefaults.instantiate(user: user) - return LoggedInViewController(user: user, networkService: networkService, keyValueStore: keyValueStore) - } - let loggedInViewControllerBuilder = ErasedInstantiator { - __safeDI_loggedInViewControllerBuilder(user: $0) - } - self.init(authService: authService, networkService: networkService, loggedInViewControllerBuilder: loggedInViewControllerBuilder) - } - } - """ - ) + // This file was generated by the SafeDIGenerateDependencyTree build tool plugin. + // Any modifications made to this file will be overwritten on subsequent builds. + // Please refrain from editing this file directly. + + #if canImport(Foundation) + import Foundation + #endif + #if canImport(UIKit) + import UIKit + #endif + + extension RootViewController { + public convenience init() { + let networkService: NetworkService = DefaultNetworkService() + let authService: AuthService = DefaultAuthService(networkService: networkService) + func __safeDI_loggedInViewControllerBuilder(user: User) -> LoggedInViewController { + let keyValueStore: KeyValueStore = UserDefaults.instantiate(user: user) + return LoggedInViewController(user: user, networkService: networkService, keyValueStore: keyValueStore) + } + let loggedInViewControllerBuilder = ErasedInstantiator { + __safeDI_loggedInViewControllerBuilder(user: $0) + } + self.init(authService: authService, networkService: networkService, loggedInViewControllerBuilder: loggedInViewControllerBuilder) + } + } + """) } @Test @@ -2671,7 +2638,7 @@ struct SafeDIToolCodeGenerationTests: ~Copyable { """, ], buildDependencyTreeOutput: false, - filesToDelete: &filesToDelete + filesToDelete: &filesToDelete, ) let grandchildModuleOutput = try await executeSafeDIToolTest( @@ -2727,7 +2694,7 @@ struct SafeDIToolCodeGenerationTests: ~Copyable { ], dependentModuleInfoPaths: [greatGrandchildModuleOutput.moduleInfoOutputPath], buildDependencyTreeOutput: false, - filesToDelete: &filesToDelete + filesToDelete: &filesToDelete, ) let childModuleOutput = try await executeSafeDIToolTest( @@ -2766,7 +2733,7 @@ struct SafeDIToolCodeGenerationTests: ~Copyable { grandchildModuleOutput.moduleInfoOutputPath, ], buildDependencyTreeOutput: false, - filesToDelete: &filesToDelete + filesToDelete: &filesToDelete, ) let topLevelModuleOutput = try await executeSafeDIToolTest( @@ -2792,65 +2759,64 @@ struct SafeDIToolCodeGenerationTests: ~Copyable { childModuleOutput.moduleInfoOutputPath, ], buildDependencyTreeOutput: true, - filesToDelete: &filesToDelete + filesToDelete: &filesToDelete, ) #expect(try #require(topLevelModuleOutput.dependencyTree) == """ - // This file was generated by the SafeDIGenerateDependencyTree build tool plugin. - // Any modifications made to this file will be overwritten on subsequent builds. - // Please refrain from editing this file directly. - - #if canImport(ChildModule) - import ChildModule - #endif - #if canImport(GrandchildModule) - import GrandchildModule - #endif - #if canImport(GreatGrandchildModule) - import GreatGrandchildModule - #endif - - extension Root { - public convenience init() { - func __safeDI_childA() -> ChildA { - func __safeDI_grandchildAA() -> GrandchildAA { - let greatGrandchild = GreatGrandchild() - return GrandchildAA(greatGrandchild: greatGrandchild) - } - let grandchildAA: GrandchildAA = __safeDI_grandchildAA() - func __safeDI_grandchildAB() -> GrandchildAB { - let greatGrandchild = GreatGrandchild() - return GrandchildAB(greatGrandchild: greatGrandchild) - } - let grandchildAB: GrandchildAB = __safeDI_grandchildAB() - return ChildA(grandchildAA: grandchildAA, grandchildAB: grandchildAB) - } - let childA: ChildA = __safeDI_childA() - func __safeDI_childB() -> ChildB { - func __safeDI_grandchildBA() -> GrandchildBA { - @Sendable func __safeDI_greatGrandchildInstantiator() -> GreatGrandchild { - GreatGrandchild() - } - let greatGrandchildInstantiator = SendableInstantiator(__safeDI_greatGrandchildInstantiator) - return GrandchildBA(greatGrandchildInstantiator: greatGrandchildInstantiator) - } - let grandchildBA: GrandchildBA = __safeDI_grandchildBA() - func __safeDI_grandchildBB() -> GrandchildBB { - @Sendable func __safeDI_greatGrandchildInstantiator() -> GreatGrandchild { - GreatGrandchild() - } - let greatGrandchildInstantiator = SendableInstantiator(__safeDI_greatGrandchildInstantiator) - return GrandchildBB(greatGrandchildInstantiator: greatGrandchildInstantiator) - } - let grandchildBB: GrandchildBB = __safeDI_grandchildBB() - return ChildB(grandchildBA: grandchildBA, grandchildBB: grandchildBB) - } - let childB: ChildB = __safeDI_childB() - self.init(childA: childA, childB: childB) - } - } - """ - ) + // This file was generated by the SafeDIGenerateDependencyTree build tool plugin. + // Any modifications made to this file will be overwritten on subsequent builds. + // Please refrain from editing this file directly. + + #if canImport(ChildModule) + import ChildModule + #endif + #if canImport(GrandchildModule) + import GrandchildModule + #endif + #if canImport(GreatGrandchildModule) + import GreatGrandchildModule + #endif + + extension Root { + public convenience init() { + func __safeDI_childA() -> ChildA { + func __safeDI_grandchildAA() -> GrandchildAA { + let greatGrandchild = GreatGrandchild() + return GrandchildAA(greatGrandchild: greatGrandchild) + } + let grandchildAA: GrandchildAA = __safeDI_grandchildAA() + func __safeDI_grandchildAB() -> GrandchildAB { + let greatGrandchild = GreatGrandchild() + return GrandchildAB(greatGrandchild: greatGrandchild) + } + let grandchildAB: GrandchildAB = __safeDI_grandchildAB() + return ChildA(grandchildAA: grandchildAA, grandchildAB: grandchildAB) + } + let childA: ChildA = __safeDI_childA() + func __safeDI_childB() -> ChildB { + func __safeDI_grandchildBA() -> GrandchildBA { + @Sendable func __safeDI_greatGrandchildInstantiator() -> GreatGrandchild { + GreatGrandchild() + } + let greatGrandchildInstantiator = SendableInstantiator(__safeDI_greatGrandchildInstantiator) + return GrandchildBA(greatGrandchildInstantiator: greatGrandchildInstantiator) + } + let grandchildBA: GrandchildBA = __safeDI_grandchildBA() + func __safeDI_grandchildBB() -> GrandchildBB { + @Sendable func __safeDI_greatGrandchildInstantiator() -> GreatGrandchild { + GreatGrandchild() + } + let greatGrandchildInstantiator = SendableInstantiator(__safeDI_greatGrandchildInstantiator) + return GrandchildBB(greatGrandchildInstantiator: greatGrandchildInstantiator) + } + let grandchildBB: GrandchildBB = __safeDI_grandchildBB() + return ChildB(grandchildBA: grandchildBA, grandchildBB: grandchildBB) + } + let childB: ChildB = __safeDI_childB() + self.init(childA: childA, childB: childB) + } + } + """) } @Test @@ -2885,27 +2851,26 @@ struct SafeDIToolCodeGenerationTests: ~Copyable { """, ], buildDependencyTreeOutput: true, - filesToDelete: &filesToDelete + filesToDelete: &filesToDelete, ) #expect(try #require(output.dependencyTree) == """ - // This file was generated by the SafeDIGenerateDependencyTree build tool plugin. - // Any modifications made to this file will be overwritten on subsequent builds. - // Please refrain from editing this file directly. - - #if canImport(Foundation) - @_implementationOnly import Foundation - #endif - - extension Root { - public init() { - let defaultUserService = DefaultUserService() - let userService: any UserService = defaultUserService - self.init(defaultUserService: defaultUserService, userService: userService) - } - } - """ - ) + // This file was generated by the SafeDIGenerateDependencyTree build tool plugin. + // Any modifications made to this file will be overwritten on subsequent builds. + // Please refrain from editing this file directly. + + #if canImport(Foundation) + @_implementationOnly import Foundation + #endif + + extension Root { + public init() { + let defaultUserService = DefaultUserService() + let userService: any UserService = defaultUserService + self.init(defaultUserService: defaultUserService, userService: userService) + } + } + """) } @Test @@ -2920,17 +2885,16 @@ struct SafeDIToolCodeGenerationTests: ~Copyable { """, ], buildDependencyTreeOutput: true, - filesToDelete: &filesToDelete + filesToDelete: &filesToDelete, ) #expect(try #require(output.dependencyTree) == """ - // This file was generated by the SafeDIGenerateDependencyTree build tool plugin. - // Any modifications made to this file will be overwritten on subsequent builds. - // Please refrain from editing this file directly. + // This file was generated by the SafeDIGenerateDependencyTree build tool plugin. + // Any modifications made to this file will be overwritten on subsequent builds. + // Please refrain from editing this file directly. - // No root @Instantiable-decorated types found, or root types already had a `public init()` method. - """ - ) + // No root @Instantiable-decorated types found, or root types already had a `public init()` method. + """) } @Test @@ -2947,21 +2911,20 @@ struct SafeDIToolCodeGenerationTests: ~Copyable { additionalImportedModules: ["Test"], buildDependencyTreeOutput: true, filesToDelete: &filesToDelete, - includeFolders: ["Fake"] + includeFolders: ["Fake"], ) #expect(try #require(output.dependencyTree) == """ - // This file was generated by the SafeDIGenerateDependencyTree build tool plugin. - // Any modifications made to this file will be overwritten on subsequent builds. - // Please refrain from editing this file directly. + // This file was generated by the SafeDIGenerateDependencyTree build tool plugin. + // Any modifications made to this file will be overwritten on subsequent builds. + // Please refrain from editing this file directly. - #if canImport(Test) - import Test - #endif + #if canImport(Test) + import Test + #endif - // No root @Instantiable-decorated types found, or root types already had a `public init()` method. - """ - ) + // No root @Instantiable-decorated types found, or root types already had a `public init()` method. + """) } @Test @@ -2976,17 +2939,16 @@ struct SafeDIToolCodeGenerationTests: ~Copyable { """, ], buildDependencyTreeOutput: true, - filesToDelete: &filesToDelete + filesToDelete: &filesToDelete, ) #expect(try #require(output.dependencyTree) == """ - // This file was generated by the SafeDIGenerateDependencyTree build tool plugin. - // Any modifications made to this file will be overwritten on subsequent builds. - // Please refrain from editing this file directly. + // This file was generated by the SafeDIGenerateDependencyTree build tool plugin. + // Any modifications made to this file will be overwritten on subsequent builds. + // Please refrain from editing this file directly. - // No root @Instantiable-decorated types found, or root types already had a `public init()` method. - """ - ) + // No root @Instantiable-decorated types found, or root types already had a `public init()` method. + """) } @Test @@ -3108,42 +3070,41 @@ struct SafeDIToolCodeGenerationTests: ~Copyable { """, ], buildDependencyTreeOutput: true, - filesToDelete: &filesToDelete + filesToDelete: &filesToDelete, ) #expect(try #require(output.dependencyTree) == """ - // This file was generated by the SafeDIGenerateDependencyTree build tool plugin. - // Any modifications made to this file will be overwritten on subsequent builds. - // Please refrain from editing this file directly. - - #if canImport(UIKit) - import UIKit - #endif - - extension RootViewController { - public convenience init() { - let networkService: NetworkService = DefaultNetworkService() - let authService: AuthService = DefaultAuthService(networkService: networkService) - func __safeDI_loggedInViewControllerBuilder(userManager: UserManager) -> LoggedInViewController { - func __safeDI_profileViewControllerBuilder() -> ProfileViewController { - let userVendor: UserVendor = userManager - func __safeDI_editProfileViewControllerBuilder() -> EditProfileViewController { - EditProfileViewController(userVendor: userVendor, userManager: userManager) - } - let editProfileViewControllerBuilder = Instantiator(__safeDI_editProfileViewControllerBuilder) - return ProfileViewController(userVendor: userVendor, editProfileViewControllerBuilder: editProfileViewControllerBuilder) - } - let profileViewControllerBuilder = Instantiator(__safeDI_profileViewControllerBuilder) - return LoggedInViewController(userManager: userManager, profileViewControllerBuilder: profileViewControllerBuilder) - } - let loggedInViewControllerBuilder = Instantiator { - __safeDI_loggedInViewControllerBuilder(userManager: $0) - } - self.init(authService: authService, networkService: networkService, loggedInViewControllerBuilder: loggedInViewControllerBuilder) - } - } - """ - ) + // This file was generated by the SafeDIGenerateDependencyTree build tool plugin. + // Any modifications made to this file will be overwritten on subsequent builds. + // Please refrain from editing this file directly. + + #if canImport(UIKit) + import UIKit + #endif + + extension RootViewController { + public convenience init() { + let networkService: NetworkService = DefaultNetworkService() + let authService: AuthService = DefaultAuthService(networkService: networkService) + func __safeDI_loggedInViewControllerBuilder(userManager: UserManager) -> LoggedInViewController { + func __safeDI_profileViewControllerBuilder() -> ProfileViewController { + let userVendor: UserVendor = userManager + func __safeDI_editProfileViewControllerBuilder() -> EditProfileViewController { + EditProfileViewController(userVendor: userVendor, userManager: userManager) + } + let editProfileViewControllerBuilder = Instantiator(__safeDI_editProfileViewControllerBuilder) + return ProfileViewController(userVendor: userVendor, editProfileViewControllerBuilder: editProfileViewControllerBuilder) + } + let profileViewControllerBuilder = Instantiator(__safeDI_profileViewControllerBuilder) + return LoggedInViewController(userManager: userManager, profileViewControllerBuilder: profileViewControllerBuilder) + } + let loggedInViewControllerBuilder = Instantiator { + __safeDI_loggedInViewControllerBuilder(userManager: $0) + } + self.init(authService: authService, networkService: networkService, loggedInViewControllerBuilder: loggedInViewControllerBuilder) + } + } + """) } @Test @@ -3183,32 +3144,31 @@ struct SafeDIToolCodeGenerationTests: ~Copyable { """, ], buildDependencyTreeOutput: true, - filesToDelete: &filesToDelete + filesToDelete: &filesToDelete, ) #expect(try #require(output.dependencyTree) == """ - // This file was generated by the SafeDIGenerateDependencyTree build tool plugin. - // Any modifications made to this file will be overwritten on subsequent builds. - // Please refrain from editing this file directly. - - extension Root { - public convenience init() { - func __safeDI_childBuilder(iterator: IndexingIterator>) -> Child { - func __safeDI_grandchildBuilder() -> Grandchild { - let anyIterator = AnyIterator(iterator) - return Grandchild(anyIterator: anyIterator) - } - let grandchildBuilder = Instantiator(__safeDI_grandchildBuilder) - return Child(iterator: iterator, grandchildBuilder: grandchildBuilder) - } - let childBuilder = Instantiator { - __safeDI_childBuilder(iterator: $0) - } - self.init(childBuilder: childBuilder) - } - } - """ - ) + // This file was generated by the SafeDIGenerateDependencyTree build tool plugin. + // Any modifications made to this file will be overwritten on subsequent builds. + // Please refrain from editing this file directly. + + extension Root { + public convenience init() { + func __safeDI_childBuilder(iterator: IndexingIterator>) -> Child { + func __safeDI_grandchildBuilder() -> Grandchild { + let anyIterator = AnyIterator(iterator) + return Grandchild(anyIterator: anyIterator) + } + let grandchildBuilder = Instantiator(__safeDI_grandchildBuilder) + return Child(iterator: iterator, grandchildBuilder: grandchildBuilder) + } + let childBuilder = Instantiator { + __safeDI_childBuilder(iterator: $0) + } + self.init(childBuilder: childBuilder) + } + } + """) } @Test @@ -3333,43 +3293,42 @@ struct SafeDIToolCodeGenerationTests: ~Copyable { """, ], buildDependencyTreeOutput: true, - filesToDelete: &filesToDelete + filesToDelete: &filesToDelete, ) #expect(try #require(output.dependencyTree) == """ - // This file was generated by the SafeDIGenerateDependencyTree build tool plugin. - // Any modifications made to this file will be overwritten on subsequent builds. - // Please refrain from editing this file directly. - - #if canImport(UIKit) - import UIKit - #endif - - extension RootViewController { - public convenience init() { - let networkService: NetworkService = DefaultNetworkService() - let authService: AuthService = DefaultAuthService(networkService: networkService) - func __safeDI_loggedInViewControllerBuilder(userManager: UserManager) -> LoggedInViewController { - let userNetworkService: NetworkService = networkService - func __safeDI_profileViewControllerBuilder() -> ProfileViewController { - let userVendor: UserVendor = userManager - func __safeDI_editProfileViewControllerBuilder() -> EditProfileViewController { - EditProfileViewController(userVendor: userVendor, userManager: userManager, userNetworkService: userNetworkService) - } - let editProfileViewControllerBuilder = Instantiator(__safeDI_editProfileViewControllerBuilder) - return ProfileViewController(userVendor: userVendor, editProfileViewControllerBuilder: editProfileViewControllerBuilder) - } - let profileViewControllerBuilder = Instantiator(__safeDI_profileViewControllerBuilder) - return LoggedInViewController(userManager: userManager, userNetworkService: userNetworkService, profileViewControllerBuilder: profileViewControllerBuilder) - } - let loggedInViewControllerBuilder = Instantiator { - __safeDI_loggedInViewControllerBuilder(userManager: $0) - } - self.init(authService: authService, networkService: networkService, loggedInViewControllerBuilder: loggedInViewControllerBuilder) - } - } - """ - ) + // This file was generated by the SafeDIGenerateDependencyTree build tool plugin. + // Any modifications made to this file will be overwritten on subsequent builds. + // Please refrain from editing this file directly. + + #if canImport(UIKit) + import UIKit + #endif + + extension RootViewController { + public convenience init() { + let networkService: NetworkService = DefaultNetworkService() + let authService: AuthService = DefaultAuthService(networkService: networkService) + func __safeDI_loggedInViewControllerBuilder(userManager: UserManager) -> LoggedInViewController { + let userNetworkService: NetworkService = networkService + func __safeDI_profileViewControllerBuilder() -> ProfileViewController { + let userVendor: UserVendor = userManager + func __safeDI_editProfileViewControllerBuilder() -> EditProfileViewController { + EditProfileViewController(userVendor: userVendor, userManager: userManager, userNetworkService: userNetworkService) + } + let editProfileViewControllerBuilder = Instantiator(__safeDI_editProfileViewControllerBuilder) + return ProfileViewController(userVendor: userVendor, editProfileViewControllerBuilder: editProfileViewControllerBuilder) + } + let profileViewControllerBuilder = Instantiator(__safeDI_profileViewControllerBuilder) + return LoggedInViewController(userManager: userManager, userNetworkService: userNetworkService, profileViewControllerBuilder: profileViewControllerBuilder) + } + let loggedInViewControllerBuilder = Instantiator { + __safeDI_loggedInViewControllerBuilder(userManager: $0) + } + self.init(authService: authService, networkService: networkService, loggedInViewControllerBuilder: loggedInViewControllerBuilder) + } + } + """) } @Test @@ -3422,31 +3381,30 @@ struct SafeDIToolCodeGenerationTests: ~Copyable { """, ], buildDependencyTreeOutput: true, - filesToDelete: &filesToDelete + filesToDelete: &filesToDelete, ) #expect(try #require(output.dependencyTree) == """ - // This file was generated by the SafeDIGenerateDependencyTree build tool plugin. - // Any modifications made to this file will be overwritten on subsequent builds. - // Please refrain from editing this file directly. - - #if canImport(UIKit) - import UIKit - #endif - - extension RootViewController { - public convenience init() { - func __safeDI_authService() -> DefaultAuthService { - let networkService: NetworkService = DefaultNetworkService() - let renamedNetworkService: NetworkService = networkService - return DefaultAuthService(networkService: networkService, renamedNetworkService: renamedNetworkService) - } - let authService: AuthService = __safeDI_authService() - self.init(authService: authService) - } - } - """ - ) + // This file was generated by the SafeDIGenerateDependencyTree build tool plugin. + // Any modifications made to this file will be overwritten on subsequent builds. + // Please refrain from editing this file directly. + + #if canImport(UIKit) + import UIKit + #endif + + extension RootViewController { + public convenience init() { + func __safeDI_authService() -> DefaultAuthService { + let networkService: NetworkService = DefaultNetworkService() + let renamedNetworkService: NetworkService = networkService + return DefaultAuthService(networkService: networkService, renamedNetworkService: renamedNetworkService) + } + let authService: AuthService = __safeDI_authService() + self.init(authService: authService) + } + } + """) } @Test @@ -3503,32 +3461,31 @@ struct SafeDIToolCodeGenerationTests: ~Copyable { """, ], buildDependencyTreeOutput: true, - filesToDelete: &filesToDelete + filesToDelete: &filesToDelete, ) #expect(try #require(output.dependencyTree) == """ - // This file was generated by the SafeDIGenerateDependencyTree build tool plugin. - // Any modifications made to this file will be overwritten on subsequent builds. - // Please refrain from editing this file directly. - - #if canImport(UIKit) - import UIKit - #endif - - extension RootViewController { - public convenience init() { - let networkService: NetworkService = DefaultNetworkService() - func __safeDI_authService() -> DefaultAuthService { - let renamedNetworkService: NetworkService = networkService - let renamedAgainNetworkService: NetworkService = renamedNetworkService - return DefaultAuthService(networkService: networkService, renamedNetworkService: renamedNetworkService, renamedAgainNetworkService: renamedAgainNetworkService) - } - let authService: AuthService = __safeDI_authService() - self.init(authService: authService, networkService: networkService) - } - } - """ - ) + // This file was generated by the SafeDIGenerateDependencyTree build tool plugin. + // Any modifications made to this file will be overwritten on subsequent builds. + // Please refrain from editing this file directly. + + #if canImport(UIKit) + import UIKit + #endif + + extension RootViewController { + public convenience init() { + let networkService: NetworkService = DefaultNetworkService() + func __safeDI_authService() -> DefaultAuthService { + let renamedNetworkService: NetworkService = networkService + let renamedAgainNetworkService: NetworkService = renamedNetworkService + return DefaultAuthService(networkService: networkService, renamedNetworkService: renamedNetworkService, renamedAgainNetworkService: renamedAgainNetworkService) + } + let authService: AuthService = __safeDI_authService() + self.init(authService: authService, networkService: networkService) + } + } + """) } @Test @@ -3650,42 +3607,41 @@ struct SafeDIToolCodeGenerationTests: ~Copyable { """, ], buildDependencyTreeOutput: true, - filesToDelete: &filesToDelete + filesToDelete: &filesToDelete, ) #expect(try #require(output.dependencyTree) == """ - // This file was generated by the SafeDIGenerateDependencyTree build tool plugin. - // Any modifications made to this file will be overwritten on subsequent builds. - // Please refrain from editing this file directly. - - #if canImport(UIKit) - import UIKit - #endif - - extension RootViewController { - public convenience init() { - let networkService: NetworkService = DefaultNetworkService() - let authService: AuthService = DefaultAuthService(networkService: networkService) - func __safeDI_loggedInViewControllerBuilder(userManager: UserManager) -> LoggedInViewController { - let userVendor: UserVendor = userManager - func __safeDI_profileViewControllerBuilder() -> ProfileViewController { - func __safeDI_editProfileViewControllerBuilder() -> EditProfileViewController { - EditProfileViewController(userVendor: userVendor, userManager: userManager) - } - let editProfileViewControllerBuilder = Instantiator(__safeDI_editProfileViewControllerBuilder) - return ProfileViewController(editProfileViewControllerBuilder: editProfileViewControllerBuilder) - } - let profileViewControllerBuilder = Instantiator(__safeDI_profileViewControllerBuilder) - return LoggedInViewController(userManager: userManager, userVendor: userVendor, profileViewControllerBuilder: profileViewControllerBuilder) - } - let loggedInViewControllerBuilder = Instantiator { - __safeDI_loggedInViewControllerBuilder(userManager: $0) - } - self.init(authService: authService, networkService: networkService, loggedInViewControllerBuilder: loggedInViewControllerBuilder) - } - } - """ - ) + // This file was generated by the SafeDIGenerateDependencyTree build tool plugin. + // Any modifications made to this file will be overwritten on subsequent builds. + // Please refrain from editing this file directly. + + #if canImport(UIKit) + import UIKit + #endif + + extension RootViewController { + public convenience init() { + let networkService: NetworkService = DefaultNetworkService() + let authService: AuthService = DefaultAuthService(networkService: networkService) + func __safeDI_loggedInViewControllerBuilder(userManager: UserManager) -> LoggedInViewController { + let userVendor: UserVendor = userManager + func __safeDI_profileViewControllerBuilder() -> ProfileViewController { + func __safeDI_editProfileViewControllerBuilder() -> EditProfileViewController { + EditProfileViewController(userVendor: userVendor, userManager: userManager) + } + let editProfileViewControllerBuilder = Instantiator(__safeDI_editProfileViewControllerBuilder) + return ProfileViewController(editProfileViewControllerBuilder: editProfileViewControllerBuilder) + } + let profileViewControllerBuilder = Instantiator(__safeDI_profileViewControllerBuilder) + return LoggedInViewController(userManager: userManager, userVendor: userVendor, profileViewControllerBuilder: profileViewControllerBuilder) + } + let loggedInViewControllerBuilder = Instantiator { + __safeDI_loggedInViewControllerBuilder(userManager: $0) + } + self.init(authService: authService, networkService: networkService, loggedInViewControllerBuilder: loggedInViewControllerBuilder) + } + } + """) } @Test @@ -3805,42 +3761,41 @@ struct SafeDIToolCodeGenerationTests: ~Copyable { """, ], buildDependencyTreeOutput: true, - filesToDelete: &filesToDelete + filesToDelete: &filesToDelete, ) #expect(try #require(output.dependencyTree) == """ - // This file was generated by the SafeDIGenerateDependencyTree build tool plugin. - // Any modifications made to this file will be overwritten on subsequent builds. - // Please refrain from editing this file directly. - - #if canImport(UIKit) - import UIKit - #endif - - extension RootViewController { - public convenience init() { - let networkService: NetworkService = DefaultNetworkService() - let authService: AuthService = DefaultAuthService(networkService: networkService) - func __safeDI_loggedInViewControllerBuilder(userManager: UserManager) -> LoggedInViewController { - func __safeDI_profileViewControllerBuilder() -> ProfileViewController { - func __safeDI_editProfileViewControllerBuilder() -> EditProfileViewController { - let userVendor: UserVendor = userManager - return EditProfileViewController(userVendor: userVendor, userManager: userManager) - } - let editProfileViewControllerBuilder = Instantiator(__safeDI_editProfileViewControllerBuilder) - return ProfileViewController(editProfileViewControllerBuilder: editProfileViewControllerBuilder) - } - let profileViewControllerBuilder = Instantiator(__safeDI_profileViewControllerBuilder) - return LoggedInViewController(userManager: userManager, profileViewControllerBuilder: profileViewControllerBuilder) - } - let loggedInViewControllerBuilder = Instantiator { - __safeDI_loggedInViewControllerBuilder(userManager: $0) - } - self.init(authService: authService, networkService: networkService, loggedInViewControllerBuilder: loggedInViewControllerBuilder) - } - } - """ - ) + // This file was generated by the SafeDIGenerateDependencyTree build tool plugin. + // Any modifications made to this file will be overwritten on subsequent builds. + // Please refrain from editing this file directly. + + #if canImport(UIKit) + import UIKit + #endif + + extension RootViewController { + public convenience init() { + let networkService: NetworkService = DefaultNetworkService() + let authService: AuthService = DefaultAuthService(networkService: networkService) + func __safeDI_loggedInViewControllerBuilder(userManager: UserManager) -> LoggedInViewController { + func __safeDI_profileViewControllerBuilder() -> ProfileViewController { + func __safeDI_editProfileViewControllerBuilder() -> EditProfileViewController { + let userVendor: UserVendor = userManager + return EditProfileViewController(userVendor: userVendor, userManager: userManager) + } + let editProfileViewControllerBuilder = Instantiator(__safeDI_editProfileViewControllerBuilder) + return ProfileViewController(editProfileViewControllerBuilder: editProfileViewControllerBuilder) + } + let profileViewControllerBuilder = Instantiator(__safeDI_profileViewControllerBuilder) + return LoggedInViewController(userManager: userManager, profileViewControllerBuilder: profileViewControllerBuilder) + } + let loggedInViewControllerBuilder = Instantiator { + __safeDI_loggedInViewControllerBuilder(userManager: $0) + } + self.init(authService: authService, networkService: networkService, loggedInViewControllerBuilder: loggedInViewControllerBuilder) + } + } + """) } @Test @@ -3893,28 +3848,27 @@ struct SafeDIToolCodeGenerationTests: ~Copyable { """, ], buildDependencyTreeOutput: true, - filesToDelete: &filesToDelete + filesToDelete: &filesToDelete, ) #expect(try #require(output.dependencyTree) == """ - // This file was generated by the SafeDIGenerateDependencyTree build tool plugin. - // Any modifications made to this file will be overwritten on subsequent builds. - // Please refrain from editing this file directly. - - extension Root { - public convenience init() { - func __safeDI_child() -> Child { - let greatGrandchild = GreatGrandchild() - let grandchild = Grandchild(greatGrandchild: greatGrandchild) - let unrelated = Unrelated() - return Child(grandchild: grandchild, unrelated: unrelated, greatGrandchild: greatGrandchild) - } - let child: Child = __safeDI_child() - self.init(child: child) - } - } - """ - ) + // This file was generated by the SafeDIGenerateDependencyTree build tool plugin. + // Any modifications made to this file will be overwritten on subsequent builds. + // Please refrain from editing this file directly. + + extension Root { + public convenience init() { + func __safeDI_child() -> Child { + let greatGrandchild = GreatGrandchild() + let grandchild = Grandchild(greatGrandchild: greatGrandchild) + let unrelated = Unrelated() + return Child(grandchild: grandchild, unrelated: unrelated, greatGrandchild: greatGrandchild) + } + let child: Child = __safeDI_child() + self.init(child: child) + } + } + """) } @Test @@ -4258,47 +4212,46 @@ struct SafeDIToolCodeGenerationTests: ~Copyable { """, ], buildDependencyTreeOutput: true, - filesToDelete: &filesToDelete + filesToDelete: &filesToDelete, ) #expect(try #require(output.dependencyTree) == """ - // This file was generated by the SafeDIGenerateDependencyTree build tool plugin. - // Any modifications made to this file will be overwritten on subsequent builds. - // Please refrain from editing this file directly. - - extension Root { - public convenience init() { - let x = X() - let a = A(x: x) - let g = G() - let e = E(g: g) - let m = M(e: e) - let o = O(m: m, e: e, g: g, a: a) - let d = D(o: o, g: g) - let f = F(a: a, x: x) - let i = I(f: f) - let p = P(i: i, x: x) - let n = N(o: o, p: p, e: e) - let r = R(a: a, m: m, o: o, n: n, e: e) - let t = T(e: e, n: n) - let s = S(a: a, t: t, o: o, r: r) - let w = W(a: a, x: x, o: o, n: n) - let u = U(p: p, d: d, o: o, w: w, n: n) - let y = Y(u: u, p: p) - let b = B(a: a, d: d, t: t, o: o, y: y, s: s) - let c = C(u: u, n: n, y: y) - let h = H(u: u, g: g) - let j = J(a: a, g: g) - let k = K(i: i, t: t) - let v = V(a: a, t: t, o: o, f: f, c: c, i: i, d: d) - let l = L(o: o, v: v, e: e) - let q = Q(u: u, t: t, e: e) - let z = Z(e: e, p: p, l: l, i: i, n: n) - self.init(a: a, b: b, c: c, d: d, e: e, f: f, g: g, h: h, i: i, j: j, k: k, l: l, m: m, n: n, o: o, p: p, q: q, r: r, s: s, t: t, u: u, v: v, w: w, x: x, y: y, z: z) - } - } - """ - ) + // This file was generated by the SafeDIGenerateDependencyTree build tool plugin. + // Any modifications made to this file will be overwritten on subsequent builds. + // Please refrain from editing this file directly. + + extension Root { + public convenience init() { + let x = X() + let a = A(x: x) + let g = G() + let e = E(g: g) + let m = M(e: e) + let o = O(m: m, e: e, g: g, a: a) + let d = D(o: o, g: g) + let f = F(a: a, x: x) + let i = I(f: f) + let p = P(i: i, x: x) + let n = N(o: o, p: p, e: e) + let r = R(a: a, m: m, o: o, n: n, e: e) + let t = T(e: e, n: n) + let s = S(a: a, t: t, o: o, r: r) + let w = W(a: a, x: x, o: o, n: n) + let u = U(p: p, d: d, o: o, w: w, n: n) + let y = Y(u: u, p: p) + let b = B(a: a, d: d, t: t, o: o, y: y, s: s) + let c = C(u: u, n: n, y: y) + let h = H(u: u, g: g) + let j = J(a: a, g: g) + let k = K(i: i, t: t) + let v = V(a: a, t: t, o: o, f: f, c: c, i: i, d: d) + let l = L(o: o, v: v, e: e) + let q = Q(u: u, t: t, e: e) + let z = Z(e: e, p: p, l: l, i: i, n: n) + self.init(a: a, b: b, c: c, d: d, e: e, f: f, g: g, h: h, i: i, j: j, k: k, l: l, m: m, n: n, o: o, p: p, q: q, r: r, s: s, t: t, u: u, v: v, w: w, x: x, y: y, z: z) + } + } + """) } @Test @@ -4323,25 +4276,24 @@ struct SafeDIToolCodeGenerationTests: ~Copyable { """, ], buildDependencyTreeOutput: true, - filesToDelete: &filesToDelete + filesToDelete: &filesToDelete, ) #expect(try #require(output.dependencyTree) == """ - // This file was generated by the SafeDIGenerateDependencyTree build tool plugin. - // Any modifications made to this file will be overwritten on subsequent builds. - // Please refrain from editing this file directly. - - extension Root { - public convenience init() { - func __safeDI_childBuilder() -> Child { - Child() - } - let childBuilder: Instantiator? = Instantiator(__safeDI_childBuilder) - self.init(childBuilder: childBuilder) - } - } - """ - ) + // This file was generated by the SafeDIGenerateDependencyTree build tool plugin. + // Any modifications made to this file will be overwritten on subsequent builds. + // Please refrain from editing this file directly. + + extension Root { + public convenience init() { + func __safeDI_childBuilder() -> Child { + Child() + } + let childBuilder: Instantiator? = Instantiator(__safeDI_childBuilder) + self.init(childBuilder: childBuilder) + } + } + """) } @Test @@ -4390,34 +4342,33 @@ struct SafeDIToolCodeGenerationTests: ~Copyable { """, ], buildDependencyTreeOutput: true, - filesToDelete: &filesToDelete + filesToDelete: &filesToDelete, ) #expect(try #require(output.dependencyTree) == """ - // This file was generated by the SafeDIGenerateDependencyTree build tool plugin. - // Any modifications made to this file will be overwritten on subsequent builds. - // Please refrain from editing this file directly. - - extension Root { - public init() { - func __safeDI_aBuilder() -> A { - func __safeDI_bBuilder() -> B { - func __safeDI_cBuilder() -> C { - let aBuilder = Instantiator(__safeDI_aBuilder) - return C(aBuilder: aBuilder) - } - let cBuilder = Instantiator(__safeDI_cBuilder) - return B(cBuilder: cBuilder) - } - let bBuilder = Instantiator(__safeDI_bBuilder) - return A(bBuilder: bBuilder) - } - let aBuilder = Instantiator(__safeDI_aBuilder) - self.init(aBuilder: aBuilder) - } - } - """ - ) + // This file was generated by the SafeDIGenerateDependencyTree build tool plugin. + // Any modifications made to this file will be overwritten on subsequent builds. + // Please refrain from editing this file directly. + + extension Root { + public init() { + func __safeDI_aBuilder() -> A { + func __safeDI_bBuilder() -> B { + func __safeDI_cBuilder() -> C { + let aBuilder = Instantiator(__safeDI_aBuilder) + return C(aBuilder: aBuilder) + } + let cBuilder = Instantiator(__safeDI_cBuilder) + return B(cBuilder: cBuilder) + } + let bBuilder = Instantiator(__safeDI_bBuilder) + return A(bBuilder: bBuilder) + } + let aBuilder = Instantiator(__safeDI_aBuilder) + self.init(aBuilder: aBuilder) + } + } + """) } @Test @@ -4466,34 +4417,33 @@ struct SafeDIToolCodeGenerationTests: ~Copyable { """, ], buildDependencyTreeOutput: true, - filesToDelete: &filesToDelete + filesToDelete: &filesToDelete, ) #expect(try #require(output.dependencyTree) == """ - // This file was generated by the SafeDIGenerateDependencyTree build tool plugin. - // Any modifications made to this file will be overwritten on subsequent builds. - // Please refrain from editing this file directly. - - extension Root { - public init() { - func __safeDI_a() -> A { - func __safeDI_b() -> B { - func __safeDI_cBuilder() -> C { - let a = A(b: b) - return C(a: a) - } - let cBuilder = Instantiator(__safeDI_cBuilder) - return B(cBuilder: cBuilder) - } - let b: B = __safeDI_b() - return A(b: b) - } - let a: A = __safeDI_a() - self.init(a: a) - } - } - """ - ) + // This file was generated by the SafeDIGenerateDependencyTree build tool plugin. + // Any modifications made to this file will be overwritten on subsequent builds. + // Please refrain from editing this file directly. + + extension Root { + public init() { + func __safeDI_a() -> A { + func __safeDI_b() -> B { + func __safeDI_cBuilder() -> C { + let a = A(b: b) + return C(a: a) + } + let cBuilder = Instantiator(__safeDI_cBuilder) + return B(cBuilder: cBuilder) + } + let b: B = __safeDI_b() + return A(b: b) + } + let a: A = __safeDI_a() + self.init(a: a) + } + } + """) } @Test @@ -4522,30 +4472,29 @@ struct SafeDIToolCodeGenerationTests: ~Copyable { """, ], buildDependencyTreeOutput: true, - filesToDelete: &filesToDelete + filesToDelete: &filesToDelete, ) #expect(try #require(output.dependencyTree) == """ - // This file was generated by the SafeDIGenerateDependencyTree build tool plugin. - // Any modifications made to this file will be overwritten on subsequent builds. - // Please refrain from editing this file directly. - - extension Root { - public init() { - func __safeDI_a() -> A { - func __safeDI_aBuilder() -> A { - let aBuilder = Instantiator(__safeDI_aBuilder) - return A(aBuilder: aBuilder) - } - let aBuilder = Instantiator(__safeDI_aBuilder) - return A(aBuilder: aBuilder) - } - let a: A = __safeDI_a() - self.init(a: a) - } - } - """ - ) + // This file was generated by the SafeDIGenerateDependencyTree build tool plugin. + // Any modifications made to this file will be overwritten on subsequent builds. + // Please refrain from editing this file directly. + + extension Root { + public init() { + func __safeDI_a() -> A { + func __safeDI_aBuilder() -> A { + let aBuilder = Instantiator(__safeDI_aBuilder) + return A(aBuilder: aBuilder) + } + let aBuilder = Instantiator(__safeDI_aBuilder) + return A(aBuilder: aBuilder) + } + let a: A = __safeDI_a() + self.init(a: a) + } + } + """) } @Test @@ -4575,30 +4524,29 @@ struct SafeDIToolCodeGenerationTests: ~Copyable { """, ], buildDependencyTreeOutput: true, - filesToDelete: &filesToDelete + filesToDelete: &filesToDelete, ) #expect(try #require(output.dependencyTree) == """ - // This file was generated by the SafeDIGenerateDependencyTree build tool plugin. - // Any modifications made to this file will be overwritten on subsequent builds. - // Please refrain from editing this file directly. - - extension Root { - public init() { - func __safeDI_aBuilder(context: String) -> A { - let aBuilder = Instantiator { - __safeDI_aBuilder(context: $0) - } - return A(aBuilder: aBuilder, context: context) - } - let aBuilder = Instantiator { - __safeDI_aBuilder(context: $0) - } - self.init(aBuilder: aBuilder) - } - } - """ - ) + // This file was generated by the SafeDIGenerateDependencyTree build tool plugin. + // Any modifications made to this file will be overwritten on subsequent builds. + // Please refrain from editing this file directly. + + extension Root { + public init() { + func __safeDI_aBuilder(context: String) -> A { + let aBuilder = Instantiator { + __safeDI_aBuilder(context: $0) + } + return A(aBuilder: aBuilder, context: context) + } + let aBuilder = Instantiator { + __safeDI_aBuilder(context: $0) + } + self.init(aBuilder: aBuilder) + } + } + """) } @Test @@ -4640,25 +4588,24 @@ struct SafeDIToolCodeGenerationTests: ~Copyable { """, ], buildDependencyTreeOutput: true, - filesToDelete: &filesToDelete + filesToDelete: &filesToDelete, ) #expect(try #require(output.dependencyTree) == """ - // This file was generated by the SafeDIGenerateDependencyTree build tool plugin. - // Any modifications made to this file will be overwritten on subsequent builds. - // Please refrain from editing this file directly. - - extension Root { - public init() { - let stringContainer: Container = Container.instantiate() - let intContainer: Container = Container.instantiate() - let floatContainer: Container = Container.instantiate() - let voidContainer: Container = Container.instantiate() - self.init(stringContainer: stringContainer, intContainer: intContainer, floatContainer: floatContainer, voidContainer: voidContainer) - } - } - """ - ) + // This file was generated by the SafeDIGenerateDependencyTree build tool plugin. + // Any modifications made to this file will be overwritten on subsequent builds. + // Please refrain from editing this file directly. + + extension Root { + public init() { + let stringContainer: Container = Container.instantiate() + let intContainer: Container = Container.instantiate() + let floatContainer: Container = Container.instantiate() + let voidContainer: Container = Container.instantiate() + self.init(stringContainer: stringContainer, intContainer: intContainer, floatContainer: floatContainer, voidContainer: voidContainer) + } + } + """) } @Test @@ -4700,25 +4647,24 @@ struct SafeDIToolCodeGenerationTests: ~Copyable { """, ], buildDependencyTreeOutput: true, - filesToDelete: &filesToDelete + filesToDelete: &filesToDelete, ) #expect(try #require(output.dependencyTree) == """ - // This file was generated by the SafeDIGenerateDependencyTree build tool plugin. - // Any modifications made to this file will be overwritten on subsequent builds. - // Please refrain from editing this file directly. - - extension Root { - public init() { - let stringContainer: MyModule.Container = MyModule.Container.instantiate() - let intContainer: MyModule.Container = MyModule.Container.instantiate() - let floatContainer: MyModule.Container = MyModule.Container.instantiate() - let voidContainer: MyModule.Container = MyModule.Container.instantiate() - self.init(stringContainer: stringContainer, intContainer: intContainer, floatContainer: floatContainer, voidContainer: voidContainer) - } - } - """ - ) + // This file was generated by the SafeDIGenerateDependencyTree build tool plugin. + // Any modifications made to this file will be overwritten on subsequent builds. + // Please refrain from editing this file directly. + + extension Root { + public init() { + let stringContainer: MyModule.Container = MyModule.Container.instantiate() + let intContainer: MyModule.Container = MyModule.Container.instantiate() + let floatContainer: MyModule.Container = MyModule.Container.instantiate() + let voidContainer: MyModule.Container = MyModule.Container.instantiate() + self.init(stringContainer: stringContainer, intContainer: intContainer, floatContainer: floatContainer, voidContainer: voidContainer) + } + } + """) } @Test @@ -4754,30 +4700,29 @@ struct SafeDIToolCodeGenerationTests: ~Copyable { """, ], buildDependencyTreeOutput: true, - filesToDelete: &filesToDelete + filesToDelete: &filesToDelete, ) #expect(try #require(output.dependencyTree) == """ - // This file was generated by the SafeDIGenerateDependencyTree build tool plugin. - // Any modifications made to this file will be overwritten on subsequent builds. - // Please refrain from editing this file directly. - - #if canImport(Foundation) - import Foundation - #endif - - extension Root { - public convenience init() { - func __safeDI_child() -> Child { - let inner = Child.Inner() - return Child(inner: inner) - } - let child: Child = __safeDI_child() - self.init(child: child) - } - } - """ - ) + // This file was generated by the SafeDIGenerateDependencyTree build tool plugin. + // Any modifications made to this file will be overwritten on subsequent builds. + // Please refrain from editing this file directly. + + #if canImport(Foundation) + import Foundation + #endif + + extension Root { + public convenience init() { + func __safeDI_child() -> Child { + let inner = Child.Inner() + return Child(inner: inner) + } + let child: Child = __safeDI_child() + self.init(child: child) + } + } + """) } @Test @@ -4837,39 +4782,38 @@ struct SafeDIToolCodeGenerationTests: ~Copyable { """, ], buildDependencyTreeOutput: true, - filesToDelete: &filesToDelete + filesToDelete: &filesToDelete, ) #expect(try #require(output.dependencyTree) == """ - // This file was generated by the SafeDIGenerateDependencyTree build tool plugin. - // Any modifications made to this file will be overwritten on subsequent builds. - // Please refrain from editing this file directly. - - #if canImport(Foundation) - import Foundation - #endif - - extension Root { - public convenience init() { - func __safeDI_child() -> Child { - func __safeDI_grandchild() -> Child.Grandchild { - func __safeDI_greatGrandchild() -> Child.Grandchild.GreatGrandchild { - let pathalogical = Child.Grandchild.GreatGrandchild.Pathalogical() - return Child.Grandchild.GreatGrandchild(pathalogical: pathalogical) - } - let greatGrandchild: Child.Grandchild.GreatGrandchild = __safeDI_greatGrandchild() - let pathalogical = Child.Grandchild.Pathalogical() - return Child.Grandchild(greatGrandchild: greatGrandchild, pathalogical: pathalogical) - } - let grandchild: Child.Grandchild = __safeDI_grandchild() - return Child(grandchild: grandchild) - } - let child: Child = __safeDI_child() - self.init(child: child) - } - } - """ - ) + // This file was generated by the SafeDIGenerateDependencyTree build tool plugin. + // Any modifications made to this file will be overwritten on subsequent builds. + // Please refrain from editing this file directly. + + #if canImport(Foundation) + import Foundation + #endif + + extension Root { + public convenience init() { + func __safeDI_child() -> Child { + func __safeDI_grandchild() -> Child.Grandchild { + func __safeDI_greatGrandchild() -> Child.Grandchild.GreatGrandchild { + let pathalogical = Child.Grandchild.GreatGrandchild.Pathalogical() + return Child.Grandchild.GreatGrandchild(pathalogical: pathalogical) + } + let greatGrandchild: Child.Grandchild.GreatGrandchild = __safeDI_greatGrandchild() + let pathalogical = Child.Grandchild.Pathalogical() + return Child.Grandchild(greatGrandchild: greatGrandchild, pathalogical: pathalogical) + } + let grandchild: Child.Grandchild = __safeDI_grandchild() + return Child(grandchild: grandchild) + } + let child: Child = __safeDI_child() + self.init(child: child) + } + } + """) } @Test @@ -4929,39 +4873,38 @@ struct SafeDIToolCodeGenerationTests: ~Copyable { """, ], buildDependencyTreeOutput: true, - filesToDelete: &filesToDelete + filesToDelete: &filesToDelete, ) #expect(try #require(output.dependencyTree) == """ - // This file was generated by the SafeDIGenerateDependencyTree build tool plugin. - // Any modifications made to this file will be overwritten on subsequent builds. - // Please refrain from editing this file directly. - - #if canImport(Foundation) - import Foundation - #endif - - extension Root { - public convenience init() { - func __safeDI_child() -> Child { - func __safeDI_grandchild() -> Child.Grandchild { - func __safeDI_greatGrandchild() -> Child.Grandchild.GreatGrandchild { - let pathalogical = Child.Grandchild.GreatGrandchild.Pathalogical() - return Child.Grandchild.GreatGrandchild(pathalogical: pathalogical) - } - let greatGrandchild: Child.Grandchild.GreatGrandchild = __safeDI_greatGrandchild() - let pathalogical = Child.Grandchild.Pathalogical() - return Child.Grandchild(greatGrandchild: greatGrandchild, pathalogical: pathalogical) - } - let grandchild: Child.Grandchild = __safeDI_grandchild() - return Child(grandchild: grandchild) - } - let child: Child = __safeDI_child() - self.init(child: child) - } - } - """ - ) + // This file was generated by the SafeDIGenerateDependencyTree build tool plugin. + // Any modifications made to this file will be overwritten on subsequent builds. + // Please refrain from editing this file directly. + + #if canImport(Foundation) + import Foundation + #endif + + extension Root { + public convenience init() { + func __safeDI_child() -> Child { + func __safeDI_grandchild() -> Child.Grandchild { + func __safeDI_greatGrandchild() -> Child.Grandchild.GreatGrandchild { + let pathalogical = Child.Grandchild.GreatGrandchild.Pathalogical() + return Child.Grandchild.GreatGrandchild(pathalogical: pathalogical) + } + let greatGrandchild: Child.Grandchild.GreatGrandchild = __safeDI_greatGrandchild() + let pathalogical = Child.Grandchild.Pathalogical() + return Child.Grandchild(greatGrandchild: greatGrandchild, pathalogical: pathalogical) + } + let grandchild: Child.Grandchild = __safeDI_grandchild() + return Child(grandchild: grandchild) + } + let child: Child = __safeDI_child() + self.init(child: child) + } + } + """) } @Test @@ -5022,35 +4965,34 @@ struct SafeDIToolCodeGenerationTests: ~Copyable { """, ], buildDependencyTreeOutput: true, - filesToDelete: &filesToDelete + filesToDelete: &filesToDelete, ) #expect(try #require(output.dependencyTree) == """ - // This file was generated by the SafeDIGenerateDependencyTree build tool plugin. - // Any modifications made to this file will be overwritten on subsequent builds. - // Please refrain from editing this file directly. - - #if canImport(Foundation) - import Foundation - #endif - - extension Root { - public convenience init() { - func __safeDI_child() -> Child { - let pathalogical = Child.Grandchild.Pathalogical() - func __safeDI_grandchild() -> Child.Grandchild { - let greatGrandchild = Child.Grandchild.GreatGrandchild(pathalogical: pathalogical) - return Child.Grandchild(greatGrandchild: greatGrandchild, pathalogical: pathalogical) - } - let grandchild: Child.Grandchild = __safeDI_grandchild() - return Child(pathalogical: pathalogical, grandchild: grandchild) - } - let child: Child = __safeDI_child() - self.init(child: child) - } - } - """ - ) + // This file was generated by the SafeDIGenerateDependencyTree build tool plugin. + // Any modifications made to this file will be overwritten on subsequent builds. + // Please refrain from editing this file directly. + + #if canImport(Foundation) + import Foundation + #endif + + extension Root { + public convenience init() { + func __safeDI_child() -> Child { + let pathalogical = Child.Grandchild.Pathalogical() + func __safeDI_grandchild() -> Child.Grandchild { + let greatGrandchild = Child.Grandchild.GreatGrandchild(pathalogical: pathalogical) + return Child.Grandchild(greatGrandchild: greatGrandchild, pathalogical: pathalogical) + } + let grandchild: Child.Grandchild = __safeDI_grandchild() + return Child(pathalogical: pathalogical, grandchild: grandchild) + } + let child: Child = __safeDI_child() + self.init(child: child) + } + } + """) } @Test @@ -5088,30 +5030,29 @@ struct SafeDIToolCodeGenerationTests: ~Copyable { """, ], buildDependencyTreeOutput: true, - filesToDelete: &filesToDelete + filesToDelete: &filesToDelete, ) #expect(try #require(output.dependencyTree) == """ - // This file was generated by the SafeDIGenerateDependencyTree build tool plugin. - // Any modifications made to this file will be overwritten on subsequent builds. - // Please refrain from editing this file directly. - - #if canImport(Foundation) - import Foundation - #endif - - extension Root { - public convenience init() { - func __safeDI_child() -> Child { - let inner: Inner = Child.DefaultInner() - return Child(inner: inner) - } - let child: Child = __safeDI_child() - self.init(child: child) - } - } - """ - ) + // This file was generated by the SafeDIGenerateDependencyTree build tool plugin. + // Any modifications made to this file will be overwritten on subsequent builds. + // Please refrain from editing this file directly. + + #if canImport(Foundation) + import Foundation + #endif + + extension Root { + public convenience init() { + func __safeDI_child() -> Child { + let inner: Inner = Child.DefaultInner() + return Child(inner: inner) + } + let child: Child = __safeDI_child() + self.init(child: child) + } + } + """) } @Test @@ -5149,30 +5090,29 @@ struct SafeDIToolCodeGenerationTests: ~Copyable { """, ], buildDependencyTreeOutput: true, - filesToDelete: &filesToDelete + filesToDelete: &filesToDelete, ) #expect(try #require(output.dependencyTree) == """ - // This file was generated by the SafeDIGenerateDependencyTree build tool plugin. - // Any modifications made to this file will be overwritten on subsequent builds. - // Please refrain from editing this file directly. - - #if canImport(Foundation) - import Foundation - #endif - - extension Root { - public convenience init() { - func __safeDI_child() -> Child { - let inner: Child.Inner = Child.DefaultInner() - return Child(inner: inner) - } - let child: Child = __safeDI_child() - self.init(child: child) - } - } - """ - ) + // This file was generated by the SafeDIGenerateDependencyTree build tool plugin. + // Any modifications made to this file will be overwritten on subsequent builds. + // Please refrain from editing this file directly. + + #if canImport(Foundation) + import Foundation + #endif + + extension Root { + public convenience init() { + func __safeDI_child() -> Child { + let inner: Child.Inner = Child.DefaultInner() + return Child(inner: inner) + } + let child: Child = __safeDI_child() + self.init(child: child) + } + } + """) } @Test @@ -5201,22 +5141,21 @@ struct SafeDIToolCodeGenerationTests: ~Copyable { """, ], buildDependencyTreeOutput: true, - filesToDelete: &filesToDelete + filesToDelete: &filesToDelete, ) #expect(try #require(output.dependencyTree) == """ - // This file was generated by the SafeDIGenerateDependencyTree build tool plugin. - // Any modifications made to this file will be overwritten on subsequent builds. - // Please refrain from editing this file directly. - - extension TypeWithDependency { - public convenience init() { - let erasedType: ErasedType = EnclosingType.SomeType() - self.init(erasedType: erasedType) - } - } - """ - ) + // This file was generated by the SafeDIGenerateDependencyTree build tool plugin. + // Any modifications made to this file will be overwritten on subsequent builds. + // Please refrain from editing this file directly. + + extension TypeWithDependency { + public convenience init() { + let erasedType: ErasedType = EnclosingType.SomeType() + self.init(erasedType: erasedType) + } + } + """) } @Test @@ -5253,22 +5192,21 @@ struct SafeDIToolCodeGenerationTests: ~Copyable { """, ], buildDependencyTreeOutput: true, - filesToDelete: &filesToDelete + filesToDelete: &filesToDelete, ) #expect(try #require(output.dependencyTree) == """ - // This file was generated by the SafeDIGenerateDependencyTree build tool plugin. - // Any modifications made to this file will be overwritten on subsequent builds. - // Please refrain from editing this file directly. - - extension TypeWithDependency { - public convenience init() { - let erasedType: ErasedType = EnclosingType.SomeType() - self.init(erasedType: erasedType) - } - } - """ - ) + // This file was generated by the SafeDIGenerateDependencyTree build tool plugin. + // Any modifications made to this file will be overwritten on subsequent builds. + // Please refrain from editing this file directly. + + extension TypeWithDependency { + public convenience init() { + let erasedType: ErasedType = EnclosingType.SomeType() + self.init(erasedType: erasedType) + } + } + """) } @Test @@ -5306,23 +5244,22 @@ struct SafeDIToolCodeGenerationTests: ~Copyable { """, ], buildDependencyTreeOutput: true, - filesToDelete: &filesToDelete + filesToDelete: &filesToDelete, ) #expect(try #require(output.dependencyTree) == """ - // This file was generated by the SafeDIGenerateDependencyTree build tool plugin. - // Any modifications made to this file will be overwritten on subsequent builds. - // Please refrain from editing this file directly. - - extension Root { - public convenience init() { - let a = A() - let b = B(a: a) - self.init(a: a, b: b) - } - } - """ - ) + // This file was generated by the SafeDIGenerateDependencyTree build tool plugin. + // Any modifications made to this file will be overwritten on subsequent builds. + // Please refrain from editing this file directly. + + extension Root { + public convenience init() { + let a = A() + let b = B(a: a) + self.init(a: a, b: b) + } + } + """) } @Test @@ -5360,23 +5297,22 @@ struct SafeDIToolCodeGenerationTests: ~Copyable { """, ], buildDependencyTreeOutput: true, - filesToDelete: &filesToDelete + filesToDelete: &filesToDelete, ) #expect(try #require(output.dependencyTree) == """ - // This file was generated by the SafeDIGenerateDependencyTree build tool plugin. - // Any modifications made to this file will be overwritten on subsequent builds. - // Please refrain from editing this file directly. - - extension Root { - public convenience init() { - let a: A? = A() - let b = B(a: a) - self.init(a: a, b: b) - } - } - """ - ) + // This file was generated by the SafeDIGenerateDependencyTree build tool plugin. + // Any modifications made to this file will be overwritten on subsequent builds. + // Please refrain from editing this file directly. + + extension Root { + public convenience init() { + let a: A? = A() + let b = B(a: a) + self.init(a: a, b: b) + } + } + """) } @Test @@ -5413,22 +5349,21 @@ struct SafeDIToolCodeGenerationTests: ~Copyable { """, ], buildDependencyTreeOutput: true, - filesToDelete: &filesToDelete + filesToDelete: &filesToDelete, ) #expect(try #require(output.dependencyTree) == """ - // This file was generated by the SafeDIGenerateDependencyTree build tool plugin. - // Any modifications made to this file will be overwritten on subsequent builds. - // Please refrain from editing this file directly. - - extension Root { - public convenience init() { - let b = B(a: nil) - self.init(b: b) - } - } - """ - ) + // This file was generated by the SafeDIGenerateDependencyTree build tool plugin. + // Any modifications made to this file will be overwritten on subsequent builds. + // Please refrain from editing this file directly. + + extension Root { + public convenience init() { + let b = B(a: nil) + self.init(b: b) + } + } + """) } @Test @@ -5476,27 +5411,26 @@ struct SafeDIToolCodeGenerationTests: ~Copyable { """, ], buildDependencyTreeOutput: true, - filesToDelete: &filesToDelete + filesToDelete: &filesToDelete, ) #expect(try #require(output.dependencyTree) == """ - // This file was generated by the SafeDIGenerateDependencyTree build tool plugin. - // Any modifications made to this file will be overwritten on subsequent builds. - // Please refrain from editing this file directly. - - extension Root { - public convenience init() { - func __safeDI_aBuilder() -> A { - let c = C() - let b = B(c: c) - return A(b: b, c: c) - } - let aBuilder = Instantiator(__safeDI_aBuilder) - self.init(aBuilder: aBuilder) - } - } - """ - ) + // This file was generated by the SafeDIGenerateDependencyTree build tool plugin. + // Any modifications made to this file will be overwritten on subsequent builds. + // Please refrain from editing this file directly. + + extension Root { + public convenience init() { + func __safeDI_aBuilder() -> A { + let c = C() + let b = B(c: c) + return A(b: b, c: c) + } + let aBuilder = Instantiator(__safeDI_aBuilder) + self.init(aBuilder: aBuilder) + } + } + """) } @Test @@ -5555,35 +5489,34 @@ struct SafeDIToolCodeGenerationTests: ~Copyable { """, ], buildDependencyTreeOutput: true, - filesToDelete: &filesToDelete + filesToDelete: &filesToDelete, ) #expect(try #require(output.dependencyTree) == """ - // This file was generated by the SafeDIGenerateDependencyTree build tool plugin. - // Any modifications made to this file will be overwritten on subsequent builds. - // Please refrain from editing this file directly. - - extension Root { - public convenience init() { - func __safeDI_aBuilder() -> A { - let c = C() - func __safeDI_d() -> D { - let b = B(c: c) - return D(b: b) - } - let d: D = __safeDI_d() - return A(c: c, d: d) - } - let aBuilder = Instantiator(__safeDI_aBuilder) - func __safeDI_bBuilder() -> B { - B(c: nil) - } - let bBuilder = Instantiator(__safeDI_bBuilder) - self.init(aBuilder: aBuilder, bBuilder: bBuilder) - } - } - """ - ) + // This file was generated by the SafeDIGenerateDependencyTree build tool plugin. + // Any modifications made to this file will be overwritten on subsequent builds. + // Please refrain from editing this file directly. + + extension Root { + public convenience init() { + func __safeDI_aBuilder() -> A { + let c = C() + func __safeDI_d() -> D { + let b = B(c: c) + return D(b: b) + } + let d: D = __safeDI_d() + return A(c: c, d: d) + } + let aBuilder = Instantiator(__safeDI_aBuilder) + func __safeDI_bBuilder() -> B { + B(c: nil) + } + let bBuilder = Instantiator(__safeDI_bBuilder) + self.init(aBuilder: aBuilder, bBuilder: bBuilder) + } + } + """) } @Test @@ -5632,30 +5565,29 @@ struct SafeDIToolCodeGenerationTests: ~Copyable { """, ], buildDependencyTreeOutput: true, - filesToDelete: &filesToDelete + filesToDelete: &filesToDelete, ) #expect(try #require(output.dependencyTree) == """ - // This file was generated by the SafeDIGenerateDependencyTree build tool plugin. - // Any modifications made to this file will be overwritten on subsequent builds. - // Please refrain from editing this file directly. - - extension Root { - public convenience init() { - func __safeDI_aBuilder() -> A { - func __safeDI_c() -> C { - let b = B(c: nil) - return C(b: b) - } - let c: C = __safeDI_c() - return A(c: c) - } - let aBuilder = Instantiator(__safeDI_aBuilder) - self.init(aBuilder: aBuilder) - } - } - """ - ) + // This file was generated by the SafeDIGenerateDependencyTree build tool plugin. + // Any modifications made to this file will be overwritten on subsequent builds. + // Please refrain from editing this file directly. + + extension Root { + public convenience init() { + func __safeDI_aBuilder() -> A { + func __safeDI_c() -> C { + let b = B(c: nil) + return C(b: b) + } + let c: C = __safeDI_c() + return A(c: c) + } + let aBuilder = Instantiator(__safeDI_aBuilder) + self.init(aBuilder: aBuilder) + } + } + """) } @Test @@ -5692,26 +5624,25 @@ struct SafeDIToolCodeGenerationTests: ~Copyable { """, ], buildDependencyTreeOutput: true, - filesToDelete: &filesToDelete + filesToDelete: &filesToDelete, ) #expect(try #require(output.dependencyTree) == """ - // This file was generated by the SafeDIGenerateDependencyTree build tool plugin. - // Any modifications made to this file will be overwritten on subsequent builds. - // Please refrain from editing this file directly. - - extension Root { - public convenience init() { - func __safeDI_b() -> B { - // Did not create `aRenamed: ARenamed?` because `a: A` is unavailable. - return B(aRenamed: nil) - } - let b: B = __safeDI_b() - self.init(b: b) - } - } - """ - ) + // This file was generated by the SafeDIGenerateDependencyTree build tool plugin. + // Any modifications made to this file will be overwritten on subsequent builds. + // Please refrain from editing this file directly. + + extension Root { + public convenience init() { + func __safeDI_b() -> B { + // Did not create `aRenamed: ARenamed?` because `a: A` is unavailable. + return B(aRenamed: nil) + } + let b: B = __safeDI_b() + self.init(b: b) + } + } + """) } @Test @@ -5759,31 +5690,30 @@ struct SafeDIToolCodeGenerationTests: ~Copyable { """, ], buildDependencyTreeOutput: true, - filesToDelete: &filesToDelete + filesToDelete: &filesToDelete, ) #expect(try #require(output.dependencyTree) == """ - // This file was generated by the SafeDIGenerateDependencyTree build tool plugin. - // Any modifications made to this file will be overwritten on subsequent builds. - // Please refrain from editing this file directly. - - extension Root { - public convenience init() { - func __safeDI_aBuilder() -> A { - let c = C() - func __safeDI_b() -> B { - let cRenamed: CRenamed? = c - return B(cRenamed: cRenamed) - } - let b: B = __safeDI_b() - return A(b: b, c: c) - } - let aBuilder = Instantiator(__safeDI_aBuilder) - self.init(aBuilder: aBuilder) - } - } - """ - ) + // This file was generated by the SafeDIGenerateDependencyTree build tool plugin. + // Any modifications made to this file will be overwritten on subsequent builds. + // Please refrain from editing this file directly. + + extension Root { + public convenience init() { + func __safeDI_aBuilder() -> A { + let c = C() + func __safeDI_b() -> B { + let cRenamed: CRenamed? = c + return B(cRenamed: cRenamed) + } + let b: B = __safeDI_b() + return A(b: b, c: c) + } + let aBuilder = Instantiator(__safeDI_aBuilder) + self.init(aBuilder: aBuilder) + } + } + """) } @Test @@ -5842,40 +5772,39 @@ struct SafeDIToolCodeGenerationTests: ~Copyable { """, ], buildDependencyTreeOutput: true, - filesToDelete: &filesToDelete + filesToDelete: &filesToDelete, ) #expect(try #require(output.dependencyTree) == """ - // This file was generated by the SafeDIGenerateDependencyTree build tool plugin. - // Any modifications made to this file will be overwritten on subsequent builds. - // Please refrain from editing this file directly. - - extension Root { - public convenience init() { - func __safeDI_aBuilder() -> A { - let c = C() - func __safeDI_d() -> D { - func __safeDI_b() -> B { - let cRenamed: CRenamed? = c - return B(cRenamed: cRenamed) - } - let b: B = __safeDI_b() - return D(b: b) - } - let d: D = __safeDI_d() - return A(c: c, d: d) - } - let aBuilder = Instantiator(__safeDI_aBuilder) - func __safeDI_bBuilder() -> B { - // Did not create `cRenamed: CRenamed?` because `c: C` is unavailable. - return B(cRenamed: nil) - } - let bBuilder = Instantiator(__safeDI_bBuilder) - self.init(aBuilder: aBuilder, bBuilder: bBuilder) - } - } - """ - ) + // This file was generated by the SafeDIGenerateDependencyTree build tool plugin. + // Any modifications made to this file will be overwritten on subsequent builds. + // Please refrain from editing this file directly. + + extension Root { + public convenience init() { + func __safeDI_aBuilder() -> A { + let c = C() + func __safeDI_d() -> D { + func __safeDI_b() -> B { + let cRenamed: CRenamed? = c + return B(cRenamed: cRenamed) + } + let b: B = __safeDI_b() + return D(b: b) + } + let d: D = __safeDI_d() + return A(c: c, d: d) + } + let aBuilder = Instantiator(__safeDI_aBuilder) + func __safeDI_bBuilder() -> B { + // Did not create `cRenamed: CRenamed?` because `c: C` is unavailable. + return B(cRenamed: nil) + } + let bBuilder = Instantiator(__safeDI_bBuilder) + self.init(aBuilder: aBuilder, bBuilder: bBuilder) + } + } + """) } @Test @@ -5904,20 +5833,19 @@ struct SafeDIToolCodeGenerationTests: ~Copyable { """, ], buildDependencyTreeOutput: true, - filesToDelete: &filesToDelete + filesToDelete: &filesToDelete, ) #expect(try #require(output.dependencyTree) == """ - // This file was generated by the SafeDIGenerateDependencyTree build tool plugin. - // Any modifications made to this file will be overwritten on subsequent builds. - // Please refrain from editing this file directly. - - #error(\""" - Compiler errors prevented the generation of the dependency tree. Files with errors: - \(try #require(output.moduleInfo.filesWithUnexpectedNodes).joined(separator: "\n\t")) - \""") - """ - ) + // This file was generated by the SafeDIGenerateDependencyTree build tool plugin. + // Any modifications made to this file will be overwritten on subsequent builds. + // Please refrain from editing this file directly. + + #error(\""" + Compiler errors prevented the generation of the dependency tree. Files with errors: + \(try #require(output.moduleInfo.filesWithUnexpectedNodes).joined(separator: "\n\t")) + \""") + """) } @Test @@ -5965,30 +5893,29 @@ struct SafeDIToolCodeGenerationTests: ~Copyable { """, ], buildDependencyTreeOutput: true, - filesToDelete: &filesToDelete + filesToDelete: &filesToDelete, ) #expect(try #require(output.dependencyTree) == """ - // This file was generated by the SafeDIGenerateDependencyTree build tool plugin. - // Any modifications made to this file will be overwritten on subsequent builds. - // Please refrain from editing this file directly. - - extension Root { - public convenience init() { - let service = Service() - func __safeDI_childVCBuilder() -> ChildVC { - func __safeDI_grandchildVCBuilder() -> GrandchildVC { - GrandchildVC(service: service) - } - let grandchildVCBuilder = Instantiator(__safeDI_grandchildVCBuilder) - return ChildVC(grandchildVCBuilder: grandchildVCBuilder) - } - let childVCBuilder = Instantiator(__safeDI_childVCBuilder) - self.init(childVCBuilder: childVCBuilder, service: service) - } - } - """ - ) + // This file was generated by the SafeDIGenerateDependencyTree build tool plugin. + // Any modifications made to this file will be overwritten on subsequent builds. + // Please refrain from editing this file directly. + + extension Root { + public convenience init() { + let service = Service() + func __safeDI_childVCBuilder() -> ChildVC { + func __safeDI_grandchildVCBuilder() -> GrandchildVC { + GrandchildVC(service: service) + } + let grandchildVCBuilder = Instantiator(__safeDI_grandchildVCBuilder) + return ChildVC(grandchildVCBuilder: grandchildVCBuilder) + } + let childVCBuilder = Instantiator(__safeDI_childVCBuilder) + self.init(childVCBuilder: childVCBuilder, service: service) + } + } + """) } @Test @@ -6010,21 +5937,20 @@ struct SafeDIToolCodeGenerationTests: ~Copyable { """, ], buildDependencyTreeOutput: true, - filesToDelete: &filesToDelete + filesToDelete: &filesToDelete, ) #expect(try #require(output.dependencyTree) == """ - // This file was generated by the SafeDIGenerateDependencyTree build tool plugin. - // Any modifications made to this file will be overwritten on subsequent builds. - // Please refrain from editing this file directly. + // This file was generated by the SafeDIGenerateDependencyTree build tool plugin. + // Any modifications made to this file will be overwritten on subsequent builds. + // Please refrain from editing this file directly. - #if canImport(Test) - import Test - #endif + #if canImport(Test) + import Test + #endif - // No root @Instantiable-decorated types found, or root types already had a `public init()` method. - """ - ) + // No root @Instantiable-decorated types found, or root types already had a `public init()` method. + """) } @Test @@ -6039,13 +5965,13 @@ struct SafeDIToolCodeGenerationTests: ~Copyable { } """, ], - filesToDelete: &filesToDelete + filesToDelete: &filesToDelete, ) #expect(output.moduleInfo.configurations == [ SafeDIConfiguration( additionalImportedModules: [], - additionalDirectoriesToInclude: ["SomeDirectory"] + additionalDirectoriesToInclude: ["SomeDirectory"], ), ]) } diff --git a/Tests/SafeDIToolTests/SafeDIToolDOTGenerationTests.swift b/Tests/SafeDIToolTests/SafeDIToolDOTGenerationTests.swift index 30794509..580cdbda 100644 --- a/Tests/SafeDIToolTests/SafeDIToolDOTGenerationTests.swift +++ b/Tests/SafeDIToolTests/SafeDIToolDOTGenerationTests.swift @@ -21,7 +21,6 @@ import Foundation import SafeDICore import Testing - @testable import SafeDITool struct SafeDIToolDOTGenerationTests: ~Copyable { @@ -44,16 +43,15 @@ struct SafeDIToolDOTGenerationTests: ~Copyable { let output = try await executeSafeDIToolTest( swiftFileContent: [], buildDOTFileOutput: true, - filesToDelete: &filesToDelete + filesToDelete: &filesToDelete, ) #expect(try #require(output.dotTree) == """ - graph SafeDI { - ranksep=2 + graph SafeDI { + ranksep=2 - } - """ - ) + } + """) } @Test @@ -78,16 +76,15 @@ struct SafeDIToolDOTGenerationTests: ~Copyable { """, ], buildDOTFileOutput: true, - filesToDelete: &filesToDelete + filesToDelete: &filesToDelete, ) #expect(try #require(output.dotTree) == """ - graph SafeDI { - ranksep=2 - RootViewController -- "networkService: NetworkService" - } - """ - ) + graph SafeDI { + ranksep=2 + RootViewController -- "networkService: NetworkService" + } + """) } @Test @@ -118,18 +115,17 @@ struct SafeDIToolDOTGenerationTests: ~Copyable { """, ], buildDOTFileOutput: true, - filesToDelete: &filesToDelete + filesToDelete: &filesToDelete, ) #expect(try #require(output.dotTree) == """ - graph SafeDI { - ranksep=2 - Root1 -- "networkService: NetworkService" + graph SafeDI { + ranksep=2 + Root1 -- "networkService: NetworkService" - Root2 -- "networkService: NetworkService" - } - """ - ) + Root2 -- "networkService: NetworkService" + } + """) } @Test @@ -201,19 +197,18 @@ struct SafeDIToolDOTGenerationTests: ~Copyable { """, ], buildDOTFileOutput: true, - filesToDelete: &filesToDelete + filesToDelete: &filesToDelete, ) #expect(try #require(output.dotTree) == """ - graph SafeDI { - ranksep=2 - RootViewController -- "networkService: NetworkService" - RootViewController -- "authService: AuthService" - RootViewController -- "loggedInViewControllerBuilder: ErasedInstantiator" - "loggedInViewControllerBuilder: ErasedInstantiator" -- "user: User" - } - """ - ) + graph SafeDI { + ranksep=2 + RootViewController -- "networkService: NetworkService" + RootViewController -- "authService: AuthService" + RootViewController -- "loggedInViewControllerBuilder: ErasedInstantiator" + "loggedInViewControllerBuilder: ErasedInstantiator" -- "user: User" + } + """) } @Test @@ -293,20 +288,19 @@ struct SafeDIToolDOTGenerationTests: ~Copyable { """, ], buildDOTFileOutput: true, - filesToDelete: &filesToDelete + filesToDelete: &filesToDelete, ) #expect(try #require(output.dotTree) == """ - graph SafeDI { - ranksep=2 - RootViewController -- "networkService: NetworkService" - RootViewController -- "authService: AuthService" - RootViewController -- "loggedInViewControllerBuilder: Instantiator" - "loggedInViewControllerBuilder: Instantiator" -- "userService: UserService" - "loggedInViewControllerBuilder: Instantiator" -- "user: User" - } - """ - ) + graph SafeDI { + ranksep=2 + RootViewController -- "networkService: NetworkService" + RootViewController -- "authService: AuthService" + RootViewController -- "loggedInViewControllerBuilder: Instantiator" + "loggedInViewControllerBuilder: Instantiator" -- "userService: UserService" + "loggedInViewControllerBuilder: Instantiator" -- "user: User" + } + """) } @Test @@ -393,21 +387,20 @@ struct SafeDIToolDOTGenerationTests: ~Copyable { """, ], buildDOTFileOutput: true, - filesToDelete: &filesToDelete + filesToDelete: &filesToDelete, ) #expect(try #require(output.dotTree) == """ - graph SafeDI { - ranksep=2 - RootViewController -- "networkService: NetworkService" - RootViewController -- "authService: AuthService" - RootViewController -- "loggedInViewControllerBuilder: ErasedInstantiator<(userID: String, userName: String), UIViewController>" - "loggedInViewControllerBuilder: ErasedInstantiator<(userID: String, userName: String), UIViewController>" -- "userService: UserService" - "loggedInViewControllerBuilder: ErasedInstantiator<(userID: String, userName: String), UIViewController>" -- "userID: String" - "loggedInViewControllerBuilder: ErasedInstantiator<(userID: String, userName: String), UIViewController>" -- "userName: String" - } - """ - ) + graph SafeDI { + ranksep=2 + RootViewController -- "networkService: NetworkService" + RootViewController -- "authService: AuthService" + RootViewController -- "loggedInViewControllerBuilder: ErasedInstantiator<(userID: String, userName: String), UIViewController>" + "loggedInViewControllerBuilder: ErasedInstantiator<(userID: String, userName: String), UIViewController>" -- "userService: UserService" + "loggedInViewControllerBuilder: ErasedInstantiator<(userID: String, userName: String), UIViewController>" -- "userID: String" + "loggedInViewControllerBuilder: ErasedInstantiator<(userID: String, userName: String), UIViewController>" -- "userName: String" + } + """) } @Test @@ -494,21 +487,20 @@ struct SafeDIToolDOTGenerationTests: ~Copyable { """, ], buildDOTFileOutput: true, - filesToDelete: &filesToDelete + filesToDelete: &filesToDelete, ) #expect(try #require(output.dotTree) == """ - graph SafeDI { - ranksep=2 - RootViewController -- "networkService: NetworkService" - RootViewController -- "authService: AuthService" - RootViewController -- "loggedInViewControllerBuilder: ErasedInstantiator" - "loggedInViewControllerBuilder: ErasedInstantiator" -- "userService: UserService" - "loggedInViewControllerBuilder: ErasedInstantiator" -- "userID: String" - "loggedInViewControllerBuilder: ErasedInstantiator" -- "userName: String" - } - """ - ) + graph SafeDI { + ranksep=2 + RootViewController -- "networkService: NetworkService" + RootViewController -- "authService: AuthService" + RootViewController -- "loggedInViewControllerBuilder: ErasedInstantiator" + "loggedInViewControllerBuilder: ErasedInstantiator" -- "userService: UserService" + "loggedInViewControllerBuilder: ErasedInstantiator" -- "userID: String" + "loggedInViewControllerBuilder: ErasedInstantiator" -- "userName: String" + } + """) } @Test @@ -589,20 +581,19 @@ struct SafeDIToolDOTGenerationTests: ~Copyable { """, ], buildDOTFileOutput: true, - filesToDelete: &filesToDelete + filesToDelete: &filesToDelete, ) #expect(try #require(output.dotTree) == """ - graph SafeDI { - ranksep=2 - RootViewController -- "networkService: NetworkService" - RootViewController -- "authService: AuthService" - RootViewController -- "loggedInViewControllerBuilder: Instantiator" - "loggedInViewControllerBuilder: Instantiator" -- "userService: UserService" - "loggedInViewControllerBuilder: Instantiator" -- "user: User" - } - """ - ) + graph SafeDI { + ranksep=2 + RootViewController -- "networkService: NetworkService" + RootViewController -- "authService: AuthService" + RootViewController -- "loggedInViewControllerBuilder: Instantiator" + "loggedInViewControllerBuilder: Instantiator" -- "userService: UserService" + "loggedInViewControllerBuilder: Instantiator" -- "user: User" + } + """) } @Test @@ -683,20 +674,19 @@ struct SafeDIToolDOTGenerationTests: ~Copyable { """, ], buildDOTFileOutput: true, - filesToDelete: &filesToDelete + filesToDelete: &filesToDelete, ) #expect(try #require(output.dotTree) == """ - graph SafeDI { - ranksep=2 - RootViewController -- "networkService: NetworkService" - RootViewController -- "authService: AuthService" - RootViewController -- "loggedInViewControllerBuilder: Instantiator" - "loggedInViewControllerBuilder: Instantiator" -- "userServiceInstantiator: Instantiator" - "loggedInViewControllerBuilder: Instantiator" -- "user: User" - } - """ - ) + graph SafeDI { + ranksep=2 + RootViewController -- "networkService: NetworkService" + RootViewController -- "authService: AuthService" + RootViewController -- "loggedInViewControllerBuilder: Instantiator" + "loggedInViewControllerBuilder: Instantiator" -- "userServiceInstantiator: Instantiator" + "loggedInViewControllerBuilder: Instantiator" -- "user: User" + } + """) } @Test @@ -756,22 +746,21 @@ struct SafeDIToolDOTGenerationTests: ~Copyable { ], buildDOTFileOutput: true, - filesToDelete: &filesToDelete + filesToDelete: &filesToDelete, ) #expect(try #require(output.dotTree) == """ - graph SafeDI { - ranksep=2 - Root -- "greatGrandchild: GreatGrandchild" - Root -- "childA: ChildA" - Root -- "childB: ChildB" - "childA: ChildA" -- "grandchildAA: GrandchildAA" - "childA: ChildA" -- "grandchildAB: GrandchildAB" - "childB: ChildB" -- "grandchildBA: GrandchildBA" - "childB: ChildB" -- "grandchildBB: GrandchildBB" - } - """ - ) + graph SafeDI { + ranksep=2 + Root -- "greatGrandchild: GreatGrandchild" + Root -- "childA: ChildA" + Root -- "childB: ChildB" + "childA: ChildA" -- "grandchildAA: GrandchildAA" + "childA: ChildA" -- "grandchildAB: GrandchildAB" + "childB: ChildB" -- "grandchildBA: GrandchildBA" + "childB: ChildB" -- "grandchildBB: GrandchildBB" + } + """) } @Test @@ -832,23 +821,22 @@ struct SafeDIToolDOTGenerationTests: ~Copyable { ], buildDOTFileOutput: true, - filesToDelete: &filesToDelete + filesToDelete: &filesToDelete, ) #expect(try #require(output.dotTree) == """ - graph SafeDI { - ranksep=2 - Root -- "childA: ChildA" - Root -- "childB: ChildB" - "childA: ChildA" -- "greatGrandchild: GreatGrandchild" - "childA: ChildA" -- "grandchildAA: GrandchildAA" - "childA: ChildA" -- "grandchildAB: GrandchildAB" - "childB: ChildB" -- "greatGrandchild: GreatGrandchild" - "childB: ChildB" -- "grandchildBA: GrandchildBA" - "childB: ChildB" -- "grandchildBB: GrandchildBB" - } - """ - ) + graph SafeDI { + ranksep=2 + Root -- "childA: ChildA" + Root -- "childB: ChildB" + "childA: ChildA" -- "greatGrandchild: GreatGrandchild" + "childA: ChildA" -- "grandchildAA: GrandchildAA" + "childA: ChildA" -- "grandchildAB: GrandchildAB" + "childB: ChildB" -- "greatGrandchild: GreatGrandchild" + "childB: ChildB" -- "grandchildBA: GrandchildBA" + "childB: ChildB" -- "grandchildBB: GrandchildBB" + } + """) } @Test @@ -888,20 +876,19 @@ struct SafeDIToolDOTGenerationTests: ~Copyable { ], buildDOTFileOutput: true, - filesToDelete: &filesToDelete + filesToDelete: &filesToDelete, ) #expect(try #require(output.dotTree) == """ - graph SafeDI { - ranksep=2 - Root -- "child: Child" - "child: Child" -- "grandchild: Grandchild" - "child: Child" -- "recreated: Recreated" - "grandchild: Grandchild" -- "recreated: Recreated" - "grandchild: Grandchild" -- "greatGrandchild: GreatGrandchild" - } - """ - ) + graph SafeDI { + ranksep=2 + Root -- "child: Child" + "child: Child" -- "grandchild: Grandchild" + "child: Child" -- "recreated: Recreated" + "grandchild: Grandchild" -- "recreated: Recreated" + "grandchild: Grandchild" -- "greatGrandchild: GreatGrandchild" + } + """) } @Test @@ -960,25 +947,24 @@ struct SafeDIToolDOTGenerationTests: ~Copyable { ], buildDOTFileOutput: true, - filesToDelete: &filesToDelete + filesToDelete: &filesToDelete, ) #expect(try #require(output.dotTree) == """ - graph SafeDI { - ranksep=2 - Root -- "childA: ChildA" - Root -- "childB: ChildB" - "childA: ChildA" -- "grandchildAA: GrandchildAA" - "childA: ChildA" -- "grandchildAB: GrandchildAB" - "grandchildAA: GrandchildAA" -- "greatGrandchild: GreatGrandchild" - "grandchildAB: GrandchildAB" -- "greatGrandchild: GreatGrandchild" - "childB: ChildB" -- "grandchildBA: GrandchildBA" - "childB: ChildB" -- "grandchildBB: GrandchildBB" - "grandchildBA: GrandchildBA" -- "greatGrandchild: GreatGrandchild" - "grandchildBB: GrandchildBB" -- "greatGrandchild: GreatGrandchild" - } - """ - ) + graph SafeDI { + ranksep=2 + Root -- "childA: ChildA" + Root -- "childB: ChildB" + "childA: ChildA" -- "grandchildAA: GrandchildAA" + "childA: ChildA" -- "grandchildAB: GrandchildAB" + "grandchildAA: GrandchildAA" -- "greatGrandchild: GreatGrandchild" + "grandchildAB: GrandchildAB" -- "greatGrandchild: GreatGrandchild" + "childB: ChildB" -- "grandchildBA: GrandchildBA" + "childB: ChildB" -- "grandchildBB: GrandchildBB" + "grandchildBA: GrandchildBA" -- "greatGrandchild: GreatGrandchild" + "grandchildBB: GrandchildBB" -- "greatGrandchild: GreatGrandchild" + } + """) } @Test @@ -991,7 +977,7 @@ struct SafeDIToolDOTGenerationTests: ~Copyable { """, ], buildDOTFileOutput: false, - filesToDelete: &filesToDelete + filesToDelete: &filesToDelete, ) let grandchildModuleOutput = try await executeSafeDIToolTest( @@ -1031,7 +1017,7 @@ struct SafeDIToolDOTGenerationTests: ~Copyable { ], dependentModuleInfoPaths: [greatGrandchildModuleOutput.moduleInfoOutputPath], buildDOTFileOutput: false, - filesToDelete: &filesToDelete + filesToDelete: &filesToDelete, ) let childModuleOutput = try await executeSafeDIToolTest( @@ -1062,7 +1048,7 @@ struct SafeDIToolDOTGenerationTests: ~Copyable { grandchildModuleOutput.moduleInfoOutputPath, ], buildDOTFileOutput: false, - filesToDelete: &filesToDelete + filesToDelete: &filesToDelete, ) let topLevelModuleOutput = try await executeSafeDIToolTest( @@ -1084,25 +1070,24 @@ struct SafeDIToolDOTGenerationTests: ~Copyable { childModuleOutput.moduleInfoOutputPath, ], buildDOTFileOutput: true, - filesToDelete: &filesToDelete + filesToDelete: &filesToDelete, ) #expect(try #require(topLevelModuleOutput.dotTree) == """ - graph SafeDI { - ranksep=2 - Root -- "childA: ChildA" - Root -- "childB: ChildB" - "childA: ChildA" -- "grandchildAA: GrandchildAA" - "childA: ChildA" -- "grandchildAB: GrandchildAB" - "grandchildAA: GrandchildAA" -- "greatGrandchild: GreatGrandchild" - "grandchildAB: GrandchildAB" -- "greatGrandchild: GreatGrandchild" - "childB: ChildB" -- "grandchildBA: GrandchildBA" - "childB: ChildB" -- "grandchildBB: GrandchildBB" - "grandchildBA: GrandchildBA" -- "greatGrandchildInstantiator: SendableInstantiator" - "grandchildBB: GrandchildBB" -- "greatGrandchildInstantiator: SendableInstantiator" - } - """ - ) + graph SafeDI { + ranksep=2 + Root -- "childA: ChildA" + Root -- "childB: ChildB" + "childA: ChildA" -- "grandchildAA: GrandchildAA" + "childA: ChildA" -- "grandchildAB: GrandchildAB" + "grandchildAA: GrandchildAA" -- "greatGrandchild: GreatGrandchild" + "grandchildAB: GrandchildAB" -- "greatGrandchild: GreatGrandchild" + "childB: ChildB" -- "grandchildBA: GrandchildBA" + "childB: ChildB" -- "grandchildBB: GrandchildBB" + "grandchildBA: GrandchildBA" -- "greatGrandchildInstantiator: SendableInstantiator" + "grandchildBB: GrandchildBB" -- "greatGrandchildInstantiator: SendableInstantiator" + } + """) } @Test @@ -1133,17 +1118,16 @@ struct SafeDIToolDOTGenerationTests: ~Copyable { """, ], buildDOTFileOutput: true, - filesToDelete: &filesToDelete + filesToDelete: &filesToDelete, ) #expect(try #require(output.dotTree) == """ - graph SafeDI { - ranksep=2 - Root -- "defaultUserService: DefaultUserService" - Root -- "userService: any UserService <- defaultUserService: DefaultUserService" - } - """ - ) + graph SafeDI { + ranksep=2 + Root -- "defaultUserService: DefaultUserService" + Root -- "userService: any UserService <- defaultUserService: DefaultUserService" + } + """) } @Test @@ -1199,19 +1183,18 @@ struct SafeDIToolDOTGenerationTests: ~Copyable { """, ], buildDOTFileOutput: true, - filesToDelete: &filesToDelete + filesToDelete: &filesToDelete, ) #expect(try #require(output.dotTree) == """ - graph SafeDI { - ranksep=2 - RootViewController -- "networkService: NetworkService" - RootViewController -- "authService: AuthService" - "authService: AuthService" -- "renamedNetworkService: NetworkService <- networkService: NetworkService" - "authService: AuthService" -- "renamedAgainNetworkService: NetworkService <- renamedNetworkService: NetworkService" - } - """ - ) + graph SafeDI { + ranksep=2 + RootViewController -- "networkService: NetworkService" + RootViewController -- "authService: AuthService" + "authService: AuthService" -- "renamedNetworkService: NetworkService <- networkService: NetworkService" + "authService: AuthService" -- "renamedAgainNetworkService: NetworkService <- renamedNetworkService: NetworkService" + } + """) } @Test @@ -1247,19 +1230,18 @@ struct SafeDIToolDOTGenerationTests: ~Copyable { """, ], buildDOTFileOutput: true, - filesToDelete: &filesToDelete + filesToDelete: &filesToDelete, ) #expect(try #require(output.dotTree) == """ - graph SafeDI { - ranksep=2 - Root -- "child: Child" - "child: Child" -- "greatGrandchild: GreatGrandchild" - "child: Child" -- "grandchild: Grandchild" - "child: Child" -- "unrelated: Unrelated" - } - """ - ) + graph SafeDI { + ranksep=2 + Root -- "child: Child" + "child: Child" -- "greatGrandchild: GreatGrandchild" + "child: Child" -- "grandchild: Grandchild" + "child: Child" -- "unrelated: Unrelated" + } + """) } @Test @@ -1499,41 +1481,40 @@ struct SafeDIToolDOTGenerationTests: ~Copyable { """, ], buildDOTFileOutput: true, - filesToDelete: &filesToDelete + filesToDelete: &filesToDelete, ) #expect(try #require(output.dotTree) == """ - graph SafeDI { - ranksep=2 - Root -- "x: X" - Root -- "a: A" - Root -- "g: G" - Root -- "e: E" - Root -- "m: M" - Root -- "o: O" - Root -- "d: D" - Root -- "f: F" - Root -- "i: I" - Root -- "p: P" - Root -- "n: N" - Root -- "r: R" - Root -- "t: T" - Root -- "s: S" - Root -- "w: W" - Root -- "u: U" - Root -- "y: Y" - Root -- "b: B" - Root -- "c: C" - Root -- "h: H" - Root -- "j: J" - Root -- "k: K" - Root -- "v: V" - Root -- "l: L" - Root -- "q: Q" - Root -- "z: Z" - } - """ - ) + graph SafeDI { + ranksep=2 + Root -- "x: X" + Root -- "a: A" + Root -- "g: G" + Root -- "e: E" + Root -- "m: M" + Root -- "o: O" + Root -- "d: D" + Root -- "f: F" + Root -- "i: I" + Root -- "p: P" + Root -- "n: N" + Root -- "r: R" + Root -- "t: T" + Root -- "s: S" + Root -- "w: W" + Root -- "u: U" + Root -- "y: Y" + Root -- "b: B" + Root -- "c: C" + Root -- "h: H" + Root -- "j: J" + Root -- "k: K" + Root -- "v: V" + Root -- "l: L" + Root -- "q: Q" + Root -- "z: Z" + } + """) } @Test @@ -1566,19 +1547,18 @@ struct SafeDIToolDOTGenerationTests: ~Copyable { """, ], buildDOTFileOutput: true, - filesToDelete: &filesToDelete + filesToDelete: &filesToDelete, ) #expect(try #require(output.dotTree) == """ - graph SafeDI { - ranksep=2 - Root -- "aBuilder: Instantiator" - "aBuilder: Instantiator" -- "bBuilder: Instantiator" - "bBuilder: Instantiator" -- "cBuilder: Instantiator" - "cBuilder: Instantiator" -- "aBuilder: Instantiator" - } - """ - ) + graph SafeDI { + ranksep=2 + Root -- "aBuilder: Instantiator" + "aBuilder: Instantiator" -- "bBuilder: Instantiator" + "bBuilder: Instantiator" -- "cBuilder: Instantiator" + "cBuilder: Instantiator" -- "aBuilder: Instantiator" + } + """) } @Test @@ -1611,19 +1591,18 @@ struct SafeDIToolDOTGenerationTests: ~Copyable { """, ], buildDOTFileOutput: true, - filesToDelete: &filesToDelete + filesToDelete: &filesToDelete, ) #expect(try #require(output.dotTree) == """ - graph SafeDI { - ranksep=2 - Root -- "a: A" - "a: A" -- "b: B" - "b: B" -- "cBuilder: Instantiator" - "cBuilder: Instantiator" -- "a: A" - } - """ - ) + graph SafeDI { + ranksep=2 + Root -- "a: A" + "a: A" -- "b: B" + "b: B" -- "cBuilder: Instantiator" + "cBuilder: Instantiator" -- "a: A" + } + """) } @Test @@ -1644,18 +1623,17 @@ struct SafeDIToolDOTGenerationTests: ~Copyable { """, ], buildDOTFileOutput: true, - filesToDelete: &filesToDelete + filesToDelete: &filesToDelete, ) #expect(try #require(output.dotTree) == """ - graph SafeDI { - ranksep=2 - Root -- "a: A" - "a: A" -- "aBuilder: Instantiator" - "aBuilder: Instantiator" -- "aBuilder: Instantiator" - } - """ - ) + graph SafeDI { + ranksep=2 + Root -- "a: A" + "a: A" -- "aBuilder: Instantiator" + "aBuilder: Instantiator" -- "aBuilder: Instantiator" + } + """) } @Test @@ -1677,19 +1655,18 @@ struct SafeDIToolDOTGenerationTests: ~Copyable { """, ], buildDOTFileOutput: true, - filesToDelete: &filesToDelete + filesToDelete: &filesToDelete, ) #expect(try #require(output.dotTree) == """ - graph SafeDI { - ranksep=2 - Root -- "aBuilder: Instantiator" - "aBuilder: Instantiator" -- "aBuilder: Instantiator" - "aBuilder: Instantiator" -- "context: String" - "aBuilder: Instantiator" -- "context: String" - } - """ - ) + graph SafeDI { + ranksep=2 + Root -- "aBuilder: Instantiator" + "aBuilder: Instantiator" -- "aBuilder: Instantiator" + "aBuilder: Instantiator" -- "context: String" + "aBuilder: Instantiator" -- "context: String" + } + """) } @Test @@ -1727,19 +1704,18 @@ struct SafeDIToolDOTGenerationTests: ~Copyable { """, ], buildDOTFileOutput: true, - filesToDelete: &filesToDelete + filesToDelete: &filesToDelete, ) #expect(try #require(output.dotTree) == """ - graph SafeDI { - ranksep=2 - Root -- "stringContainer: Container" - Root -- "intContainer: Container" - Root -- "floatContainer: Container" - Root -- "voidContainer: Container" - } - """ - ) + graph SafeDI { + ranksep=2 + Root -- "stringContainer: Container" + Root -- "intContainer: Container" + Root -- "floatContainer: Container" + Root -- "voidContainer: Container" + } + """) } @Test @@ -1777,19 +1753,18 @@ struct SafeDIToolDOTGenerationTests: ~Copyable { """, ], buildDOTFileOutput: true, - filesToDelete: &filesToDelete + filesToDelete: &filesToDelete, ) #expect(try #require(output.dotTree) == """ - graph SafeDI { - ranksep=2 - Root -- "stringContainer: MyModule.Container" - Root -- "intContainer: MyModule.Container" - Root -- "floatContainer: MyModule.Container" - Root -- "voidContainer: MyModule.Container" - } - """ - ) + graph SafeDI { + ranksep=2 + Root -- "stringContainer: MyModule.Container" + Root -- "intContainer: MyModule.Container" + Root -- "floatContainer: MyModule.Container" + Root -- "voidContainer: MyModule.Container" + } + """) } // MARK: Private From f908af7bce4102ae5d93e4f75ea8098eec2ddf03 Mon Sep 17 00:00:00 2001 From: Dan Federman Date: Sun, 29 Mar 2026 18:29:14 -0700 Subject: [PATCH 3/6] Add MigrateSafeDIFromVersionOne command plugin Provides `swift package plugin safedi-v1-to-v2 --target ` to help users migrate from SafeDI 1.x to 2.x. The plugin validates the swift-tools-version, migrates CSV configuration files to a @SafeDIConfiguration enum, and creates the configuration file if one doesn't already exist. Co-Authored-By: Claude Opus 4.6 (1M context) --- Package.swift | 18 ++ .../MigrateSafeDIFromVersionOne.swift | 170 ++++++++++++++++++ README.md | 25 +++ 3 files changed, 213 insertions(+) create mode 100644 Plugins/MigrateSafeDIFromVersionOne/MigrateSafeDIFromVersionOne.swift diff --git a/Package.swift b/Package.swift index d45710fa..ed40272d 100644 --- a/Package.swift +++ b/Package.swift @@ -34,6 +34,10 @@ let package = Package( name: "InstallSafeDITool", targets: ["InstallSafeDITool"], ), + .plugin( + name: "MigrateSafeDIFromVersionOne", + targets: ["MigrateSafeDIFromVersionOne"], + ), ], dependencies: [ .package(url: "https://github.com/apple/swift-argument-parser.git", from: "1.2.0"), @@ -101,6 +105,20 @@ let package = Package( dependencies: [], ), + .plugin( + name: "MigrateSafeDIFromVersionOne", + capability: .command( + intent: .custom( + verb: "safedi-v1-to-v2", + description: "Migrates a project from SafeDI 1.x to 2.x.", + ), + permissions: [ + .writeToPackageDirectory(reason: "Creates a SafeDIConfiguration.swift file and removes obsolete CSV configuration files."), + ], + ), + dependencies: [], + ), + .plugin( name: "SafeDIGenerator", capability: .buildTool(), diff --git a/Plugins/MigrateSafeDIFromVersionOne/MigrateSafeDIFromVersionOne.swift b/Plugins/MigrateSafeDIFromVersionOne/MigrateSafeDIFromVersionOne.swift new file mode 100644 index 00000000..9afbf12d --- /dev/null +++ b/Plugins/MigrateSafeDIFromVersionOne/MigrateSafeDIFromVersionOne.swift @@ -0,0 +1,170 @@ +// Distributed under the MIT License +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. + +import Foundation +import PackagePlugin + +@main +struct MigrateSafeDIFromVersionOne: CommandPlugin { + func performCommand( + context: PackagePlugin.PluginContext, + arguments: [String], + ) throws { + // Parse --target argument. + guard let targetIndex = arguments.firstIndex(of: "--target"), + arguments.index(after: targetIndex) < arguments.endIndex + else { + let availableTargets = context.package.targets.map(\.name).joined(separator: ", ") + Diagnostics.error("Missing required --target argument. Available targets: \(availableTargets)") + return + } + let targetName = arguments[arguments.index(after: targetIndex)] + + guard let target = context.package.targets.first(where: { $0.name == targetName }) else { + let availableTargets = context.package.targets.map(\.name).joined(separator: ", ") + Diagnostics.error("Target '\(targetName)' not found. Available targets: \(availableTargets)") + return + } + + // Validate swift-tools-version >= 6.3. + let packageSwiftURL = context.package.directoryURL.appending(component: "Package.swift") + let packageSwiftContents = try String(contentsOf: packageSwiftURL, encoding: .utf8) + guard let firstLine = packageSwiftContents.components(separatedBy: .newlines).first, + let versionMatch = try? /swift-tools-version:\s*(\d+)\.(\d+)/.firstMatch(in: firstLine), + let major = Int(versionMatch.output.1), + let minor = Int(versionMatch.output.2) + else { + Diagnostics.error("Could not parse swift-tools-version from Package.swift") + return + } + guard major > 6 || (major == 6 && minor >= 3) else { + Diagnostics.error("SafeDI 2.x requires swift-tools-version 6.3 or later. Found \(major).\(minor). Update your Package.swift before migrating.") + return + } + + let targetDirectoryURL = target.directoryURL + let safediFolder = context.package.directoryURL.appending(component: ".safedi") + let configurationFolder = safediFolder.appending(component: "configuration") + + // Check for existing @SafeDIConfiguration in target sources. + let existingConfigurationFile = findExistingSafeDIConfiguration(in: targetDirectoryURL) + + // Read CSV files if they exist. + let includeCSV = configurationFolder.appending(component: "include.csv") + let additionalImportedModulesCSV = configurationFolder.appending(component: "additionalImportedModules.csv") + let includeValues = readCSV(at: includeCSV) + let additionalImportedModulesValues = readCSV(at: additionalImportedModulesCSV) + + // Create SafeDIConfiguration.swift if one doesn't already exist. + if let existingConfigurationFile { + Diagnostics.warning("@SafeDIConfiguration already exists at \(existingConfigurationFile.path(percentEncoded: false)). Skipping file creation.") + if includeValues != nil || additionalImportedModulesValues != nil { + Diagnostics.warning("CSV configuration files were found but a @SafeDIConfiguration file already exists. Please manually migrate CSV values into your existing @SafeDIConfiguration and delete the CSV files.") + } + } else { + let configurationFileContent = generateSafeDIConfigurationFile( + additionalImportedModules: additionalImportedModulesValues ?? [], + additionalDirectoriesToInclude: includeValues ?? [], + ) + let outputURL = targetDirectoryURL.appending(component: "SafeDIConfiguration.swift") + try configurationFileContent.write( + to: outputURL, + atomically: true, + encoding: .utf8, + ) + Diagnostics.remark("Created \(outputURL.path(percentEncoded: false))") + } + + // Delete CSV files if they existed. + var deletedCSVFiles = [String]() + if includeValues != nil { + try FileManager.default.removeItem(at: includeCSV) + deletedCSVFiles.append(includeCSV.path(percentEncoded: false)) + } + if additionalImportedModulesValues != nil { + try FileManager.default.removeItem(at: additionalImportedModulesCSV) + deletedCSVFiles.append(additionalImportedModulesCSV.path(percentEncoded: false)) + } + if !deletedCSVFiles.isEmpty { + Diagnostics.remark("Deleted CSV configuration files: \(deletedCSVFiles.joined(separator: ", "))") + } + } + + // MARK: Private + + private func findExistingSafeDIConfiguration(in directoryURL: URL) -> URL? { + guard let enumerator = FileManager.default.enumerator( + at: directoryURL, + includingPropertiesForKeys: nil, + options: [.skipsHiddenFiles], + ) else { + return nil + } + for case let fileURL as URL in enumerator { + guard fileURL.pathExtension == "swift" else { continue } + guard let contents = try? String(contentsOf: fileURL, encoding: .utf8) else { continue } + if contents.contains("@SafeDIConfiguration") { + return fileURL + } + } + return nil + } + + private func readCSV(at url: URL) -> [String]? { + guard FileManager.default.fileExists(atPath: url.path(percentEncoded: false)), + let contents = try? String(contentsOf: url, encoding: .utf8) + else { + return nil + } + return contents + .components(separatedBy: CharacterSet(arrayLiteral: ",")) + .map { $0.trimmingCharacters(in: .whitespacesAndNewlines) } + .filter { !$0.isEmpty } + } + + private func generateSafeDIConfigurationFile( + additionalImportedModules: [String], + additionalDirectoriesToInclude: [String], + ) -> String { + let importedModulesArray = formatStringArray(additionalImportedModules) + let directoriesToIncludeArray = formatStringArray(additionalDirectoriesToInclude) + return """ + import SafeDI + + @SafeDIConfiguration + enum SafeDIConfiguration { + \t/// The names of modules to import in the generated dependency tree. + \t/// This list is in addition to the import statements found in files that declare @Instantiable types. + \tstatic let additionalImportedModules: [StaticString] = \(importedModulesArray) + + \t/// Directories containing Swift files to include, relative to the executing directory. + \t/// This property only applies to SafeDI repos that utilize the SPM plugin via an Xcode project. + \tstatic let additionalDirectoriesToInclude: [StaticString] = \(directoriesToIncludeArray) + } + """ + } + + private func formatStringArray(_ values: [String]) -> String { + if values.isEmpty { + return "[]" + } + return "[\(values.map { "\"\($0)\"" }.joined(separator: ", "))]" + } +} diff --git a/README.md b/README.md index 2f2ec665..f1d74f4f 100644 --- a/README.md +++ b/README.md @@ -169,6 +169,31 @@ SafeDI’s compile-time safety and hierarchical dependency scoping make it simil Other Swift DI libraries, like [Factory](https://github.com/hmlongco/Factory) and [swift-dependencies](https://github.com/pointfreeco/swift-dependencies) do offer compile-time validation of the dependency tree but do not have hierarchical dependency scoping. This means scoped dependencies—like an authentication token in a network layer—can only be optionally injected when using these libraries. Meanwhile, libraries like [Swinject](https://github.com/Swinject/Swinject) do not offer compile-time safety. +## Migrating from SafeDI 1.x to 2.x + +SafeDI 2.x requires Swift 6.3 or later and removes support for CSV-based configuration files (`.safedi/configuration/include.csv` and `.safedi/configuration/additionalImportedModules.csv`). Configuration is now done via the `@SafeDIConfiguration` macro. + +### Automated migration + +SafeDI provides a command plugin to automate the migration: + +```bash +swift package plugin safedi-v1-to-v2 --target +``` + +This plugin will: +1. Verify your `swift-tools-version` is 6.3 or later +2. Create a `SafeDIConfiguration.swift` file in your target's source directory +3. Migrate any existing CSV configuration values into the new `@SafeDIConfiguration` enum +4. Delete the obsolete CSV files + +### Manual migration + +1. Update your `swift-tools-version` to 6.3 or later +2. Update your SafeDI dependency to `from: "2.0.0"` +3. If you have `.safedi/configuration/include.csv` or `.safedi/configuration/additionalImportedModules.csv`, create a `@SafeDIConfiguration` enum in your root module with the equivalent values and delete the CSV files +4. If you don't have CSV configuration files, create a `@SafeDIConfiguration`-decorated enum in your root module + ## Contributing I’m glad you’re interested in SafeDI, and I’d love to see where you take it. Please review the [contributing guidelines](Contributing.md) prior to submitting a Pull Request. From 50a5271792058e36f30ac02b74e5cc2da3e9f5b1 Mon Sep 17 00:00:00 2001 From: Dan Federman Date: Sun, 29 Mar 2026 22:10:19 -0700 Subject: [PATCH 4/6] Bump platforms given base developer tools --- Examples/Example Package Integration/Package.swift | 11 ++++++----- .../ExamplePrebuiltPackageIntegration/Package.swift | 11 ++++++----- Package.swift | 10 +++++----- 3 files changed, 17 insertions(+), 15 deletions(-) diff --git a/Examples/Example Package Integration/Package.swift b/Examples/Example Package Integration/Package.swift index 82f30b3a..856ee656 100644 --- a/Examples/Example Package Integration/Package.swift +++ b/Examples/Example Package Integration/Package.swift @@ -6,11 +6,12 @@ import PackageDescription let package = Package( name: "ExamplePackageIntegration", platforms: [ - .macOS(.v10_15), - .iOS(.v13), - .tvOS(.v13), - .watchOS(.v6), - .macCatalyst(.v13), + .macOS(.v11), + .iOS(.v15), + .tvOS(.v15), + .watchOS(.v8), + .macCatalyst(.v15), + .visionOS(.v1), ], products: [ // Products define the executables and libraries a package produces, making them visible to other packages. diff --git a/Examples/ExamplePrebuiltPackageIntegration/Package.swift b/Examples/ExamplePrebuiltPackageIntegration/Package.swift index 592e1947..7e514eff 100644 --- a/Examples/ExamplePrebuiltPackageIntegration/Package.swift +++ b/Examples/ExamplePrebuiltPackageIntegration/Package.swift @@ -6,11 +6,12 @@ import PackageDescription let package = Package( name: "ExamplePackageIntegration", platforms: [ - .macOS(.v10_15), - .iOS(.v13), - .tvOS(.v13), - .watchOS(.v6), - .macCatalyst(.v13), + .macOS(.v11), + .iOS(.v15), + .tvOS(.v15), + .watchOS(.v8), + .macCatalyst(.v15), + .visionOS(.v1), ], products: [ // Products define the executables and libraries a package produces, making them visible to other packages. diff --git a/Package.swift b/Package.swift index ed40272d..5aa49322 100644 --- a/Package.swift +++ b/Package.swift @@ -7,11 +7,11 @@ import PackageDescription let package = Package( name: "SafeDI", platforms: [ - .macOS(.v10_15), - .iOS(.v13), - .tvOS(.v13), - .watchOS(.v6), - .macCatalyst(.v13), + .macOS(.v11), + .iOS(.v15), + .tvOS(.v15), + .watchOS(.v8), + .macCatalyst(.v15), .visionOS(.v1), ], products: [ From e162219e161f4bca116f67a31a7aacabad78be13 Mon Sep 17 00:00:00 2001 From: Dan Federman Date: Sun, 29 Mar 2026 22:09:56 -0700 Subject: [PATCH 5/6] Delete podspec --- .github/workflows/ci.yml | 57 --- Documentation/Manual.md | 2 +- .../ExampleCocoaPodsIntegration/.gitignore | 5 - .../project.pbxproj | 407 ------------------ .../contents.xcworkspacedata | 7 - .../AccentColor.colorset/Contents.json | 11 - .../AppIcon.appiconset/Contents.json | 35 -- .../Assets.xcassets/Contents.json | 6 - .../Models/StringStorage.swift | 42 -- .../Models/UserService.swift | 79 ---- .../Preview Assets.xcassets/Contents.json | 6 - .../Views/ExampleApp.swift | 64 --- .../Views/NameEntryView.swift | 54 --- .../Views/NoteView.swift | 63 --- Examples/ExampleCocoaPodsIntegration/Podfile | 5 - .../safeditool.sh | 2 +- README.md | 16 +- SafeDI.podspec | 43 -- Scripts/check-version-consistency.sh | 6 +- 19 files changed, 4 insertions(+), 906 deletions(-) delete mode 100644 Examples/ExampleCocoaPodsIntegration/.gitignore delete mode 100644 Examples/ExampleCocoaPodsIntegration/ExampleCocoaPodsIntegration.xcodeproj/project.pbxproj delete mode 100644 Examples/ExampleCocoaPodsIntegration/ExampleCocoaPodsIntegration.xcodeproj/project.xcworkspace/contents.xcworkspacedata delete mode 100644 Examples/ExampleCocoaPodsIntegration/ExampleCocoaPodsIntegration/Assets.xcassets/AccentColor.colorset/Contents.json delete mode 100644 Examples/ExampleCocoaPodsIntegration/ExampleCocoaPodsIntegration/Assets.xcassets/AppIcon.appiconset/Contents.json delete mode 100644 Examples/ExampleCocoaPodsIntegration/ExampleCocoaPodsIntegration/Assets.xcassets/Contents.json delete mode 100644 Examples/ExampleCocoaPodsIntegration/ExampleCocoaPodsIntegration/Models/StringStorage.swift delete mode 100644 Examples/ExampleCocoaPodsIntegration/ExampleCocoaPodsIntegration/Models/UserService.swift delete mode 100644 Examples/ExampleCocoaPodsIntegration/ExampleCocoaPodsIntegration/Preview Content/Preview Assets.xcassets/Contents.json delete mode 100644 Examples/ExampleCocoaPodsIntegration/ExampleCocoaPodsIntegration/Views/ExampleApp.swift delete mode 100644 Examples/ExampleCocoaPodsIntegration/ExampleCocoaPodsIntegration/Views/NameEntryView.swift delete mode 100644 Examples/ExampleCocoaPodsIntegration/ExampleCocoaPodsIntegration/Views/NoteView.swift delete mode 100644 Examples/ExampleCocoaPodsIntegration/Podfile rename Examples/{ExampleCocoaPodsIntegration => PrebuildScript}/safeditool.sh (98%) delete mode 100644 SafeDI.podspec diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 251df922..df0041e6 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -111,30 +111,6 @@ jobs: - name: Build Project Integration run: pushd Examples/ExampleMultiProjectIntegration; xcrun xcodebuild build -skipPackagePluginValidation -skipMacroValidation -scheme ExampleMultiProjectIntegration; popd - pod-project-integration: - name: Build CocoaPods Integration on Xcode 26 - runs-on: macos-26 - permissions: - contents: read - steps: - - name: Checkout Repo - uses: actions/checkout@v6 - - uses: ruby/setup-ruby@v1 - with: - ruby-version: '3.3.5' - bundler-cache: true - - name: Select Xcode Version - run: sudo xcode-select --switch /Applications/Xcode_26.4.app/Contents/Developer - - name: Install Pod - run: bundle exec pod install --project-directory=Examples/ExampleCocoaPodsIntegration - - name: Download iOS - run: | - sudo xcodebuild -runFirstLaunch - sudo xcrun simctl list - sudo xcodebuild -downloadPlatform iOS - - name: Build CocoaPods Integration - run: xcrun xcodebuild build -scheme ExampleCocoaPodsIntegration -configuration Debug -workspace Examples/ExampleCocoaPodsIntegration/ExampleCocoaPodsIntegration.xcworkspace -destination 'platform=iOS Simulator,OS=26.2,name=iPad (A16)' # Explicitly test the Debug build. Our pod lint jobs are already testing the Release build. - spm: name: Build and Test on Xcode 26 runs-on: macos-26 @@ -160,39 +136,6 @@ jobs: verbose: true os: macos - pod-lint: - name: Pod Lint - runs-on: macos-26 - strategy: - matrix: - platforms: [ - "ios", - "tvos", - "watchos", - "macos", - "visionos", - ] - fail-fast: false - permissions: - contents: read - steps: - - name: Checkout Repo - uses: actions/checkout@v6 - - uses: ruby/setup-ruby@v1 - with: - ruby-version: '3.3.5' - bundler-cache: true - - name: Select Xcode Version - run: sudo xcode-select --switch /Applications/Xcode_26.4.app/Contents/Developer - - name: Download Simulator - if: matrix.platforms != 'macos' - run: | - sudo xcodebuild -runFirstLaunch - sudo xcrun simctl list - sudo xcodebuild -downloadPlatform ${{ matrix.platforms }} - - name: Lint Podspec - run: bundle exec pod lib lint --verbose --fail-fast --swift-version=6.3 --platforms=${{ matrix.platforms }} - linux: name: Build and Test on Linux runs-on: ubuntu-latest diff --git a/Documentation/Manual.md b/Documentation/Manual.md index 0284cec1..6739c279 100644 --- a/Documentation/Manual.md +++ b/Documentation/Manual.md @@ -511,7 +511,7 @@ UIKit applications’ natural root is the `UIApplicationDelegate`-conforming app ## Example applications -We’ve tied everything together with an example multi-user notes application backed by SwiftUI. You can compile and run this code in [an example single-module Xcode project](../Examples/ExampleProjectIntegration). This same multi-user notes app also exists in [an example multi-module Xcode project](../Examples/ExampleMultiProjectIntegration), and also in [an example Xcode project using CocoaPods](../Examples/ExampleCocoaPodsIntegration). We have also created [an example multi-module `Package.swift` that integrates with SafeDI](../Examples/Example Package Integration). +We’ve tied everything together with an example multi-user notes application backed by SwiftUI. You can compile and run this code in [an example single-module Xcode project](../Examples/ExampleProjectIntegration). This same multi-user notes app also exists in [an example multi-module Xcode project](../Examples/ExampleMultiProjectIntegration). We have also created [an example multi-module `Package.swift` that integrates with SafeDI](../Examples/Example Package Integration). ## Under the hood diff --git a/Examples/ExampleCocoaPodsIntegration/.gitignore b/Examples/ExampleCocoaPodsIntegration/.gitignore deleted file mode 100644 index bbf67b12..00000000 --- a/Examples/ExampleCocoaPodsIntegration/.gitignore +++ /dev/null @@ -1,5 +0,0 @@ -ExampleCocoaPodsIntegration.xcodeproj/xcuserdata -ExampleCocoaPodsIntegration.xcworkspace/ -Podfile.lock -Pods/ -SafeDIOutput/SafeDI.swift diff --git a/Examples/ExampleCocoaPodsIntegration/ExampleCocoaPodsIntegration.xcodeproj/project.pbxproj b/Examples/ExampleCocoaPodsIntegration/ExampleCocoaPodsIntegration.xcodeproj/project.pbxproj deleted file mode 100644 index a42bc1a5..00000000 --- a/Examples/ExampleCocoaPodsIntegration/ExampleCocoaPodsIntegration.xcodeproj/project.pbxproj +++ /dev/null @@ -1,407 +0,0 @@ -// !$*UTF8*$! -{ - archiveVersion = 1; - classes = { - }; - objectVersion = 77; - objects = { - -/* Begin PBXBuildFile section */ - 001683DA816535E0BA21C523 /* libPods-ExampleCocoaPodsIntegration.a in Frameworks */ = {isa = PBXBuildFile; fileRef = AA03B1B1D70965940D873662 /* libPods-ExampleCocoaPodsIntegration.a */; }; - 32E57D002D27DD3E001742A8 /* SafeDI.swift in Sources */ = {isa = PBXBuildFile; fileRef = 32E57CFF2D27DD3E001742A8 /* SafeDI.swift */; }; -/* End PBXBuildFile section */ - -/* Begin PBXFileReference section */ - 286F3DB0181A38EBFB5A11C2 /* Pods-ExampleCocoaPodsIntegration.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-ExampleCocoaPodsIntegration.release.xcconfig"; path = "../../ExampleCocoapodsIntegration/Pods/Target Support Files/Pods-ExampleCocoaPodsIntegration/Pods-ExampleCocoaPodsIntegration.release.xcconfig"; sourceTree = ""; }; - 324DF6F62D27BD28007A980D /* ExampleCocoaPodsIntegration.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = ExampleCocoaPodsIntegration.app; sourceTree = BUILT_PRODUCTS_DIR; }; - 32E57CFF2D27DD3E001742A8 /* SafeDI.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = SafeDI.swift; path = SafeDIOutput/SafeDI.swift; sourceTree = ""; }; - AA03B1B1D70965940D873662 /* libPods-ExampleCocoaPodsIntegration.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-ExampleCocoaPodsIntegration.a"; sourceTree = BUILT_PRODUCTS_DIR; }; - D4FD8A2B660A7F91670D20AC /* Pods-ExampleCocoaPodsIntegration.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-ExampleCocoaPodsIntegration.debug.xcconfig"; path = "../../ExampleCocoapodsIntegration/Pods/Target Support Files/Pods-ExampleCocoaPodsIntegration/Pods-ExampleCocoaPodsIntegration.debug.xcconfig"; sourceTree = ""; }; -/* End PBXFileReference section */ - -/* Begin PBXFileSystemSynchronizedRootGroup section */ - 324DF6F82D27BD28007A980D /* ExampleCocoaPodsIntegration */ = { - isa = PBXFileSystemSynchronizedRootGroup; - path = ExampleCocoaPodsIntegration; - sourceTree = ""; - }; -/* End PBXFileSystemSynchronizedRootGroup section */ - -/* Begin PBXFrameworksBuildPhase section */ - 324DF6F32D27BD28007A980D /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - 001683DA816535E0BA21C523 /* libPods-ExampleCocoaPodsIntegration.a in Frameworks */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXFrameworksBuildPhase section */ - -/* Begin PBXGroup section */ - 324DF6ED2D27BD28007A980D = { - isa = PBXGroup; - children = ( - 32E57CFF2D27DD3E001742A8 /* SafeDI.swift */, - 324DF6F82D27BD28007A980D /* ExampleCocoaPodsIntegration */, - 324DF6F72D27BD28007A980D /* Products */, - B5A0477003AF79C3877E5921 /* Pods */, - E49C4DEEF8009D272E214E10 /* Frameworks */, - ); - sourceTree = ""; - }; - 324DF6F72D27BD28007A980D /* Products */ = { - isa = PBXGroup; - children = ( - 324DF6F62D27BD28007A980D /* ExampleCocoaPodsIntegration.app */, - ); - name = Products; - sourceTree = ""; - }; - B5A0477003AF79C3877E5921 /* Pods */ = { - isa = PBXGroup; - children = ( - D4FD8A2B660A7F91670D20AC /* Pods-ExampleCocoaPodsIntegration.debug.xcconfig */, - 286F3DB0181A38EBFB5A11C2 /* Pods-ExampleCocoaPodsIntegration.release.xcconfig */, - ); - path = Pods; - sourceTree = ""; - }; - E49C4DEEF8009D272E214E10 /* Frameworks */ = { - isa = PBXGroup; - children = ( - AA03B1B1D70965940D873662 /* libPods-ExampleCocoaPodsIntegration.a */, - ); - name = Frameworks; - sourceTree = ""; - }; -/* End PBXGroup section */ - -/* Begin PBXNativeTarget section */ - 324DF6F52D27BD28007A980D /* ExampleCocoaPodsIntegration */ = { - isa = PBXNativeTarget; - buildConfigurationList = 324DF7042D27BD29007A980D /* Build configuration list for PBXNativeTarget "ExampleCocoaPodsIntegration" */; - buildPhases = ( - 436E472576A4DD3983B97EFD /* [CP] Check Pods Manifest.lock */, - 324DF7102D27BDED007A980D /* Run SafeDITool */, - 324DF6F22D27BD28007A980D /* Sources */, - 324DF6F32D27BD28007A980D /* Frameworks */, - 324DF6F42D27BD28007A980D /* Resources */, - ); - buildRules = ( - ); - dependencies = ( - ); - fileSystemSynchronizedGroups = ( - 324DF6F82D27BD28007A980D /* ExampleCocoaPodsIntegration */, - ); - name = ExampleCocoaPodsIntegration; - productName = ExampleCocoaPodsIntegration; - productReference = 324DF6F62D27BD28007A980D /* ExampleCocoaPodsIntegration.app */; - productType = "com.apple.product-type.application"; - }; -/* End PBXNativeTarget section */ - -/* Begin PBXProject section */ - 324DF6EE2D27BD28007A980D /* Project object */ = { - isa = PBXProject; - attributes = { - BuildIndependentTargetsInParallel = 1; - LastSwiftUpdateCheck = 1620; - LastUpgradeCheck = 1620; - TargetAttributes = { - 324DF6F52D27BD28007A980D = { - CreatedOnToolsVersion = 16.2; - }; - }; - }; - buildConfigurationList = 324DF6F12D27BD28007A980D /* Build configuration list for PBXProject "ExampleCocoaPodsIntegration" */; - developmentRegion = en; - hasScannedForEncodings = 0; - knownRegions = ( - en, - Base, - ); - mainGroup = 324DF6ED2D27BD28007A980D; - minimizedProjectReferenceProxies = 1; - preferredProjectObjectVersion = 77; - productRefGroup = 324DF6F72D27BD28007A980D /* Products */; - projectDirPath = ""; - projectRoot = ""; - targets = ( - 324DF6F52D27BD28007A980D /* ExampleCocoaPodsIntegration */, - ); - }; -/* End PBXProject section */ - -/* Begin PBXResourcesBuildPhase section */ - 324DF6F42D27BD28007A980D /* Resources */ = { - isa = PBXResourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXResourcesBuildPhase section */ - -/* Begin PBXShellScriptBuildPhase section */ - 324DF7102D27BDED007A980D /* Run SafeDITool */ = { - isa = PBXShellScriptBuildPhase; - alwaysOutOfDate = 1; - buildActionMask = 2147483647; - files = ( - ); - inputFileListPaths = ( - ); - inputPaths = ( - ); - name = "Run SafeDITool"; - outputFileListPaths = ( - ); - outputPaths = ( - $PROJECT_DIR/SafeDIOutput/SafeDI.swift, - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "$PROJECT_DIR/safeditool.sh\n"; - }; - 436E472576A4DD3983B97EFD /* [CP] Check Pods Manifest.lock */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputFileListPaths = ( - ); - inputPaths = ( - "${PODS_PODFILE_DIR_PATH}/Podfile.lock", - "${PODS_ROOT}/Manifest.lock", - ); - name = "[CP] Check Pods Manifest.lock"; - outputFileListPaths = ( - ); - outputPaths = ( - "$(DERIVED_FILE_DIR)/Pods-ExampleCocoaPodsIntegration-checkManifestLockResult.txt", - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; - showEnvVarsInLog = 0; - }; -/* End PBXShellScriptBuildPhase section */ - -/* Begin PBXSourcesBuildPhase section */ - 324DF6F22D27BD28007A980D /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 32E57D002D27DD3E001742A8 /* SafeDI.swift in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXSourcesBuildPhase section */ - -/* Begin XCBuildConfiguration section */ - 324DF7022D27BD29007A980D /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; - CLANG_ANALYZER_NONNULL = YES; - CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++20"; - CLANG_ENABLE_MODULES = YES; - CLANG_ENABLE_OBJC_ARC = YES; - CLANG_ENABLE_OBJC_WEAK = YES; - CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; - CLANG_WARN_BOOL_CONVERSION = YES; - CLANG_WARN_COMMA = YES; - CLANG_WARN_CONSTANT_CONVERSION = YES; - CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; - CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_DOCUMENTATION_COMMENTS = YES; - CLANG_WARN_EMPTY_BODY = YES; - CLANG_WARN_ENUM_CONVERSION = YES; - CLANG_WARN_INFINITE_RECURSION = YES; - CLANG_WARN_INT_CONVERSION = YES; - CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; - CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; - CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; - CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; - CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; - CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; - CLANG_WARN_STRICT_PROTOTYPES = YES; - CLANG_WARN_SUSPICIOUS_MOVE = YES; - CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; - CLANG_WARN_UNREACHABLE_CODE = YES; - CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - COPY_PHASE_STRIP = NO; - DEBUG_INFORMATION_FORMAT = dwarf; - ENABLE_STRICT_OBJC_MSGSEND = YES; - ENABLE_TESTABILITY = YES; - ENABLE_USER_SCRIPT_SANDBOXING = YES; - GCC_C_LANGUAGE_STANDARD = gnu17; - GCC_DYNAMIC_NO_PIC = NO; - GCC_NO_COMMON_BLOCKS = YES; - GCC_OPTIMIZATION_LEVEL = 0; - GCC_PREPROCESSOR_DEFINITIONS = ( - "DEBUG=1", - "$(inherited)", - ); - GCC_WARN_64_TO_32_BIT_CONVERSION = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; - GCC_WARN_UNDECLARED_SELECTOR = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; - GCC_WARN_UNUSED_FUNCTION = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 18.2; - LOCALIZATION_PREFERS_STRING_CATALOGS = YES; - MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; - MTL_FAST_MATH = YES; - ONLY_ACTIVE_ARCH = YES; - SDKROOT = iphoneos; - SWIFT_ACTIVE_COMPILATION_CONDITIONS = "DEBUG $(inherited)"; - SWIFT_OPTIMIZATION_LEVEL = "-Onone"; - }; - name = Debug; - }; - 324DF7032D27BD29007A980D /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; - CLANG_ANALYZER_NONNULL = YES; - CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++20"; - CLANG_ENABLE_MODULES = YES; - CLANG_ENABLE_OBJC_ARC = YES; - CLANG_ENABLE_OBJC_WEAK = YES; - CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; - CLANG_WARN_BOOL_CONVERSION = YES; - CLANG_WARN_COMMA = YES; - CLANG_WARN_CONSTANT_CONVERSION = YES; - CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; - CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_DOCUMENTATION_COMMENTS = YES; - CLANG_WARN_EMPTY_BODY = YES; - CLANG_WARN_ENUM_CONVERSION = YES; - CLANG_WARN_INFINITE_RECURSION = YES; - CLANG_WARN_INT_CONVERSION = YES; - CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; - CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; - CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; - CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; - CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; - CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; - CLANG_WARN_STRICT_PROTOTYPES = YES; - CLANG_WARN_SUSPICIOUS_MOVE = YES; - CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; - CLANG_WARN_UNREACHABLE_CODE = YES; - CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - COPY_PHASE_STRIP = NO; - DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; - ENABLE_NS_ASSERTIONS = NO; - ENABLE_STRICT_OBJC_MSGSEND = YES; - ENABLE_USER_SCRIPT_SANDBOXING = YES; - GCC_C_LANGUAGE_STANDARD = gnu17; - GCC_NO_COMMON_BLOCKS = YES; - GCC_WARN_64_TO_32_BIT_CONVERSION = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; - GCC_WARN_UNDECLARED_SELECTOR = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; - GCC_WARN_UNUSED_FUNCTION = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 18.2; - LOCALIZATION_PREFERS_STRING_CATALOGS = YES; - MTL_ENABLE_DEBUG_INFO = NO; - MTL_FAST_MATH = YES; - SDKROOT = iphoneos; - SWIFT_COMPILATION_MODE = wholemodule; - VALIDATE_PRODUCT = YES; - }; - name = Release; - }; - 324DF7052D27BD29007A980D /* Debug */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = D4FD8A2B660A7F91670D20AC /* Pods-ExampleCocoaPodsIntegration.debug.xcconfig */; - buildSettings = { - ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; - CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 1; - DEVELOPMENT_ASSET_PATHS = "\"ExampleCocoaPodsIntegration/Preview Content\""; - ENABLE_PREVIEWS = YES; - ENABLE_USER_SCRIPT_SANDBOXING = NO; - GENERATE_INFOPLIST_FILE = YES; - INFOPLIST_KEY_UIApplicationSceneManifest_Generation = YES; - INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES; - INFOPLIST_KEY_UILaunchScreen_Generation = YES; - INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; - INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; - LD_RUNPATH_SEARCH_PATHS = ( - "$(inherited)", - "@executable_path/Frameworks", - ); - MARKETING_VERSION = 1.0; - PRODUCT_BUNDLE_IDENTIFIER = com.dfed.safedi.ExampleCocoaPodsIntegration; - PRODUCT_NAME = "$(TARGET_NAME)"; - SWIFT_EMIT_LOC_STRINGS = YES; - SWIFT_VERSION = 5.0; - TARGETED_DEVICE_FAMILY = "1,2"; - }; - name = Debug; - }; - 324DF7062D27BD29007A980D /* Release */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 286F3DB0181A38EBFB5A11C2 /* Pods-ExampleCocoaPodsIntegration.release.xcconfig */; - buildSettings = { - ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; - CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 1; - DEVELOPMENT_ASSET_PATHS = "\"ExampleCocoaPodsIntegration/Preview Content\""; - ENABLE_PREVIEWS = YES; - ENABLE_USER_SCRIPT_SANDBOXING = NO; - GENERATE_INFOPLIST_FILE = YES; - INFOPLIST_KEY_UIApplicationSceneManifest_Generation = YES; - INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES; - INFOPLIST_KEY_UILaunchScreen_Generation = YES; - INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; - INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; - LD_RUNPATH_SEARCH_PATHS = ( - "$(inherited)", - "@executable_path/Frameworks", - ); - MARKETING_VERSION = 1.0; - PRODUCT_BUNDLE_IDENTIFIER = com.dfed.safedi.ExampleCocoaPodsIntegration; - PRODUCT_NAME = "$(TARGET_NAME)"; - SWIFT_EMIT_LOC_STRINGS = YES; - SWIFT_VERSION = 5.0; - TARGETED_DEVICE_FAMILY = "1,2"; - }; - name = Release; - }; -/* End XCBuildConfiguration section */ - -/* Begin XCConfigurationList section */ - 324DF6F12D27BD28007A980D /* Build configuration list for PBXProject "ExampleCocoaPodsIntegration" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 324DF7022D27BD29007A980D /* Debug */, - 324DF7032D27BD29007A980D /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - 324DF7042D27BD29007A980D /* Build configuration list for PBXNativeTarget "ExampleCocoaPodsIntegration" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 324DF7052D27BD29007A980D /* Debug */, - 324DF7062D27BD29007A980D /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; -/* End XCConfigurationList section */ - }; - rootObject = 324DF6EE2D27BD28007A980D /* Project object */; -} diff --git a/Examples/ExampleCocoaPodsIntegration/ExampleCocoaPodsIntegration.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/Examples/ExampleCocoaPodsIntegration/ExampleCocoaPodsIntegration.xcodeproj/project.xcworkspace/contents.xcworkspacedata deleted file mode 100644 index 919434a6..00000000 --- a/Examples/ExampleCocoaPodsIntegration/ExampleCocoaPodsIntegration.xcodeproj/project.xcworkspace/contents.xcworkspacedata +++ /dev/null @@ -1,7 +0,0 @@ - - - - - diff --git a/Examples/ExampleCocoaPodsIntegration/ExampleCocoaPodsIntegration/Assets.xcassets/AccentColor.colorset/Contents.json b/Examples/ExampleCocoaPodsIntegration/ExampleCocoaPodsIntegration/Assets.xcassets/AccentColor.colorset/Contents.json deleted file mode 100644 index eb878970..00000000 --- a/Examples/ExampleCocoaPodsIntegration/ExampleCocoaPodsIntegration/Assets.xcassets/AccentColor.colorset/Contents.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "colors" : [ - { - "idiom" : "universal" - } - ], - "info" : { - "author" : "xcode", - "version" : 1 - } -} diff --git a/Examples/ExampleCocoaPodsIntegration/ExampleCocoaPodsIntegration/Assets.xcassets/AppIcon.appiconset/Contents.json b/Examples/ExampleCocoaPodsIntegration/ExampleCocoaPodsIntegration/Assets.xcassets/AppIcon.appiconset/Contents.json deleted file mode 100644 index 23058801..00000000 --- a/Examples/ExampleCocoaPodsIntegration/ExampleCocoaPodsIntegration/Assets.xcassets/AppIcon.appiconset/Contents.json +++ /dev/null @@ -1,35 +0,0 @@ -{ - "images" : [ - { - "idiom" : "universal", - "platform" : "ios", - "size" : "1024x1024" - }, - { - "appearances" : [ - { - "appearance" : "luminosity", - "value" : "dark" - } - ], - "idiom" : "universal", - "platform" : "ios", - "size" : "1024x1024" - }, - { - "appearances" : [ - { - "appearance" : "luminosity", - "value" : "tinted" - } - ], - "idiom" : "universal", - "platform" : "ios", - "size" : "1024x1024" - } - ], - "info" : { - "author" : "xcode", - "version" : 1 - } -} diff --git a/Examples/ExampleCocoaPodsIntegration/ExampleCocoaPodsIntegration/Assets.xcassets/Contents.json b/Examples/ExampleCocoaPodsIntegration/ExampleCocoaPodsIntegration/Assets.xcassets/Contents.json deleted file mode 100644 index 73c00596..00000000 --- a/Examples/ExampleCocoaPodsIntegration/ExampleCocoaPodsIntegration/Assets.xcassets/Contents.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "info" : { - "author" : "xcode", - "version" : 1 - } -} diff --git a/Examples/ExampleCocoaPodsIntegration/ExampleCocoaPodsIntegration/Models/StringStorage.swift b/Examples/ExampleCocoaPodsIntegration/ExampleCocoaPodsIntegration/Models/StringStorage.swift deleted file mode 100644 index ef2fce82..00000000 --- a/Examples/ExampleCocoaPodsIntegration/ExampleCocoaPodsIntegration/Models/StringStorage.swift +++ /dev/null @@ -1,42 +0,0 @@ -// Distributed under the MIT License -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. - -import Foundation -import SafeDI - -public protocol StringStorage { - func string(forKey key: String) -> String? - func setString(_ string: String?, forKey key: String) -} - -@Instantiable(fulfillingAdditionalTypes: [StringStorage.self]) -extension UserDefaults: @retroactive Instantiable, StringStorage { - public static func instantiate() -> UserDefaults { - .standard - } - - public func string(forKey key: String) -> String? { - object(forKey: key) as? String - } - - public func setString(_ string: String?, forKey key: String) { - set(string, forKey: key) - } -} diff --git a/Examples/ExampleCocoaPodsIntegration/ExampleCocoaPodsIntegration/Models/UserService.swift b/Examples/ExampleCocoaPodsIntegration/ExampleCocoaPodsIntegration/Models/UserService.swift deleted file mode 100644 index f8785fdc..00000000 --- a/Examples/ExampleCocoaPodsIntegration/ExampleCocoaPodsIntegration/Models/UserService.swift +++ /dev/null @@ -1,79 +0,0 @@ -// Distributed under the MIT License -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. - -import Combine -import SafeDI - -public protocol UserService: ObservableObject { - var userName: String? { get set } - var observableObjectPublisher: ObservableObjectPublisher { get } -} - -/// A type-erased wrapper around a `UserService` that is itself a `UserService` and `ObservableObject`. -public final class AnyUserService: UserService, ObservableObject { - public init(_ userService: some UserService) { - self.userService = userService - objectWillChange = userService - .objectWillChange - .map { _ in () } - .eraseToAnyPublisher() - } - - public var userName: String? { - get { - userService.userName - } - set { - userService.userName = newValue - } - } - - public var observableObjectPublisher: ObservableObjectPublisher { - userService.observableObjectPublisher - } - - public let objectWillChange: AnyPublisher - - private let userService: any UserService -} - -@Instantiable(fulfillingAdditionalTypes: [UserService.self]) -public final class DefaultUserService: Instantiable, UserService { - public init(stringStorage: StringStorage) { - self.stringStorage = stringStorage - } - - public var userName: String? { - get { - stringStorage.string(forKey: #function) - } - set { - objectWillChange.send() - stringStorage.setString(newValue, forKey: #function) - } - } - - public var observableObjectPublisher: ObservableObjectPublisher { - objectWillChange - } - - @Received - @Published private var stringStorage: StringStorage -} diff --git a/Examples/ExampleCocoaPodsIntegration/ExampleCocoaPodsIntegration/Preview Content/Preview Assets.xcassets/Contents.json b/Examples/ExampleCocoaPodsIntegration/ExampleCocoaPodsIntegration/Preview Content/Preview Assets.xcassets/Contents.json deleted file mode 100644 index 73c00596..00000000 --- a/Examples/ExampleCocoaPodsIntegration/ExampleCocoaPodsIntegration/Preview Content/Preview Assets.xcassets/Contents.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "info" : { - "author" : "xcode", - "version" : 1 - } -} diff --git a/Examples/ExampleCocoaPodsIntegration/ExampleCocoaPodsIntegration/Views/ExampleApp.swift b/Examples/ExampleCocoaPodsIntegration/ExampleCocoaPodsIntegration/Views/ExampleApp.swift deleted file mode 100644 index 69c2a7ca..00000000 --- a/Examples/ExampleCocoaPodsIntegration/ExampleCocoaPodsIntegration/Views/ExampleApp.swift +++ /dev/null @@ -1,64 +0,0 @@ -// Distributed under the MIT License -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. - -import Combine -import SafeDI -import SwiftUI - -// @Instantiable macro marks this type as capable of being instantiated by SafeDI. The `isRoot` parameter marks this type as being the root of the dependency tree. -@Instantiable(isRoot: true) -@MainActor -@main -public struct NotesApp: Instantiable, App { - public var body: some Scene { - WindowGroup { - if let userName = userService.userName { - // Returns a new instance of `NoteView`. - noteViewBuilder.instantiate(userName) - } else { - // Returns a new instance of a `NameEntryView`. - nameEntryViewBuilder.instantiate() - } - } - } - - // Memberwise initializer to satisfy SafeDI. - // `public init()` will be generated for this type because this type is a root. - public init( - userService: AnyUserService, - stringStorage: StringStorage, - nameEntryViewBuilder: Instantiator, - noteViewBuilder: Instantiator, - ) { - self.userService = userService - self.stringStorage = stringStorage - self.nameEntryViewBuilder = nameEntryViewBuilder - self.noteViewBuilder = noteViewBuilder - } - - /// A private property that is instantiated when the app is instantiated and manages the User state. - @ObservedObject @Instantiated(fulfilledByType: "DefaultUserService", erasedToConcreteExistential: true) private var userService: AnyUserService - /// A private property that is instantiated when the app is instantiated and manages the persistence of strings. - @Instantiated private let stringStorage: StringStorage - /// A private property that is instantiated when the app is instantiated and can create a NameEntryView on demand. - @Instantiated private let nameEntryViewBuilder: Instantiator - /// A private property that is instantiated when the app is instantiated and can create a NoteView on demand. - @Instantiated private let noteViewBuilder: Instantiator -} diff --git a/Examples/ExampleCocoaPodsIntegration/ExampleCocoaPodsIntegration/Views/NameEntryView.swift b/Examples/ExampleCocoaPodsIntegration/ExampleCocoaPodsIntegration/Views/NameEntryView.swift deleted file mode 100644 index b4e0d1c3..00000000 --- a/Examples/ExampleCocoaPodsIntegration/ExampleCocoaPodsIntegration/Views/NameEntryView.swift +++ /dev/null @@ -1,54 +0,0 @@ -// Distributed under the MIT License -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. - -import SafeDI -import SwiftUI - -@MainActor -@Instantiable -public struct NameEntryView: Instantiable, View { - public init(userService: AnyUserService) { - self.userService = userService - } - - public var body: some View { - VStack { - TextField( - text: $name, - prompt: Text("Enter your name"), - label: {}, - ) - Button(action: { - userService.userName = name - }, label: { - Text("Log in") - }) - } - .padding() - } - - @State private var name: String = "" - - @Received private let userService: AnyUserService -} - -#Preview { - NameEntryView(userService: .init(DefaultUserService(stringStorage: UserDefaults.standard))) -} diff --git a/Examples/ExampleCocoaPodsIntegration/ExampleCocoaPodsIntegration/Views/NoteView.swift b/Examples/ExampleCocoaPodsIntegration/ExampleCocoaPodsIntegration/Views/NoteView.swift deleted file mode 100644 index d270a4a6..00000000 --- a/Examples/ExampleCocoaPodsIntegration/ExampleCocoaPodsIntegration/Views/NoteView.swift +++ /dev/null @@ -1,63 +0,0 @@ -// Distributed under the MIT License -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. - -import SafeDI -import SwiftUI - -@MainActor -@Instantiable -public struct NoteView: Instantiable, View { - public init(userName: String, userService: AnyUserService, stringStorage: StringStorage) { - self.userName = userName - self.userService = userService - self.stringStorage = stringStorage - _note = State(initialValue: stringStorage.string(forKey: userName) ?? "") - } - - public var body: some View { - VStack { - Text("\(userName)’s note") - TextEditor(text: $note) - .onChange(of: note) { _, newValue in - stringStorage.setString(newValue, forKey: userName) - } - Button(action: { - userService.userName = nil - }, label: { - Text("Log out") - }) - } - .padding() - } - - @Forwarded private let userName: String - @Received private let userService: AnyUserService - @Received private let stringStorage: StringStorage - - @State private var note: String = "" -} - -#Preview { - NoteView( - userName: "dfed", - userService: .init(DefaultUserService(stringStorage: UserDefaults.standard)), - stringStorage: UserDefaults.standard, - ) -} diff --git a/Examples/ExampleCocoaPodsIntegration/Podfile b/Examples/ExampleCocoaPodsIntegration/Podfile deleted file mode 100644 index 6d6a23e0..00000000 --- a/Examples/ExampleCocoaPodsIntegration/Podfile +++ /dev/null @@ -1,5 +0,0 @@ -platform :ios, '18.0' - -target 'ExampleCocoaPodsIntegration' do - pod 'SafeDI', :path => '../../' -end diff --git a/Examples/ExampleCocoaPodsIntegration/safeditool.sh b/Examples/PrebuildScript/safeditool.sh similarity index 98% rename from Examples/ExampleCocoaPodsIntegration/safeditool.sh rename to Examples/PrebuildScript/safeditool.sh index 07b894e2..6c2dbdb3 100755 --- a/Examples/ExampleCocoaPodsIntegration/safeditool.sh +++ b/Examples/PrebuildScript/safeditool.sh @@ -2,7 +2,7 @@ set -e -VERSION='1.2.2' +VERSION='2.0.0' SAFEDI_LOCATION="$BUILD_DIR/SafeDITool-Release/$VERSION/safeditool" # Download the tool from Github releases. diff --git a/README.md b/README.md index f1d74f4f..4421cc36 100644 --- a/README.md +++ b/README.md @@ -86,14 +86,6 @@ dependencies: [ To install the SafeDI framework into an Xcode project with Swift Package Manager, follow [Apple’s instructions](https://developer.apple.com/documentation/xcode/adding-package-dependencies-to-your-app) to add `https://github.com/dfed/SafeDI.git` as a dependency. -#### CocoaPods - -To add the SafeDI framework as a dependency to a package utilizing [CocoaPods](https://blog.cocoapods.org/CocoaPods-Specs-Repo), add the following to your `Podfile`: - -```ruby -pod ‘SafeDI’, ‘~> 2.0.0’ -``` - ### Generating your dependency tree SafeDI provides a code generation plugin named `SafeDIGenerator`. This plugin works out of the box on most project configurations. If your project uses a custom build system, you can configure your build to utilize the `SafeDITool` command-line executable directly. @@ -151,15 +143,9 @@ enum MySafeDIConfiguration { SafeDI vends a `SafeDIPrebuiltGenerator` plugin for both Xcode and Swift package manager. This plugin utilizes a prebuilt binary for dependency tree generation and does not require compiling `SwiftSyntax`. Integrating this plugin will guide you through the one-step process of downloading the binary to the expected location. -#### CocoaPods - -Use a pre-build script to download the `SafeDITool` binary and generate your SafeDI dependency tree ([example](Examples/ExampleCocoaPodsIntegration/safeditool.sh)). Make sure to set `ENABLE_USER_SCRIPT_SANDBOXING` to `NO` in the target running the pre-build script. - -You can see this integration in practice in the [ExampleCocoaPodsIntegration](Examples/ExampleCocoaPodsIntegration) package. Run `bundle exec pod install --project-directory=Examples/ExampleCocoaPodsIntegration` to create the `ExampleCocoaPodsIntegration.xcworkspace`. - #### Additional configurations -`SafeDITool` is designed to integrate into projects of any size or shape. Our [Releases](https://github.com/dfed/SafeDI/releases) page has prebuilt, codesigned release binaries of the `SafeDITool` that can be downloaded and utilizied directly in a pre-build script, similar to the CocoaPods integration linked above. +`SafeDITool` is designed to integrate into projects of any size or shape. Our [Releases](https://github.com/dfed/SafeDI/releases) page has prebuilt, codesigned release binaries of the `SafeDITool` that can be downloaded and utilizied directly in a pre-build script ([example](Examples/PrebuildScript/safeditool.sh)). Make sure to set `ENABLE_USER_SCRIPT_SANDBOXING` to `NO` in the target running the pre-build script. `SafeDITool` can parse all of your Swift files at once, or for even better performance, the tool can be run on each dependent module as part of the build. Run `swift run SafeDITool --help` to see documentation of the tool’s supported arguments. diff --git a/SafeDI.podspec b/SafeDI.podspec deleted file mode 100644 index a575f89c..00000000 --- a/SafeDI.podspec +++ /dev/null @@ -1,43 +0,0 @@ -Pod::Spec.new do |s| - s.name = 'SafeDI' - s.version = '2.0.0' - s.summary = 'Compile-time-safe dependency injection' - s.homepage = 'https://github.com/dfed/SafeDI' - s.license = 'MIT' - s.authors = 'Dan Federman' - s.source = { :git => 'https://github.com/dfed/SafeDI.git', :tag => s.version } - - s.ios.deployment_target = '13.0' - s.tvos.deployment_target = '13.0' - s.watchos.deployment_target = '6.0' - s.macos.deployment_target = '10.15' - s.visionos.deployment_target = '1.0' - - s.source_files = 'Sources/SafeDI/**/*.{swift}' - s.preserve_paths = 'Package.swift', 'Sources/**/*', 'Tests/**/*', 'Plugins/**/*' - - # The below scripts and flags were inspired by https://soumyamahunt.medium.com/support-swift-macros-with-cocoapods-3911f9317042 - script = <<-SCRIPT.squish - env -i PATH="$PATH" "$SHELL" -l -c - "set -x; SAFEDI_MACRO_COCOAPODS_BUILD=1 swift build -c $(echo ${CONFIGURATION} | tr '[:upper:]' '[:lower:]') --product SafeDIMacros - --sdk \\"`xcrun --show-sdk-path`\\" - --package-path \\"${PODS_TARGET_SRCROOT}\\" - --scratch-path \\"${PODS_BUILD_DIR}/Macros/SafeDIMacros\\"" - SCRIPT - - s.script_phase = { - :name => 'Build SafeDI macro plugin', - :script => script, - :input_files => Dir.glob("{Package.swift,Sources/SafeDIMacros/**/*,Sources/SafeDICore/**/*").map { - |path| "$(PODS_TARGET_SRCROOT)/#{path}" - }, - :output_files => ["$(PODS_BUILD_DIR)/Macros/SafeDIMacros/${CONFIGURATION}/SafeDIMacros-tool"], - :execution_position => :before_compile - } - - xcconfig = { - 'OTHER_SWIFT_FLAGS' => "-Xfrontend -load-plugin-executable -Xfrontend ${PODS_BUILD_DIR}/Macros/SafeDIMacros/${CONFIGURATION}/SafeDIMacros-tool#SafeDIMacros", - } - s.user_target_xcconfig = xcconfig - s.pod_target_xcconfig = xcconfig -end diff --git a/Scripts/check-version-consistency.sh b/Scripts/check-version-consistency.sh index cff334a6..d4e06521 100755 --- a/Scripts/check-version-consistency.sh +++ b/Scripts/check-version-consistency.sh @@ -39,11 +39,7 @@ echo " SafeDITool.swift: $TOOL_VERSION" PLUGIN_VERSION=$(extract_version "Plugins/Shared.swift" "var safeDIVersion: String" 4 '"') echo " Plugins/Shared.swift: $PLUGIN_VERSION" -# Extract version from SafeDI.podspec -PODSPEC_VERSION=$(extract_version "SafeDI.podspec" "s.version" 0 "'") -echo " SafeDI.podspec: $PODSPEC_VERSION" - -if [ "$TOOL_VERSION" != "$PLUGIN_VERSION" ] || [ "$TOOL_VERSION" != "$PODSPEC_VERSION" ]; then +if [ "$TOOL_VERSION" != "$PLUGIN_VERSION" ]; then echo "ERROR: Version mismatch detected!" exit 1 fi From 27aaf91801ce15f9d6775b4c40b0a8ad9b1c0297 Mon Sep 17 00:00:00 2001 From: Dan Federman Date: Mon, 30 Mar 2026 21:50:51 -0700 Subject: [PATCH 6/6] Fix migration plugin deleting CSV files when manual migration is needed MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When an existing @SafeDIConfiguration file was found, the plugin warned that CSV values must be manually migrated, but then unconditionally deleted the CSV files — destroying the data the user needs to migrate. Move CSV deletion inside the else branch so it only runs when the plugin successfully creates the new configuration file. Co-Authored-By: Claude Opus 4.6 (1M context) --- .../MigrateSafeDIFromVersionOne.swift | 28 ++++++++++--------- 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/Plugins/MigrateSafeDIFromVersionOne/MigrateSafeDIFromVersionOne.swift b/Plugins/MigrateSafeDIFromVersionOne/MigrateSafeDIFromVersionOne.swift index 9afbf12d..5381a3d3 100644 --- a/Plugins/MigrateSafeDIFromVersionOne/MigrateSafeDIFromVersionOne.swift +++ b/Plugins/MigrateSafeDIFromVersionOne/MigrateSafeDIFromVersionOne.swift @@ -90,20 +90,22 @@ struct MigrateSafeDIFromVersionOne: CommandPlugin { encoding: .utf8, ) Diagnostics.remark("Created \(outputURL.path(percentEncoded: false))") - } - // Delete CSV files if they existed. - var deletedCSVFiles = [String]() - if includeValues != nil { - try FileManager.default.removeItem(at: includeCSV) - deletedCSVFiles.append(includeCSV.path(percentEncoded: false)) - } - if additionalImportedModulesValues != nil { - try FileManager.default.removeItem(at: additionalImportedModulesCSV) - deletedCSVFiles.append(additionalImportedModulesCSV.path(percentEncoded: false)) - } - if !deletedCSVFiles.isEmpty { - Diagnostics.remark("Deleted CSV configuration files: \(deletedCSVFiles.joined(separator: ", "))") + // Only delete CSV files when we successfully created the new configuration file. + // If an existing @SafeDIConfiguration was found, the user must manually migrate + // and delete the CSV files themselves. + var deletedCSVFiles = [String]() + if includeValues != nil { + try FileManager.default.removeItem(at: includeCSV) + deletedCSVFiles.append(includeCSV.path(percentEncoded: false)) + } + if additionalImportedModulesValues != nil { + try FileManager.default.removeItem(at: additionalImportedModulesCSV) + deletedCSVFiles.append(additionalImportedModulesCSV.path(percentEncoded: false)) + } + if !deletedCSVFiles.isEmpty { + Diagnostics.remark("Deleted CSV configuration files: \(deletedCSVFiles.joined(separator: ", "))") + } } }