Add a type parameter on FieldInfo to represent signature (#84)

This commit is contained in:
Patrick Stevens
2025-07-02 18:41:28 +01:00
committed by GitHub
parent b5f4ed6dec
commit c79f775ce4
4 changed files with 71 additions and 64 deletions

View File

@@ -45,7 +45,10 @@ type DumpedAssembly =
/// Dictionary of all type definitions in this assembly, keyed by their handle.
/// </summary>
TypeDefs :
IReadOnlyDictionary<TypeDefinitionHandle, WoofWare.PawPrint.TypeInfo<WoofWare.PawPrint.GenericParameter>>
IReadOnlyDictionary<
TypeDefinitionHandle,
WoofWare.PawPrint.TypeInfo<WoofWare.PawPrint.GenericParameter, TypeDefn>
>
/// <summary>
/// Dictionary of all type references in this assembly, keyed by their handle.
@@ -75,7 +78,7 @@ type DumpedAssembly =
/// <summary>
/// Dictionary of all field definitions in this assembly, keyed by their handle.
/// </summary>
Fields : IReadOnlyDictionary<FieldDefinitionHandle, WoofWare.PawPrint.FieldInfo<FakeUnit>>
Fields : IReadOnlyDictionary<FieldDefinitionHandle, WoofWare.PawPrint.FieldInfo<FakeUnit, TypeDefn>>
/// <summary>
/// The entry point method of the assembly, if one exists.
@@ -143,7 +146,10 @@ type DumpedAssembly =
/// Internal lookup for type definitions by namespace and name.
/// </summary>
_TypeDefsLookup :
ImmutableDictionary<string * string, WoofWare.PawPrint.TypeInfo<WoofWare.PawPrint.GenericParameter>>
ImmutableDictionary<
string * string,
WoofWare.PawPrint.TypeInfo<WoofWare.PawPrint.GenericParameter, TypeDefn>
>
}
static member internal BuildExportedTypesLookup
@@ -199,7 +205,7 @@ type DumpedAssembly =
static member internal BuildTypeDefsLookup
(logger : ILogger)
(name : AssemblyName)
(typeDefs : WoofWare.PawPrint.TypeInfo<WoofWare.PawPrint.GenericParameter> seq)
(typeDefs : WoofWare.PawPrint.TypeInfo<WoofWare.PawPrint.GenericParameter, TypeDefn> seq)
=
let result = ImmutableDictionary.CreateBuilder ()
let keys = HashSet ()
@@ -230,7 +236,7 @@ type DumpedAssembly =
member this.TypeDef
(``namespace`` : string)
(name : string)
: WoofWare.PawPrint.TypeInfo<WoofWare.PawPrint.GenericParameter> option
: WoofWare.PawPrint.TypeInfo<WoofWare.PawPrint.GenericParameter, TypeDefn> option
=
match this._TypeDefsLookup.TryGetValue ((``namespace``, name)) with
| false, _ -> None
@@ -247,13 +253,13 @@ type DumpedAssembly =
type TypeResolutionResult =
| FirstLoadAssy of WoofWare.PawPrint.AssemblyReference
| Resolved of DumpedAssembly * TypeInfo<TypeDefn>
| Resolved of DumpedAssembly * TypeInfo<TypeDefn, TypeDefn>
override this.ToString () : string =
match this with
| TypeResolutionResult.FirstLoadAssy a -> $"FirstLoadAssy(%s{a.Name.FullName})"
| TypeResolutionResult.Resolved (assy, ty) ->
$"Resolved(%s{assy.Name.FullName}: {string<TypeInfo<TypeDefn>> ty})"
$"Resolved(%s{assy.Name.FullName}: {string<TypeInfo<TypeDefn, TypeDefn>> ty})"
[<RequireQualifiedAccess>]
module Assembly =

View File

@@ -8,7 +8,8 @@ open System.Reflection.Metadata
/// Represents detailed information about a field in a .NET assembly.
/// This is a strongly-typed representation of FieldDefinition from System.Reflection.Metadata.
/// </summary>
type FieldInfo<'typeGeneric when 'typeGeneric : comparison and 'typeGeneric :> IComparable<'typeGeneric>> =
type FieldInfo<'typeGeneric, 'fieldGeneric when 'typeGeneric : comparison and 'typeGeneric :> IComparable<'typeGeneric>>
=
{
/// <summary>
/// The metadata token handle that uniquely identifies this field in the assembly.
@@ -26,7 +27,7 @@ type FieldInfo<'typeGeneric when 'typeGeneric : comparison and 'typeGeneric :> I
/// <summary>
/// The type of the field.
/// </summary>
Signature : TypeDefn
Signature : 'fieldGeneric
/// <summary>
/// The attributes applied to this field, including visibility, static/instance,
@@ -45,7 +46,7 @@ module FieldInfo =
(assembly : AssemblyName)
(handle : FieldDefinitionHandle)
(def : FieldDefinition)
: FieldInfo<FakeUnit>
: FieldInfo<FakeUnit, TypeDefn>
=
let name = mr.GetString def.Name
let fieldSig = def.DecodeSignature (TypeDefn.typeProvider assembly, ())
@@ -66,11 +67,11 @@ module FieldInfo =
Attributes = def.Attributes
}
let mapTypeGenerics<'a, 'b
let mapTypeGenerics<'a, 'b, 'field
when 'a :> IComparable<'a> and 'a : comparison and 'b :> IComparable<'b> and 'b : comparison>
(f : int -> 'a -> 'b)
(input : FieldInfo<'a>)
: FieldInfo<'b>
(input : FieldInfo<'a, 'field>)
: FieldInfo<'b, 'field>
=
let declaringType = input.DeclaringType |> ConcreteType.mapGeneric f

View File

@@ -23,7 +23,7 @@ type MethodImplParsed =
/// Represents detailed information about a type definition in a .NET assembly.
/// This is a strongly-typed representation of TypeDefinition from System.Reflection.Metadata.
/// </summary>
type TypeInfo<'generic> =
type TypeInfo<'generic, 'fieldGeneric> =
{
/// <summary>The namespace containing the type.</summary>
Namespace : string
@@ -45,7 +45,7 @@ type TypeInfo<'generic> =
/// <summary>
/// Fields defined in this type.
/// </summary>
Fields : WoofWare.PawPrint.FieldInfo<FakeUnit> list
Fields : WoofWare.PawPrint.FieldInfo<FakeUnit, 'fieldGeneric> list
/// <summary>
/// The base type that this type inherits from, or None for types that don't have a base type
@@ -85,7 +85,7 @@ type TypeInfo<'generic> =
$"%s{this.Assembly.Name}.%s{this.Namespace}.%s{this.Name}"
type TypeInfoEval<'ret> =
abstract Eval<'a> : TypeInfo<'a> -> 'ret
abstract Eval<'a, 'field> : TypeInfo<'a, 'field> -> 'ret
type TypeInfoCrate =
abstract Apply<'ret> : TypeInfoEval<'ret> -> 'ret
@@ -97,13 +97,13 @@ type TypeInfoCrate =
[<RequireQualifiedAccess>]
module TypeInfoCrate =
let make<'a> (t : TypeInfo<'a>) =
let make<'a, 'field> (t : TypeInfo<'a, 'field>) =
{ new TypeInfoCrate with
member _.Apply e = e.Eval t
member this.ToString () =
{ new TypeInfoEval<_> with
member _.Eval this = string<TypeInfo<_>> this
member _.Eval this = string<TypeInfo<_, _>> this
}
|> this.Apply
@@ -119,37 +119,37 @@ module TypeInfoCrate =
type BaseClassTypes<'corelib> =
{
Corelib : 'corelib
String : TypeInfo<WoofWare.PawPrint.GenericParameter>
Boolean : TypeInfo<WoofWare.PawPrint.GenericParameter>
Char : TypeInfo<WoofWare.PawPrint.GenericParameter>
SByte : TypeInfo<WoofWare.PawPrint.GenericParameter>
Byte : TypeInfo<WoofWare.PawPrint.GenericParameter>
Int16 : TypeInfo<WoofWare.PawPrint.GenericParameter>
UInt16 : TypeInfo<WoofWare.PawPrint.GenericParameter>
Int32 : TypeInfo<WoofWare.PawPrint.GenericParameter>
UInt32 : TypeInfo<WoofWare.PawPrint.GenericParameter>
Int64 : TypeInfo<WoofWare.PawPrint.GenericParameter>
UInt64 : TypeInfo<WoofWare.PawPrint.GenericParameter>
Single : TypeInfo<WoofWare.PawPrint.GenericParameter>
Double : TypeInfo<WoofWare.PawPrint.GenericParameter>
Array : TypeInfo<WoofWare.PawPrint.GenericParameter>
Enum : TypeInfo<WoofWare.PawPrint.GenericParameter>
ValueType : TypeInfo<WoofWare.PawPrint.GenericParameter>
DelegateType : TypeInfo<WoofWare.PawPrint.GenericParameter>
Object : TypeInfo<WoofWare.PawPrint.GenericParameter>
RuntimeMethodHandle : TypeInfo<WoofWare.PawPrint.GenericParameter>
RuntimeFieldHandle : TypeInfo<WoofWare.PawPrint.GenericParameter>
RuntimeTypeHandle : TypeInfo<WoofWare.PawPrint.GenericParameter>
RuntimeType : TypeInfo<WoofWare.PawPrint.GenericParameter>
Void : TypeInfo<WoofWare.PawPrint.GenericParameter>
TypedReference : TypeInfo<WoofWare.PawPrint.GenericParameter>
IntPtr : TypeInfo<WoofWare.PawPrint.GenericParameter>
UIntPtr : TypeInfo<WoofWare.PawPrint.GenericParameter>
String : TypeInfo<WoofWare.PawPrint.GenericParameter, TypeDefn>
Boolean : TypeInfo<WoofWare.PawPrint.GenericParameter, TypeDefn>
Char : TypeInfo<WoofWare.PawPrint.GenericParameter, TypeDefn>
SByte : TypeInfo<WoofWare.PawPrint.GenericParameter, TypeDefn>
Byte : TypeInfo<WoofWare.PawPrint.GenericParameter, TypeDefn>
Int16 : TypeInfo<WoofWare.PawPrint.GenericParameter, TypeDefn>
UInt16 : TypeInfo<WoofWare.PawPrint.GenericParameter, TypeDefn>
Int32 : TypeInfo<WoofWare.PawPrint.GenericParameter, TypeDefn>
UInt32 : TypeInfo<WoofWare.PawPrint.GenericParameter, TypeDefn>
Int64 : TypeInfo<WoofWare.PawPrint.GenericParameter, TypeDefn>
UInt64 : TypeInfo<WoofWare.PawPrint.GenericParameter, TypeDefn>
Single : TypeInfo<WoofWare.PawPrint.GenericParameter, TypeDefn>
Double : TypeInfo<WoofWare.PawPrint.GenericParameter, TypeDefn>
Array : TypeInfo<WoofWare.PawPrint.GenericParameter, TypeDefn>
Enum : TypeInfo<WoofWare.PawPrint.GenericParameter, TypeDefn>
ValueType : TypeInfo<WoofWare.PawPrint.GenericParameter, TypeDefn>
DelegateType : TypeInfo<WoofWare.PawPrint.GenericParameter, TypeDefn>
Object : TypeInfo<WoofWare.PawPrint.GenericParameter, TypeDefn>
RuntimeMethodHandle : TypeInfo<WoofWare.PawPrint.GenericParameter, TypeDefn>
RuntimeFieldHandle : TypeInfo<WoofWare.PawPrint.GenericParameter, TypeDefn>
RuntimeTypeHandle : TypeInfo<WoofWare.PawPrint.GenericParameter, TypeDefn>
RuntimeType : TypeInfo<WoofWare.PawPrint.GenericParameter, TypeDefn>
Void : TypeInfo<WoofWare.PawPrint.GenericParameter, TypeDefn>
TypedReference : TypeInfo<WoofWare.PawPrint.GenericParameter, TypeDefn>
IntPtr : TypeInfo<WoofWare.PawPrint.GenericParameter, TypeDefn>
UIntPtr : TypeInfo<WoofWare.PawPrint.GenericParameter, TypeDefn>
}
[<RequireQualifiedAccess>]
module TypeInfo =
let withGenerics<'a, 'b> (gen : 'b ImmutableArray) (t : TypeInfo<'a>) : TypeInfo<'b> =
let withGenerics<'a, 'b, 'field> (gen : 'b ImmutableArray) (t : TypeInfo<'a, 'field>) : TypeInfo<'b, 'field> =
{
Namespace = t.Namespace
Name = t.Name
@@ -165,7 +165,7 @@ module TypeInfo =
Events = t.Events
}
let mapGeneric<'a, 'b> (f : int -> 'a -> 'b) (t : TypeInfo<'a>) : TypeInfo<'b> =
let mapGeneric<'a, 'b, 'field> (f : int -> 'a -> 'b) (t : TypeInfo<'a, 'field>) : TypeInfo<'b, 'field> =
withGenerics (t.Generics |> Seq.mapi f |> ImmutableArray.CreateRange) t
let internal read
@@ -174,7 +174,7 @@ module TypeInfo =
(thisAssembly : AssemblyName)
(metadataReader : MetadataReader)
(typeHandle : TypeDefinitionHandle)
: TypeInfo<WoofWare.PawPrint.GenericParameter>
: TypeInfo<WoofWare.PawPrint.GenericParameter, TypeDefn>
=
let typeDef = metadataReader.GetTypeDefinition typeHandle
let methods = typeDef.GetMethods ()
@@ -279,11 +279,11 @@ module TypeInfo =
else
None
let rec resolveBaseType<'corelib, 'generic>
let rec resolveBaseType<'corelib, 'generic, 'field>
(baseClassTypes : BaseClassTypes<'corelib>)
(getName : 'corelib -> AssemblyName)
(getTypeDef : 'corelib -> TypeDefinitionHandle -> TypeInfo<'generic>)
(getTypeRef : 'corelib -> TypeReferenceHandle -> TypeInfo<'generic>)
(getTypeDef : 'corelib -> TypeDefinitionHandle -> TypeInfo<'generic, 'field>)
(getTypeRef : 'corelib -> TypeReferenceHandle -> TypeInfo<'generic, 'field>)
(sourceAssembly : AssemblyName)
(value : BaseTypeInfo option)
: ResolvedBaseType
@@ -315,16 +315,16 @@ module TypeInfo =
let toTypeDefn
(corelib : BaseClassTypes<'corelib>)
(getName : 'corelib -> AssemblyName)
(getTypeDef : 'corelib -> TypeDefinitionHandle -> TypeInfo<'generic>)
(getTypeRef : 'corelib -> TypeReferenceHandle -> TypeInfo<'generic>)
(ty : TypeInfo<'generic>)
(getTypeDef : 'corelib -> TypeDefinitionHandle -> TypeInfo<'generic, 'field>)
(getTypeRef : 'corelib -> TypeReferenceHandle -> TypeInfo<'generic, 'field>)
(ty : TypeInfo<'generic, 'field>)
: TypeDefn
=
let stk =
match resolveBaseType corelib getName getTypeDef getTypeRef ty.Assembly ty.BaseType with
| ResolvedBaseType.Enum
| ResolvedBaseType.ValueType -> SignatureTypeKind.ValueType
| ResolvedBaseType.Object -> SignatureTypeKind.Class
| ResolvedBaseType.Delegate -> failwith "todo"
| ResolvedBaseType.Object
| ResolvedBaseType.Delegate -> SignatureTypeKind.Class
TypeDefn.FromDefinition (ComparableTypeDefinitionHandle.Make ty.TypeDefHandle, ty.Assembly.FullName, stk)

View File

@@ -195,7 +195,7 @@ module IlMachineState =
(genericArgs : ImmutableArray<TypeDefn> option)
(assy : DumpedAssembly)
(state : IlMachineState)
: IlMachineState * DumpedAssembly * WoofWare.PawPrint.TypeInfo<TypeDefn>
: IlMachineState * DumpedAssembly * WoofWare.PawPrint.TypeInfo<TypeDefn, TypeDefn>
=
match Assembly.resolveTypeFromName assy state._LoadedAssemblies ns name genericArgs with
| TypeResolutionResult.Resolved (assy, typeDef) -> state, assy, typeDef
@@ -215,7 +215,7 @@ module IlMachineState =
(ty : WoofWare.PawPrint.ExportedType)
(genericArgs : ImmutableArray<TypeDefn> option)
(state : IlMachineState)
: IlMachineState * DumpedAssembly * WoofWare.PawPrint.TypeInfo<TypeDefn>
: IlMachineState * DumpedAssembly * WoofWare.PawPrint.TypeInfo<TypeDefn, TypeDefn>
=
match Assembly.resolveTypeFromExport fromAssembly state._LoadedAssemblies ty genericArgs with
| TypeResolutionResult.Resolved (assy, typeDef) -> state, assy, typeDef
@@ -235,7 +235,7 @@ module IlMachineState =
(target : TypeRef)
(typeGenericArgs : ImmutableArray<TypeDefn> option)
(state : IlMachineState)
: IlMachineState * DumpedAssembly * WoofWare.PawPrint.TypeInfo<TypeDefn>
: IlMachineState * DumpedAssembly * WoofWare.PawPrint.TypeInfo<TypeDefn, TypeDefn>
=
match Assembly.resolveTypeRef state._LoadedAssemblies referencedInAssembly target typeGenericArgs with
| TypeResolutionResult.Resolved (assy, typeDef) -> state, assy, typeDef
@@ -255,7 +255,7 @@ module IlMachineState =
(genericArgs : ImmutableArray<TypeDefn> option)
(assy : DumpedAssembly)
(state : IlMachineState)
: IlMachineState * DumpedAssembly * WoofWare.PawPrint.TypeInfo<TypeDefn>
: IlMachineState * DumpedAssembly * WoofWare.PawPrint.TypeInfo<TypeDefn, TypeDefn>
=
let target = assy.TypeRefs.[ty]
@@ -269,7 +269,7 @@ module IlMachineState =
(methodGenericArgs : ImmutableArray<TypeDefn>)
(assy : DumpedAssembly)
(state : IlMachineState)
: IlMachineState * DumpedAssembly * WoofWare.PawPrint.TypeInfo<TypeDefn>
: IlMachineState * DumpedAssembly * WoofWare.PawPrint.TypeInfo<TypeDefn, TypeDefn>
=
match ty with
| TypeDefn.GenericInstantiation (generic, args) ->
@@ -366,7 +366,7 @@ module IlMachineState =
(typeGenericArgs : TypeDefn ImmutableArray option)
(methodGenericArgs : TypeDefn ImmutableArray)
(state : IlMachineState)
: IlMachineState * DumpedAssembly * WoofWare.PawPrint.TypeInfo<TypeDefn>
: IlMachineState * DumpedAssembly * WoofWare.PawPrint.TypeInfo<TypeDefn, TypeDefn>
=
let sign = assy.TypeSpecs.[ty].Signature
resolveTypeFromDefn loggerFactory corelib sign typeGenericArgs methodGenericArgs assy state
@@ -1205,8 +1205,8 @@ module IlMachineState =
ManagedHeap = heap
}
let allocateManagedObject<'generic>
(typeInfo : WoofWare.PawPrint.TypeInfo<'generic>)
let allocateManagedObject<'generic, 'field>
(typeInfo : WoofWare.PawPrint.TypeInfo<'generic, 'field>)
(fields : (string * CliType) list)
(state : IlMachineState)
: ManagedHeapAddress * IlMachineState
@@ -1290,7 +1290,7 @@ module IlMachineState =
AssemblyName *
Choice<
WoofWare.PawPrint.MethodInfo<TypeDefn, WoofWare.PawPrint.GenericParameter>,
WoofWare.PawPrint.FieldInfo<TypeDefn>
WoofWare.PawPrint.FieldInfo<TypeDefn, TypeDefn>
>
=
// TODO: do we need to initialise the parent class here?