[swift-evolution] Proposal: Change Obj-C name for nested types to include enclosing types

Kevin Ballard kevin at sb.org
Thu Dec 10 22:23:42 CST 2015


Ah, I see what you mean.

My preference would be to print @objc types wherever they are, but
include enclosing types in the Obj-C name. This means that
something like

class Foo: NSObject {    class Bar: NSObject {} }

would actually generate

@interface Foo : NSObject @end @interface FooBar : NSObject @end

In other words, the Obj-C name would default to the fully-qualified
Swift name, with the periods removed (e.g. Foo.Bar -> FooBar).

Furthermore, I think it should do this even if an enclosing type is
not @objc.

That said, I also wonder if we should have a way to explicitly hide
an @objc type from the generated header. If I'm making something
Obj-C-compatible because I need to use the Obj-C runtime, that
doesn't necessarily mean the type is actually appropriate to expose
to Obj-C code.

-Kevin Ballard

On Thu, Dec 10, 2015, at 04:48 PM, Jordan Rose wrote:
> 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/1c2120a9/attachment.html>


More information about the swift-evolution mailing list