mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
This test stops working with deployment targets that no longer link @rpath/libswiftCoreGraphics.dylib when running on OSes that still require the CoreGraphics overlay. Explicitly link it to workaround. rdar://135451615
826 lines
25 KiB
Swift
826 lines
25 KiB
Swift
// RUN: %empty-directory(%t)
|
|
//
|
|
// RUN: %target-clang %S/Inputs/Mirror/Mirror.mm -c -o %t/Mirror.mm.o -g
|
|
// RUN: %target-build-swift -parse-stdlib -Xfrontend -disable-access-control -module-name a -I %S/Inputs/Mirror/ -Xlinker %t/Mirror.mm.o %s -o %t.out -Xfrontend -disable-deserialization-safety -lswiftCoreGraphics
|
|
// RUN: %target-codesign %t.out
|
|
// RUN: %target-run %t.out
|
|
// REQUIRES: executable_test
|
|
// REQUIRES: objc_interop
|
|
|
|
import Swift
|
|
import StdlibUnittest
|
|
|
|
|
|
import Foundation
|
|
import CoreGraphics
|
|
import SwiftShims
|
|
import MirrorObjC
|
|
|
|
var nsObjectCanaryCount = 0
|
|
@objc class NSObjectCanary : NSObject {
|
|
override init() {
|
|
nsObjectCanaryCount += 1
|
|
}
|
|
deinit {
|
|
nsObjectCanaryCount -= 1
|
|
}
|
|
}
|
|
|
|
struct NSObjectCanaryStruct {
|
|
var ref = NSObjectCanary()
|
|
}
|
|
|
|
var swiftObjectCanaryCount = 0
|
|
class SwiftObjectCanary {
|
|
init() {
|
|
swiftObjectCanaryCount += 1
|
|
}
|
|
deinit {
|
|
swiftObjectCanaryCount -= 1
|
|
}
|
|
}
|
|
|
|
struct SwiftObjectCanaryStruct {
|
|
var ref = SwiftObjectCanary()
|
|
}
|
|
|
|
@objc class ClassA {
|
|
init(value: Int) {
|
|
self.value = value
|
|
}
|
|
|
|
var value: Int
|
|
}
|
|
|
|
struct BridgedValueType : _ObjectiveCBridgeable {
|
|
init(value: Int) {
|
|
self.value = value
|
|
}
|
|
|
|
func _bridgeToObjectiveC() -> ClassA {
|
|
return ClassA(value: value)
|
|
}
|
|
|
|
static func _forceBridgeFromObjectiveC(
|
|
_ x: ClassA,
|
|
result: inout BridgedValueType?
|
|
) {
|
|
assert(x.value % 2 == 0, "not bridged to Objective-C")
|
|
result = BridgedValueType(value: x.value)
|
|
}
|
|
|
|
static func _conditionallyBridgeFromObjectiveC(
|
|
_ x: ClassA,
|
|
result: inout BridgedValueType?
|
|
) -> Bool {
|
|
if x.value % 2 == 0 {
|
|
result = BridgedValueType(value: x.value)
|
|
return true
|
|
}
|
|
|
|
result = nil
|
|
return false
|
|
}
|
|
|
|
static func _unconditionallyBridgeFromObjectiveC(_ source: ClassA?)
|
|
-> BridgedValueType {
|
|
var result: BridgedValueType?
|
|
_forceBridgeFromObjectiveC(source!, result: &result)
|
|
return result!
|
|
}
|
|
|
|
var value: Int
|
|
var canaryRef = SwiftObjectCanary()
|
|
}
|
|
|
|
struct BridgedLargeValueType : _ObjectiveCBridgeable {
|
|
init(value: Int) {
|
|
value0 = value
|
|
value1 = value
|
|
value2 = value
|
|
value3 = value
|
|
value4 = value
|
|
value5 = value
|
|
value6 = value
|
|
value7 = value
|
|
}
|
|
|
|
func _bridgeToObjectiveC() -> ClassA {
|
|
assert(value == value0)
|
|
return ClassA(value: value0)
|
|
}
|
|
|
|
static func _forceBridgeFromObjectiveC(
|
|
_ x: ClassA,
|
|
result: inout BridgedLargeValueType?
|
|
) {
|
|
assert(x.value % 2 == 0, "not bridged to Objective-C")
|
|
result = BridgedLargeValueType(value: x.value)
|
|
}
|
|
|
|
static func _conditionallyBridgeFromObjectiveC(
|
|
_ x: ClassA,
|
|
result: inout BridgedLargeValueType?
|
|
) -> Bool {
|
|
if x.value % 2 == 0 {
|
|
result = BridgedLargeValueType(value: x.value)
|
|
return true
|
|
}
|
|
|
|
result = nil
|
|
return false
|
|
}
|
|
|
|
static func _unconditionallyBridgeFromObjectiveC(_ source: ClassA?)
|
|
-> BridgedLargeValueType {
|
|
var result: BridgedLargeValueType?
|
|
_forceBridgeFromObjectiveC(source!, result: &result)
|
|
return result!
|
|
}
|
|
|
|
var value: Int {
|
|
let x = value0
|
|
assert(value0 == x && value1 == x && value2 == x && value3 == x &&
|
|
value4 == x && value5 == x && value6 == x && value7 == x)
|
|
return x
|
|
}
|
|
|
|
var (value0, value1, value2, value3): (Int, Int, Int, Int)
|
|
var (value4, value5, value6, value7): (Int, Int, Int, Int)
|
|
var canaryRef = SwiftObjectCanary()
|
|
}
|
|
|
|
class BridgedVerbatimRefType {
|
|
var value: Int = 42
|
|
var canaryRef = SwiftObjectCanary()
|
|
}
|
|
|
|
func withSwiftObjectCanary<T>(
|
|
_ createValue: () -> T,
|
|
_ check: (T) -> Void,
|
|
file: String = #file, line: UInt = #line
|
|
) {
|
|
let stackTrace = SourceLocStack(SourceLoc(file, line))
|
|
|
|
swiftObjectCanaryCount = 0
|
|
autoreleasepool {
|
|
var valueWithCanary = createValue()
|
|
expectEqual(1, swiftObjectCanaryCount, stackTrace: stackTrace)
|
|
check(valueWithCanary)
|
|
}
|
|
expectEqual(0, swiftObjectCanaryCount, stackTrace: stackTrace)
|
|
}
|
|
|
|
// Hack to ensure the CustomReflectable conformance is used directly by the test
|
|
// in case it comes from a library that would otherwise not be autolinked.
|
|
@inline(never)
|
|
func assertCustomReflectable<T: CustomReflectable>(_ t: T) {}
|
|
|
|
var Runtime = TestSuite("Runtime")
|
|
|
|
func _isClassOrObjCExistential_Opaque<T>(_ x: T.Type) -> Bool {
|
|
return _isClassOrObjCExistential(_opaqueIdentity(x))
|
|
}
|
|
|
|
Runtime.test("_isClassOrObjCExistential") {
|
|
expectTrue(_isClassOrObjCExistential(NSObjectCanary.self))
|
|
expectTrue(_isClassOrObjCExistential_Opaque(NSObjectCanary.self))
|
|
|
|
expectFalse(_isClassOrObjCExistential(NSObjectCanaryStruct.self))
|
|
expectFalse(_isClassOrObjCExistential_Opaque(NSObjectCanaryStruct.self))
|
|
|
|
expectTrue(_isClassOrObjCExistential(SwiftObjectCanary.self))
|
|
expectTrue(_isClassOrObjCExistential_Opaque(SwiftObjectCanary.self))
|
|
|
|
expectFalse(_isClassOrObjCExistential(SwiftObjectCanaryStruct.self))
|
|
expectFalse(_isClassOrObjCExistential_Opaque(SwiftObjectCanaryStruct.self))
|
|
|
|
typealias SwiftClosure = () -> ()
|
|
expectFalse(_isClassOrObjCExistential(SwiftClosure.self))
|
|
expectFalse(_isClassOrObjCExistential_Opaque(SwiftClosure.self))
|
|
|
|
typealias ObjCClosure = @convention(block) () -> ()
|
|
expectTrue(_isClassOrObjCExistential(ObjCClosure.self))
|
|
expectTrue(_isClassOrObjCExistential_Opaque(ObjCClosure.self))
|
|
|
|
expectTrue(_isClassOrObjCExistential(CFArray.self))
|
|
expectTrue(_isClassOrObjCExistential_Opaque(CFArray.self))
|
|
|
|
expectTrue(_isClassOrObjCExistential(CFArray.self))
|
|
expectTrue(_isClassOrObjCExistential_Opaque(CFArray.self))
|
|
|
|
expectTrue(_isClassOrObjCExistential(AnyObject.self))
|
|
expectTrue(_isClassOrObjCExistential_Opaque(AnyObject.self))
|
|
|
|
// AnyClass == AnyObject.Type
|
|
expectFalse(_isClassOrObjCExistential(AnyClass.self))
|
|
expectFalse(_isClassOrObjCExistential_Opaque(AnyClass.self))
|
|
|
|
expectFalse(_isClassOrObjCExistential(AnyObject.Protocol.self))
|
|
expectFalse(_isClassOrObjCExistential_Opaque(AnyObject.Protocol.self))
|
|
|
|
expectFalse(_isClassOrObjCExistential(NSObjectCanary.Type.self))
|
|
expectFalse(_isClassOrObjCExistential_Opaque(NSObjectCanary.Type.self))
|
|
}
|
|
|
|
Runtime.test("_canBeClass") {
|
|
expectEqual(1, _canBeClass(NSObjectCanary.self))
|
|
expectEqual(0, _canBeClass(NSObjectCanaryStruct.self))
|
|
|
|
typealias ObjCClosure = @convention(block) () -> ()
|
|
expectEqual(1, _canBeClass(ObjCClosure.self))
|
|
|
|
expectEqual(1, _canBeClass(CFArray.self))
|
|
}
|
|
|
|
Runtime.test("bridgeToObjectiveC") {
|
|
expectEqual(42, (_bridgeAnythingToObjectiveC(BridgedValueType(value: 42)) as! ClassA).value)
|
|
|
|
expectEqual(42, (_bridgeAnythingToObjectiveC(BridgedLargeValueType(value: 42)) as! ClassA).value)
|
|
|
|
var bridgedVerbatimRef = BridgedVerbatimRefType()
|
|
expectTrue(_bridgeAnythingToObjectiveC(bridgedVerbatimRef) === bridgedVerbatimRef)
|
|
}
|
|
|
|
Runtime.test("bridgeToObjectiveC/NoLeak") {
|
|
withSwiftObjectCanary(
|
|
{ BridgedValueType(value: 42) },
|
|
{ expectEqual(42, (_bridgeAnythingToObjectiveC($0) as! ClassA).value) })
|
|
|
|
withSwiftObjectCanary(
|
|
{ BridgedLargeValueType(value: 42) },
|
|
{ expectEqual(42, (_bridgeAnythingToObjectiveC($0) as! ClassA).value) })
|
|
|
|
withSwiftObjectCanary(
|
|
{ BridgedVerbatimRefType() },
|
|
{ expectTrue(_bridgeAnythingToObjectiveC($0) === $0) })
|
|
}
|
|
|
|
Runtime.test("forceBridgeFromObjectiveC") {
|
|
|
|
// Bridge back using BridgedValueType.
|
|
expectNil(_conditionallyBridgeFromObjectiveC(
|
|
ClassA(value: 21), BridgedValueType.self))
|
|
|
|
expectEqual(42, _forceBridgeFromObjectiveC(
|
|
ClassA(value: 42), BridgedValueType.self).value)
|
|
expectEqual(42, _conditionallyBridgeFromObjectiveC(
|
|
ClassA(value: 42), BridgedValueType.self)!.value)
|
|
|
|
expectNil(_conditionallyBridgeFromObjectiveC(
|
|
BridgedVerbatimRefType(), BridgedValueType.self))
|
|
|
|
// Bridge back using BridgedLargeValueType.
|
|
expectNil(_conditionallyBridgeFromObjectiveC(
|
|
ClassA(value: 21), BridgedLargeValueType.self))
|
|
|
|
expectEqual(42, _forceBridgeFromObjectiveC(
|
|
ClassA(value: 42), BridgedLargeValueType.self).value)
|
|
expectEqual(42, _conditionallyBridgeFromObjectiveC(
|
|
ClassA(value: 42), BridgedLargeValueType.self)!.value)
|
|
|
|
expectNil(_conditionallyBridgeFromObjectiveC(
|
|
BridgedVerbatimRefType(), BridgedLargeValueType.self))
|
|
|
|
// Bridge back using BridgedVerbatimRefType.
|
|
expectNil(_conditionallyBridgeFromObjectiveC(
|
|
ClassA(value: 21), BridgedVerbatimRefType.self))
|
|
|
|
expectNil(_conditionallyBridgeFromObjectiveC(
|
|
ClassA(value: 42), BridgedVerbatimRefType.self))
|
|
|
|
var bridgedVerbatimRef = BridgedVerbatimRefType()
|
|
expectTrue(_forceBridgeFromObjectiveC(
|
|
bridgedVerbatimRef, BridgedVerbatimRefType.self) === bridgedVerbatimRef)
|
|
expectTrue(_conditionallyBridgeFromObjectiveC(
|
|
bridgedVerbatimRef, BridgedVerbatimRefType.self)! === bridgedVerbatimRef)
|
|
}
|
|
|
|
|
|
Runtime.test("isBridgedToObjectiveC") {
|
|
expectTrue(_isBridgedToObjectiveC(BridgedValueType.self))
|
|
expectTrue(_isBridgedToObjectiveC(BridgedVerbatimRefType.self))
|
|
}
|
|
|
|
Runtime.test("isBridgedVerbatimToObjectiveC") {
|
|
expectFalse(_isBridgedVerbatimToObjectiveC(BridgedValueType.self))
|
|
expectTrue(_isBridgedVerbatimToObjectiveC(BridgedVerbatimRefType.self))
|
|
}
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
protocol SomeNativeProto {}
|
|
|
|
class SomeClass {}
|
|
@objc class SomeObjCClass {}
|
|
|
|
class SomeNSObjectSubclass : NSObject, SomeNativeProto {}
|
|
extension SomeNativeProto {
|
|
// https://github.com/apple/swift/issues/43154
|
|
func expectSelfTypeNameEqual(to typeName: String) {
|
|
expectEqual(typeName, _typeName(type(of: self)))
|
|
}
|
|
}
|
|
|
|
Runtime.test("typeName") {
|
|
expectEqual("a.SomeObjCClass", _typeName(SomeObjCClass.self))
|
|
expectEqual("a.SomeNSObjectSubclass", _typeName(SomeNSObjectSubclass.self))
|
|
expectEqual("NSObject", _typeName(NSObject.self))
|
|
|
|
var a : Any = SomeObjCClass()
|
|
expectEqual("a.SomeObjCClass", _typeName(type(of: a)))
|
|
|
|
a = SomeNSObjectSubclass()
|
|
expectEqual("a.SomeNSObjectSubclass", _typeName(type(of: a)))
|
|
|
|
a = NSObject()
|
|
expectEqual("NSObject", _typeName(type(of: a)))
|
|
|
|
SomeNSObjectSubclass().expectSelfTypeNameEqual(to: "a.SomeNSObjectSubclass")
|
|
}
|
|
|
|
class GenericClass<T> {}
|
|
class MultiGenericClass<T, U> {}
|
|
struct GenericStruct<T> {}
|
|
enum GenericEnum<T> {}
|
|
|
|
struct PlainStruct {}
|
|
enum PlainEnum {}
|
|
|
|
protocol ProtocolA {}
|
|
protocol ProtocolB {}
|
|
|
|
class OuterClass {
|
|
|
|
private class PrivateGeneric<T, U> {
|
|
class InnerGeneric<X> {
|
|
class Inner { }
|
|
}
|
|
}
|
|
|
|
static func getPrivateGenericName() -> String {
|
|
return NSStringFromClass(OuterClass.PrivateGeneric<Int, Bool>.self)
|
|
}
|
|
static func getInnerGenericName() -> String {
|
|
return NSStringFromClass(OuterClass.PrivateGeneric<Int, Bool>.InnerGeneric<Float>.self)
|
|
}
|
|
static func getInnerName() -> String {
|
|
return NSStringFromClass(OuterClass.PrivateGeneric<Int, Bool>.InnerGeneric<Float>.Inner.self)
|
|
}
|
|
}
|
|
|
|
// The private discriminator is not deterministic.
|
|
// Replace it with a constant string.
|
|
func removePrivateDiscriminator(_ symbol: String) -> String {
|
|
let regexp = try! NSRegularExpression(pattern: "P[0-9]+\\$[0-9a-f]+")
|
|
let range = NSRange(0..<symbol.count)
|
|
return regexp.stringByReplacingMatches(in: symbol, range: range, withTemplate: "XXX")
|
|
}
|
|
|
|
Runtime.test("Generic class ObjC runtime names") {
|
|
expectEqual("_TtGC1a12GenericClassSi_",
|
|
NSStringFromClass(GenericClass<Int>.self))
|
|
expectEqual("_TtGC1a12GenericClassVS_11PlainStruct_",
|
|
NSStringFromClass(GenericClass<PlainStruct>.self))
|
|
expectEqual("_TtGC1a12GenericClassOS_9PlainEnum_",
|
|
NSStringFromClass(GenericClass<PlainEnum>.self))
|
|
expectEqual("_TtGC1a12GenericClassTVS_11PlainStructOS_9PlainEnumS1___",
|
|
NSStringFromClass(GenericClass<(PlainStruct, PlainEnum, PlainStruct)>.self))
|
|
expectEqual("_TtGC1a12GenericClassMVS_11PlainStruct_",
|
|
NSStringFromClass(GenericClass<PlainStruct.Type>.self))
|
|
expectEqual("_TtGC1a12GenericClassFMVS_11PlainStructS1__",
|
|
NSStringFromClass(GenericClass<(PlainStruct.Type) -> PlainStruct>.self))
|
|
|
|
expectEqual("_TtGC1a12GenericClassFzMVS_11PlainStructS1__",
|
|
NSStringFromClass(GenericClass<(PlainStruct.Type) throws -> PlainStruct>.self))
|
|
expectEqual("_TtGC1a12GenericClassFTVS_11PlainStructROS_9PlainEnum_Si_",
|
|
NSStringFromClass(GenericClass<(PlainStruct, inout PlainEnum) -> Int>.self))
|
|
|
|
expectEqual("_TtGC1a12GenericClassPS_9ProtocolA__",
|
|
NSStringFromClass(GenericClass<ProtocolA>.self))
|
|
expectEqual("_TtGC1a12GenericClassPS_9ProtocolAS_9ProtocolB__",
|
|
NSStringFromClass(GenericClass<ProtocolA & ProtocolB>.self))
|
|
expectEqual("_TtGC1a12GenericClassPMPS_9ProtocolAS_9ProtocolB__",
|
|
NSStringFromClass(GenericClass<(ProtocolA & ProtocolB).Type>.self))
|
|
expectEqual("_TtGC1a12GenericClassMPS_9ProtocolAS_9ProtocolB__",
|
|
NSStringFromClass(GenericClass<(ProtocolB & ProtocolA).Protocol>.self))
|
|
|
|
expectEqual("_TtGC1a12GenericClassaSo10CFArrayRef_",
|
|
NSStringFromClass(GenericClass<CFArray>.self))
|
|
expectEqual("_TtGC1a12GenericClassaSo9NSDecimal_",
|
|
NSStringFromClass(GenericClass<Decimal>.self))
|
|
expectEqual("_TtGC1a12GenericClassCSo8NSObject_",
|
|
NSStringFromClass(GenericClass<NSObject>.self))
|
|
expectEqual("_TtGC1a12GenericClassCSo8NSObject_",
|
|
NSStringFromClass(GenericClass<NSObject>.self))
|
|
expectEqual("_TtGC1a12GenericClassPSo9NSCopying__",
|
|
NSStringFromClass(GenericClass<NSCopying>.self))
|
|
expectEqual("_TtGC1a12GenericClassPSo9NSCopyingS_9ProtocolAS_9ProtocolB__",
|
|
NSStringFromClass(GenericClass<ProtocolB & NSCopying & ProtocolA>.self))
|
|
|
|
expectEqual("_TtGC1a12GenericClassXcCS_9SomeClassS_9ProtocolA__",
|
|
NSStringFromClass(GenericClass<ProtocolA & SomeClass>.self))
|
|
expectEqual("_TtGC1a12GenericClassPS_9ProtocolAs9AnyObject__",
|
|
NSStringFromClass(GenericClass<ProtocolA & AnyObject>.self))
|
|
expectEqual("_TtGC1a12GenericClassPs9AnyObject__",
|
|
NSStringFromClass(GenericClass<AnyObject>.self))
|
|
|
|
expectEqual("_TtGC1a17MultiGenericClassGVS_13GenericStructSi_GOS_11GenericEnumGS2_Si___",
|
|
NSStringFromClass(MultiGenericClass<GenericStruct<Int>,
|
|
GenericEnum<GenericEnum<Int>>>.self))
|
|
|
|
expectEqual("_TtGCC1a10OuterClassXXXPrivateGeneric_SiSb_",
|
|
removePrivateDiscriminator(OuterClass.getPrivateGenericName()))
|
|
expectEqual("_TtGCCC1a10OuterClassXXXPrivateGeneric12InnerGeneric_SiSb_Sf_",
|
|
removePrivateDiscriminator(OuterClass.getInnerGenericName()))
|
|
expectEqual("_TtGCCCC1a10OuterClassXXXPrivateGeneric12InnerGeneric5Inner_SiSb_Sf__",
|
|
removePrivateDiscriminator(OuterClass.getInnerName()))
|
|
}
|
|
|
|
@objc protocol P {}
|
|
struct AnyObjStruct<T: AnyObject> {}
|
|
|
|
Runtime.test("typeByName") {
|
|
// Make sure we don't crash if we have foreign classes in the
|
|
// table -- those don't have NominalTypeDescriptors
|
|
print(CFArray.self)
|
|
expectTrue(_typeByName("a.SomeClass") == SomeClass.self)
|
|
expectTrue(_typeByName("DoesNotExist") == nil)
|
|
expectTrue(_typeByName("1a12AnyObjStructVyAA1P_pG") == AnyObjStruct<P>.self)
|
|
}
|
|
|
|
Runtime.test("casting AnyObject to class metatypes") {
|
|
do {
|
|
var ao: AnyObject = SomeClass.self
|
|
expectTrue(ao as? Any.Type == SomeClass.self)
|
|
expectTrue(ao as? AnyClass == SomeClass.self)
|
|
expectTrue(ao as? SomeClass.Type == SomeClass.self)
|
|
}
|
|
|
|
do {
|
|
var ao : AnyObject = SomeNSObjectSubclass()
|
|
expectTrue(ao as? Any.Type == nil)
|
|
expectTrue(ao as? AnyClass == nil)
|
|
|
|
ao = SomeNSObjectSubclass.self
|
|
expectTrue(ao as? Any.Type == SomeNSObjectSubclass.self)
|
|
expectTrue(ao as? AnyClass == SomeNSObjectSubclass.self)
|
|
expectTrue(ao as? SomeNSObjectSubclass.Type == SomeNSObjectSubclass.self)
|
|
}
|
|
|
|
do {
|
|
var a : Any = SomeNSObjectSubclass()
|
|
expectTrue(a as? Any.Type == nil)
|
|
expectTrue(a as? AnyClass == nil)
|
|
}
|
|
|
|
do {
|
|
var nso: NSObject = SomeNSObjectSubclass()
|
|
expectTrue(nso as? AnyClass == nil)
|
|
|
|
nso = (SomeNSObjectSubclass.self as AnyObject) as! NSObject
|
|
expectTrue(nso as? Any.Type == SomeNSObjectSubclass.self)
|
|
expectTrue(nso as? AnyClass == SomeNSObjectSubclass.self)
|
|
expectTrue(nso as? SomeNSObjectSubclass.Type == SomeNSObjectSubclass.self)
|
|
}
|
|
}
|
|
|
|
var RuntimeFoundationWrappers = TestSuite("RuntimeFoundationWrappers")
|
|
|
|
RuntimeFoundationWrappers.test("_stdlib_NSObject_isEqual/NoLeak") {
|
|
nsObjectCanaryCount = 0
|
|
autoreleasepool {
|
|
let a = NSObjectCanary()
|
|
let b = NSObjectCanary()
|
|
expectEqual(2, nsObjectCanaryCount)
|
|
_stdlib_NSObject_isEqual(a, b)
|
|
}
|
|
expectEqual(0, nsObjectCanaryCount)
|
|
}
|
|
|
|
var nsStringCanaryCount = 0
|
|
@objc class NSStringCanary : NSString {
|
|
override init() {
|
|
nsStringCanaryCount += 1
|
|
super.init()
|
|
}
|
|
required init(coder: NSCoder) {
|
|
fatalError("don't call this initializer")
|
|
}
|
|
required init(itemProviderData data: Data, typeIdentifier: String) throws {
|
|
fatalError("don't call this initializer")
|
|
}
|
|
deinit {
|
|
nsStringCanaryCount -= 1
|
|
}
|
|
@objc override var length: Int {
|
|
return 0
|
|
}
|
|
@objc override func character(at index: Int) -> unichar {
|
|
fatalError("out-of-bounds access")
|
|
}
|
|
}
|
|
|
|
RuntimeFoundationWrappers.test("_stdlib_CFStringCreateCopy/NoLeak") {
|
|
nsStringCanaryCount = 0
|
|
autoreleasepool {
|
|
let a = NSStringCanary()
|
|
expectEqual(1, nsStringCanaryCount)
|
|
_stdlib_binary_CFStringCreateCopy(a)
|
|
}
|
|
expectEqual(0, nsStringCanaryCount)
|
|
}
|
|
|
|
RuntimeFoundationWrappers.test("_stdlib_CFStringGetLength/NoLeak") {
|
|
nsStringCanaryCount = 0
|
|
autoreleasepool {
|
|
let a = NSStringCanary()
|
|
expectEqual(1, nsStringCanaryCount)
|
|
_stdlib_binary_CFStringGetLength(a)
|
|
}
|
|
expectEqual(0, nsStringCanaryCount)
|
|
}
|
|
|
|
RuntimeFoundationWrappers.test("_stdlib_CFStringGetCharactersPtr/NoLeak") {
|
|
nsStringCanaryCount = 0
|
|
autoreleasepool {
|
|
let a = NSStringCanary()
|
|
expectEqual(1, nsStringCanaryCount)
|
|
_stdlib_binary_CFStringGetCharactersPtr(a)
|
|
}
|
|
expectEqual(0, nsStringCanaryCount)
|
|
}
|
|
|
|
RuntimeFoundationWrappers.test("bridgedNSArray") {
|
|
var c = [NSObject]()
|
|
autoreleasepool {
|
|
let a = [NSObject]()
|
|
let b = a as NSArray
|
|
c = b as! [NSObject]
|
|
}
|
|
c.append(NSObject())
|
|
// expect no crash.
|
|
}
|
|
|
|
var Reflection = TestSuite("Reflection")
|
|
|
|
class SwiftFooMoreDerivedObjCClass : FooMoreDerivedObjCClass {
|
|
let first: Int = 123
|
|
let second: String = "abc"
|
|
}
|
|
|
|
Reflection.test("Class/ObjectiveCBase/Default") {
|
|
do {
|
|
let value = SwiftFooMoreDerivedObjCClass()
|
|
var output = ""
|
|
dump(value, to: &output)
|
|
|
|
let expected =
|
|
"▿ This is FooObjCClass #0\n" +
|
|
" - super: FooMoreDerivedObjCClass\n" +
|
|
" - super: FooDerivedObjCClass\n" +
|
|
" - super: FooObjCClass\n" +
|
|
" - super: NSObject\n" +
|
|
" - first: 123\n" +
|
|
" - second: \"abc\"\n"
|
|
|
|
expectEqual(expected, output)
|
|
}
|
|
}
|
|
|
|
@objc protocol SomeObjCProto {}
|
|
extension SomeClass: SomeObjCProto {}
|
|
|
|
Reflection.test("MetatypeMirror") {
|
|
do {
|
|
let concreteClassMetatype = SomeClass.self
|
|
let expectedSomeClass = "- a.SomeClass #0\n"
|
|
let objcProtocolMetatype: SomeObjCProto.Type = SomeClass.self
|
|
var output = ""
|
|
dump(objcProtocolMetatype, to: &output)
|
|
expectEqual(expectedSomeClass, output)
|
|
|
|
let objcProtocolConcreteMetatype = SomeObjCProto.self
|
|
let expectedObjCProtocolConcrete = "- a.SomeObjCProto #0\n"
|
|
output = ""
|
|
dump(objcProtocolConcreteMetatype, to: &output)
|
|
expectEqual(expectedObjCProtocolConcrete, output)
|
|
|
|
let compositionConcreteMetatype = (SomeNativeProto & SomeObjCProto).self
|
|
let expectedComposition = "- a.SomeNativeProto & a.SomeObjCProto #0\n"
|
|
output = ""
|
|
dump(compositionConcreteMetatype, to: &output)
|
|
expectEqual(expectedComposition, output)
|
|
|
|
let objcDefinedProtoType = NSObjectProtocol.self
|
|
expectEqual(String(describing: objcDefinedProtoType), "NSObject")
|
|
}
|
|
}
|
|
|
|
Reflection.test("CGPoint") {
|
|
var output = ""
|
|
let point = CGPoint(x: 1.25, y: 2.75)
|
|
assertCustomReflectable(point)
|
|
dump(point, to: &output)
|
|
|
|
let expected =
|
|
"▿ (1.25, 2.75)\n" +
|
|
" - x: 1.25\n" +
|
|
" - y: 2.75\n"
|
|
|
|
expectEqual(expected, output)
|
|
}
|
|
|
|
Reflection.test("CGSize") {
|
|
var output = ""
|
|
let size = CGSize(width: 1.25, height: 2.75)
|
|
assertCustomReflectable(size)
|
|
dump(size, to: &output)
|
|
|
|
let expected =
|
|
"▿ (1.25, 2.75)\n" +
|
|
" - width: 1.25\n" +
|
|
" - height: 2.75\n"
|
|
|
|
expectEqual(expected, output)
|
|
}
|
|
|
|
Reflection.test("CGRect") {
|
|
var output = ""
|
|
let rect = CGRect(
|
|
origin: CGPoint(x: 1.25, y: 2.25),
|
|
size: CGSize(width: 10.25, height: 11.75))
|
|
assertCustomReflectable(rect)
|
|
dump(rect, to: &output)
|
|
|
|
let expected =
|
|
"▿ (1.25, 2.25, 10.25, 11.75)\n" +
|
|
" ▿ origin: (1.25, 2.25)\n" +
|
|
" - x: 1.25\n" +
|
|
" - y: 2.25\n" +
|
|
" ▿ size: (10.25, 11.75)\n" +
|
|
" - width: 10.25\n" +
|
|
" - height: 11.75\n"
|
|
|
|
expectEqual(expected, output)
|
|
}
|
|
|
|
Reflection.test("Unmanaged/nil") {
|
|
var output = ""
|
|
var optionalURL: Unmanaged<CFURL>?
|
|
dump(optionalURL, to: &output)
|
|
|
|
let expected = "- nil\n"
|
|
|
|
expectEqual(expected, output)
|
|
}
|
|
|
|
Reflection.test("Unmanaged/not-nil") {
|
|
var output = ""
|
|
var optionalURL: Unmanaged<CFURL>? =
|
|
Unmanaged.passRetained(CFURLCreateWithString(nil, "http://llvm.org/" as CFString, nil))
|
|
dump(optionalURL, to: &output)
|
|
|
|
let expected =
|
|
"▿ Optional(Swift.Unmanaged<__C.CFURLRef>(_value: http://llvm.org/))\n" +
|
|
" ▿ some: Swift.Unmanaged<__C.CFURLRef>\n" +
|
|
" - _value: http://llvm.org/ #0\n" +
|
|
" - super: NSObject\n"
|
|
|
|
expectEqual(expected, output)
|
|
|
|
optionalURL!.release()
|
|
}
|
|
|
|
Reflection.test("TupleMirror/NoLeak") {
|
|
do {
|
|
nsObjectCanaryCount = 0
|
|
autoreleasepool {
|
|
var tuple = (1, NSObjectCanary())
|
|
expectEqual(1, nsObjectCanaryCount)
|
|
var output = ""
|
|
dump(tuple, to: &output)
|
|
}
|
|
expectEqual(0, nsObjectCanaryCount)
|
|
}
|
|
do {
|
|
nsObjectCanaryCount = 0
|
|
autoreleasepool {
|
|
var tuple = (1, NSObjectCanaryStruct())
|
|
expectEqual(1, nsObjectCanaryCount)
|
|
var output = ""
|
|
dump(tuple, to: &output)
|
|
}
|
|
expectEqual(0, nsObjectCanaryCount)
|
|
}
|
|
do {
|
|
swiftObjectCanaryCount = 0
|
|
autoreleasepool {
|
|
var tuple = (1, SwiftObjectCanary())
|
|
expectEqual(1, swiftObjectCanaryCount)
|
|
var output = ""
|
|
dump(tuple, to: &output)
|
|
}
|
|
expectEqual(0, swiftObjectCanaryCount)
|
|
}
|
|
do {
|
|
swiftObjectCanaryCount = 0
|
|
autoreleasepool {
|
|
var tuple = (1, SwiftObjectCanaryStruct())
|
|
expectEqual(1, swiftObjectCanaryCount)
|
|
var output = ""
|
|
dump(tuple, to: &output)
|
|
}
|
|
expectEqual(0, swiftObjectCanaryCount)
|
|
}
|
|
}
|
|
|
|
@objc @objcMembers class TestArtificialSubclass: NSObject {
|
|
dynamic var foo = "foo"
|
|
}
|
|
|
|
var KVOHandle = 0
|
|
|
|
Reflection.test("Name of metatype of artificial subclass") {
|
|
let obj = TestArtificialSubclass()
|
|
|
|
expectEqual("\(type(of: obj))", "TestArtificialSubclass")
|
|
expectEqual(String(describing: type(of: obj)), "TestArtificialSubclass")
|
|
expectEqual(String(reflecting: type(of: obj)), "a.TestArtificialSubclass")
|
|
|
|
// Trigger the creation of a KVO subclass for TestArtificialSubclass.
|
|
obj.addObserver(obj, forKeyPath: "foo", options: [.new], context: &KVOHandle)
|
|
expectEqual("\(type(of: obj))", "TestArtificialSubclass")
|
|
expectEqual(String(describing: type(of: obj)), "TestArtificialSubclass")
|
|
expectEqual(String(reflecting: type(of: obj)), "a.TestArtificialSubclass")
|
|
obj.removeObserver(obj, forKeyPath: "foo")
|
|
|
|
expectEqual("\(type(of: obj))", "TestArtificialSubclass")
|
|
expectEqual(String(describing: type(of: obj)), "TestArtificialSubclass")
|
|
expectEqual(String(reflecting: type(of: obj)), "a.TestArtificialSubclass")
|
|
}
|
|
|
|
@objc class StringConvertibleInDebugAndOtherwise_Native : NSObject {
|
|
override var description: String { return "description" }
|
|
override var debugDescription: String { return "debugDescription" }
|
|
}
|
|
|
|
Reflection.test("NSObject is properly CustomDebugStringConvertible") {
|
|
let objectNative = StringConvertibleInDebugAndOtherwise_Native()
|
|
let objectObjC = StringConvertibleInDebugAndOtherwise_ObjC()
|
|
|
|
expectEqual(String(reflecting: objectNative), objectNative.debugDescription)
|
|
expectEqual(String(reflecting: objectObjC), objectObjC.debugDescription)
|
|
}
|
|
|
|
Reflection.test("NSRange QuickLook") {
|
|
let rng = NSRange(location:Int.min, length:5)
|
|
let ql = PlaygroundQuickLook(reflecting: rng)
|
|
switch ql {
|
|
case .range(let loc, let len):
|
|
expectEqual(loc, Int64(Int.min))
|
|
expectEqual(len, 5)
|
|
default:
|
|
expectUnreachable("PlaygroundQuickLook for NSRange did not match Range")
|
|
}
|
|
}
|
|
|
|
class SomeSubclass : SomeClass {}
|
|
|
|
var ObjCConformsToProtocolTestSuite = TestSuite("ObjCConformsToProtocol")
|
|
|
|
ObjCConformsToProtocolTestSuite.test("cast/instance") {
|
|
expectTrue(SomeClass() is SomeObjCProto)
|
|
expectTrue(SomeSubclass() is SomeObjCProto)
|
|
}
|
|
|
|
ObjCConformsToProtocolTestSuite.test("cast/metatype") {
|
|
expectTrue(SomeClass.self is SomeObjCProto.Type)
|
|
expectTrue(SomeSubclass.self is SomeObjCProto.Type)
|
|
}
|
|
|
|
// https://github.com/apple/swift/issues/49905
|
|
|
|
extension Optional where Wrapped == NSData {
|
|
private class Inner {
|
|
}
|
|
|
|
var asInner: Inner {
|
|
return Inner()
|
|
}
|
|
}
|
|
|
|
var RuntimeClassNamesTestSuite = TestSuite("runtime class names")
|
|
|
|
RuntimeClassNamesTestSuite.test("private class nested in same-type-constrained extension") {
|
|
let base: NSData? = nil
|
|
let util = base.asInner
|
|
|
|
let clazz = unsafeBitCast(type(of: util), to: NSObject.self)
|
|
let desc = clazz.description
|
|
expectEqual("_TtCE1a", desc.prefix(7))
|
|
expectEqual("Inner", desc.suffix(5))
|
|
}
|
|
|
|
runAllTests()
|