// dnlib: See LICENSE.txt for more info using System.Collections.Generic; /* All signature classes: CallingConventionSig FieldSig MethodBaseSig MethodSig PropertySig LocalSig GenericInstMethodSig */ namespace dnlib.DotNet { /// /// Base class for sigs with a calling convention /// public abstract class CallingConventionSig : IContainsGenericParameter { /// /// The calling convention /// protected CallingConvention callingConvention; byte[] extraData; /// /// Gets/sets the extra data found after the signature /// public byte[] ExtraData { get => extraData; set => extraData = value; } /// /// Returns true if is set /// public bool IsDefault => (callingConvention & CallingConvention.Mask) == CallingConvention.Default; /// /// Returns true if is set /// public bool IsC => (callingConvention & CallingConvention.Mask) == CallingConvention.C; /// /// Returns true if is set /// public bool IsStdCall => (callingConvention & CallingConvention.Mask) == CallingConvention.StdCall; /// /// Returns true if is set /// public bool IsThisCall => (callingConvention & CallingConvention.Mask) == CallingConvention.ThisCall; /// /// Returns true if is set /// public bool IsFastCall => (callingConvention & CallingConvention.Mask) == CallingConvention.FastCall; /// /// Returns true if is set /// public bool IsVarArg => (callingConvention & CallingConvention.Mask) == CallingConvention.VarArg; /// /// Returns true if is set /// public bool IsField => (callingConvention & CallingConvention.Mask) == CallingConvention.Field; /// /// Returns true if is set /// public bool IsLocalSig => (callingConvention & CallingConvention.Mask) == CallingConvention.LocalSig; /// /// Returns true if is set /// public bool IsProperty => (callingConvention & CallingConvention.Mask) == CallingConvention.Property; /// /// Returns true if is set /// public bool IsUnmanaged => (callingConvention & CallingConvention.Mask) == CallingConvention.Unmanaged; /// /// Returns true if is set /// public bool IsGenericInst => (callingConvention & CallingConvention.Mask) == CallingConvention.GenericInst; /// /// Returns true if is set /// public bool IsNativeVarArg => (callingConvention & CallingConvention.Mask) == CallingConvention.NativeVarArg; /// /// Gets/sets the bit /// public bool Generic { get => (callingConvention & CallingConvention.Generic) != 0; set { if (value) callingConvention |= CallingConvention.Generic; else callingConvention &= ~CallingConvention.Generic; } } /// /// Gets/sets the bit /// public bool HasThis { get => (callingConvention & CallingConvention.HasThis) != 0; set { if (value) callingConvention |= CallingConvention.HasThis; else callingConvention &= ~CallingConvention.HasThis; } } /// /// Gets/sets the bit /// public bool ExplicitThis { get => (callingConvention & CallingConvention.ExplicitThis) != 0; set { if (value) callingConvention |= CallingConvention.ExplicitThis; else callingConvention &= ~CallingConvention.ExplicitThis; } } /// /// Gets/sets the bit /// public bool ReservedByCLR { get => (callingConvention & CallingConvention.ReservedByCLR) != 0; set { if (value) callingConvention |= CallingConvention.ReservedByCLR; else callingConvention &= ~CallingConvention.ReservedByCLR; } } /// /// true if there's an implicit this parameter /// public bool ImplicitThis => HasThis && !ExplicitThis; /// /// true if this contains a /// or a . /// public bool ContainsGenericParameter => TypeHelper.ContainsGenericParameter(this); /// /// Default constructor /// protected CallingConventionSig() { } /// /// Constructor /// /// The calling convention protected CallingConventionSig(CallingConvention callingConvention) => this.callingConvention = callingConvention; /// /// Gets the calling convention /// public CallingConvention GetCallingConvention() => callingConvention; } /// /// A field signature /// public sealed class FieldSig : CallingConventionSig { TypeSig type; /// /// Gets/sets the field type /// public TypeSig Type { get => type; set => type = value; } /// /// Default constructor /// public FieldSig() => callingConvention = CallingConvention.Field; /// /// Constructor /// /// Field type public FieldSig(TypeSig type) { callingConvention = CallingConvention.Field; this.type = type; } /// /// Constructor /// /// Field type /// The calling convention (must have Field set) internal FieldSig(CallingConvention callingConvention, TypeSig type) { this.callingConvention = callingConvention; this.type = type; } /// /// Clone this /// public FieldSig Clone() => new FieldSig(callingConvention, type); /// public override string ToString() => FullNameFactory.FullName(type, false, null, null, null, null); } /// /// Method sig base class /// public abstract class MethodBaseSig : CallingConventionSig { /// protected TypeSig retType; /// protected IList parameters; /// protected uint genParamCount; /// protected IList paramsAfterSentinel; /// /// Gets/sets the calling convention /// public CallingConvention CallingConvention { get => callingConvention; set => callingConvention = value; } /// /// Gets/sets the return type /// public TypeSig RetType { get => retType; set => retType = value; } /// /// Gets the parameters. This is never null /// public IList Params => parameters; /// /// Gets/sets the generic param count /// public uint GenParamCount { get => genParamCount; set => genParamCount = value; } /// /// Gets the parameters that are present after the sentinel. Note that this is null /// if there's no sentinel. It can still be empty even if it's not null. /// public IList ParamsAfterSentinel { get => paramsAfterSentinel; set => paramsAfterSentinel = value; } } /// /// A method signature /// public sealed class MethodSig : MethodBaseSig { uint origToken; /// /// Gets/sets the original token. It's set when reading calli instruction operands /// and it's a hint to the module writer if it tries to re-use the same token. /// public uint OriginalToken { get => origToken; set => origToken = value; } /// /// Creates a static MethodSig /// /// Return type public static MethodSig CreateStatic(TypeSig retType) => new MethodSig(CallingConvention.Default, 0, retType); /// /// Creates a static MethodSig /// /// Return type /// Arg type #1 public static MethodSig CreateStatic(TypeSig retType, TypeSig argType1) => new MethodSig(CallingConvention.Default, 0, retType, argType1); /// /// Creates a static MethodSig /// /// Return type /// Arg type #1 /// Arg type #2 public static MethodSig CreateStatic(TypeSig retType, TypeSig argType1, TypeSig argType2) => new MethodSig(CallingConvention.Default, 0, retType, argType1, argType2); /// /// Creates a static MethodSig /// /// Return type /// Arg type #1 /// Arg type #2 /// Arg type #3 public static MethodSig CreateStatic(TypeSig retType, TypeSig argType1, TypeSig argType2, TypeSig argType3) => new MethodSig(CallingConvention.Default, 0, retType, argType1, argType2, argType3); /// /// Creates a static MethodSig /// /// Return type /// Argument types public static MethodSig CreateStatic(TypeSig retType, params TypeSig[] argTypes) => new MethodSig(CallingConvention.Default, 0, retType, argTypes); /// /// Creates an instance MethodSig /// /// Return type public static MethodSig CreateInstance(TypeSig retType) => new MethodSig(CallingConvention.Default | CallingConvention.HasThis, 0, retType); /// /// Creates an instance MethodSig /// /// Return type /// Arg type #1 public static MethodSig CreateInstance(TypeSig retType, TypeSig argType1) => new MethodSig(CallingConvention.Default | CallingConvention.HasThis, 0, retType, argType1); /// /// Creates an instance MethodSig /// /// Return type /// Arg type #1 /// Arg type #2 public static MethodSig CreateInstance(TypeSig retType, TypeSig argType1, TypeSig argType2) => new MethodSig(CallingConvention.Default | CallingConvention.HasThis, 0, retType, argType1, argType2); /// /// Creates an instance MethodSig /// /// Return type /// Arg type #1 /// Arg type #2 /// Arg type #3 public static MethodSig CreateInstance(TypeSig retType, TypeSig argType1, TypeSig argType2, TypeSig argType3) => new MethodSig(CallingConvention.Default | CallingConvention.HasThis, 0, retType, argType1, argType2, argType3); /// /// Creates an instance MethodSig /// /// Return type /// Argument types public static MethodSig CreateInstance(TypeSig retType, params TypeSig[] argTypes) => new MethodSig(CallingConvention.Default | CallingConvention.HasThis, 0, retType, argTypes); /// /// Creates a static generic MethodSig /// /// Number of generic parameters /// Return type public static MethodSig CreateStaticGeneric(uint genParamCount, TypeSig retType) => new MethodSig(CallingConvention.Default | CallingConvention.Generic, genParamCount, retType); /// /// Creates a static generic MethodSig /// /// Number of generic parameters /// Return type /// Arg type #1 public static MethodSig CreateStaticGeneric(uint genParamCount, TypeSig retType, TypeSig argType1) => new MethodSig(CallingConvention.Default | CallingConvention.Generic, genParamCount, retType, argType1); /// /// Creates a static generic MethodSig /// /// Number of generic parameters /// Return type /// Arg type #1 /// Arg type #2 public static MethodSig CreateStaticGeneric(uint genParamCount, TypeSig retType, TypeSig argType1, TypeSig argType2) => new MethodSig(CallingConvention.Default | CallingConvention.Generic, genParamCount, retType, argType1, argType2); /// /// Creates a static generic MethodSig /// /// Number of generic parameters /// Return type /// Arg type #1 /// Arg type #2 /// Arg type #3 public static MethodSig CreateStaticGeneric(uint genParamCount, TypeSig retType, TypeSig argType1, TypeSig argType2, TypeSig argType3) => new MethodSig(CallingConvention.Default | CallingConvention.Generic, genParamCount, retType, argType1, argType2, argType3); /// /// Creates a static generic MethodSig /// /// Number of generic parameters /// Return type /// Argument types public static MethodSig CreateStaticGeneric(uint genParamCount, TypeSig retType, params TypeSig[] argTypes) => new MethodSig(CallingConvention.Default | CallingConvention.Generic, genParamCount, retType, argTypes); /// /// Creates an instance generic MethodSig /// /// Number of generic parameters /// Return type public static MethodSig CreateInstanceGeneric(uint genParamCount, TypeSig retType) => new MethodSig(CallingConvention.Default | CallingConvention.HasThis | CallingConvention.Generic, genParamCount, retType); /// /// Creates an instance generic MethodSig /// /// Number of generic parameters /// Return type /// Arg type #1 public static MethodSig CreateInstanceGeneric(uint genParamCount, TypeSig retType, TypeSig argType1) => new MethodSig(CallingConvention.Default | CallingConvention.HasThis | CallingConvention.Generic, genParamCount, retType, argType1); /// /// Creates an instance generic MethodSig /// /// Number of generic parameters /// Return type /// Arg type #1 /// Arg type #2 public static MethodSig CreateInstanceGeneric(uint genParamCount, TypeSig retType, TypeSig argType1, TypeSig argType2) => new MethodSig(CallingConvention.Default | CallingConvention.HasThis | CallingConvention.Generic, genParamCount, retType, argType1, argType2); /// /// Creates an instance generic MethodSig /// /// Number of generic parameters /// Return type /// Arg type #1 /// Arg type #2 /// Arg type #3 public static MethodSig CreateInstanceGeneric(uint genParamCount, TypeSig retType, TypeSig argType1, TypeSig argType2, TypeSig argType3) => new MethodSig(CallingConvention.Default | CallingConvention.HasThis | CallingConvention.Generic, genParamCount, retType, argType1, argType2, argType3); /// /// Creates an instance generic MethodSig /// /// Number of generic parameters /// Return type /// Argument types public static MethodSig CreateInstanceGeneric(uint genParamCount, TypeSig retType, params TypeSig[] argTypes) => new MethodSig(CallingConvention.Default | CallingConvention.HasThis | CallingConvention.Generic, genParamCount, retType, argTypes); /// /// Default constructor /// public MethodSig() => parameters = new List(); /// /// Constructor /// /// Calling convention public MethodSig(CallingConvention callingConvention) { this.callingConvention = callingConvention; parameters = new List(); } /// /// Constructor /// /// Calling convention /// Number of generic parameters public MethodSig(CallingConvention callingConvention, uint genParamCount) { this.callingConvention = callingConvention; this.genParamCount = genParamCount; parameters = new List(); } /// /// Constructor /// /// Calling convention /// Number of generic parameters /// Return type public MethodSig(CallingConvention callingConvention, uint genParamCount, TypeSig retType) { this.callingConvention = callingConvention; this.genParamCount = genParamCount; this.retType = retType; parameters = new List(); } /// /// Constructor /// /// Calling convention /// Number of generic parameters /// Return type /// Arg type #1 public MethodSig(CallingConvention callingConvention, uint genParamCount, TypeSig retType, TypeSig argType1) { this.callingConvention = callingConvention; this.genParamCount = genParamCount; this.retType = retType; parameters = new List { argType1 }; } /// /// Constructor /// /// Calling convention /// Number of generic parameters /// Return type /// Arg type #1 /// Arg type #2 public MethodSig(CallingConvention callingConvention, uint genParamCount, TypeSig retType, TypeSig argType1, TypeSig argType2) { this.callingConvention = callingConvention; this.genParamCount = genParamCount; this.retType = retType; parameters = new List { argType1, argType2 }; } /// /// Constructor /// /// Calling convention /// Number of generic parameters /// Return type /// Arg type #1 /// Arg type #2 /// Arg type #3 public MethodSig(CallingConvention callingConvention, uint genParamCount, TypeSig retType, TypeSig argType1, TypeSig argType2, TypeSig argType3) { this.callingConvention = callingConvention; this.genParamCount = genParamCount; this.retType = retType; parameters = new List { argType1, argType2, argType3 }; } /// /// Constructor /// /// Calling convention /// Number of generic parameters /// Return type /// Argument types public MethodSig(CallingConvention callingConvention, uint genParamCount, TypeSig retType, params TypeSig[] argTypes) { this.callingConvention = callingConvention; this.genParamCount = genParamCount; this.retType = retType; parameters = new List(argTypes); } /// /// Constructor /// /// Calling convention /// Number of generic parameters /// Return type /// Argument types public MethodSig(CallingConvention callingConvention, uint genParamCount, TypeSig retType, IList argTypes) { this.callingConvention = callingConvention; this.genParamCount = genParamCount; this.retType = retType; parameters = new List(argTypes); } /// /// Constructor /// /// Calling convention /// Number of generic parameters /// Return type /// Argument types /// Parameters after sentinel public MethodSig(CallingConvention callingConvention, uint genParamCount, TypeSig retType, IList argTypes, IList paramsAfterSentinel) { this.callingConvention = callingConvention; this.genParamCount = genParamCount; this.retType = retType; parameters = new List(argTypes); this.paramsAfterSentinel = paramsAfterSentinel is null ? null : new List(paramsAfterSentinel); } /// /// Clone this /// public MethodSig Clone() => new MethodSig(callingConvention, genParamCount, retType, parameters, paramsAfterSentinel); /// public override string ToString() => FullNameFactory.MethodBaseSigFullName(this, null); } /// /// A property signature /// public sealed class PropertySig : MethodBaseSig { /// /// Creates a static PropertySig /// /// Return type public static PropertySig CreateStatic(TypeSig retType) => new PropertySig(false, retType); /// /// Creates a static PropertySig /// /// Return type /// Arg type #1 public static PropertySig CreateStatic(TypeSig retType, TypeSig argType1) => new PropertySig(false, retType, argType1); /// /// Creates a static PropertySig /// /// Return type /// Arg type #1 /// Arg type #2 public static PropertySig CreateStatic(TypeSig retType, TypeSig argType1, TypeSig argType2) => new PropertySig(false, retType, argType1, argType2); /// /// Creates a static PropertySig /// /// Return type /// Arg type #1 /// Arg type #2 /// Arg type #3 public static PropertySig CreateStatic(TypeSig retType, TypeSig argType1, TypeSig argType2, TypeSig argType3) => new PropertySig(false, retType, argType1, argType2, argType3); /// /// Creates a static PropertySig /// /// Return type /// Argument types public static PropertySig CreateStatic(TypeSig retType, params TypeSig[] argTypes) => new PropertySig(false, retType, argTypes); /// /// Creates an instance PropertySig /// /// Return type public static PropertySig CreateInstance(TypeSig retType) => new PropertySig(true, retType); /// /// Creates an instance PropertySig /// /// Return type /// Arg type #1 public static PropertySig CreateInstance(TypeSig retType, TypeSig argType1) => new PropertySig(true, retType, argType1); /// /// Creates an instance PropertySig /// /// Return type /// Arg type #1 /// Arg type #2 public static PropertySig CreateInstance(TypeSig retType, TypeSig argType1, TypeSig argType2) => new PropertySig(true, retType, argType1, argType2); /// /// Creates an instance PropertySig /// /// Return type /// Arg type #1 /// Arg type #2 /// Arg type #3 public static PropertySig CreateInstance(TypeSig retType, TypeSig argType1, TypeSig argType2, TypeSig argType3) => new PropertySig(true, retType, argType1, argType2, argType3); /// /// Creates an instance PropertySig /// /// Return type /// Argument types public static PropertySig CreateInstance(TypeSig retType, params TypeSig[] argTypes) => new PropertySig(true, retType, argTypes); /// /// Default constructor /// public PropertySig() { callingConvention = CallingConvention.Property; parameters = new List(); } /// /// Constructor /// /// Calling convention (must have Property set) internal PropertySig(CallingConvention callingConvention) { this.callingConvention = callingConvention; parameters = new List(); } /// /// Constructor /// /// true if instance, false if static public PropertySig(bool hasThis) { callingConvention = CallingConvention.Property | (hasThis ? CallingConvention.HasThis : 0); parameters = new List(); } /// /// Constructor /// /// true if instance, false if static /// Return type public PropertySig(bool hasThis, TypeSig retType) { callingConvention = CallingConvention.Property | (hasThis ? CallingConvention.HasThis : 0); this.retType = retType; parameters = new List(); } /// /// Constructor /// /// true if instance, false if static /// Return type /// Arg type #1 public PropertySig(bool hasThis, TypeSig retType, TypeSig argType1) { callingConvention = CallingConvention.Property | (hasThis ? CallingConvention.HasThis : 0); this.retType = retType; parameters = new List { argType1 }; } /// /// Constructor /// /// true if instance, false if static /// Return type /// Arg type #1 /// Arg type #2 public PropertySig(bool hasThis, TypeSig retType, TypeSig argType1, TypeSig argType2) { callingConvention = CallingConvention.Property | (hasThis ? CallingConvention.HasThis : 0); this.retType = retType; parameters = new List { argType1, argType2 }; } /// /// Constructor /// /// true if instance, false if static /// Return type /// Arg type #1 /// Arg type #2 /// Arg type #3 public PropertySig(bool hasThis, TypeSig retType, TypeSig argType1, TypeSig argType2, TypeSig argType3) { callingConvention = CallingConvention.Property | (hasThis ? CallingConvention.HasThis : 0); this.retType = retType; parameters = new List { argType1, argType2, argType3 }; } /// /// Constructor /// /// true if instance, false if static /// Return type /// Argument types public PropertySig(bool hasThis, TypeSig retType, params TypeSig[] argTypes) { callingConvention = CallingConvention.Property | (hasThis ? CallingConvention.HasThis : 0); this.retType = retType; parameters = new List(argTypes); } /// /// Constructor /// /// Calling convention /// Number of generic parameters /// Return type /// Argument types /// Parameters after sentinel internal PropertySig(CallingConvention callingConvention, uint genParamCount, TypeSig retType, IList argTypes, IList paramsAfterSentinel) { this.callingConvention = callingConvention; this.genParamCount = genParamCount; this.retType = retType; parameters = new List(argTypes); this.paramsAfterSentinel = paramsAfterSentinel is null ? null : new List(paramsAfterSentinel); } /// /// Clone this /// public PropertySig Clone() => new PropertySig(callingConvention, genParamCount, retType, parameters, paramsAfterSentinel); /// public override string ToString() => FullNameFactory.MethodBaseSigFullName(this, null); } /// /// A local variables signature /// public sealed class LocalSig : CallingConventionSig { readonly IList locals; /// /// All local types. This is never null. /// public IList Locals => locals; /// /// Default constructor /// public LocalSig() { callingConvention = CallingConvention.LocalSig; locals = new List(); } /// /// Constructor /// /// Calling convention (must have LocalSig set) /// Number of locals internal LocalSig(CallingConvention callingConvention, uint count) { this.callingConvention = callingConvention; locals = new List((int)count); } /// /// Constructor /// /// Local type #1 public LocalSig(TypeSig local1) { callingConvention = CallingConvention.LocalSig; locals = new List { local1 }; } /// /// Constructor /// /// Local type #1 /// Local type #2 public LocalSig(TypeSig local1, TypeSig local2) { callingConvention = CallingConvention.LocalSig; locals = new List { local1, local2 }; } /// /// Constructor /// /// Local type #1 /// Local type #2 /// Local type #3 public LocalSig(TypeSig local1, TypeSig local2, TypeSig local3) { callingConvention = CallingConvention.LocalSig; locals = new List { local1, local2, local3 }; } /// /// Constructor /// /// All locals public LocalSig(params TypeSig[] locals) { callingConvention = CallingConvention.LocalSig; this.locals = new List(locals); } /// /// Constructor /// /// All locals public LocalSig(IList locals) { callingConvention = CallingConvention.LocalSig; this.locals = new List(locals); } /// /// Constructor /// /// All locals (this instance now owns it) /// Dummy internal LocalSig(IList locals, bool dummy) { callingConvention = CallingConvention.LocalSig; this.locals = locals; } /// /// Clone this /// public LocalSig Clone() => new LocalSig(locals); } /// /// An instantiated generic method signature /// public sealed class GenericInstMethodSig : CallingConventionSig { readonly IList genericArgs; /// /// Gets the generic arguments (must be instantiated types, i.e., closed types) /// public IList GenericArguments => genericArgs; /// /// Default constructor /// public GenericInstMethodSig() { callingConvention = CallingConvention.GenericInst; genericArgs = new List(); } /// /// Constructor /// /// Calling convention (must have GenericInst set) /// Number of generic args internal GenericInstMethodSig(CallingConvention callingConvention, uint size) { this.callingConvention = callingConvention; genericArgs = new List((int)size); } /// /// Constructor /// /// Generic arg #1 public GenericInstMethodSig(TypeSig arg1) { callingConvention = CallingConvention.GenericInst; genericArgs = new List { arg1 }; } /// /// Constructor /// /// Generic arg #1 /// Generic arg #2 public GenericInstMethodSig(TypeSig arg1, TypeSig arg2) { callingConvention = CallingConvention.GenericInst; genericArgs = new List { arg1, arg2 }; } /// /// Constructor /// /// Generic arg #1 /// Generic arg #2 /// Generic arg #3 public GenericInstMethodSig(TypeSig arg1, TypeSig arg2, TypeSig arg3) { callingConvention = CallingConvention.GenericInst; genericArgs = new List { arg1, arg2, arg3 }; } /// /// Constructor /// /// Generic args public GenericInstMethodSig(params TypeSig[] args) { callingConvention = CallingConvention.GenericInst; genericArgs = new List(args); } /// /// Constructor /// /// Generic args public GenericInstMethodSig(IList args) { callingConvention = CallingConvention.GenericInst; genericArgs = new List(args); } /// /// Clone this /// public GenericInstMethodSig Clone() => new GenericInstMethodSig(genericArgs); } public static partial class Extensions { /// /// Gets the field type /// /// this /// Field type or null if none public static TypeSig GetFieldType(this FieldSig sig) => sig?.Type; /// /// Gets the return type /// /// this /// Return type or null if none public static TypeSig GetRetType(this MethodBaseSig sig) => sig?.RetType; /// /// Gets the parameters /// /// this /// The parameters public static IList GetParams(this MethodBaseSig sig) => sig?.Params ?? new List(); /// /// Gets the parameter count /// /// this /// Parameter count public static int GetParamCount(this MethodBaseSig sig) => sig?.Params.Count ?? 0; /// /// Gets the generic parameter count /// /// this /// Generic parameter count public static uint GetGenParamCount(this MethodBaseSig sig) => sig?.GenParamCount ?? 0; /// /// Gets the parameters after the sentinel /// /// this /// Parameters after sentinel or null if none public static IList GetParamsAfterSentinel(this MethodBaseSig sig) => sig?.ParamsAfterSentinel; /// /// Gets the locals /// /// this /// All locals public static IList GetLocals(this LocalSig sig) => sig?.Locals ?? new List(); /// /// Gets the generic arguments /// /// this /// All generic arguments public static IList GetGenericArguments(this GenericInstMethodSig sig) => sig?.GenericArguments ?? new List(); /// /// Gets the property /// /// this /// The type's property or /// false if input isnull public static bool GetIsDefault(this CallingConventionSig sig) => sig?.IsDefault ?? false; } }