-
Notifications
You must be signed in to change notification settings - Fork 434
Generate availability annotations #2232
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 1 commit
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -42,6 +42,8 @@ public struct CodeGenerator: Sendable { | |
public var server: Bool | ||
/// The name of the core gRPC module. | ||
public var grpcCoreModuleName: String | ||
/// The availability annotations to use on the generated code. | ||
public var availability: AvailabilityAnnotations = .default | ||
|
||
/// Creates a new configuration. | ||
/// | ||
|
@@ -84,6 +86,50 @@ public struct CodeGenerator: Sendable { | |
/// The generated code will have `package` access level. | ||
public static var `package`: Self { Self(level: .`package`) } | ||
} | ||
|
||
// The availability that generated code is annotated generated with. | ||
public struct AvailabilityAnnotations: Sendable, Hashable { | ||
public struct Platform: Sendable, Hashable { | ||
/// The name of the OS, e.g. 'macOS'. | ||
public var os: String | ||
/// The version of the OS, e.g. '15.0'. | ||
public var version: String | ||
|
||
public init(os: String, version: String) { | ||
self.os = os | ||
self.version = version | ||
} | ||
} | ||
|
||
fileprivate enum Wrapped: Sendable, Hashable { | ||
case macOS15Aligned | ||
case custom([Platform]) | ||
} | ||
|
||
fileprivate var wrapped: Wrapped | ||
|
||
private init(_ wrapped: Wrapped) { | ||
self.wrapped = wrapped | ||
} | ||
|
||
/// Use the default availability. | ||
/// | ||
/// The default platform availability is: | ||
/// - macOS 15.0 | ||
/// - iOS 18.0 | ||
/// - tvOS 18.0 | ||
/// - watchOS 11.0 | ||
/// - visionOS 2.0 | ||
Comment on lines
+117
to
+122
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can we include There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
I couldn't find authoritative documentation on this, but:
I also just tested this locally by building code for Mac Catalyst which only had iOS availability annotations on. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. TIL. We should reconsider what we do in other projects then, because we have added it explicitly elsewhere. |
||
public static var `default`: Self { | ||
Self(.macOS15Aligned) | ||
} | ||
|
||
/// Use a custom set of availability attributes. | ||
/// - Parameter platforms: Availability requirements. | ||
public static func custom(_ platforms: [Platform]) -> Self { | ||
Self(.custom(platforms)) | ||
} | ||
} | ||
} | ||
|
||
/// Transforms a ``CodeGenerationRequest`` object into a ``SourceFile`` object containing | ||
|
@@ -100,11 +146,25 @@ public struct CodeGenerator: Sendable { | |
accessLevelOnImports: self.config.accessLevelOnImports, | ||
client: self.config.client, | ||
server: self.config.server, | ||
grpcCoreModuleName: self.config.grpcCoreModuleName | ||
grpcCoreModuleName: self.config.grpcCoreModuleName, | ||
availability: AvailabilityDescription(self.config.availability) | ||
) | ||
|
||
let sourceFile = try textRenderer.render(structured: structuredSwiftRepresentation) | ||
|
||
return sourceFile | ||
} | ||
} | ||
|
||
extension AvailabilityDescription { | ||
init(_ availability: CodeGenerator.Config.AvailabilityAnnotations) throws { | ||
switch availability.wrapped { | ||
case .macOS15Aligned: | ||
self = .macOS15Aligned | ||
case .custom(let platforms): | ||
self.osVersions = platforms.map { | ||
.init(os: .init(name: $0.os), version: $0.version) | ||
} | ||
} | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -14,6 +14,18 @@ | |
* limitations under the License. | ||
*/ | ||
|
||
extension AvailabilityDescription { | ||
package static let macOS15Aligned = AvailabilityDescription( | ||
osVersions: [ | ||
OSVersion(os: .macOS, version: "15.0"), | ||
OSVersion(os: .iOS, version: "18.0"), | ||
OSVersion(os: .watchOS, version: "11.0"), | ||
OSVersion(os: .tvOS, version: "18.0"), | ||
OSVersion(os: .visionOS, version: "2.0"), | ||
] | ||
) | ||
} | ||
|
||
extension TypealiasDescription { | ||
/// `typealias Input = <name>` | ||
package static func methodInput( | ||
|
@@ -341,6 +353,7 @@ extension [CodeBlock] { | |
package static func serviceMetadata( | ||
accessModifier: AccessModifier? = nil, | ||
service: ServiceDescriptor, | ||
availability: AvailabilityDescription, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. API breakage is detecting a false positive here:
|
||
namer: Namer = Namer() | ||
) -> Self { | ||
var blocks: [CodeBlock] = [] | ||
|
@@ -357,7 +370,7 @@ extension [CodeBlock] { | |
comment: .doc( | ||
"Namespace containing generated types for the \"\(service.name.identifyingName)\" service." | ||
), | ||
item: .declaration(.enum(serviceNamespace)) | ||
item: .declaration(.guarded(availability, .enum(serviceNamespace))) | ||
) | ||
) | ||
|
||
|
@@ -367,7 +380,9 @@ extension [CodeBlock] { | |
literalFullyQualifiedService: service.name.identifyingName, | ||
namer: namer | ||
) | ||
blocks.append(CodeBlock(item: .declaration(.extension(descriptorExtension)))) | ||
blocks.append( | ||
CodeBlock(item: .declaration(.guarded(availability, .extension(descriptorExtension)))) | ||
) | ||
|
||
return blocks | ||
} | ||
|
Uh oh!
There was an error while loading. Please reload this page.