Skip to content

Commit 0f2f4f8

Browse files
authored
Id to any (swiftlang#555)
* Migrate collection classes and assocated APIs from id to Any with a boxing storage. Convert NSArray, NSDictionary, and NSSet for AnyObject to Any. Remove the `.bridge()` function! Re-work the tests to no longer need `.bridge()` calls. This is over 400 unique places where `.bridge()` was removed. Bring in a number of NSString APIs for String since it helps avoid calls to `.bridge()`. * Fix broken tests and correct a few missing value conversions * remove _expensivePropertyListConversion since we now have a better tool for the job: _SwiftValue.fetch * Move _SwiftValue into Bridging * remove @convention(c) from closures that take Any since it invokes _ObjectiveCBridgeable * Remove String AUMP reference * Notification object is stored as Any * compare the other box’s unboxed value to the unboxed value (not to the container) * NSCFDictionary should store and fetch keys and values before sending to CF * NSProcessInfo environment fetch needs to access keys and values as String not NSString
1 parent 76a261d commit 0f2f4f8

File tree

89 files changed

+4141
-3562
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

89 files changed

+4141
-3562
lines changed

Foundation.xcodeproj/project.pbxproj

+24-4
Original file line numberDiff line numberDiff line change
@@ -220,7 +220,7 @@
220220
5B7C8B021BEA830200C5B690 /* CFBurstTrie.h in Headers */ = {isa = PBXBuildFile; fileRef = 5B5D89341BBDA76300234F36 /* CFBurstTrie.h */; settings = {ATTRIBUTES = (Private, ); }; };
221221
5B7C8B031BEA86A900C5B690 /* libCoreFoundation.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 5B7C8A6E1BEA7F8F00C5B690 /* libCoreFoundation.a */; };
222222
5B8BA1621D0B773A00938C27 /* IndexSet.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5B8BA1611D0B773A00938C27 /* IndexSet.swift */; };
223-
5B94E8821C430DE70055C035 /* String.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5B94E8811C430DE70055C035 /* String.swift */; };
223+
5B94E8821C430DE70055C035 /* NSStringAPI.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5B94E8811C430DE70055C035 /* NSStringAPI.swift */; };
224224
5BA9BEA41CF380E8009DBD6C /* URLRequest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5BA9BEA31CF380E8009DBD6C /* URLRequest.swift */; };
225225
5BA9BEA61CF3D747009DBD6C /* Data.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5BA9BEA51CF3D747009DBD6C /* Data.swift */; };
226226
5BA9BEA81CF3E7E7009DBD6C /* CharacterSet.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5BA9BEA71CF3E7E7009DBD6C /* CharacterSet.swift */; };
@@ -230,6 +230,11 @@
230230
5BC46D541D05D6D900005853 /* DateInterval.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5BC46D531D05D6D900005853 /* DateInterval.swift */; };
231231
5BCCA8D91CE6697F0059B963 /* URLComponents.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5BCCA8D81CE6697F0059B963 /* URLComponents.swift */; };
232232
5BCD03821D3EE35C00E3FF9B /* TimeZone.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5BCD03811D3EE35C00E3FF9B /* TimeZone.swift */; };
233+
5BD31D201D5CE8C400563814 /* Bridging.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5BD31D1F1D5CE8C400563814 /* Bridging.swift */; };
234+
5BD31D221D5CEBA800563814 /* String.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5BD31D211D5CEBA800563814 /* String.swift */; };
235+
5BD31D241D5CECC400563814 /* Array.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5BD31D231D5CECC400563814 /* Array.swift */; };
236+
5BD31D3F1D5D19D600563814 /* Dictionary.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5BD31D3E1D5D19D600563814 /* Dictionary.swift */; };
237+
5BD31D411D5D1BC300563814 /* Set.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5BD31D401D5D1BC300563814 /* Set.swift */; };
233238
5BD70FB21D3D4CDC003B9BF8 /* Locale.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5BD70FB11D3D4CDC003B9BF8 /* Locale.swift */; };
234239
5BD70FB41D3D4F8B003B9BF8 /* Calendar.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5BD70FB31D3D4F8B003B9BF8 /* Calendar.swift */; };
235240
5BDC3FCA1BCF176100ED97BB /* NSCFArray.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5BDC3FC91BCF176100ED97BB /* NSCFArray.swift */; };
@@ -613,7 +618,7 @@
613618
5B6F17961C48631C00935030 /* TestUtils.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TestUtils.swift; sourceTree = "<group>"; };
614619
5B7C8A6E1BEA7F8F00C5B690 /* libCoreFoundation.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libCoreFoundation.a; sourceTree = BUILT_PRODUCTS_DIR; };
615620
5B8BA1611D0B773A00938C27 /* IndexSet.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = IndexSet.swift; sourceTree = "<group>"; };
616-
5B94E8811C430DE70055C035 /* String.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = String.swift; sourceTree = "<group>"; };
621+
5B94E8811C430DE70055C035 /* NSStringAPI.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NSStringAPI.swift; sourceTree = "<group>"; };
617622
5BA9BEA31CF380E8009DBD6C /* URLRequest.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = URLRequest.swift; sourceTree = "<group>"; };
618623
5BA9BEA51CF3D747009DBD6C /* Data.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Data.swift; sourceTree = "<group>"; };
619624
5BA9BEA71CF3E7E7009DBD6C /* CharacterSet.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CharacterSet.swift; sourceTree = "<group>"; };
@@ -623,6 +628,11 @@
623628
5BC46D531D05D6D900005853 /* DateInterval.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DateInterval.swift; sourceTree = "<group>"; };
624629
5BCCA8D81CE6697F0059B963 /* URLComponents.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = URLComponents.swift; sourceTree = "<group>"; };
625630
5BCD03811D3EE35C00E3FF9B /* TimeZone.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TimeZone.swift; sourceTree = "<group>"; };
631+
5BD31D1F1D5CE8C400563814 /* Bridging.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Bridging.swift; sourceTree = "<group>"; };
632+
5BD31D211D5CEBA800563814 /* String.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = String.swift; sourceTree = "<group>"; };
633+
5BD31D231D5CECC400563814 /* Array.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Array.swift; sourceTree = "<group>"; };
634+
5BD31D3E1D5D19D600563814 /* Dictionary.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Dictionary.swift; sourceTree = "<group>"; };
635+
5BD31D401D5D1BC300563814 /* Set.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Set.swift; sourceTree = "<group>"; };
626636
5BD70FB11D3D4CDC003B9BF8 /* Locale.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Locale.swift; sourceTree = "<group>"; };
627637
5BD70FB31D3D4F8B003B9BF8 /* Calendar.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Calendar.swift; sourceTree = "<group>"; };
628638
5BDC3F191BCC440100ED97BB /* CFICULogging.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CFICULogging.h; sourceTree = "<group>"; };
@@ -1446,6 +1456,7 @@
14461456
5BDC3F3F1BCC5DCB00ED97BB /* NSObject.swift */,
14471457
5BDC3F461BCC5DCB00ED97BB /* NSSwiftRuntime.swift */,
14481458
5B23AB861CE62D17000DB898 /* Boxing.swift */,
1459+
5BD31D1F1D5CE8C400563814 /* Bridging.swift */,
14491460
5B23AB881CE62D4D000DB898 /* ReferenceConvertible.swift */,
14501461
);
14511462
name = Runtime;
@@ -1461,9 +1472,12 @@
14611472
EADE0B621BD15DFF00C49C64 /* NSIndexPath.swift */,
14621473
5B424C751D0B6E5B007B39C8 /* IndexPath.swift */,
14631474
5BDC3F2E1BCC5DCB00ED97BB /* NSArray.swift */,
1475+
5BD31D231D5CECC400563814 /* Array.swift */,
14641476
5BDC3F361BCC5DCB00ED97BB /* NSDictionary.swift */,
1477+
5BD31D3E1D5D19D600563814 /* Dictionary.swift */,
14651478
5BDC3FCD1BCF17D300ED97BB /* NSCFDictionary.swift */,
14661479
5BDC3F441BCC5DCB00ED97BB /* NSSet.swift */,
1480+
5BD31D401D5D1BC300563814 /* Set.swift */,
14671481
5BDC3FCF1BCF17E600ED97BB /* NSCFSet.swift */,
14681482
EADE0B541BD15DFF00C49C64 /* NSCache.swift */,
14691483
EADE0B781BD15DFF00C49C64 /* NSSortDescriptor.swift */,
@@ -1496,7 +1510,8 @@
14961510
5BDC3F451BCC5DCB00ED97BB /* NSString.swift */,
14971511
5B40920F1D1B304C0022B067 /* NSStringEncodings.swift */,
14981512
5BDC3FCB1BCF177E00ED97BB /* NSCFString.swift */,
1499-
5B94E8811C430DE70055C035 /* String.swift */,
1513+
5B94E8811C430DE70055C035 /* NSStringAPI.swift */,
1514+
5BD31D211D5CEBA800563814 /* String.swift */,
15001515
5B4092111D1B30B40022B067 /* ExtraStringAPIs.swift */,
15011516
);
15021517
name = String;
@@ -1910,6 +1925,7 @@
19101925
5B23AB891CE62D4D000DB898 /* ReferenceConvertible.swift in Sources */,
19111926
D3E8D6D11C367AB600295652 /* NSSpecialValue.swift in Sources */,
19121927
EAB57B721BD1C7A5004AC5C5 /* NSPortMessage.swift in Sources */,
1928+
5BD31D201D5CE8C400563814 /* Bridging.swift in Sources */,
19131929
EADE0BBB1BD15E0000C49C64 /* NSURLAuthenticationChallenge.swift in Sources */,
19141930
EADE0BA11BD15DFF00C49C64 /* NSIndexSet.swift in Sources */,
19151931
5BF7AEA91BCD51F9008F214A /* NSDate.swift in Sources */,
@@ -1922,6 +1938,8 @@
19221938
5BD70FB21D3D4CDC003B9BF8 /* Locale.swift in Sources */,
19231939
EADE0BB71BD15E0000C49C64 /* NSStream.swift in Sources */,
19241940
5BF7AEBF1BCD51F9008F214A /* NSURL.swift in Sources */,
1941+
5BD31D411D5D1BC300563814 /* Set.swift in Sources */,
1942+
5BD31D241D5CECC400563814 /* Array.swift in Sources */,
19251943
5BF7AEBC1BCD51F9008F214A /* NSThread.swift in Sources */,
19261944
D31302011C30CEA900295652 /* NSConcreteValue.swift in Sources */,
19271945
5BF7AEA81BCD51F9008F214A /* NSData.swift in Sources */,
@@ -1942,7 +1960,8 @@
19421960
5BF7AEA51BCD51F9008F214A /* NSCalendar.swift in Sources */,
19431961
EADE0BB81BD15E0000C49C64 /* NSTask.swift in Sources */,
19441962
5BF7AEB31BCD51F9008F214A /* NSObjCRuntime.swift in Sources */,
1945-
5B94E8821C430DE70055C035 /* String.swift in Sources */,
1963+
5BD31D3F1D5D19D600563814 /* Dictionary.swift in Sources */,
1964+
5B94E8821C430DE70055C035 /* NSStringAPI.swift in Sources */,
19461965
5B0163BB1D024EB7003CCD96 /* DateComponents.swift in Sources */,
19471966
5BF7AEAB1BCD51F9008F214A /* NSDictionary.swift in Sources */,
19481967
EADE0BAA1BD15E0000C49C64 /* NSNumberFormatter.swift in Sources */,
@@ -1957,6 +1976,7 @@
19571976
EA418C261D57257D005EAD0D /* NSKeyedArchiverHelpers.swift in Sources */,
19581977
EADE0B981BD15DFF00C49C64 /* NSDecimalNumber.swift in Sources */,
19591978
5BA9BEA61CF3D747009DBD6C /* Data.swift in Sources */,
1979+
5BD31D221D5CEBA800563814 /* String.swift in Sources */,
19601980
5BF7AEA71BCD51F9008F214A /* NSCoder.swift in Sources */,
19611981
D3BCEBA01C2F6DDB00295652 /* NSKeyedCoderOldStyleArray.swift in Sources */,
19621982
5B8BA1621D0B773A00938C27 /* IndexSet.swift in Sources */,

Foundation/Array.swift

+47
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
// This source file is part of the Swift.org open source project
2+
//
3+
// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors
4+
// Licensed under Apache License v2.0 with Runtime Library Exception
5+
//
6+
// See http://swift.org/LICENSE.txt for license information
7+
// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
8+
//
9+
10+
extension Array : _ObjectTypeBridgeable {
11+
12+
public typealias _ObjectType = NSArray
13+
public func _bridgeToObjectiveC() -> _ObjectType {
14+
return NSArray(array: map { (element: Element) -> AnyObject in
15+
return _SwiftValue.store(element)
16+
})
17+
}
18+
19+
static public func _forceBridgeFromObjectiveC(_ source: _ObjectType, result: inout Array?) {
20+
result = _unconditionallyBridgeFromObjectiveC(source)
21+
}
22+
23+
@discardableResult
24+
static public func _conditionallyBridgeFromObjectiveC(_ source: _ObjectType, result: inout Array?) -> Bool {
25+
var array = [Element]()
26+
for value in source.allObjects {
27+
if let v = value as? Element {
28+
array.append(v)
29+
} else {
30+
return false
31+
}
32+
}
33+
result = array
34+
return true
35+
}
36+
37+
static public func _unconditionallyBridgeFromObjectiveC(_ source: _ObjectType?) -> Array {
38+
if let object = source {
39+
var value: Array<Element>?
40+
_conditionallyBridgeFromObjectiveC(object, result: &value)
41+
return value!
42+
} else {
43+
return Array<Element>()
44+
}
45+
}
46+
}
47+

Foundation/Bridging.swift

+143
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,143 @@
1+
//===----------------------------------------------------------------------===//
2+
//
3+
// This source file is part of the Swift.org open source project
4+
//
5+
// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors
6+
// Licensed under Apache License v2.0 with Runtime Library Exception
7+
//
8+
// See http://swift.org/LICENSE.txt for license information
9+
// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
10+
//
11+
//===----------------------------------------------------------------------===//
12+
13+
// Support protocols for casting
14+
public protocol _ObjectBridgeable {
15+
func _bridgeToAnyObject() -> AnyObject
16+
}
17+
18+
public protocol _StructBridgeable {
19+
func _bridgeToAny() -> Any
20+
}
21+
22+
/// - Note: This is a similar interface to the _ObjectiveCBridgeable protocol
23+
public protocol _ObjectTypeBridgeable : _ObjectBridgeable {
24+
associatedtype _ObjectType : AnyObject
25+
26+
func _bridgeToObjectiveC() -> _ObjectType
27+
28+
static func _forceBridgeFromObjectiveC(_ source: _ObjectType, result: inout Self?)
29+
30+
@discardableResult
31+
static func _conditionallyBridgeFromObjectiveC(_ source: _ObjectType, result: inout Self?) -> Bool
32+
33+
static func _unconditionallyBridgeFromObjectiveC(_ source: _ObjectType?) -> Self
34+
}
35+
36+
/// - Note: This does not exist currently on Darwin but it is the inverse corrilation to the bridge types such that a
37+
/// reference type can be converted via a callout to a conversion method.
38+
public protocol _StructTypeBridgeable : _StructBridgeable {
39+
associatedtype _StructType
40+
41+
func _bridgeToSwift() -> _StructType
42+
}
43+
44+
// Default adoption of the type specific variants to the Any variant
45+
extension _ObjectTypeBridgeable {
46+
public func _bridgeToAnyObject() -> AnyObject {
47+
return _bridgeToObjectiveC()
48+
}
49+
}
50+
51+
extension _StructTypeBridgeable {
52+
public func _bridgeToAny() -> Any {
53+
return _bridgeToSwift()
54+
}
55+
}
56+
57+
// slated for removal, these are the swift-corelibs-only variant of the _ObjectiveCBridgeable
58+
internal protocol _CFBridgable {
59+
associatedtype CFType
60+
var _cfObject: CFType { get }
61+
}
62+
63+
internal protocol _SwiftBridgable {
64+
associatedtype SwiftType
65+
var _swiftObject: SwiftType { get }
66+
}
67+
68+
internal protocol _NSBridgable {
69+
associatedtype NSType
70+
var _nsObject: NSType { get }
71+
}
72+
73+
74+
/// - Note: This is an internal boxing value for containing abstract structures
75+
internal final class _SwiftValue : NSObject, NSCopying {
76+
internal private(set) var value: Any
77+
78+
static func fetch(_ object: AnyObject?) -> Any? {
79+
if let obj = object {
80+
return fetch(obj)
81+
}
82+
return nil
83+
}
84+
85+
static func fetch(_ object: AnyObject) -> Any {
86+
if let container = object as? _SwiftValue {
87+
return container.value
88+
} else if let val = object as? _StructBridgeable {
89+
return val._bridgeToAny()
90+
} else {
91+
return object
92+
}
93+
}
94+
95+
static func store(_ value: Any?) -> NSObject? {
96+
if let val = value {
97+
return store(val)
98+
}
99+
return nil
100+
}
101+
102+
static func store(_ value: Any) -> NSObject {
103+
if let val = value as? NSObject {
104+
return val
105+
} else if let val = value as? _ObjectBridgeable {
106+
return val._bridgeToAnyObject() as! NSObject
107+
} else {
108+
return _SwiftValue(value)
109+
}
110+
}
111+
112+
init(_ value: Any) {
113+
self.value = value
114+
}
115+
116+
override var hash: Int {
117+
if let hashable = value as? AnyHashable {
118+
return hashable.hashValue
119+
}
120+
return ObjectIdentifier(self).hashValue
121+
}
122+
123+
override func isEqual(_ object: AnyObject?) -> Bool {
124+
guard let other = object else {
125+
return false
126+
}
127+
if let box = other as? _SwiftValue {
128+
if let otherHashable = box.value as? AnyHashable,
129+
let hashable = value as? AnyHashable {
130+
return hashable == otherHashable
131+
}
132+
}
133+
if let otherHashable = other as? AnyHashable,
134+
let hashable = value as? AnyHashable {
135+
return hashable == otherHashable
136+
}
137+
return false
138+
}
139+
140+
public func copy(with zone: NSZone?) -> Any {
141+
return _SwiftValue(value)
142+
}
143+
}

Foundation/Calendar.swift

+1-1
Original file line numberDiff line numberDiff line change
@@ -1127,7 +1127,7 @@ public func ==(lhs: Calendar, rhs: Calendar) -> Bool {
11271127
}
11281128
}
11291129

1130-
extension Calendar {
1130+
extension Calendar : _ObjectTypeBridgeable {
11311131
public static func _isBridgedToObjectiveC() -> Bool {
11321132
return true
11331133
}

Foundation/CharacterSet.swift

+1-1
Original file line numberDiff line numberDiff line change
@@ -464,7 +464,7 @@ public struct CharacterSet : ReferenceConvertible, Equatable, Hashable, SetAlgeb
464464

465465

466466
// MARK: Objective-C Bridging
467-
extension CharacterSet {
467+
extension CharacterSet : _ObjectTypeBridgeable {
468468
public static func _isBridgedToObjectiveC() -> Bool {
469469
return true
470470
}

Foundation/Data.swift

+1-1
Original file line numberDiff line numberDiff line change
@@ -628,7 +628,7 @@ public func ==(d1 : Data, d2 : Data) -> Bool {
628628
}
629629

630630
/// Provides bridging functionality for struct Data to class NSData and vice-versa.
631-
extension Data {
631+
extension Data : _ObjectTypeBridgeable {
632632
public static func _isBridgedToObjectiveC() -> Bool {
633633
return true
634634
}

Foundation/Date.swift

+1-1
Original file line numberDiff line numberDiff line change
@@ -230,7 +230,7 @@ extension Date : CustomDebugStringConvertible, CustomStringConvertible, CustomRe
230230
}
231231
}
232232

233-
extension Date {
233+
extension Date : _ObjectTypeBridgeable {
234234
@_semantics("convertToObjectiveC")
235235
public func _bridgeToObjectiveC() -> NSDate {
236236
return NSDate(timeIntervalSinceReferenceDate: _time)

Foundation/DateComponents.swift

+1-1
Original file line numberDiff line numberDiff line change
@@ -313,7 +313,7 @@ extension DateComponents : CustomStringConvertible, CustomDebugStringConvertible
313313

314314
// MARK: - Bridging
315315

316-
extension DateComponents {
316+
extension DateComponents : _ObjectTypeBridgeable {
317317
public static func _isBridgedToObjectiveC() -> Bool {
318318
return true
319319
}

Foundation/DateInterval.swift

+1-1
Original file line numberDiff line numberDiff line change
@@ -187,7 +187,7 @@ extension DateInterval : CustomStringConvertible, CustomDebugStringConvertible,
187187
}
188188
}
189189

190-
extension DateInterval {
190+
extension DateInterval : _ObjectTypeBridgeable {
191191
public static func _isBridgedToObjectiveC() -> Bool {
192192
return true
193193
}

0 commit comments

Comments
 (0)