Skip to content

Commit

Permalink
Worked around compiler bugs and fixed extension property writing.
Browse files Browse the repository at this point in the history
  • Loading branch information
tristanlabelle committed Mar 21, 2024
1 parent 423c934 commit f682fcd
Show file tree
Hide file tree
Showing 8 changed files with 28 additions and 12 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -46,10 +46,9 @@ fileprivate func writeInterfacePropertyImplementation(
_ property: Property, typeGenericArgs: [TypeNode], classDefinition: ClassDefinition?,
documentation: Bool, overridable: Bool, static: Bool, thisPointer: ThisPointer,
projection: SwiftProjection, to writer: SwiftTypeDefinitionWriter) throws {
if `static` {
// Instance properties come from interfaces for which we generate extensions
// with non-throwing properties. Static properties are implemented directly.
assert(typeGenericArgs.isEmpty) // True for classes
if try property.definingType.hasAttribute(ExclusiveToAttribute.self) {
// The property is exclusive to this class so it doesn't come
// from an interface that would an extension property.
// public static var myProperty: MyPropertyType { ... }
try writeNonthrowingPropertyImplementation(
property: property, static: `static`, projection: projection, to: writer)
Expand Down
12 changes: 10 additions & 2 deletions Generator/Sources/SwiftWinRT/Writing/SecondaryInterfaces.swift
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,16 @@ internal enum SecondaryInterfaces {
try writer.writeBracedBlock("try \(storedPropertyName).\(SupportModule.comLazyReference_getInterop)") { writer in
if let staticOf {
let activatableId = try WinRTTypeName.from(type: staticOf.bindType()).description
writer.writeStatement("try WindowsRuntime.getActivationFactory("
+ "activatableId: \"\(activatableId)\", id: \(abiStructType).iid)")
if interfaceName == "IActivationFactory" {
// Workaround a compiler bug where the compiler doesn't see the SWRT_IActivationFactory extension.
writer.writeStatement("try WindowsRuntime.getActivationFactory(\n"
+ "activatableId: \"\(activatableId)\",\n"
+ "id: WindowsRuntime.IActivationFactoryProjection.interfaceID)")
} else {
writer.writeStatement("try WindowsRuntime.getActivationFactory(\n"
+ "activatableId: \"\(activatableId)\",\n"
+ "id: \(abiStructType).iid)")
}
}
else {
let qiMethodName = composable ? "_queryInnerInterface" : "_queryInterface"
Expand Down
6 changes: 3 additions & 3 deletions InteropTests/Tests/PropertyTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -32,12 +32,12 @@ class PropertyTests: WinRTTestCase {
}

Int32Global.getSet = 0
assertGet(expected: 0)
try assertGet(expected: 0)

Int32Global.getSet = 1
assertGet(expected: 1)
try assertGet(expected: 1)

try Int32Global._getSet(2)
assertGet(expected: 2)
try assertGet(expected: 2)
}
}
5 changes: 5 additions & 0 deletions InteropTests/WinRTComponent/Int32Wrapper.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,13 @@ namespace winrt::WinRTComponent::implementation
static int32_t _value;
};
}

namespace winrt::WinRTComponent::factory_implementation
{
struct Int32Wrapper : Int32WrapperT<Int32Wrapper, implementation::Int32Wrapper>
{
};

struct Int32Global : Int32GlobalT<Int32Global, implementation::Int32Global>
{
};
Expand Down
1 change: 1 addition & 0 deletions InteropTests/WinRTComponent/Int32Wrapper.idl
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ namespace WinRTComponent
{
runtimeclass Int32Wrapper
{
Int32Wrapper();
Int32 GetSet;
Int32 GetOnly { get; };
};
Expand Down
3 changes: 2 additions & 1 deletion Support/Sources/COM/COMInterop.swift
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@ public protocol COMIUnknownStruct {

/// Wraps a COM interface pointer and exposes projected versions of its methods.
/// This struct is extended with methods for each COM interface it wraps.
public struct COMInterop<Interface> where Interface: COMIUnknownStruct {
// Should require COMIUnknownStruct but we run into compiler bugs.
public struct COMInterop<Interface> /* where Interface: COMIUnknownStruct */ {
public let this: UnsafeMutablePointer<Interface>

public init(_ pointer: UnsafeMutablePointer<Interface>) {
Expand Down
3 changes: 2 additions & 1 deletion Support/Sources/COM/COMLazyReference.swift
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
/// Lazily initialized reference to a COM object.
/// Essentially an Optional<COMReference<Interface>> without language support.
public struct COMLazyReference<Interface: COMIUnknownStruct>: ~Copyable {
// Should require COMIUnknownStruct but we run into compiler bugs.
public struct COMLazyReference<Interface>: ~Copyable /* where Interface: COMIUnknownStruct */ {
private var pointer: UnsafeMutablePointer<Interface>?

public init() {
Expand Down
3 changes: 2 additions & 1 deletion Support/Sources/COM/COMReference.swift
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import WindowsRuntime_ABI

/// Holds a strong reference to a COM object, like a C++ smart pointer.
public struct COMReference<Interface: COMIUnknownStruct>: ~Copyable {
// Should require COMIUnknownStruct but we run into compiler bugs.
public struct COMReference<Interface>: ~Copyable /* where Interface: COMIUnknownStruct */ {
public var pointer: UnsafeMutablePointer<Interface>

public init(transferringRef pointer: UnsafeMutablePointer<Interface>) {
Expand Down

0 comments on commit f682fcd

Please sign in to comment.