diff --git a/Generator/Sources/ProjectionModel/Projection+conversion.swift b/Generator/Sources/ProjectionModel/Projection+conversion.swift index 34e1a45..b7dddda 100644 --- a/Generator/Sources/ProjectionModel/Projection+conversion.swift +++ b/Generator/Sources/ProjectionModel/Projection+conversion.swift @@ -83,9 +83,10 @@ 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, @@ -93,7 +94,7 @@ extension Projection { 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, diff --git a/Generator/Sources/ProjectionModel/Projection.swift b/Generator/Sources/ProjectionModel/Projection.swift index 3dcdc4a..24599f1 100644 --- a/Generator/Sources/ProjectionModel/Projection.swift +++ b/Generator/Sources/ProjectionModel/Projection.swift @@ -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 @@ -10,8 +11,11 @@ public class Projection { public private(set) var modulesByName = OrderedDictionary() 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) diff --git a/Generator/Sources/SwiftWinRT/CommandLineArguments.swift b/Generator/Sources/SwiftWinRT/CommandLineArguments.swift index 8021403..4d72f7a 100644 --- a/Generator/Sources/SwiftWinRT/CommandLineArguments.swift +++ b/Generator/Sources/SwiftWinRT/CommandLineArguments.swift @@ -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 diff --git a/Generator/Sources/SwiftWinRT/Writing/ABIBinding.swift b/Generator/Sources/SwiftWinRT/Writing/ABIBinding.swift index c48f25f..ab852ce 100644 --- a/Generator/Sources/SwiftWinRT/Writing/ABIBinding.swift +++ b/Generator/Sources/SwiftWinRT/Writing/ABIBinding.swift @@ -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), @@ -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 } } @@ -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 { "..." } @@ -110,7 +110,7 @@ fileprivate func writeStructBindingExtension( // extension : 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 @@ -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 @@ -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 diff --git a/Generator/Sources/SwiftWinRT/Writing/ClassDefinition.swift b/Generator/Sources/SwiftWinRT/Writing/ClassDefinition.swift index c30f07f..3682e57 100644 --- a/Generator/Sources/SwiftWinRT/Writing/ClassDefinition.swift +++ b/Generator/Sources/SwiftWinRT/Writing/ClassDefinition.swift @@ -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( @@ -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) @@ -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 @@ -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 @@ -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() }, diff --git a/Generator/Sources/SwiftWinRT/Writing/EnumDefinition.swift b/Generator/Sources/SwiftWinRT/Writing/EnumDefinition.swift index 6b429fd..5280ace 100644 --- a/Generator/Sources/SwiftWinRT/Writing/EnumDefinition.swift +++ b/Generator/Sources/SwiftWinRT/Writing/EnumDefinition.swift @@ -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 @@ -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) @@ -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()), diff --git a/Generator/Sources/SwiftWinRT/Writing/InterfaceDefinition.swift b/Generator/Sources/SwiftWinRT/Writing/InterfaceDefinition.swift index b2d0206..1f301c3 100644 --- a/Generator/Sources/SwiftWinRT/Writing/InterfaceDefinition.swift +++ b/Generator/Sources/SwiftWinRT/Writing/InterfaceDefinition.swift @@ -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 }, @@ -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) }, @@ -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, @@ -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) @@ -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) @@ -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) @@ -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 }, @@ -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( diff --git a/Generator/Sources/SwiftWinRT/Writing/MemberDefinition.swift b/Generator/Sources/SwiftWinRT/Writing/MemberDefinition.swift index cfc2663..69c1064 100644 --- a/Generator/Sources/SwiftWinRT/Writing/MemberDefinition.swift +++ b/Generator/Sources/SwiftWinRT/Writing/MemberDefinition.swift @@ -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), @@ -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), @@ -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, @@ -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, @@ -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), diff --git a/Generator/Sources/SwiftWinRT/Writing/NonthrowingProperties.swift b/Generator/Sources/SwiftWinRT/Writing/NonthrowingProperties.swift index 9655553..bc6ed28 100644 --- a/Generator/Sources/SwiftWinRT/Writing/NonthrowingProperties.swift +++ b/Generator/Sources/SwiftWinRT/Writing/NonthrowingProperties.swift @@ -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 diff --git a/Generator/Sources/SwiftWinRT/Writing/StructDefinition.swift b/Generator/Sources/SwiftWinRT/Writing/StructDefinition.swift index db3ff4b..a39ef6a 100644 --- a/Generator/Sources/SwiftWinRT/Writing/StructDefinition.swift +++ b/Generator/Sources/SwiftWinRT/Writing/StructDefinition.swift @@ -16,7 +16,7 @@ internal func writeStructDefinition(_ structDefinition: StructDefinition, projec ] try writer.writeStruct( documentation: projection.getDocumentationComment(structDefinition), - attributes: Projection.getAttributes(structDefinition), + attributes: projection.getAttributes(structDefinition), visibility: Projection.toVisibility(structDefinition.visibility), name: try projection.toTypeName(structDefinition), typeParams: structDefinition.genericParams.map { $0.name }, @@ -34,7 +34,7 @@ fileprivate func writeStructFields(_ structDefinition: StructDefinition, project try writer.writeStoredProperty( documentation: projection.getDocumentationComment(field), - attributes: Projection.getAttributes(field), + attributes: projection.getAttributes(field), visibility: .public, declarator: .var, name: Projection.toMemberName(field), type: projection.toTypeExpression(field.type)) } diff --git a/Generator/Sources/SwiftWinRT/Writing/TypeDefinition.swift b/Generator/Sources/SwiftWinRT/Writing/TypeDefinition.swift index a5acfbe..10ee200 100644 --- a/Generator/Sources/SwiftWinRT/Writing/TypeDefinition.swift +++ b/Generator/Sources/SwiftWinRT/Writing/TypeDefinition.swift @@ -27,7 +27,7 @@ internal func writeTypeDefinition( fileprivate func writeDelegateDefinition(_ delegateDefinition: DelegateDefinition, projection: Projection, to writer: SwiftSourceFileWriter) throws { try writer.writeTypeAlias( documentation: projection.getDocumentationComment(delegateDefinition), - attributes: Projection.getAttributes(delegateDefinition), + attributes: projection.getAttributes(delegateDefinition), visibility: Projection.toVisibility(delegateDefinition.visibility), name: try projection.toTypeName(delegateDefinition), typeParams: delegateDefinition.genericParams.map { $0.name }, diff --git a/Generator/Sources/SwiftWinRT/createProjection.swift b/Generator/Sources/SwiftWinRT/createProjection.swift index 76d7c64..6569cf6 100644 --- a/Generator/Sources/SwiftWinRT/createProjection.swift +++ b/Generator/Sources/SwiftWinRT/createProjection.swift @@ -11,7 +11,8 @@ internal func createProjection(commandLineArguments: CommandLineArguments, proje winMDFilePaths.formUnion(try getWindowsSdkWinMDPaths(sdkVersion: windowsSdkVersion)) } - let projection = Projection() + let projection = Projection( + deprecations: !commandLineArguments.noDeprecations) // Preload assemblies and create modules for filePath in winMDFilePaths.sorted(by: { $0.lastPathComponent < $1.lastPathComponent }) {