<!DOCTYPE html>
<html>
<head>
<title></title>
</head>
<body><div>Ah, I see what you mean.<br></div>
<div>&nbsp;</div>
<div>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<br></div>
<div>&nbsp;</div>
<div>class Foo: NSObject {<br></div>
<div>&nbsp; &nbsp; class Bar: NSObject {}<br></div>
<div>}<br></div>
<div>&nbsp;</div>
<div>would actually generate<br></div>
<div>&nbsp;</div>
<div>@interface Foo : NSObject<br></div>
<div>@end<br></div>
<div>@interface FooBar : NSObject<br></div>
<div>@end<br></div>
<div>&nbsp;</div>
<div>In other words, the Obj-C name would default to the fully-qualified Swift name, with the periods removed (e.g. Foo.Bar -&gt; FooBar).<br></div>
<div>&nbsp;</div>
<div>Furthermore, I think it should do this even if an enclosing type is not @objc.<br></div>
<div>&nbsp;</div>
<div>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.</div>
<div>&nbsp;</div>
<div>-Kevin Ballard</div>
<div>&nbsp;</div>
<div>On Thu, Dec 10, 2015, at 04:48 PM, Jordan Rose wrote:<br></div>
<blockquote type="cite"><div>My point is that Swift currently treats @objc on nested types differently based on whether the <i>outer</i>&nbsp;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?<br></div>
<div>&nbsp;</div>
<div>(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.)<br></div>
<div>&nbsp;</div>
<div>Jordan<br></div>
<div>&nbsp;</div>
<div>&nbsp;</div>
<div><blockquote type="cite"><div>On Dec 9, 2015, at 21:36, Kevin Ballard &lt;<a href="mailto:kevin@sb.org">kevin@sb.org</a>&gt; wrote:<br></div>
<div>&nbsp;</div>
<div><div><div>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).<br></div>
<div>&nbsp;</div>
<div>-Kevin<br></div>
<div>&nbsp;</div>
<div>On Wed, Dec 9, 2015, at 06:03 PM, Jordan Rose wrote:<br></div>
<blockquote type="cite"><div>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.<br></div>
<div>&nbsp;</div>
<div>Jordan<br></div>
<div>&nbsp;</div>
<div>&nbsp;</div>
<blockquote type="cite"><div>On Dec 9, 2015, at 15:24, Kevin Ballard via swift-evolution &lt;<a href="mailto:swift-evolution@swift.org">swift-evolution@swift.org</a>&gt; wrote:<br></div>
<div>&nbsp;</div>
<div>When exposing some type to Obj-C, if the type is nested within another type, the Obj-C name should include the enclosing types.<br></div>
<div>&nbsp;</div>
<div>For example:<br></div>
<div>&nbsp;</div>
<div>class Foo: NSObject {<br></div>
<div> &nbsp;&nbsp;@objc enum Bar: Int {<br></div>
<div> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;case One, Two<br></div>
<div> &nbsp;&nbsp;}<br></div>
<div> &nbsp;&nbsp;@objc class Baz: NSObject {}<br></div>
<div>}<br></div>
<div>&nbsp;</div>
<div>is currently exported to Swift as<br></div>
<div>&nbsp;</div>
<div>SWIFT_CLASS("_TtC7unnamed3Foo")<br></div>
<div>@interface Foo : NSObject<br></div>
<div>- (nonnull instancetype)init OBJC_DESIGNATED_INITIALIZER;<br></div>
<div>@end<br></div>
<div>&nbsp;</div>
<div>typedef SWIFT_ENUM(NSInteger, Bar) {<br></div>
<div> BarOne = 0,<br></div>
<div> BarTwo = 1,<br></div>
<div>};<br></div>
<div>&nbsp;</div>
<div>SWIFT_CLASS("_TtCC7unnamed3Foo3Baz")<br></div>
<div>@interface Baz : NSObject<br></div>
<div>- (nonnull instancetype)init OBJC_DESIGNATED_INITIALIZER;<br></div>
<div>@end<br></div>
<div>&nbsp;</div>
<div>I think it should be exported instead as<br></div>
<div>&nbsp;</div>
<div>SWIFT_CLASS("_TtC7unnamed3Foo")<br></div>
<div>@interface Foo : NSObject<br></div>
<div>- (nonnull instancetype)init OBJC_DESIGNATED_INITIALIZER;<br></div>
<div>@end<br></div>
<div>&nbsp;</div>
<div>typedef SWIFT_ENUM(NSInteger, FooBar) {<br></div>
<div> FooBarOne = 0,<br></div>
<div> FooBarTwo = 1,<br></div>
<div>};<br></div>
<div>&nbsp;</div>
<div>SWIFT_CLASS("_TtCC7unnamed3Foo3Baz")<br></div>
<div>@interface FooBaz : NSObject<br></div>
<div>- (nonnull instancetype)init OBJC_DESIGNATED_INITIALIZER;<br></div>
<div>@end<br></div>
<div>&nbsp;</div>
<div>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:<br></div>
<div>&nbsp;</div>
<div>class Foo: NSObject {<br></div>
<div> &nbsp;&nbsp;@objc enum Bar: Int {<br></div>
<div> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;case One, Two<br></div>
<div> &nbsp;&nbsp;}<br></div>
<div>}<br></div>
<div>&nbsp;</div>
<div>class Baz: NSObject {<br></div>
<div> &nbsp;&nbsp;@objc enum Bar: Int {<br></div>
<div> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;case Apple, Orange<br></div>
<div> &nbsp;&nbsp;}<br></div>
<div>}<br></div>
<div>&nbsp;</div>
<div>is currently exported to Obj-C as:<br></div>
<div>&nbsp;</div>
<div>SWIFT_CLASS("_TtC7unnamed3Baz")<br></div>
<div>@interface Baz : NSObject<br></div>
<div>- (nonnull instancetype)init OBJC_DESIGNATED_INITIALIZER;<br></div>
<div>@end<br></div>
<div>&nbsp;</div>
<div>typedef SWIFT_ENUM(NSInteger, Bar) {<br></div>
<div> BarApple = 0,<br></div>
<div> BarOrange = 1,<br></div>
<div>};<br></div>
<div>&nbsp;</div>
<div>SWIFT_CLASS("_TtC7unnamed3Foo")<br></div>
<div>@interface Foo : NSObject<br></div>
<div>- (nonnull instancetype)init OBJC_DESIGNATED_INITIALIZER;<br></div>
<div>@end<br></div>
<div>&nbsp;</div>
<div>typedef SWIFT_ENUM(NSInteger, Bar) {<br></div>
<div> BarOne = 0,<br></div>
<div> BarTwo = 1,<br></div>
<div>};<br></div>
<div>&nbsp;</div>
<div>This is attempting to redefine the type Bar, which is of course problematic.<br></div>
<div>&nbsp;</div>
<div>-Kevin Ballard<br></div>
<div>_______________________________________________<br></div>
<div>swift-evolution mailing list<br></div>
<div><a href="mailto:swift-evolution@swift.org">swift-evolution@swift.org</a><br></div>
<div>https://lists.swift.org/mailman/listinfo/swift-evolution<br></div>
</blockquote></blockquote></div>
</div>
</blockquote></div>
</blockquote><div>&nbsp;</div>
</body>
</html>