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 }