mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
When generating a stub fix-it for a protocol conformance or implementation extension, Swift will now evaluate whether the context allows the declaration of stored properties and, if so, will suggest one. It will also use the `let` keyword instead of `var` if the property has no setter.
266 lines
6.5 KiB
Swift
266 lines
6.5 KiB
Swift
// RUN: %target-typecheck-verify-swift -import-objc-header %S/Inputs/objc_implementation.h -target %target-stable-abi-triple
|
|
// RUN: %target-typecheck-verify-swift -DPRIVATE_MODULE -Xcc -fmodule-map-file=%S/Inputs/objc_implementation_private.modulemap -target %target-stable-abi-triple
|
|
|
|
// REQUIRES: objc_interop
|
|
|
|
// Swift doesn't diagnose selector conflicts if there are other errors
|
|
// in the file. This is equivalent to decl/ext/objc_implementation.swift
|
|
// but has no failures, so we get to that stage of type checking.
|
|
|
|
#if PRIVATE_MODULE
|
|
import objc_implementation_private
|
|
#endif
|
|
|
|
@objc @implementation extension ObjCClass {
|
|
@objc func method(fromHeader1: CInt) {
|
|
// OK, provides an implementation for the header's method.
|
|
}
|
|
|
|
@objc func method(fromHeader2: CInt) {
|
|
// OK, provides an implementation for the header's method.
|
|
}
|
|
|
|
@objc func method(fromHeader3: CInt) {
|
|
// OK
|
|
}
|
|
|
|
func method(fromHeader4: CInt) {
|
|
// OK
|
|
}
|
|
|
|
func methodFromHeader5() -> CInt {
|
|
return 1 // OK
|
|
}
|
|
|
|
func method(fromHeader6: CInt) {
|
|
// OK
|
|
}
|
|
|
|
@objc fileprivate func methodNot(fromHeader1: CInt) {
|
|
// OK, declares a new @objc dynamic method.
|
|
}
|
|
|
|
final func methodNot(fromHeader2: CInt) {
|
|
// OK, declares a new Swift method.
|
|
}
|
|
|
|
@objc var propertyFromHeader1: CInt
|
|
// OK, provides an implementation with a stored property
|
|
|
|
@objc var propertyFromHeader2: CInt
|
|
// OK, provides an implementation with a stored property
|
|
|
|
@objc var propertyFromHeader3: CInt {
|
|
// OK, provides an implementation with a computed property
|
|
get { return 1 }
|
|
set {}
|
|
}
|
|
|
|
@objc var propertyFromHeader4: CInt {
|
|
// OK, provides an implementation with a computed property
|
|
get { return 1 }
|
|
set {}
|
|
}
|
|
|
|
@objc var propertyFromHeader5: CInt
|
|
|
|
@objc var propertyFromHeader6: CInt {
|
|
get { return 1 }
|
|
set {}
|
|
}
|
|
|
|
@objc var propertyFromHeader7: CInt {
|
|
get { return 1 }
|
|
set {}
|
|
}
|
|
|
|
var propertyFromHeader8: CInt
|
|
|
|
@objc var propertyFromHeader9: CInt
|
|
|
|
@objc var propertyFromHeader10: CInt
|
|
|
|
@objc var propertyFromHeader11: CInt
|
|
|
|
@objc var readonlyPropertyFromHeader1: CInt
|
|
// OK, provides an implementation with a stored property that's nonpublicly settable
|
|
|
|
@objc var readonlyPropertyFromHeader2: CInt
|
|
// OK, provides an implementation with a stored property that's nonpublicly settable
|
|
|
|
@objc var readonlyPropertyFromHeader3: CInt {
|
|
// FIXME: OK, provides an implementation with a computed property
|
|
get { return 1 }
|
|
set {}
|
|
}
|
|
|
|
@objc var readonlyPropertyFromHeader4: CInt {
|
|
// OK, provides an implementation with a computed property
|
|
get { return 1 }
|
|
set {}
|
|
}
|
|
|
|
@objc let readonlyPropertyFromHeader5: CInt
|
|
// OK, provides an implementation with a stored read-only property
|
|
|
|
@objc var readonlyPropertyFromHeader6: CInt {
|
|
// OK, provides an implementation with a computed read-only property
|
|
get { return 1 }
|
|
}
|
|
|
|
@objc let readonlyPropertyFromHeader7: CInt
|
|
|
|
@objc fileprivate var propertyNotFromHeader2: CInt
|
|
// OK, provides a nonpublic but ObjC-compatible stored property
|
|
|
|
@objc private var propertyNotFromHeader3: CInt {
|
|
// OK, provides a nonpublic but ObjC-compatible computed property
|
|
get { return 1 }
|
|
set {}
|
|
}
|
|
|
|
final var propertyNotFromHeader4: CInt
|
|
// OK, provides a Swift-only stored property
|
|
|
|
@objc final var propertyNotFromHeader5: CInt
|
|
// OK, @objc final is weird but supported, not a member impl
|
|
|
|
override open func superclassMethod(_: CInt) {
|
|
// OK
|
|
}
|
|
|
|
override open var superclassProperty: CInt {
|
|
get {
|
|
// OK
|
|
}
|
|
set {
|
|
// OK
|
|
}
|
|
}
|
|
|
|
override public init(fromSuperclass v: CInt) {
|
|
// OK
|
|
super.init(fromSuperclass: v)
|
|
}
|
|
|
|
override public init(fromSuperclass2 v: CInt) {
|
|
// OK
|
|
super.init(fromSuperclass2: v)
|
|
}
|
|
|
|
@objc(initFromProtocol1:)
|
|
required public init?(fromProtocol1 v: CInt) {
|
|
// OK
|
|
super.init(fromSuperclass: v)
|
|
}
|
|
|
|
@objc(initFromProtocol2:)
|
|
required public init?(fromProtocol2 v: CInt) {
|
|
// OK
|
|
super.init(fromSuperclass: v)
|
|
}
|
|
|
|
@objc(initNotFromProtocol:)
|
|
public init?(notFromProtocol v: CInt) {
|
|
// OK
|
|
super.init(fromSuperclass: v)
|
|
}
|
|
|
|
class func classMethod1(_: CInt) {}
|
|
class func classMethod2(_: CInt) {}
|
|
class func classMethod3(_: CInt) {}
|
|
|
|
func instanceMethod1(_: CInt) {}
|
|
func instanceMethod2(_: CInt) {}
|
|
|
|
@objc func extensionMethod(fromHeader1: CInt) {}
|
|
@objc func extensionMethod(fromHeader2: CInt) {}
|
|
|
|
@objc(copyWithZone:) func copy(with zone: NSZone?) -> Any { self }
|
|
|
|
let rdar122280735: (@escaping () -> ()) -> Void = { _ in }
|
|
}
|
|
|
|
@objc(PresentAdditions) @implementation extension ObjCClass {
|
|
@objc func categoryMethod(fromHeader3: CInt) {
|
|
// OK
|
|
}
|
|
|
|
@objc func categoryMethod(fromHeader1: CInt) {
|
|
// OK, provides an implementation for the header's method.
|
|
}
|
|
|
|
@objc func categoryMethod(fromHeader2: CInt) {
|
|
// OK, provides an implementation for the header's method.
|
|
}
|
|
|
|
@objc func categoryMethod(fromHeader4: CInt) {
|
|
// OK, provides an implementation for the header's method.
|
|
}
|
|
|
|
@objc fileprivate func categoryMethodNot(fromHeader1: CInt) {
|
|
// OK, declares a new @objc dynamic method.
|
|
}
|
|
|
|
final func categoryMethodNot(fromHeader2: CInt) {
|
|
// OK, declares a new Swift method.
|
|
}
|
|
|
|
private func categoryMethodNot(fromHeader3: CInt) {
|
|
// OK
|
|
}
|
|
|
|
@objc var categoryPropertyFromHeader1: CInt {
|
|
get { return 1 }
|
|
set {}
|
|
}
|
|
|
|
@objc var categoryPropertyFromHeader2: CInt {
|
|
get { return 1 }
|
|
set {}
|
|
}
|
|
|
|
@objc var categoryPropertyFromHeader3: CInt {
|
|
// OK, provides an implementation with a computed property
|
|
get { return 1 }
|
|
set {}
|
|
}
|
|
|
|
@objc var categoryPropertyFromHeader4: CInt {
|
|
// OK, provides an implementation with a computed property
|
|
get { return 1 }
|
|
set {}
|
|
}
|
|
|
|
@objc var categoryPropertyFromHeader5: CInt {
|
|
// OK, provides an implementation with a computed property
|
|
get { return 1 }
|
|
set {}
|
|
}
|
|
|
|
@objc var categoryReadonlyPropertyFromHeader1: CInt {
|
|
// OK, provides an implementation with a computed property
|
|
get { return 1 }
|
|
}
|
|
}
|
|
|
|
@objc class SwiftClass {}
|
|
|
|
func usesAreNotAmbiguous(obj: ObjCClass) {
|
|
obj.method(fromHeader1: 1)
|
|
obj.method(fromHeader2: 2)
|
|
obj.method(fromHeader3: 3)
|
|
obj.method(fromHeader4: 4)
|
|
|
|
obj.methodNot(fromHeader1: 1)
|
|
obj.methodNot(fromHeader2: 2)
|
|
|
|
obj.categoryMethod(fromHeader1: 1)
|
|
obj.categoryMethod(fromHeader2: 2)
|
|
obj.categoryMethod(fromHeader3: 3)
|
|
obj.categoryMethod(fromHeader4: 4)
|
|
|
|
obj.categoryMethodNot(fromHeader1: 1)
|
|
obj.categoryMethodNot(fromHeader2: 2)
|
|
}
|