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

Kevin Ballard kevin at sb.org
Wed Dec 9 23:36:00 CST 2015


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
> 


More information about the swift-evolution mailing list