Skip to content

Commit cb3e8c9

Browse files
committed
Enable String, URL and XML-related types for WASI
fix
1 parent e2219b9 commit cb3e8c9

8 files changed

+101
-22
lines changed

Sources/Foundation/NSString.swift

+8-4
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,11 @@ func NSLocalizedString(_ key: String,
2525
bundle: Bundle = Bundle.main,
2626
value: String = "",
2727
comment: String) -> String {
28+
#if os(WASI)
29+
return key
30+
#else
2831
return bundle.localizedString(forKey: key, value: value, table: tableName)
32+
#endif
2933
}
3034

3135
internal let kCFStringEncodingMacRoman = CFStringBuiltInEncodings.macRoman.rawValue
@@ -237,7 +241,7 @@ open class NSString : NSObject, NSCopying, NSMutableCopying, NSSecureCoding, NSC
237241
internal init(_ string: String) {
238242
_storage = string
239243
}
240-
244+
241245
public convenience required init?(coder aDecoder: NSCoder) {
242246
guard aDecoder.allowsKeyedCoding else {
243247
preconditionFailure("Unkeyed coding is unsupported.")
@@ -292,11 +296,11 @@ open class NSString : NSObject, NSCopying, NSMutableCopying, NSSecureCoding, NSC
292296
characters.deallocate()
293297
return result
294298
}
295-
299+
296300
public static var supportsSecureCoding: Bool {
297301
return true
298302
}
299-
303+
300304
open func encode(with aCoder: NSCoder) {
301305
if let aKeyedCoder = aCoder as? NSKeyedArchiver {
302306
aKeyedCoder._encodePropertyList(self, forKey: "NS.string")
@@ -1267,7 +1271,7 @@ extension NSString {
12671271
}
12681272
data = mData
12691273
}
1270-
1274+
12711275
internal func _writeTo(_ url: URL, _ useAuxiliaryFile: Bool, _ enc: UInt) throws {
12721276
var data = Data()
12731277
try _getExternalRepresentation(&data, url, enc)

Sources/Foundation/NSSwiftRuntime.swift

+9-1
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,15 @@
1616
@_exported import Darwin
1717
#elseif os(Linux) || os(Android) || CYGWIN || os(OpenBSD)
1818
@_exported import Glibc
19+
#elseif os(WASI)
20+
@_exported import WASILibc
1921
#elseif os(Windows)
2022
@_exported import CRT
2123
#endif
2224

25+
#if !os(WASI)
2326
@_exported import Dispatch
27+
#endif
2428

2529
#if os(Windows)
2630
import WinSDK
@@ -257,8 +261,10 @@ internal func __CFInitializeSwift() {
257261
__CFSwiftBridge.NSMutableString.appendString = _CFSwiftStringAppend
258262
__CFSwiftBridge.NSMutableString.appendCharacters = _CFSwiftStringAppendCharacters
259263
__CFSwiftBridge.NSMutableString._cfAppendCString = _CFSwiftStringAppendCString
260-
264+
265+
#if !os(WASI)
261266
__CFSwiftBridge.NSRunLoop._new = _NSRunLoopNew
267+
#endif
262268

263269
__CFSwiftBridge.NSCharacterSet._expandedCFCharacterSet = _CFSwiftCharacterSetExpandedCFCharacterSet
264270
__CFSwiftBridge.NSCharacterSet._retainedBitmapRepresentation = _CFSwiftCharacterSetRetainedBitmapRepresentation
@@ -304,6 +310,7 @@ internal func __CFInitializeSwift() {
304310

305311
// __CFDefaultEightBitStringEncoding = UInt32(kCFStringEncodingUTF8)
306312

313+
#if !os(WASI)
307314
__CFSwiftBridge.NSURL.copyResourcePropertyForKey = _CFSwiftURLCopyResourcePropertyForKey
308315
__CFSwiftBridge.NSURL.copyResourcePropertiesForKeys = _CFSwiftURLCopyResourcePropertiesForKeys
309316
__CFSwiftBridge.NSURL.setResourcePropertyForKey = _CFSwiftURLSetResourcePropertyForKey
@@ -312,6 +319,7 @@ internal func __CFInitializeSwift() {
312319
__CFSwiftBridge.NSURL.clearResourcePropertyCache = _CFSwiftURLClearResourcePropertyCache
313320
__CFSwiftBridge.NSURL.setTemporaryResourceValueForKey = _CFSwiftSetTemporaryResourceValueForKey
314321
__CFSwiftBridge.NSURL.resourceIsReachable = _CFSwiftURLResourceIsReachable
322+
#endif
315323
}
316324

317325
public func === (lhs: AnyClass, rhs: AnyClass) -> Bool {

Sources/Foundation/NSTextCheckingResult.swift

+2-2
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ open class NSTextCheckingResult: NSObject, NSCopying, NSSecureCoding {
5353
open class var supportsSecureCoding: Bool {
5454
NSRequiresConcreteImplementation()
5555
}
56-
56+
5757
open override func copy() -> Any {
5858
return copy(with: nil)
5959
}
@@ -115,7 +115,7 @@ internal class NSRegularExpressionCheckingResult: NSTextCheckingResult {
115115
_rangeArray = nil
116116
super.init()
117117
}
118-
118+
119119
public convenience required init?(coder aDecoder: NSCoder) {
120120
guard aDecoder.allowsKeyedCoding else {
121121
fatalError("Decoding this class requires keyed coding")

Sources/Foundation/NSTimeZone.swift

+5-5
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ open class NSTimeZone : NSObject, NSCopying, NSSecureCoding, NSCoding {
3939
return nil
4040
}
4141
}
42-
42+
4343
public convenience required init?(coder aDecoder: NSCoder) {
4444
guard aDecoder.allowsKeyedCoding else {
4545
preconditionFailure("Unkeyed coding is unsupported.")
@@ -53,7 +53,7 @@ open class NSTimeZone : NSObject, NSCopying, NSSecureCoding, NSCoding {
5353

5454
self.init(name: String._unconditionallyBridgeFromObjectiveC(name), data: data?._swiftObject)
5555
}
56-
56+
5757
open override var hash: Int {
5858
return Int(bitPattern: CFHash(_cfObject))
5959
}
@@ -112,7 +112,7 @@ open class NSTimeZone : NSObject, NSCopying, NSSecureCoding, NSCoding {
112112
// Darwin versions of this method can and will encode mutable data, however it is not required for compatibility
113113
aCoder.encode(self.data._bridgeToObjectiveC(), forKey:"NS.data")
114114
}
115-
115+
116116
public static var supportsSecureCoding: Bool {
117117
return true
118118
}
@@ -296,7 +296,7 @@ internal class __NSLocalTimeZone: NSTimeZone {
296296
private init() {
297297
super.init(_name: "GMT+0000")
298298
}
299-
299+
300300
public convenience required init?(coder aDecoder: NSCoder) {
301301
// We do not encode details of the local time zone, merely the placeholder object.
302302
self.init()
@@ -305,7 +305,7 @@ internal class __NSLocalTimeZone: NSTimeZone {
305305
override func encode(with aCoder: NSCoder) {
306306
// We do not encode details of the local time zone, merely the placeholder object.
307307
}
308-
308+
309309
private var system: NSTimeZone {
310310
return NSTimeZone.system._nsObject
311311
}

Sources/Foundation/NSURL.swift

+30-6
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,7 @@ open class NSURL : NSObject, NSSecureCoding, NSCopying {
153153
open func copy(with zone: NSZone? = nil) -> Any {
154154
if isFileURL {
155155
let newURL = CFURLCreateWithString(kCFAllocatorSystemDefault, relativeString._cfObject, self.baseURL?._cfObject)!
156+
156157
if let storage = _resourceStorageIfPresent {
157158
let newStorage = URLResourceValuesStorage(copying: storage)
158159
_CFURLSetResourceInfo(newURL, newStorage)
@@ -186,7 +187,7 @@ open class NSURL : NSObject, NSSecureCoding, NSCopying {
186187
aCoder.encode(self.baseURL?._nsObject, forKey:"NS.base")
187188
aCoder.encode(self.relativeString._bridgeToObjectiveC(), forKey:"NS.relative")
188189
}
189-
190+
190191
public init(fileURLWithPath path: String, isDirectory isDir: Bool, relativeTo baseURL: URL?) {
191192
super.init()
192193

@@ -198,14 +199,15 @@ open class NSURL : NSObject, NSSecureCoding, NSCopying {
198199
_CFURLInitWithFileSystemPathRelativeToBase(_cfObject, baseURL.path._cfObject, kCFURLPlatformPathStyle, baseURL.hasDirectoryPath, nil)
199200
}
200201
}
201-
202+
202203
public convenience init(fileURLWithPath path: String, relativeTo baseURL: URL?) {
203204
let thePath = _standardizedPath(path)
204205

205206
var isDir: ObjCBool = false
206207
if validPathSeps.contains(where: { thePath.hasSuffix(String($0)) }) {
207208
isDir = true
208209
} else {
210+
#if !os(WASI)
209211
let absolutePath: String
210212
if let absPath = baseURL?.appendingPathComponent(path).path {
211213
absolutePath = absPath
@@ -214,6 +216,7 @@ open class NSURL : NSObject, NSSecureCoding, NSCopying {
214216
}
215217

216218
let _ = FileManager.default.fileExists(atPath: absolutePath, isDirectory: &isDir)
219+
#endif
217220
}
218221

219222
self.init(fileURLWithPath: thePath, isDirectory: isDir.boolValue, relativeTo: baseURL)
@@ -230,9 +233,11 @@ open class NSURL : NSObject, NSSecureCoding, NSCopying {
230233
if validPathSeps.contains(where: { thePath.hasSuffix(String($0)) }) {
231234
isDir = true
232235
} else {
236+
#if !os(WASI)
233237
if !FileManager.default.fileExists(atPath: path, isDirectory: &isDir) {
234238
isDir = false
235239
}
240+
#endif
236241
}
237242
super.init()
238243
_CFURLInitWithFileSystemPathRelativeToBase(_cfObject, thePath._cfObject, kCFURLPlatformPathStyle, isDir.boolValue, nil)
@@ -243,7 +248,7 @@ open class NSURL : NSObject, NSSecureCoding, NSCopying {
243248
let pathString = String(cString: path)
244249
self.init(fileURLWithPath: pathString, isDirectory: isDir, relativeTo: baseURL)
245250
}
246-
251+
247252
public convenience init?(string URLString: String) {
248253
self.init(string: URLString, relativeTo:nil)
249254
}
@@ -542,6 +547,9 @@ open class NSURL : NSObject, NSSecureCoding, NSCopying {
542547
// TODO: should be `checkResourceIsReachableAndReturnError` with autoreleased error parameter.
543548
// Currently Autoreleased pointers is not supported on Linux.
544549
open func checkResourceIsReachable() throws -> Bool {
550+
#if os(WASI)
551+
return false
552+
#else
545553
guard isFileURL,
546554
let path = path else {
547555
throw NSError(domain: NSCocoaErrorDomain,
@@ -557,6 +565,7 @@ open class NSURL : NSObject, NSSecureCoding, NSCopying {
557565
}
558566

559567
return true
568+
#endif
560569
}
561570

562571
/* Returns a file path URL that refers to the same resource as a specified URL. File path URLs use a file system style path. An error will occur if the url parameter is not a file URL. A file reference URL's resource must exist and be reachable to be converted to a file path URL. Symbol is present in iOS 4, but performs no operation.
@@ -760,7 +769,7 @@ extension NSString {
760769
}
761770

762771
extension NSURL {
763-
772+
764773
/* The following methods work on the path portion of a URL in the same manner that the NSPathUtilities methods on NSString do.
765774
*/
766775
open class func fileURL(withPathComponents components: [String]) -> URL? {
@@ -841,6 +850,9 @@ extension NSURL {
841850

842851
open func appendingPathComponent(_ pathComponent: String) -> URL? {
843852
var result : URL? = appendingPathComponent(pathComponent, isDirectory: false)
853+
854+
// File URLs can't be handled on WASI without file system access
855+
#if !os(WASI)
844856
// Since we are appending to a URL, path seperators should
845857
// always be '/', even if we're on Windows
846858
if !pathComponent.hasSuffix("/") && isFileURL {
@@ -852,6 +864,7 @@ extension NSURL {
852864
}
853865

854866
}
867+
#endif
855868
return result
856869
}
857870

@@ -870,15 +883,15 @@ extension NSURL {
870883
open var deletingPathExtension: URL? {
871884
return CFURLCreateCopyDeletingPathExtension(kCFAllocatorSystemDefault, _cfObject)?._swiftObject
872885
}
873-
886+
874887
/* The following methods work only on `file:` scheme URLs; for non-`file:` scheme URLs, these methods return the URL unchanged.
875888
*/
876889
open var standardizingPath: URL? {
877890
// Documentation says it should expand initial tilde, but it does't do this on OS X.
878891
// In remaining cases it works just like URLByResolvingSymlinksInPath.
879892
return _resolveSymlinksInPath(excludeSystemDirs: true, preserveDirectoryFlag: true)
880893
}
881-
894+
882895
open var resolvingSymlinksInPath: URL? {
883896
return _resolveSymlinksInPath(excludeSystemDirs: true)
884897
}
@@ -896,8 +909,12 @@ extension NSURL {
896909
if selfPath.isAbsolutePath {
897910
absolutePath = selfPath
898911
} else {
912+
#if os(WASI)
913+
return nil
914+
#else
899915
let workingDir = FileManager.default.currentDirectoryPath
900916
absolutePath = workingDir._bridgeToObjectiveC().appendingPathComponent(selfPath)
917+
#endif
901918
}
902919

903920

@@ -918,15 +935,20 @@ extension NSURL {
918935

919936
default:
920937
resolvedPath = resolvedPath._bridgeToObjectiveC().appendingPathComponent(component)
938+
#if !os(WASI)
921939
if let destination = FileManager.default._tryToResolveTrailingSymlinkInPath(resolvedPath) {
922940
resolvedPath = destination
923941
}
942+
#endif
924943
}
925944
}
926945

927946
// It might be a responsibility of NSURL(fileURLWithPath:). Check it.
928947
var isExistingDirectory: ObjCBool = false
948+
949+
#if !os(WASI)
929950
let _ = FileManager.default.fileExists(atPath: resolvedPath, isDirectory: &isExistingDirectory)
951+
#endif
930952

931953
if excludeSystemDirs {
932954
resolvedPath = resolvedPath._tryToRemovePathPrefix("/private") ?? resolvedPath
@@ -1005,6 +1027,7 @@ extension NSURL : _StructTypeBridgeable {
10051027

10061028
// -----
10071029

1030+
#if !os(WASI)
10081031
internal func _CFSwiftURLCopyResourcePropertyForKey(_ url: CFTypeRef, _ key: CFString, _ valuePointer: UnsafeMutablePointer<Unmanaged<CFTypeRef>?>?, _ errorPointer: UnsafeMutablePointer<Unmanaged<CFError>?>?) -> _DarwinCompatibleBoolean {
10091032
do {
10101033
let key = URLResourceKey(rawValue: key._swiftObject)
@@ -1538,6 +1561,7 @@ fileprivate extension URLResourceValuesStorage {
15381561
}
15391562
}
15401563
}
1564+
#endif
15411565

15421566
// -----
15431567

Sources/Foundation/PropertyListSerialization.swift

+2
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@ open class PropertyListSerialization : NSObject {
7474
}
7575
}
7676

77+
#if !os(WASI)
7778
internal class func propertyList(with stream: CFReadStream, options opt: ReadOptions, format: UnsafeMutablePointer <PropertyListFormat>?) throws -> Any {
7879
var fmt = kCFPropertyListBinaryFormat_v1_0
7980
var error: Unmanaged<CFError>? = nil
@@ -93,4 +94,5 @@ open class PropertyListSerialization : NSObject {
9394
open class func propertyList(with stream: InputStream, options opt: ReadOptions = [], format: UnsafeMutablePointer<PropertyListFormat>?) throws -> Any {
9495
return try propertyList(with: stream._stream, options: opt, format: format)
9596
}
97+
#endif
9698
}

Sources/Foundation/URL.swift

+1-2
Original file line numberDiff line numberDiff line change
@@ -504,7 +504,7 @@ public struct URL : ReferenceConvertible, Equatable {
504504
guard !string.isEmpty, let inner = NSURL(string: string, relativeTo: url) else { return nil }
505505
_url = URL._converted(from: inner)
506506
}
507-
507+
508508
/// Initializes a newly created file URL referencing the local file or directory at path, relative to a base URL.
509509
///
510510
/// If an empty string is used for the path, then the path is assumed to be ".".
@@ -1054,7 +1054,6 @@ extension URL : Codable {
10541054
}
10551055
}
10561056

1057-
10581057
//===----------------------------------------------------------------------===//
10591058
// File references, for playgrounds.
10601059
//===----------------------------------------------------------------------===//

0 commit comments

Comments
 (0)