Skip to content

Commit

Permalink
Support getInterfaceID for IActivationFactory (#62)
Browse files Browse the repository at this point in the history
  • Loading branch information
tristanlabelle authored Dec 9, 2024
1 parent 2079017 commit e995795
Show file tree
Hide file tree
Showing 3 changed files with 49 additions and 4 deletions.
19 changes: 16 additions & 3 deletions Sources/WindowsMetadata/InterfaceID.swift
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,27 @@ public func getInterfaceID(_ typeDefinition: TypeDefinition, genericArgs: [TypeN
guard typeDefinition is InterfaceDefinition || typeDefinition is DelegateDefinition else {
throw UnexpectedTypeError(typeDefinition.fullName, context: #function, reason: "Only interfaces and delegates have interface IDs")
}
if let genericArgs = genericArgs, genericArgs.count > 0 {

/// Generic interfaces/delegates have a GUID computed based on the generic arguments.
if let genericArgs, genericArgs.count > 0 {
let signature = try WinRTTypeSignature(typeDefinition.bindType(genericArgs: genericArgs))
return signature.parameterizedID
}
else {
guard let attribute = try typeDefinition.findAttribute(GuidAttribute.self) else { throw WinMDError.missingAttribute }
/// Non-generic interfaces/delegates defined in winmd files specify their GUID via Windows.Foundation.Metadata.GuidAttribute.
else if let attribute = try typeDefinition.findAttribute(WindowsMetadata.GuidAttribute.self) {
return attribute.value
}
/// We consider System.Runtime.InteropServices.WindowsRuntime.IActivationFactory to be a WinRT interface,
/// but since it's defined in mscorlib, it uses System.Runtime.InteropServices.GuidAttribute instead.
else if typeDefinition.namespace == "System.Runtime.InteropServices.WindowsRuntime",
typeDefinition.name == "IActivationFactory",
let attribute = try typeDefinition.findAttribute(DotNetMetadata.GuidAttribute.self) {
guard let guid = UUID(uuidString: attribute.value) else { throw InvalidMetadataError.attributeArguments }
return guid
}
else {
throw WinMDError.missingAttribute
}
}

public func getInterfaceID(_ type: BoundType) throws -> UUID {
Expand Down
29 changes: 29 additions & 0 deletions Tests/WindowsMetadata/InterfaceIDTests.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import DotNetMetadata
import XCTest
import WindowsMetadata

final class InterfaceIDTests: XCTestCase {
internal static var context: WinMDLoadContext!
internal static var mscorlib: Assembly!

override func setUpWithError() throws {
if Self.mscorlib == nil {
Self.context = WinMDLoadContext()

// Expect mscorlib.winmd side-by-side with the test executable
let mscorlibURL = Bundle.main.bundleURL.appendingPathComponent("mscorlib.winmd", isDirectory: false)
Self.mscorlib = try Self.context.load(url: mscorlibURL)
}
}

/// Test that we can get the interface ID for `IActivationFactory`,
/// which lives in the core library rather than a Windows Metadata file,
/// so uses System's GuidAttribute, not Windows.Foundation's.
public func testCoreLibraryIActivationFactory() throws {
let typeDefinition = try XCTUnwrap(Self.mscorlib.resolveTypeDefinition(
namespace: "System.Runtime.InteropServices.WindowsRuntime", name: "IActivationFactory"))
XCTAssertEqual(
try getInterfaceID(typeDefinition),
UUID(uuidString: "00000035-0000-0000-c000-000000000046"))
}
}
5 changes: 4 additions & 1 deletion WindowsMetadataCoreLibrary/mscorlib.il
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,10 @@
// Attributes
.class public System.AttributeUsageAttribute extends System.Attribute {}
.class public System.FlagsAttribute extends System.Attribute {}
.class public System.Runtime.InteropServices.GuidAttribute extends System.Attribute {}

.class public System.Runtime.InteropServices.GuidAttribute extends System.Attribute {
.method public hidebysig specialname rtspecialname instance void .ctor(string guid) runtime managed internalcall {}
}

// IActivationFactory interface
.class interface public abstract import windowsruntime System.Runtime.InteropServices.WindowsRuntime.IActivationFactory
Expand Down

0 comments on commit e995795

Please sign in to comment.