blob: d868ed4591f505528c1965ac4f99bb091a4816f9 [file] [log] [blame]
// 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())
// Problem with field alignment in direct generic subclass of NSObject -
// <https://bugs.swift.org/browse/SR-2586>
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())
}