blob: 8eb9821dad94c64a0d1f5d5448a38f8679d474d4 [file] [log] [blame]
// RUN: %target-typecheck-verify-swift %clang-importer-sdk -I %S/Inputs/custom-modules
// RUN: not %target-swift-frontend -typecheck %clang-importer-sdk -I %S/Inputs/custom-modules %s 2>&1 | %FileCheck %s
// REQUIRES: OS=macosx
// REQUIRES: objc_interop
import Foundation
// Tests for uses of version-based potential unavailability imported from ObjC APIs.
func callUnavailableObjC() {
// expected-note@-1 5{{add @available attribute to enclosing global function}}
_ = NSAvailableOn10_51() // expected-error {{'NSAvailableOn10_51' is only available on OS X 10.51 or newer}}
// expected-note@-1 {{add 'if #available' version check}}
if #available(OSX 10.51, *) {
let o = NSAvailableOn10_51()!
// Properties
_ = o.propertyOn10_52 // expected-error {{'propertyOn10_52' is only available on OS X 10.52 or newer}}
// expected-note@-1 {{add 'if #available' version check}}
o.propertyOn10_52 = 22 // expected-error {{'propertyOn10_52' is only available on OS X 10.52 or newer}}
// expected-note@-1 {{add 'if #available' version check}}
// Methods
o.methodAvailableOn10_52() // expected-error {{'methodAvailableOn10_52()' is only available on OS X 10.52 or newer}}
// expected-note@-1 {{add 'if #available' version check}}
// Initializers
_ = NSAvailableOn10_51(stringOn10_52:"Hi") // expected-error {{'init(stringOn10_52:)' is only available on OS X 10.52 or newer}}
// expected-note@-1 {{add 'if #available' version check}}
}
}
// Declarations with Objective-C-originated potentially unavailable APIs
func functionWithObjCParam(o: NSAvailableOn10_51) { // expected-error {{'NSAvailableOn10_51' is only available on OS X 10.51 or newer}}
// expected-note@-1 {{add @available attribute to enclosing global function}}
}
class ClassExtendingUnvailableClass : NSAvailableOn10_51 { // expected-error {{'NSAvailableOn10_51' is only available on OS X 10.51 or newer}}
// expected-note@-1 {{add @available attribute to enclosing class}}
}
// We allow classes to conform to potentially unavailable protocols
class ClassAdoptingUnavailableProtocol : NSProtocolAvailableOn10_51 {
}
class SomeSoonToBeConformingClass { }
extension SomeSoonToBeConformingClass : NSProtocolAvailableOn10_51 {
}
// Enums from Objective-C
let _: NSPotentiallyUnavailableOptions = .first // expected-error {{'NSPotentiallyUnavailableOptions' is only available on OS X 10.51 or newer}}
// expected-note@-1 {{add 'if #available' version check}}
let _: NSOptionsWithUnavailableElement = .third // expected-error {{'third' is only available on OS X 10.51 or newer}}
// expected-note@-1 {{add 'if #available' version check}}
let _: NSUnavailableEnum = .first // expected-error {{'NSUnavailableEnum' is only available on OS X 10.51 or newer}}
// expected-note@-1 {{add 'if #available' version check}}
let _: NSEnumWithUnavailableElement = .third // expected-error {{'third' is only available on OS X 10.51 or newer}}
// expected-note@-1 {{add 'if #available' version check}}
// Differing availability on getters and setters imported from ObjC.
func gettersAndSettersFromObjC(o: NSAvailableOn10_9) {
// expected-note@-1 6{{add @available attribute to enclosing global function}}
let _: Int = o.propertyOn10_51WithSetterOn10_52After // expected-error {{'propertyOn10_51WithSetterOn10_52After' is only available on OS X 10.51 or newer}}
// expected-note@-1 {{add 'if #available' version check}}
if #available(OSX 10.51, *) {
// Properties with unavailable accessors declared before property in Objective-C header
o.propertyOn10_51WithSetterOn10_52Before = 5 // expected-error {{setter for 'propertyOn10_51WithSetterOn10_52Before' is only available on OS X 10.52 or newer}}
// expected-note@-1 {{add 'if #available' version check}}
let _: Int = o.propertyOn10_51WithGetterOn10_52Before // expected-error {{getter for 'propertyOn10_51WithGetterOn10_52Before' is only available on OS X 10.52 or newer}}
// expected-note@-1 {{add 'if #available' version check}}
// Properties with unavailable accessors declared after property in Objective-C header
o.propertyOn10_51WithSetterOn10_52After = 5 // expected-error {{setter for 'propertyOn10_51WithSetterOn10_52After' is only available on OS X 10.52 or newer}}
// expected-note@-1 {{add 'if #available' version check}}
let _: Int = o.propertyOn10_51WithGetterOn10_52After // expected-error {{getter for 'propertyOn10_51WithGetterOn10_52After' is only available on OS X 10.52 or newer}}
// expected-note@-1 {{add 'if #available' version check}}
// Property with unavailable setter redeclared in Objective-C category
o.readOnlyRedeclaredWithSetterInCategory = 5 // expected-error {{setter for 'readOnlyRedeclaredWithSetterInCategory' is only available on OS X 10.52 or newer}}
// expected-note@-1 {{add 'if #available' version check}}
}
}
// Globals from Objective-C
func useGlobalsFromObjectiveC() {
// expected-note@-1 3{{add @available attribute to enclosing global function}}
_ = globalStringAvailableOn10_51 // expected-error {{'globalStringAvailableOn10_51' is only available on OS X 10.51 or newer}}
// expected-note@-1 {{add 'if #available' version check}}
_ = globalStringAvailableOn10_52 // expected-error {{'globalStringAvailableOn10_52' is only available on OS X 10.52 or newer}}
// expected-note@-1 {{add 'if #available' version check}}
_ = globalClassInstanceAvailableOn10_51 // expected-error {{'globalClassInstanceAvailableOn10_51' is only available on OS X 10.51 or newer}}
// expected-note@-1 {{add 'if #available' version check}}
if #available(OSX 10.51, *) {
_ = globalStringAvailableOn10_51
let _: NSAvailableOn10_51 = globalClassInstanceAvailableOn10_51
}
}
// Optional Protocol Requirements from Objective-C
// Make sure we're not emitting errors in the Foundation module, where the witness is.
// CHECK-NOT: Foundation.ClassWithMethodFromNSProtocolWithOptionalRequirement:
class SubclassOfNSClassWithMethodFromNSProtocolWithOptionalRequirement : NSClassWithMethodFromNSProtocolWithOptionalRequirement {
}
class SubclassWithItsOwnAvailableWitnessOfNSClassWithMethodFromNSProtocolWithOptionalRequirement : NSClassWithMethodFromNSProtocolWithOptionalRequirement {
override func optionalRequirement() { }
}
// Inference of protocol requirement availability when checking conformance to
// unannotated Objective-C protocols
class UserClass : UnannotatedFrameworkProtocol {
@available(OSX 10.51, *)
@objc(doSomethingWithClass:)
func doSomething(with k: AnnotatedFrameworkClass?) { }
@available(OSX 10.51, *)
@objc
func doSomething(withNonNullableClass k: AnnotatedFrameworkClass) { }
@available(OSX 10.51, *)
@objc(doSomethingWithIUOClass:)
func doSomething(withIUOClass k: AnnotatedFrameworkClass!) { }
@objc
@available(OSX 10.51, *)
func returnSomething() -> AnnotatedFrameworkClass? {
return nil
}
@objc
func noUnavailableTypesInSignature() { }
@objc(doSomethingWithClass:andLaterClass:) @available(OSX 10.52, *)
func doSomething(with k: AnnotatedFrameworkClass, andLaterClass lk: AnnotatedLaterFrameworkClass) { }
@objc
@available(OSX 10.53, *)
func someMethodWithAvailability() { }
@available(OSX 10.51, *)
@objc var someProperty: AnnotatedFrameworkClass {
get { return AnnotatedFrameworkClass() }
set(newValue) { }
}
}
func callViaUnannotatedFrameworkProtocol(p: UnannotatedFrameworkProtocol) {
// expected-note@-1 {{add @available attribute to enclosing global function}}
let _ = p.returnSomething() // expected-error {{'returnSomething()' is only available on OS X 10.51 or newer}}
// expected-note@-1 {{add 'if #available' version check}}
}
func callViaAnnotatedFrameworkProtocol(p: AnnotatedFrameworkProtocol) {
// We won't synthesize availability for AnnotatedFrameworkProtocol because
// the protocol has an availability annotation on it.
let _ = p.returnSomething()
}
class SubclassOfFrameworkClassConformingToUnannotatedFrameworkProtocol : FrameworkClassConformingToUnannotatedFrameworkProtocol {
@available(OSX 10.51, *)
override func doSomething(withNonNullableClass k: AnnotatedFrameworkClass) {
}
@available(OSX 10.51, *)
override var someProperty: AnnotatedFrameworkClass {
get { return AnnotatedFrameworkClass() }
set(newValue) { }
}
@available(OSX 10.52, *)
override func doSomething(withIUOClass k: AnnotatedFrameworkClass!) { } // expected-error {{'doSomething' must be as available as declaration it overrides}}
}
@available(OSX 10.52, *)
class SubclassOfLaterFrameworkClassConformingToUnannotatedFrameworkProtocol : LaterFrameworkClassConformingToUnannotatedFrameworkProtocol {
@available(OSX 10.52, *)
override func doSomething(withNonNullableClass k: AnnotatedFrameworkClass) {
}
@available(OSX 10.53, *)
override func someMethodWithAvailability() { }
}
class SubclassOfFrameworkClassConformingToLaterAnnotatedFrameworkProtocol : FrameworkClassConformingToLaterAnnotatedFrameworkProtocol {
@available(OSX 10.52, *)
override func returnSomething() -> AnnotatedFrameworkClass? {
}
@available(OSX 10.53, *)
override func someMethodWithAvailability() { }
@available(OSX 10.52, *)
override var someProperty: AnnotatedFrameworkClass {
get { return AnnotatedFrameworkClass() }
set(newValue) { }
}
}