mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
329 lines
6.7 KiB
Swift
329 lines
6.7 KiB
Swift
// RUN: %empty-directory(%t)
|
|
//
|
|
// RUN: %target-clang -fobjc-arc %S/Inputs/ObjCClasses/ObjCClasses.m -c -o %t/ObjCClasses.o
|
|
// RUN: %target-build-swift -I %S/Inputs/ObjCClasses/ -Xlinker %t/ObjCClasses.o %s -o %t/a.out
|
|
// RUN: %target-codesign %t/a.out
|
|
// RUN: %target-run %t/a.out | %FileCheck %s
|
|
|
|
// REQUIRES: executable_test
|
|
// REQUIRES: objc_interop
|
|
|
|
import Foundation
|
|
import ObjCClasses
|
|
|
|
@objc protocol P {
|
|
func calculatePrice() -> Int
|
|
}
|
|
|
|
protocol PP {
|
|
func calculateTaxes() -> Int
|
|
}
|
|
|
|
//
|
|
// Generic subclass of an @objc class
|
|
//
|
|
|
|
class A<T> : HasHiddenIvars, P {
|
|
var first: Int = 16
|
|
var second: T?
|
|
var third: Int = 61
|
|
|
|
override var description: String {
|
|
return "Grilled artichokes"
|
|
}
|
|
|
|
func calculatePrice() -> Int {
|
|
return 400
|
|
}
|
|
}
|
|
|
|
let a = A<Int>()
|
|
|
|
// CHECK: Grilled artichokes
|
|
// CHECK: Grilled artichokes
|
|
print(a.description)
|
|
print((a as NSObject).description)
|
|
|
|
let f = { (a.x, a.y, a.z, a.t, a.first, a.second, a.third) }
|
|
|
|
// CHECK: (0, 0, 0, 0, 16, nil, 61)
|
|
print(f())
|
|
|
|
// CHECK: (25, 225, 255, 2255, 16, nil, 61)
|
|
a.x = 25
|
|
a.y = 225
|
|
a.z = 255
|
|
a.t = 2255
|
|
print(f())
|
|
|
|
// CHECK: (36, 225, 255, 2255, 16, nil, 61)
|
|
a.x = 36
|
|
print(f())
|
|
|
|
// CHECK: (36, 225, 255, 2255, 16, Optional(121), 61)
|
|
a.second = 121
|
|
print(f())
|
|
|
|
//
|
|
// Instantiate the class with a different set of generic parameters
|
|
//
|
|
|
|
let aa = A<(Int, Int)>()
|
|
let ff = { (aa.x, aa.y, aa.z, aa.t, aa.first, aa.second, aa.third) }
|
|
|
|
// CHECK: (0, 0, 0, 0, 16, nil, 61)
|
|
print(ff())
|
|
|
|
aa.x = 101
|
|
aa.second = (19, 84)
|
|
aa.third = 17
|
|
|
|
// CHECK: (101, 0, 0, 0, 16, Optional((19, 84)), 17)
|
|
print(ff())
|
|
|
|
//
|
|
// Concrete subclass of generic subclass of @objc class
|
|
//
|
|
|
|
class B : A<(Int, Int)> {
|
|
override var description: String {
|
|
return "Salmon"
|
|
}
|
|
|
|
@nonobjc override func calculatePrice() -> Int {
|
|
return 1675
|
|
}
|
|
}
|
|
|
|
class BB : B {}
|
|
|
|
class C : A<(Int, Int)>, PP {
|
|
@nonobjc override var description: String {
|
|
return "Invisible Chicken"
|
|
}
|
|
|
|
override func calculatePrice() -> Int {
|
|
return 650
|
|
}
|
|
|
|
func calculateTaxes() -> Int {
|
|
return 110
|
|
}
|
|
}
|
|
|
|
// CHECK: 400
|
|
// CHECK: 400
|
|
// CHECK: 650
|
|
// CHECK: 110
|
|
print((BB() as P).calculatePrice())
|
|
print((B() as P).calculatePrice())
|
|
print((C() as P).calculatePrice())
|
|
print((C() as PP).calculateTaxes())
|
|
|
|
// CHECK: Salmon
|
|
// CHECK: Grilled artichokes
|
|
print((B() as NSObject).description)
|
|
print((C() as NSObject).description)
|
|
|
|
let b = B()
|
|
let g = { (b.x, b.y, b.z, b.t, b.first, b.second, b.third) }
|
|
|
|
// CHECK: (0, 0, 0, 0, 16, nil, 61)
|
|
print(g())
|
|
|
|
b.x = 101
|
|
b.second = (19, 84)
|
|
b.third = 17
|
|
|
|
// CHECK: (101, 0, 0, 0, 16, Optional((19, 84)), 17)
|
|
print(g())
|
|
|
|
//
|
|
// Generic subclass of @objc class without any generically-sized members
|
|
//
|
|
|
|
class FixedA<T> : HasHiddenIvars, P {
|
|
var first: Int = 16
|
|
var second: [T] = []
|
|
var third: Int = 61
|
|
|
|
override var description: String {
|
|
return "Grilled artichokes"
|
|
}
|
|
|
|
func calculatePrice() -> Int {
|
|
return 400
|
|
}
|
|
}
|
|
|
|
let fixedA = FixedA<Int>()
|
|
|
|
// CHECK: Grilled artichokes
|
|
// CHECK: Grilled artichokes
|
|
print(fixedA.description)
|
|
print((fixedA as NSObject).description)
|
|
|
|
let fixedF = { (fixedA.x, fixedA.y, fixedA.z, fixedA.t, fixedA.first, fixedA.second, fixedA.third) }
|
|
|
|
// CHECK: (0, 0, 0, 0, 16, [], 61)
|
|
print(fixedF())
|
|
|
|
// CHECK: (25, 225, 255, 2255, 16, [], 61)
|
|
fixedA.x = 25
|
|
fixedA.y = 225
|
|
fixedA.z = 255
|
|
fixedA.t = 2255
|
|
print(fixedF())
|
|
|
|
// CHECK: (36, 225, 255, 2255, 16, [], 61)
|
|
fixedA.x = 36
|
|
print(fixedF())
|
|
|
|
// CHECK: (36, 225, 255, 2255, 16, [121], 61)
|
|
fixedA.second = [121]
|
|
print(fixedF())
|
|
|
|
//
|
|
// Instantiate the class with a different set of generic parameters
|
|
//
|
|
|
|
let fixedAA = FixedA<(Int, Int)>()
|
|
let fixedFF = { (fixedAA.x, fixedAA.y, fixedAA.z, fixedAA.t, fixedAA.first, fixedAA.second, fixedAA.third) }
|
|
|
|
// CHECK: (0, 0, 0, 0, 16, [], 61)
|
|
print(fixedFF())
|
|
|
|
fixedAA.x = 101
|
|
fixedAA.second = [(19, 84)]
|
|
fixedAA.third = 17
|
|
|
|
// CHECK: (101, 0, 0, 0, 16, [(19, 84)], 17)
|
|
print(fixedFF())
|
|
|
|
//
|
|
// Concrete subclass of generic subclass of @objc class
|
|
// without any generically-sized members
|
|
//
|
|
|
|
class FixedB : FixedA<Int> {
|
|
override var description: String {
|
|
return "Salmon"
|
|
}
|
|
|
|
override func calculatePrice() -> Int {
|
|
return 1675
|
|
}
|
|
}
|
|
|
|
// CHECK: 675
|
|
print((FixedB() as P).calculatePrice())
|
|
|
|
// CHECK: Salmon
|
|
print((FixedB() as NSObject).description)
|
|
|
|
let fixedB = FixedB()
|
|
let fixedG = { (fixedB.x, fixedB.y, fixedB.z, fixedB.t, fixedB.first, fixedB.second, fixedB.third) }
|
|
|
|
// CHECK: (0, 0, 0, 0, 16, [], 61)
|
|
print(fixedG())
|
|
|
|
fixedB.x = 101
|
|
fixedB.second = [19, 84]
|
|
fixedB.third = 17
|
|
|
|
// CHECK: (101, 0, 0, 0, 16, [19, 84], 17)
|
|
print(fixedG())
|
|
|
|
// https://github.com/apple/swift/issues/45191
|
|
// Problem with field alignment in direct generic subclass of 'NSObject'.
|
|
|
|
public class PandorasBox<T>: NSObject {
|
|
final public var value: T
|
|
|
|
public init(_ value: T) {
|
|
// Uses ConstantIndirect access pattern
|
|
self.value = value
|
|
}
|
|
}
|
|
|
|
let c = PandorasBox(30)
|
|
// CHECK: 30
|
|
// Uses ConstantDirect access pattern
|
|
print(c.value)
|
|
|
|
// Super method calls from a generic subclass of an @objc class
|
|
class HasDynamicMethod : NSObject {
|
|
@objc dynamic class func funkyTown() {
|
|
print("Here we are with \(self)")
|
|
}
|
|
}
|
|
|
|
class GenericOverrideOfDynamicMethod<T> : HasDynamicMethod {
|
|
override class func funkyTown() {
|
|
print("Hello from \(self) with T = \(T.self)")
|
|
super.funkyTown()
|
|
print("Goodbye from \(self) with T = \(T.self)")
|
|
}
|
|
}
|
|
|
|
class ConcreteOverrideOfDynamicMethod : GenericOverrideOfDynamicMethod<Int> {
|
|
override class func funkyTown() {
|
|
print("Hello from \(self)")
|
|
super.funkyTown()
|
|
print("Goodbye from \(self)")
|
|
}
|
|
}
|
|
|
|
// CHECK: Hello from ConcreteOverrideOfDynamicMethod
|
|
// CHECK: Hello from ConcreteOverrideOfDynamicMethod with T = Int
|
|
// CHECK: Here we are with ConcreteOverrideOfDynamicMethod
|
|
// CHECK: Goodbye from ConcreteOverrideOfDynamicMethod with T = Int
|
|
// CHECK: Goodbye from ConcreteOverrideOfDynamicMethod
|
|
ConcreteOverrideOfDynamicMethod.funkyTown()
|
|
|
|
class Foo {}
|
|
class Bar {}
|
|
class DependOnAlignOf<T> : HasHiddenIvars2 {
|
|
var first = Foo()
|
|
var second = Bar()
|
|
var third: T?
|
|
}
|
|
|
|
let ad = DependOnAlignOf<Double>()
|
|
let ai = DependOnAlignOf<Int>()
|
|
|
|
do {
|
|
let fd = { (ad.x, ad.first, ad.second, ad.third) }
|
|
let fi = { (ai.x, ai.first, ai.second, ai.third) }
|
|
|
|
// CHECK: (nil, a.Foo, a.Bar, nil)
|
|
print(fd())
|
|
|
|
// CHECK: (nil, a.Foo, a.Bar, nil)
|
|
print(fi())
|
|
}
|
|
|
|
// Same as above, but there's another class in between the
|
|
// Objective-C class and us
|
|
class HasHiddenIvars3 : HasHiddenIvars2 { }
|
|
|
|
class AlsoDependOnAlignOf<T> : HasHiddenIvars3 {
|
|
var first = Foo()
|
|
var second = Bar()
|
|
var third: T?
|
|
}
|
|
|
|
do {
|
|
let ad = AlsoDependOnAlignOf<Double>()
|
|
let ai = AlsoDependOnAlignOf<Int>()
|
|
|
|
let fd = { (ad.x, ad.first, ad.second, ad.third) }
|
|
let fi = { (ai.x, ai.first, ai.second, ai.third) }
|
|
|
|
// CHECK: (nil, a.Foo, a.Bar, nil)
|
|
print(fd())
|
|
|
|
// CHECK: (nil, a.Foo, a.Bar, nil)
|
|
print(fi())
|
|
}
|