namespace WoofWare.PawPrint
open System.Reflection.Metadata
open System.Reflection.Metadata.Ecma335
///
/// Represents a strongly-typed metadata token which can reference various elements in the assembly metadata.
/// This discriminated union provides type-safe handling of metadata tokens with specific handle types.
///
type MetadataToken =
/// Method implementation token, specifying how a virtual method is implemented.
| MethodImplementation of MethodImplementationHandle
/// Method definition token, identifying a method defined in this assembly.
| MethodDef of MethodDefinitionHandle
/// Method specification token, typically for generic method instantiations.
| MethodSpecification of MethodSpecificationHandle
/// Member reference token, for references to fields or methods in other modules/assemblies.
| MemberReference of MemberReferenceHandle
/// Type reference token, for references to types in other modules/assemblies.
| TypeReference of TypeReferenceHandle
/// Assembly reference token, identifying an external assembly.
| AssemblyReference of AssemblyReferenceHandle
/// Type specification token, for representing complex types like generic instantiations.
| TypeSpecification of TypeSpecificationHandle
/// Type definition token, identifying a type defined in this assembly.
| TypeDefinition of TypeDefinitionHandle
/// Field definition token, identifying a field defined in this assembly.
| FieldDefinition of FieldDefinitionHandle
/// Parameter token, identifying a parameter of a method.
| Parameter of ParameterHandle
/// Interface implementation token, mapping an implementation to an interface method.
| InterfaceImplementation of InterfaceImplementationHandle
/// Exported type token, identifying a type exported from this assembly.
| ExportedType of ExportedTypeHandle
/// Standalone signature token, for method signatures not attached to any method.
| StandaloneSignature of StandaloneSignatureHandle
/// Event definition token, identifying an event defined in this assembly.
| EventDefinition of EventDefinitionHandle
/// Constant token, representing a constant value stored in metadata.
| Constant of ConstantHandle
/// Custom attribute token, identifying an attribute applied to a metadata element.
| CustomAttribute of CustomAttributeHandle
/// Security attribute token, for declarative security attributes.
| DeclarativeSecurityAttribute of DeclarativeSecurityAttributeHandle
/// Property definition token, identifying a property defined in this assembly.
| PropertyDefinition of PropertyDefinitionHandle
/// Module reference token, for references to other modules in the same assembly.
| ModuleReference of ModuleReferenceHandle
/// Assembly file token, identifying a file that is part of this assembly.
| AssemblyFile of AssemblyFileHandle
/// Manifest resource token, identifying a resource embedded in this assembly.
| ManifestResource of ManifestResourceHandle
/// Generic parameter token, identifying a generic type or method parameter.
| GenericParameter of GenericParameterHandle
/// Generic parameter constraint token, identifying a constraint on a generic parameter.
| GenericParameterConstraint of GenericParameterConstraintHandle
/// Document token, used in debugging information.
| Document of DocumentHandle
/// Method debug information token, for debugging metadata about a method.
| MethodDebugInformation of MethodDebugInformationHandle
/// Local scope token, identifying a scope within a method body.
| LocalScope of LocalScopeHandle
/// Local variable token, identifying a local variable in a method.
| LocalVariable of LocalVariableHandle
/// Local constant token, identifying a local constant in a method.
| LocalConstant of LocalConstantHandle
/// Import scope token, used in debugging information for namespace imports.
| ImportScope of ImportScopeHandle
/// Custom debug information token, for user-defined debugging metadata.
| CustomDebugInformation of CustomDebugInformationHandle
[]
module MetadataToken =
let ofInt (value : int32) : MetadataToken =
let asRowNum = value &&& 0x00FFFFFF
match LanguagePrimitives.EnumOfValue (byte (value &&& 0xFF000000 >>> 24)) with
| HandleKind.ModuleDefinition -> failwith "TODO"
| HandleKind.TypeReference -> MetadataToken.TypeReference (MetadataTokens.TypeReferenceHandle asRowNum)
| HandleKind.TypeDefinition -> MetadataToken.TypeDefinition (MetadataTokens.TypeDefinitionHandle asRowNum)
| HandleKind.FieldDefinition -> MetadataToken.FieldDefinition (MetadataTokens.FieldDefinitionHandle asRowNum)
| HandleKind.MethodDefinition -> MetadataToken.MethodDef (MetadataTokens.MethodDefinitionHandle asRowNum)
| HandleKind.Parameter -> MetadataToken.Parameter (MetadataTokens.ParameterHandle asRowNum)
| HandleKind.InterfaceImplementation ->
MetadataToken.InterfaceImplementation (MetadataTokens.InterfaceImplementationHandle asRowNum)
| HandleKind.MemberReference -> MetadataToken.MemberReference (MetadataTokens.MemberReferenceHandle asRowNum)
| HandleKind.Constant -> MetadataToken.Constant (MetadataTokens.ConstantHandle asRowNum)
| HandleKind.CustomAttribute -> MetadataToken.CustomAttribute (MetadataTokens.CustomAttributeHandle asRowNum)
| HandleKind.DeclarativeSecurityAttribute ->
MetadataToken.DeclarativeSecurityAttribute (MetadataTokens.DeclarativeSecurityAttributeHandle asRowNum)
| HandleKind.StandaloneSignature ->
MetadataToken.StandaloneSignature (MetadataTokens.StandaloneSignatureHandle asRowNum)
| HandleKind.EventDefinition -> MetadataToken.EventDefinition (MetadataTokens.EventDefinitionHandle asRowNum)
| HandleKind.PropertyDefinition ->
MetadataToken.PropertyDefinition (MetadataTokens.PropertyDefinitionHandle asRowNum)
| HandleKind.MethodImplementation ->
MetadataToken.MethodImplementation (MetadataTokens.MethodImplementationHandle asRowNum)
| HandleKind.ModuleReference -> MetadataToken.ModuleReference (MetadataTokens.ModuleReferenceHandle asRowNum)
| HandleKind.TypeSpecification ->
MetadataToken.TypeSpecification (MetadataTokens.TypeSpecificationHandle asRowNum)
| HandleKind.AssemblyDefinition -> failwith "TODO"
| HandleKind.AssemblyReference ->
MetadataToken.AssemblyReference (MetadataTokens.AssemblyReferenceHandle asRowNum)
| HandleKind.AssemblyFile -> MetadataToken.AssemblyFile (MetadataTokens.AssemblyFileHandle asRowNum)
| HandleKind.ExportedType -> MetadataToken.ExportedType (MetadataTokens.ExportedTypeHandle asRowNum)
| HandleKind.ManifestResource -> MetadataToken.ManifestResource (MetadataTokens.ManifestResourceHandle asRowNum)
| HandleKind.GenericParameter -> MetadataToken.GenericParameter (MetadataTokens.GenericParameterHandle asRowNum)
| HandleKind.MethodSpecification ->
MetadataToken.MethodSpecification (MetadataTokens.MethodSpecificationHandle asRowNum)
| HandleKind.GenericParameterConstraint ->
MetadataToken.GenericParameterConstraint (MetadataTokens.GenericParameterConstraintHandle asRowNum)
| HandleKind.Document -> MetadataToken.Document (MetadataTokens.DocumentHandle asRowNum)
| HandleKind.MethodDebugInformation ->
MetadataToken.MethodDebugInformation (MetadataTokens.MethodDebugInformationHandle asRowNum)
| HandleKind.LocalScope -> MetadataToken.LocalScope (MetadataTokens.LocalScopeHandle asRowNum)
| HandleKind.LocalVariable -> MetadataToken.LocalVariable (MetadataTokens.LocalVariableHandle asRowNum)
| HandleKind.LocalConstant -> MetadataToken.LocalConstant (MetadataTokens.LocalConstantHandle asRowNum)
| HandleKind.ImportScope -> MetadataToken.ImportScope (MetadataTokens.ImportScopeHandle asRowNum)
| HandleKind.CustomDebugInformation ->
MetadataToken.CustomDebugInformation (MetadataTokens.CustomDebugInformationHandle asRowNum)
| HandleKind.UserString -> failwith "TODO"
| HandleKind.Blob -> failwith "TODO"
| HandleKind.Guid -> failwith "TODO"
| HandleKind.String -> failwith "TODO"
| HandleKind.NamespaceDefinition -> failwith "TODO"
| h -> failwith $"Unrecognised kind: {h}"
let ofEntityHandle (eh : EntityHandle) : MetadataToken = ofInt (eh.GetHashCode ())