From 2936a15bb97a052c89c514c521189c299fe30a21 Mon Sep 17 00:00:00 2001 From: Tristan Labelle Date: Wed, 25 Dec 2024 08:10:53 -0500 Subject: [PATCH 1/5] Better leverage Projection.toType(Reference|Expression) --- .../Projection+conversion.swift | 11 +++++ .../ProjectionModel/Projection+params.swift | 2 +- .../ProjectionModel/Projection+types.swift | 34 +++++-------- .../ProjectionModel/SupportModules.swift | 5 ++ .../SwiftWinRT/Writing/ABIBinding.swift | 49 +++++++++---------- .../SwiftWinRT/Writing/COMImportClass.swift | 12 ++--- .../SwiftWinRT/Writing/ClassDefinition.swift | 14 +++--- .../SwiftWinRT/Writing/EnumDefinition.swift | 4 +- .../Writing/InterfaceDefinition.swift | 2 +- .../SwiftWinRT/Writing/NamespaceModules.swift | 2 +- .../SwiftWinRT/Writing/StructDefinition.swift | 4 +- .../SwiftWinRT/Writing/TypeDefinition.swift | 2 +- 12 files changed, 70 insertions(+), 71 deletions(-) diff --git a/Generator/Sources/ProjectionModel/Projection+conversion.swift b/Generator/Sources/ProjectionModel/Projection+conversion.swift index de6f8520..1d19cb9a 100644 --- a/Generator/Sources/ProjectionModel/Projection+conversion.swift +++ b/Generator/Sources/ProjectionModel/Projection+conversion.swift @@ -72,6 +72,17 @@ extension Projection { return result } + public func toBindingType(_ type: TypeDefinition) throws -> SwiftType { + .named(try toBindingTypeName(type)) + } + + public func toBindingType(_ type: BoundType) throws -> SwiftType { + let definitionBindingType = try toBindingType(type.definition) + return type.genericArgs.isEmpty + ? definitionBindingType + : definitionBindingType.member(try Projection.toBindingInstantiationTypeName(genericArgs: type.genericArgs)) + } + public static func getSwiftAttributes(_ member: any Attributable) throws -> [SwiftAttribute] { // We recognize any attribute called SwiftAttribute and expect it has a field called Literal, // ideally that would be a positional argument, but IDL doesn't seem to have a syntax for that. diff --git a/Generator/Sources/ProjectionModel/Projection+params.swift b/Generator/Sources/ProjectionModel/Projection+params.swift index cfd30c90..a6776fe1 100644 --- a/Generator/Sources/ProjectionModel/Projection+params.swift +++ b/Generator/Sources/ProjectionModel/Projection+params.swift @@ -12,7 +12,7 @@ extension Projection { public func toParameter(label: String = "_", _ param: Param, genericTypeArgs: [TypeNode] = []) throws -> SwiftParam { SwiftParam(label: label, name: toParamName(param), `inout`: param.isByRef, - type: try genericTypeArgs.isEmpty ? toType(param.type) : toType(param.type.bindGenericParams(typeArgs: genericTypeArgs))) + type: try toTypeExpression(genericTypeArgs.isEmpty ? param.type : param.type.bindGenericParams(typeArgs: genericTypeArgs))) } public func getParamBinding(_ param: ParamBase, genericTypeArgs: [TypeNode] = []) throws -> ParamProjection { diff --git a/Generator/Sources/ProjectionModel/Projection+types.swift b/Generator/Sources/ProjectionModel/Projection+types.swift index 6616d453..acdd3f0f 100644 --- a/Generator/Sources/ProjectionModel/Projection+types.swift +++ b/Generator/Sources/ProjectionModel/Projection+types.swift @@ -3,28 +3,28 @@ import WindowsMetadata import CodeWriters extension Projection { - public func toType(_ type: TypeNode) throws -> SwiftType { + public func toTypeExpression(_ type: TypeNode, outerNullable: Bool = true) throws -> SwiftType { switch type { case let .bound(type): - return try toType(type) + let boundSwiftType = try toTypeReference(type) + return type.definition.isReferenceType && outerNullable ? boundSwiftType.optional() : boundSwiftType case let .genericParam(param): return .named(param.name) case let .array(of: element): - return .array(element: try toType(element)) + return .array(element: try toTypeExpression(element)) default: fatalError("Not implemented: Swift representation of values of type \(type)") } } - public func toType(_ boundType: BoundType, nullable: Bool = true) throws -> SwiftType { + public func toTypeReference(_ boundType: BoundType) throws -> SwiftType { if let specialTypeBinding = try getSpecialTypeBinding(boundType) { return specialTypeBinding.swiftType } - let swiftObjectType: SwiftType = .named( + return .named( try toTypeName(boundType.definition), - genericArgs: try boundType.genericArgs.map { try toType($0) }) - return boundType.definition.isReferenceType && nullable ? swiftObjectType.optional() : swiftObjectType + genericArgs: try boundType.genericArgs.map { try toTypeExpression($0) }) } public func isPODBinding(_ typeDefinition: TypeDefinition) throws -> Bool { @@ -60,9 +60,8 @@ extension Projection { try enumDefinition.attributes.contains(where: { try $0.type.name == "SwiftEnumAttribute" }) && !enumDefinition.isFlags } - public func toReturnType(_ type: TypeNode, typeGenericArgs: [TypeNode]? = nil) throws -> SwiftType { - let swiftType = try toType(type.bindGenericParams(typeArgs: typeGenericArgs)) - return isNullAsErrorEligible(type) ? swiftType.unwrapOptional() : swiftType + public func toReturnType(_ type: TypeNode) throws -> SwiftType { + try toTypeExpression(type, outerNullable: !isNullAsErrorEligible(type)) } public func getTypeBinding(_ type: TypeNode) throws -> TypeProjection { @@ -108,23 +107,12 @@ extension Projection { abiType = .unsafeMutablePointer(pointee: abiType).optional() } - let bindingType: SwiftType = try { - let bindingTypeName = try toBindingTypeName(type.definition) - if type.genericArgs.isEmpty { - return .named(bindingTypeName) - } - else { - return .named(bindingTypeName) - .member(try Projection.toBindingInstantiationTypeName(genericArgs: type.genericArgs)) - } - }() - return TypeProjection( abiType: abiType, abiDefaultValue: type.definition.isReferenceType ? "nil" : .defaultInitializer, - swiftType: try toType(type.asNode), + swiftType: try toTypeExpression(type.asNode), swiftDefaultValue: type.definition.isReferenceType ? "nil" : .defaultInitializer, - bindingType: bindingType, + bindingType: try toBindingType(type), kind: try isPODBinding(type.definition) ? .pod : .allocating) } diff --git a/Generator/Sources/ProjectionModel/SupportModules.swift b/Generator/Sources/ProjectionModel/SupportModules.swift index d6976d9d..88cbe81e 100644 --- a/Generator/Sources/ProjectionModel/SupportModules.swift +++ b/Generator/Sources/ProjectionModel/SupportModules.swift @@ -33,6 +33,11 @@ extension SupportModules.COM { public static var comBinding: SwiftType { moduleType.member("COMBinding") } public static var comTwoWayBinding: SwiftType { moduleType.member("COMTwoWayBinding") } + public static var comImport: SwiftType { moduleType.member("COMImport") } + public static func comImport(of type: SwiftType) -> SwiftType { + moduleType.member("COMImport", genericArgs: [type]) + } + public static var comEmbedding: SwiftType { moduleType.member("COMEmbedding") } public static var comReference: SwiftType { moduleType.member("COMReference") } diff --git a/Generator/Sources/SwiftWinRT/Writing/ABIBinding.swift b/Generator/Sources/SwiftWinRT/Writing/ABIBinding.swift index 7a56cd94..9cf55b6b 100644 --- a/Generator/Sources/SwiftWinRT/Writing/ABIBinding.swift +++ b/Generator/Sources/SwiftWinRT/Writing/ABIBinding.swift @@ -8,10 +8,11 @@ import struct Foundation.UUID /// Writes a type or extension providing the ABIBinding conformance for a given projected WinRT type. internal func writeABIBindingConformance(_ typeDefinition: TypeDefinition, genericArgs: [TypeNode]?, projection: Projection, to writer: SwiftSourceFileWriter) throws { if SupportModules.WinRT.getBuiltInTypeKind(typeDefinition) == .definitionAndBinding { - // The support module already defines a projection, just import and reexport it. + // The support module already defines a projection, just reexport it. if typeDefinition.isReferenceType { - let bindingTypeName = try projection.toBindingTypeName(typeDefinition) - writer.writeImport(exported: true, kind: .enum, module: SupportModules.WinRT.moduleName, symbolName: bindingTypeName) + writer.writeImport(exported: true, kind: .enum, + module: SupportModules.WinRT.moduleName, + symbolName: try projection.toBindingTypeName(typeDefinition)) } else { // The struct conforms to ABIBinding itself, and we already imported it. @@ -30,7 +31,7 @@ internal func writeABIBindingConformance(_ typeDefinition: TypeDefinition, gener let enumBindingProtocol = try projection.isSwiftEnumEligible(enumDefinition) ? SupportModules.WinRT.closedEnumBinding : SupportModules.WinRT.openEnumBinding try writer.writeExtension( - type: .named(projection.toTypeName(enumDefinition)), + type: projection.toTypeReference(enumDefinition.bindType()), protocolConformances: [ enumBindingProtocol ]) { writer in // public static var typeName: String { "..." } try writeTypeNameProperty(type: enumDefinition.bindType(), to: writer) @@ -59,7 +60,8 @@ internal func writeABIBindingConformance(_ typeDefinition: TypeDefinition, gener // Non-generic type, create a standard projection type. // enum IVectorBinding: WinRTBinding... {} try writeInterfaceOrDelegateBindingType(typeDefinition.bindType(), - projectionName: try projection.toBindingTypeName(typeDefinition), projection: projection, to: writer) + name: try projection.toBindingTypeName(typeDefinition), + projection: projection, to: writer) } else if let genericArgs { // Generic type specialization. Create a projection for the specialization. @@ -67,12 +69,11 @@ internal func writeABIBindingConformance(_ typeDefinition: TypeDefinition, gener // internal final class Boolean: WinRTBinding... {} // } try writer.writeExtension( - type: .named(projection.toBindingTypeName(typeDefinition))) { writer in + type: projection.toBindingType(typeDefinition)) { writer in try writeInterfaceOrDelegateBindingType( typeDefinition.bindType(genericArgs: genericArgs), - projectionName: try Projection.toBindingInstantiationTypeName(genericArgs: genericArgs), - projection: projection, - to: writer) + name: try Projection.toBindingInstantiationTypeName(genericArgs: genericArgs), + projection: projection, to: writer) } } else { @@ -256,21 +257,19 @@ fileprivate func writeClassBindingType( to writer: SwiftSourceFileWriter) throws { assert(!classDefinition.isStatic) - let projectionProtocol = try classDefinition.hasAttribute(ComposableAttribute.self) + let bindingProtocol = try classDefinition.hasAttribute(ComposableAttribute.self) ? SupportModules.WinRT.composableClassBinding : SupportModules.WinRT.runtimeClassBinding - let bindingTypeName = try projection.toBindingTypeName(classDefinition) try writer.writeClass( visibility: Projection.toVisibility(classDefinition.visibility), - name: bindingTypeName, protocolConformances: [ projectionProtocol ]) { writer throws in - let typeName = try projection.toTypeName(classDefinition) - + name: projection.toBindingTypeName(classDefinition), + protocolConformances: [ bindingProtocol ]) { writer throws in try writeReferenceTypeBindingConformance( apiType: classDefinition.bindType(), abiType: defaultInterface.asBoundType, wrapImpl: { writer, paramName in - writer.writeStatement("\(typeName)(_wrapping: consume \(paramName))") + writer.writeStatement(".init(_wrapping: consume \(paramName))") }, projection: projection, to: writer) @@ -289,8 +288,7 @@ fileprivate func writeComposableClassOuterObject( let baseOuterObjectClass: SwiftType if let base = try classDefinition.base, try base.definition.base != nil { - baseOuterObjectClass = .named(try projection.toBindingTypeName(base.definition)) - .member(outerObjectClassName) + baseOuterObjectClass = try projection.toBindingType(base.definition).member(outerObjectClassName) } else { baseOuterObjectClass = SupportModules.WinRT.composableClass_outerObject } @@ -306,8 +304,6 @@ fileprivate func writeComposableClassOuterObject( return } - let classSwiftType: SwiftType = .named(try projection.toTypeName(classDefinition)) - try writer.writeClass( visibility: .open, name: outerObjectClassName, @@ -326,7 +322,7 @@ fileprivate func writeComposableClassOuterObject( // _ifoo.initOwner(owner as! MyClass) // return _ifoo.toCOM() - writer.writeStatement("\(propertyName).initOwner(owner as! \(classSwiftType))") + writer.writeStatement("\(propertyName).initOwner(owner as! SwiftObject)") writer.writeReturnStatement(value: "\(propertyName).toCOM()") } } @@ -356,19 +352,19 @@ fileprivate func writeComposableClassOuterObject( fileprivate func writeInterfaceOrDelegateBindingType( _ type: BoundType, - projectionName: String, + name: String, projection: Projection, to writer: some SwiftDeclarationWriter) throws { precondition(type.definition is InterfaceDefinition || type.definition is DelegateDefinition) - let projectionProtocol = type.definition is InterfaceDefinition + let bindingProtocol = type.definition is InterfaceDefinition ? SupportModules.WinRT.interfaceBinding : SupportModules.WinRT.delegateBinding // Projections of generic instantiations are not owned by any specific module. // Making them internal avoids clashes between redundant definitions across modules. try writer.writeEnum( visibility: type.genericArgs.isEmpty ? Projection.toVisibility(type.definition.visibility) : .internal, - name: projectionName, - protocolConformances: [ projectionProtocol ]) { writer throws in + name: name, + protocolConformances: [ bindingProtocol ]) { writer throws in let importClassName = "Import" @@ -397,7 +393,8 @@ fileprivate func writeInterfaceOrDelegateBindingType( } try writeCOMImportClass( - type, visibility: .private, name: importClassName, projectionName: projectionName, + type, visibility: .private, name: importClassName, + bindingType: .named(name), projection: projection, to: writer) // public static var virtualTablePointer: UnsafeRawPointer { .init(withUnsafePointer(to: &virtualTable) { $0 }) } @@ -426,7 +423,7 @@ internal func writeReferenceTypeBindingConformance( projection: Projection, to writer: SwiftTypeDefinitionWriter) throws { writer.writeTypeAlias(visibility: .public, name: "SwiftObject", - target: try projection.toType(apiType.asNode).unwrapOptional()) + target: try projection.toTypeReference(apiType)) writer.writeTypeAlias(visibility: .public, name: "ABIStruct", target: try projection.toABIType(abiType)) diff --git a/Generator/Sources/SwiftWinRT/Writing/COMImportClass.swift b/Generator/Sources/SwiftWinRT/Writing/COMImportClass.swift index 25f94a1c..dbadafdb 100644 --- a/Generator/Sources/SwiftWinRT/Writing/COMImportClass.swift +++ b/Generator/Sources/SwiftWinRT/Writing/COMImportClass.swift @@ -9,17 +9,17 @@ internal func writeCOMImportClass( _ type: BoundType, visibility: SwiftVisibility, name: String, - projectionName: String, + bindingType: SwiftType, projection: Projection, to writer: SwiftTypeDefinitionWriter) throws { - let importBaseTypeName: String + let importBaseType: SwiftType let protocolConformances: [SwiftType] switch type.definition { case let interfaceDefinition as InterfaceDefinition: - importBaseTypeName = "WinRTImport" + importBaseType = SupportModules.WinRT.winRTImport(of: bindingType) protocolConformances = [.named(try projection.toProtocolName(interfaceDefinition)) ] case is DelegateDefinition: - importBaseTypeName = "COMImport" + importBaseType = SupportModules.COM.comImport(of: bindingType) protocolConformances = [] default: fatalError() } @@ -27,7 +27,7 @@ internal func writeCOMImportClass( // private final class Import: WinRTImport, IFooProtocol {} try writer.writeClass( visibility: visibility, final: true, name: name, - base: .named(importBaseTypeName, genericArgs: [ .named(projectionName) ]), + base: importBaseType, protocolConformances: protocolConformances) { writer throws in let interfaces = try type.definition.baseInterfaces.map { @@ -92,7 +92,7 @@ internal func writeGenericTypeAliases(interfaces: [BoundInterface], projection: for (index, genericArg) in interface.genericArgs.enumerated() { let genericParamName = interface.definition.genericParams[index].name if typeAliases[genericParamName] == nil { - typeAliases[genericParamName] = try projection.toType(genericArg) + typeAliases[genericParamName] = try projection.toTypeExpression(genericArg) } } } diff --git a/Generator/Sources/SwiftWinRT/Writing/ClassDefinition.swift b/Generator/Sources/SwiftWinRT/Writing/ClassDefinition.swift index 0322618f..fd1ac164 100644 --- a/Generator/Sources/SwiftWinRT/Writing/ClassDefinition.swift +++ b/Generator/Sources/SwiftWinRT/Writing/ClassDefinition.swift @@ -23,15 +23,13 @@ internal func writeClassDefinition(_ classDefinition: ClassDefinition, projectio return } - let bindingTypeName = try projection.toBindingTypeName(classDefinition) - // Both composable and activatable classes can have a base class let base: SwiftType if let baseClassDefinition = try getRuntimeClassBase(classDefinition) { - base = try projection.toType(baseClassDefinition.bindType(), nullable: false) + base = try projection.toTypeReference(baseClassDefinition.bindType()) } else { - base = classDefinition.isSealed - ? SupportModules.WinRT.winRTImport(of: .named(bindingTypeName)) + base = try classDefinition.isSealed + ? SupportModules.WinRT.winRTImport(of: projection.toBindingType(classDefinition)) : SupportModules.WinRT.composableClass } @@ -259,7 +257,7 @@ fileprivate func writeComposableInitializers( let propertyName = SecondaryInterfaces.getPropertyName(factoryInterface.bind()) let baseClassDefinition = try getRuntimeClassBase(classDefinition) - let outerObjectType: SwiftType = .named(try projection.toBindingTypeName(classDefinition)).member("OuterObject") + let outerObjectType = try projection.toBindingType(classDefinition).member("OuterObject") for method in factoryInterface.methods { // Swift requires "override" on initializers iff the same initializer is defined in the direct base class @@ -325,9 +323,9 @@ fileprivate func writeDefaultActivatableInitializer( override: isOverriding, throws: true) { writer in let propertyName = SecondaryInterfaces.getPropertyName(interfaceName: "IActivationFactory") - let projectionClassName = try projection.toBindingTypeName(classDefinition) + let bindingType = try projection.toBindingType(classDefinition) writer.writeStatement("let _instance = \(SupportModules.COM.comReference)(transferringRef: try Self.\(propertyName)" - + ".activateInstance(binding: \(projectionClassName).self))") + + ".activateInstance(binding: \(bindingType).self))") if try hasComposableBase(classDefinition) { writer.writeStatement("super.init(_wrapping: _instance.cast()) // Transitively casts down to IInspectable") } diff --git a/Generator/Sources/SwiftWinRT/Writing/EnumDefinition.swift b/Generator/Sources/SwiftWinRT/Writing/EnumDefinition.swift index fbe305d8..cc9fe6c3 100644 --- a/Generator/Sources/SwiftWinRT/Writing/EnumDefinition.swift +++ b/Generator/Sources/SwiftWinRT/Writing/EnumDefinition.swift @@ -30,7 +30,7 @@ fileprivate func writeOpenEnumDefinition(_ enumDefinition: EnumDefinition, proje name: structName, protocolConformances: [.named("CStyleEnum") ]) { writer throws in - let rawValueType = try projection.toType(enumDefinition.underlyingType.bindNode()) + let rawValueType = try projection.toTypeExpression(enumDefinition.underlyingType.bindNode()) writer.writeStoredProperty(visibility: .public, declarator: .var, name: "rawValue", type: rawValueType) writer.writeInit(visibility: .public, params: [ .init(name: "rawValue", type: rawValueType, defaultValue: "0") ]) { @@ -90,7 +90,7 @@ fileprivate func writeClosedEnumDefinition(_ enumDefinition: EnumDefinition, pro documentation: projection.getDocumentationComment(enumDefinition), visibility: Projection.toVisibility(enumDefinition.visibility), name: try projection.toTypeName(enumDefinition), - rawValueType: try projection.toType(enumDefinition.underlyingType.bindNode()), + rawValueType: try projection.toTypeExpression(enumDefinition.underlyingType.bindNode()), protocolConformances: [.named("ClosedEnum") ]) { writer throws in for field in enumDefinition.fields.filter({ $0.visibility == .public && $0.isStatic }) { try writer.writeEnumCase( diff --git a/Generator/Sources/SwiftWinRT/Writing/InterfaceDefinition.swift b/Generator/Sources/SwiftWinRT/Writing/InterfaceDefinition.swift index dd7b40ad..867734e7 100644 --- a/Generator/Sources/SwiftWinRT/Writing/InterfaceDefinition.swift +++ b/Generator/Sources/SwiftWinRT/Writing/InterfaceDefinition.swift @@ -53,7 +53,7 @@ fileprivate func writeProtocol(_ interfaceDefinition: InterfaceDefinition, proje // For example, IVector : IIterable, so we don't generate "where T == T" if case .genericParam(let genericParamArg) = genericArg, genericParamArg.name == genericParam.name { continue } - whereGenericConstraints[genericParam.name] = try projection.toType(genericArg) + whereGenericConstraints[genericParam.name] = try projection.toTypeExpression(genericArg) } } diff --git a/Generator/Sources/SwiftWinRT/Writing/NamespaceModules.swift b/Generator/Sources/SwiftWinRT/Writing/NamespaceModules.swift index 1977af78..9f5c3122 100644 --- a/Generator/Sources/SwiftWinRT/Writing/NamespaceModules.swift +++ b/Generator/Sources/SwiftWinRT/Writing/NamespaceModules.swift @@ -90,6 +90,6 @@ fileprivate func writeShortNameTypeAlias( try writer.writeTypeAlias( visibility: Projection.toVisibility(typeDefinition.visibility), name: projection.toBindingTypeName(typeDefinition, namespaced: false), - target: .named(projection.toBindingTypeName(typeDefinition))) + target: projection.toBindingType(typeDefinition)) } } \ No newline at end of file diff --git a/Generator/Sources/SwiftWinRT/Writing/StructDefinition.swift b/Generator/Sources/SwiftWinRT/Writing/StructDefinition.swift index 1c2d4ff9..e395139f 100644 --- a/Generator/Sources/SwiftWinRT/Writing/StructDefinition.swift +++ b/Generator/Sources/SwiftWinRT/Writing/StructDefinition.swift @@ -34,7 +34,7 @@ fileprivate func writeStructFields(_ structDefinition: StructDefinition, project try writer.writeStoredProperty( documentation: projection.getDocumentationComment(field), visibility: .public, declarator: .var, name: Projection.toMemberName(field), - type: projection.toType(field.type)) + type: projection.toTypeExpression(field.type)) } } @@ -72,7 +72,7 @@ fileprivate func writeDefaultInitializer(_ structDefinition: StructDefinition, p fileprivate func writeFieldwiseInitializer(_ structDefinition: StructDefinition, projection: Projection, to writer: SwiftTypeDefinitionWriter) throws { let params = try structDefinition.fields .filter { $0.visibility == .public && $0.isInstance } - .map { SwiftParam(name: Projection.toMemberName($0), type: try projection.toType($0.type)) } + .map { SwiftParam(name: Projection.toMemberName($0), type: try projection.toTypeExpression($0.type)) } guard !params.isEmpty else { return } writer.writeInit(visibility: .public, params: params) { diff --git a/Generator/Sources/SwiftWinRT/Writing/TypeDefinition.swift b/Generator/Sources/SwiftWinRT/Writing/TypeDefinition.swift index f8834aa5..a500c1dd 100644 --- a/Generator/Sources/SwiftWinRT/Writing/TypeDefinition.swift +++ b/Generator/Sources/SwiftWinRT/Writing/TypeDefinition.swift @@ -31,7 +31,7 @@ fileprivate func writeDelegateDefinition(_ delegateDefinition: DelegateDefinitio name: try projection.toTypeName(delegateDefinition), typeParams: delegateDefinition.genericParams.map { $0.name }, target: .function( - params: delegateDefinition.invokeMethod.params.map { try projection.toType($0.type) }, + params: delegateDefinition.invokeMethod.params.map { try projection.toTypeExpression($0.type) }, throws: true, returnType: delegateDefinition.invokeMethod.hasReturnValue ? projection.toReturnType(delegateDefinition.invokeMethod.returnType) From e399afd9f6164dd65a9ca4c4b932b5915e3b3ab9 Mon Sep 17 00:00:00 2001 From: Tristan Labelle Date: Wed, 25 Dec 2024 08:25:22 -0500 Subject: [PATCH 2/5] Fix regression in System.Object type expressions --- Generator/Sources/ProjectionModel/Projection+types.swift | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/Generator/Sources/ProjectionModel/Projection+types.swift b/Generator/Sources/ProjectionModel/Projection+types.swift index acdd3f0f..9fe303ae 100644 --- a/Generator/Sources/ProjectionModel/Projection+types.swift +++ b/Generator/Sources/ProjectionModel/Projection+types.swift @@ -18,6 +18,11 @@ extension Projection { } public func toTypeReference(_ boundType: BoundType) throws -> SwiftType { + // Workaround for getSpecialTypeBinding returning Optional for System.Object. + if boundType.definition.namespace == "System", boundType.definition.name == "Object" { + return SupportModules.WinRT.iinspectable + } + if let specialTypeBinding = try getSpecialTypeBinding(boundType) { return specialTypeBinding.swiftType } From 160e2524049e5a1110329cfad2cf2f83f68f9da6 Mon Sep 17 00:00:00 2001 From: Tristan Labelle Date: Wed, 25 Dec 2024 09:00:22 -0500 Subject: [PATCH 3/5] Fix type expressions for special types --- .../ProjectionModel/Projection+types.swift | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/Generator/Sources/ProjectionModel/Projection+types.swift b/Generator/Sources/ProjectionModel/Projection+types.swift index 9fe303ae..142004d5 100644 --- a/Generator/Sources/ProjectionModel/Projection+types.swift +++ b/Generator/Sources/ProjectionModel/Projection+types.swift @@ -6,7 +6,13 @@ extension Projection { public func toTypeExpression(_ type: TypeNode, outerNullable: Bool = true) throws -> SwiftType { switch type { case let .bound(type): - let boundSwiftType = try toTypeReference(type) + if let specialTypeBinding = try getSpecialTypeBinding(type) { + return specialTypeBinding.swiftType + } + + let boundSwiftType = try SwiftType.named( + toTypeName(boundType.definition), + genericArgs: boundType.genericArgs.map { try toTypeExpression($0) }) return type.definition.isReferenceType && outerNullable ? boundSwiftType.optional() : boundSwiftType case let .genericParam(param): return .named(param.name) @@ -18,13 +24,9 @@ extension Projection { } public func toTypeReference(_ boundType: BoundType) throws -> SwiftType { - // Workaround for getSpecialTypeBinding returning Optional for System.Object. - if boundType.definition.namespace == "System", boundType.definition.name == "Object" { - return SupportModules.WinRT.iinspectable - } - + // getSpecialTypeBinding returns a type expression, which includes the optional wrapping. if let specialTypeBinding = try getSpecialTypeBinding(boundType) { - return specialTypeBinding.swiftType + return specialTypeBinding.swiftType.unwrapOptional() } return .named( From 6ad24413af69cf80e1a12893c755e70c63298b24 Mon Sep 17 00:00:00 2001 From: Tristan Labelle Date: Wed, 25 Dec 2024 09:05:13 -0500 Subject: [PATCH 4/5] Fix variable reference --- Generator/Sources/ProjectionModel/Projection+types.swift | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Generator/Sources/ProjectionModel/Projection+types.swift b/Generator/Sources/ProjectionModel/Projection+types.swift index 142004d5..5a5ef924 100644 --- a/Generator/Sources/ProjectionModel/Projection+types.swift +++ b/Generator/Sources/ProjectionModel/Projection+types.swift @@ -5,15 +5,15 @@ import CodeWriters extension Projection { public func toTypeExpression(_ type: TypeNode, outerNullable: Bool = true) throws -> SwiftType { switch type { - case let .bound(type): - if let specialTypeBinding = try getSpecialTypeBinding(type) { + case let .bound(boundType): + if let specialTypeBinding = try getSpecialTypeBinding(boundType) { return specialTypeBinding.swiftType } - let boundSwiftType = try SwiftType.named( + let swiftType = try SwiftType.named( toTypeName(boundType.definition), genericArgs: boundType.genericArgs.map { try toTypeExpression($0) }) - return type.definition.isReferenceType && outerNullable ? boundSwiftType.optional() : boundSwiftType + return boundType.definition.isReferenceType && outerNullable ? swiftType.optional() : swiftType case let .genericParam(param): return .named(param.name) case let .array(of: element): From a1f561de3c1a62e3ed55e8b8df1d9e1b48f4a63d Mon Sep 17 00:00:00 2001 From: Tristan Labelle Date: Wed, 25 Dec 2024 10:01:58 -0500 Subject: [PATCH 5/5] Workaround for IInspectable --- Generator/Sources/ProjectionModel/Projection+types.swift | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Generator/Sources/ProjectionModel/Projection+types.swift b/Generator/Sources/ProjectionModel/Projection+types.swift index 5a5ef924..90630837 100644 --- a/Generator/Sources/ProjectionModel/Projection+types.swift +++ b/Generator/Sources/ProjectionModel/Projection+types.swift @@ -7,6 +7,9 @@ extension Projection { switch type { case let .bound(boundType): if let specialTypeBinding = try getSpecialTypeBinding(boundType) { + if boundType.definition.namespace == "System", boundType.definition.name == "Object", !outerNullable { + return specialTypeBinding.swiftType.unwrapOptional() + } return specialTypeBinding.swiftType }