apple / swift-system

Low-level system calls and types for Swift
Apache License 2.0
1.18k stars 102 forks source link

Foundation additions #7

Closed benrimmington closed 1 week ago

benrimmington commented 3 years ago

Should the open-source Swift System have a new module, with the same Foundation additions as in the closed-source Swift System?

// MARK: - Foundation Additions

import Foundation

// Available when Foundation is imported with System
@available(macOS 11.0, iOS 14.0, watchOS 7.0, tvOS 14.0, *)
extension FilePath {

    /// Creates a file path from a URL
    ///
    /// The result is nil if `url` doesn't refer to a local file.
    public init?(_ url: URL)
}

// Available when Foundation is imported with System
@available(macOS 11.0, iOS 14.0, watchOS 7.0, tvOS 14.0, *)
extension URL {

    /// Creates a URL from a file path by by copying and validating its UTF-8 contents.
    ///
    /// This initializer does not try to repair ill-formed UTF-8 code unit
    /// sequences. If any are found, the result of the initializer is `nil`.
    ///
    public init?(_ path: FilePath)

    /// Creates a URL from a file path by by copying and validating its UTF-8 contents.
    ///
    /// This initializer does not try to repair ill-formed UTF-8 code unit
    /// sequences. If any are found, the result of the initializer is `nil`.
    ///
    public init?(_ path: FilePath, isDirectory: Bool)
}
milseman commented 3 years ago

@lorentey do you know what the story is with cross-import overlays, especially in a package build environment?

milseman commented 3 years ago

We can definitely have the code in System, but I'm not sure how the build system side of things would work out with SwiftPM. @abertelrud do you know how SPM handles cross-import modules?

lorentey commented 3 years ago

One thing we could do is to put the combo overlay APIs into a separate build product that must be imported explicitly.

karwa commented 3 years ago

I think it would be better if these went the other way - i.e. in Foundation.

The reason is that the natural layering of these 2 libraries would have swift-system sit at the bottom, and for Foundation to depend on it and use it, and for swift-system not to depend on Foundation. For example, it would be fantastic if FS APIs such as FileManager would also accept a FilePath without requiring that it goes through String.

milseman commented 3 years ago

@karwa that's certainly how things are starting to shake out, at least for implementation details. I think it would be nice to formally establish this layering. Foundation will (likely) forever pull in the Darwin module though, so we'll still have the C APIs as well as System.

@Catfish-Man thoughts?

hassila commented 2 years ago

I think it would be better if these went the other way - i.e. in Foundation.

The reason is that the natural layering of these 2 libraries would have swift-system sit at the bottom, and for Foundation to depend on it and use it, and for swift-system not to depend on Foundation.

+1 on that, it's nice to be able to build server-side swift without pulling in Foundation at all (and swift-system is definitely useful for that context).

benrimmington commented 1 week ago

As of macOS 15 and iOS 18, I think these additions have moved into the Foundation framework.

(And perhaps the _System_Foundation framework has been removed?)

@available(macOS 11.0, iOS 14.0, watchOS 7.0, tvOS 14.0, *)
@_originallyDefinedIn(module: "_System_Foundation", macOS 15)
@_originallyDefinedIn(module: "_System_Foundation", iOS 18)
@_originallyDefinedIn(module: "_System_Foundation", tvOS 18)
@_originallyDefinedIn(module: "_System_Foundation", watchOS 11)
extension System.FilePath {
  @available(macOS 11.0, iOS 14.0, watchOS 7.0, tvOS 14.0, *)
  init?(_ url: Foundation.URL)
}

@available(macOS 11.0, iOS 14.0, watchOS 7.0, tvOS 14.0, *)
@_originallyDefinedIn(module: "_System_Foundation", macOS 15)
@_originallyDefinedIn(module: "_System_Foundation", iOS 18)
@_originallyDefinedIn(module: "_System_Foundation", tvOS 18)
@_originallyDefinedIn(module: "_System_Foundation", watchOS 11)
extension Foundation.URL {
  @available(macOS, introduced: 11.0, deprecated: 13.0, renamed: "init(filePath:)")
  @available(iOS, introduced: 14.0, deprecated: 16.0, renamed: "init(filePath:)")
  @available(watchOS, introduced: 7.0, deprecated: 9.0, renamed: "init(filePath:)")
  @available(tvOS, introduced: 14.0, deprecated: 16.0, renamed: "init(filePath:)")
  @available(visionOS, unavailable, renamed: "init(filePath:)")
  init?(_ path: System.FilePath)

  @available(macOS, introduced: 11.0, deprecated: 13.0, message: "Use init?(filePath:directoryHint:) instead")
  @available(iOS, introduced: 14.0, deprecated: 16.0, message: "Use init?(filePath:directoryHint:) instead")
  @available(watchOS, introduced: 7.0, deprecated: 9.0, message: "Use init?(filePath:directoryHint:) instead")
  @available(tvOS, introduced: 14.0, deprecated: 16.0, message: "Use init?(filePath:directoryHint:) instead")
  @available(visionOS, unavailable, message: "Use init?(filePath:directoryHint:) instead")
  init?(_ path: System.FilePath, isDirectory: Swift.Bool)
}