From c1d8329fc943f3881a05e73a694dab32e8af81a7 Mon Sep 17 00:00:00 2001
From: Patrick Stevens <3138005+Smaug123@users.noreply.github.com>
Date: Sat, 1 Mar 2025 23:55:23 +0000
Subject: [PATCH] Add docstrings to custom reflection type records (#3)
---
WoofWare.PawPrint/Assembly.fs | 97 +++++++++++++++++++++++++++-
WoofWare.PawPrint/CustomAttribute.fs | 12 ++++
WoofWare.PawPrint/ExportedType.fs | 44 +++++++++++++
WoofWare.PawPrint/FieldInfo.fs | 22 +++++++
WoofWare.PawPrint/MethodInfo.fs | 75 ++++++++++++++++++++-
WoofWare.PawPrint/Tokens.fs | 34 ++++++++++
WoofWare.PawPrint/TypeDefn.fs | 23 +++++++
WoofWare.PawPrint/TypeInfo.fs | 45 +++++++++++++
WoofWare.PawPrint/TypeRef.fs | 15 +++++
WoofWare.PawPrint/TypeSpec.fs | 13 ++++
10 files changed, 376 insertions(+), 4 deletions(-)
diff --git a/WoofWare.PawPrint/Assembly.fs b/WoofWare.PawPrint/Assembly.fs
index 22ca7aa..b7c4070 100644
--- a/WoofWare.PawPrint/Assembly.fs
+++ b/WoofWare.PawPrint/Assembly.fs
@@ -11,8 +11,15 @@ open System.Reflection.PortableExecutable
open Microsoft.Extensions.Logging
open Microsoft.FSharp.Core
+///
+/// Represents a .NET assembly definition.
+/// This is a strongly-typed representation of AssemblyDefinition from System.Reflection.Metadata.
+///
type AssemblyDefinition =
{
+ ///
+ /// The fully specified name of the assembly, including name, version, culture, and public key token.
+ ///
Name : AssemblyName
}
@@ -23,30 +30,116 @@ module AssemblyDefinition =
Name = assy.GetAssemblyName ()
}
+///
+/// Represents a fully parsed .NET assembly with all its metadata components.
+/// This serves as the main container for accessing assembly information in the PawPrint library.
+///
type DumpedAssembly =
{
+ /// Logger for recording information about this assembly.
Logger : ILogger
+
+ ///
+ /// Dictionary of all type definitions in this assembly, keyed by their handle.
+ ///
TypeDefs : IReadOnlyDictionary
+
+ ///
+ /// Dictionary of all type references in this assembly, keyed by their handle.
+ ///
TypeRefs : IReadOnlyDictionary
+
+ ///
+ /// Dictionary of all type specifications in this assembly, keyed by their handle.
+ /// Type specifications represent complex types like generic instantiations.
+ ///
TypeSpecs : IReadOnlyDictionary
+
+ ///
+ /// Dictionary of all method definitions in this assembly, keyed by their handle.
+ ///
Methods : IReadOnlyDictionary
+
+ ///
+ /// Dictionary of all member references in this assembly, keyed by their handle.
+ ///
Members : IReadOnlyDictionary>
+
+ ///
+ /// Dictionary of all field definitions in this assembly, keyed by their handle.
+ ///
Fields : IReadOnlyDictionary
+
+ ///
+ /// The entry point method of the assembly, if one exists.
+ ///
MainMethod : MethodDefinitionHandle option
- /// Map of four-byte int token to metadata
+
+ ///
+ /// Dictionary mapping four-byte integer tokens to method definitions.
+ ///
MethodDefinitions : ImmutableDictionary
+
+ ///
+ /// Dictionary of all method specifications in this assembly, keyed by their handle.
+ /// Method specifications typically represent generic method instantiations.
+ ///
MethodSpecs : ImmutableDictionary
+
+ ///
+ /// Function to resolve string tokens to their actual string values.
+ ///
Strings : StringToken -> string
+
+ ///
+ /// Dictionary of all assembly references in this assembly, keyed by their handle.
+ ///
AssemblyReferences : ImmutableDictionary
+
+ ///
+ /// Information about this assembly.
+ ///
ThisAssemblyDefinition : AssemblyDefinition
+
+ ///
+ /// The root namespace of this assembly.
+ ///
RootNamespace : Namespace
+
+ ///
+ /// Dictionary of all non-root namespaces in this assembly, keyed by their name components.
+ ///
NonRootNamespaces : ImmutableDictionary
- // TODO: work out how to render all the strings up front, then drop this
+
+ ///
+ /// The PE reader for the underlying assembly file.
+ /// TODO: work out how to render all the strings up front, then drop this.
+ ///
PeReader : PEReader
+
+ ///
+ /// Dictionary of all custom attributes in this assembly, keyed by their handle.
+ ///
Attributes : ImmutableDictionary
+
+ ///
+ /// Dictionary of all exported types in this assembly, keyed by their handle.
+ ///
ExportedTypes : ImmutableDictionary
+
+ ///
+ /// Internal lookup for exported types by namespace and name.
+ ///
_ExportedTypesLookup : ImmutableDictionary
+
+ ///
+ /// Internal lookup for type references by namespace and name.
+ ///
_TypeRefsLookup : ImmutableDictionary
+
+ ///
+ /// Internal lookup for type definitions by namespace and name.
+ ///
_TypeDefsLookup : ImmutableDictionary
}
diff --git a/WoofWare.PawPrint/CustomAttribute.fs b/WoofWare.PawPrint/CustomAttribute.fs
index 59d8daa..3ef8e51 100644
--- a/WoofWare.PawPrint/CustomAttribute.fs
+++ b/WoofWare.PawPrint/CustomAttribute.fs
@@ -2,9 +2,21 @@ namespace WoofWare.PawPrint
open System.Reflection.Metadata
+///
+/// Represents a custom attribute applied to a type, method, field, or other metadata entity.
+/// This is a strongly-typed representation of CustomAttribute from System.Reflection.Metadata.
+///
type CustomAttribute =
{
+ ///
+ /// The metadata token handle that uniquely identifies this custom attribute in the assembly.
+ ///
Handle : CustomAttributeHandle
+
+ ///
+ /// The constructor method used to create this custom attribute instance.
+ /// This token references the method that constructs the attribute.
+ ///
Constructor : MetadataToken
}
diff --git a/WoofWare.PawPrint/ExportedType.fs b/WoofWare.PawPrint/ExportedType.fs
index 50659cb..47ac449 100644
--- a/WoofWare.PawPrint/ExportedType.fs
+++ b/WoofWare.PawPrint/ExportedType.fs
@@ -3,17 +3,61 @@ namespace WoofWare.PawPrint
open System.Reflection
open System.Reflection.Metadata
+///
+/// Represents the implementation details of an exported type.
+/// This discriminated union indicates whether the type is forwarded to another assembly
+/// or references another exported type.
+///
type ExportedTypeData =
+ ///
+ /// Indicates the type is forwarded to another assembly.
+ /// Type forwarders are used to redirect type references to implementations in other assemblies.
+ ///
| ForwardsTo of AssemblyReferenceHandle
+
+ ///
+ /// Indicates the type references another exported type within the assembly.
+ /// This is often used for nested types.
+ ///
| NonForwarded of ExportedTypeHandle
+///
+/// Represents a type exported from an assembly.
+/// Exported types are types that are defined in one module but made visible
+/// at the assembly level, or types that are forwarded to another assembly.
+///
type ExportedType =
{
+ ///
+ /// The metadata token handle that uniquely identifies this exported type.
+ ///
Handle : ExportedTypeHandle
+
+ ///
+ /// The name of the exported type.
+ ///
Name : string
+
+ ///
+ /// The namespace containing the exported type, if any.
+ /// None if the type is not in a namespace.
+ ///
Namespace : string option
+
+ ///
+ /// The metadata handle for the namespace definition containing this type.
+ ///
NamespaceDefn : NamespaceDefinitionHandle
+
+ ///
+ /// The type attributes (visibility, inheritance characteristics, etc.) for this exported type.
+ ///
TypeAttrs : TypeAttributes
+
+ ///
+ /// The implementation details of this exported type, indicating whether it forwards
+ /// to another assembly or references another exported type.
+ ///
Data : ExportedTypeData
}
diff --git a/WoofWare.PawPrint/FieldInfo.fs b/WoofWare.PawPrint/FieldInfo.fs
index 4f0d5b0..3254278 100644
--- a/WoofWare.PawPrint/FieldInfo.fs
+++ b/WoofWare.PawPrint/FieldInfo.fs
@@ -2,12 +2,34 @@ namespace WoofWare.PawPrint
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.
+///
type FieldInfo =
{
+ ///
+ /// The metadata token handle that uniquely identifies this field in the assembly.
+ ///
Handle : FieldDefinitionHandle
+
+ /// The name of the field.
Name : string
+
+ ///
+ /// The type that declares this field.
+ ///
DeclaringType : TypeDefinitionHandle
+
+ ///
+ /// The type of the field.
+ ///
Signature : TypeDefn
+
+ ///
+ /// The attributes applied to this field, including visibility, static/instance,
+ /// literal, and other characteristics.
+ ///
Attributes : System.Reflection.FieldAttributes
}
diff --git a/WoofWare.PawPrint/MethodInfo.fs b/WoofWare.PawPrint/MethodInfo.fs
index c57359d..d3aaf86 100644
--- a/WoofWare.PawPrint/MethodInfo.fs
+++ b/WoofWare.PawPrint/MethodInfo.fs
@@ -8,10 +8,25 @@ open System.Reflection.Metadata
open System.Reflection.PortableExecutable
open Microsoft.Extensions.Logging
+///
+/// Represents information about a method parameter.
+/// Corresponds to Parameter in System.Reflection.Metadata.
+///
type Parameter =
{
+ /// The name of the parameter.
Name : string
+
+ ///
+ /// The default value of the parameter, if one is specified.
+ /// This is used for optional parameters.
+ ///
DefaultValue : Constant
+
+ ///
+ /// The position of the parameter in the parameter list.
+ /// For instance methods, index 0 is the 'this' parameter.
+ ///
SequenceNumber : int
}
@@ -30,9 +45,19 @@ module Parameter =
)
|> ImmutableArray.CreateRange
+///
+/// Represents a generic type or method parameter definition.
+/// Corresponds to GenericParameter in System.Reflection.Metadata.
+///
type GenericParameter =
{
+ /// The name of the generic parameter (e.g., 'T', 'TKey', etc.).
Name : string
+
+ ///
+ /// The zero-based index of the generic parameter in the generic parameter list.
+ /// For example, in Dictionary, TKey has index 0 and TValue has index 1.
+ ///
SequenceNumber : int
}
@@ -54,20 +79,66 @@ module GenericParameter =
)
|> ImmutableArray.CreateRange
+///
+/// Represents detailed information about a method in a .NET assembly.
+/// This is a strongly-typed representation of MethodDefinition from System.Reflection.Metadata.
+///
type MethodInfo =
{
+ ///
+ /// The type that declares this method, along with its assembly information.
+ ///
DeclaringType : TypeDefinitionHandle * AssemblyName
+
+ ///
+ /// The metadata token handle that uniquely identifies this method in the assembly.
+ ///
Handle : MethodDefinitionHandle
+
+ /// The name of the method.
Name : string
- /// also stores the offset of this instruction
+
+ ///
+ /// The IL instructions that comprise the method body, along with their offset positions.
+ /// Each tuple contains the instruction and its offset in the method body.
+ ///
Instructions : (IlOp * int) list
- /// inverted Instructions: a mapping of program counter to op
+
+ ///
+ /// A map from instruction offset (program counter) to the corresponding IL operation.
+ /// This is the inverse of Instructions for efficient lookup.
+ ///
Locations : Map
+
+ ///
+ /// The parameters of this method.
+ ///
Parameters : Parameter ImmutableArray
+
+ ///
+ /// The generic type parameters defined by this method, if any.
+ ///
Generics : GenericParameter ImmutableArray
+
+ ///
+ /// The signature of the method, including return type and parameter types.
+ ///
Signature : TypeMethodSignature
+
+ ///
+ /// Whether this method is implemented as a platform invoke (P/Invoke) to unmanaged code.
+ ///
IsPinvokeImpl : bool
+
+ ///
+ /// Whether local variables in this method should be initialized to their default values.
+ /// This corresponds to the localsinit flag in the method header.
+ ///
LocalsInit : bool
+
+ ///
+ /// Whether this method is static (true) or an instance method (false).
+ ///
IsStatic : bool
}
diff --git a/WoofWare.PawPrint/Tokens.fs b/WoofWare.PawPrint/Tokens.fs
index db8a058..175efe1 100644
--- a/WoofWare.PawPrint/Tokens.fs
+++ b/WoofWare.PawPrint/Tokens.fs
@@ -3,36 +3,70 @@ 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
[]
diff --git a/WoofWare.PawPrint/TypeDefn.fs b/WoofWare.PawPrint/TypeDefn.fs
index a144dce..291d150 100644
--- a/WoofWare.PawPrint/TypeDefn.fs
+++ b/WoofWare.PawPrint/TypeDefn.fs
@@ -4,12 +4,35 @@ open System.Collections.Immutable
open System.Reflection.Metadata
open System.Reflection.Metadata.Ecma335
+///
+/// Represents a method signature with type parameters.
+/// Corresponds to MethodSignature in System.Reflection.Metadata.
+///
type TypeMethodSignature<'Types> =
{
+ ///
+ /// Contains calling convention and other method attributes encoded in the metadata.
+ ///
Header : SignatureHeader
+
+ ///
+ /// The types of all parameters of the method.
+ ///
ParameterTypes : 'Types list
+
+ ///
+ /// The number of generic type parameters defined by this method.
+ ///
GenericParameterCount : int
+
+ ///
+ /// The number of required parameters (non-optional parameters).
+ ///
RequiredParameterCount : int
+
+ ///
+ /// The return type of the method.
+ ///
ReturnType : 'Types
}
diff --git a/WoofWare.PawPrint/TypeInfo.fs b/WoofWare.PawPrint/TypeInfo.fs
index 8e85037..4520035 100644
--- a/WoofWare.PawPrint/TypeInfo.fs
+++ b/WoofWare.PawPrint/TypeInfo.fs
@@ -8,8 +8,15 @@ open System.Reflection.PortableExecutable
open Microsoft.Extensions.Logging
open Microsoft.FSharp.Core
+///
+/// Represents a method specification, which provides information about a method,
+/// particularly for generic method instantiations.
+///
type MethodSpec =
{
+ ///
+ /// The token that identifies the method being specialized.
+ ///
Method : MetadataToken
}
@@ -31,16 +38,54 @@ type MethodImplParsed =
| MethodImplementation of MethodImplementationHandle
| MethodDefinition of MethodDefinitionHandle
+///
+/// Represents detailed information about a type definition in a .NET assembly.
+/// This is a strongly-typed representation of TypeDefinition from System.Reflection.Metadata.
+///
type TypeInfo =
{
+ /// The namespace containing the type.
Namespace : string
+
+ /// The name of the type.
Name : string
+
+ ///
+ /// All methods defined within this type.
+ ///
Methods : WoofWare.PawPrint.MethodInfo list
+
+ ///
+ /// Method implementation mappings for this type, often used for interface implementations
+ /// or overriding virtual methods from base classes.
+ ///
MethodImpls : ImmutableDictionary
+
+ ///
+ /// Fields defined in this type.
+ ///
Fields : WoofWare.PawPrint.FieldInfo list
+
+ ///
+ /// The base type that this type inherits from, or None for types that don't have a base type
+ /// (like System.Object).
+ ///
BaseType : BaseTypeInfo option
+
+ ///
+ /// Attributes applied to this type, such as visibility, inheritance characteristics,
+ /// special handling, and other flags.
+ ///
TypeAttributes : TypeAttributes
+
+ ///
+ /// Custom attributes applied to this type.
+ ///
Attributes : WoofWare.PawPrint.CustomAttribute list
+
+ ///
+ /// The metadata token handle that uniquely identifies this type in the assembly.
+ ///
TypeDefHandle : TypeDefinitionHandle
}
diff --git a/WoofWare.PawPrint/TypeRef.fs b/WoofWare.PawPrint/TypeRef.fs
index 73f78f5..a518637 100644
--- a/WoofWare.PawPrint/TypeRef.fs
+++ b/WoofWare.PawPrint/TypeRef.fs
@@ -2,10 +2,25 @@ namespace WoofWare.PawPrint
open System.Reflection.Metadata
+///
+/// Represents a type reference in a .NET assembly metadata.
+/// This corresponds to a TypeReferenceHandle in System.Reflection.Metadata.
+///
type TypeRef =
{
+ /// The simple name of the referenced type (without namespace).
Name : string
+
+ /// The namespace of the referenced type, or empty string for nested types.
Namespace : string
+
+ ///
+ /// The scope of the type reference. This can be:
+ /// - AssemblyReference token: When the type is defined in another assembly
+ /// - ModuleReference token: When the type is defined in another module of the same assembly
+ /// - TypeReference token: When the type is a nested type
+ /// - ModuleDefinition token: When the type is defined in the current module
+ ///
ResolutionScope : WoofWare.PawPrint.MetadataToken
}
diff --git a/WoofWare.PawPrint/TypeSpec.fs b/WoofWare.PawPrint/TypeSpec.fs
index 8c83b78..e3450a0 100644
--- a/WoofWare.PawPrint/TypeSpec.fs
+++ b/WoofWare.PawPrint/TypeSpec.fs
@@ -2,9 +2,22 @@ namespace WoofWare.PawPrint
open System.Reflection.Metadata
+///
+/// Represents a type specification in assembly metadata.
+/// Type specifications describe complex types like generic instantiations,
+/// arrays, pointers, and other composite types.
+///
type TypeSpec =
{
+ ///
+ /// The metadata token handle that uniquely identifies this type specification.
+ ///
Handle : TypeSpecificationHandle
+
+ ///
+ /// The full type definition/signature of this type specification.
+ /// This contains all the details about the composite type structure.
+ ///
Signature : TypeDefn
}