1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618
|
// RUN: %target-typecheck-verify-swift -import-objc-header %S/Inputs/objc_implementation.h -enable-experimental-feature ObjCImplementation -enable-experimental-feature CImplementation
// REQUIRES: objc_interop
protocol EmptySwiftProto {}
@_objcImplementation extension ObjCClass: EmptySwiftProto, EmptyObjCProto {
// expected-note@-1 {{previously implemented by extension here}}
// expected-warning@-2 {{extension for main class interface should provide implementation for instance method 'method(fromHeader4:)'}}
// expected-warning@-3 {{extension for main class interface should provide implementation for property 'propertyFromHeader9'}}
// FIXME: give better diagnostic expected-warning@-4 {{extension for main class interface should provide implementation for property 'propertyFromHeader8'}}
// FIXME: give better diagnostic expected-warning@-5 {{extension for main class interface should provide implementation for property 'propertyFromHeader7'}}
// FIXME: give better diagnostic expected-warning@-6 {{extension for main class interface should provide implementation for instance method 'method(fromHeader3:)'}}
// expected-warning@-7 {{'@_objcImplementation' extension cannot add conformance to 'EmptySwiftProto'; add this conformance with an ordinary extension}}
// expected-warning@-8 {{'@_objcImplementation' extension cannot add conformance to 'EmptyObjCProto'; add this conformance in the Objective-C header}}
// expected-warning@-9 {{extension for main class interface should provide implementation for instance method 'extensionMethod(fromHeader2:)'}}
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.
}
func categoryMethod(fromHeader3: CInt) {
// FIXME: should emit expected-DISABLED-error@-1 {{instance method 'categoryMethod(fromHeader3:)' should be implemented in extension for category 'PresentAdditions', not main class interface}}
// FIXME: expected-warning@-2 {{instance method 'categoryMethod(fromHeader3:)' does not match any instance method declared in the headers for 'ObjCClass'; did you use the instance method's Swift name?; this will become an error after adopting '@implementation'}}
// FIXME: expected-note@-3 {{add 'private' or 'fileprivate' to define an Objective-C-compatible instance method not declared in the header}} {{3-3=private }}
// FIXME: expected-note@-4 {{add 'final' to define a Swift instance method that cannot be overridden}} {{3-3=final }}
}
@objc fileprivate func methodNot(fromHeader1: CInt) {
// OK, declares a new @objc dynamic method.
}
final func methodNot(fromHeader2: CInt) {
// OK, declares a new Swift method.
}
func methodNot(fromHeader3: CInt) {
// expected-warning@-1 {{instance method 'methodNot(fromHeader3:)' does not match any instance method declared in the headers for 'ObjCClass'; did you use the instance method's Swift name?; this will become an error after adopting '@implementation'}}
// expected-note@-2 {{add 'private' or 'fileprivate' to define an Objective-C-compatible instance method not declared in the header}} {{3-3=private }}
// expected-note@-3 {{add 'final' to define a Swift instance method that cannot be overridden}} {{3-3=final }}
}
var methodFromHeader5: CInt
// expected-warning@-1 {{property 'methodFromHeader5' does not match the instance method declared by the header}}
func method(fromHeader6: Double) {
// expected-warning@-1 {{instance method 'method(fromHeader6:)' of type '(Double) -> ()' does not match type '(Int32) -> Void' declared by the header}}
}
var propertyFromHeader1: CInt
// OK, provides an implementation with a stored property
@objc var propertyFromHeader2: CInt
// OK, provides an implementation with a stored property
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 let propertyFromHeader5: CInt
// expected-warning@-1 {{property 'propertyFromHeader5' should be settable to match the settable property declared by the header}}
@objc var propertyFromHeader6: CInt {
// expected-warning@-1 {{property 'propertyFromHeader6' should be settable to match the settable property declared by the header}}
get { return 1 }
}
final var propertyFromHeader8: CInt
// FIXME: Should complain about final not fulfilling the @objc requirement
func propertyFromHeader10() -> CInt {
// expected-warning@-1 {{instance method 'propertyFromHeader10()' does not match the property declared by the header}}
return 1
}
var propertyFromHeader11: Float
// expected-warning@-1 {{property 'propertyFromHeader11' of type 'Float' does not match type 'Int32' declared by the header}}
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
var readonlyPropertyFromHeader3: CInt {
// 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 }
}
internal var propertyNotFromHeader1: CInt
// expected-warning@-1 {{property 'propertyNotFromHeader1' does not match any property declared in the headers for 'ObjCClass'; did you use the property's Swift name?; this will become an error after adopting '@implementation'}}
// expected-note@-2 {{add 'private' or 'fileprivate' to define an Objective-C-compatible property not declared in the header}} {{3-11=private}}
// expected-note@-3 {{add 'final' to define a Swift property that cannot be overridden}} {{3-3=final }}
@objc private var propertyNotFromHeader2: CInt
// OK, provides a nonpublic but ObjC-compatible stored property
@objc fileprivate 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 _: CInt) {
// OK
}
@objc(initFromProtocol1:)
required public init?(fromProtocol1: CInt) {
// OK
}
@objc(initFromProtocol2:)
public init?(fromProtocol2: CInt) {
// expected-warning@-1 {{initializer 'init(fromProtocol2:)' should be 'required' to match initializer declared by the header}} {{3-3=required }}
}
@objc(initNotFromProtocol:)
required public init?(notFromProtocol: CInt) {
// expected-warning@-1 {{initializer 'init(notFromProtocol:)' should not be 'required' to match initializer declared by the header}} {{3-12=}}
}
class func classMethod1(_: CInt) {
// OK
}
func classMethod2(_: CInt) {
// expected-warning@-1 {{instance method 'classMethod2' does not match class method declared in header; this will become an error after adopting '@implementation'}} {{3-3=class }}
}
class func classMethod3(_: Float) {
// expected-warning@-1 {{class method 'classMethod3' of type '(Float) -> ()' does not match type '(Int32) -> Void' declared by the header}}
}
func instanceMethod1(_: CInt) {
// OK
}
class func instanceMethod2(_: CInt) {
// expected-warning@-1 {{class method 'instanceMethod2' does not match instance method declared in header; this will become an error after adopting '@implementation'}} {{3-9=}}
}
public init(notFromHeader1: CInt) {
// expected-warning@-1 {{initializer 'init(notFromHeader1:)' does not match any initializer declared in the headers for 'ObjCClass'; did you use the initializer's Swift name?}}
// expected-note@-2 {{add 'private' or 'fileprivate' to define an Objective-C-compatible initializer not declared in the header}} {{3-9=private}}
// expected-note@-3 {{add '@nonobjc' to define a Swift-only initializer}} {{3-3=@nonobjc }}
}
public required init(notFromHeader2: CInt) {
// expected-warning@-1 {{initializer 'init(notFromHeader2:)' does not match any initializer declared in the headers for 'ObjCClass'; did you use the initializer's Swift name?}}
// expected-note@-2 {{add 'private' or 'fileprivate' to define an Objective-C-compatible initializer not declared in the header}} {{3-9=private}}
// expected-note@-3 {{add '@nonobjc' to define a Swift-only initializer}} {{3-3=@nonobjc }}
}
public convenience init(notFromHeader3: CInt) {
// expected-warning@-1 {{initializer 'init(notFromHeader3:)' does not match any initializer declared in the headers for 'ObjCClass'; did you use the initializer's Swift name?}}
// expected-note@-2 {{add 'private' or 'fileprivate' to define an Objective-C-compatible initializer not declared in the header}} {{3-9=private}}
// expected-note@-3 {{add '@nonobjc' to define a Swift-only initializer}} {{3-3=@nonobjc }}
}
@nonobjc public init(notFromHeader4: CInt) {
// expected-warning@-1 {{initializer 'init(notFromHeader4:)' is not valid in an '@_objcImplementation' extension because Objective-C subclasses must be able to override designated initializers}}
// expected-note@-2 {{add 'convenience' keyword to make this a convenience initializer}} {{12-12=convenience }}
}
@nonobjc public required init(notFromHeader5: CInt) {
// expected-warning@-1 {{initializer 'init(notFromHeader5:)' is not valid in an '@_objcImplementation' extension because Objective-C subclasses must be able to override required initializers}}
// expected-note@-2 {{replace 'required' keyword with 'convenience' to make this a convenience initializer}} {{19-27=convenience}}
}
@nonobjc public convenience init(notFromHeader6: CInt) {
// OK
}
@objc func extensionMethod(fromHeader1: CInt) {
// OK
}
@objc(copyWithZone:) func copy(with zone: NSZone?) -> Any {
// OK
return self
}
// rdar://122280735 - crash when the parameter of a block property needs @escaping
let rdar122280735: (() -> ()) -> Void = { _ in }
// expected-warning@-1 {{property 'rdar122280735' of type '(() -> ()) -> Void' does not match type '(@escaping () -> Void) -> Void' declared by the header}}
}
@_objcImplementation(PresentAdditions) extension ObjCClass {
// expected-note@-1 {{previously implemented by extension here}}
// expected-warning@-2 {{extension for category 'PresentAdditions' should provide implementation for instance method 'categoryMethod(fromHeader4:)'; this will become an error after adopting '@implementation'}}
// FIXME: give better diagnostic expected-warning@-3 {{extension for category 'PresentAdditions' should provide implementation for instance method 'categoryMethod(fromHeader3:)'; this will become an error after adopting '@implementation'}}
func method(fromHeader3: CInt) {
// FIXME: should emit expected-DISABLED-error@-1 {{instance method 'method(fromHeader3:)' should be implemented in extension for main class interface, not category 'PresentAdditions'}}
// FIXME: expected-warning@-2 {{instance method 'method(fromHeader3:)' does not match any instance method declared in the headers for 'ObjCClass'; did you use the instance method's Swift name?; this will become an error after adopting '@implementation'}}
// FIXME: expected-note@-3 {{add 'private' or 'fileprivate' to define an Objective-C-compatible instance method not declared in the header}} {{3-3=private }}
// FIXME: expected-note@-4 {{add 'final' to define a Swift instance method that cannot be overridden}} {{3-3=final }}
}
var propertyFromHeader7: CInt {
// FIXME: should emit expected-DISABLED-error@-1 {{property 'propertyFromHeader7' should be implemented in extension for main class interface, not category 'PresentAdditions'}}
// FIXME: expected-warning@-2 {{property 'propertyFromHeader7' does not match any property declared in the headers for 'ObjCClass'; did you use the property's Swift name?; this will become an error after adopting '@implementation'}}
// FIXME: expected-note@-3 {{add 'private' or 'fileprivate' to define an Objective-C-compatible property not declared in the header}} {{3-3=private }}
// FIXME: expected-note@-4 {{add 'final' to define a Swift property that cannot be overridden}} {{3-3=final }}
get { return 1 }
}
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 fileprivate func categoryMethodNot(fromHeader1: CInt) {
// OK, declares a new @objc dynamic method.
}
final func categoryMethodNot(fromHeader2: CInt) {
// OK, declares a new Swift method.
}
func categoryMethodNot(fromHeader3: CInt) {
// expected-warning@-1 {{instance method 'categoryMethodNot(fromHeader3:)' does not match any instance method declared in the headers for 'ObjCClass'; did you use the instance method's Swift name?; this will become an error after adopting '@implementation'}}
// expected-note@-2 {{add 'private' or 'fileprivate' to define an Objective-C-compatible instance method not declared in the header}} {{3-3=private }}
// expected-note@-3 {{add 'final' to define a Swift instance method that cannot be overridden}} {{3-3=final }}
}
var categoryPropertyFromHeader1: CInt
// expected-error@-1 {{extensions must not contain stored properties}}
@objc var categoryPropertyFromHeader2: CInt
// expected-error@-1 {{extensions must not contain stored properties}}
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 {}
}
}
@_objcImplementation(SwiftNameTests) extension ObjCClass {
// expected-warning@-1 {{extension for category 'SwiftNameTests' should provide implementation for instance method 'methodSwiftName6B()'; this will become an error after adopting '@implementation'}}
func methodSwiftName1() {
// expected-warning@-1 {{selector 'methodSwiftName1' for instance method 'methodSwiftName1()' not found in header; did you mean 'methodObjCName1'?; this will become an error after adopting '@implementation'}} {{3-3=@objc(methodObjCName1) }}
}
@objc(methodObjCName2) func methodSwiftName2() {
// OK
}
func methodObjCName3() {
// expected-warning@-1 {{selector 'methodObjCName3' used in header by instance method with a different name; did you mean 'methodSwiftName3()'?}} {{8-23=methodSwiftName3}} {{3-3=@objc(methodObjCName3) }}
// FIXME: probably needs an @objc too, since the name is not explicit
}
@objc(methodWrongObjCName4) func methodSwiftName4() {
// expected-warning@-1 {{selector 'methodWrongObjCName4' for instance method 'methodSwiftName4()' not found in header; did you mean 'methodObjCName4'?; this will become an error after adopting '@implementation'}} {{9-29=methodObjCName4}}
}
@objc(methodObjCName5) func methodWrongSwiftName5() {
// expected-warning@-1 {{selector 'methodObjCName5' used in header by instance method with a different name; did you mean 'methodSwiftName5()'?}} {{31-52=methodSwiftName5}}
}
@objc(methodObjCName6A) func methodSwiftName6B() {
// expected-warning@-1 {{selector 'methodObjCName6A' used in header by instance method with a different name; did you mean 'methodSwiftName6A()'?}} {{32-49=methodSwiftName6A}}
}
}
@_objcImplementation(AmbiguousMethods) extension ObjCClass {
// expected-warning@-1 {{found multiple implementations that could match instance method 'ambiguousMethod4(with:)' with selector 'ambiguousMethod4WithCInt:'; this will become an error after adopting '@implementation'}}
@objc func ambiguousMethod1(with: CInt) {
// expected-warning@-1 {{instance method 'ambiguousMethod1(with:)' could match several different members declared in the header; this will become an error after adopting '@implementation'}}
// expected-note@-2 {{instance method 'ambiguousMethod1(with:)' (with selector 'ambiguousMethod1WithCInt:') is a potential match; insert '@objc(ambiguousMethod1WithCInt:)' to use it}} {{8-8=(ambiguousMethod1WithCInt:)}}
// expected-note@-3 {{instance method 'ambiguousMethod1(with:)' (with selector 'ambiguousMethod1WithCChar:') is a potential match; insert '@objc(ambiguousMethod1WithCChar:)' to use it}} {{8-8=(ambiguousMethod1WithCChar:)}}
}
func ambiguousMethod1(with: CChar) {
// expected-warning@-1 {{instance method 'ambiguousMethod1(with:)' could match several different members declared in the header; this will become an error after adopting '@implementation'}}
// expected-note@-2 {{instance method 'ambiguousMethod1(with:)' (with selector 'ambiguousMethod1WithCInt:') is a potential match; insert '@objc(ambiguousMethod1WithCInt:)' to use it}} {{3-3=@objc(ambiguousMethod1WithCInt:) }}
// expected-note@-3 {{instance method 'ambiguousMethod1(with:)' (with selector 'ambiguousMethod1WithCChar:') is a potential match; insert '@objc(ambiguousMethod1WithCChar:)' to use it}} {{3-3=@objc(ambiguousMethod1WithCChar:) }}
}
@objc(ambiguousMethod2WithCInt:) func ambiguousMethod2(with: CInt) {
// OK, matches -ambiguousMethod2WithCInt: because of explicit @objc
}
func ambiguousMethod2(with: CChar) {
// FIXME: OK, matches -ambiguousMethod2WithCChar: because the WithCInt: variant has been eliminated
// FIXME: expected-warning@-2 {{selector 'ambiguousMethod2With:' for instance method 'ambiguousMethod2(with:)' not found in header; did you mean 'ambiguousMethod2WithCChar:'?; this will become an error after adopting '@implementation'}}
}
func ambiguousMethod3(with: CInt) {
// expected-warning@-1 {{instance method 'ambiguousMethod3(with:)' could match several different members declared in the header; this will become an error after adopting '@implementation'}}
// expected-note@-2 {{instance method 'ambiguousMethod3(with:)' (with selector 'ambiguousMethod3WithCInt:') is a potential match; insert '@objc(ambiguousMethod3WithCInt:)' to use it}} {{3-3=@objc(ambiguousMethod3WithCInt:) }}
// expected-note@-3 {{instance method 'ambiguousMethod3(with:)' (with selector 'ambiguousMethod3WithCChar:') is a potential match; insert '@objc(ambiguousMethod3WithCChar:)' to use it}} {{3-3=@objc(ambiguousMethod3WithCChar:) }}
}
@objc func ambiguousMethod4(with: CInt) {
// expected-note@-1 {{instance method 'ambiguousMethod4(with:)' is a potential match; insert '@objc(ambiguousMethod4WithCInt:)' to use it}} {{8-8=(ambiguousMethod4WithCInt:)}}
}
func ambiguousMethod4(with: CChar) {
// expected-note@-1 {{instance method 'ambiguousMethod4(with:)' is a potential match; insert '@objc(ambiguousMethod4WithCInt:)' to use it}} {{3-3=@objc(ambiguousMethod4WithCInt:) }}
}
}
@_objcImplementation(Effects) extension ObjCClass {
@available(SwiftStdlib 5.1, *)
public func doSomethingAsynchronous() async throws -> Any {
return self
}
@available(SwiftStdlib 5.1, *)
public func doSomethingElseAsynchronous() async -> Any {
return self
}
public func doSomethingFunAndAsynchronous(completionHandler: @escaping (Any?, Error?) -> Void) {
}
@available(SwiftStdlib 5.1, *)
@objc(doSomethingOverloadedWithCompletionHandler:)
public func doSomethingOverloaded() async {}
@available(*, noasync)
@objc(doSomethingOverloaded)
public func doSomethingOverloaded() {}
@objc(doSomethingThatCanFailWithHandler:error:)
public func doSomethingThatCanFail(handler: @escaping () -> Void) throws {
// OK
}
@objc(doSomethingElseThatCanFail:handler:)
public func doSomethingElseThatCanFail(handler: @escaping () -> Void) throws {
// OK
}
@objc(doSomethingThatCanFailWithWeirdParameterWithHandler::)
public func doSomethingThatCanFailWithWeirdParameter(handler: @escaping () -> Void) throws {
// expected-warning@-1 {{instance method 'doSomethingThatCanFailWithWeirdParameter(handler:)' does not match the declaration in the header because it uses parameter #1 for the error, not parameter #2; a selector part called 'error:' can control which parameter to use}}
}
@objc(doSomethingThatCanFailWithWeirdReturnCodeWithError:)
public func doSomethingThatCanFailWithWeirdReturnCode() throws {
// expected-warning@-1 {{instance method 'doSomethingThatCanFailWithWeirdReturnCode()' does not match the declaration in the header because it indicates an error by returning zero, rather than by returning non-zero}}
}
}
@_objcImplementation(Conformance) extension ObjCClass {
// expected-warning@-1 {{extension for category 'Conformance' should provide implementation for instance method 'requiredMethod2()'; this will become an error after adopting '@implementation'}}
// no-error concerning 'optionalMethod2()'
func requiredMethod1() {}
func optionalMethod1() {}
}
@_objcImplementation(TypeMatchOptionality) extension ObjCClass {
func nullableResultAndArg(_: Any?) -> Any? { fatalError() } // no-error
func nonnullResultAndArg(_: Any) -> Any { fatalError() } // no-error
func nullUnspecifiedResultAndArg(_: Any!) -> Any! { fatalError() } // no-error
func nonnullResult1() -> Any { fatalError() } // no-error
func nonnullResult2() -> Any? { fatalError() } // expected-warning {{instance method 'nonnullResult2()' of type '() -> Any?' does not match type '() -> Any' declared by the header}}
func nonnullResult3() -> Any! { fatalError() } // no-error (special case)
func nonnullArgument1(_: Any) {} // no-error
func nonnullArgument2(_: Any?) {} // expected-warning {{instance method 'nonnullArgument2' of type '(Any?) -> ()' does not match type '(Any) -> Void' declared by the header}}
func nonnullArgument3(_: Any!) {} // no-error (special case)
func nullableResult() -> Any { fatalError() } // expected-warning {{instance method 'nullableResult()' of type '() -> Any' does not match type '() -> Any?' declared by the header}}
func nullableArgument(_: Any) {} // expected-warning {{instance method 'nullableArgument' of type '(Any) -> ()' does not match type '(Any?) -> Void' declared by the header}}
func nonPointerResult() -> CInt! { fatalError() } // expected-error{{method cannot be in an @_objcImplementation extension of a class (without final or @nonobjc) because its result type cannot be represented in Objective-C}}
func nonPointerArgument(_: CInt!) {} // expected-error {{method cannot be in an @_objcImplementation extension of a class (without final or @nonobjc) because the type of the parameter cannot be represented in Objective-C}}
}
// Intentionally using `@_objcImplementation` for this test; do not upgrade!
@_objcImplementation(EmptyCategory) extension ObjCClass {
// expected-warning@-1 {{'@_objcImplementation' is deprecated; use '@implementation' instead}} {{2-21=implementation}}
}
@_objcImplementation extension ObjCImplSubclass {
// expected-warning@-1 {{'@_objcImplementation' is deprecated; use '@implementation' instead}} {{2-21=implementation}}
@objc(initFromProtocol1:)
required public init?(fromProtocol1: CInt) {
// OK
}
}
@_objcImplementation extension ObjCBasicInitClass {
// expected-warning@-1 {{'@_objcImplementation' is deprecated; use '@implementation' instead}} {{2-21=implementation}}
init() {
// OK
}
}
@_objcImplementation extension ObjCClass {}
// expected-error@-1 {{duplicate implementation of Objective-C class 'ObjCClass'}}
@_objcImplementation(PresentAdditions) extension ObjCClass {}
// expected-error@-1 {{duplicate implementation of Objective-C category 'PresentAdditions' on class 'ObjCClass'}}
@_objcImplementation(MissingAdditions) extension ObjCClass {}
// expected-error@-1 {{could not find category 'MissingAdditions' on Objective-C class 'ObjCClass'; make sure your umbrella or bridging header imports the header that declares it}}
// expected-note@-2 {{remove arguments to implement the main '@interface' for this class}} {{21-39=}}
@_objcImplementation extension ObjCStruct {}
// expected-error@-1 {{cannot mark extension of struct 'ObjCStruct' with '@_objcImplementation'; it is not an imported Objective-C class}} {{1-22=}}
@_objcImplementation(CantWork) extension ObjCStruct {}
// expected-error@-1 {{cannot mark extension of struct 'ObjCStruct' with '@_objcImplementation'; it is not an imported Objective-C class}} {{1-32=}}
@objc class SwiftClass {}
// expected-note@-1 2 {{'SwiftClass' declared here}}
@_objcImplementation extension SwiftClass {}
// expected-error@-1 {{'@_objcImplementation' cannot be used to extend class 'SwiftClass' because it was defined by a Swift 'class' declaration, not an imported Objective-C '@interface' declaration}} {{1-22=}}
@_objcImplementation(WTF) extension SwiftClass {} // expected
// expected-error@-1 {{'@_objcImplementation' cannot be used to extend class 'SwiftClass' because it was defined by a Swift 'class' declaration, not an imported Objective-C '@interface' declaration}} {{1-27=}}
@_objcImplementation extension ObjCImplRootClass {
// expected-error@-1 {{'@_objcImplementation' cannot be used to implement root class 'ObjCImplRootClass'; declare its superclass in the header}}
}
@_objcImplementation extension ObjCImplGenericClass {
// expected-error@-1 {{'@_objcImplementation' cannot be used to implement generic class 'ObjCImplGenericClass'}}
}
//
// @_cdecl for global functions
//
@_objcImplementation @_cdecl("CImplFunc1")
func CImplFunc1(_: Int32) {
// OK
}
@_objcImplementation(BadCategory) @_cdecl("CImplFunc2")
func CImplFunc2(_: Int32) {
// expected-error@-2 {{global function 'CImplFunc2' does not belong to an Objective-C category; remove the category name from this attribute}} {{21-34=}}
}
@_objcImplementation @_cdecl("CImplFuncMissing")
func CImplFuncMissing(_: Int32) {
// expected-error@-2 {{could not find imported function 'CImplFuncMissing' matching global function 'CImplFuncMissing'; make sure your umbrella or bridging header imports the header that declares it}}
}
@_objcImplementation @_cdecl("CImplFuncMismatch1")
func CImplFuncMismatch1(_: Float) {
// expected-warning@-1 {{global function 'CImplFuncMismatch1' of type '(Float) -> ()' does not match type '(Int32) -> Void' declared by the header}}
}
@_objcImplementation @_cdecl("CImplFuncMismatch2")
func CImplFuncMismatch2(_: Int32) -> Float {
// expected-warning@-1 {{global function 'CImplFuncMismatch2' of type '(Int32) -> Float' does not match type '(Int32) -> Void' declared by the header}}
}
@_objcImplementation @_cdecl("CImplFuncMismatch3")
func CImplFuncMismatch3(_: Any?) {
// OK
}
@_objcImplementation @_cdecl("CImplFuncMismatch4")
func CImplFuncMismatch4(_: Any) {
// expected-warning@-1 {{global function 'CImplFuncMismatch4' of type '(Any) -> ()' does not match type '(Any?) -> Void' declared by the header}}
}
@_objcImplementation @_cdecl("CImplFuncMismatch5")
func CImplFuncMismatch5(_: Any) {
// OK
}
@_objcImplementation @_cdecl("CImplFuncMismatch6")
func CImplFuncMismatch6(_: Any!) {
// OK, mismatch allowed
}
@_objcImplementation @_cdecl("CImplFuncMismatch3a")
func CImplFuncMismatch3a(_: Int32) -> Any? {
// OK
}
@_objcImplementation @_cdecl("CImplFuncMismatch4a")
func CImplFuncMismatch4a(_: Int32) -> Any {
// expected-warning@-1 {{global function 'CImplFuncMismatch4a' of type '(Int32) -> Any' does not match type '(Int32) -> Any?' declared by the header}}
}
@_objcImplementation @_cdecl("CImplFuncMismatch5a")
func CImplFuncMismatch5a(_: Int32) -> Any {
// OK
}
@_objcImplementation @_cdecl("CImplFuncMismatch6a")
func CImplFuncMismatch6a(_: Int32) -> Any! {
// OK, mismatch allowed
}
@_objcImplementation @_cdecl("CImplFuncNameMismatch1")
func mismatchedName1(_: Int32) {
// expected-error@-2 {{could not find imported function 'CImplFuncNameMismatch1' matching global function 'mismatchedName1'; make sure your umbrella or bridging header imports the header that declares it}}
// FIXME: Improve diagnostic for a partial match.
}
@_objcImplementation @_cdecl("mismatchedName2")
func CImplFuncNameMismatch2(_: Int32) {
// expected-error@-2 {{could not find imported function 'mismatchedName2' matching global function 'CImplFuncNameMismatch2'; make sure your umbrella or bridging header imports the header that declares it}}
// FIXME: Improve diagnostic for a partial match.
}
//
// TODO: @_cdecl for global functions imported as computed vars
//
var cImplComputedGlobal1: Int32 {
@_objcImplementation @_cdecl("CImplGetComputedGlobal1")
get {
// FIXME: Lookup for vars isn't working yet
// expected-error@-3 {{could not find imported function 'CImplGetComputedGlobal1' matching getter for var 'cImplComputedGlobal1'; make sure your umbrella or bridging header imports the header that declares it}}
return 0
}
@_objcImplementation @_cdecl("CImplSetComputedGlobal1")
set {
// FIXME: Lookup for vars isn't working yet
// expected-error@-3 {{could not find imported function 'CImplSetComputedGlobal1' matching setter for var 'cImplComputedGlobal1'; make sure your umbrella or bridging header imports the header that declares it}}
print(newValue)
}
}
//
// TODO: @_cdecl for import-as-member functions
//
extension CImplStruct {
@_objcImplementation @_cdecl("CImplStructStaticFunc1")
static func staticFunc1(_: Int32) {
// FIXME: Add underlying support for this
// expected-error@-3 {{@_cdecl can only be applied to global functions}}
// FIXME: Lookup in an enclosing type is not working yet
// expected-error@-5 {{could not find imported function 'CImplStructStaticFunc1' matching static method 'staticFunc1'; make sure your umbrella or bridging header imports the header that declares it}}
}
}
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)
}
|