/*
Copyright (C) 2014-2019 de4dot@gmail.com
This file is part of dnSpy
dnSpy is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
dnSpy is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with dnSpy. If not, see .
*/
using System;
using System.Collections.Generic;
namespace dnSpy.Debugger.DotNet.Metadata {
///
/// A .NET AppDomain
///
public abstract class DmdAppDomain : DmdObject {
///
/// Dummy abstract method to make sure no-one outside this assembly can create their own
///
private protected abstract void YouCantDeriveFromThisClass();
///
/// Gets the runtime
///
public abstract DmdRuntime Runtime { get; }
///
/// Gets the unique AppDomain id
///
public abstract int Id { get; }
///
/// Creates an assembly and adds it to the AppDomain. The first created assembly must be the corlib ()
///
/// Called to provide the metadata
/// true if the module is in memory ()
/// true if it's a dynamic module (types can be added at runtime) ()
/// The fully qualified name of the module (). See
/// Location of the assembly or an empty string ()
///
public DmdAssembly CreateAssembly(Func getMetadata, bool isInMemory, bool isDynamic, string fullyQualifiedName, string assemblyLocation) =>
CreateAssembly(getMetadata, isInMemory, isDynamic, fullyQualifiedName, assemblyLocation, assemblySimpleName: null, isSynthetic: false, addAssembly: true);
///
/// Creates a synthetic assembly but does not add it to the AppDomain
///
/// Called to provide the metadata
/// true if the module is in memory ()
/// true if it's a dynamic module (types can be added at runtime) ()
/// The fully qualified name of the module (). See
/// Location of the assembly or an empty string ()
/// The assembly's simple name or null if it's unknown
///
public DmdAssembly CreateSyntheticAssembly(Func getMetadata, bool isInMemory, bool isDynamic, string fullyQualifiedName, string assemblyLocation, string? assemblySimpleName) =>
CreateAssembly(getMetadata, isInMemory, isDynamic, fullyQualifiedName, assemblyLocation, assemblySimpleName: assemblySimpleName, isSynthetic: true, addAssembly: false);
///
/// Creates an assembly and optionally adds it to the AppDomain. The first created assembly must be the corlib ()
///
/// Called to provide the metadata
/// true if the module is in memory ()
/// true if it's a dynamic module (types can be added at runtime) ()
/// The fully qualified name of the module (). See
/// Location of the assembly or an empty string ()
/// The assembly's simple name or null if it's unknown
/// true if it's a synthetic assembly; it's not loaded in the debugged process
/// true if the assembly should be added to the AppDomain
///
public DmdAssembly CreateAssembly(Func getMetadata, bool isInMemory, bool isDynamic, string fullyQualifiedName, string assemblyLocation, string? assemblySimpleName, bool isSynthetic, bool addAssembly) =>
CreateAssembly(getMetadata, new DmdCreateAssemblyInfo(isInMemory, isDynamic, isSynthetic, addAssembly, fullyQualifiedName, assemblyLocation, assemblySimpleName));
///
/// Creates an assembly and optionally adds it to the AppDomain. The first created assembly must be the corlib ()
///
/// Called to provide the metadata
/// Assembly info
///
public abstract DmdAssembly CreateAssembly(Func getMetadata, DmdCreateAssemblyInfo assemblyInfo);
///
/// Creates an assembly. The first created assembly must be the corlib ()
///
/// Filename
/// true if file layout, false if memory layout
/// true if the module is in memory ()
/// true if it's a dynamic module (types can be added at runtime) ()
/// The fully qualified name of the module (). See
/// Location of the assembly or an empty string ()
///
public DmdAssembly CreateAssembly(string filename, bool isFileLayout = true, bool isInMemory = false, bool isDynamic = false, string? fullyQualifiedName = null, string? assemblyLocation = null) {
if (filename is null)
throw new ArgumentNullException(nameof(filename));
return CreateAssembly(() => new DmdLazyMetadataBytesFile(filename, isFileLayout), isInMemory, isDynamic, fullyQualifiedName ?? filename, assemblyLocation ?? filename);
}
///
/// Creates an assembly. The first created assembly must be the corlib ()
///
/// Address of PE file
/// Size of PE file
/// true if file layout, false if memory layout
/// true if the module is in memory ()
/// true if it's a dynamic module (types can be added at runtime) ()
/// The fully qualified name of the module (). See
/// Location of the assembly or an empty string ()
///
public DmdAssembly CreateAssembly(IntPtr address, uint size, bool isFileLayout, bool isInMemory, bool isDynamic, string fullyQualifiedName, string assemblyLocation) =>
CreateAssembly(() => new DmdLazyMetadataBytesPtr(address, size, isFileLayout), isInMemory, isDynamic, fullyQualifiedName, assemblyLocation);
///
/// Creates an assembly. The first created assembly must be the corlib ()
///
/// Raw PE file bytes
/// true if file layout, false if memory layout
/// true if the module is in memory ()
/// true if it's a dynamic module (types can be added at runtime) ()
/// The fully qualified name of the module (). See
/// Location of the assembly or an empty string ()
///
public DmdAssembly CreateAssembly(byte[] assemblyBytes, bool isFileLayout, bool isInMemory, bool isDynamic, string fullyQualifiedName, string assemblyLocation) {
if (assemblyBytes is null)
throw new ArgumentNullException(nameof(assemblyBytes));
return CreateAssembly(() => new DmdLazyMetadataBytesArray(assemblyBytes, isFileLayout), isInMemory, isDynamic, fullyQualifiedName, assemblyLocation);
}
///
/// Creates an assembly. The first created assembly must be the corlib ()
///
/// COM IMetaDataImport instance
/// Helper class
/// Dispatcher to use when accessing
/// true if the module is in memory ()
/// true if it's a dynamic module (types can be added at runtime) ()
/// The fully qualified name of the module (). See
/// Location of the assembly or an empty string ()
///
public DmdAssembly CreateAssembly(object comMetadata, DmdDynamicModuleHelper dynamicModuleHelper, DmdDispatcher dispatcher, bool isInMemory, bool isDynamic, string fullyQualifiedName, string? assemblyLocation = null) {
if (comMetadata is null)
throw new ArgumentNullException(nameof(comMetadata));
if (dynamicModuleHelper is null)
throw new ArgumentNullException(nameof(dynamicModuleHelper));
if (dispatcher is null)
throw new ArgumentNullException(nameof(dispatcher));
var mdi = comMetadata as Impl.COMD.IMetaDataImport2 ?? throw new ArgumentException("Only IMetaDataImport is supported");
return CreateAssembly(() => new DmdLazyMetadataBytesCom(mdi, dynamicModuleHelper, dispatcher), isInMemory, isDynamic, fullyQualifiedName, assemblyLocation ?? string.Empty);
}
///
/// Adds a module to an existing assembly
///
/// Assembly
/// Called to provide the metadata
/// true if the module is in memory ()
/// true if it's a dynamic module (types can be added at runtime) ()
/// The fully qualified name of the module (). See
///
public abstract DmdModule CreateModule(DmdAssembly assembly, Func getMetadata, bool isInMemory, bool isDynamic, string fullyQualifiedName);
///
/// Adds a module to an existing assembly
///
/// Assembly
/// Filename
/// true if file layout, false if memory layout
/// true if the module is in memory ()
/// true if it's a dynamic module (types can be added at runtime) ()
/// The fully qualified name of the module (). See
///
public DmdModule CreateModule(DmdAssembly assembly, string filename, bool isFileLayout = true, bool isInMemory = false, bool isDynamic = false, string? fullyQualifiedName = null) {
if (filename is null)
throw new ArgumentNullException(nameof(filename));
return CreateModule(assembly, () => new DmdLazyMetadataBytesFile(filename, isFileLayout), isInMemory, isDynamic, fullyQualifiedName ?? filename);
}
///
/// Adds a module to an existing assembly
///
/// Assembly
/// Address of the PE file
/// Size of the PE file
/// true if file layout, false if memory layout
/// true if the module is in memory ()
/// true if it's a dynamic module (types can be added at runtime) ()
/// The fully qualified name of the module (). See
///
public DmdModule CreateModule(DmdAssembly assembly, IntPtr address, uint size, bool isFileLayout, bool isInMemory, bool isDynamic, string fullyQualifiedName) =>
CreateModule(assembly, () => new DmdLazyMetadataBytesPtr(address, size, isFileLayout), isInMemory, isDynamic, fullyQualifiedName);
///
/// Adds a module to an existing assembly
///
/// Assembly
/// Raw PE file bytes
/// true if file layout, false if memory layout
/// true if the module is in memory ()
/// true if it's a dynamic module (types can be added at runtime) ()
/// The fully qualified name of the module (). See
///
public DmdModule CreateModule(DmdAssembly assembly, byte[] moduleBytes, bool isFileLayout, bool isInMemory, bool isDynamic, string fullyQualifiedName) {
if (moduleBytes is null)
throw new ArgumentNullException(nameof(moduleBytes));
return CreateModule(assembly, () => new DmdLazyMetadataBytesArray(moduleBytes, isFileLayout), isInMemory, isDynamic, fullyQualifiedName);
}
///
/// Adds a module to an existing assembly
///
/// Assembly
/// COM IMetaDataImport instance
/// Helper class
/// Dispatcher to use when accessing
/// true if the module is in memory ()
/// true if it's a dynamic module (types can be added at runtime) ()
/// The fully qualified name of the module (). See
///
public DmdModule CreateModule(DmdAssembly assembly, object comMetadata, DmdDynamicModuleHelper dynamicModuleHelper, DmdDispatcher dispatcher, bool isInMemory, bool isDynamic, string fullyQualifiedName) {
if (comMetadata is null)
throw new ArgumentNullException(nameof(comMetadata));
if (dynamicModuleHelper is null)
throw new ArgumentNullException(nameof(dynamicModuleHelper));
if (dispatcher is null)
throw new ArgumentNullException(nameof(dispatcher));
var mdi = comMetadata as Impl.COMD.IMetaDataImport2 ?? throw new ArgumentException("Only IMetaDataImport is supported");
return CreateModule(assembly, () => new DmdLazyMetadataBytesCom(mdi, dynamicModuleHelper, dispatcher), isInMemory, isDynamic, fullyQualifiedName);
}
///
/// Adds an assembly
///
/// Assembly to add
public abstract void Add(DmdAssembly assembly);
///
/// Removes an assembly
///
/// Assembly to remove
public abstract void Remove(DmdAssembly assembly);
///
/// Adds an assembly. It gets removed when the return value's method gets called
///
/// Assembly to add
///
public TemporaryAssemblyDisposable AddTemporaryAssembly(DmdAssembly assembly) => new TemporaryAssemblyDisposable(assembly);
///
/// Adds and removes an assembly
///
public readonly struct TemporaryAssemblyDisposable : IDisposable {
readonly DmdAssembly assembly;
internal TemporaryAssemblyDisposable(DmdAssembly assembly) {
this.assembly = assembly ?? throw new ArgumentNullException(nameof(assembly));
assembly.AppDomain.Add(assembly);
}
///
/// Dispose()
///
public void Dispose() => assembly.AppDomain.Remove(assembly);
}
///
/// Gets all assemblies
///
///
public DmdAssembly[] GetAssemblies() => GetAssemblies(includeSyntheticAssemblies: true);
///
/// Gets all assemblies
///
/// true to include synthetic assemblies
///
public abstract DmdAssembly[] GetAssemblies(bool includeSyntheticAssemblies);
///
/// Gets an assembly or returns null if there's no such assembly
///
/// Simple name of the assembly, eg. "System"
///
public abstract DmdAssembly? GetAssembly(string simpleName);
///
/// Gets an assembly or returns null if there's no such assembly
///
/// Assembly name
///
public abstract DmdAssembly? GetAssembly(IDmdAssemblyName name);
///
/// Loads an assembly
///
/// Evaluation context
/// Full assembly name
///
public DmdAssembly? Load(object? context, string assemblyName) => Load(context, new DmdReadOnlyAssemblyName(assemblyName));
///
/// Loads an assembly
///
/// Evaluation context
/// Assembly name
///
public abstract DmdAssembly? Load(object? context, IDmdAssemblyName name);
///
/// Loads an assembly. Will fail on .NET Core 1.x (but not on .NET Core 2.x or later)
///
/// Evaluation context
/// Assembly name or path to assembly
///
public abstract DmdAssembly? LoadFrom(object? context, string assemblyFile);
///
/// Loads an assembly. Will fail on .NET Core 1.x (but not on .NET Core 2.x or later)
///
/// Evaluation context
/// Path to assembly
///
public abstract DmdAssembly? LoadFile(object? context, string path);
///
/// Gets the core library (eg. mscorlib if it's .NET Framework)
///
public abstract DmdAssembly? CorLib { get; }
///
/// Checks if a well known type exists in one of the loaded assemblies
///
/// Well known type
///
public bool HasWellKnownType(DmdWellKnownType wellKnownType) => GetWellKnownType(wellKnownType, isOptional: true) is not null;
///
/// Gets a well known type
///
/// Well known type
///
public DmdType GetWellKnownType(DmdWellKnownType wellKnownType) => GetWellKnownType(wellKnownType, isOptional: false)!;
///
/// Gets a well known type
///
/// Well known type
/// Used if the type couldn't be found. If true, null is returned, and if false, an exception is thrown
///
public DmdType? GetWellKnownType(DmdWellKnownType wellKnownType, bool isOptional) =>
GetWellKnownType(wellKnownType, isOptional, onlyCorlib: false);
internal abstract DmdType? GetWellKnownType(DmdWellKnownType wellKnownType, bool isOptional, bool onlyCorlib);
#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member
public DmdType System_Object => GetWellKnownType(DmdWellKnownType.System_Object);
public DmdType System_Enum => GetWellKnownType(DmdWellKnownType.System_Enum);
public DmdType System_MulticastDelegate => GetWellKnownType(DmdWellKnownType.System_MulticastDelegate);
public DmdType System_Delegate => GetWellKnownType(DmdWellKnownType.System_Delegate);
public DmdType System_ValueType => GetWellKnownType(DmdWellKnownType.System_ValueType);
public DmdType System_Void => GetWellKnownType(DmdWellKnownType.System_Void);
public DmdType System_Boolean => GetWellKnownType(DmdWellKnownType.System_Boolean);
public DmdType System_Char => GetWellKnownType(DmdWellKnownType.System_Char);
public DmdType System_SByte => GetWellKnownType(DmdWellKnownType.System_SByte);
public DmdType System_Byte => GetWellKnownType(DmdWellKnownType.System_Byte);
public DmdType System_Int16 => GetWellKnownType(DmdWellKnownType.System_Int16);
public DmdType System_UInt16 => GetWellKnownType(DmdWellKnownType.System_UInt16);
public DmdType System_Int32 => GetWellKnownType(DmdWellKnownType.System_Int32);
public DmdType System_UInt32 => GetWellKnownType(DmdWellKnownType.System_UInt32);
public DmdType System_Int64 => GetWellKnownType(DmdWellKnownType.System_Int64);
public DmdType System_UInt64 => GetWellKnownType(DmdWellKnownType.System_UInt64);
public DmdType System_Decimal => GetWellKnownType(DmdWellKnownType.System_Decimal);
public DmdType System_Single => GetWellKnownType(DmdWellKnownType.System_Single);
public DmdType System_Double => GetWellKnownType(DmdWellKnownType.System_Double);
public DmdType System_String => GetWellKnownType(DmdWellKnownType.System_String);
public DmdType System_IntPtr => GetWellKnownType(DmdWellKnownType.System_IntPtr);
public DmdType System_UIntPtr => GetWellKnownType(DmdWellKnownType.System_UIntPtr);
public DmdType System_Array => GetWellKnownType(DmdWellKnownType.System_Array);
public DmdType System_Collections_IEnumerable => GetWellKnownType(DmdWellKnownType.System_Collections_IEnumerable);
public DmdType System_Collections_Generic_IEnumerable_T => GetWellKnownType(DmdWellKnownType.System_Collections_Generic_IEnumerable_T);
public DmdType System_Collections_Generic_IList_T => GetWellKnownType(DmdWellKnownType.System_Collections_Generic_IList_T);
public DmdType System_Collections_Generic_ICollection_T => GetWellKnownType(DmdWellKnownType.System_Collections_Generic_ICollection_T);
public DmdType System_Collections_IEnumerator => GetWellKnownType(DmdWellKnownType.System_Collections_IEnumerator);
public DmdType System_Collections_Generic_IEnumerator_T => GetWellKnownType(DmdWellKnownType.System_Collections_Generic_IEnumerator_T);
public DmdType System_Collections_Generic_IReadOnlyList_T => GetWellKnownType(DmdWellKnownType.System_Collections_Generic_IReadOnlyList_T);
public DmdType System_Collections_Generic_IReadOnlyCollection_T => GetWellKnownType(DmdWellKnownType.System_Collections_Generic_IReadOnlyCollection_T);
public DmdType System_Nullable_T => GetWellKnownType(DmdWellKnownType.System_Nullable_T);
public DmdType System_DateTime => GetWellKnownType(DmdWellKnownType.System_DateTime);
public DmdType System_Runtime_CompilerServices_IsVolatile => GetWellKnownType(DmdWellKnownType.System_Runtime_CompilerServices_IsVolatile);
public DmdType System_IDisposable => GetWellKnownType(DmdWellKnownType.System_IDisposable);
public DmdType System_TypedReference => GetWellKnownType(DmdWellKnownType.System_TypedReference);
public DmdType System_ArgIterator => GetWellKnownType(DmdWellKnownType.System_ArgIterator);
public DmdType System_RuntimeArgumentHandle => GetWellKnownType(DmdWellKnownType.System_RuntimeArgumentHandle);
public DmdType System_RuntimeFieldHandle => GetWellKnownType(DmdWellKnownType.System_RuntimeFieldHandle);
public DmdType System_RuntimeMethodHandle => GetWellKnownType(DmdWellKnownType.System_RuntimeMethodHandle);
public DmdType System_RuntimeTypeHandle => GetWellKnownType(DmdWellKnownType.System_RuntimeTypeHandle);
public DmdType System_IAsyncResult => GetWellKnownType(DmdWellKnownType.System_IAsyncResult);
public DmdType System_AsyncCallback => GetWellKnownType(DmdWellKnownType.System_AsyncCallback);
public DmdType System_Type => GetWellKnownType(DmdWellKnownType.System_Type);
#pragma warning restore CS1591 // Missing XML comment for publicly visible type or member
///
/// Returns a cached type if present else the input type
///
/// Type
/// Options
///
public abstract DmdType Intern(DmdType type, DmdMakeTypeOptions options = DmdMakeTypeOptions.None);
///
/// Makes a pointer type
///
/// Element type
/// Custom modifiers or null
/// Options
///
public abstract DmdType MakePointerType(DmdType elementType, IList? customModifiers, DmdMakeTypeOptions options = DmdMakeTypeOptions.None);
///
/// Makes a by-ref type
///
/// Element type
/// Custom modifiers or null
/// Options
///
public abstract DmdType MakeByRefType(DmdType elementType, IList? customModifiers, DmdMakeTypeOptions options = DmdMakeTypeOptions.None);
///
/// Makes a SZ array type
///
/// Element type
/// Custom modifiers or null
/// Options
///
public abstract DmdType MakeArrayType(DmdType elementType, IList? customModifiers, DmdMakeTypeOptions options = DmdMakeTypeOptions.None);
///
/// Makes a multi-dimensional array type
///
/// Element type
/// Number of dimensions
/// Sizes
/// Lower bounds
/// Custom modifiers or null
/// Options
///
public abstract DmdType MakeArrayType(DmdType elementType, int rank, IList sizes, IList lowerBounds, IList? customModifiers, DmdMakeTypeOptions options = DmdMakeTypeOptions.None);
///
/// Makes a generic type
///
/// Generic type definition
/// Generic arguments
/// Custom modifiers or null
/// Options
///
public abstract DmdType MakeGenericType(DmdType genericTypeDefinition, IList typeArguments, IList? customModifiers, DmdMakeTypeOptions options = DmdMakeTypeOptions.None);
///
/// Makes a generic method
///
/// Generic method definition
/// Generic arguments
/// Options
///
public abstract DmdMethodInfo MakeGenericMethod(DmdMethodInfo genericMethodDefinition, IList typeArguments, DmdMakeTypeOptions options = DmdMakeTypeOptions.None);
///
/// Makes a function pointer type
///
/// Method signature
/// Custom modifiers or null
/// Options
///
public abstract DmdType MakeFunctionPointerType(DmdMethodSignature methodSignature, IList? customModifiers, DmdMakeTypeOptions options = DmdMakeTypeOptions.None);
///
/// Makes a function pointer type
///
/// Flags
/// Number of generic parameters
/// Return type
/// Parameter types
/// VarArgs parameter types
/// Custom modifiers or null
/// Options
///
public abstract DmdType MakeFunctionPointerType(DmdSignatureCallingConvention flags, int genericParameterCount, DmdType returnType, IList parameterTypes, IList varArgsParameterTypes, IList? customModifiers, DmdMakeTypeOptions options = DmdMakeTypeOptions.None);
///
/// Makes a generic type parameter
///
/// Position
/// Declaring type
///
public DmdType MakeGenericTypeParameter(int position, DmdType declaringType) => MakeGenericTypeParameter(position, declaringType, string.Empty, 0, null);
///
/// Makes a generic type parameter
///
/// Position
/// Declaring type
/// Name
/// Attributes
/// Custom modifiers or null
/// Options
///
public abstract DmdType MakeGenericTypeParameter(int position, DmdType declaringType, string name, DmdGenericParameterAttributes attributes, IList? customModifiers, DmdMakeTypeOptions options = DmdMakeTypeOptions.None);
///
/// Makes a generic method parameter
///
/// Position
/// Declaring method
///
public DmdType MakeGenericMethodParameter(int position, DmdMethodBase declaringMethod) => MakeGenericMethodParameter(position, declaringMethod, string.Empty, 0, null);
///
/// Makes a generic method parameter
///
/// Position
/// Declaring method
/// Name
/// Attributes
/// Custom modifiers or null
/// Options
///
public abstract DmdType MakeGenericMethodParameter(int position, DmdMethodBase declaringMethod, string name, DmdGenericParameterAttributes attributes, IList? customModifiers, DmdMakeTypeOptions options = DmdMakeTypeOptions.None);
///
/// Gets a type
///
/// Type
///
public DmdType? GetType(Type type) => GetType(type, DmdGetTypeOptions.None);
///
/// Gets a type and throws if it couldn't be found
///
///
///
public DmdType GetTypeThrow(Type type) => GetType(type, DmdGetTypeOptions.ThrowOnError)!;
///
/// Gets a type
///
/// Type
/// Options
///
public DmdType? GetType(Type type, DmdGetTypeOptions options) {
if (type is null)
throw new ArgumentNullException(nameof(type));
var assemblyQualifiedName = type.AssemblyQualifiedName ?? throw new ArgumentException();
return GetType(assemblyQualifiedName, options);
}
///
/// Gets a type
///
/// Full name of the type () or the assembly qualified name ().
/// Version, public key token and culture are optional.
/// Options
///
public abstract DmdType? GetType(string typeName, DmdGetTypeOptions options);
///
/// Gets a type
///
/// Full name of the type () or the assembly qualified name ().
/// Version, public key token and culture are optional.
///
public DmdType? GetType(string typeName) => GetType(typeName, DmdGetTypeOptions.None);
///
/// Gets a type and throws if it couldn't be found
///
/// Full name of the type () or the assembly qualified name ().
/// Version, public key token and culture are optional.
///
public DmdType GetTypeThrow(string typeName) => GetType(typeName, DmdGetTypeOptions.ThrowOnError)!;
///
/// Creates a new instance of a type
///
/// Evaluation context
/// Constructor
/// Parameters passed to the method
///
public abstract object? CreateInstance(object? context, DmdConstructorInfo ctor, object?[] parameters);
///
/// Executes a method
///
/// Evaluation context
/// Method to call
/// Instance object or null if it's a static method
/// Parameters passed to the method
///
public abstract object? Invoke(object? context, DmdMethodBase method, object? obj, object?[]? parameters);
///
/// Loads a field
///
/// Evaluation context
/// Field
/// Instance object or null if it's a static field
///
public abstract object? LoadField(object? context, DmdFieldInfo field, object? obj);
///
/// Stores a value in a field
///
/// Evaluation context
/// Field
/// Instance object or null if it's a static field
/// Value to store in the field
public abstract void StoreField(object? context, DmdFieldInfo field, object? obj, object? value);
}
///
/// Options used when creating types
///
[Flags]
public enum DmdMakeTypeOptions {
///
/// No bit is set
///
None = 0,
///
/// Don't try to resolve a reference
///
NoResolve = 0x00000001,
}
///
/// Options used when finding a type
///
[Flags]
public enum DmdGetTypeOptions {
///
/// No bit is set
///
None = 0,
///
/// Throw if the type couldn't be found
///
ThrowOnError = 0x00000001,
///
/// Ignore case
///
IgnoreCase = 0x00000002,
}
///
/// Create-assembly-options
///
public enum DmdCreateAssemblyOptions {
///
/// No bit is set
///
None = 0,
///
/// Set if the module is in memory ()
///
InMemory = 0x00000001,
///
/// Set if it's a dynamic module (types can be added at runtime) ()
///
Dynamic = 0x00000002,
///
/// Synthetic assembly, eg. created by the expression compiler
///
Synthetic = 0x00000004,
///
/// Don't add the assembly to the AppDomain
///
DontAddAssembly = 0x00000008,
///
/// It's an exe file. If it's not set, it's either a DLL or it's unknown
///
IsEXE = 0x00000010,
///
/// It's a dll file. If it's not set, it's either an EXE or it's unknown
///
IsDLL = 0x00000020,
}
///
/// Info needed when creating an assembly
///
public readonly struct DmdCreateAssemblyInfo {
///
/// Gets the options
///
public DmdCreateAssemblyOptions Options { get; }
///
/// The fully qualified name of the module (). See
///
public string FullyQualifiedName { get; }
///
/// Location of the assembly or an empty string ()
///
public string AssemblyLocation { get; }
///
/// Gets the assembly's simple name or null if it's unknown
///
public string? AssemblySimpleName { get; }
///
/// Constructor
///
/// Options
/// The fully qualified name of the module (). See
/// Location of the assembly or an empty string ()
/// The assembly's simple name or null if it's unknown
public DmdCreateAssemblyInfo(DmdCreateAssemblyOptions options, string fullyQualifiedName, string assemblyLocation, string? assemblySimpleName) {
if ((options & (DmdCreateAssemblyOptions.IsEXE | DmdCreateAssemblyOptions.IsDLL)) == (DmdCreateAssemblyOptions.IsEXE | DmdCreateAssemblyOptions.IsDLL))
throw new ArgumentException();
Options = options;
FullyQualifiedName = fullyQualifiedName ?? throw new ArgumentNullException(nameof(fullyQualifiedName));
AssemblyLocation = assemblyLocation ?? throw new ArgumentNullException(nameof(assemblyLocation));
AssemblySimpleName = assemblySimpleName;
}
///
/// Constructor
///
/// true if the module is in memory ()
/// true if it's a dynamic module (types can be added at runtime) ()
/// true if it's a synthetic assembly, eg. created by the expression compiler
/// true if the assembly should be added to the AppDomain
/// The fully qualified name of the module (). See
/// Location of the assembly or an empty string ()
/// The assembly's simple name or null if it's unknown
public DmdCreateAssemblyInfo(bool isInMemory, bool isDynamic, bool isSynthetic, bool addAssembly, string fullyQualifiedName, string assemblyLocation, string? assemblySimpleName)
: this(GetOptions(isInMemory, isDynamic, isSynthetic, addAssembly), fullyQualifiedName, assemblyLocation, assemblySimpleName) {
}
static DmdCreateAssemblyOptions GetOptions(bool isInMemory, bool isDynamic, bool isSynthetic, bool addAssembly) {
var options = DmdCreateAssemblyOptions.None;
if (isInMemory)
options |= DmdCreateAssemblyOptions.InMemory;
if (isDynamic)
options |= DmdCreateAssemblyOptions.Dynamic;
if (isSynthetic)
options |= DmdCreateAssemblyOptions.Synthetic;
if (!addAssembly)
options |= DmdCreateAssemblyOptions.DontAddAssembly;
return options;
}
}
}