mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
...and collapse StaticVar/ClassVar and StaticLet/ClassLet into StaticProperty/ClassProperty. "var" and "let" aren't great nouns to use in diagnostics to begin with, especially alongside semantic terms like "instance method". Focus on the type vs. non-type aspect instead with "property", which better matches how people talk about member vars (and lets) anyway.
238 lines
10 KiB
Swift
238 lines
10 KiB
Swift
// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk) -disable-objc-attr-requires-foundation-module -typecheck -primary-file %s %S/Inputs/property_helper.swift -verify -swift-version 4
|
|
import ObjectiveC
|
|
|
|
// REQUIRES: objc_interop
|
|
|
|
@objc class HelperClass: NSObject {}
|
|
|
|
struct Wrapper {
|
|
var objcInstance = ObjCClass()
|
|
}
|
|
|
|
class ObjCClass {
|
|
@objc var myProperty = HelperClass()
|
|
@objc let myConstant = HelperClass() // expected-note 4{{'myConstant' declared here}}
|
|
@objc var myComputedReadOnlyProperty: HelperClass { // expected-note 2{{'myComputedReadOnlyProperty' declared here}}
|
|
get {
|
|
return HelperClass()
|
|
}
|
|
}
|
|
@objc var myComputedReadWriteProperty: HelperClass {
|
|
get {
|
|
return HelperClass()
|
|
}
|
|
set {
|
|
}
|
|
}
|
|
|
|
@objc func myFunc() {}
|
|
@objc class func myClassFunc() {}
|
|
|
|
func instanceMethod() {
|
|
let _ = #selector(myFunc)
|
|
let _ = #selector(getter: myProperty)
|
|
let _ = #selector(setter: myProperty)
|
|
let _ = #selector(setter: myComputedReadWriteProperty)
|
|
|
|
let _ = #selector(setter: myConstant) // expected-error {{argument of '#selector(setter:)' refers to non-settable property 'myConstant'}}
|
|
let _ = #selector(setter: myComputedReadOnlyProperty) // expected-error {{argument of '#selector(setter:)' refers to non-settable property 'myComputedReadOnlyProperty'}}
|
|
|
|
let _ = #selector(myClassFunc) // expected-error{{static member 'myClassFunc' cannot be used on instance of type 'ObjCClass'}}
|
|
}
|
|
|
|
class func classMethod() {
|
|
let _ = #selector(myFunc)
|
|
let _ = #selector(getter: myProperty)
|
|
let _ = #selector(setter: myProperty)
|
|
let _ = #selector(setter: myComputedReadWriteProperty)
|
|
|
|
let _ = #selector(setter: myConstant) // expected-error {{argument of '#selector(setter:)' refers to non-settable property 'myConstant'}}
|
|
let _ = #selector(setter: myComputedReadOnlyProperty) // expected-error {{argument of '#selector(setter:)' refers to non-settable property 'myComputedReadOnlyProperty'}}
|
|
|
|
let _ = #selector(myClassFunc)
|
|
}
|
|
}
|
|
|
|
let myObjcInstance = ObjCClass()
|
|
let myWrapperInstance = Wrapper()
|
|
|
|
func testSimple(myObjcInstance: ObjCClass, myWrapperInstance: Wrapper) {
|
|
// Check cases that should work
|
|
let _ = #selector(ObjCClass.myFunc)
|
|
let _ = #selector(getter: ObjCClass.myProperty)
|
|
let _ = #selector(setter: ObjCClass.myProperty)
|
|
|
|
let _ = #selector(myObjcInstance.myFunc)
|
|
let _ = #selector(getter: myObjcInstance.myProperty)
|
|
let _ = #selector(setter: myObjcInstance.myProperty)
|
|
|
|
let _ = #selector(myWrapperInstance.objcInstance.myFunc)
|
|
let _ = #selector(getter: myWrapperInstance.objcInstance.myProperty)
|
|
let _ = #selector(setter: myWrapperInstance.objcInstance.myProperty)
|
|
}
|
|
|
|
func testWrongKind(myObjcInstance: ObjCClass, myWrapperInstance: Wrapper) {
|
|
|
|
// Referring to a property with a method selector or a method with a
|
|
// property selector
|
|
|
|
let _ = #selector(myObjcInstance.myProperty) // expected-error{{use 'getter:' or 'setter:' to refer to the Objective-C getter or setter of property 'myProperty', respectively}}
|
|
// expected-note@-1{{add 'getter:' to reference the Objective-C getter for 'myProperty'}}{{21-21=getter: }}
|
|
// expected-note@-2{{add 'setter:' to reference the Objective-C setter for 'myProperty'}}{{21-21=setter: }}
|
|
let _ = #selector(myObjcInstance.myComputedReadOnlyProperty) // expected-error{{use 'getter:' to refer to the Objective-C getter of property 'myComputedReadOnlyProperty'}}{{21-21=getter: }}
|
|
let _ = #selector(ObjCClass.myProperty) // expected-error{{use 'getter:' or 'setter:' to refer to the Objective-C getter or setter of property 'myProperty', respectively}}
|
|
// expected-note@-1{{add 'setter:' to reference the Objective-C setter for 'myProperty'}}{{21-21=setter: }}
|
|
// expected-note@-2{{add 'getter:' to reference the Objective-C getter for 'myProperty'}}{{21-21=getter: }}
|
|
|
|
// Referring to a method with a property selector
|
|
let _ = #selector(getter: myObjcInstance.myFunc) // expected-error{{cannot reference instance method 'myFunc()' as a property; remove 'getter:'}} {{21-29=}}
|
|
let _ = #selector(setter: myObjcInstance.myFunc) // expected-error{{cannot reference instance method 'myFunc()' as a property; remove 'setter:'}} {{21-29=}}
|
|
let _ = #selector(getter: ObjCClass.myFunc) // expected-error{{cannot reference instance method 'myFunc()' as a property; remove 'getter:'}} {{21-29=}}
|
|
let _ = #selector(setter: ObjCClass.myFunc) // expected-error{{cannot reference instance method 'myFunc()' as a property; remove 'setter:'}} {{21-29=}}
|
|
|
|
// Referring to a let property with a setter
|
|
let _ = #selector(setter: myObjcInstance.myConstant) // expected-error {{argument of '#selector(setter:)' refers to non-settable property 'myConstant'}}
|
|
let _ = #selector(setter: ObjCClass.myConstant) // expected-error {{argument of '#selector(setter:)' refers to non-settable property 'myConstant'}}
|
|
}
|
|
|
|
// Referring to non ObjC members
|
|
|
|
class NonObjCClass {
|
|
var nonObjCPropertyForGetter = HelperClass() // expected-note{{add '@objc' to expose this property to Objective-C}} {{3-3=@objc }}
|
|
var nonObjCPropertyForSetter = HelperClass() // expected-note{{add '@objc' to expose this property to Objective-C}} {{3-3=@objc }}
|
|
}
|
|
|
|
func testNonObjCMembers(nonObjCInstance: NonObjCClass) {
|
|
let _ = #selector(getter: nonObjCInstance.nonObjCPropertyForGetter) // expected-error{{argument of '#selector' refers to property 'nonObjCPropertyForGetter' that is not exposed to Objective-C}}
|
|
let _ = #selector(setter: nonObjCInstance.nonObjCPropertyForSetter) // expected-error{{argument of '#selector' refers to property 'nonObjCPropertyForSetter' that is not exposed to Objective-C}}
|
|
|
|
// Referencing undefined symbols
|
|
|
|
let _ = #selector(getter: UndefinedClass.myVariable) // expected-error{{use of unresolved identifier 'UndefinedClass'}}
|
|
let _ = #selector(getter: ObjCClass.undefinedProperty) // expected-error{{type 'ObjCClass' has no member 'undefinedProperty'}}
|
|
let _ = #selector(getter: myObjcInstance.undefinedProperty) // expected-error{{value of type 'ObjCClass' has no member 'undefinedProperty'}}
|
|
}
|
|
|
|
// Ambiguous expressions
|
|
func testAmbiguous(myObjcInstance: ObjCClass) { // expected-note{{'myObjcInstance' declared here}}
|
|
|
|
// Referring to a properties not within a type.
|
|
let myOtherObjcInstance = ObjCClass(); // expected-note{{'myOtherObjcInstance' declared here}}
|
|
let _ = #selector(getter: myObjcInstance) // expected-error{{argument of '#selector' cannot refer to parameter 'myObjcInstance'}}
|
|
let _ = #selector(getter: myOtherObjcInstance) // expected-error{{argument of '#selector' cannot refer to variable 'myOtherObjcInstance'}}
|
|
}
|
|
|
|
// Getter/setter is no keyword
|
|
let getter = HelperClass()
|
|
let setter = HelperClass()
|
|
|
|
// Referencing methods named getter and setter
|
|
class ObjCClassWithGetterSetter: NSObject {
|
|
@objc func getter() {
|
|
}
|
|
|
|
@objc func setter() {
|
|
}
|
|
|
|
func referenceGetterSetter() {
|
|
let _ = #selector(getter)
|
|
let _ = #selector(setter)
|
|
}
|
|
}
|
|
|
|
// Looking up inherited members
|
|
|
|
class BaseClass: NSObject {
|
|
@objc var myVar = 1
|
|
|
|
@objc func myFunc() {
|
|
}
|
|
}
|
|
|
|
class SubClass: BaseClass {
|
|
|
|
}
|
|
|
|
func testInherited() {
|
|
let _ = #selector(getter: SubClass.myVar)
|
|
let _ = #selector(SubClass.myFunc)
|
|
|
|
let subInstance = SubClass()
|
|
|
|
let _ = #selector(getter: subInstance.myVar)
|
|
let _ = #selector(subInstance.myFunc)
|
|
}
|
|
|
|
// Looking up instance/static methods on instance/static contexts
|
|
|
|
class InstanceStaticTestClass {
|
|
@objc static let staticProperty = HelperClass()
|
|
@objc let instanceProperty = HelperClass()
|
|
|
|
@objc class func classMethod() {}
|
|
|
|
@objc static func staticMethod() {}
|
|
|
|
@objc func instanceMethod() {}
|
|
|
|
@objc func instanceAndStaticMethod() {}
|
|
@objc class func instanceAndStaticMethod() {}
|
|
|
|
class func testClass() {
|
|
let _ = #selector(getter: instanceProperty)
|
|
let _ = #selector(instanceMethod)
|
|
|
|
let _ = #selector(classMethod)
|
|
let _ = #selector(staticMethod)
|
|
let _ = #selector(getter: staticProperty)
|
|
|
|
let _ = #selector(instanceAndStaticMethod)
|
|
}
|
|
|
|
static func testStatic() {
|
|
let _ = #selector(getter: instanceProperty)
|
|
let _ = #selector(getter: staticProperty)
|
|
|
|
let _ = #selector(instanceMethod)
|
|
let _ = #selector(classMethod)
|
|
let _ = #selector(staticMethod)
|
|
|
|
let _ = #selector(instanceAndStaticMethod)
|
|
}
|
|
|
|
func testInstance() {
|
|
let _ = #selector(getter: instanceProperty)
|
|
let _ = #selector(instanceMethod)
|
|
|
|
let _ = #selector(getter: staticProperty) // expected-error{{static member 'staticProperty' cannot be used on instance of type 'InstanceStaticTestClass'}}
|
|
let _ = #selector(classMethod) // expected-error{{static member 'classMethod' cannot be used on instance of type 'InstanceStaticTestClass'}}
|
|
let _ = #selector(staticMethod) // expected-error{{static member 'staticMethod' cannot be used on instance of type 'InstanceStaticTestClass'}}
|
|
|
|
let _ = #selector(instanceAndStaticMethod)
|
|
}
|
|
}
|
|
|
|
// Accessibility
|
|
let otherObjCInstance = OtherObjCClass()
|
|
|
|
let v11 = #selector(getter: OtherObjCClass.privateVar) // expected-error{{'privateVar' is inaccessible due to 'private' protection level}}
|
|
let v12 = #selector(setter: OtherObjCClass.privateVar) // expected-error{{'privateVar' is inaccessible due to 'private' protection level}}
|
|
let v13 = #selector(getter: otherObjCInstance.privateVar) // expected-error{{}}
|
|
let v14 = #selector(setter: otherObjCInstance.privateVar) // expected-error{{privateVar' is inaccessible due to 'private' protection level}}
|
|
|
|
let v21 = #selector(getter: OtherObjCClass.privateSetVar)
|
|
let v22 = #selector(setter: OtherObjCClass.privateSetVar) // expected-error{{setter of property 'privateSetVar' is inaccessible}}
|
|
let v23 = #selector(getter: otherObjCInstance.privateSetVar)
|
|
let v24 = #selector(setter: otherObjCInstance.privateSetVar) // expected-error{{setter of property 'privateSetVar' is inaccessible}}
|
|
|
|
let v31 = #selector(getter: OtherObjCClass.internalVar)
|
|
let v32 = #selector(setter: OtherObjCClass.internalVar)
|
|
let v33 = #selector(getter: otherObjCInstance.internalVar)
|
|
let v34 = #selector(setter: otherObjCInstance.internalVar)
|
|
|
|
let v41 = #selector(OtherObjCClass.internalFunc)
|
|
let v42 = #selector(otherObjCInstance.internalFunc)
|
|
|
|
let v51 = #selector(OtherObjCClass.privateFunc) // expected-error{{'privateFunc' is inaccessible due to 'private' protection level}}
|
|
let v52 = #selector(otherObjCInstance.privateFunc) // expected-error{{'privateFunc' is inaccessible due to 'private' protection level}}
|