mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
175 lines
5.1 KiB
Swift
175 lines
5.1 KiB
Swift
// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk) -disable-objc-attr-requires-foundation-module -typecheck %s -verify
|
|
import ObjectiveC
|
|
|
|
// REQUIRES: objc_interop
|
|
|
|
@objc class A { }
|
|
@objc class B { }
|
|
|
|
class C1 {
|
|
@objc init(a: A, b: B) { }
|
|
|
|
@objc func method1(_ a: A, b: B) { }
|
|
@objc(someMethodWithA:B:) func method2(_ a: A, b: B) { }
|
|
|
|
@objc class func method3(_ a: A, b: B) { } // expected-note{{found this candidate}}
|
|
@objc class func method3(a: A, b: B) { } // expected-note{{found this candidate}}
|
|
|
|
@objc(ambiguous1:b:) class func ambiguous(a: A, b: A) { } // expected-note{{found this candidate}}
|
|
@objc(ambiguous2:b:) class func ambiguous(a: A, b: B) { } // expected-note{{found this candidate}}
|
|
|
|
@objc func getC1() -> AnyObject { return self }
|
|
|
|
@objc func testUnqualifiedSelector(_ a: A, b: B) {
|
|
_ = #selector(testUnqualifiedSelector(_:b:))
|
|
let testUnqualifiedSelector = 1
|
|
_ = #selector(testUnqualifiedSelector(_:b:))
|
|
_ = testUnqualifiedSelector // suppress unused warning
|
|
}
|
|
|
|
@objc func testParam(_ testParam: A) { // expected-note{{'testParam' declared here}}
|
|
_ = #selector(testParam) // expected-error{{argument of '#selector' cannot refer to parameter 'testParam'}}
|
|
}
|
|
|
|
@objc func testVariable() {
|
|
let testVariable = 1 // expected-note{{'testVariable' declared here}}
|
|
_ = #selector(testVariable) // expected-error{{argument of '#selector' cannot refer to variable 'testVariable'}}
|
|
}
|
|
}
|
|
|
|
@objc protocol P1 {
|
|
func method4(_ a: A, b: B)
|
|
static func method5(_ a: B, b: B)
|
|
}
|
|
|
|
extension C1 {
|
|
final func method6() { } // expected-note{{add '@objc' to expose this instance method to Objective-C}}{{3-3=@objc }}
|
|
}
|
|
|
|
func testSelector(_ c1: C1, p1: P1, obj: AnyObject) {
|
|
// Instance methods on an instance
|
|
let sel1 = #selector(c1.method1)
|
|
_ = #selector(c1.method1(_:b:))
|
|
_ = #selector(c1.method2)
|
|
|
|
// Instance methods on a class.
|
|
_ = #selector(C1.method1)
|
|
_ = #selector(C1.method1(_:b:))
|
|
_ = #selector(C1.method2)
|
|
|
|
// Class methods on a class.
|
|
_ = #selector(C1.method3(_:b:))
|
|
_ = #selector(C1.method3(a:b:))
|
|
|
|
// Methods on a protocol.
|
|
_ = #selector(P1.method4)
|
|
_ = #selector(P1.method4(_:b:))
|
|
_ = #selector(P1.method5) // expected-error{{static member 'method5' cannot be used on protocol metatype '(any P1).Type'}}
|
|
_ = #selector(P1.method5(_:b:)) // expected-error{{static member 'method5(_:b:)' cannot be used on protocol metatype '(any P1).Type'}}
|
|
_ = #selector(p1.method4)
|
|
_ = #selector(p1.method4(_:b:))
|
|
_ = #selector(type(of: p1).method5)
|
|
_ = #selector(type(of: p1).method5(_:b:))
|
|
|
|
// Interesting expressions that refer to methods.
|
|
_ = #selector(Swift.AnyObject.method1)
|
|
_ = #selector(AnyObject.method1!)
|
|
// expected-error@-1 {{cannot force unwrap value of non-optional type '(AnyObject) -> ((A, B) -> ())?'}}
|
|
_ = #selector(obj.getC1?().method1)
|
|
|
|
// Initializers
|
|
_ = #selector(C1.init(a:b:))
|
|
|
|
// Make sure the result has type "ObjectiveC.Selector"
|
|
let sel2: Selector
|
|
sel2 = sel1
|
|
_ = sel2
|
|
|
|
let dict: [Selector: Int] = [:]
|
|
let _: Int? = dict[#selector(c1.method1)]
|
|
let _ = [#selector(c1.method1)]
|
|
}
|
|
|
|
func testAmbiguity() {
|
|
_ = #selector(C1.method3) // expected-error{{ambiguous use of 'method3'}}
|
|
_ = #selector(C1.ambiguous) // expected-error{{ambiguous use of 'ambiguous(a:b:)'}}
|
|
}
|
|
|
|
func testUnusedSelector() {
|
|
#selector(C1.getC1) // expected-warning{{result of '#selector' is unused}}
|
|
}
|
|
|
|
func testNonObjC(_ c1: C1) {
|
|
_ = #selector(c1.method6) // expected-error{{argument of '#selector' refers to instance method 'method6()' that is not exposed to Objective-C}}
|
|
}
|
|
|
|
func testParseErrors1() {
|
|
_ = #selector foo // expected-error{{expected '(' following '#selector'}}
|
|
}
|
|
|
|
func testParseErrors2() {
|
|
_ = #selector( // expected-error{{expected expression naming a method within '#selector(...)'}}
|
|
}
|
|
|
|
func testParseErrors3(_ c1: C1) {
|
|
_ = #selector( // expected-note{{to match this opening '('}}
|
|
c1.method1(_:b:) // expected-error{{expected ')' to complete '#selector' expression}}
|
|
}
|
|
|
|
func testParseErrors4() {
|
|
_ = #selector(C1.subscript) // expected-error{{type 'C1' has no member 'subscript'}}
|
|
}
|
|
|
|
// https://github.com/apple/swift/issues/44436
|
|
do {
|
|
let optionalSel: Selector?
|
|
|
|
switch optionalSel {
|
|
case #selector(C1.method1)?:
|
|
break
|
|
default:
|
|
break
|
|
}
|
|
|
|
@objc class C {
|
|
@objc func bar() {}
|
|
}
|
|
|
|
switch optionalSel {
|
|
case #selector(C.bar):
|
|
break
|
|
case #selector(C.bar)!: // expected-error{{cannot force unwrap value of non-optional type 'Selector'}}
|
|
break
|
|
case #selector(C.bar)?:
|
|
break
|
|
default:
|
|
break
|
|
}
|
|
}
|
|
|
|
// https://github.com/apple/swift/issues/51857
|
|
|
|
protocol SomeProtocol {
|
|
func someFunction()
|
|
func anotherFunction()
|
|
}
|
|
|
|
extension SomeProtocol {
|
|
func someFunction() {
|
|
let _ = #selector(anotherFunction) // expected-error {{cannot use 'anotherFunction' as a selector because protocol 'SomeProtocol' is not exposed to Objective-C}} {{none}}
|
|
}
|
|
|
|
func anotherFunction() {
|
|
print("Hello world!")
|
|
}
|
|
}
|
|
|
|
@objc class OverloadedFuncAndProperty {
|
|
@objc static func f() {}
|
|
@objc var f: Int { 0 }
|
|
}
|
|
|
|
func test() -> Selector {
|
|
#selector(OverloadedFuncAndProperty.f)
|
|
}
|