Skip to content

Commit

Permalink
Support --no-deprecations command line flag (#472)
Browse files Browse the repository at this point in the history
  • Loading branch information
tristanlabelle authored Jan 8, 2025
1 parent 0744143 commit 7b87e31
Show file tree
Hide file tree
Showing 12 changed files with 44 additions and 35 deletions.
5 changes: 3 additions & 2 deletions Generator/Sources/ProjectionModel/Projection+conversion.swift
Original file line number Diff line number Diff line change
Expand Up @@ -83,17 +83,18 @@ extension Projection {
: definitionBindingType.member(try Projection.toBindingInstantiationTypeName(genericArgs: type.genericArgs))
}

public static func getAvailableAttribute(
public func getAvailableAttribute(
_ attributable: any Attributable,
deprecator: (any Attributable)? = nil) throws -> SwiftAttribute? {
guard self.deprecations else { return nil }
guard let deprecatedAttribute = try attributable.findAttribute(WindowsMetadata.DeprecatedAttribute.self)
?? deprecator?.findAttribute(WindowsMetadata.DeprecatedAttribute.self) else { return nil }
// DeprecatedAttribute tells us the ContractVersion in which an attribute was deprecated,
// but since apps should run on any future OS version, we can mark it as unconditionally deprecated.
return SwiftAttribute("available(*, deprecated, message: \"\(deprecatedAttribute.message)\")")
}

public static func getAttributes(
public func getAttributes(
_ attributable: any Attributable,
deprecator: (any Attributable)? = nil) throws -> [SwiftAttribute] {
// We recognize any attribute called SwiftAttribute and expect it has a field called Literal,
Expand Down
6 changes: 5 additions & 1 deletion Generator/Sources/ProjectionModel/Projection.swift
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import Collections
import DotNetMetadata
import DotNetXMLDocs

/// Describes how to project a collection of Windows metadata assemblies into Swift modules.
public class Projection {
internal struct AssemblyEntry {
var module: Module
Expand All @@ -10,8 +11,11 @@ public class Projection {

public private(set) var modulesByName = OrderedDictionary<String, Module>()
internal var assembliesToModules = [Assembly: AssemblyEntry]()
public let deprecations: Bool

public init() {}
public init(deprecations: Bool = true) {
self.deprecations = deprecations
}

public func addModule(name: String) -> Module {
precondition(modulesByName[name] == nil)
Expand Down
3 changes: 3 additions & 0 deletions Generator/Sources/SwiftWinRT/CommandLineArguments.swift
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,9 @@ struct CommandLineArguments: ParsableCommand {
@Flag(name: .customLong("no-docs"), help: "Don't generate documentation comments.")
var noDocs: Bool = false

@Flag(name: .customLong("no-deprecations"), help: "Don't generate @available attributes for deprecated APIs.")
var noDeprecations: Bool = false

@Option(name: .customLong("out"), help: .init("A path to the output directory.", valueName: "dir"))
var outputDirectoryPath: String

Expand Down
12 changes: 6 additions & 6 deletions Generator/Sources/SwiftWinRT/Writing/ABIBinding.swift
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ internal func writeABIBindingConformance(_ typeDefinition: TypeDefinition, gener
// internal final class Boolean: WinRTBinding... {}
// }
try writer.writeExtension(
attributes: [ Projection.getAvailableAttribute(typeDefinition) ].compactMap { $0 },
attributes: [ projection.getAvailableAttribute(typeDefinition) ].compactMap { $0 },
type: projection.toBindingType(typeDefinition)) { writer in
try writeInterfaceOrDelegateBindingType(
typeDefinition.bindType(genericArgs: genericArgs),
Expand All @@ -70,7 +70,7 @@ internal func writeABIBindingConformance(_ typeDefinition: TypeDefinition, gener
// Generic type definition. Create a namespace for projections of specializations.
// public enum IVectorBinding {}
try writer.writeEnum(
attributes: [ Projection.getAvailableAttribute(typeDefinition) ].compactMap { $0 },
attributes: [ projection.getAvailableAttribute(typeDefinition) ].compactMap { $0 },
visibility: Projection.toVisibility(typeDefinition.visibility),
name: projection.toBindingTypeName(typeDefinition)) { _ in }
}
Expand All @@ -84,7 +84,7 @@ fileprivate func writeEnumBindingExtension(
let enumBindingProtocol = try projection.isSwiftEnumEligible(enumDefinition)
? SupportModules.WinRT.closedEnumBinding : SupportModules.WinRT.openEnumBinding
try writer.writeExtension(
attributes: [ Projection.getAvailableAttribute(enumDefinition) ].compactMap { $0 },
attributes: [ projection.getAvailableAttribute(enumDefinition) ].compactMap { $0 },
type: projection.toTypeReference(enumDefinition.bindType()),
protocolConformances: [ enumBindingProtocol ]) { writer in
// public static var typeName: String { "..." }
Expand All @@ -110,7 +110,7 @@ fileprivate func writeStructBindingExtension(

// extension <struct>: IReferenceableBinding[, PODBinding]
try writer.writeExtension(
attributes: [ Projection.getAvailableAttribute(structDefinition) ].compactMap { $0 },
attributes: [ projection.getAvailableAttribute(structDefinition) ].compactMap { $0 },
type: .named(projection.toTypeName(structDefinition)),
protocolConformances: protocolConformances) { writer in

Expand Down Expand Up @@ -276,7 +276,7 @@ fileprivate func writeClassBindingType(
// Runtimeclass bindings are classes so they can be found using NSClassFromString,
// which allows supporting instantiating the most derived class wrapper when returned from WinRT.
try writer.writeClass(
attributes: [ Projection.getAvailableAttribute(classDefinition) ].compactMap { $0 },
attributes: [ projection.getAvailableAttribute(classDefinition) ].compactMap { $0 },
visibility: Projection.toVisibility(classDefinition.visibility),
name: projection.toBindingTypeName(classDefinition),
protocolConformances: [ bindingProtocol ]) { writer throws in
Expand Down Expand Up @@ -377,7 +377,7 @@ fileprivate func writeInterfaceOrDelegateBindingType(
// Projections of generic instantiations are not owned by any specific module.
// Making them internal avoids clashes between redundant definitions across modules.
try writer.writeEnum(
attributes: [ Projection.getAvailableAttribute(type.definition) ].compactMap { $0 },
attributes: [ projection.getAvailableAttribute(type.definition) ].compactMap { $0 },
visibility: type.genericArgs.isEmpty ? Projection.toVisibility(type.definition.visibility) : .internal,
name: name,
protocolConformances: [ bindingProtocol ]) { writer throws in
Expand Down
10 changes: 5 additions & 5 deletions Generator/Sources/SwiftWinRT/Writing/ClassDefinition.swift
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ internal func writeClassDefinition(_ classDefinition: ClassDefinition, projectio

try writer.writeEnum(
documentation: projection.getDocumentationComment(classDefinition),
attributes: Projection.getAttributes(classDefinition),
attributes: projection.getAttributes(classDefinition),
visibility: Projection.toVisibility(classDefinition.visibility),
name: typeName) { writer in
try writeClassMembers(
Expand Down Expand Up @@ -48,7 +48,7 @@ internal func writeClassDefinition(_ classDefinition: ClassDefinition, projectio

try writer.writeClass(
documentation: projection.getDocumentationComment(classDefinition),
attributes: Projection.getAttributes(classDefinition),
attributes: projection.getAttributes(classDefinition),
visibility: Projection.toVisibility(classDefinition.visibility, inheritableClass: !classDefinition.isSealed),
final: classDefinition.isSealed, name: typeName, base: base, protocolConformances: protocolConformances) { writer in
try writeClassMembers(classDefinition, interfaces: interfaces, projection: projection, to: writer)
Expand Down Expand Up @@ -274,7 +274,7 @@ fileprivate func writeComposableInitializers(

try writer.writeInit(
documentation: docs,
attributes: Projection.getAttributes(method),
attributes: projection.getAttributes(method),
visibility: .public,
override: `override`,
params: params.dropLast(2).map { $0.toSwiftParam() }, // Drop inner and outer pointer params
Expand Down Expand Up @@ -316,7 +316,7 @@ fileprivate func writeDefaultActivatableInitializer(

try writer.writeInit(
documentation: constructor.flatMap { try projection.getDocumentationComment($0) },
attributes: constructor.map { try Projection.getAttributes($0) } ?? [],
attributes: constructor.map { try projection.getAttributes($0) } ?? [],
visibility: .public,
override: isOverriding,
throws: true) { writer in
Expand Down Expand Up @@ -352,7 +352,7 @@ fileprivate func writeActivatableInitializers(

try writer.writeInit(
documentation: docs,
attributes: Projection.getAttributes(method),
attributes: projection.getAttributes(method),
visibility: .public,
override: isOverriding,
params: params.map { $0.toSwiftParam() },
Expand Down
6 changes: 3 additions & 3 deletions Generator/Sources/SwiftWinRT/Writing/EnumDefinition.swift
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ fileprivate func writeOpenEnumDefinition(_ enumDefinition: EnumDefinition, proje
let structName = try projection.toTypeName(enumDefinition)
try writer.writeStruct(
documentation: projection.getDocumentationComment(enumDefinition),
attributes: Projection.getAttributes(enumDefinition),
attributes: projection.getAttributes(enumDefinition),
visibility: Projection.toVisibility(enumDefinition.visibility),
name: structName,
protocolConformances: [.named("CStyleEnum") ]) { writer throws in
Expand All @@ -44,7 +44,7 @@ fileprivate func writeOpenEnumDefinition(_ enumDefinition: EnumDefinition, proje
let initializer = value == "0" ? "Self()" : "Self(rawValue: \(value))"
try writer.writeStoredProperty(
documentation: projection.getDocumentationComment(field),
attributes: Projection.getAttributes(field),
attributes: projection.getAttributes(field),
visibility: .public, static: true, declarator: .let,
name: Projection.toMemberName(field),
initialValue: initializer)
Expand Down Expand Up @@ -90,7 +90,7 @@ fileprivate func writeOpenEnumDefinition(_ enumDefinition: EnumDefinition, proje
fileprivate func writeClosedEnumDefinition(_ enumDefinition: EnumDefinition, projection: Projection, to writer: SwiftSourceFileWriter) throws {
try writer.writeEnum(
documentation: projection.getDocumentationComment(enumDefinition),
attributes: Projection.getAttributes(enumDefinition),
attributes: projection.getAttributes(enumDefinition),
visibility: Projection.toVisibility(enumDefinition.visibility),
name: try projection.toTypeName(enumDefinition),
rawValueType: try projection.toTypeExpression(enumDefinition.underlyingType.bindNode()),
Expand Down
16 changes: 8 additions & 8 deletions Generator/Sources/SwiftWinRT/Writing/InterfaceDefinition.swift
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ fileprivate func writeProtocol(_ interfaceDefinition: InterfaceDefinition, proje
let protocolName = try projection.toProtocolName(interfaceDefinition)
try writer.writeProtocol(
documentation: projection.getDocumentationComment(interfaceDefinition),
attributes: Projection.getAttributes(interfaceDefinition),
attributes: projection.getAttributes(interfaceDefinition),
visibility: Projection.toVisibility(interfaceDefinition.visibility),
name: protocolName,
typeParams: interfaceDefinition.genericParams.map { $0.name },
Expand All @@ -78,7 +78,7 @@ fileprivate func writeProtocol(_ interfaceDefinition: InterfaceDefinition, proje
guard method.nameKind == .regular else { continue }
try writer.writeFunc(
documentation: projection.getDocumentationComment(method),
attributes: Projection.getAttributes(method),
attributes: projection.getAttributes(method),
name: Projection.toMemberName(method),
typeParams: method.genericParams.map { $0.name },
params: method.params.map { try projection.toParameter($0) },
Expand All @@ -90,7 +90,7 @@ fileprivate func writeProtocol(_ interfaceDefinition: InterfaceDefinition, proje
if let addAccessor = try event.addAccessor {
try writer.writeFunc(
documentation: projection.getDocumentationComment(event),
attributes: Projection.getAttributes(addAccessor, deprecator: event) + [ .discardableResult ],
attributes: projection.getAttributes(addAccessor, deprecator: event) + [ .discardableResult ],
name: Projection.toMemberName(event),
params: addAccessor.params.map { try projection.toParameter(label: "adding", $0) },
throws: true,
Expand All @@ -99,7 +99,7 @@ fileprivate func writeProtocol(_ interfaceDefinition: InterfaceDefinition, proje

if let removeAccessor = try event.removeAccessor {
try writer.writeFunc(
attributes: Projection.getAttributes(removeAccessor, deprecator: event),
attributes: projection.getAttributes(removeAccessor, deprecator: event),
name: Projection.toMemberName(event),
params: removeAccessor.params.map { try projection.toParameter(label: "removing", $0) },
throws: true)
Expand All @@ -113,7 +113,7 @@ fileprivate func writeProtocol(_ interfaceDefinition: InterfaceDefinition, proje
if let getter = try property.getter {
try writer.writeProperty(
documentation: projection.getDocumentationComment(property, accessor: .getter),
attributes: Projection.getAttributes(getter, deprecator: property),
attributes: projection.getAttributes(getter, deprecator: property),
name: Projection.toMemberName(property),
type: projection.toReturnType(getter.returnType),
throws: true)
Expand All @@ -123,7 +123,7 @@ fileprivate func writeProtocol(_ interfaceDefinition: InterfaceDefinition, proje
try writer.writeFunc(
groupAsProperty: true,
documentation: projection.getDocumentationComment(property, accessor: .setter),
attributes: Projection.getAttributes(setter, deprecator: property),
attributes: projection.getAttributes(setter, deprecator: property),
name: Projection.toMemberName(property),
params: setter.params.map { try projection.toParameter($0) },
throws: true)
Expand All @@ -138,7 +138,7 @@ fileprivate func writeProtocol(_ interfaceDefinition: InterfaceDefinition, proje
fileprivate func writeProtocolTypeAlias(_ interfaceDefinition: InterfaceDefinition, projection: Projection, to writer: SwiftSourceFileWriter) throws {
try writer.writeTypeAlias(
documentation: projection.getDocumentationComment(interfaceDefinition),
attributes: [ Projection.getAvailableAttribute(interfaceDefinition) ].compactMap { $0 },
attributes: [ projection.getAvailableAttribute(interfaceDefinition) ].compactMap { $0 },
visibility: Projection.toVisibility(interfaceDefinition.visibility),
name: projection.toTypeName(interfaceDefinition),
typeParams: interfaceDefinition.genericParams.map { $0.name },
Expand All @@ -155,7 +155,7 @@ fileprivate func writeNonthrowingPropertiesExtension(

let protocolType = SwiftType.named(try projection.toProtocolName(interfaceDefinition))
try writer.writeExtension(
attributes: [ Projection.getAvailableAttribute(interfaceDefinition) ].compactMap { $0 },
attributes: [ projection.getAvailableAttribute(interfaceDefinition) ].compactMap { $0 },
type: protocolType) { writer in
for property in getSetProperties {
try writeNonthrowingPropertyImplementation(
Expand Down
10 changes: 5 additions & 5 deletions Generator/Sources/SwiftWinRT/Writing/MemberDefinition.swift
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ fileprivate func writePropertyDefinition(
let returnParamBinding = try projection.getParamBinding(getter.returnParam, genericTypeArgs: typeGenericArgs)
try writer.writeComputedProperty(
documentation: documentation ? projection.getDocumentationComment(property, accessor: .getter, classDefinition: classDefinition) : nil,
attributes: Projection.getAttributes(getter, deprecator: property),
attributes: projection.getAttributes(getter, deprecator: property),
visibility: overridable ? .open : .public,
static: `static`,
name: Projection.toMemberName(property),
Expand All @@ -72,7 +72,7 @@ fileprivate func writePropertyDefinition(
let newValueParamBinding = try projection.getParamBinding(newValueParam, genericTypeArgs: typeGenericArgs)
try writer.writeFunc(
documentation: documentation ? projection.getDocumentationComment(property, accessor: .setter, classDefinition: classDefinition) : nil,
attributes: Projection.getAttributes(setter, deprecator: property),
attributes: projection.getAttributes(setter, deprecator: property),
visibility: .public,
static: `static`,
name: Projection.toMemberName(property),
Expand Down Expand Up @@ -109,7 +109,7 @@ fileprivate func writeEventDefinition(
let eventRegistrationType = SupportModules.WinRT.eventRegistration
try writer.writeFunc(
documentation: documentation ? projection.getDocumentationComment(event, classDefinition: classDefinition) : nil,
attributes: Projection.getAttributes(addAccessor, deprecator: event) + [ .discardableResult ],
attributes: projection.getAttributes(addAccessor, deprecator: event) + [ .discardableResult ],
visibility: overridable ? .open : .public, static: `static`,
name: name,
params: [ handlerParamBinding.toSwiftParam(label: "adding") ], throws: true,
Expand All @@ -131,7 +131,7 @@ fileprivate func writeEventDefinition(
if let removeAccessor = try event.removeAccessor, let tokenParameter = try removeAccessor.params.first {
let tokenParamBinding = try projection.getParamBinding(tokenParameter, genericTypeArgs: typeGenericArgs)
try writer.writeFunc(
attributes: Projection.getAttributes(removeAccessor, deprecator: event),
attributes: projection.getAttributes(removeAccessor, deprecator: event),
visibility: overridable ? .open : .public,
static: `static`,
name: name,
Expand All @@ -152,7 +152,7 @@ fileprivate func writeMethodDefinition(
let (params, returnParam) = try projection.getParamBindings(method: method, genericTypeArgs: typeGenericArgs)
try writer.writeFunc(
documentation: documentation ? projection.getDocumentationComment(method, classDefinition: classDefinition) : nil,
attributes: Projection.getAttributes(method),
attributes: projection.getAttributes(method),
visibility: overridable ? .open : .public,
static: `static`,
name: Projection.toMemberName(method),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ internal func writeNonthrowingPropertyImplementation(

try writer.writeComputedProperty(
documentation: documentation ? projection.getDocumentationComment(property, accessor: .nonthrowingGetterSetter, classDefinition: classDefinition) : nil,
attributes: Projection.getAttributes(property),
attributes: projection.getAttributes(property),
visibility: .public,
static: `static`,
name: Projection.toMemberName(property) + "_", // Disambiguate from throwing accessors
Expand Down
Loading

0 comments on commit 7b87e31

Please sign in to comment.