[swift-evolution] Proposal: Change Obj-C name for nested types to include enclosing types
Jordan Rose
jordan_rose at apple.com
Thu Dec 10 18:48:25 CST 2015
My point is that Swift currently treats @objc on nested types differently based on whether the outer type is @objc—if the outer type is @objc, the inner types end up in the generated header; otherwise they don't. And what about @objc on local types?
(Right now we have a hole: an API using an @objc type will show up in the generated header, but the type may not, leading to errors in the header. We should resolve that somehow.)
Jordan
> On Dec 9, 2015, at 21:36, Kevin Ballard <kevin at sb.org> wrote:
>
> We already default nested types to @nonobjc (hence the explicit @objc in my sample). I like that Swift supports using @objc on nested types, because that way I can avoid having to uglify my Swift API just for the sake of Obj-C compatibility (I know I can use a typealias inside the outer type to provide a convenient shorthand for the formerly-nested type, but I still consider that ugly).
>
> -Kevin
>
> On Wed, Dec 9, 2015, at 06:03 PM, Jordan Rose wrote:
>> I would rather just not print nested types in the generated header. We already don't do so if the enclosing type is not Objective-C-compatible.
>>
>> Jordan
>>
>>
>>> On Dec 9, 2015, at 15:24, Kevin Ballard via swift-evolution <swift-evolution at swift.org> wrote:
>>>
>>> When exposing some type to Obj-C, if the type is nested within another type, the Obj-C name should include the enclosing types.
>>>
>>> For example:
>>>
>>> class Foo: NSObject {
>>> @objc enum Bar: Int {
>>> case One, Two
>>> }
>>> @objc class Baz: NSObject {}
>>> }
>>>
>>> is currently exported to Swift as
>>>
>>> SWIFT_CLASS("_TtC7unnamed3Foo")
>>> @interface Foo : NSObject
>>> - (nonnull instancetype)init OBJC_DESIGNATED_INITIALIZER;
>>> @end
>>>
>>> typedef SWIFT_ENUM(NSInteger, Bar) {
>>> BarOne = 0,
>>> BarTwo = 1,
>>> };
>>>
>>> SWIFT_CLASS("_TtCC7unnamed3Foo3Baz")
>>> @interface Baz : NSObject
>>> - (nonnull instancetype)init OBJC_DESIGNATED_INITIALIZER;
>>> @end
>>>
>>> I think it should be exported instead as
>>>
>>> SWIFT_CLASS("_TtC7unnamed3Foo")
>>> @interface Foo : NSObject
>>> - (nonnull instancetype)init OBJC_DESIGNATED_INITIALIZER;
>>> @end
>>>
>>> typedef SWIFT_ENUM(NSInteger, FooBar) {
>>> FooBarOne = 0,
>>> FooBarTwo = 1,
>>> };
>>>
>>> SWIFT_CLASS("_TtCC7unnamed3Foo3Baz")
>>> @interface FooBaz : NSObject
>>> - (nonnull instancetype)init OBJC_DESIGNATED_INITIALIZER;
>>> @end
>>>
>>> This is because the Obj-C declarations are all at the top level (as Obj-C does not have nested types), so a type that is clearly unambiguous in Swift may become ambiguous in Obj-C. As a trivial example, the following Swift code:
>>>
>>> class Foo: NSObject {
>>> @objc enum Bar: Int {
>>> case One, Two
>>> }
>>> }
>>>
>>> class Baz: NSObject {
>>> @objc enum Bar: Int {
>>> case Apple, Orange
>>> }
>>> }
>>>
>>> is currently exported to Obj-C as:
>>>
>>> SWIFT_CLASS("_TtC7unnamed3Baz")
>>> @interface Baz : NSObject
>>> - (nonnull instancetype)init OBJC_DESIGNATED_INITIALIZER;
>>> @end
>>>
>>> typedef SWIFT_ENUM(NSInteger, Bar) {
>>> BarApple = 0,
>>> BarOrange = 1,
>>> };
>>>
>>> SWIFT_CLASS("_TtC7unnamed3Foo")
>>> @interface Foo : NSObject
>>> - (nonnull instancetype)init OBJC_DESIGNATED_INITIALIZER;
>>> @end
>>>
>>> typedef SWIFT_ENUM(NSInteger, Bar) {
>>> BarOne = 0,
>>> BarTwo = 1,
>>> };
>>>
>>> This is attempting to redefine the type Bar, which is of course problematic.
>>>
>>> -Kevin Ballard
>>> _______________________________________________
>>> swift-evolution mailing list
>>> swift-evolution at swift.org
>>> https://lists.swift.org/mailman/listinfo/swift-evolution
>>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20151210/b6c171e5/attachment.html>
More information about the swift-evolution
mailing list