Files
swift-mirror/test/SILGen/keypaths_objc.swift
Joe Groff f7fc74332c AST: Property requirements in @objc protocols should return true for requiresForeignGetterAndSetter.
We need to use ObjC dispatch to get to the witness of an ObjC protocol requirement. The wrong answer here was causing us to do the wrong thing when producing identifiers for key paths that refer to ObjC protocol requirements.
2017-12-18 12:29:14 -08:00

91 lines
2.9 KiB
Swift

// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk) -emit-silgen -import-objc-header %S/Inputs/keypaths_objc.h %s | %FileCheck %s
// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk) -emit-ir -import-objc-header %S/Inputs/keypaths_objc.h %s
// REQUIRES: objc_interop
import Foundation
struct NonObjC {
var x: Int
var y: NSObject
}
class Foo: NSObject {
@objc var int: Int { fatalError() }
@objc var bar: Bar { fatalError() }
var nonobjc: NonObjC { fatalError() }
@objc(thisIsADifferentName) var differentName: Bar { fatalError() }
@objc subscript(x: Int) -> Foo { return self }
@objc subscript(x: Bar) -> Foo { return self }
dynamic var dyn: String { fatalError() }
}
class Bar: NSObject {
@objc var foo: Foo { fatalError() }
}
// CHECK-LABEL: sil hidden @_T013keypaths_objc0B8KeypathsyyF
func objcKeypaths() {
// CHECK: keypath $WritableKeyPath<NonObjC, Int>, (root
_ = \NonObjC.x
// CHECK: keypath $WritableKeyPath<NonObjC, NSObject>, (root
_ = \NonObjC.y
// CHECK: keypath $KeyPath<Foo, Int>, (objc "int"
_ = \Foo.int
// CHECK: keypath $KeyPath<Foo, Bar>, (objc "bar"
_ = \Foo.bar
// CHECK: keypath $KeyPath<Foo, Foo>, (objc "bar.foo"
_ = \Foo.bar.foo
// CHECK: keypath $KeyPath<Foo, Bar>, (objc "bar.foo.bar"
_ = \Foo.bar.foo.bar
// CHECK: keypath $KeyPath<Foo, NonObjC>, (root
_ = \Foo.nonobjc
// CHECK: keypath $KeyPath<Foo, NSObject>, (root
_ = \Foo.bar.foo.nonobjc.y
// CHECK: keypath $KeyPath<Foo, Bar>, (objc "thisIsADifferentName"
_ = \Foo.differentName
}
// CHECK-LABEL: sil hidden @_T013keypaths_objc0B18KeypathIdentifiersyyF
func objcKeypathIdentifiers() {
// CHECK: keypath $KeyPath<ObjCFoo, String>, (objc "objcProp"; {{.*}} id #ObjCFoo.objcProp!getter.1.foreign
_ = \ObjCFoo.objcProp
// CHECK: keypath $KeyPath<Foo, String>, (objc "dyn"; {{.*}} id #Foo.dyn!getter.1.foreign
_ = \Foo.dyn
// CHECK: keypath $KeyPath<Foo, Int>, (objc "int"; {{.*}} id #Foo.int!getter.1 :
_ = \Foo.int
}
struct X {}
extension NSObject {
var x: X { return X() }
@objc var objc: Int { return 0 }
@objc dynamic var dynamic: Int { return 0 }
}
// CHECK-LABEL: sil hidden @{{.*}}nonobjcExtensionOfObjCClass
func nonobjcExtensionOfObjCClass() {
// Should be treated as a statically-dispatch property
// CHECK: keypath $KeyPath<NSObject, X>, ({{.*}} id @
_ = \NSObject.x
// CHECK: keypath $KeyPath<NSObject, Int>, ({{.*}} id #NSObject.objc!getter.1.foreign
_ = \NSObject.objc
// CHECK: keypath $KeyPath<NSObject, Int>, ({{.*}} id #NSObject.dynamic!getter.1.foreign
_ = \NSObject.dynamic
}
@objc protocol ObjCProto {
var objcRequirement: Int { get set }
}
// CHECK-LABEL: sil hidden @{{.*}}ProtocolRequirement
func objcProtocolRequirement<T: ObjCProto>(_: T) {
// CHECK: keypath {{.*}} id #ObjCProto.objcRequirement!getter.1.foreign
_ = \T.objcRequirement
// CHECK: keypath {{.*}} id #ObjCProto.objcRequirement!getter.1.foreign
_ = \ObjCProto.objcRequirement
}