From b072544df3dbaaacdbc0c19e91896ee45b74bd07 Mon Sep 17 00:00:00 2001 From: Tristan Labelle Date: Mon, 19 Feb 2024 07:47:12 -0500 Subject: [PATCH] Make findAttribute/getAttributes always return a struct for the attribute. --- Sources/DotNetMetadata/Attributable.swift | 6 +++--- Sources/DotNetMetadata/AttributeType.swift | 6 ++---- .../Attributes/ComImportAttribute.swift | 4 ++-- .../Attributes/ComVisibleAttribute.swift | 12 +++++++++--- .../DotNetMetadata/Attributes/FlagsAttribute.swift | 4 ++-- .../DotNetMetadata/Attributes/GuidAttribute.swift | 12 +++++++++--- .../{ => Attributes}/ActivatableAttribute.swift | 0 .../{ => Attributes}/AllowMultipleAttribute.swift | 4 ++-- .../{ => Attributes}/ApiContractAttribute.swift | 4 ++-- .../{ => Attributes}/ComposableAttribute.swift | 0 .../ContractVersionAttribute.swift | 0 .../{ => Attributes}/DefaultAttribute.swift | 4 ++-- .../DefaultOverloadAttribute.swift | 4 ++-- .../{ => Attributes}/DeprecatedAttribute.swift | 0 .../DualApiPartitionAttribute.swift | 14 ++++++++++---- .../{ => Attributes}/ExclusiveToAttribute.swift | 12 +++++++++--- .../{ => Attributes}/ExperimentalAttribute.swift | 4 ++-- .../{ => Attributes}/GuidAttribute.swift | 14 ++++++++++---- .../{ => Attributes}/InternalAttribute.swift | 4 ++-- .../{ => Attributes}/LengthIsAttribute.swift | 12 +++++++++--- .../MarshalingBehaviorAttribute.swift | 12 +++++++++--- .../{ => Attributes}/NoExceptionAttribute.swift | 4 ++-- .../{ => Attributes}/OverloadAttribute.swift | 12 +++++++++--- .../{ => Attributes}/ProtectedAttribute.swift | 4 ++-- .../{ => Attributes}/StaticAttribute.swift | 0 .../{ => Attributes}/ThreadingAttribute.swift | 12 +++++++++--- .../{ => Attributes}/VariantAttribute.swift | 4 ++-- Sources/WindowsMetadata/InterfaceID.swift | 4 ++-- .../WinRTTypeSignature+fromBoundType.swift | 6 +++--- 29 files changed, 115 insertions(+), 63 deletions(-) rename Sources/WindowsMetadata/{ => Attributes}/ActivatableAttribute.swift (100%) rename Sources/WindowsMetadata/{ => Attributes}/AllowMultipleAttribute.swift (86%) rename Sources/WindowsMetadata/{ => Attributes}/ApiContractAttribute.swift (86%) rename Sources/WindowsMetadata/{ => Attributes}/ComposableAttribute.swift (100%) rename Sources/WindowsMetadata/{ => Attributes}/ContractVersionAttribute.swift (100%) rename Sources/WindowsMetadata/{ => Attributes}/DefaultAttribute.swift (91%) rename Sources/WindowsMetadata/{ => Attributes}/DefaultOverloadAttribute.swift (87%) rename Sources/WindowsMetadata/{ => Attributes}/DeprecatedAttribute.swift (100%) rename Sources/WindowsMetadata/{ => Attributes}/DualApiPartitionAttribute.swift (71%) rename Sources/WindowsMetadata/{ => Attributes}/ExclusiveToAttribute.swift (73%) rename Sources/WindowsMetadata/{ => Attributes}/ExperimentalAttribute.swift (88%) rename Sources/WindowsMetadata/{ => Attributes}/GuidAttribute.swift (90%) rename Sources/WindowsMetadata/{ => Attributes}/InternalAttribute.swift (88%) rename Sources/WindowsMetadata/{ => Attributes}/LengthIsAttribute.swift (77%) rename Sources/WindowsMetadata/{ => Attributes}/MarshalingBehaviorAttribute.swift (83%) rename Sources/WindowsMetadata/{ => Attributes}/NoExceptionAttribute.swift (86%) rename Sources/WindowsMetadata/{ => Attributes}/OverloadAttribute.swift (77%) rename Sources/WindowsMetadata/{ => Attributes}/ProtectedAttribute.swift (88%) rename Sources/WindowsMetadata/{ => Attributes}/StaticAttribute.swift (100%) rename Sources/WindowsMetadata/{ => Attributes}/ThreadingAttribute.swift (82%) rename Sources/WindowsMetadata/{ => Attributes}/VariantAttribute.swift (89%) diff --git a/Sources/DotNetMetadata/Attributable.swift b/Sources/DotNetMetadata/Attributable.swift index 2a71704..ac705b9 100644 --- a/Sources/DotNetMetadata/Attributable.swift +++ b/Sources/DotNetMetadata/Attributable.swift @@ -16,13 +16,13 @@ extension Attributable { try attributes.contains { try $0.hasType(T.self) } } - public func findAttribute(_ type: T.Type) throws -> T.Value? { + public func findAttribute(_ type: T.Type) throws -> T? { guard let attribute = try attributes.first(where: { try $0.hasType(T.self) }) else { return nil } return try attribute.decode(as: T.self) } - public func getAttributes(_ type: T.Type) throws -> [T.Value] { - var result = [T.Value]() + public func getAttributes(_ type: T.Type) throws -> [T] { + var result = [T]() for attribute in attributes { guard try attribute.hasType(T.self) else { continue } result.append(try attribute.decode(as: T.self)) diff --git a/Sources/DotNetMetadata/AttributeType.swift b/Sources/DotNetMetadata/AttributeType.swift index 539c093..7621e7e 100644 --- a/Sources/DotNetMetadata/AttributeType.swift +++ b/Sources/DotNetMetadata/AttributeType.swift @@ -1,13 +1,11 @@ public protocol AttributeType { - associatedtype Value = Self - static var namespace: String? { get } static var name: String { get } static var validOn: AttributeTargets { get } static var allowMultiple: Bool { get } static var inherited: Bool { get } - static func decode(_ attribute: Attribute) throws -> Value + static func decode(_ attribute: Attribute) throws -> Self } extension Attribute { @@ -16,7 +14,7 @@ extension Attribute { return actualType.namespace == type.namespace && actualType.name == type.name } - public func decode(as type: T.Type) throws -> T.Value { + public func decode(as type: T.Type) throws -> T { try type.decode(self) } } \ No newline at end of file diff --git a/Sources/DotNetMetadata/Attributes/ComImportAttribute.swift b/Sources/DotNetMetadata/Attributes/ComImportAttribute.swift index d1c840e..45f4495 100644 --- a/Sources/DotNetMetadata/Attributes/ComImportAttribute.swift +++ b/Sources/DotNetMetadata/Attributes/ComImportAttribute.swift @@ -1,9 +1,9 @@ -public enum ComImportAttribute: AttributeType { +public struct ComImportAttribute: AttributeType { public static var namespace: String? { "System.Runtime.InteropServices" } public static var name: String { "ComImportAttribute" } public static var validOn: AttributeTargets { .class | .interface } public static var allowMultiple: Bool { false } public static var inherited: Bool { false } - public static func decode(_ attribute: Attribute) throws -> Void { () } + public static func decode(_ attribute: Attribute) throws -> Self { .init() } } diff --git a/Sources/DotNetMetadata/Attributes/ComVisibleAttribute.swift b/Sources/DotNetMetadata/Attributes/ComVisibleAttribute.swift index 6218870..794cf89 100644 --- a/Sources/DotNetMetadata/Attributes/ComVisibleAttribute.swift +++ b/Sources/DotNetMetadata/Attributes/ComVisibleAttribute.swift @@ -1,16 +1,22 @@ -public enum ComVisibleAttribute: AttributeType { +public struct ComVisibleAttribute: AttributeType { + public var value: Bool + + public init(_ value: Bool) { + self.value = value + } + public static var namespace: String? { "System.Runtime.InteropServices" } public static var name: String { "ComVisibleAttribute" } public static var validOn: AttributeTargets { .assembly | .allTypes | .method | .property | .field } public static var allowMultiple: Bool { false } public static var inherited: Bool { false } - public static func decode(_ attribute: Attribute) throws -> Bool { + public static func decode(_ attribute: Attribute) throws -> Self { let arguments = try attribute.arguments guard arguments.count == 1, case .constant(let constant) = arguments[0], case .boolean(let value) = constant else { throw InvalidMetadataError.attributeArguments } - return value + return .init(value) } } diff --git a/Sources/DotNetMetadata/Attributes/FlagsAttribute.swift b/Sources/DotNetMetadata/Attributes/FlagsAttribute.swift index 35ecb36..e3dc85d 100644 --- a/Sources/DotNetMetadata/Attributes/FlagsAttribute.swift +++ b/Sources/DotNetMetadata/Attributes/FlagsAttribute.swift @@ -1,10 +1,10 @@ /// Indicates that an enumeration can be treated as a bit field; that is, a set of flags. -public enum FlagsAttribute: AttributeType { +public struct FlagsAttribute: AttributeType { public static var namespace: String? { "System" } public static var name: String { "FlagsAttribute" } public static var validOn: AttributeTargets { .enum } public static var allowMultiple: Bool { false } public static var inherited: Bool { false } - public static func decode(_ attribute: Attribute) throws -> Void {} + public static func decode(_ attribute: Attribute) throws -> Self { .init() } } diff --git a/Sources/DotNetMetadata/Attributes/GuidAttribute.swift b/Sources/DotNetMetadata/Attributes/GuidAttribute.swift index 9d7d8d1..26d65ea 100644 --- a/Sources/DotNetMetadata/Attributes/GuidAttribute.swift +++ b/Sources/DotNetMetadata/Attributes/GuidAttribute.swift @@ -1,15 +1,21 @@ -public enum GuidAttribute: AttributeType { +public struct GuidAttribute: AttributeType { + public var value: String + + public init(_ value: String) { + self.value = value + } + public static var namespace: String? { "System.Runtime.InteropServices" } public static var name: String { "GuidAttribute" } public static var validOn: AttributeTargets { .assembly | .allTypes } public static var allowMultiple: Bool { false } public static var inherited: Bool { true } - public static func decode(_ attribute: Attribute) throws -> String { + public static func decode(_ attribute: Attribute) throws -> GuidAttribute { let arguments = try attribute.arguments guard arguments.count == 1, case .constant(let constant) = arguments[0], case .string(let value) = constant else { throw InvalidMetadataError.attributeArguments } - return value + return .init(value) } } diff --git a/Sources/WindowsMetadata/ActivatableAttribute.swift b/Sources/WindowsMetadata/Attributes/ActivatableAttribute.swift similarity index 100% rename from Sources/WindowsMetadata/ActivatableAttribute.swift rename to Sources/WindowsMetadata/Attributes/ActivatableAttribute.swift diff --git a/Sources/WindowsMetadata/AllowMultipleAttribute.swift b/Sources/WindowsMetadata/Attributes/AllowMultipleAttribute.swift similarity index 86% rename from Sources/WindowsMetadata/AllowMultipleAttribute.swift rename to Sources/WindowsMetadata/Attributes/AllowMultipleAttribute.swift index 199c113..ffb0eb6 100644 --- a/Sources/WindowsMetadata/AllowMultipleAttribute.swift +++ b/Sources/WindowsMetadata/Attributes/AllowMultipleAttribute.swift @@ -1,12 +1,12 @@ import DotNetMetadata /// Indicates that multiple instances of a custom attribute can be applied to a target. -public enum AllowMultipleAttribute: AttributeType { +public struct AllowMultipleAttribute: AttributeType { public static var namespace: String? { "Windows.Foundation.Metadata" } public static var name: String { "AllowMultipleAttribute" } public static var validOn: AttributeTargets { .class } public static var allowMultiple: Bool { false } public static var inherited: Bool { true } - public static func decode(_ attribute: Attribute) throws -> Void {} + public static func decode(_ attribute: Attribute) throws -> Self { .init() } } \ No newline at end of file diff --git a/Sources/WindowsMetadata/ApiContractAttribute.swift b/Sources/WindowsMetadata/Attributes/ApiContractAttribute.swift similarity index 86% rename from Sources/WindowsMetadata/ApiContractAttribute.swift rename to Sources/WindowsMetadata/Attributes/ApiContractAttribute.swift index 9b5695f..bbdd64d 100644 --- a/Sources/WindowsMetadata/ApiContractAttribute.swift +++ b/Sources/WindowsMetadata/Attributes/ApiContractAttribute.swift @@ -1,12 +1,12 @@ import DotNetMetadata /// Specifies that the type represents an API contract. -public enum ApiContractAttribute: AttributeType { +public struct ApiContractAttribute: AttributeType { public static var namespace: String? { "Windows.Foundation.Metadata" } public static var name: String { "ApiContractAttribute" } public static var validOn: AttributeTargets { .enum } public static var allowMultiple: Bool { false } public static var inherited: Bool { true } - public static func decode(_ attribute: Attribute) throws -> Void {} + public static func decode(_ attribute: Attribute) throws -> Self { .init() } } \ No newline at end of file diff --git a/Sources/WindowsMetadata/ComposableAttribute.swift b/Sources/WindowsMetadata/Attributes/ComposableAttribute.swift similarity index 100% rename from Sources/WindowsMetadata/ComposableAttribute.swift rename to Sources/WindowsMetadata/Attributes/ComposableAttribute.swift diff --git a/Sources/WindowsMetadata/ContractVersionAttribute.swift b/Sources/WindowsMetadata/Attributes/ContractVersionAttribute.swift similarity index 100% rename from Sources/WindowsMetadata/ContractVersionAttribute.swift rename to Sources/WindowsMetadata/Attributes/ContractVersionAttribute.swift diff --git a/Sources/WindowsMetadata/DefaultAttribute.swift b/Sources/WindowsMetadata/Attributes/DefaultAttribute.swift similarity index 91% rename from Sources/WindowsMetadata/DefaultAttribute.swift rename to Sources/WindowsMetadata/Attributes/DefaultAttribute.swift index 3aad919..1c809f9 100644 --- a/Sources/WindowsMetadata/DefaultAttribute.swift +++ b/Sources/WindowsMetadata/Attributes/DefaultAttribute.swift @@ -1,14 +1,14 @@ import DotNetMetadata /// Indicates the default interface for a runtime class. -public enum DefaultAttribute: AttributeType { +public struct DefaultAttribute: AttributeType { public static var namespace: String? { "Windows.Foundation.Metadata" } public static var name: String { "DefaultAttribute" } public static var validOn: AttributeTargets { .none } // No attribute target for interface implementations public static var allowMultiple: Bool { false } public static var inherited: Bool { true } - public static func decode(_ attribute: Attribute) throws -> Void {} + public static func decode(_ attribute: Attribute) throws -> Self { .init() } public static func getDefaultInterface(_ class: ClassDefinition) throws -> BoundInterface? { try `class`.baseInterfaces.first { try $0.hasAttribute(DefaultAttribute.self) }?.interface diff --git a/Sources/WindowsMetadata/DefaultOverloadAttribute.swift b/Sources/WindowsMetadata/Attributes/DefaultOverloadAttribute.swift similarity index 87% rename from Sources/WindowsMetadata/DefaultOverloadAttribute.swift rename to Sources/WindowsMetadata/Attributes/DefaultOverloadAttribute.swift index 9247609..5115d58 100644 --- a/Sources/WindowsMetadata/DefaultOverloadAttribute.swift +++ b/Sources/WindowsMetadata/Attributes/DefaultOverloadAttribute.swift @@ -2,12 +2,12 @@ import DotNetMetadata /// Indicates that a method is the default overload method. /// This attribute must be used with OverloadAttribute. -public enum DefaultOverloadAttribute: AttributeType { +public struct DefaultOverloadAttribute: AttributeType { public static var namespace: String? { "Windows.Foundation.Metadata" } public static var name: String { "DefaultOverloadAttribute" } public static var validOn: AttributeTargets { .method } public static var allowMultiple: Bool { false } public static var inherited: Bool { true } - public static func decode(_ attribute: Attribute) throws -> Void {} + public static func decode(_ attribute: Attribute) throws -> Self { .init() } } \ No newline at end of file diff --git a/Sources/WindowsMetadata/DeprecatedAttribute.swift b/Sources/WindowsMetadata/Attributes/DeprecatedAttribute.swift similarity index 100% rename from Sources/WindowsMetadata/DeprecatedAttribute.swift rename to Sources/WindowsMetadata/Attributes/DeprecatedAttribute.swift diff --git a/Sources/WindowsMetadata/DualApiPartitionAttribute.swift b/Sources/WindowsMetadata/Attributes/DualApiPartitionAttribute.swift similarity index 71% rename from Sources/WindowsMetadata/DualApiPartitionAttribute.swift rename to Sources/WindowsMetadata/Attributes/DualApiPartitionAttribute.swift index f8adf1a..7e0baec 100644 --- a/Sources/WindowsMetadata/DualApiPartitionAttribute.swift +++ b/Sources/WindowsMetadata/Attributes/DualApiPartitionAttribute.swift @@ -1,20 +1,26 @@ import DotNetMetadata -public enum DualApiPartitionAttribute: AttributeType { +public struct DualApiPartitionAttribute: AttributeType { + public var version: Version + + public init(_ version: Version) { + self.version = version + } + public static var namespace: String? { "Windows.Foundation.Metadata" } public static var name: String { "DualApiPartitionAttribute" } public static var validOn: AttributeTargets { .class } public static var allowMultiple: Bool { false } public static var inherited: Bool { true } - public static func decode(_ attribute: Attribute) throws -> Version { + public static func decode(_ attribute: Attribute) throws -> Self { let namedArguments = try attribute.namedArguments - if namedArguments.count == 0 { return Version(major: 0, minor: 0) } + if namedArguments.count == 0 { return .init(Version(major: 0, minor: 0)) } guard namedArguments.count <= 1, case .field(let field) = namedArguments[0].target, field.name == "version", case .constant(let versionConstant) = namedArguments[0].value, case .uint32(let versionValue) = versionConstant else { throw InvalidMetadataError.attributeArguments } - return Version(unpacking: versionValue) + return .init(Version(unpacking: versionValue)) } } \ No newline at end of file diff --git a/Sources/WindowsMetadata/ExclusiveToAttribute.swift b/Sources/WindowsMetadata/Attributes/ExclusiveToAttribute.swift similarity index 73% rename from Sources/WindowsMetadata/ExclusiveToAttribute.swift rename to Sources/WindowsMetadata/Attributes/ExclusiveToAttribute.swift index ad92d83..02f1182 100644 --- a/Sources/WindowsMetadata/ExclusiveToAttribute.swift +++ b/Sources/WindowsMetadata/Attributes/ExclusiveToAttribute.swift @@ -1,17 +1,23 @@ import DotNetMetadata -public enum ExclusiveToAttribute: AttributeType { +public struct ExclusiveToAttribute: AttributeType { + public var target: ClassDefinition + + public init(_ target: ClassDefinition) { + self.target = target + } + public static var namespace: String? { "Windows.Foundation.Metadata" } public static var name: String { "ExclusiveToAttribute" } public static var validOn: AttributeTargets { .interface } public static var allowMultiple: Bool { false } public static var inherited: Bool { true } - public static func decode(_ attribute: Attribute) throws -> ClassDefinition { + public static func decode(_ attribute: Attribute) throws -> ExclusiveToAttribute { let arguments = try attribute.arguments guard arguments.count == 1, case .type(let target) = arguments[0], let targetClass = target as? ClassDefinition else { throw InvalidMetadataError.attributeArguments } - return targetClass + return .init(targetClass) } } diff --git a/Sources/WindowsMetadata/ExperimentalAttribute.swift b/Sources/WindowsMetadata/Attributes/ExperimentalAttribute.swift similarity index 88% rename from Sources/WindowsMetadata/ExperimentalAttribute.swift rename to Sources/WindowsMetadata/Attributes/ExperimentalAttribute.swift index 570b72a..119dca8 100644 --- a/Sources/WindowsMetadata/ExperimentalAttribute.swift +++ b/Sources/WindowsMetadata/Attributes/ExperimentalAttribute.swift @@ -2,12 +2,12 @@ import DotNetMetadata /// Indicates that a type or member should be marked in metadata as experimental, /// and consequently may not be present in the final, released version of an SDK or library. -public enum ExperimentalAttribute: AttributeType { +public struct ExperimentalAttribute: AttributeType { public static var namespace: String? { "Windows.Foundation.Metadata" } public static var name: String { "ExperimentalAttribute" } public static var validOn: AttributeTargets { .allTypes } public static var allowMultiple: Bool { false } public static var inherited: Bool { true } - public static func decode(_ attribute: Attribute) throws -> Void {} + public static func decode(_ attribute: Attribute) throws -> Self { .init() } } \ No newline at end of file diff --git a/Sources/WindowsMetadata/GuidAttribute.swift b/Sources/WindowsMetadata/Attributes/GuidAttribute.swift similarity index 90% rename from Sources/WindowsMetadata/GuidAttribute.swift rename to Sources/WindowsMetadata/Attributes/GuidAttribute.swift index 50a51a5..0fee456 100644 --- a/Sources/WindowsMetadata/GuidAttribute.swift +++ b/Sources/WindowsMetadata/Attributes/GuidAttribute.swift @@ -1,14 +1,20 @@ import DotNetMetadata import struct Foundation.UUID -public enum GuidAttribute: AttributeType { +public struct GuidAttribute: AttributeType { + public var value: UUID + + public init(_ value: UUID) { + self.value = value + } + public static var namespace: String? { "Windows.Foundation.Metadata" } public static var name: String { "GuidAttribute" } public static var validOn: AttributeTargets { .interface | .delegate } public static var allowMultiple: Bool { false } public static var inherited: Bool { true } - public static func decode(_ attribute: Attribute) throws -> UUID { + public static func decode(_ attribute: Attribute) throws -> Self { // [Windows.Foundation.Metadata.Guid(1516535814u, 33850, 19881, 134, 91, 157, 38, 229, 223, 173, 123)] let arguments = try attribute.arguments guard arguments.count == 11 else { throw InvalidMetadataError.attributeArguments } @@ -28,11 +34,11 @@ public enum GuidAttribute: AttributeType { return value } - return UUID(uuid: ( + return .init(UUID(uuid: ( UInt8((a >> 24) & 0xFF), UInt8((a >> 16) & 0xFF), UInt8((a >> 8) & 0xFF), UInt8((a >> 0) & 0xFF), UInt8((b >> 8) & 0xFF), UInt8((b >> 0) & 0xFF), UInt8((c >> 8) & 0xFF), UInt8((c >> 0) & 0xFF), rest[0], rest[1], rest[2], rest[3], rest[4], rest[5], rest[6], rest[7] - )) + ))) } } diff --git a/Sources/WindowsMetadata/InternalAttribute.swift b/Sources/WindowsMetadata/Attributes/InternalAttribute.swift similarity index 88% rename from Sources/WindowsMetadata/InternalAttribute.swift rename to Sources/WindowsMetadata/Attributes/InternalAttribute.swift index bfa3f79..e0d2539 100644 --- a/Sources/WindowsMetadata/InternalAttribute.swift +++ b/Sources/WindowsMetadata/Attributes/InternalAttribute.swift @@ -1,12 +1,12 @@ import DotNetMetadata /// Indicates that the interface contains internal methods. -public enum InternalAttribute: AttributeType { +public struct InternalAttribute: AttributeType { public static var namespace: String? { "Windows.Foundation.Metadata" } public static var name: String { "InternalAttribute" } public static var validOn: AttributeTargets { .none } // No attribute target for interface implementations public static var allowMultiple: Bool { false } public static var inherited: Bool { true } - public static func decode(_ attribute: Attribute) throws -> Void {} + public static func decode(_ attribute: Attribute) throws -> Self { .init() } } \ No newline at end of file diff --git a/Sources/WindowsMetadata/LengthIsAttribute.swift b/Sources/WindowsMetadata/Attributes/LengthIsAttribute.swift similarity index 77% rename from Sources/WindowsMetadata/LengthIsAttribute.swift rename to Sources/WindowsMetadata/Attributes/LengthIsAttribute.swift index 2313641..bb45170 100644 --- a/Sources/WindowsMetadata/LengthIsAttribute.swift +++ b/Sources/WindowsMetadata/Attributes/LengthIsAttribute.swift @@ -1,18 +1,24 @@ import DotNetMetadata /// Indicates the number of array elements. -public enum LengthIsAttribute: AttributeType { +public struct LengthIsAttribute: AttributeType { + public var paramIndex: Int32 + + public init(_ paramIndex: Int32) { + self.paramIndex = paramIndex + } + public static var namespace: String? { "Windows.Foundation.Metadata" } public static var name: String { "LengthIsAttribute" } public static var validOn: AttributeTargets { .param } public static var allowMultiple: Bool { false } public static var inherited: Bool { true } - public static func decode(_ attribute: Attribute) throws -> Int32 { + public static func decode(_ attribute: Attribute) throws -> Self { let arguments = try attribute.arguments guard arguments.count == 1, case .constant(let constant) = arguments[0], case .int32(let value) = constant else { throw InvalidMetadataError.attributeArguments } - return value + return .init(value) } } \ No newline at end of file diff --git a/Sources/WindowsMetadata/MarshalingBehaviorAttribute.swift b/Sources/WindowsMetadata/Attributes/MarshalingBehaviorAttribute.swift similarity index 83% rename from Sources/WindowsMetadata/MarshalingBehaviorAttribute.swift rename to Sources/WindowsMetadata/Attributes/MarshalingBehaviorAttribute.swift index a6a5b8b..eefcdf7 100644 --- a/Sources/WindowsMetadata/MarshalingBehaviorAttribute.swift +++ b/Sources/WindowsMetadata/Attributes/MarshalingBehaviorAttribute.swift @@ -1,20 +1,26 @@ import DotNetMetadata /// Indicates the threading model of a Windows Runtime component. -public enum MarshalingBehaviorAttribute: AttributeType { +public struct MarshalingBehaviorAttribute: AttributeType { + public var type: MarshalingType + + public init(type: MarshalingType) { + self.type = type + } + public static var namespace: String? { "Windows.Foundation.Metadata" } public static var name: String { "MarshalingBehaviorAttribute" } public static var validOn: AttributeTargets { .class } public static var allowMultiple: Bool { false } public static var inherited: Bool { true } - public static func decode(_ attribute: Attribute) throws -> MarshalingType { + public static func decode(_ attribute: Attribute) throws -> Self { let arguments = try attribute.arguments guard arguments.count == 1, case .constant(let constant) = arguments[0], case .int32(let value) = constant, let marshalingType = MarshalingType(rawValue: value) else { throw InvalidMetadataError.attributeArguments } - return marshalingType + return .init(type: marshalingType) } } diff --git a/Sources/WindowsMetadata/NoExceptionAttribute.swift b/Sources/WindowsMetadata/Attributes/NoExceptionAttribute.swift similarity index 86% rename from Sources/WindowsMetadata/NoExceptionAttribute.swift rename to Sources/WindowsMetadata/Attributes/NoExceptionAttribute.swift index cf8d806..09c00d6 100644 --- a/Sources/WindowsMetadata/NoExceptionAttribute.swift +++ b/Sources/WindowsMetadata/Attributes/NoExceptionAttribute.swift @@ -1,12 +1,12 @@ import DotNetMetadata /// Indicates that the interface contains protected methods. -public enum NoExceptionAttribute: AttributeType { +public struct NoExceptionAttribute: AttributeType { public static var namespace: String? { "Windows.Foundation.Metadata" } public static var name: String { "NoExceptionAttribute" } public static var validOn: AttributeTargets { .method | .property } public static var allowMultiple: Bool { false } public static var inherited: Bool { true } - public static func decode(_ attribute: Attribute) throws -> Void {} + public static func decode(_ attribute: Attribute) throws -> Self { .init() } } \ No newline at end of file diff --git a/Sources/WindowsMetadata/OverloadAttribute.swift b/Sources/WindowsMetadata/Attributes/OverloadAttribute.swift similarity index 77% rename from Sources/WindowsMetadata/OverloadAttribute.swift rename to Sources/WindowsMetadata/Attributes/OverloadAttribute.swift index 6c9c2a7..fb2af15 100644 --- a/Sources/WindowsMetadata/OverloadAttribute.swift +++ b/Sources/WindowsMetadata/Attributes/OverloadAttribute.swift @@ -1,18 +1,24 @@ import DotNetMetadata /// Identifies the method as an overload in a language that supports overloading. -public enum OverloadAttribute: AttributeType { +public struct OverloadAttribute: AttributeType { + public var methodName: String + + public init(_ methodName: String) { + self.methodName = methodName + } + public static var namespace: String? { "Windows.Foundation.Metadata" } public static var name: String { "OverloadAttribute" } public static var validOn: AttributeTargets { .method } public static var allowMultiple: Bool { false } public static var inherited: Bool { true } - public static func decode(_ attribute: Attribute) throws -> String { + public static func decode(_ attribute: Attribute) throws -> Self { let arguments = try attribute.arguments guard arguments.count == 1, case .constant(let constant) = arguments[0], case .string(let name) = constant else { throw InvalidMetadataError.attributeArguments } - return name + return .init(name) } } \ No newline at end of file diff --git a/Sources/WindowsMetadata/ProtectedAttribute.swift b/Sources/WindowsMetadata/Attributes/ProtectedAttribute.swift similarity index 88% rename from Sources/WindowsMetadata/ProtectedAttribute.swift rename to Sources/WindowsMetadata/Attributes/ProtectedAttribute.swift index 7b72f0c..5d0ea72 100644 --- a/Sources/WindowsMetadata/ProtectedAttribute.swift +++ b/Sources/WindowsMetadata/Attributes/ProtectedAttribute.swift @@ -1,12 +1,12 @@ import DotNetMetadata /// Indicates that the interface contains protected methods. -public enum ProtectedAttribute: AttributeType { +public struct ProtectedAttribute: AttributeType { public static var namespace: String? { "Windows.Foundation.Metadata" } public static var name: String { "ProtectedAttribute" } public static var validOn: AttributeTargets { .none } // No attribute target for interface implementations public static var allowMultiple: Bool { false } public static var inherited: Bool { true } - public static func decode(_ attribute: Attribute) throws -> Void {} + public static func decode(_ attribute: Attribute) throws -> Self { .init() } } \ No newline at end of file diff --git a/Sources/WindowsMetadata/StaticAttribute.swift b/Sources/WindowsMetadata/Attributes/StaticAttribute.swift similarity index 100% rename from Sources/WindowsMetadata/StaticAttribute.swift rename to Sources/WindowsMetadata/Attributes/StaticAttribute.swift diff --git a/Sources/WindowsMetadata/ThreadingAttribute.swift b/Sources/WindowsMetadata/Attributes/ThreadingAttribute.swift similarity index 82% rename from Sources/WindowsMetadata/ThreadingAttribute.swift rename to Sources/WindowsMetadata/Attributes/ThreadingAttribute.swift index 214d6ab..7016fad 100644 --- a/Sources/WindowsMetadata/ThreadingAttribute.swift +++ b/Sources/WindowsMetadata/Attributes/ThreadingAttribute.swift @@ -1,20 +1,26 @@ import DotNetMetadata /// Indicates the threading model of a Windows Runtime component. -public enum ThreadingAttribute: AttributeType { +public struct ThreadingAttribute: AttributeType { + public var model: ThreadingModel + + public init(_ model: ThreadingModel) { + self.model = model + } + public static var namespace: String? { "Windows.Foundation.Metadata" } public static var name: String { "ThreadingAttribute" } public static var validOn: AttributeTargets { .class } public static var allowMultiple: Bool { false } public static var inherited: Bool { true } - public static func decode(_ attribute: Attribute) throws -> ThreadingModel { + public static func decode(_ attribute: Attribute) throws -> Self { let arguments = try attribute.arguments guard arguments.count == 1, case .constant(let constant) = arguments[0], case .int32(let value) = constant, let threadingModel = ThreadingModel(rawValue: value) else { throw InvalidMetadataError.attributeArguments } - return threadingModel + return .init(threadingModel) } } diff --git a/Sources/WindowsMetadata/VariantAttribute.swift b/Sources/WindowsMetadata/Attributes/VariantAttribute.swift similarity index 89% rename from Sources/WindowsMetadata/VariantAttribute.swift rename to Sources/WindowsMetadata/Attributes/VariantAttribute.swift index bd68b5a..b3c248a 100644 --- a/Sources/WindowsMetadata/VariantAttribute.swift +++ b/Sources/WindowsMetadata/Attributes/VariantAttribute.swift @@ -2,12 +2,12 @@ import DotNetMetadata /// Indicates that the item is an instance of a variant **IInspectable**. /// Applies to method parameters, properties, and return values of types. -public enum VariantAttribute: AttributeType { +public struct VariantAttribute: AttributeType { public static var namespace: String? { "Windows.Foundation.Metadata" } public static var name: String { "VariantAttribute" } public static var validOn: AttributeTargets { .property | .param } public static var allowMultiple: Bool { false } public static var inherited: Bool { true } - public static func decode(_ attribute: Attribute) throws -> Void {} + public static func decode(_ attribute: Attribute) throws -> Self { .init() } } \ No newline at end of file diff --git a/Sources/WindowsMetadata/InterfaceID.swift b/Sources/WindowsMetadata/InterfaceID.swift index 01f6548..8393ea8 100644 --- a/Sources/WindowsMetadata/InterfaceID.swift +++ b/Sources/WindowsMetadata/InterfaceID.swift @@ -10,8 +10,8 @@ public func getInterfaceID(_ typeDefinition: TypeDefinition, genericArgs: [TypeN return signature.parameterizedID } else { - guard let guid = try typeDefinition.findAttribute(GuidAttribute.self) else { throw WinMDError.missingAttribute } - return guid + guard let attribute = try typeDefinition.findAttribute(GuidAttribute.self) else { throw WinMDError.missingAttribute } + return attribute.value } } diff --git a/Sources/WindowsMetadata/WinRTTypeSignature+fromBoundType.swift b/Sources/WindowsMetadata/WinRTTypeSignature+fromBoundType.swift index 775509f..c1b4d0c 100644 --- a/Sources/WindowsMetadata/WinRTTypeSignature+fromBoundType.swift +++ b/Sources/WindowsMetadata/WinRTTypeSignature+fromBoundType.swift @@ -7,7 +7,7 @@ extension WinRTTypeSignature { private static func fromBoundType(_ type: BoundType) throws -> WinRTTypeSignature { if type.genericArgs.count > 0 { - let id = try type.definition.findAttribute(GuidAttribute.self)! + let id = try type.definition.findAttribute(GuidAttribute.self)!.value let args = try type.genericArgs.map { guard case .bound(let arg) = $0 else { throw UnexpectedTypeError($0.description, context: "WinRT generic argument", reason: "Not a bound type") @@ -54,11 +54,11 @@ extension WinRTTypeSignature { return .enum(name: type.definition.fullName, flags: try type.definition.hasAttribute(FlagsAttribute.self)) case is InterfaceDefinition: - let id = try type.definition.findAttribute(GuidAttribute.self)! + let id = try type.definition.findAttribute(GuidAttribute.self)!.value return .interface(id: id) case is DelegateDefinition: - let id = try type.definition.findAttribute(GuidAttribute.self)! + let id = try type.definition.findAttribute(GuidAttribute.self)!.value return .delegate(id: id) case let classDefinition as ClassDefinition: