Skip to content

Commit

Permalink
Remove implicit availability of Foundation from future manifest ver…
Browse files Browse the repository at this point in the history
…sions

This changes all imports of `Foundation` in the `PackageDescription` module to be implementation-only, making it so that it needs to be explicitly imported if being used. To avoid breaking existing packages, we inject an explicit import into manifests with tools-version 5.7 or earlier. In the next tools-version, `Foundation` will no longer be implicitly available.

rdar://92879696
  • Loading branch information
neonichu committed Nov 16, 2022
1 parent 1c53ef5 commit 228fd6a
Show file tree
Hide file tree
Showing 18 changed files with 63 additions and 15 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
2 changes: 1 addition & 1 deletion Sources/PackageDescription/PackageDependency.swift
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
//
//===----------------------------------------------------------------------===//

import Foundation
@_implementationOnly import Foundation

// MARK: - file system

Expand Down
2 changes: 1 addition & 1 deletion Sources/PackageDescription/PackageDescription.swift
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
@_implementationOnly import ucrt
@_implementationOnly import struct WinSDK.HANDLE
#endif
import Foundation
@_implementationOnly import Foundation

/// The configuration of a Swift package.
///
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
//
//===----------------------------------------------------------------------===//

import Foundation
@_implementationOnly import Foundation
#if canImport(Glibc)
@_implementationOnly import Glibc
#elseif canImport(Darwin)
Expand Down
2 changes: 1 addition & 1 deletion Sources/PackageDescription/Target.swift
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
//
//===----------------------------------------------------------------------===//

import Foundation
@_implementationOnly import Foundation

/// The basic building block of a Swift package.
///
Expand Down
1 change: 0 additions & 1 deletion Sources/PackageLoading/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
add_library(PackageLoading
ContextModel.swift
Diagnostics.swift
IdentityResolver.swift
ManifestLoader.swift
ManifestLoader+Validation.swift
ModuleMapGenerator.swift
Expand Down
2 changes: 1 addition & 1 deletion Sources/PackageLoading/ContextModel.swift
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
//
//===----------------------------------------------------------------------===//

import Foundation
@_implementationOnly import Foundation

struct ContextModel {
let packageDirectory : String
Expand Down
2 changes: 1 addition & 1 deletion Sources/PackageLoading/ManifestJSONParser.swift
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
//===----------------------------------------------------------------------===//

import Basics
import Foundation
@_implementationOnly import Foundation
import PackageModel
import TSCBasic

Expand Down
2 changes: 1 addition & 1 deletion Sources/PackageLoading/ManifestLoader+Validation.swift
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
//===----------------------------------------------------------------------===//

import Basics
import Foundation
@_implementationOnly import Foundation
import PackageModel
import TSCBasic

Expand Down
13 changes: 11 additions & 2 deletions Sources/PackageLoading/ManifestLoader.swift
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@
//===----------------------------------------------------------------------===//

import Basics
import Foundation
import Dispatch
@_implementationOnly import Foundation
import PackageModel
import TSCBasic
import enum TSCUtility.Diagnostics
Expand Down Expand Up @@ -431,10 +432,18 @@ public final class ManifestLoader: ManifestLoaderProtocol {
callbackQueue: DispatchQueue,
completion: @escaping (Result<EvaluationResult, Error>) -> 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: [
Expand Down
2 changes: 1 addition & 1 deletion Sources/PackageLoading/ModuleMapGenerator.swift
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
//===----------------------------------------------------------------------===//

import Basics
import Foundation
@_implementationOnly import Foundation
import PackageModel
import TSCBasic

Expand Down
2 changes: 1 addition & 1 deletion Sources/PackageLoading/PkgConfig.swift
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
//===----------------------------------------------------------------------===//

import Basics
import Foundation
@_implementationOnly import Foundation
import TSCBasic

/// Information on an individual `pkg-config` supported package.
Expand Down
2 changes: 1 addition & 1 deletion Sources/PackageLoading/TargetSourcesBuilder.swift
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
//===----------------------------------------------------------------------===//

import Basics
import Foundation
@_implementationOnly import Foundation
import PackageModel
import TSCBasic

Expand Down
2 changes: 1 addition & 1 deletion Sources/PackageLoading/ToolsVersionParser.swift
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
//===----------------------------------------------------------------------===//

import Basics
import Foundation
@_implementationOnly import Foundation
import PackageModel
import TSCBasic

Expand Down
1 change: 1 addition & 0 deletions Sources/PackageModel/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ add_library(PackageModel
BuildSettings.swift
Destination.swift
Diagnostics.swift
IdentityResolver.swift
Manifest.swift
Manifest/PackageConditionDescription.swift
Manifest/PackageDependencyDescription.swift
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@
//===----------------------------------------------------------------------===//

import Foundation
import PackageModel
import TSCBasic

// TODO: refactor this when adding registry support
Expand Down
16 changes: 16 additions & 0 deletions Tests/PackageLoadingTests/PD_5_7_LoadingTests .swift
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
20 changes: 20 additions & 0 deletions Tests/PackageLoadingTests/PD_Next_LoadingTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
//===----------------------------------------------------------------------===//

import Basics
import PackageLoading
import PackageModel
import SPMTestSupport
import XCTest
Expand All @@ -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)")
}
}
}
}

0 comments on commit 228fd6a

Please sign in to comment.