diff --git a/CHANGELOG.md b/CHANGELOG.md index 75853ed0b77..a0da7767cd8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,10 @@ Note: This is in reverse chronological order, so newer entries are added to the Swift 5.8 ----------- +* [#5874] + + In packages using tools version 5.8 or later, Foundation is no longer implicitly imported into package manifests. If Foundation APIs are used, the module needs to be imported explicitly. + * [#5728] In packages that specify resources using tools version 5.8 or later, the generated resource bundle accessor will import `Foundation.Bundle` for its own implementation only. _Clients_ of such packages therefore no longer silently import `Foundation`, preventing inadvertent use of Foundation extensions to standard library APIs, which helps to avoid unexpected code size increases. diff --git a/Sources/PackageDescription/PackageDependency.swift b/Sources/PackageDescription/PackageDependency.swift index e8f6ee1b150..98975164806 100644 --- a/Sources/PackageDescription/PackageDependency.swift +++ b/Sources/PackageDescription/PackageDependency.swift @@ -10,7 +10,7 @@ // //===----------------------------------------------------------------------===// -import Foundation +@_implementationOnly import Foundation // MARK: - file system diff --git a/Sources/PackageDescription/PackageDescription.swift b/Sources/PackageDescription/PackageDescription.swift index bc3ca6bf073..4d1d71d3939 100644 --- a/Sources/PackageDescription/PackageDescription.swift +++ b/Sources/PackageDescription/PackageDescription.swift @@ -18,7 +18,7 @@ @_implementationOnly import ucrt @_implementationOnly import struct WinSDK.HANDLE #endif -import Foundation +@_implementationOnly import Foundation /// The configuration of a Swift package. /// diff --git a/Sources/PackageDescription/PackageDescriptionSerialization.swift b/Sources/PackageDescription/PackageDescriptionSerialization.swift index 90020ca1994..b80515558fd 100644 --- a/Sources/PackageDescription/PackageDescriptionSerialization.swift +++ b/Sources/PackageDescription/PackageDescriptionSerialization.swift @@ -10,7 +10,7 @@ // //===----------------------------------------------------------------------===// -import Foundation +@_implementationOnly import Foundation #if canImport(Glibc) @_implementationOnly import Glibc #elseif canImport(Darwin) diff --git a/Sources/PackageDescription/Target.swift b/Sources/PackageDescription/Target.swift index 7f558ac971a..037fae4389b 100644 --- a/Sources/PackageDescription/Target.swift +++ b/Sources/PackageDescription/Target.swift @@ -10,7 +10,7 @@ // //===----------------------------------------------------------------------===// -import Foundation +@_implementationOnly import Foundation /// The basic building block of a Swift package. /// diff --git a/Sources/PackageLoading/CMakeLists.txt b/Sources/PackageLoading/CMakeLists.txt index aeed241602b..f1922b51d43 100644 --- a/Sources/PackageLoading/CMakeLists.txt +++ b/Sources/PackageLoading/CMakeLists.txt @@ -9,7 +9,6 @@ add_library(PackageLoading ContextModel.swift Diagnostics.swift - IdentityResolver.swift ManifestLoader.swift ManifestLoader+Validation.swift ModuleMapGenerator.swift diff --git a/Sources/PackageLoading/ContextModel.swift b/Sources/PackageLoading/ContextModel.swift index 559271cdb8c..d9b42513abd 100644 --- a/Sources/PackageLoading/ContextModel.swift +++ b/Sources/PackageLoading/ContextModel.swift @@ -10,7 +10,7 @@ // //===----------------------------------------------------------------------===// -import Foundation +@_implementationOnly import Foundation struct ContextModel { let packageDirectory : String diff --git a/Sources/PackageLoading/ManifestJSONParser.swift b/Sources/PackageLoading/ManifestJSONParser.swift index 76801b58d10..fb116469708 100644 --- a/Sources/PackageLoading/ManifestJSONParser.swift +++ b/Sources/PackageLoading/ManifestJSONParser.swift @@ -11,7 +11,7 @@ //===----------------------------------------------------------------------===// import Basics -import Foundation +@_implementationOnly import Foundation import PackageModel import TSCBasic diff --git a/Sources/PackageLoading/ManifestLoader+Validation.swift b/Sources/PackageLoading/ManifestLoader+Validation.swift index 9509e27b154..a841b649aaa 100644 --- a/Sources/PackageLoading/ManifestLoader+Validation.swift +++ b/Sources/PackageLoading/ManifestLoader+Validation.swift @@ -11,7 +11,7 @@ //===----------------------------------------------------------------------===// import Basics -import Foundation +@_implementationOnly import Foundation import PackageModel import TSCBasic diff --git a/Sources/PackageLoading/ManifestLoader.swift b/Sources/PackageLoading/ManifestLoader.swift index 30def0ce51b..eac9214cb75 100644 --- a/Sources/PackageLoading/ManifestLoader.swift +++ b/Sources/PackageLoading/ManifestLoader.swift @@ -11,7 +11,7 @@ //===----------------------------------------------------------------------===// import Basics -import Foundation +@_implementationOnly import Foundation import PackageModel import TSCBasic import enum TSCUtility.Diagnostics @@ -431,10 +431,18 @@ public final class ManifestLoader: ManifestLoaderProtocol { callbackQueue: DispatchQueue, completion: @escaping (Result) -> Void ) throws { + let manifestPreamble: ByteString + switch toolsVersion { + case .vNext: + manifestPreamble = ByteString() + default: + manifestPreamble = ByteString("import Foundation\n") + } + do { try withTemporaryDirectory { tempDir, cleanupTempDir in let manifestTempFilePath = tempDir.appending(component: "manifest.swift") - try localFileSystem.writeFileContents(manifestTempFilePath, bytes: ByteString(manifestContents)) + try localFileSystem.writeFileContents(manifestTempFilePath, bytes: ByteString(manifestPreamble.contents + manifestContents)) let vfsOverlayTempFilePath = tempDir.appending(component: "vfs.yaml") try VFSOverlay(roots: [ diff --git a/Sources/PackageLoading/ModuleMapGenerator.swift b/Sources/PackageLoading/ModuleMapGenerator.swift index 2617d717893..01fdfc61f7d 100644 --- a/Sources/PackageLoading/ModuleMapGenerator.swift +++ b/Sources/PackageLoading/ModuleMapGenerator.swift @@ -11,7 +11,7 @@ //===----------------------------------------------------------------------===// import Basics -import Foundation +@_implementationOnly import Foundation import PackageModel import TSCBasic diff --git a/Sources/PackageLoading/PkgConfig.swift b/Sources/PackageLoading/PkgConfig.swift index d144cf495da..579b90cf4ff 100644 --- a/Sources/PackageLoading/PkgConfig.swift +++ b/Sources/PackageLoading/PkgConfig.swift @@ -11,7 +11,7 @@ //===----------------------------------------------------------------------===// import Basics -import Foundation +@_implementationOnly import Foundation import TSCBasic /// Information on an individual `pkg-config` supported package. diff --git a/Sources/PackageLoading/TargetSourcesBuilder.swift b/Sources/PackageLoading/TargetSourcesBuilder.swift index 2ef3fe1af70..ed08c3b5bc8 100644 --- a/Sources/PackageLoading/TargetSourcesBuilder.swift +++ b/Sources/PackageLoading/TargetSourcesBuilder.swift @@ -11,7 +11,7 @@ //===----------------------------------------------------------------------===// import Basics -import Foundation +@_implementationOnly import Foundation import PackageModel import TSCBasic diff --git a/Sources/PackageLoading/ToolsVersionParser.swift b/Sources/PackageLoading/ToolsVersionParser.swift index c3720021200..52cc20d9d05 100644 --- a/Sources/PackageLoading/ToolsVersionParser.swift +++ b/Sources/PackageLoading/ToolsVersionParser.swift @@ -11,7 +11,7 @@ //===----------------------------------------------------------------------===// import Basics -import Foundation +@_implementationOnly import Foundation import PackageModel import TSCBasic diff --git a/Sources/PackageModel/CMakeLists.txt b/Sources/PackageModel/CMakeLists.txt index 6497a4a598e..ada0caacea4 100644 --- a/Sources/PackageModel/CMakeLists.txt +++ b/Sources/PackageModel/CMakeLists.txt @@ -13,6 +13,7 @@ add_library(PackageModel BuildSettings.swift Destination.swift Diagnostics.swift + IdentityResolver.swift Manifest.swift Manifest/PackageConditionDescription.swift Manifest/PackageDependencyDescription.swift diff --git a/Sources/PackageLoading/IdentityResolver.swift b/Sources/PackageModel/IdentityResolver.swift similarity index 99% rename from Sources/PackageLoading/IdentityResolver.swift rename to Sources/PackageModel/IdentityResolver.swift index 1130ffd7501..9f44ef69760 100644 --- a/Sources/PackageLoading/IdentityResolver.swift +++ b/Sources/PackageModel/IdentityResolver.swift @@ -11,7 +11,6 @@ //===----------------------------------------------------------------------===// import Foundation -import PackageModel import TSCBasic // TODO: refactor this when adding registry support diff --git a/Tests/PackageLoadingTests/PD_5_7_LoadingTests .swift b/Tests/PackageLoadingTests/PD_5_7_LoadingTests .swift index ddc509866a4..eece30c2de2 100644 --- a/Tests/PackageLoadingTests/PD_5_7_LoadingTests .swift +++ b/Tests/PackageLoadingTests/PD_5_7_LoadingTests .swift @@ -22,6 +22,22 @@ class PackageDescription5_7LoadingTests: PackageDescriptionLoadingTests { .v5_7 } + func testImplicitFoundationImportWorks() throws { + let content = """ + import PackageDescription + + _ = FileManager.default + + let package = Package(name: "MyPackage") + """ + + let observability = ObservabilitySystem.makeForTesting() + let (manifest, validationDiagnostics) = try loadAndValidateManifest(content, observabilityScope: observability.topScope) + XCTAssertNoDiagnostics(observability.diagnostics) + XCTAssertNoDiagnostics(validationDiagnostics) + XCTAssertEqual(manifest.displayName, "MyPackage") + } + func testRegistryDependencies() throws { let content = """ import PackageDescription diff --git a/Tests/PackageLoadingTests/PD_Next_LoadingTests.swift b/Tests/PackageLoadingTests/PD_Next_LoadingTests.swift index bb5ef358550..85d8c1bdb2c 100644 --- a/Tests/PackageLoadingTests/PD_Next_LoadingTests.swift +++ b/Tests/PackageLoadingTests/PD_Next_LoadingTests.swift @@ -11,6 +11,7 @@ //===----------------------------------------------------------------------===// import Basics +import PackageLoading import PackageModel import SPMTestSupport import XCTest @@ -19,4 +20,23 @@ class PackageDescriptionNextLoadingTests: PackageDescriptionLoadingTests { override var toolsVersion: ToolsVersion { .vNext } + + func testImplicitFoundationImportFails() throws { + let content = """ + import PackageDescription + + _ = FileManager.default + + let package = Package(name: "MyPackage") + """ + + let observability = ObservabilitySystem.makeForTesting() + XCTAssertThrowsError(try loadAndValidateManifest(content, observabilityScope: observability.topScope), "expected error") { + if case ManifestParseError.invalidManifestFormat(let error, _) = $0 { + XCTAssertMatch(error, .contains("cannot find 'FileManager' in scope")) + } else { + XCTFail("unexpected error: \($0)") + } + } + } }