mirror of
https://github.com/Smaug123/WoofWare.PawPrint
synced 2025-10-08 07:28:40 +00:00
Split WoofWare.PawPrint.Domain into a new subtree (#41)
This commit is contained in:
94
WoofWare.PawPrint.Domain/TypeRef.fs
Normal file
94
WoofWare.PawPrint.Domain/TypeRef.fs
Normal file
@@ -0,0 +1,94 @@
|
||||
namespace WoofWare.PawPrint
|
||||
|
||||
open System
|
||||
open System.Reflection.Metadata
|
||||
open Microsoft.FSharp.Core
|
||||
|
||||
[<CustomComparison>]
|
||||
[<CustomEquality>]
|
||||
type TypeRefResolutionScope =
|
||||
| Assembly of AssemblyReferenceHandle
|
||||
| ModuleRef of ModuleReferenceHandle
|
||||
| TypeRef of TypeReferenceHandle
|
||||
|
||||
override this.Equals (other : obj) : bool =
|
||||
let other =
|
||||
match other with
|
||||
| :? TypeRefResolutionScope as other -> other
|
||||
| _ -> failwith "should never compare with non-TypeRefResolutionScope"
|
||||
|
||||
match this, other with
|
||||
| TypeRefResolutionScope.Assembly a1, TypeRefResolutionScope.Assembly a2 -> a1 = a2
|
||||
| TypeRefResolutionScope.Assembly _, _ -> false
|
||||
| TypeRefResolutionScope.ModuleRef m1, TypeRefResolutionScope.ModuleRef m2 -> m1 = m2
|
||||
| TypeRefResolutionScope.ModuleRef _, _ -> false
|
||||
| TypeRefResolutionScope.TypeRef t1, TypeRefResolutionScope.TypeRef t2 -> t1 = t2
|
||||
| TypeRefResolutionScope.TypeRef _, _ -> false
|
||||
|
||||
override this.GetHashCode () : int =
|
||||
match this with
|
||||
| TypeRefResolutionScope.Assembly h -> hash (1, h)
|
||||
| TypeRefResolutionScope.ModuleRef h -> hash (2, h)
|
||||
| TypeRefResolutionScope.TypeRef h -> hash (3, h)
|
||||
|
||||
interface IComparable<TypeRefResolutionScope> with
|
||||
member this.CompareTo other =
|
||||
match this, other with
|
||||
| TypeRefResolutionScope.Assembly h1, TypeRefResolutionScope.Assembly h2 ->
|
||||
// this happens to get the underlying int
|
||||
h1.GetHashCode().CompareTo (h2.GetHashCode ())
|
||||
| TypeRefResolutionScope.Assembly _, TypeRefResolutionScope.ModuleRef _ -> -1
|
||||
| TypeRefResolutionScope.Assembly _, TypeRefResolutionScope.TypeRef _ -> -1
|
||||
| TypeRefResolutionScope.ModuleRef _, Assembly _ -> 1
|
||||
| TypeRefResolutionScope.ModuleRef m1, ModuleRef m2 -> m1.GetHashCode().CompareTo (m2.GetHashCode ())
|
||||
| TypeRefResolutionScope.ModuleRef _, TypeRef _ -> -1
|
||||
| TypeRefResolutionScope.TypeRef _, Assembly _ -> 1
|
||||
| TypeRefResolutionScope.TypeRef _, ModuleRef _ -> 1
|
||||
| TypeRefResolutionScope.TypeRef t1, TypeRef t2 -> t1.GetHashCode().CompareTo (t2.GetHashCode ())
|
||||
|
||||
interface IComparable with
|
||||
member this.CompareTo (other : obj) : int =
|
||||
let other =
|
||||
match other with
|
||||
| :? TypeRefResolutionScope as other -> other
|
||||
| _ -> failwith "unexpectedly comparing TypeRefResolutionScope with something else"
|
||||
|
||||
(this :> IComparable<TypeRefResolutionScope>).CompareTo other
|
||||
|
||||
/// <summary>
|
||||
/// Represents a type reference in a .NET assembly metadata.
|
||||
/// This corresponds to a TypeReferenceHandle in System.Reflection.Metadata.
|
||||
/// </summary>
|
||||
type TypeRef =
|
||||
{
|
||||
/// <summary>The simple name of the referenced type (without namespace).</summary>
|
||||
Name : string
|
||||
|
||||
/// <summary>The namespace of the referenced type, or empty string for nested types.</summary>
|
||||
Namespace : string
|
||||
|
||||
/// <summary>
|
||||
/// The scope of the type reference: where to find the type.
|
||||
/// </summary>
|
||||
ResolutionScope : TypeRefResolutionScope
|
||||
}
|
||||
|
||||
[<RequireQualifiedAccess>]
|
||||
module TypeRef =
|
||||
let make (metadataReader : MetadataReader) (ty : TypeReferenceHandle) : TypeRef =
|
||||
let typeRef = metadataReader.GetTypeReference ty
|
||||
let prettyName = metadataReader.GetString typeRef.Name
|
||||
let prettyNamespace = metadataReader.GetString typeRef.Namespace
|
||||
|
||||
let resolutionScope =
|
||||
match MetadataToken.ofEntityHandle typeRef.ResolutionScope with
|
||||
| MetadataToken.AssemblyReference ref -> TypeRefResolutionScope.Assembly ref
|
||||
| MetadataToken.ModuleReference ref -> TypeRefResolutionScope.ModuleRef ref
|
||||
| MetadataToken.TypeReference ref -> TypeRefResolutionScope.TypeRef ref
|
||||
| handle -> failwith $"Unexpected TypeRef resolution scope: {handle}"
|
||||
|
||||
{
|
||||
Name = prettyName
|
||||
Namespace = prettyNamespace
|
||||
ResolutionScope = resolutionScope
|
||||
}
|
Reference in New Issue
Block a user