[swift-evolution] [PITCH] ADD AN @RESTRICTED DECLARATION ATTRIBUTE

Stuart Breckenridge stuart.breckenridge at icloud.com
Thu May 26 08:25:06 CDT 2016


ADD AN @RESTRICTED DECLARATION ATTRIBUTE

Proposal: SE-NNNN
Author: Stuart Breckenridge
Status: DRAFT
Review Manager: TBD
Introduction

Adapted from the Swift 2.2 Programming Guide:
The @available attribute indicates a declaration’s life cycle relative to certain platforms and operating systems. Today’s functionality allows you to add multiple @available attributes on a declaration to specify its availability on different platforms.
In a related Swift Evolution discussion examining the @available attribute, it was confirmed that there is currently no way to limit availability to specific platform without using the long form approach.
Motivation

When a declaration is only available on a certain platform, it requires multiple @available attributes to restrict its availability to that platform. Consider the following example using SLServiceType like constants:
@available(iOS, unavailable)
@available(tvOS, unavailable)
@available(watchOS, unavailable)
@available(OSX 10.8, *)
case LinkedIn = "com.apple.social.linkedin"
The compiler will only use an @available attribute when the attribute specifies a platform that matches the current target platform. The implication being that if the target platform isn’t specified, then the attribute defaults to available.
Thus, while it is clear that the above is restricting availability to OS X 10.8 and later, it is verbose and can be simplified.
Proposal

Implement an @restricted attribute which is the inverse of @available. The effect would be that the compiler would use @restricted to limit the declaration to be available on the platform(s) specified in the attribute. Similar to @available, multiple @restricted attributes can be added to a declaration. 
Therefore, where @restricted attribute(s) are present and target platform is not specified, the declaration is not available on the unspecified target platform. In addition, where a @restricted attribute has been applied to a declaration, it should not be commingled with @available on the same declaration (it would lead to intense confusion).
Design

From a syntax perspective, it would follow @available:
@restricted(platform name version number, *)
or
@restricted(platform name, introduced=version number)
Similarly, all @available arguments would be available to @restricted. 
Examples

Using the previous example, instead of using @available to specify unavailability, we use @restricted to scope the declarations availability:
Single Platform Restriction
@restricted(OSX 10.8, *)
case LinkedIn = "com.apple.social.linkedin"
Effect: only available on OS X 10.8 or newer.
Multiple Platform Restriction
@restricted(OSX 10.8, iOS 9.4, *)
case LinkedIn = "com.apple.social.linkedin"
Effect: Available on OSX 10.8 or newer, and iOS 9.4 or newer.
Restricted within Version Bounds
@restricted(OSX, introduced=10.8, deprecated=10.10, obsoleted=10.11, message="No longer available.")
case LinkedIn = "com.apple.social.linkedin"
Effect: Available on OS X from 10.8 through 10.11 only.
Restricted with Renamed Case
// Initial Release
@restricted(OSX 10.10, *)
case TencentWeibo = "com.apple.social.tencentweibo"

// Second Release
@restricted(OSX, introduced=10.10, deprecated=10.11, renamed="Weibo")
case TencentWeibo = "com.apple.social.tencentweibo"

@restricted(OSX 10.11) case Weibo = "com.apple.social.weibo"
Effect: Initial release case is restricted to 10.10 and newer; second release has the original case deprecated from 10.11, with a new case introduced which is available on OS X 10.11 and newer only. 
Benefits & Impact on existing code

@restricted has the benefit of reducing the amount code while maintaining clarity of purpose: it is obvious based on the attribute name what the intent is. 
@restricted is purely additive, and therefore has no impact on existing code that makes use of @available. 
Alternatives

An alternative, though not a strict replacement of @restricted, could be to extract the unavailableargument and use it as an attribute (@unavailable). In use:
@available(OSX 10.8, *)
@unavailable(iOS, *)
case LinkedIn = "com.apple.social.linkedin"
Effect: Available on OS X but not iOS.
@unavailable is worthy of further discussion as using an unavailable argument inside an @availableattribute seems counterintuitive. 
However, this proposal is limited to the consideration of @restricted.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20160526/782d0789/attachment.html>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: smime.p7s
Type: application/pkcs7-signature
Size: 3138 bytes
Desc: not available
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20160526/782d0789/attachment.p7s>


More information about the swift-evolution mailing list