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 (#5874)

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 authored Nov 16, 2022
1 parent 18da7e0 commit 0ade4d8
Show file tree
Hide file tree
Showing 19 changed files with 64 additions and 16 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 @@ -435,10 +436,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)")
}
}
}
}
2 changes: 1 addition & 1 deletion Tests/WorkspaceTests/WorkspaceTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -215,7 +215,7 @@ final class WorkspaceTests: XCTestCase {
XCTAssert(rootManifests.count == 0, "\(rootManifests)")

testDiagnostics(observability.diagnostics) { result in
let diagnostic = result.check(diagnostic: .prefix("invalid manifest\n\(path.appending(components: "MyPkg", "Package.swift")):3:8: error: An error in MyPkg"), severity: .error)
let diagnostic = result.check(diagnostic: .prefix("invalid manifest\n\(path.appending(components: "MyPkg", "Package.swift")):4:8: error: An error in MyPkg"), severity: .error)
XCTAssertEqual(diagnostic?.metadata?.packageIdentity, .init(path: pkgDir))
XCTAssertEqual(diagnostic?.metadata?.packageKind, .root(pkgDir))
}
Expand Down

0 comments on commit 0ade4d8

Please sign in to comment.