.NET has an EditorBrowsable 
<https://msdn.microsoft.com/en-us/library/system.componentmodel.editorbrowsableattribute(v=vs.110).aspx>
 attribute that controls whether things appear in autocomplete or not. I think 
that this alternative deserves some consideration.

It clearly won't have identical semantics, but I think that it would be a 
little more graceful and much less involved. This solution only needs a new 
attribute and SourceKit changes.

Félix

> Le 5 janv. 2016 à 15:23:55, Kevin Ballard via swift-evolution 
> <[email protected]> a écrit :
> 
> Proposal PR submitted as https://github.com/apple/swift-evolution/pull/85
> 
> -Kevin Ballard
> 
> On Tue, Dec 15, 2015, at 11:18 AM, Kevin Ballard wrote:
>> When writing ObjC code, there's a macro NS_REFINED_FOR_SWIFT (or 
>> __attribute__((swift_private))) that mangles the name when imported into 
>> Swift. The intention here is to hide an API from normal Swift usage (but 
>> still make it callable) so that a better Swift API can be written around it.
>> 
>> But there's no facility for doing this in reverse. You can expose Swift APIs 
>> to ObjC, but the API has to be ObjC-compatible. Which means that if you have 
>> a non-ObjC-compatible API, you have to write a separate API to expose it to 
>> ObjC, and this separate API now shows up in the Swift API too.
>> 
>> I think the simplest way to fix this is to allow for a modifier public(objc) 
>> (following the syntax of private(set)). The only thing this modifier does is 
>> ensure the declaration gets added to the generated header as if it were 
>> public (or—for apps—internal). If the declaration is not marked as @objc 
>> then it would emit an error (it could imply @objc but it feels weird to me 
>> to have an access control modifier do that). If the declaration is already 
>> public (but not internal, so the same source can be used in apps and 
>> libraries) it will emit a warning.
>> 
>> Armed with this new modifier, I can start to write code like
>> 
>> class MyClass: NSObject {
>>     func foo<T>(x: T) { ... }
>> }
>> 
>> extension MyClass {
>>     @objc(foo) public(objc) private func __foo(x: AnyObject) { ... }
>> }
>> 
>> When used on a property that already has private(set), the public(objc) 
>> modifier will only apply to the getter (e.g. the private(set) takes 
>> precedence for the setter).
>> 
>> Alternatives:
>> 
>> * Add a new attribute @export_objc that has the same behavior.
>> 
>> * Change the @objc attribute to take an optional second argument, which may 
>> be the token "exported", as in @objc(foo,exported). When using the 
>> "exported" token, the selector portion is required. We could possibly 
>> support an empty selector to indicate the default, as in @objc(,exported), 
>> but that looks odd.
>> 
>> My preference is for public(objc) as proposed as it matches more closely 
>> with the intended behavior, which is "this API is private in Swift and 
>> public in ObjC".
>> 
>> -Kevin Ballard
> _______________________________________________
> swift-evolution mailing list
> [email protected]
> https://lists.swift.org/mailman/listinfo/swift-evolution

_______________________________________________
swift-evolution mailing list
[email protected]
https://lists.swift.org/mailman/listinfo/swift-evolution

Reply via email to