Created
October 17, 2018 18:13
-
-
Save jcansdale/2d97240b53b23e14ec5324c4fe0916bb to your computer and use it in GitHub Desktop.
proj2src Mono.Cecil.csproj Mono.Cecil.cs
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#region ProjectInfo.cs | |
namespace Internal { | |
// | |
// Author: | |
// Jb Evain (jbevain@gmail.com) | |
// | |
// Copyright (c) 2008 - 2015 Jb Evain | |
// | |
// Licensed under the MIT/X11 license. | |
// | |
using System.Reflection; | |
using System.Runtime.InteropServices; | |
/*[assembly: AssemblyProduct (Consts.AssemblyName)]*/ | |
/*[assembly: AssemblyCopyright ("Copyright ยฉ 2008 - 2018 Jb Evain")]*/ | |
/*[assembly: ComVisible (false)]*/ | |
/*[assembly: AssemblyVersion ("0.10.1.0")]*/ | |
/*[assembly: AssemblyFileVersion ("0.10.1.0")]*/ | |
/*[assembly: AssemblyInformationalVersion ("0.10.1.0")]*/ | |
} | |
#endregion | |
#region Mono\*.cs | |
namespace Internal { | |
// | |
// Author: | |
// Jb Evain (jbevain@gmail.com) | |
// | |
// Copyright (c) 2008 - 2015 Jb Evain | |
// Copyright (c) 2008 - 2011 Novell, Inc. | |
// | |
// Licensed under the MIT/X11 license. | |
// | |
using System; | |
namespace Mono { | |
static class Disposable { | |
public static Disposable<T> Owned<T> (T value) where T : class, IDisposable | |
{ | |
return new Disposable<T> (value, owned: true); | |
} | |
public static Disposable<T> NotOwned<T> (T value) where T : class, IDisposable | |
{ | |
return new Disposable<T> (value, owned: false); | |
} | |
} | |
struct Disposable<T> : IDisposable where T : class, IDisposable { | |
internal readonly T value; | |
readonly bool owned; | |
public Disposable (T value, bool owned) | |
{ | |
this.value = value; | |
this.owned = owned; | |
} | |
public void Dispose () | |
{ | |
if (value != null && owned) | |
value.Dispose (); | |
} | |
} | |
} | |
} | |
#endregion | |
#region Mono\*.cs | |
namespace Internal { | |
// | |
// Author: | |
// Jb Evain (jbevain@gmail.com) | |
// | |
// Copyright (c) 2008 - 2015 Jb Evain | |
// Copyright (c) 2008 - 2011 Novell, Inc. | |
// | |
// Licensed under the MIT/X11 license. | |
// | |
using System; | |
using Mono.Collections.Generic; | |
namespace Mono { | |
static class Empty<T> { | |
public static readonly T [] Array = new T [0]; | |
} | |
class ArgumentNullOrEmptyException : ArgumentException { | |
public ArgumentNullOrEmptyException (string paramName) | |
: base ("Argument null or empty", paramName) | |
{ | |
} | |
} | |
} | |
namespace Mono.Cecil { | |
static partial class Mixin { | |
public static bool IsNullOrEmpty<T> (this T [] self) | |
{ | |
return self == null || self.Length == 0; | |
} | |
public static bool IsNullOrEmpty<T> (this Collection<T> self) | |
{ | |
return self == null || self.size == 0; | |
} | |
public static T [] Resize<T> (this T [] self, int length) | |
{ | |
Array.Resize (ref self, length); | |
return self; | |
} | |
public static T [] Add<T> (this T [] self, T item) | |
{ | |
if (self == null) { | |
self = new [] { item }; | |
return self; | |
} | |
self = self.Resize (self.Length + 1); | |
self [self.Length - 1] = item; | |
return self; | |
} | |
} | |
} | |
} | |
#endregion | |
#region Mono\*.cs | |
namespace Internal { | |
// | |
// Author: | |
// Jb Evain (jbevain@gmail.com) | |
// | |
// Copyright (c) 2008 - 2015 Jb Evain | |
// Copyright (c) 2008 - 2011 Novell, Inc. | |
// | |
// Licensed under the MIT/X11 license. | |
// | |
using System; | |
using System.Reflection; | |
#if NET_CORE | |
using System.Collections.Generic; | |
#endif | |
namespace Mono { | |
#if NET_CORE | |
enum TypeCode { | |
Empty = 0, | |
Object = 1, | |
DBNull = 2, | |
Boolean = 3, | |
Char = 4, | |
SByte = 5, | |
Byte = 6, | |
Int16 = 7, | |
UInt16 = 8, | |
Int32 = 9, | |
UInt32 = 10, | |
Int64 = 11, | |
UInt64 = 12, | |
Single = 13, | |
Double = 14, | |
Decimal = 15, | |
DateTime = 16, | |
String = 18 | |
} | |
#endif | |
static class TypeExtensions { | |
#if NET_CORE | |
private static readonly Dictionary<Type, TypeCode> TypeCodeMap = new Dictionary<Type, TypeCode> | |
{ | |
{ typeof (bool), TypeCode.Boolean }, | |
{ typeof (char), TypeCode.Char }, | |
{ typeof (sbyte), TypeCode.SByte }, | |
{ typeof (byte), TypeCode.Byte }, | |
{ typeof (short), TypeCode.Int16 }, | |
{ typeof (ushort), TypeCode.UInt16 }, | |
{ typeof (int), TypeCode.Int32 }, | |
{ typeof (uint), TypeCode.UInt32 }, | |
{ typeof (long), TypeCode.Int64 }, | |
{ typeof (ulong), TypeCode.UInt64 }, | |
{ typeof (float), TypeCode.Single }, | |
{ typeof (double), TypeCode.Double }, | |
{ typeof (decimal), TypeCode.Decimal }, | |
{ typeof (DateTime), TypeCode.DateTime }, | |
{ typeof (string), TypeCode.String }, | |
}; | |
#endif | |
public static TypeCode GetTypeCode (this Type type) | |
{ | |
#if NET_CORE | |
if (type == null) | |
return TypeCode.Empty; | |
TypeCode code; | |
if (!TypeCodeMap.TryGetValue (type, out code)) | |
return TypeCode.Object; | |
return code; | |
#else | |
return Type.GetTypeCode (type); | |
#endif | |
} | |
public static Assembly Assembly (this Type type) | |
{ | |
#if NET_CORE | |
return type.GetTypeInfo ().Assembly; | |
#else | |
return type.Assembly; | |
#endif | |
} | |
public static MethodBase DeclaringMethod (this Type type) | |
{ | |
#if NET_CORE | |
return type.GetTypeInfo ().DeclaringMethod; | |
#else | |
return type.DeclaringMethod; | |
#endif | |
} | |
public static Type [] GetGenericArguments (this Type type) | |
{ | |
#if NET_CORE | |
var info = type.GetTypeInfo (); | |
return info.IsGenericTypeDefinition ? info.GenericTypeParameters : info.GenericTypeArguments; | |
#else | |
return type.GetGenericArguments (); | |
#endif | |
} | |
public static bool IsGenericType (this Type type) | |
{ | |
#if NET_CORE | |
return type.GetTypeInfo ().IsGenericType; | |
#else | |
return type.IsGenericType; | |
#endif | |
} | |
public static bool IsGenericTypeDefinition (this Type type) | |
{ | |
#if NET_CORE | |
return type.GetTypeInfo ().IsGenericTypeDefinition; | |
#else | |
return type.IsGenericTypeDefinition; | |
#endif | |
} | |
public static bool IsValueType (this Type type) | |
{ | |
#if NET_CORE | |
return type.GetTypeInfo ().IsValueType; | |
#else | |
return type.IsValueType; | |
#endif | |
} | |
} | |
} | |
} | |
#endregion | |
#region Mono.Cecil\*.cs | |
namespace Internal { | |
// | |
// Author: | |
// Jb Evain (jbevain@gmail.com) | |
// | |
// Copyright (c) 2008 - 2015 Jb Evain | |
// Copyright (c) 2008 - 2011 Novell, Inc. | |
// | |
// Licensed under the MIT/X11 license. | |
// | |
using System; | |
using System.Text; | |
using Mono.Collections.Generic; | |
using MD = Mono.Cecil.Metadata; | |
namespace Mono.Cecil { | |
internal struct ArrayDimension { | |
int? lower_bound; | |
int? upper_bound; | |
public int? LowerBound { | |
get { return lower_bound; } | |
set { lower_bound = value; } | |
} | |
public int? UpperBound { | |
get { return upper_bound; } | |
set { upper_bound = value; } | |
} | |
public bool IsSized { | |
get { return lower_bound.HasValue || upper_bound.HasValue; } | |
} | |
public ArrayDimension (int? lowerBound, int? upperBound) | |
{ | |
this.lower_bound = lowerBound; | |
this.upper_bound = upperBound; | |
} | |
public override string ToString () | |
{ | |
return !IsSized | |
? string.Empty | |
: lower_bound + "..." + upper_bound; | |
} | |
} | |
internal sealed class ArrayType : TypeSpecification { | |
Collection<ArrayDimension> dimensions; | |
public Collection<ArrayDimension> Dimensions { | |
get { | |
if (dimensions != null) | |
return dimensions; | |
dimensions = new Collection<ArrayDimension> (); | |
dimensions.Add (new ArrayDimension ()); | |
return dimensions; | |
} | |
} | |
public int Rank { | |
get { return dimensions == null ? 1 : dimensions.Count; } | |
} | |
public bool IsVector { | |
get { | |
if (dimensions == null) | |
return true; | |
if (dimensions.Count > 1) | |
return false; | |
var dimension = dimensions [0]; | |
return !dimension.IsSized; | |
} | |
} | |
public override bool IsValueType { | |
get { return false; } | |
set { throw new InvalidOperationException (); } | |
} | |
public override string Name { | |
get { return base.Name + Suffix; } | |
} | |
public override string FullName { | |
get { return base.FullName + Suffix; } | |
} | |
string Suffix { | |
get { | |
if (IsVector) | |
return "[]"; | |
var suffix = new StringBuilder (); | |
suffix.Append ("["); | |
for (int i = 0; i < dimensions.Count; i++) { | |
if (i > 0) | |
suffix.Append (","); | |
suffix.Append (dimensions [i].ToString ()); | |
} | |
suffix.Append ("]"); | |
return suffix.ToString (); | |
} | |
} | |
public override bool IsArray { | |
get { return true; } | |
} | |
public ArrayType (TypeReference type) | |
: base (type) | |
{ | |
Mixin.CheckType (type); | |
this.etype = MD.ElementType.Array; | |
} | |
public ArrayType (TypeReference type, int rank) | |
: this (type) | |
{ | |
Mixin.CheckType (type); | |
if (rank == 1) | |
return; | |
dimensions = new Collection<ArrayDimension> (rank); | |
for (int i = 0; i < rank; i++) | |
dimensions.Add (new ArrayDimension ()); | |
this.etype = MD.ElementType.Array; | |
} | |
} | |
} | |
} | |
#endregion | |
#region Mono.Cecil\*.cs | |
namespace Internal { | |
// | |
// Author: | |
// Jb Evain (jbevain@gmail.com) | |
// | |
// Copyright (c) 2008 - 2015 Jb Evain | |
// Copyright (c) 2008 - 2011 Novell, Inc. | |
// | |
// Licensed under the MIT/X11 license. | |
// | |
using System; | |
using System.IO; | |
using Mono.Collections.Generic; | |
namespace Mono.Cecil { | |
internal sealed class AssemblyDefinition : ICustomAttributeProvider, ISecurityDeclarationProvider, IDisposable { | |
AssemblyNameDefinition name; | |
internal ModuleDefinition main_module; | |
Collection<ModuleDefinition> modules; | |
Collection<CustomAttribute> custom_attributes; | |
Collection<SecurityDeclaration> security_declarations; | |
public AssemblyNameDefinition Name { | |
get { return name; } | |
set { name = value; } | |
} | |
public string FullName { | |
get { return name != null ? name.FullName : string.Empty; } | |
} | |
public MetadataToken MetadataToken { | |
get { return new MetadataToken (TokenType.Assembly, 1); } | |
set { } | |
} | |
public Collection<ModuleDefinition> Modules { | |
get { | |
if (modules != null) | |
return modules; | |
if (main_module.HasImage) | |
return main_module.Read (ref modules, this, (_, reader) => reader.ReadModules ()); | |
return modules = new Collection<ModuleDefinition> (1) { main_module }; | |
} | |
} | |
public ModuleDefinition MainModule { | |
get { return main_module; } | |
} | |
public MethodDefinition EntryPoint { | |
get { return main_module.EntryPoint; } | |
set { main_module.EntryPoint = value; } | |
} | |
public bool HasCustomAttributes { | |
get { | |
if (custom_attributes != null) | |
return custom_attributes.Count > 0; | |
return this.GetHasCustomAttributes (main_module); | |
} | |
} | |
public Collection<CustomAttribute> CustomAttributes { | |
get { return custom_attributes ?? (this.GetCustomAttributes (ref custom_attributes, main_module)); } | |
} | |
public bool HasSecurityDeclarations { | |
get { | |
if (security_declarations != null) | |
return security_declarations.Count > 0; | |
return this.GetHasSecurityDeclarations (main_module); | |
} | |
} | |
public Collection<SecurityDeclaration> SecurityDeclarations { | |
get { return security_declarations ?? (this.GetSecurityDeclarations (ref security_declarations, main_module)); } | |
} | |
internal AssemblyDefinition () | |
{ | |
} | |
public void Dispose () | |
{ | |
if (this.modules == null) { | |
main_module.Dispose (); | |
return; | |
} | |
var modules = this.Modules; | |
for (int i = 0; i < modules.Count; i++) | |
modules [i].Dispose (); | |
} | |
#if !READ_ONLY | |
public static AssemblyDefinition CreateAssembly (AssemblyNameDefinition assemblyName, string moduleName, ModuleKind kind) | |
{ | |
return CreateAssembly (assemblyName, moduleName, new ModuleParameters { Kind = kind }); | |
} | |
public static AssemblyDefinition CreateAssembly (AssemblyNameDefinition assemblyName, string moduleName, ModuleParameters parameters) | |
{ | |
if (assemblyName == null) | |
throw new ArgumentNullException ("assemblyName"); | |
if (moduleName == null) | |
throw new ArgumentNullException ("moduleName"); | |
Mixin.CheckParameters (parameters); | |
if (parameters.Kind == ModuleKind.NetModule) | |
throw new ArgumentException ("kind"); | |
var assembly = ModuleDefinition.CreateModule (moduleName, parameters).Assembly; | |
assembly.Name = assemblyName; | |
return assembly; | |
} | |
#endif | |
public static AssemblyDefinition ReadAssembly (string fileName) | |
{ | |
return ReadAssembly (ModuleDefinition.ReadModule (fileName)); | |
} | |
public static AssemblyDefinition ReadAssembly (string fileName, ReaderParameters parameters) | |
{ | |
return ReadAssembly (ModuleDefinition.ReadModule (fileName, parameters)); | |
} | |
public static AssemblyDefinition ReadAssembly (Stream stream) | |
{ | |
return ReadAssembly (ModuleDefinition.ReadModule (stream)); | |
} | |
public static AssemblyDefinition ReadAssembly (Stream stream, ReaderParameters parameters) | |
{ | |
return ReadAssembly (ModuleDefinition.ReadModule (stream, parameters)); | |
} | |
static AssemblyDefinition ReadAssembly (ModuleDefinition module) | |
{ | |
var assembly = module.Assembly; | |
if (assembly == null) | |
throw new ArgumentException (); | |
return assembly; | |
} | |
#if !READ_ONLY | |
public void Write (string fileName) | |
{ | |
Write (fileName, new WriterParameters ()); | |
} | |
public void Write (string fileName, WriterParameters parameters) | |
{ | |
main_module.Write (fileName, parameters); | |
} | |
public void Write () | |
{ | |
main_module.Write (); | |
} | |
public void Write (WriterParameters parameters) | |
{ | |
main_module.Write (parameters); | |
} | |
public void Write (Stream stream) | |
{ | |
Write (stream, new WriterParameters ()); | |
} | |
public void Write (Stream stream, WriterParameters parameters) | |
{ | |
main_module.Write (stream, parameters); | |
} | |
#endif | |
public override string ToString () | |
{ | |
return this.FullName; | |
} | |
} | |
} | |
} | |
#endregion | |
#region Mono.Cecil\*.cs | |
namespace Internal { | |
// | |
// Author: | |
// Jb Evain (jbevain@gmail.com) | |
// | |
// Copyright (c) 2008 - 2015 Jb Evain | |
// Copyright (c) 2008 - 2011 Novell, Inc. | |
// | |
// Licensed under the MIT/X11 license. | |
// | |
using System; | |
namespace Mono.Cecil { | |
[Flags] | |
internal enum AssemblyAttributes : uint { | |
PublicKey = 0x0001, | |
SideBySideCompatible = 0x0000, | |
Retargetable = 0x0100, | |
WindowsRuntime = 0x0200, | |
DisableJITCompileOptimizer = 0x4000, | |
EnableJITCompileTracking = 0x8000, | |
} | |
} | |
} | |
#endregion | |
#region Mono.Cecil\*.cs | |
namespace Internal { | |
// | |
// Author: | |
// Jb Evain (jbevain@gmail.com) | |
// | |
// Copyright (c) 2008 - 2015 Jb Evain | |
// Copyright (c) 2008 - 2011 Novell, Inc. | |
// | |
// Licensed under the MIT/X11 license. | |
// | |
namespace Mono.Cecil { | |
internal enum AssemblyHashAlgorithm : uint { | |
None = 0x0000, | |
Reserved = 0x8003, // MD5 | |
SHA1 = 0x8004 | |
} | |
} | |
} | |
#endregion | |
#region Mono.Cecil\*.cs | |
namespace Internal { | |
// | |
// Author: | |
// Jb Evain (jbevain@gmail.com) | |
// | |
// Copyright (c) 2008 - 2015 Jb Evain | |
// Copyright (c) 2008 - 2011 Novell, Inc. | |
// | |
// Licensed under the MIT/X11 license. | |
// | |
using System.Reflection; | |
using System.Runtime.CompilerServices; | |
using System.Runtime.InteropServices; | |
/*[assembly: AssemblyTitle (Consts.AssemblyName)]*/ | |
#if !NET_CORE | |
/*[assembly: Guid ("fd225bb4-fa53-44b2-a6db-85f5e48dcb54")]*/ | |
#endif | |
/*[assembly: InternalsVisibleTo ("Mono.Cecil.Pdb, PublicKey=" + Consts.PublicKey)]*/ | |
/*[assembly: InternalsVisibleTo ("Mono.Cecil.Mdb, PublicKey=" + Consts.PublicKey)]*/ | |
/*[assembly: InternalsVisibleTo ("Mono.Cecil.Rocks, PublicKey=" + Consts.PublicKey)]*/ | |
/*[assembly: InternalsVisibleTo ("Mono.Cecil.Tests, PublicKey=" + Consts.PublicKey)]*/ | |
} | |
#endregion | |
#region Mono.Cecil\*.cs | |
namespace Internal { | |
// | |
// Author: | |
// Jb Evain (jbevain@gmail.com) | |
// | |
// Copyright (c) 2008 - 2015 Jb Evain | |
// Copyright (c) 2008 - 2011 Novell, Inc. | |
// | |
// Licensed under the MIT/X11 license. | |
// | |
using System; | |
namespace Mono.Cecil { | |
internal sealed class AssemblyLinkedResource : Resource { | |
AssemblyNameReference reference; | |
public AssemblyNameReference Assembly { | |
get { return reference; } | |
set { reference = value; } | |
} | |
public override ResourceType ResourceType { | |
get { return ResourceType.AssemblyLinked; } | |
} | |
public AssemblyLinkedResource (string name, ManifestResourceAttributes flags) | |
: base (name, flags) | |
{ | |
} | |
public AssemblyLinkedResource (string name, ManifestResourceAttributes flags, AssemblyNameReference reference) | |
: base (name, flags) | |
{ | |
this.reference = reference; | |
} | |
} | |
} | |
} | |
#endregion | |
#region Mono.Cecil\*.cs | |
namespace Internal { | |
// | |
// Author: | |
// Jb Evain (jbevain@gmail.com) | |
// | |
// Copyright (c) 2008 - 2015 Jb Evain | |
// Copyright (c) 2008 - 2011 Novell, Inc. | |
// | |
// Licensed under the MIT/X11 license. | |
// | |
using System; | |
namespace Mono.Cecil { | |
internal sealed class AssemblyNameDefinition : AssemblyNameReference { | |
public override byte [] Hash { | |
get { return Empty<byte>.Array; } | |
} | |
internal AssemblyNameDefinition () | |
{ | |
this.token = new MetadataToken (TokenType.Assembly, 1); | |
} | |
public AssemblyNameDefinition (string name, Version version) | |
: base (name, version) | |
{ | |
this.token = new MetadataToken (TokenType.Assembly, 1); | |
} | |
} | |
} | |
} | |
#endregion | |
#region Mono.Cecil\*.cs | |
namespace Internal { | |
// | |
// Author: | |
// Jb Evain (jbevain@gmail.com) | |
// | |
// Copyright (c) 2008 - 2015 Jb Evain | |
// Copyright (c) 2008 - 2011 Novell, Inc. | |
// | |
// Licensed under the MIT/X11 license. | |
// | |
using System; | |
using System.Globalization; | |
using System.Security.Cryptography; | |
using System.Text; | |
namespace Mono.Cecil { | |
internal class AssemblyNameReference : IMetadataScope { | |
string name; | |
string culture; | |
Version version; | |
uint attributes; | |
byte [] public_key; | |
byte [] public_key_token; | |
AssemblyHashAlgorithm hash_algorithm; | |
byte [] hash; | |
internal MetadataToken token; | |
string full_name; | |
public string Name { | |
get { return name; } | |
set { | |
name = value; | |
full_name = null; | |
} | |
} | |
public string Culture { | |
get { return culture; } | |
set { | |
culture = value; | |
full_name = null; | |
} | |
} | |
public Version Version { | |
get { return version; } | |
set { | |
version = Mixin.CheckVersion (value); | |
full_name = null; | |
} | |
} | |
public AssemblyAttributes Attributes { | |
get { return (AssemblyAttributes) attributes; } | |
set { attributes = (uint) value; } | |
} | |
public bool HasPublicKey { | |
get { return attributes.GetAttributes ((uint) AssemblyAttributes.PublicKey); } | |
set { attributes = attributes.SetAttributes ((uint) AssemblyAttributes.PublicKey, value); } | |
} | |
public bool IsSideBySideCompatible { | |
get { return attributes.GetAttributes ((uint) AssemblyAttributes.SideBySideCompatible); } | |
set { attributes = attributes.SetAttributes ((uint) AssemblyAttributes.SideBySideCompatible, value); } | |
} | |
public bool IsRetargetable { | |
get { return attributes.GetAttributes ((uint) AssemblyAttributes.Retargetable); } | |
set { attributes = attributes.SetAttributes ((uint) AssemblyAttributes.Retargetable, value); } | |
} | |
public bool IsWindowsRuntime { | |
get { return attributes.GetAttributes ((uint) AssemblyAttributes.WindowsRuntime); } | |
set { attributes = attributes.SetAttributes ((uint) AssemblyAttributes.WindowsRuntime, value); } | |
} | |
public byte [] PublicKey { | |
get { return public_key ?? Empty<byte>.Array; } | |
set { | |
public_key = value; | |
HasPublicKey = !public_key.IsNullOrEmpty (); | |
public_key_token = Empty<byte>.Array; | |
full_name = null; | |
} | |
} | |
public byte [] PublicKeyToken { | |
get { | |
if (public_key_token.IsNullOrEmpty () && !public_key.IsNullOrEmpty ()) { | |
var hash = HashPublicKey (); | |
// we need the last 8 bytes in reverse order | |
var local_public_key_token = new byte [8]; | |
Array.Copy (hash, (hash.Length - 8), local_public_key_token, 0, 8); | |
Array.Reverse (local_public_key_token, 0, 8); | |
public_key_token = local_public_key_token; // publish only once finished (required for thread-safety) | |
} | |
return public_key_token ?? Empty<byte>.Array; | |
} | |
set { | |
public_key_token = value; | |
full_name = null; | |
} | |
} | |
byte [] HashPublicKey () | |
{ | |
HashAlgorithm algorithm; | |
switch (hash_algorithm) { | |
case AssemblyHashAlgorithm.Reserved: | |
algorithm = MD5.Create (); | |
break; | |
default: | |
// None default to SHA1 | |
algorithm = SHA1.Create (); | |
break; | |
} | |
using (algorithm) | |
return algorithm.ComputeHash (public_key); | |
} | |
public virtual MetadataScopeType MetadataScopeType { | |
get { return MetadataScopeType.AssemblyNameReference; } | |
} | |
public string FullName { | |
get { | |
if (full_name != null) | |
return full_name; | |
const string sep = ", "; | |
var builder = new StringBuilder (); | |
builder.Append (name); | |
builder.Append (sep); | |
builder.Append ("Version="); | |
builder.Append (version.ToString (fieldCount: 4)); | |
builder.Append (sep); | |
builder.Append ("Culture="); | |
builder.Append (string.IsNullOrEmpty (culture) ? "neutral" : culture); | |
builder.Append (sep); | |
builder.Append ("PublicKeyToken="); | |
var pk_token = PublicKeyToken; | |
if (!pk_token.IsNullOrEmpty () && pk_token.Length > 0) { | |
for (int i = 0 ; i < pk_token.Length ; i++) { | |
builder.Append (pk_token [i].ToString ("x2")); | |
} | |
} else | |
builder.Append ("null"); | |
if (IsRetargetable) { | |
builder.Append (sep); | |
builder.Append ("Retargetable=Yes"); | |
} | |
return full_name = builder.ToString (); | |
} | |
} | |
public static AssemblyNameReference Parse (string fullName) | |
{ | |
if (fullName == null) | |
throw new ArgumentNullException ("fullName"); | |
if (fullName.Length == 0) | |
throw new ArgumentException ("Name can not be empty"); | |
var name = new AssemblyNameReference (); | |
var tokens = fullName.Split (','); | |
for (int i = 0; i < tokens.Length; i++) { | |
var token = tokens [i].Trim (); | |
if (i == 0) { | |
name.Name = token; | |
continue; | |
} | |
var parts = token.Split ('='); | |
if (parts.Length != 2) | |
throw new ArgumentException ("Malformed name"); | |
switch (parts [0].ToLowerInvariant ()) { | |
case "version": | |
name.Version = new Version (parts [1]); | |
break; | |
case "culture": | |
name.Culture = parts [1] == "neutral" ? "" : parts [1]; | |
break; | |
case "publickeytoken": | |
var pk_token = parts [1]; | |
if (pk_token == "null") | |
break; | |
name.PublicKeyToken = new byte [pk_token.Length / 2]; | |
for (int j = 0; j < name.PublicKeyToken.Length; j++) | |
name.PublicKeyToken [j] = Byte.Parse (pk_token.Substring (j * 2, 2), NumberStyles.HexNumber); | |
break; | |
} | |
} | |
return name; | |
} | |
public AssemblyHashAlgorithm HashAlgorithm { | |
get { return hash_algorithm; } | |
set { hash_algorithm = value; } | |
} | |
public virtual byte [] Hash { | |
get { return hash; } | |
set { hash = value; } | |
} | |
public MetadataToken MetadataToken { | |
get { return token; } | |
set { token = value; } | |
} | |
internal AssemblyNameReference () | |
{ | |
this.version = Mixin.ZeroVersion; | |
this.token = new MetadataToken (TokenType.AssemblyRef); | |
} | |
public AssemblyNameReference (string name, Version version) | |
{ | |
Mixin.CheckName (name); | |
this.name = name; | |
this.version = Mixin.CheckVersion (version); | |
this.hash_algorithm = AssemblyHashAlgorithm.None; | |
this.token = new MetadataToken (TokenType.AssemblyRef); | |
} | |
public override string ToString () | |
{ | |
return this.FullName; | |
} | |
} | |
partial class Mixin { | |
public static Version ZeroVersion = new Version (0, 0, 0 ,0); | |
public static Version CheckVersion (Version version) | |
{ | |
if (version == null) | |
return ZeroVersion; | |
if (version.Build == -1) | |
return new Version (version.Major, version.Minor, 0, 0); | |
if (version.Revision == -1) | |
return new Version (version.Major, version.Minor, version.Build, 0); | |
return version; | |
} | |
} | |
} | |
} | |
#endregion | |
#region Mono.Cecil\*.cs | |
namespace Internal { | |
// | |
// Author: | |
// Jb Evain (jbevain@gmail.com) | |
// | |
// Copyright (c) 2008 - 2015 Jb Evain | |
// Copyright (c) 2008 - 2011 Novell, Inc. | |
// | |
// Licensed under the MIT/X11 license. | |
// | |
using System; | |
using System.Collections.Generic; | |
using System.IO; | |
using System.IO.Compression; | |
using System.Text; | |
using Mono.Collections.Generic; | |
using Mono.Cecil.Cil; | |
using Mono.Cecil.Metadata; | |
using Mono.Cecil.PE; | |
using RVA = System.UInt32; | |
namespace Mono.Cecil { | |
abstract class ModuleReader { | |
readonly protected ModuleDefinition module; | |
protected ModuleReader (Image image, ReadingMode mode) | |
{ | |
this.module = new ModuleDefinition (image); | |
this.module.ReadingMode = mode; | |
} | |
protected abstract void ReadModule (); | |
public abstract void ReadSymbols (ModuleDefinition module); | |
protected void ReadModuleManifest (MetadataReader reader) | |
{ | |
reader.Populate (module); | |
ReadAssembly (reader); | |
} | |
void ReadAssembly (MetadataReader reader) | |
{ | |
var name = reader.ReadAssemblyNameDefinition (); | |
if (name == null) { | |
module.kind = ModuleKind.NetModule; | |
return; | |
} | |
var assembly = new AssemblyDefinition (); | |
assembly.Name = name; | |
module.assembly = assembly; | |
assembly.main_module = module; | |
} | |
public static ModuleDefinition CreateModule (Image image, ReaderParameters parameters) | |
{ | |
var reader = CreateModuleReader (image, parameters.ReadingMode); | |
var module = reader.module; | |
if (parameters.assembly_resolver != null) | |
module.assembly_resolver = Disposable.NotOwned (parameters.assembly_resolver); | |
if (parameters.metadata_resolver != null) | |
module.metadata_resolver = parameters.metadata_resolver; | |
#if !READ_ONLY | |
if (parameters.metadata_importer_provider != null) | |
module.metadata_importer = parameters.metadata_importer_provider.GetMetadataImporter (module); | |
if (parameters.reflection_importer_provider != null) | |
module.reflection_importer = parameters.reflection_importer_provider.GetReflectionImporter (module); | |
#endif | |
GetMetadataKind (module, parameters); | |
reader.ReadModule (); | |
ReadSymbols (module, parameters); | |
reader.ReadSymbols (module); | |
if (parameters.ReadingMode == ReadingMode.Immediate) | |
module.MetadataSystem.Clear (); | |
return module; | |
} | |
static void ReadSymbols (ModuleDefinition module, ReaderParameters parameters) | |
{ | |
var symbol_reader_provider = parameters.SymbolReaderProvider; | |
if (symbol_reader_provider == null && parameters.ReadSymbols) | |
symbol_reader_provider = new DefaultSymbolReaderProvider (); | |
if (symbol_reader_provider != null) { | |
module.SymbolReaderProvider = symbol_reader_provider; | |
var reader = parameters.SymbolStream != null | |
? symbol_reader_provider.GetSymbolReader (module, parameters.SymbolStream) | |
: symbol_reader_provider.GetSymbolReader (module, module.FileName); | |
if (reader != null) | |
module.ReadSymbols (reader, parameters.ThrowIfSymbolsAreNotMatching); | |
} | |
if (module.Image.HasDebugTables ()) | |
module.ReadSymbols (new PortablePdbReader (module.Image, module)); | |
} | |
static void GetMetadataKind (ModuleDefinition module, ReaderParameters parameters) | |
{ | |
if (!parameters.ApplyWindowsRuntimeProjections) { | |
module.MetadataKind = MetadataKind.Ecma335; | |
return; | |
} | |
var runtime_version = module.RuntimeVersion; | |
if (!runtime_version.Contains ("WindowsRuntime")) | |
module.MetadataKind = MetadataKind.Ecma335; | |
else if (runtime_version.Contains ("CLR")) | |
module.MetadataKind = MetadataKind.ManagedWindowsMetadata; | |
else | |
module.MetadataKind = MetadataKind.WindowsMetadata; | |
} | |
static ModuleReader CreateModuleReader (Image image, ReadingMode mode) | |
{ | |
switch (mode) { | |
case ReadingMode.Immediate: | |
return new ImmediateModuleReader (image); | |
case ReadingMode.Deferred: | |
return new DeferredModuleReader (image); | |
default: | |
throw new ArgumentException (); | |
} | |
} | |
} | |
sealed class ImmediateModuleReader : ModuleReader { | |
bool resolve_attributes; | |
public ImmediateModuleReader (Image image) | |
: base (image, ReadingMode.Immediate) | |
{ | |
} | |
protected override void ReadModule () | |
{ | |
this.module.Read (this.module, (module, reader) => { | |
ReadModuleManifest (reader); | |
ReadModule (module, resolve_attributes: true); | |
}); | |
} | |
public void ReadModule (ModuleDefinition module, bool resolve_attributes) | |
{ | |
this.resolve_attributes = resolve_attributes; | |
if (module.HasAssemblyReferences) | |
Mixin.Read (module.AssemblyReferences); | |
if (module.HasResources) | |
Mixin.Read (module.Resources); | |
if (module.HasModuleReferences) | |
Mixin.Read (module.ModuleReferences); | |
if (module.HasTypes) | |
ReadTypes (module.Types); | |
if (module.HasExportedTypes) | |
Mixin.Read (module.ExportedTypes); | |
ReadCustomAttributes (module); | |
var assembly = module.Assembly; | |
if (assembly == null) | |
return; | |
ReadCustomAttributes (assembly); | |
ReadSecurityDeclarations (assembly); | |
} | |
void ReadTypes (Collection<TypeDefinition> types) | |
{ | |
for (int i = 0; i < types.Count; i++) | |
ReadType (types [i]); | |
} | |
void ReadType (TypeDefinition type) | |
{ | |
ReadGenericParameters (type); | |
if (type.HasInterfaces) | |
ReadInterfaces (type); | |
if (type.HasNestedTypes) | |
ReadTypes (type.NestedTypes); | |
if (type.HasLayoutInfo) | |
Mixin.Read (type.ClassSize); | |
if (type.HasFields) | |
ReadFields (type); | |
if (type.HasMethods) | |
ReadMethods (type); | |
if (type.HasProperties) | |
ReadProperties (type); | |
if (type.HasEvents) | |
ReadEvents (type); | |
ReadSecurityDeclarations (type); | |
ReadCustomAttributes (type); | |
} | |
void ReadInterfaces (TypeDefinition type) | |
{ | |
var interfaces = type.Interfaces; | |
for (int i = 0; i < interfaces.Count; i++) | |
ReadCustomAttributes (interfaces [i]); | |
} | |
void ReadGenericParameters (IGenericParameterProvider provider) | |
{ | |
if (!provider.HasGenericParameters) | |
return; | |
var parameters = provider.GenericParameters; | |
for (int i = 0; i < parameters.Count; i++) { | |
var parameter = parameters [i]; | |
if (parameter.HasConstraints) | |
Mixin.Read (parameter.Constraints); | |
ReadCustomAttributes (parameter); | |
} | |
} | |
void ReadSecurityDeclarations (ISecurityDeclarationProvider provider) | |
{ | |
if (!provider.HasSecurityDeclarations) | |
return; | |
var security_declarations = provider.SecurityDeclarations; | |
if (!resolve_attributes) | |
return; | |
for (int i = 0; i < security_declarations.Count; i++) { | |
var security_declaration = security_declarations [i]; | |
Mixin.Read (security_declaration.SecurityAttributes); | |
} | |
} | |
void ReadCustomAttributes (ICustomAttributeProvider provider) | |
{ | |
if (!provider.HasCustomAttributes) | |
return; | |
var custom_attributes = provider.CustomAttributes; | |
if (!resolve_attributes) | |
return; | |
for (int i = 0; i < custom_attributes.Count; i++) { | |
var custom_attribute = custom_attributes [i]; | |
Mixin.Read (custom_attribute.ConstructorArguments); | |
} | |
} | |
void ReadFields (TypeDefinition type) | |
{ | |
var fields = type.Fields; | |
for (int i = 0; i < fields.Count; i++) { | |
var field = fields [i]; | |
if (field.HasConstant) | |
Mixin.Read (field.Constant); | |
if (field.HasLayoutInfo) | |
Mixin.Read (field.Offset); | |
if (field.RVA > 0) | |
Mixin.Read (field.InitialValue); | |
if (field.HasMarshalInfo) | |
Mixin.Read (field.MarshalInfo); | |
ReadCustomAttributes (field); | |
} | |
} | |
void ReadMethods (TypeDefinition type) | |
{ | |
var methods = type.Methods; | |
for (int i = 0; i < methods.Count; i++) { | |
var method = methods [i]; | |
ReadGenericParameters (method); | |
if (method.HasParameters) | |
ReadParameters (method); | |
if (method.HasOverrides) | |
Mixin.Read (method.Overrides); | |
if (method.IsPInvokeImpl) | |
Mixin.Read (method.PInvokeInfo); | |
ReadSecurityDeclarations (method); | |
ReadCustomAttributes (method); | |
var return_type = method.MethodReturnType; | |
if (return_type.HasConstant) | |
Mixin.Read (return_type.Constant); | |
if (return_type.HasMarshalInfo) | |
Mixin.Read (return_type.MarshalInfo); | |
ReadCustomAttributes (return_type); | |
} | |
} | |
void ReadParameters (MethodDefinition method) | |
{ | |
var parameters = method.Parameters; | |
for (int i = 0; i < parameters.Count; i++) { | |
var parameter = parameters [i]; | |
if (parameter.HasConstant) | |
Mixin.Read (parameter.Constant); | |
if (parameter.HasMarshalInfo) | |
Mixin.Read (parameter.MarshalInfo); | |
ReadCustomAttributes (parameter); | |
} | |
} | |
void ReadProperties (TypeDefinition type) | |
{ | |
var properties = type.Properties; | |
for (int i = 0; i < properties.Count; i++) { | |
var property = properties [i]; | |
Mixin.Read (property.GetMethod); | |
if (property.HasConstant) | |
Mixin.Read (property.Constant); | |
ReadCustomAttributes (property); | |
} | |
} | |
void ReadEvents (TypeDefinition type) | |
{ | |
var events = type.Events; | |
for (int i = 0; i < events.Count; i++) { | |
var @event = events [i]; | |
Mixin.Read (@event.AddMethod); | |
ReadCustomAttributes (@event); | |
} | |
} | |
public override void ReadSymbols (ModuleDefinition module) | |
{ | |
if (module.symbol_reader == null) | |
return; | |
ReadTypesSymbols (module.Types, module.symbol_reader); | |
} | |
void ReadTypesSymbols (Collection<TypeDefinition> types, ISymbolReader symbol_reader) | |
{ | |
for (int i = 0; i < types.Count; i++) { | |
var type = types [i]; | |
if (type.HasNestedTypes) | |
ReadTypesSymbols (type.NestedTypes, symbol_reader); | |
if (type.HasMethods) | |
ReadMethodsSymbols (type, symbol_reader); | |
} | |
} | |
void ReadMethodsSymbols (TypeDefinition type, ISymbolReader symbol_reader) | |
{ | |
var methods = type.Methods; | |
for (int i = 0; i < methods.Count; i++) { | |
var method = methods [i]; | |
if (method.HasBody && method.token.RID != 0 && method.debug_info == null) | |
method.debug_info = symbol_reader.Read (method); | |
} | |
} | |
} | |
sealed class DeferredModuleReader : ModuleReader { | |
public DeferredModuleReader (Image image) | |
: base (image, ReadingMode.Deferred) | |
{ | |
} | |
protected override void ReadModule () | |
{ | |
this.module.Read (this.module, (_, reader) => ReadModuleManifest (reader)); | |
} | |
public override void ReadSymbols (ModuleDefinition module) | |
{ | |
} | |
} | |
sealed class MetadataReader : ByteBuffer { | |
readonly internal Image image; | |
readonly internal ModuleDefinition module; | |
readonly internal MetadataSystem metadata; | |
internal CodeReader code; | |
internal IGenericContext context; | |
readonly MetadataReader metadata_reader; | |
public MetadataReader (ModuleDefinition module) | |
: base (module.Image.TableHeap.data) | |
{ | |
this.image = module.Image; | |
this.module = module; | |
this.metadata = module.MetadataSystem; | |
this.code = new CodeReader (this); | |
} | |
public MetadataReader (Image image, ModuleDefinition module, MetadataReader metadata_reader) | |
: base (image.TableHeap.data) | |
{ | |
this.image = image; | |
this.module = module; | |
this.metadata = module.MetadataSystem; | |
this.metadata_reader = metadata_reader; | |
} | |
int GetCodedIndexSize (CodedIndex index) | |
{ | |
return image.GetCodedIndexSize (index); | |
} | |
uint ReadByIndexSize (int size) | |
{ | |
if (size == 4) | |
return ReadUInt32 (); | |
else | |
return ReadUInt16 (); | |
} | |
byte [] ReadBlob () | |
{ | |
var blob_heap = image.BlobHeap; | |
if (blob_heap == null) { | |
position += 2; | |
return Empty<byte>.Array; | |
} | |
return blob_heap.Read (ReadBlobIndex ()); | |
} | |
byte [] ReadBlob (uint signature) | |
{ | |
var blob_heap = image.BlobHeap; | |
if (blob_heap == null) | |
return Empty<byte>.Array; | |
return blob_heap.Read (signature); | |
} | |
uint ReadBlobIndex () | |
{ | |
var blob_heap = image.BlobHeap; | |
return ReadByIndexSize (blob_heap != null ? blob_heap.IndexSize : 2); | |
} | |
void GetBlobView (uint signature, out byte [] blob, out int index, out int count) | |
{ | |
var blob_heap = image.BlobHeap; | |
if (blob_heap == null) { | |
blob = null; | |
index = count = 0; | |
return; | |
} | |
blob_heap.GetView (signature, out blob, out index, out count); | |
} | |
string ReadString () | |
{ | |
return image.StringHeap.Read (ReadByIndexSize (image.StringHeap.IndexSize)); | |
} | |
uint ReadStringIndex () | |
{ | |
return ReadByIndexSize (image.StringHeap.IndexSize); | |
} | |
Guid ReadGuid () | |
{ | |
return image.GuidHeap.Read (ReadByIndexSize (image.GuidHeap.IndexSize)); | |
} | |
uint ReadTableIndex (Table table) | |
{ | |
return ReadByIndexSize (image.GetTableIndexSize (table)); | |
} | |
MetadataToken ReadMetadataToken (CodedIndex index) | |
{ | |
return index.GetMetadataToken (ReadByIndexSize (GetCodedIndexSize (index))); | |
} | |
int MoveTo (Table table) | |
{ | |
var info = image.TableHeap [table]; | |
if (info.Length != 0) | |
this.position = (int) info.Offset; | |
return (int) info.Length; | |
} | |
bool MoveTo (Table table, uint row) | |
{ | |
var info = image.TableHeap [table]; | |
var length = info.Length; | |
if (length == 0 || row > length) | |
return false; | |
this.position = (int) (info.Offset + (info.RowSize * (row - 1))); | |
return true; | |
} | |
public AssemblyNameDefinition ReadAssemblyNameDefinition () | |
{ | |
if (MoveTo (Table.Assembly) == 0) | |
return null; | |
var name = new AssemblyNameDefinition (); | |
name.HashAlgorithm = (AssemblyHashAlgorithm) ReadUInt32 (); | |
PopulateVersionAndFlags (name); | |
name.PublicKey = ReadBlob (); | |
PopulateNameAndCulture (name); | |
return name; | |
} | |
public ModuleDefinition Populate (ModuleDefinition module) | |
{ | |
if (MoveTo (Table.Module) == 0) | |
return module; | |
Advance (2); // Generation | |
module.Name = ReadString (); | |
module.Mvid = ReadGuid (); | |
return module; | |
} | |
void InitializeAssemblyReferences () | |
{ | |
if (metadata.AssemblyReferences != null) | |
return; | |
int length = MoveTo (Table.AssemblyRef); | |
var references = metadata.AssemblyReferences = new AssemblyNameReference [length]; | |
for (uint i = 0; i < length; i++) { | |
var reference = new AssemblyNameReference (); | |
reference.token = new MetadataToken (TokenType.AssemblyRef, i + 1); | |
PopulateVersionAndFlags (reference); | |
var key_or_token = ReadBlob (); | |
if (reference.HasPublicKey) | |
reference.PublicKey = key_or_token; | |
else | |
reference.PublicKeyToken = key_or_token; | |
PopulateNameAndCulture (reference); | |
reference.Hash = ReadBlob (); | |
references [i] = reference; | |
} | |
} | |
public Collection<AssemblyNameReference> ReadAssemblyReferences () | |
{ | |
InitializeAssemblyReferences (); | |
var references = new Collection<AssemblyNameReference> (metadata.AssemblyReferences); | |
if (module.IsWindowsMetadata ()) | |
module.Projections.AddVirtualReferences (references); | |
return references; | |
} | |
public MethodDefinition ReadEntryPoint () | |
{ | |
if (module.Image.EntryPointToken == 0) | |
return null; | |
var token = new MetadataToken (module.Image.EntryPointToken); | |
return GetMethodDefinition (token.RID); | |
} | |
public Collection<ModuleDefinition> ReadModules () | |
{ | |
var modules = new Collection<ModuleDefinition> (1); | |
modules.Add (this.module); | |
int length = MoveTo (Table.File); | |
for (uint i = 1; i <= length; i++) { | |
var attributes = (FileAttributes) ReadUInt32 (); | |
var name = ReadString (); | |
ReadBlobIndex (); | |
if (attributes != FileAttributes.ContainsMetaData) | |
continue; | |
var parameters = new ReaderParameters { | |
ReadingMode = module.ReadingMode, | |
SymbolReaderProvider = module.SymbolReaderProvider, | |
AssemblyResolver = module.AssemblyResolver | |
}; | |
modules.Add (ModuleDefinition.ReadModule ( | |
GetModuleFileName (name), parameters)); | |
} | |
return modules; | |
} | |
string GetModuleFileName (string name) | |
{ | |
if (module.FileName == null) | |
throw new NotSupportedException (); | |
var path = Path.GetDirectoryName (module.FileName); | |
return Path.Combine (path, name); | |
} | |
void InitializeModuleReferences () | |
{ | |
if (metadata.ModuleReferences != null) | |
return; | |
int length = MoveTo (Table.ModuleRef); | |
var references = metadata.ModuleReferences = new ModuleReference [length]; | |
for (uint i = 0; i < length; i++) { | |
var reference = new ModuleReference (ReadString ()); | |
reference.token = new MetadataToken (TokenType.ModuleRef, i + 1); | |
references [i] = reference; | |
} | |
} | |
public Collection<ModuleReference> ReadModuleReferences () | |
{ | |
InitializeModuleReferences (); | |
return new Collection<ModuleReference> (metadata.ModuleReferences); | |
} | |
public bool HasFileResource () | |
{ | |
int length = MoveTo (Table.File); | |
if (length == 0) | |
return false; | |
for (uint i = 1; i <= length; i++) | |
if (ReadFileRecord (i).Col1 == FileAttributes.ContainsNoMetaData) | |
return true; | |
return false; | |
} | |
public Collection<Resource> ReadResources () | |
{ | |
int length = MoveTo (Table.ManifestResource); | |
var resources = new Collection<Resource> (length); | |
for (int i = 1; i <= length; i++) { | |
var offset = ReadUInt32 (); | |
var flags = (ManifestResourceAttributes) ReadUInt32 (); | |
var name = ReadString (); | |
var implementation = ReadMetadataToken (CodedIndex.Implementation); | |
Resource resource; | |
if (implementation.RID == 0) { | |
resource = new EmbeddedResource (name, flags, offset, this); | |
} else if (implementation.TokenType == TokenType.AssemblyRef) { | |
resource = new AssemblyLinkedResource (name, flags) { | |
Assembly = (AssemblyNameReference) GetTypeReferenceScope (implementation), | |
}; | |
} else if (implementation.TokenType == TokenType.File) { | |
var file_record = ReadFileRecord (implementation.RID); | |
resource = new LinkedResource (name, flags) { | |
File = file_record.Col2, | |
hash = ReadBlob (file_record.Col3) | |
}; | |
} else | |
continue; | |
resources.Add (resource); | |
} | |
return resources; | |
} | |
Row<FileAttributes, string, uint> ReadFileRecord (uint rid) | |
{ | |
var position = this.position; | |
if (!MoveTo (Table.File, rid)) | |
throw new ArgumentException (); | |
var record = new Row<FileAttributes, string, uint> ( | |
(FileAttributes) ReadUInt32 (), | |
ReadString (), | |
ReadBlobIndex ()); | |
this.position = position; | |
return record; | |
} | |
public byte [] GetManagedResource (uint offset) | |
{ | |
return image.GetReaderAt (image.Resources.VirtualAddress, offset, (o, reader) => { | |
reader.Advance ((int) o); | |
return reader.ReadBytes (reader.ReadInt32 ()); | |
}) ?? Empty<byte>.Array; | |
} | |
void PopulateVersionAndFlags (AssemblyNameReference name) | |
{ | |
name.Version = new Version ( | |
ReadUInt16 (), | |
ReadUInt16 (), | |
ReadUInt16 (), | |
ReadUInt16 ()); | |
name.Attributes = (AssemblyAttributes) ReadUInt32 (); | |
} | |
void PopulateNameAndCulture (AssemblyNameReference name) | |
{ | |
name.Name = ReadString (); | |
name.Culture = ReadString (); | |
} | |
public TypeDefinitionCollection ReadTypes () | |
{ | |
InitializeTypeDefinitions (); | |
var mtypes = metadata.Types; | |
var type_count = mtypes.Length - metadata.NestedTypes.Count; | |
var types = new TypeDefinitionCollection (module, type_count); | |
for (int i = 0; i < mtypes.Length; i++) { | |
var type = mtypes [i]; | |
if (IsNested (type.Attributes)) | |
continue; | |
types.Add (type); | |
} | |
if (image.HasTable (Table.MethodPtr) || image.HasTable (Table.FieldPtr)) | |
CompleteTypes (); | |
return types; | |
} | |
void CompleteTypes () | |
{ | |
var types = metadata.Types; | |
for (int i = 0; i < types.Length; i++) { | |
var type = types [i]; | |
Mixin.Read (type.Fields); | |
Mixin.Read (type.Methods); | |
} | |
} | |
void InitializeTypeDefinitions () | |
{ | |
if (metadata.Types != null) | |
return; | |
InitializeNestedTypes (); | |
InitializeFields (); | |
InitializeMethods (); | |
int length = MoveTo (Table.TypeDef); | |
var types = metadata.Types = new TypeDefinition [length]; | |
for (uint i = 0; i < length; i++) { | |
if (types [i] != null) | |
continue; | |
types [i] = ReadType (i + 1); | |
} | |
if (module.IsWindowsMetadata ()) { | |
for (uint i = 0; i < length; i++) { | |
WindowsRuntimeProjections.Project (types [i]); | |
} | |
} | |
} | |
static bool IsNested (TypeAttributes attributes) | |
{ | |
switch (attributes & TypeAttributes.VisibilityMask) { | |
case TypeAttributes.NestedAssembly: | |
case TypeAttributes.NestedFamANDAssem: | |
case TypeAttributes.NestedFamily: | |
case TypeAttributes.NestedFamORAssem: | |
case TypeAttributes.NestedPrivate: | |
case TypeAttributes.NestedPublic: | |
return true; | |
default: | |
return false; | |
} | |
} | |
public bool HasNestedTypes (TypeDefinition type) | |
{ | |
Collection<uint> mapping; | |
InitializeNestedTypes (); | |
if (!metadata.TryGetNestedTypeMapping (type, out mapping)) | |
return false; | |
return mapping.Count > 0; | |
} | |
public Collection<TypeDefinition> ReadNestedTypes (TypeDefinition type) | |
{ | |
InitializeNestedTypes (); | |
Collection<uint> mapping; | |
if (!metadata.TryGetNestedTypeMapping (type, out mapping)) | |
return new MemberDefinitionCollection<TypeDefinition> (type); | |
var nested_types = new MemberDefinitionCollection<TypeDefinition> (type, mapping.Count); | |
for (int i = 0; i < mapping.Count; i++) { | |
var nested_type = GetTypeDefinition (mapping [i]); | |
if (nested_type != null) | |
nested_types.Add (nested_type); | |
} | |
metadata.RemoveNestedTypeMapping (type); | |
return nested_types; | |
} | |
void InitializeNestedTypes () | |
{ | |
if (metadata.NestedTypes != null) | |
return; | |
var length = MoveTo (Table.NestedClass); | |
metadata.NestedTypes = new Dictionary<uint, Collection<uint>> (length); | |
metadata.ReverseNestedTypes = new Dictionary<uint, uint> (length); | |
if (length == 0) | |
return; | |
for (int i = 1; i <= length; i++) { | |
var nested = ReadTableIndex (Table.TypeDef); | |
var declaring = ReadTableIndex (Table.TypeDef); | |
AddNestedMapping (declaring, nested); | |
} | |
} | |
void AddNestedMapping (uint declaring, uint nested) | |
{ | |
metadata.SetNestedTypeMapping (declaring, AddMapping (metadata.NestedTypes, declaring, nested)); | |
metadata.SetReverseNestedTypeMapping (nested, declaring); | |
} | |
static Collection<TValue> AddMapping<TKey, TValue> (Dictionary<TKey, Collection<TValue>> cache, TKey key, TValue value) | |
{ | |
Collection<TValue> mapped; | |
if (!cache.TryGetValue (key, out mapped)) { | |
mapped = new Collection<TValue> (); | |
} | |
mapped.Add (value); | |
return mapped; | |
} | |
TypeDefinition ReadType (uint rid) | |
{ | |
if (!MoveTo (Table.TypeDef, rid)) | |
return null; | |
var attributes = (TypeAttributes) ReadUInt32 (); | |
var name = ReadString (); | |
var @namespace = ReadString (); | |
var type = new TypeDefinition (@namespace, name, attributes); | |
type.token = new MetadataToken (TokenType.TypeDef, rid); | |
type.scope = module; | |
type.module = module; | |
metadata.AddTypeDefinition (type); | |
this.context = type; | |
type.BaseType = GetTypeDefOrRef (ReadMetadataToken (CodedIndex.TypeDefOrRef)); | |
type.fields_range = ReadListRange (rid, Table.TypeDef, Table.Field); | |
type.methods_range = ReadListRange (rid, Table.TypeDef, Table.Method); | |
if (IsNested (attributes)) | |
type.DeclaringType = GetNestedTypeDeclaringType (type); | |
return type; | |
} | |
TypeDefinition GetNestedTypeDeclaringType (TypeDefinition type) | |
{ | |
uint declaring_rid; | |
if (!metadata.TryGetReverseNestedTypeMapping (type, out declaring_rid)) | |
return null; | |
metadata.RemoveReverseNestedTypeMapping (type); | |
return GetTypeDefinition (declaring_rid); | |
} | |
Range ReadListRange (uint current_index, Table current, Table target) | |
{ | |
var list = new Range (); | |
var start = ReadTableIndex (target); | |
if (start == 0) | |
return list; | |
uint next_index; | |
var current_table = image.TableHeap [current]; | |
if (current_index == current_table.Length) | |
next_index = image.TableHeap [target].Length + 1; | |
else { | |
var position = this.position; | |
this.position += (int) (current_table.RowSize - image.GetTableIndexSize (target)); | |
next_index = ReadTableIndex (target); | |
this.position = position; | |
} | |
list.Start = start; | |
list.Length = next_index - start; | |
return list; | |
} | |
public Row<short, int> ReadTypeLayout (TypeDefinition type) | |
{ | |
InitializeTypeLayouts (); | |
Row<ushort, uint> class_layout; | |
var rid = type.token.RID; | |
if (!metadata.ClassLayouts.TryGetValue (rid, out class_layout)) | |
return new Row<short, int> (Mixin.NoDataMarker, Mixin.NoDataMarker); | |
type.PackingSize = (short) class_layout.Col1; | |
type.ClassSize = (int) class_layout.Col2; | |
metadata.ClassLayouts.Remove (rid); | |
return new Row<short, int> ((short) class_layout.Col1, (int) class_layout.Col2); | |
} | |
void InitializeTypeLayouts () | |
{ | |
if (metadata.ClassLayouts != null) | |
return; | |
int length = MoveTo (Table.ClassLayout); | |
var class_layouts = metadata.ClassLayouts = new Dictionary<uint, Row<ushort, uint>> (length); | |
for (uint i = 0; i < length; i++) { | |
var packing_size = ReadUInt16 (); | |
var class_size = ReadUInt32 (); | |
var parent = ReadTableIndex (Table.TypeDef); | |
class_layouts.Add (parent, new Row<ushort, uint> (packing_size, class_size)); | |
} | |
} | |
public TypeReference GetTypeDefOrRef (MetadataToken token) | |
{ | |
return (TypeReference) LookupToken (token); | |
} | |
public TypeDefinition GetTypeDefinition (uint rid) | |
{ | |
InitializeTypeDefinitions (); | |
var type = metadata.GetTypeDefinition (rid); | |
if (type != null) | |
return type; | |
type = ReadTypeDefinition (rid); | |
if (module.IsWindowsMetadata ()) | |
WindowsRuntimeProjections.Project (type); | |
return type; | |
} | |
TypeDefinition ReadTypeDefinition (uint rid) | |
{ | |
if (!MoveTo (Table.TypeDef, rid)) | |
return null; | |
return ReadType (rid); | |
} | |
void InitializeTypeReferences () | |
{ | |
if (metadata.TypeReferences != null) | |
return; | |
metadata.TypeReferences = new TypeReference [image.GetTableLength (Table.TypeRef)]; | |
} | |
public TypeReference GetTypeReference (string scope, string full_name) | |
{ | |
InitializeTypeReferences (); | |
var length = metadata.TypeReferences.Length; | |
for (uint i = 1; i <= length; i++) { | |
var type = GetTypeReference (i); | |
if (type.FullName != full_name) | |
continue; | |
if (string.IsNullOrEmpty (scope)) | |
return type; | |
if (type.Scope.Name == scope) | |
return type; | |
} | |
return null; | |
} | |
TypeReference GetTypeReference (uint rid) | |
{ | |
InitializeTypeReferences (); | |
var type = metadata.GetTypeReference (rid); | |
if (type != null) | |
return type; | |
return ReadTypeReference (rid); | |
} | |
TypeReference ReadTypeReference (uint rid) | |
{ | |
if (!MoveTo (Table.TypeRef, rid)) | |
return null; | |
TypeReference declaring_type = null; | |
IMetadataScope scope; | |
var scope_token = ReadMetadataToken (CodedIndex.ResolutionScope); | |
var name = ReadString (); | |
var @namespace = ReadString (); | |
var type = new TypeReference ( | |
@namespace, | |
name, | |
module, | |
null); | |
type.token = new MetadataToken (TokenType.TypeRef, rid); | |
metadata.AddTypeReference (type); | |
if (scope_token.TokenType == TokenType.TypeRef) { | |
declaring_type = GetTypeDefOrRef (scope_token); | |
scope = declaring_type != null | |
? declaring_type.Scope | |
: module; | |
} else | |
scope = GetTypeReferenceScope (scope_token); | |
type.scope = scope; | |
type.DeclaringType = declaring_type; | |
MetadataSystem.TryProcessPrimitiveTypeReference (type); | |
if (type.Module.IsWindowsMetadata ()) | |
WindowsRuntimeProjections.Project (type); | |
return type; | |
} | |
IMetadataScope GetTypeReferenceScope (MetadataToken scope) | |
{ | |
if (scope.TokenType == TokenType.Module) | |
return module; | |
IMetadataScope[] scopes; | |
switch (scope.TokenType) { | |
case TokenType.AssemblyRef: | |
InitializeAssemblyReferences (); | |
scopes = metadata.AssemblyReferences; | |
break; | |
case TokenType.ModuleRef: | |
InitializeModuleReferences (); | |
scopes = metadata.ModuleReferences; | |
break; | |
default: | |
throw new NotSupportedException (); | |
} | |
var index = scope.RID - 1; | |
if (index < 0 || index >= scopes.Length) | |
return null; | |
return scopes [index]; | |
} | |
public IEnumerable<TypeReference> GetTypeReferences () | |
{ | |
InitializeTypeReferences (); | |
var length = image.GetTableLength (Table.TypeRef); | |
var type_references = new TypeReference [length]; | |
for (uint i = 1; i <= length; i++) | |
type_references [i - 1] = GetTypeReference (i); | |
return type_references; | |
} | |
TypeReference GetTypeSpecification (uint rid) | |
{ | |
if (!MoveTo (Table.TypeSpec, rid)) | |
return null; | |
var reader = ReadSignature (ReadBlobIndex ()); | |
var type = reader.ReadTypeSignature (); | |
if (type.token.RID == 0) | |
type.token = new MetadataToken (TokenType.TypeSpec, rid); | |
return type; | |
} | |
SignatureReader ReadSignature (uint signature) | |
{ | |
return new SignatureReader (signature, this); | |
} | |
public bool HasInterfaces (TypeDefinition type) | |
{ | |
InitializeInterfaces (); | |
Collection<Row<uint, MetadataToken>> mapping; | |
return metadata.TryGetInterfaceMapping (type, out mapping); | |
} | |
public InterfaceImplementationCollection ReadInterfaces (TypeDefinition type) | |
{ | |
InitializeInterfaces (); | |
Collection<Row<uint, MetadataToken>> mapping; | |
if (!metadata.TryGetInterfaceMapping (type, out mapping)) | |
return new InterfaceImplementationCollection (type); | |
var interfaces = new InterfaceImplementationCollection (type, mapping.Count); | |
this.context = type; | |
for (int i = 0; i < mapping.Count; i++) { | |
interfaces.Add ( | |
new InterfaceImplementation ( | |
GetTypeDefOrRef (mapping [i].Col2), | |
new MetadataToken(TokenType.InterfaceImpl, mapping [i].Col1))); | |
} | |
metadata.RemoveInterfaceMapping (type); | |
return interfaces; | |
} | |
void InitializeInterfaces () | |
{ | |
if (metadata.Interfaces != null) | |
return; | |
int length = MoveTo (Table.InterfaceImpl); | |
metadata.Interfaces = new Dictionary<uint, Collection<Row<uint, MetadataToken>>> (length); | |
for (uint i = 1; i <= length; i++) { | |
var type = ReadTableIndex (Table.TypeDef); | |
var @interface = ReadMetadataToken (CodedIndex.TypeDefOrRef); | |
AddInterfaceMapping (type, new Row<uint, MetadataToken> (i, @interface)); | |
} | |
} | |
void AddInterfaceMapping (uint type, Row<uint, MetadataToken> @interface) | |
{ | |
metadata.SetInterfaceMapping (type, AddMapping (metadata.Interfaces, type, @interface)); | |
} | |
public Collection<FieldDefinition> ReadFields (TypeDefinition type) | |
{ | |
var fields_range = type.fields_range; | |
if (fields_range.Length == 0) | |
return new MemberDefinitionCollection<FieldDefinition> (type); | |
var fields = new MemberDefinitionCollection<FieldDefinition> (type, (int) fields_range.Length); | |
this.context = type; | |
if (!MoveTo (Table.FieldPtr, fields_range.Start)) { | |
if (!MoveTo (Table.Field, fields_range.Start)) | |
return fields; | |
for (uint i = 0; i < fields_range.Length; i++) | |
ReadField (fields_range.Start + i, fields); | |
} else | |
ReadPointers (Table.FieldPtr, Table.Field, fields_range, fields, ReadField); | |
return fields; | |
} | |
void ReadField (uint field_rid, Collection<FieldDefinition> fields) | |
{ | |
var attributes = (FieldAttributes) ReadUInt16 (); | |
var name = ReadString (); | |
var signature = ReadBlobIndex (); | |
var field = new FieldDefinition (name, attributes, ReadFieldType (signature)); | |
field.token = new MetadataToken (TokenType.Field, field_rid); | |
metadata.AddFieldDefinition (field); | |
if (IsDeleted (field)) | |
return; | |
fields.Add (field); | |
if (module.IsWindowsMetadata ()) | |
WindowsRuntimeProjections.Project (field); | |
} | |
void InitializeFields () | |
{ | |
if (metadata.Fields != null) | |
return; | |
metadata.Fields = new FieldDefinition [image.GetTableLength (Table.Field)]; | |
} | |
TypeReference ReadFieldType (uint signature) | |
{ | |
var reader = ReadSignature (signature); | |
const byte field_sig = 0x6; | |
if (reader.ReadByte () != field_sig) | |
throw new NotSupportedException (); | |
return reader.ReadTypeSignature (); | |
} | |
public int ReadFieldRVA (FieldDefinition field) | |
{ | |
InitializeFieldRVAs (); | |
var rid = field.token.RID; | |
RVA rva; | |
if (!metadata.FieldRVAs.TryGetValue (rid, out rva)) | |
return 0; | |
var size = GetFieldTypeSize (field.FieldType); | |
if (size == 0 || rva == 0) | |
return 0; | |
metadata.FieldRVAs.Remove (rid); | |
field.InitialValue = GetFieldInitializeValue (size, rva); | |
return (int) rva; | |
} | |
byte [] GetFieldInitializeValue (int size, RVA rva) | |
{ | |
return image.GetReaderAt (rva, size, (s, reader) => reader.ReadBytes (s)) ?? Empty<byte>.Array; | |
} | |
static int GetFieldTypeSize (TypeReference type) | |
{ | |
int size = 0; | |
switch (type.etype) { | |
case ElementType.Boolean: | |
case ElementType.U1: | |
case ElementType.I1: | |
size = 1; | |
break; | |
case ElementType.U2: | |
case ElementType.I2: | |
case ElementType.Char: | |
size = 2; | |
break; | |
case ElementType.U4: | |
case ElementType.I4: | |
case ElementType.R4: | |
size = 4; | |
break; | |
case ElementType.U8: | |
case ElementType.I8: | |
case ElementType.R8: | |
size = 8; | |
break; | |
case ElementType.Ptr: | |
case ElementType.FnPtr: | |
size = IntPtr.Size; | |
break; | |
case ElementType.CModOpt: | |
case ElementType.CModReqD: | |
return GetFieldTypeSize (((IModifierType) type).ElementType); | |
default: | |
var field_type = type.Resolve (); | |
if (field_type != null && field_type.HasLayoutInfo) | |
size = field_type.ClassSize; | |
break; | |
} | |
return size; | |
} | |
void InitializeFieldRVAs () | |
{ | |
if (metadata.FieldRVAs != null) | |
return; | |
int length = MoveTo (Table.FieldRVA); | |
var field_rvas = metadata.FieldRVAs = new Dictionary<uint, uint> (length); | |
for (int i = 0; i < length; i++) { | |
var rva = ReadUInt32 (); | |
var field = ReadTableIndex (Table.Field); | |
field_rvas.Add (field, rva); | |
} | |
} | |
public int ReadFieldLayout (FieldDefinition field) | |
{ | |
InitializeFieldLayouts (); | |
var rid = field.token.RID; | |
uint offset; | |
if (!metadata.FieldLayouts.TryGetValue (rid, out offset)) | |
return Mixin.NoDataMarker; | |
metadata.FieldLayouts.Remove (rid); | |
return (int) offset; | |
} | |
void InitializeFieldLayouts () | |
{ | |
if (metadata.FieldLayouts != null) | |
return; | |
int length = MoveTo (Table.FieldLayout); | |
var field_layouts = metadata.FieldLayouts = new Dictionary<uint, uint> (length); | |
for (int i = 0; i < length; i++) { | |
var offset = ReadUInt32 (); | |
var field = ReadTableIndex (Table.Field); | |
field_layouts.Add (field, offset); | |
} | |
} | |
public bool HasEvents (TypeDefinition type) | |
{ | |
InitializeEvents (); | |
Range range; | |
if (!metadata.TryGetEventsRange (type, out range)) | |
return false; | |
return range.Length > 0; | |
} | |
public Collection<EventDefinition> ReadEvents (TypeDefinition type) | |
{ | |
InitializeEvents (); | |
Range range; | |
if (!metadata.TryGetEventsRange (type, out range)) | |
return new MemberDefinitionCollection<EventDefinition> (type); | |
var events = new MemberDefinitionCollection<EventDefinition> (type, (int) range.Length); | |
metadata.RemoveEventsRange (type); | |
if (range.Length == 0) | |
return events; | |
this.context = type; | |
if (!MoveTo (Table.EventPtr, range.Start)) { | |
if (!MoveTo (Table.Event, range.Start)) | |
return events; | |
for (uint i = 0; i < range.Length; i++) | |
ReadEvent (range.Start + i, events); | |
} else | |
ReadPointers (Table.EventPtr, Table.Event, range, events, ReadEvent); | |
return events; | |
} | |
void ReadEvent (uint event_rid, Collection<EventDefinition> events) | |
{ | |
var attributes = (EventAttributes) ReadUInt16 (); | |
var name = ReadString (); | |
var event_type = GetTypeDefOrRef (ReadMetadataToken (CodedIndex.TypeDefOrRef)); | |
var @event = new EventDefinition (name, attributes, event_type); | |
@event.token = new MetadataToken (TokenType.Event, event_rid); | |
if (IsDeleted (@event)) | |
return; | |
events.Add (@event); | |
} | |
void InitializeEvents () | |
{ | |
if (metadata.Events != null) | |
return; | |
int length = MoveTo (Table.EventMap); | |
metadata.Events = new Dictionary<uint, Range> (length); | |
for (uint i = 1; i <= length; i++) { | |
var type_rid = ReadTableIndex (Table.TypeDef); | |
Range events_range = ReadListRange (i, Table.EventMap, Table.Event); | |
metadata.AddEventsRange (type_rid, events_range); | |
} | |
} | |
public bool HasProperties (TypeDefinition type) | |
{ | |
InitializeProperties (); | |
Range range; | |
if (!metadata.TryGetPropertiesRange (type, out range)) | |
return false; | |
return range.Length > 0; | |
} | |
public Collection<PropertyDefinition> ReadProperties (TypeDefinition type) | |
{ | |
InitializeProperties (); | |
Range range; | |
if (!metadata.TryGetPropertiesRange (type, out range)) | |
return new MemberDefinitionCollection<PropertyDefinition> (type); | |
metadata.RemovePropertiesRange (type); | |
var properties = new MemberDefinitionCollection<PropertyDefinition> (type, (int) range.Length); | |
if (range.Length == 0) | |
return properties; | |
this.context = type; | |
if (!MoveTo (Table.PropertyPtr, range.Start)) { | |
if (!MoveTo (Table.Property, range.Start)) | |
return properties; | |
for (uint i = 0; i < range.Length; i++) | |
ReadProperty (range.Start + i, properties); | |
} else | |
ReadPointers (Table.PropertyPtr, Table.Property, range, properties, ReadProperty); | |
return properties; | |
} | |
void ReadProperty (uint property_rid, Collection<PropertyDefinition> properties) | |
{ | |
var attributes = (PropertyAttributes) ReadUInt16 (); | |
var name = ReadString (); | |
var signature = ReadBlobIndex (); | |
var reader = ReadSignature (signature); | |
const byte property_signature = 0x8; | |
var calling_convention = reader.ReadByte (); | |
if ((calling_convention & property_signature) == 0) | |
throw new NotSupportedException (); | |
var has_this = (calling_convention & 0x20) != 0; | |
reader.ReadCompressedUInt32 (); // count | |
var property = new PropertyDefinition (name, attributes, reader.ReadTypeSignature ()); | |
property.HasThis = has_this; | |
property.token = new MetadataToken (TokenType.Property, property_rid); | |
if (IsDeleted (property)) | |
return; | |
properties.Add (property); | |
} | |
void InitializeProperties () | |
{ | |
if (metadata.Properties != null) | |
return; | |
int length = MoveTo (Table.PropertyMap); | |
metadata.Properties = new Dictionary<uint, Range> (length); | |
for (uint i = 1; i <= length; i++) { | |
var type_rid = ReadTableIndex (Table.TypeDef); | |
var properties_range = ReadListRange (i, Table.PropertyMap, Table.Property); | |
metadata.AddPropertiesRange (type_rid, properties_range); | |
} | |
} | |
MethodSemanticsAttributes ReadMethodSemantics (MethodDefinition method) | |
{ | |
InitializeMethodSemantics (); | |
Row<MethodSemanticsAttributes, MetadataToken> row; | |
if (!metadata.Semantics.TryGetValue (method.token.RID, out row)) | |
return MethodSemanticsAttributes.None; | |
var type = method.DeclaringType; | |
switch (row.Col1) { | |
case MethodSemanticsAttributes.AddOn: | |
GetEvent (type, row.Col2).add_method = method; | |
break; | |
case MethodSemanticsAttributes.Fire: | |
GetEvent (type, row.Col2).invoke_method = method; | |
break; | |
case MethodSemanticsAttributes.RemoveOn: | |
GetEvent (type, row.Col2).remove_method = method; | |
break; | |
case MethodSemanticsAttributes.Getter: | |
GetProperty (type, row.Col2).get_method = method; | |
break; | |
case MethodSemanticsAttributes.Setter: | |
GetProperty (type, row.Col2).set_method = method; | |
break; | |
case MethodSemanticsAttributes.Other: | |
switch (row.Col2.TokenType) { | |
case TokenType.Event: { | |
var @event = GetEvent (type, row.Col2); | |
if (@event.other_methods == null) | |
@event.other_methods = new Collection<MethodDefinition> (); | |
@event.other_methods.Add (method); | |
break; | |
} | |
case TokenType.Property: { | |
var property = GetProperty (type, row.Col2); | |
if (property.other_methods == null) | |
property.other_methods = new Collection<MethodDefinition> (); | |
property.other_methods.Add (method); | |
break; | |
} | |
default: | |
throw new NotSupportedException (); | |
} | |
break; | |
default: | |
throw new NotSupportedException (); | |
} | |
metadata.Semantics.Remove (method.token.RID); | |
return row.Col1; | |
} | |
static EventDefinition GetEvent (TypeDefinition type, MetadataToken token) | |
{ | |
if (token.TokenType != TokenType.Event) | |
throw new ArgumentException (); | |
return GetMember (type.Events, token); | |
} | |
static PropertyDefinition GetProperty (TypeDefinition type, MetadataToken token) | |
{ | |
if (token.TokenType != TokenType.Property) | |
throw new ArgumentException (); | |
return GetMember (type.Properties, token); | |
} | |
static TMember GetMember<TMember> (Collection<TMember> members, MetadataToken token) where TMember : IMemberDefinition | |
{ | |
for (int i = 0; i < members.Count; i++) { | |
var member = members [i]; | |
if (member.MetadataToken == token) | |
return member; | |
} | |
throw new ArgumentException (); | |
} | |
void InitializeMethodSemantics () | |
{ | |
if (metadata.Semantics != null) | |
return; | |
int length = MoveTo (Table.MethodSemantics); | |
var semantics = metadata.Semantics = new Dictionary<uint, Row<MethodSemanticsAttributes, MetadataToken>> (0); | |
for (uint i = 0; i < length; i++) { | |
var attributes = (MethodSemanticsAttributes) ReadUInt16 (); | |
var method_rid = ReadTableIndex (Table.Method); | |
var association = ReadMetadataToken (CodedIndex.HasSemantics); | |
semantics [method_rid] = new Row<MethodSemanticsAttributes, MetadataToken> (attributes, association); | |
} | |
} | |
public void ReadMethods (PropertyDefinition property) | |
{ | |
ReadAllSemantics (property.DeclaringType); | |
} | |
public void ReadMethods (EventDefinition @event) | |
{ | |
ReadAllSemantics (@event.DeclaringType); | |
} | |
public void ReadAllSemantics (MethodDefinition method) | |
{ | |
ReadAllSemantics (method.DeclaringType); | |
} | |
void ReadAllSemantics (TypeDefinition type) | |
{ | |
var methods = type.Methods; | |
for (int i = 0; i < methods.Count; i++) { | |
var method = methods [i]; | |
if (method.sem_attrs_ready) | |
continue; | |
method.sem_attrs = ReadMethodSemantics (method); | |
method.sem_attrs_ready = true; | |
} | |
} | |
public Collection<MethodDefinition> ReadMethods (TypeDefinition type) | |
{ | |
var methods_range = type.methods_range; | |
if (methods_range.Length == 0) | |
return new MemberDefinitionCollection<MethodDefinition> (type); | |
var methods = new MemberDefinitionCollection<MethodDefinition> (type, (int) methods_range.Length); | |
if (!MoveTo (Table.MethodPtr, methods_range.Start)) { | |
if (!MoveTo (Table.Method, methods_range.Start)) | |
return methods; | |
for (uint i = 0; i < methods_range.Length; i++) | |
ReadMethod (methods_range.Start + i, methods); | |
} else | |
ReadPointers (Table.MethodPtr, Table.Method, methods_range, methods, ReadMethod); | |
return methods; | |
} | |
void ReadPointers<TMember> (Table ptr, Table table, Range range, Collection<TMember> members, Action<uint, Collection<TMember>> reader) | |
where TMember : IMemberDefinition | |
{ | |
for (uint i = 0; i < range.Length; i++) { | |
MoveTo (ptr, range.Start + i); | |
var rid = ReadTableIndex (table); | |
MoveTo (table, rid); | |
reader (rid, members); | |
} | |
} | |
static bool IsDeleted (IMemberDefinition member) | |
{ | |
return member.IsSpecialName && member.Name == "_Deleted"; | |
} | |
void InitializeMethods () | |
{ | |
if (metadata.Methods != null) | |
return; | |
metadata.Methods = new MethodDefinition [image.GetTableLength (Table.Method)]; | |
} | |
void ReadMethod (uint method_rid, Collection<MethodDefinition> methods) | |
{ | |
var method = new MethodDefinition (); | |
method.rva = ReadUInt32 (); | |
method.ImplAttributes = (MethodImplAttributes) ReadUInt16 (); | |
method.Attributes = (MethodAttributes) ReadUInt16 (); | |
method.Name = ReadString (); | |
method.token = new MetadataToken (TokenType.Method, method_rid); | |
if (IsDeleted (method)) | |
return; | |
methods.Add (method); // attach method | |
var signature = ReadBlobIndex (); | |
var param_range = ReadListRange (method_rid, Table.Method, Table.Param); | |
this.context = method; | |
ReadMethodSignature (signature, method); | |
metadata.AddMethodDefinition (method); | |
if (param_range.Length != 0) { | |
var position = base.position; | |
ReadParameters (method, param_range); | |
base.position = position; | |
} | |
if (module.IsWindowsMetadata ()) | |
WindowsRuntimeProjections.Project (method); | |
} | |
void ReadParameters (MethodDefinition method, Range param_range) | |
{ | |
if (!MoveTo (Table.ParamPtr, param_range.Start)) { | |
if (!MoveTo (Table.Param, param_range.Start)) | |
return; | |
for (uint i = 0; i < param_range.Length; i++) | |
ReadParameter (param_range.Start + i, method); | |
} else | |
ReadParameterPointers (method, param_range); | |
} | |
void ReadParameterPointers (MethodDefinition method, Range range) | |
{ | |
for (uint i = 0; i < range.Length; i++) { | |
MoveTo (Table.ParamPtr, range.Start + i); | |
var rid = ReadTableIndex (Table.Param); | |
MoveTo (Table.Param, rid); | |
ReadParameter (rid, method); | |
} | |
} | |
void ReadParameter (uint param_rid, MethodDefinition method) | |
{ | |
var attributes = (ParameterAttributes) ReadUInt16 (); | |
var sequence = ReadUInt16 (); | |
var name = ReadString (); | |
var parameter = sequence == 0 | |
? method.MethodReturnType.Parameter | |
: method.Parameters [sequence - 1]; | |
parameter.token = new MetadataToken (TokenType.Param, param_rid); | |
parameter.Name = name; | |
parameter.Attributes = attributes; | |
} | |
void ReadMethodSignature (uint signature, IMethodSignature method) | |
{ | |
var reader = ReadSignature (signature); | |
reader.ReadMethodSignature (method); | |
} | |
public PInvokeInfo ReadPInvokeInfo (MethodDefinition method) | |
{ | |
InitializePInvokes (); | |
Row<PInvokeAttributes, uint, uint> row; | |
var rid = method.token.RID; | |
if (!metadata.PInvokes.TryGetValue (rid, out row)) | |
return null; | |
metadata.PInvokes.Remove (rid); | |
return new PInvokeInfo ( | |
row.Col1, | |
image.StringHeap.Read (row.Col2), | |
module.ModuleReferences [(int) row.Col3 - 1]); | |
} | |
void InitializePInvokes () | |
{ | |
if (metadata.PInvokes != null) | |
return; | |
int length = MoveTo (Table.ImplMap); | |
var pinvokes = metadata.PInvokes = new Dictionary<uint, Row<PInvokeAttributes, uint, uint>> (length); | |
for (int i = 1; i <= length; i++) { | |
var attributes = (PInvokeAttributes) ReadUInt16 (); | |
var method = ReadMetadataToken (CodedIndex.MemberForwarded); | |
var name = ReadStringIndex (); | |
var scope = ReadTableIndex (Table.File); | |
if (method.TokenType != TokenType.Method) | |
continue; | |
pinvokes.Add (method.RID, new Row<PInvokeAttributes, uint, uint> (attributes, name, scope)); | |
} | |
} | |
public bool HasGenericParameters (IGenericParameterProvider provider) | |
{ | |
InitializeGenericParameters (); | |
Range [] ranges; | |
if (!metadata.TryGetGenericParameterRanges (provider, out ranges)) | |
return false; | |
return RangesSize (ranges) > 0; | |
} | |
public Collection<GenericParameter> ReadGenericParameters (IGenericParameterProvider provider) | |
{ | |
InitializeGenericParameters (); | |
Range [] ranges; | |
if (!metadata.TryGetGenericParameterRanges (provider, out ranges)) | |
return new GenericParameterCollection (provider); | |
metadata.RemoveGenericParameterRange (provider); | |
var generic_parameters = new GenericParameterCollection (provider, RangesSize (ranges)); | |
for (int i = 0; i < ranges.Length; i++) | |
ReadGenericParametersRange (ranges [i], provider, generic_parameters); | |
return generic_parameters; | |
} | |
void ReadGenericParametersRange (Range range, IGenericParameterProvider provider, GenericParameterCollection generic_parameters) | |
{ | |
if (!MoveTo (Table.GenericParam, range.Start)) | |
return; | |
for (uint i = 0; i < range.Length; i++) { | |
ReadUInt16 (); // index | |
var flags = (GenericParameterAttributes) ReadUInt16 (); | |
ReadMetadataToken (CodedIndex.TypeOrMethodDef); | |
var name = ReadString (); | |
var parameter = new GenericParameter (name, provider); | |
parameter.token = new MetadataToken (TokenType.GenericParam, range.Start + i); | |
parameter.Attributes = flags; | |
generic_parameters.Add (parameter); | |
} | |
} | |
void InitializeGenericParameters () | |
{ | |
if (metadata.GenericParameters != null) | |
return; | |
metadata.GenericParameters = InitializeRanges ( | |
Table.GenericParam, () => { | |
Advance (4); | |
var next = ReadMetadataToken (CodedIndex.TypeOrMethodDef); | |
ReadStringIndex (); | |
return next; | |
}); | |
} | |
Dictionary<MetadataToken, Range []> InitializeRanges (Table table, Func<MetadataToken> get_next) | |
{ | |
int length = MoveTo (table); | |
var ranges = new Dictionary<MetadataToken, Range []> (length); | |
if (length == 0) | |
return ranges; | |
MetadataToken owner = MetadataToken.Zero; | |
Range range = new Range (1, 0); | |
for (uint i = 1; i <= length; i++) { | |
var next = get_next (); | |
if (i == 1) { | |
owner = next; | |
range.Length++; | |
} else if (next != owner) { | |
AddRange (ranges, owner, range); | |
range = new Range (i, 1); | |
owner = next; | |
} else | |
range.Length++; | |
} | |
AddRange (ranges, owner, range); | |
return ranges; | |
} | |
static void AddRange (Dictionary<MetadataToken, Range []> ranges, MetadataToken owner, Range range) | |
{ | |
if (owner.RID == 0) | |
return; | |
Range [] slots; | |
if (!ranges.TryGetValue (owner, out slots)) { | |
ranges.Add (owner, new [] { range }); | |
return; | |
} | |
ranges [owner] = slots.Add(range); | |
} | |
public bool HasGenericConstraints (GenericParameter generic_parameter) | |
{ | |
InitializeGenericConstraints (); | |
Collection<MetadataToken> mapping; | |
if (!metadata.TryGetGenericConstraintMapping (generic_parameter, out mapping)) | |
return false; | |
return mapping.Count > 0; | |
} | |
public Collection<TypeReference> ReadGenericConstraints (GenericParameter generic_parameter) | |
{ | |
InitializeGenericConstraints (); | |
Collection<MetadataToken> mapping; | |
if (!metadata.TryGetGenericConstraintMapping (generic_parameter, out mapping)) | |
return new Collection<TypeReference> (); | |
var constraints = new Collection<TypeReference> (mapping.Count); | |
this.context = (IGenericContext) generic_parameter.Owner; | |
for (int i = 0; i < mapping.Count; i++) | |
constraints.Add (GetTypeDefOrRef (mapping [i])); | |
metadata.RemoveGenericConstraintMapping (generic_parameter); | |
return constraints; | |
} | |
void InitializeGenericConstraints () | |
{ | |
if (metadata.GenericConstraints != null) | |
return; | |
var length = MoveTo (Table.GenericParamConstraint); | |
metadata.GenericConstraints = new Dictionary<uint, Collection<MetadataToken>> (length); | |
for (int i = 1; i <= length; i++) | |
AddGenericConstraintMapping ( | |
ReadTableIndex (Table.GenericParam), | |
ReadMetadataToken (CodedIndex.TypeDefOrRef)); | |
} | |
void AddGenericConstraintMapping (uint generic_parameter, MetadataToken constraint) | |
{ | |
metadata.SetGenericConstraintMapping ( | |
generic_parameter, | |
AddMapping (metadata.GenericConstraints, generic_parameter, constraint)); | |
} | |
public bool HasOverrides (MethodDefinition method) | |
{ | |
InitializeOverrides (); | |
Collection<MetadataToken> mapping; | |
if (!metadata.TryGetOverrideMapping (method, out mapping)) | |
return false; | |
return mapping.Count > 0; | |
} | |
public Collection<MethodReference> ReadOverrides (MethodDefinition method) | |
{ | |
InitializeOverrides (); | |
Collection<MetadataToken> mapping; | |
if (!metadata.TryGetOverrideMapping (method, out mapping)) | |
return new Collection<MethodReference> (); | |
var overrides = new Collection<MethodReference> (mapping.Count); | |
this.context = method; | |
for (int i = 0; i < mapping.Count; i++) | |
overrides.Add ((MethodReference) LookupToken (mapping [i])); | |
metadata.RemoveOverrideMapping (method); | |
return overrides; | |
} | |
void InitializeOverrides () | |
{ | |
if (metadata.Overrides != null) | |
return; | |
var length = MoveTo (Table.MethodImpl); | |
metadata.Overrides = new Dictionary<uint, Collection<MetadataToken>> (length); | |
for (int i = 1; i <= length; i++) { | |
ReadTableIndex (Table.TypeDef); | |
var method = ReadMetadataToken (CodedIndex.MethodDefOrRef); | |
if (method.TokenType != TokenType.Method) | |
throw new NotSupportedException (); | |
var @override = ReadMetadataToken (CodedIndex.MethodDefOrRef); | |
AddOverrideMapping (method.RID, @override); | |
} | |
} | |
void AddOverrideMapping (uint method_rid, MetadataToken @override) | |
{ | |
metadata.SetOverrideMapping ( | |
method_rid, | |
AddMapping (metadata.Overrides, method_rid, @override)); | |
} | |
public MethodBody ReadMethodBody (MethodDefinition method) | |
{ | |
return code.ReadMethodBody (method); | |
} | |
public int ReadCodeSize (MethodDefinition method) | |
{ | |
return code.ReadCodeSize (method); | |
} | |
public CallSite ReadCallSite (MetadataToken token) | |
{ | |
if (!MoveTo (Table.StandAloneSig, token.RID)) | |
return null; | |
var signature = ReadBlobIndex (); | |
var call_site = new CallSite (); | |
ReadMethodSignature (signature, call_site); | |
call_site.MetadataToken = token; | |
return call_site; | |
} | |
public VariableDefinitionCollection ReadVariables (MetadataToken local_var_token) | |
{ | |
if (!MoveTo (Table.StandAloneSig, local_var_token.RID)) | |
return null; | |
var reader = ReadSignature (ReadBlobIndex ()); | |
const byte local_sig = 0x7; | |
if (reader.ReadByte () != local_sig) | |
throw new NotSupportedException (); | |
var count = reader.ReadCompressedUInt32 (); | |
if (count == 0) | |
return null; | |
var variables = new VariableDefinitionCollection ((int) count); | |
for (int i = 0; i < count; i++) | |
variables.Add (new VariableDefinition (reader.ReadTypeSignature ())); | |
return variables; | |
} | |
public IMetadataTokenProvider LookupToken (MetadataToken token) | |
{ | |
var rid = token.RID; | |
if (rid == 0) | |
return null; | |
if (metadata_reader != null) | |
return metadata_reader.LookupToken (token); | |
IMetadataTokenProvider element; | |
var position = this.position; | |
var context = this.context; | |
switch (token.TokenType) { | |
case TokenType.TypeDef: | |
element = GetTypeDefinition (rid); | |
break; | |
case TokenType.TypeRef: | |
element = GetTypeReference (rid); | |
break; | |
case TokenType.TypeSpec: | |
element = GetTypeSpecification (rid); | |
break; | |
case TokenType.Field: | |
element = GetFieldDefinition (rid); | |
break; | |
case TokenType.Method: | |
element = GetMethodDefinition (rid); | |
break; | |
case TokenType.MemberRef: | |
element = GetMemberReference (rid); | |
break; | |
case TokenType.MethodSpec: | |
element = GetMethodSpecification (rid); | |
break; | |
default: | |
return null; | |
} | |
this.position = position; | |
this.context = context; | |
return element; | |
} | |
public FieldDefinition GetFieldDefinition (uint rid) | |
{ | |
InitializeTypeDefinitions (); | |
var field = metadata.GetFieldDefinition (rid); | |
if (field != null) | |
return field; | |
return LookupField (rid); | |
} | |
FieldDefinition LookupField (uint rid) | |
{ | |
var type = metadata.GetFieldDeclaringType (rid); | |
if (type == null) | |
return null; | |
Mixin.Read (type.Fields); | |
return metadata.GetFieldDefinition (rid); | |
} | |
public MethodDefinition GetMethodDefinition (uint rid) | |
{ | |
InitializeTypeDefinitions (); | |
var method = metadata.GetMethodDefinition (rid); | |
if (method != null) | |
return method; | |
return LookupMethod (rid); | |
} | |
MethodDefinition LookupMethod (uint rid) | |
{ | |
var type = metadata.GetMethodDeclaringType (rid); | |
if (type == null) | |
return null; | |
Mixin.Read (type.Methods); | |
return metadata.GetMethodDefinition (rid); | |
} | |
MethodSpecification GetMethodSpecification (uint rid) | |
{ | |
if (!MoveTo (Table.MethodSpec, rid)) | |
return null; | |
var element_method = (MethodReference) LookupToken ( | |
ReadMetadataToken (CodedIndex.MethodDefOrRef)); | |
var signature = ReadBlobIndex (); | |
var method_spec = ReadMethodSpecSignature (signature, element_method); | |
method_spec.token = new MetadataToken (TokenType.MethodSpec, rid); | |
return method_spec; | |
} | |
MethodSpecification ReadMethodSpecSignature (uint signature, MethodReference method) | |
{ | |
var reader = ReadSignature (signature); | |
const byte methodspec_sig = 0x0a; | |
var call_conv = reader.ReadByte (); | |
if (call_conv != methodspec_sig) | |
throw new NotSupportedException (); | |
var instance = new GenericInstanceMethod (method); | |
reader.ReadGenericInstanceSignature (method, instance); | |
return instance; | |
} | |
MemberReference GetMemberReference (uint rid) | |
{ | |
InitializeMemberReferences (); | |
var member = metadata.GetMemberReference (rid); | |
if (member != null) | |
return member; | |
member = ReadMemberReference (rid); | |
if (member != null && !member.ContainsGenericParameter) | |
metadata.AddMemberReference (member); | |
return member; | |
} | |
MemberReference ReadMemberReference (uint rid) | |
{ | |
if (!MoveTo (Table.MemberRef, rid)) | |
return null; | |
var token = ReadMetadataToken (CodedIndex.MemberRefParent); | |
var name = ReadString (); | |
var signature = ReadBlobIndex (); | |
MemberReference member; | |
switch (token.TokenType) { | |
case TokenType.TypeDef: | |
case TokenType.TypeRef: | |
case TokenType.TypeSpec: | |
member = ReadTypeMemberReference (token, name, signature); | |
break; | |
case TokenType.Method: | |
member = ReadMethodMemberReference (token, name, signature); | |
break; | |
default: | |
throw new NotSupportedException (); | |
} | |
member.token = new MetadataToken (TokenType.MemberRef, rid); | |
if (module.IsWindowsMetadata ()) | |
WindowsRuntimeProjections.Project (member); | |
return member; | |
} | |
MemberReference ReadTypeMemberReference (MetadataToken type, string name, uint signature) | |
{ | |
var declaring_type = GetTypeDefOrRef (type); | |
if (!declaring_type.IsArray) | |
this.context = declaring_type; | |
var member = ReadMemberReferenceSignature (signature, declaring_type); | |
member.Name = name; | |
return member; | |
} | |
MemberReference ReadMemberReferenceSignature (uint signature, TypeReference declaring_type) | |
{ | |
var reader = ReadSignature (signature); | |
const byte field_sig = 0x6; | |
if (reader.buffer [reader.position] == field_sig) { | |
reader.position++; | |
var field = new FieldReference (); | |
field.DeclaringType = declaring_type; | |
field.FieldType = reader.ReadTypeSignature (); | |
return field; | |
} else { | |
var method = new MethodReference (); | |
method.DeclaringType = declaring_type; | |
reader.ReadMethodSignature (method); | |
return method; | |
} | |
} | |
MemberReference ReadMethodMemberReference (MetadataToken token, string name, uint signature) | |
{ | |
var method = GetMethodDefinition (token.RID); | |
this.context = method; | |
var member = ReadMemberReferenceSignature (signature, method.DeclaringType); | |
member.Name = name; | |
return member; | |
} | |
void InitializeMemberReferences () | |
{ | |
if (metadata.MemberReferences != null) | |
return; | |
metadata.MemberReferences = new MemberReference [image.GetTableLength (Table.MemberRef)]; | |
} | |
public IEnumerable<MemberReference> GetMemberReferences () | |
{ | |
InitializeMemberReferences (); | |
var length = image.GetTableLength (Table.MemberRef); | |
var type_system = module.TypeSystem; | |
var context = new MethodDefinition (string.Empty, MethodAttributes.Static, type_system.Void); | |
context.DeclaringType = new TypeDefinition (string.Empty, string.Empty, TypeAttributes.Public); | |
var member_references = new MemberReference [length]; | |
for (uint i = 1; i <= length; i++) { | |
this.context = context; | |
member_references [i - 1] = GetMemberReference (i); | |
} | |
return member_references; | |
} | |
void InitializeConstants () | |
{ | |
if (metadata.Constants != null) | |
return; | |
var length = MoveTo (Table.Constant); | |
var constants = metadata.Constants = new Dictionary<MetadataToken, Row<ElementType, uint>> (length); | |
for (uint i = 1; i <= length; i++) { | |
var type = (ElementType) ReadUInt16 (); | |
var owner = ReadMetadataToken (CodedIndex.HasConstant); | |
var signature = ReadBlobIndex (); | |
constants.Add (owner, new Row<ElementType, uint> (type, signature)); | |
} | |
} | |
public TypeReference ReadConstantSignature (MetadataToken token) | |
{ | |
if (token.TokenType != TokenType.Signature) | |
throw new NotSupportedException (); | |
if (token.RID == 0) | |
return null; | |
if (!MoveTo (Table.StandAloneSig, token.RID)) | |
return null; | |
return ReadFieldType (ReadBlobIndex ()); | |
} | |
public object ReadConstant (IConstantProvider owner) | |
{ | |
InitializeConstants (); | |
Row<ElementType, uint> row; | |
if (!metadata.Constants.TryGetValue (owner.MetadataToken, out row)) | |
return Mixin.NoValue; | |
metadata.Constants.Remove (owner.MetadataToken); | |
return ReadConstantValue (row.Col1, row.Col2); | |
} | |
object ReadConstantValue (ElementType etype, uint signature) | |
{ | |
switch (etype) { | |
case ElementType.Class: | |
case ElementType.Object: | |
return null; | |
case ElementType.String: | |
return ReadConstantString (signature); | |
default: | |
return ReadConstantPrimitive (etype, signature); | |
} | |
} | |
string ReadConstantString (uint signature) | |
{ | |
byte [] blob; | |
int index, count; | |
GetBlobView (signature, out blob, out index, out count); | |
if (count == 0) | |
return string.Empty; | |
if ((count & 1) == 1) | |
count--; | |
return Encoding.Unicode.GetString (blob, index, count); | |
} | |
object ReadConstantPrimitive (ElementType type, uint signature) | |
{ | |
var reader = ReadSignature (signature); | |
return reader.ReadConstantSignature (type); | |
} | |
internal void InitializeCustomAttributes () | |
{ | |
if (metadata.CustomAttributes != null) | |
return; | |
metadata.CustomAttributes = InitializeRanges ( | |
Table.CustomAttribute, () => { | |
var next = ReadMetadataToken (CodedIndex.HasCustomAttribute); | |
ReadMetadataToken (CodedIndex.CustomAttributeType); | |
ReadBlobIndex (); | |
return next; | |
}); | |
} | |
public bool HasCustomAttributes (ICustomAttributeProvider owner) | |
{ | |
InitializeCustomAttributes (); | |
Range [] ranges; | |
if (!metadata.TryGetCustomAttributeRanges (owner, out ranges)) | |
return false; | |
return RangesSize (ranges) > 0; | |
} | |
public Collection<CustomAttribute> ReadCustomAttributes (ICustomAttributeProvider owner) | |
{ | |
InitializeCustomAttributes (); | |
Range [] ranges; | |
if (!metadata.TryGetCustomAttributeRanges (owner, out ranges)) | |
return new Collection<CustomAttribute> (); | |
var custom_attributes = new Collection<CustomAttribute> (RangesSize (ranges)); | |
for (int i = 0; i < ranges.Length; i++) | |
ReadCustomAttributeRange (ranges [i], custom_attributes); | |
metadata.RemoveCustomAttributeRange (owner); | |
if (module.IsWindowsMetadata ()) | |
foreach (var custom_attribute in custom_attributes) | |
WindowsRuntimeProjections.Project (owner, custom_attribute); | |
return custom_attributes; | |
} | |
void ReadCustomAttributeRange (Range range, Collection<CustomAttribute> custom_attributes) | |
{ | |
if (!MoveTo (Table.CustomAttribute, range.Start)) | |
return; | |
for (var i = 0; i < range.Length; i++) { | |
ReadMetadataToken (CodedIndex.HasCustomAttribute); | |
var constructor = (MethodReference) LookupToken ( | |
ReadMetadataToken (CodedIndex.CustomAttributeType)); | |
var signature = ReadBlobIndex (); | |
custom_attributes.Add (new CustomAttribute (signature, constructor)); | |
} | |
} | |
static int RangesSize (Range [] ranges) | |
{ | |
uint size = 0; | |
for (int i = 0; i < ranges.Length; i++) | |
size += ranges [i].Length; | |
return (int) size; | |
} | |
public IEnumerable<CustomAttribute> GetCustomAttributes () | |
{ | |
InitializeTypeDefinitions (); | |
var length = image.TableHeap [Table.CustomAttribute].Length; | |
var custom_attributes = new Collection<CustomAttribute> ((int) length); | |
ReadCustomAttributeRange (new Range (1, length), custom_attributes); | |
return custom_attributes; | |
} | |
public byte [] ReadCustomAttributeBlob (uint signature) | |
{ | |
return ReadBlob (signature); | |
} | |
public void ReadCustomAttributeSignature (CustomAttribute attribute) | |
{ | |
var reader = ReadSignature (attribute.signature); | |
if (!reader.CanReadMore ()) | |
return; | |
if (reader.ReadUInt16 () != 0x0001) | |
throw new InvalidOperationException (); | |
var constructor = attribute.Constructor; | |
if (constructor.HasParameters) | |
reader.ReadCustomAttributeConstructorArguments (attribute, constructor.Parameters); | |
if (!reader.CanReadMore ()) | |
return; | |
var named = reader.ReadUInt16 (); | |
if (named == 0) | |
return; | |
reader.ReadCustomAttributeNamedArguments (named, ref attribute.fields, ref attribute.properties); | |
} | |
void InitializeMarshalInfos () | |
{ | |
if (metadata.FieldMarshals != null) | |
return; | |
var length = MoveTo (Table.FieldMarshal); | |
var marshals = metadata.FieldMarshals = new Dictionary<MetadataToken, uint> (length); | |
for (int i = 0; i < length; i++) { | |
var token = ReadMetadataToken (CodedIndex.HasFieldMarshal); | |
var signature = ReadBlobIndex (); | |
if (token.RID == 0) | |
continue; | |
marshals.Add (token, signature); | |
} | |
} | |
public bool HasMarshalInfo (IMarshalInfoProvider owner) | |
{ | |
InitializeMarshalInfos (); | |
return metadata.FieldMarshals.ContainsKey (owner.MetadataToken); | |
} | |
public MarshalInfo ReadMarshalInfo (IMarshalInfoProvider owner) | |
{ | |
InitializeMarshalInfos (); | |
uint signature; | |
if (!metadata.FieldMarshals.TryGetValue (owner.MetadataToken, out signature)) | |
return null; | |
var reader = ReadSignature (signature); | |
metadata.FieldMarshals.Remove (owner.MetadataToken); | |
return reader.ReadMarshalInfo (); | |
} | |
void InitializeSecurityDeclarations () | |
{ | |
if (metadata.SecurityDeclarations != null) | |
return; | |
metadata.SecurityDeclarations = InitializeRanges ( | |
Table.DeclSecurity, () => { | |
ReadUInt16 (); | |
var next = ReadMetadataToken (CodedIndex.HasDeclSecurity); | |
ReadBlobIndex (); | |
return next; | |
}); | |
} | |
public bool HasSecurityDeclarations (ISecurityDeclarationProvider owner) | |
{ | |
InitializeSecurityDeclarations (); | |
Range [] ranges; | |
if (!metadata.TryGetSecurityDeclarationRanges (owner, out ranges)) | |
return false; | |
return RangesSize (ranges) > 0; | |
} | |
public Collection<SecurityDeclaration> ReadSecurityDeclarations (ISecurityDeclarationProvider owner) | |
{ | |
InitializeSecurityDeclarations (); | |
Range [] ranges; | |
if (!metadata.TryGetSecurityDeclarationRanges (owner, out ranges)) | |
return new Collection<SecurityDeclaration> (); | |
var security_declarations = new Collection<SecurityDeclaration> (RangesSize (ranges)); | |
for (int i = 0; i < ranges.Length; i++) | |
ReadSecurityDeclarationRange (ranges [i], security_declarations); | |
metadata.RemoveSecurityDeclarationRange (owner); | |
return security_declarations; | |
} | |
void ReadSecurityDeclarationRange (Range range, Collection<SecurityDeclaration> security_declarations) | |
{ | |
if (!MoveTo (Table.DeclSecurity, range.Start)) | |
return; | |
for (int i = 0; i < range.Length; i++) { | |
var action = (SecurityAction) ReadUInt16 (); | |
ReadMetadataToken (CodedIndex.HasDeclSecurity); | |
var signature = ReadBlobIndex (); | |
security_declarations.Add (new SecurityDeclaration (action, signature, module)); | |
} | |
} | |
public byte [] ReadSecurityDeclarationBlob (uint signature) | |
{ | |
return ReadBlob (signature); | |
} | |
public void ReadSecurityDeclarationSignature (SecurityDeclaration declaration) | |
{ | |
var signature = declaration.signature; | |
var reader = ReadSignature (signature); | |
if (reader.buffer [reader.position] != '.') { | |
ReadXmlSecurityDeclaration (signature, declaration); | |
return; | |
} | |
reader.position++; | |
var count = reader.ReadCompressedUInt32 (); | |
var attributes = new Collection<SecurityAttribute> ((int) count); | |
for (int i = 0; i < count; i++) | |
attributes.Add (reader.ReadSecurityAttribute ()); | |
declaration.security_attributes = attributes; | |
} | |
void ReadXmlSecurityDeclaration (uint signature, SecurityDeclaration declaration) | |
{ | |
var attributes = new Collection<SecurityAttribute> (1); | |
var attribute = new SecurityAttribute ( | |
module.TypeSystem.LookupType ("System.Security.Permissions", "PermissionSetAttribute")); | |
attribute.properties = new Collection<CustomAttributeNamedArgument> (1); | |
attribute.properties.Add ( | |
new CustomAttributeNamedArgument ( | |
"XML", | |
new CustomAttributeArgument ( | |
module.TypeSystem.String, | |
ReadUnicodeStringBlob (signature)))); | |
attributes.Add (attribute); | |
declaration.security_attributes = attributes; | |
} | |
public Collection<ExportedType> ReadExportedTypes () | |
{ | |
var length = MoveTo (Table.ExportedType); | |
if (length == 0) | |
return new Collection<ExportedType> (); | |
var exported_types = new Collection<ExportedType> (length); | |
for (int i = 1; i <= length; i++) { | |
var attributes = (TypeAttributes) ReadUInt32 (); | |
var identifier = ReadUInt32 (); | |
var name = ReadString (); | |
var @namespace = ReadString (); | |
var implementation = ReadMetadataToken (CodedIndex.Implementation); | |
ExportedType declaring_type = null; | |
IMetadataScope scope = null; | |
switch (implementation.TokenType) { | |
case TokenType.AssemblyRef: | |
case TokenType.File: | |
scope = GetExportedTypeScope (implementation); | |
break; | |
case TokenType.ExportedType: | |
// FIXME: if the table is not properly sorted | |
declaring_type = exported_types [(int) implementation.RID - 1]; | |
break; | |
} | |
var exported_type = new ExportedType (@namespace, name, module, scope) { | |
Attributes = attributes, | |
Identifier = (int) identifier, | |
DeclaringType = declaring_type, | |
}; | |
exported_type.token = new MetadataToken (TokenType.ExportedType, i); | |
exported_types.Add (exported_type); | |
} | |
return exported_types; | |
} | |
IMetadataScope GetExportedTypeScope (MetadataToken token) | |
{ | |
var position = this.position; | |
IMetadataScope scope; | |
switch (token.TokenType) { | |
case TokenType.AssemblyRef: | |
InitializeAssemblyReferences (); | |
scope = metadata.GetAssemblyNameReference (token.RID); | |
break; | |
case TokenType.File: | |
InitializeModuleReferences (); | |
scope = GetModuleReferenceFromFile (token); | |
break; | |
default: | |
throw new NotSupportedException (); | |
} | |
this.position = position; | |
return scope; | |
} | |
ModuleReference GetModuleReferenceFromFile (MetadataToken token) | |
{ | |
if (!MoveTo (Table.File, token.RID)) | |
return null; | |
ReadUInt32 (); | |
var file_name = ReadString (); | |
var modules = module.ModuleReferences; | |
ModuleReference reference; | |
for (int i = 0; i < modules.Count; i++) { | |
reference = modules [i]; | |
if (reference.Name == file_name) | |
return reference; | |
} | |
reference = new ModuleReference (file_name); | |
modules.Add (reference); | |
return reference; | |
} | |
void InitializeDocuments () | |
{ | |
if (metadata.Documents != null) | |
return; | |
int length = MoveTo (Table.Document); | |
var documents = metadata.Documents = new Document [length]; | |
for (uint i = 1; i <= length; i++) { | |
var name_index = ReadBlobIndex (); | |
var hash_algorithm = ReadGuid (); | |
var hash = ReadBlob (); | |
var language = ReadGuid (); | |
var signature = ReadSignature (name_index); | |
var name = signature.ReadDocumentName (); | |
documents [i - 1] = new Document (name) { | |
HashAlgorithmGuid = hash_algorithm, | |
Hash = hash, | |
LanguageGuid = language, | |
token = new MetadataToken (TokenType.Document, i), | |
}; | |
} | |
} | |
public Collection<SequencePoint> ReadSequencePoints (MethodDefinition method) | |
{ | |
InitializeDocuments (); | |
if (!MoveTo (Table.MethodDebugInformation, method.MetadataToken.RID)) | |
return new Collection<SequencePoint> (0); | |
var document_index = ReadTableIndex (Table.Document); | |
var signature = ReadBlobIndex (); | |
if (signature == 0) | |
return new Collection<SequencePoint> (0); | |
var document = GetDocument (document_index); | |
var reader = ReadSignature (signature); | |
return reader.ReadSequencePoints (document); | |
} | |
public Document GetDocument (uint rid) | |
{ | |
var document = metadata.GetDocument (rid); | |
if (document == null) | |
return null; | |
document.custom_infos = GetCustomDebugInformation (document); | |
return document; | |
} | |
void InitializeLocalScopes () | |
{ | |
if (metadata.LocalScopes != null) | |
return; | |
InitializeMethods (); | |
int length = MoveTo (Table.LocalScope); | |
metadata.LocalScopes = new Dictionary<uint, Collection<Row<uint, Range, Range, uint, uint, uint>>> (); | |
for (uint i = 1; i <= length; i++) { | |
var method = ReadTableIndex (Table.Method); | |
var import = ReadTableIndex (Table.ImportScope); | |
var variables = ReadListRange (i, Table.LocalScope, Table.LocalVariable); | |
var constants = ReadListRange (i, Table.LocalScope, Table.LocalConstant); | |
var scope_start = ReadUInt32 (); | |
var scope_length = ReadUInt32 (); | |
metadata.SetLocalScopes (method, AddMapping (metadata.LocalScopes, method, new Row<uint, Range, Range, uint, uint, uint> (import, variables, constants, scope_start, scope_length, i))); | |
} | |
} | |
public ScopeDebugInformation ReadScope (MethodDefinition method) | |
{ | |
InitializeLocalScopes (); | |
InitializeImportScopes (); | |
Collection<Row<uint, Range, Range, uint, uint, uint>> records; | |
if (!metadata.TryGetLocalScopes (method, out records)) | |
return null; | |
var method_scope = null as ScopeDebugInformation; | |
for (int i = 0; i < records.Count; i++) { | |
var scope = ReadLocalScope (records [i]); | |
if (i == 0) { | |
method_scope = scope; | |
continue; | |
} | |
if (!AddScope (method_scope.scopes, scope)) | |
method_scope.Scopes.Add (scope); | |
} | |
return method_scope; | |
} | |
static bool AddScope (Collection<ScopeDebugInformation> scopes, ScopeDebugInformation scope) | |
{ | |
if (scopes.IsNullOrEmpty ()) | |
return false; | |
foreach (var sub_scope in scopes) { | |
if (sub_scope.HasScopes && AddScope (sub_scope.Scopes, scope)) | |
return true; | |
if (scope.Start.Offset >= sub_scope.Start.Offset && scope.End.Offset <= sub_scope.End.Offset) { | |
sub_scope.Scopes.Add (scope); | |
return true; | |
} | |
} | |
return false; | |
} | |
ScopeDebugInformation ReadLocalScope (Row<uint, Range, Range, uint, uint, uint> record) | |
{ | |
var scope = new ScopeDebugInformation | |
{ | |
start = new InstructionOffset ((int) record.Col4), | |
end = new InstructionOffset ((int) (record.Col4 + record.Col5)), | |
token = new MetadataToken (TokenType.LocalScope, record.Col6), | |
}; | |
if (record.Col1 > 0) | |
scope.import = metadata.GetImportScope (record.Col1); | |
if (record.Col2.Length > 0) { | |
scope.variables = new Collection<VariableDebugInformation> ((int) record.Col2.Length); | |
for (uint i = 0; i < record.Col2.Length; i++) { | |
var variable = ReadLocalVariable (record.Col2.Start + i); | |
if (variable != null) | |
scope.variables.Add (variable); | |
} | |
} | |
if (record.Col3.Length > 0) { | |
scope.constants = new Collection<ConstantDebugInformation> ((int) record.Col3.Length); | |
for (uint i = 0; i < record.Col3.Length; i++) { | |
var constant = ReadLocalConstant (record.Col3.Start + i); | |
if (constant != null) | |
scope.constants.Add (constant); | |
} | |
} | |
return scope; | |
} | |
VariableDebugInformation ReadLocalVariable (uint rid) | |
{ | |
if (!MoveTo (Table.LocalVariable, rid)) | |
return null; | |
var attributes = (VariableAttributes) ReadUInt16 (); | |
var index = ReadUInt16 (); | |
var name = ReadString (); | |
var variable = new VariableDebugInformation (index, name) { Attributes = attributes, token = new MetadataToken (TokenType.LocalVariable, rid) }; | |
variable.custom_infos = GetCustomDebugInformation (variable); | |
return variable; | |
} | |
ConstantDebugInformation ReadLocalConstant (uint rid) | |
{ | |
if (!MoveTo (Table.LocalConstant, rid)) | |
return null; | |
var name = ReadString (); | |
var signature = ReadSignature (ReadBlobIndex ()); | |
var type = signature.ReadTypeSignature (); | |
object value; | |
if (type.etype == ElementType.String) { | |
if (signature.buffer [signature.position] != 0xff) { | |
var bytes = signature.ReadBytes ((int) (signature.sig_length - (signature.position - signature.start))); | |
value = Encoding.Unicode.GetString (bytes, 0, bytes.Length); | |
} else | |
value = null; | |
} else if (type.IsTypeOf ("System", "Decimal")) { | |
var b = signature.ReadByte (); | |
value = new decimal (signature.ReadInt32 (), signature.ReadInt32 (), signature.ReadInt32 (), (b & 0x80) != 0, (byte) (b & 0x7f)); | |
} else if (type.IsTypeOf ("System", "DateTime")) { | |
value = new DateTime (signature.ReadInt64()); | |
} else if (type.etype == ElementType.Object || type.etype == ElementType.None || type.etype == ElementType.Class) { | |
value = null; | |
} else | |
value = signature.ReadConstantSignature (type.etype); | |
var constant = new ConstantDebugInformation (name, type, value) { token = new MetadataToken (TokenType.LocalConstant, rid) }; | |
constant.custom_infos = GetCustomDebugInformation (constant); | |
return constant; | |
} | |
void InitializeImportScopes () | |
{ | |
if (metadata.ImportScopes != null) | |
return; | |
var length = MoveTo (Table.ImportScope); | |
metadata.ImportScopes = new ImportDebugInformation [length]; | |
for (int i = 1; i <= length; i++) { | |
ReadTableIndex (Table.ImportScope); | |
var import = new ImportDebugInformation (); | |
import.token = new MetadataToken (TokenType.ImportScope, i); | |
var signature = ReadSignature (ReadBlobIndex ()); | |
while (signature.CanReadMore ()) | |
import.Targets.Add (ReadImportTarget (signature)); | |
metadata.ImportScopes [i - 1] = import; | |
} | |
MoveTo (Table.ImportScope); | |
for (int i = 0; i < length; i++) { | |
var parent = ReadTableIndex (Table.ImportScope); | |
ReadBlobIndex (); | |
if (parent != 0) | |
metadata.ImportScopes [i].Parent = metadata.GetImportScope (parent); | |
} | |
} | |
public string ReadUTF8StringBlob (uint signature) | |
{ | |
return ReadStringBlob (signature, Encoding.UTF8); | |
} | |
string ReadUnicodeStringBlob (uint signature) | |
{ | |
return ReadStringBlob (signature, Encoding.Unicode); | |
} | |
string ReadStringBlob (uint signature, Encoding encoding) | |
{ | |
byte [] blob; | |
int index, count; | |
GetBlobView (signature, out blob, out index, out count); | |
if (count == 0) | |
return string.Empty; | |
return encoding.GetString (blob, index, count); | |
} | |
ImportTarget ReadImportTarget (SignatureReader signature) | |
{ | |
AssemblyNameReference reference = null; | |
string @namespace = null; | |
string alias = null; | |
TypeReference type = null; | |
var kind = (ImportTargetKind) signature.ReadCompressedUInt32 (); | |
switch (kind) { | |
case ImportTargetKind.ImportNamespace: | |
@namespace = ReadUTF8StringBlob (signature.ReadCompressedUInt32 ()); | |
break; | |
case ImportTargetKind.ImportNamespaceInAssembly: | |
reference = metadata.GetAssemblyNameReference (signature.ReadCompressedUInt32 ()); | |
@namespace = ReadUTF8StringBlob (signature.ReadCompressedUInt32 ()); | |
break; | |
case ImportTargetKind.ImportType: | |
type = signature.ReadTypeToken (); | |
break; | |
case ImportTargetKind.ImportXmlNamespaceWithAlias: | |
alias = ReadUTF8StringBlob (signature.ReadCompressedUInt32 ()); | |
@namespace = ReadUTF8StringBlob (signature.ReadCompressedUInt32 ()); | |
break; | |
case ImportTargetKind.ImportAlias: | |
alias = ReadUTF8StringBlob (signature.ReadCompressedUInt32 ()); | |
break; | |
case ImportTargetKind.DefineAssemblyAlias: | |
alias = ReadUTF8StringBlob (signature.ReadCompressedUInt32 ()); | |
reference = metadata.GetAssemblyNameReference (signature.ReadCompressedUInt32 ()); | |
break; | |
case ImportTargetKind.DefineNamespaceAlias: | |
alias = ReadUTF8StringBlob (signature.ReadCompressedUInt32 ()); | |
@namespace = ReadUTF8StringBlob (signature.ReadCompressedUInt32 ()); | |
break; | |
case ImportTargetKind.DefineNamespaceInAssemblyAlias: | |
alias = ReadUTF8StringBlob (signature.ReadCompressedUInt32 ()); | |
reference = metadata.GetAssemblyNameReference (signature.ReadCompressedUInt32 ()); | |
@namespace = ReadUTF8StringBlob (signature.ReadCompressedUInt32 ()); | |
break; | |
case ImportTargetKind.DefineTypeAlias: | |
alias = ReadUTF8StringBlob (signature.ReadCompressedUInt32 ()); | |
type = signature.ReadTypeToken (); | |
break; | |
} | |
return new ImportTarget (kind) { | |
alias = alias, | |
type = type, | |
@namespace = @namespace, | |
reference = reference, | |
}; | |
} | |
void InitializeStateMachineMethods () | |
{ | |
if (metadata.StateMachineMethods != null) | |
return; | |
var length = MoveTo (Table.StateMachineMethod); | |
metadata.StateMachineMethods = new Dictionary<uint, uint> (length); | |
for (int i = 0; i < length; i++) | |
metadata.StateMachineMethods.Add (ReadTableIndex (Table.Method), ReadTableIndex (Table.Method)); | |
} | |
public MethodDefinition ReadStateMachineKickoffMethod (MethodDefinition method) | |
{ | |
InitializeStateMachineMethods (); | |
uint rid; | |
if (!metadata.TryGetStateMachineKickOffMethod (method, out rid)) | |
return null; | |
return GetMethodDefinition (rid); | |
} | |
void InitializeCustomDebugInformations () | |
{ | |
if (metadata.CustomDebugInformations != null) | |
return; | |
var length = MoveTo (Table.CustomDebugInformation); | |
metadata.CustomDebugInformations = new Dictionary<MetadataToken, Row<Guid, uint, uint> []> (); | |
for (uint i = 1; i <= length; i++) { | |
var token = ReadMetadataToken (CodedIndex.HasCustomDebugInformation); | |
var info = new Row<Guid, uint, uint> (ReadGuid (), ReadBlobIndex (), i); | |
Row<Guid, uint, uint> [] infos; | |
metadata.CustomDebugInformations.TryGetValue (token, out infos); | |
metadata.CustomDebugInformations [token] = infos.Add (info); | |
} | |
} | |
public Collection<CustomDebugInformation> GetCustomDebugInformation (ICustomDebugInformationProvider provider) | |
{ | |
InitializeCustomDebugInformations (); | |
Row<Guid, uint, uint> [] rows; | |
if (!metadata.CustomDebugInformations.TryGetValue (provider.MetadataToken, out rows)) | |
return null; | |
var infos = new Collection<CustomDebugInformation> (rows.Length); | |
for (int i = 0; i < rows.Length; i++) { | |
if (rows [i].Col1 == StateMachineScopeDebugInformation.KindIdentifier) { | |
var signature = ReadSignature (rows [i].Col2); | |
var scopes = new Collection<StateMachineScope> (); | |
while (signature.CanReadMore ()) { | |
var start = signature.ReadInt32 (); | |
var end = start + signature.ReadInt32 (); | |
scopes.Add (new StateMachineScope (start, end)); | |
} | |
var state_machine = new StateMachineScopeDebugInformation (); | |
state_machine.scopes = scopes; | |
infos.Add (state_machine); | |
} else if (rows [i].Col1 == AsyncMethodBodyDebugInformation.KindIdentifier) { | |
var signature = ReadSignature (rows [i].Col2); | |
var catch_offset = signature.ReadInt32 () - 1; | |
var yields = new Collection<InstructionOffset> (); | |
var resumes = new Collection<InstructionOffset> (); | |
var resume_methods = new Collection<MethodDefinition> (); | |
while (signature.CanReadMore ()) { | |
yields.Add (new InstructionOffset (signature.ReadInt32 ())); | |
resumes.Add (new InstructionOffset (signature.ReadInt32 ())); | |
resume_methods.Add (GetMethodDefinition (signature.ReadCompressedUInt32 ())); | |
} | |
var async_body = new AsyncMethodBodyDebugInformation (catch_offset); | |
async_body.yields = yields; | |
async_body.resumes = resumes; | |
async_body.resume_methods = resume_methods; | |
infos.Add (async_body); | |
} else if (rows [i].Col1 == EmbeddedSourceDebugInformation.KindIdentifier) { | |
var signature = ReadSignature (rows [i].Col2); | |
var format = signature.ReadInt32 (); | |
var length = signature.sig_length - 4; | |
var info = null as CustomDebugInformation; | |
if (format == 0) { | |
info = new EmbeddedSourceDebugInformation (signature.ReadBytes ((int) length), compress: false); | |
} else if (format > 0) { | |
var compressed_stream = new MemoryStream (signature.ReadBytes ((int) length)); | |
var decompressed_document = new byte [format]; // if positive, format is the decompressed length of the document | |
var decompressed_stream = new MemoryStream (decompressed_document); | |
using (var deflate_stream = new DeflateStream (compressed_stream, CompressionMode.Decompress, leaveOpen: true)) | |
deflate_stream.CopyTo (decompressed_stream); | |
info = new EmbeddedSourceDebugInformation (decompressed_document, compress: true); | |
} else if (format < 0) { | |
info = new BinaryCustomDebugInformation (rows [i].Col1, ReadBlob (rows [i].Col2)); | |
} | |
infos.Add (info); | |
} else if (rows [i].Col1 == SourceLinkDebugInformation.KindIdentifier) { | |
infos.Add (new SourceLinkDebugInformation (Encoding.UTF8.GetString (ReadBlob (rows [i].Col2)))); | |
} else { | |
infos.Add (new BinaryCustomDebugInformation (rows [i].Col1, ReadBlob (rows [i].Col2))); | |
} | |
infos [i].token = new MetadataToken (TokenType.CustomDebugInformation, rows [i].Col3); | |
} | |
return infos; | |
} | |
} | |
sealed class SignatureReader : ByteBuffer { | |
readonly MetadataReader reader; | |
readonly internal uint start, sig_length; | |
TypeSystem TypeSystem { | |
get { return reader.module.TypeSystem; } | |
} | |
public SignatureReader (uint blob, MetadataReader reader) | |
: base (reader.image.BlobHeap.data) | |
{ | |
this.reader = reader; | |
this.position = (int) blob; | |
this.sig_length = ReadCompressedUInt32(); | |
this.start = (uint) this.position; | |
} | |
MetadataToken ReadTypeTokenSignature () | |
{ | |
return CodedIndex.TypeDefOrRef.GetMetadataToken (ReadCompressedUInt32 ()); | |
} | |
GenericParameter GetGenericParameter (GenericParameterType type, uint var) | |
{ | |
var context = reader.context; | |
int index = (int) var; | |
if (context == null) | |
return GetUnboundGenericParameter (type, index); | |
IGenericParameterProvider provider; | |
switch (type) { | |
case GenericParameterType.Type: | |
provider = context.Type; | |
break; | |
case GenericParameterType.Method: | |
provider = context.Method; | |
break; | |
default: | |
throw new NotSupportedException (); | |
} | |
if (!context.IsDefinition) | |
CheckGenericContext (provider, index); | |
if (index >= provider.GenericParameters.Count) | |
return GetUnboundGenericParameter (type, index); | |
return provider.GenericParameters [index]; | |
} | |
GenericParameter GetUnboundGenericParameter (GenericParameterType type, int index) | |
{ | |
return new GenericParameter (index, type, reader.module); | |
} | |
static void CheckGenericContext (IGenericParameterProvider owner, int index) | |
{ | |
var owner_parameters = owner.GenericParameters; | |
for (int i = owner_parameters.Count; i <= index; i++) | |
owner_parameters.Add (new GenericParameter (owner)); | |
} | |
public void ReadGenericInstanceSignature (IGenericParameterProvider provider, IGenericInstance instance) | |
{ | |
var arity = ReadCompressedUInt32 (); | |
if (!provider.IsDefinition) | |
CheckGenericContext (provider, (int) arity - 1); | |
var instance_arguments = instance.GenericArguments; | |
for (int i = 0; i < arity; i++) | |
instance_arguments.Add (ReadTypeSignature ()); | |
} | |
ArrayType ReadArrayTypeSignature () | |
{ | |
var array = new ArrayType (ReadTypeSignature ()); | |
var rank = ReadCompressedUInt32 (); | |
var sizes = new uint [ReadCompressedUInt32 ()]; | |
for (int i = 0; i < sizes.Length; i++) | |
sizes [i] = ReadCompressedUInt32 (); | |
var low_bounds = new int [ReadCompressedUInt32 ()]; | |
for (int i = 0; i < low_bounds.Length; i++) | |
low_bounds [i] = ReadCompressedInt32 (); | |
array.Dimensions.Clear (); | |
for (int i = 0; i < rank; i++) { | |
int? lower = null, upper = null; | |
if (i < low_bounds.Length) | |
lower = low_bounds [i]; | |
if (i < sizes.Length) | |
upper = lower + (int) sizes [i] - 1; | |
array.Dimensions.Add (new ArrayDimension (lower, upper)); | |
} | |
return array; | |
} | |
TypeReference GetTypeDefOrRef (MetadataToken token) | |
{ | |
return reader.GetTypeDefOrRef (token); | |
} | |
public TypeReference ReadTypeSignature () | |
{ | |
return ReadTypeSignature ((ElementType) ReadByte ()); | |
} | |
public TypeReference ReadTypeToken () | |
{ | |
return GetTypeDefOrRef (ReadTypeTokenSignature ()); | |
} | |
TypeReference ReadTypeSignature (ElementType etype) | |
{ | |
switch (etype) { | |
case ElementType.ValueType: { | |
var value_type = GetTypeDefOrRef (ReadTypeTokenSignature ()); | |
value_type.KnownValueType (); | |
return value_type; | |
} | |
case ElementType.Class: | |
return GetTypeDefOrRef (ReadTypeTokenSignature ()); | |
case ElementType.Ptr: | |
return new PointerType (ReadTypeSignature ()); | |
case ElementType.FnPtr: { | |
var fptr = new FunctionPointerType (); | |
ReadMethodSignature (fptr); | |
return fptr; | |
} | |
case ElementType.ByRef: | |
return new ByReferenceType (ReadTypeSignature ()); | |
case ElementType.Pinned: | |
return new PinnedType (ReadTypeSignature ()); | |
case ElementType.SzArray: | |
return new ArrayType (ReadTypeSignature ()); | |
case ElementType.Array: | |
return ReadArrayTypeSignature (); | |
case ElementType.CModOpt: | |
return new OptionalModifierType ( | |
GetTypeDefOrRef (ReadTypeTokenSignature ()), ReadTypeSignature ()); | |
case ElementType.CModReqD: | |
return new RequiredModifierType ( | |
GetTypeDefOrRef (ReadTypeTokenSignature ()), ReadTypeSignature ()); | |
case ElementType.Sentinel: | |
return new SentinelType (ReadTypeSignature ()); | |
case ElementType.Var: | |
return GetGenericParameter (GenericParameterType.Type, ReadCompressedUInt32 ()); | |
case ElementType.MVar: | |
return GetGenericParameter (GenericParameterType.Method, ReadCompressedUInt32 ()); | |
case ElementType.GenericInst: { | |
var is_value_type = ReadByte () == (byte) ElementType.ValueType; | |
var element_type = GetTypeDefOrRef (ReadTypeTokenSignature ()); | |
var generic_instance = new GenericInstanceType (element_type); | |
ReadGenericInstanceSignature (element_type, generic_instance); | |
if (is_value_type) { | |
generic_instance.KnownValueType (); | |
element_type.GetElementType ().KnownValueType (); | |
} | |
return generic_instance; | |
} | |
case ElementType.Object: return TypeSystem.Object; | |
case ElementType.Void: return TypeSystem.Void; | |
case ElementType.TypedByRef: return TypeSystem.TypedReference; | |
case ElementType.I: return TypeSystem.IntPtr; | |
case ElementType.U: return TypeSystem.UIntPtr; | |
default: return GetPrimitiveType (etype); | |
} | |
} | |
public void ReadMethodSignature (IMethodSignature method) | |
{ | |
var calling_convention = ReadByte (); | |
const byte has_this = 0x20; | |
const byte explicit_this = 0x40; | |
if ((calling_convention & has_this) != 0) { | |
method.HasThis = true; | |
calling_convention = (byte) (calling_convention & ~has_this); | |
} | |
if ((calling_convention & explicit_this) != 0) { | |
method.ExplicitThis = true; | |
calling_convention = (byte) (calling_convention & ~explicit_this); | |
} | |
method.CallingConvention = (MethodCallingConvention) calling_convention; | |
var generic_context = method as MethodReference; | |
if (generic_context != null && !generic_context.DeclaringType.IsArray) | |
reader.context = generic_context; | |
if ((calling_convention & 0x10) != 0) { | |
var arity = ReadCompressedUInt32 (); | |
if (generic_context != null && !generic_context.IsDefinition) | |
CheckGenericContext (generic_context, (int) arity -1 ); | |
} | |
var param_count = ReadCompressedUInt32 (); | |
method.MethodReturnType.ReturnType = ReadTypeSignature (); | |
if (param_count == 0) | |
return; | |
Collection<ParameterDefinition> parameters; | |
var method_ref = method as MethodReference; | |
if (method_ref != null) | |
parameters = method_ref.parameters = new ParameterDefinitionCollection (method, (int) param_count); | |
else | |
parameters = method.Parameters; | |
for (int i = 0; i < param_count; i++) | |
parameters.Add (new ParameterDefinition (ReadTypeSignature ())); | |
} | |
public object ReadConstantSignature (ElementType type) | |
{ | |
return ReadPrimitiveValue (type); | |
} | |
public void ReadCustomAttributeConstructorArguments (CustomAttribute attribute, Collection<ParameterDefinition> parameters) | |
{ | |
var count = parameters.Count; | |
if (count == 0) | |
return; | |
attribute.arguments = new Collection<CustomAttributeArgument> (count); | |
for (int i = 0; i < count; i++) | |
attribute.arguments.Add ( | |
ReadCustomAttributeFixedArgument (parameters [i].ParameterType)); | |
} | |
CustomAttributeArgument ReadCustomAttributeFixedArgument (TypeReference type) | |
{ | |
if (type.IsArray) | |
return ReadCustomAttributeFixedArrayArgument ((ArrayType) type); | |
return ReadCustomAttributeElement (type); | |
} | |
public void ReadCustomAttributeNamedArguments (ushort count, ref Collection<CustomAttributeNamedArgument> fields, ref Collection<CustomAttributeNamedArgument> properties) | |
{ | |
for (int i = 0; i < count; i++) { | |
if (!CanReadMore ()) | |
return; | |
ReadCustomAttributeNamedArgument (ref fields, ref properties); | |
} | |
} | |
void ReadCustomAttributeNamedArgument (ref Collection<CustomAttributeNamedArgument> fields, ref Collection<CustomAttributeNamedArgument> properties) | |
{ | |
var kind = ReadByte (); | |
var type = ReadCustomAttributeFieldOrPropType (); | |
var name = ReadUTF8String (); | |
Collection<CustomAttributeNamedArgument> container; | |
switch (kind) { | |
case 0x53: | |
container = GetCustomAttributeNamedArgumentCollection (ref fields); | |
break; | |
case 0x54: | |
container = GetCustomAttributeNamedArgumentCollection (ref properties); | |
break; | |
default: | |
throw new NotSupportedException (); | |
} | |
container.Add (new CustomAttributeNamedArgument (name, ReadCustomAttributeFixedArgument (type))); | |
} | |
static Collection<CustomAttributeNamedArgument> GetCustomAttributeNamedArgumentCollection (ref Collection<CustomAttributeNamedArgument> collection) | |
{ | |
if (collection != null) | |
return collection; | |
return collection = new Collection<CustomAttributeNamedArgument> (); | |
} | |
CustomAttributeArgument ReadCustomAttributeFixedArrayArgument (ArrayType type) | |
{ | |
var length = ReadUInt32 (); | |
if (length == 0xffffffff) | |
return new CustomAttributeArgument (type, null); | |
if (length == 0) | |
return new CustomAttributeArgument (type, Empty<CustomAttributeArgument>.Array); | |
var arguments = new CustomAttributeArgument [length]; | |
var element_type = type.ElementType; | |
for (int i = 0; i < length; i++) | |
arguments [i] = ReadCustomAttributeElement (element_type); | |
return new CustomAttributeArgument (type, arguments); | |
} | |
CustomAttributeArgument ReadCustomAttributeElement (TypeReference type) | |
{ | |
if (type.IsArray) | |
return ReadCustomAttributeFixedArrayArgument ((ArrayType) type); | |
return new CustomAttributeArgument ( | |
type, | |
type.etype == ElementType.Object | |
? ReadCustomAttributeElement (ReadCustomAttributeFieldOrPropType ()) | |
: ReadCustomAttributeElementValue (type)); | |
} | |
object ReadCustomAttributeElementValue (TypeReference type) | |
{ | |
var etype = type.etype; | |
switch (etype) { | |
case ElementType.String: | |
return ReadUTF8String (); | |
case ElementType.None: | |
if (type.IsTypeOf ("System", "Type")) | |
return ReadTypeReference (); | |
return ReadCustomAttributeEnum (type); | |
default: | |
return ReadPrimitiveValue (etype); | |
} | |
} | |
object ReadPrimitiveValue (ElementType type) | |
{ | |
switch (type) { | |
case ElementType.Boolean: | |
return ReadByte () == 1; | |
case ElementType.I1: | |
return (sbyte) ReadByte (); | |
case ElementType.U1: | |
return ReadByte (); | |
case ElementType.Char: | |
return (char) ReadUInt16 (); | |
case ElementType.I2: | |
return ReadInt16 (); | |
case ElementType.U2: | |
return ReadUInt16 (); | |
case ElementType.I4: | |
return ReadInt32 (); | |
case ElementType.U4: | |
return ReadUInt32 (); | |
case ElementType.I8: | |
return ReadInt64 (); | |
case ElementType.U8: | |
return ReadUInt64 (); | |
case ElementType.R4: | |
return ReadSingle (); | |
case ElementType.R8: | |
return ReadDouble (); | |
default: | |
throw new NotImplementedException (type.ToString ()); | |
} | |
} | |
TypeReference GetPrimitiveType (ElementType etype) | |
{ | |
switch (etype) { | |
case ElementType.Boolean: | |
return TypeSystem.Boolean; | |
case ElementType.Char: | |
return TypeSystem.Char; | |
case ElementType.I1: | |
return TypeSystem.SByte; | |
case ElementType.U1: | |
return TypeSystem.Byte; | |
case ElementType.I2: | |
return TypeSystem.Int16; | |
case ElementType.U2: | |
return TypeSystem.UInt16; | |
case ElementType.I4: | |
return TypeSystem.Int32; | |
case ElementType.U4: | |
return TypeSystem.UInt32; | |
case ElementType.I8: | |
return TypeSystem.Int64; | |
case ElementType.U8: | |
return TypeSystem.UInt64; | |
case ElementType.R4: | |
return TypeSystem.Single; | |
case ElementType.R8: | |
return TypeSystem.Double; | |
case ElementType.String: | |
return TypeSystem.String; | |
default: | |
throw new NotImplementedException (etype.ToString ()); | |
} | |
} | |
TypeReference ReadCustomAttributeFieldOrPropType () | |
{ | |
var etype = (ElementType) ReadByte (); | |
switch (etype) { | |
case ElementType.Boxed: | |
return TypeSystem.Object; | |
case ElementType.SzArray: | |
return new ArrayType (ReadCustomAttributeFieldOrPropType ()); | |
case ElementType.Enum: | |
return ReadTypeReference (); | |
case ElementType.Type: | |
return TypeSystem.LookupType ("System", "Type"); | |
default: | |
return GetPrimitiveType (etype); | |
} | |
} | |
public TypeReference ReadTypeReference () | |
{ | |
return TypeParser.ParseType (reader.module, ReadUTF8String ()); | |
} | |
object ReadCustomAttributeEnum (TypeReference enum_type) | |
{ | |
var type = enum_type.CheckedResolve (); | |
if (!type.IsEnum) | |
throw new ArgumentException (); | |
return ReadCustomAttributeElementValue (type.GetEnumUnderlyingType ()); | |
} | |
public SecurityAttribute ReadSecurityAttribute () | |
{ | |
var attribute = new SecurityAttribute (ReadTypeReference ()); | |
ReadCompressedUInt32 (); | |
ReadCustomAttributeNamedArguments ( | |
(ushort) ReadCompressedUInt32 (), | |
ref attribute.fields, | |
ref attribute.properties); | |
return attribute; | |
} | |
public MarshalInfo ReadMarshalInfo () | |
{ | |
var native = ReadNativeType (); | |
switch (native) { | |
case NativeType.Array: { | |
var array = new ArrayMarshalInfo (); | |
if (CanReadMore ()) | |
array.element_type = ReadNativeType (); | |
if (CanReadMore ()) | |
array.size_parameter_index = (int) ReadCompressedUInt32 (); | |
if (CanReadMore ()) | |
array.size = (int) ReadCompressedUInt32 (); | |
if (CanReadMore ()) | |
array.size_parameter_multiplier = (int) ReadCompressedUInt32 (); | |
return array; | |
} | |
case NativeType.SafeArray: { | |
var array = new SafeArrayMarshalInfo (); | |
if (CanReadMore ()) | |
array.element_type = ReadVariantType (); | |
return array; | |
} | |
case NativeType.FixedArray: { | |
var array = new FixedArrayMarshalInfo (); | |
if (CanReadMore ()) | |
array.size = (int) ReadCompressedUInt32 (); | |
if (CanReadMore ()) | |
array.element_type = ReadNativeType (); | |
return array; | |
} | |
case NativeType.FixedSysString: { | |
var sys_string = new FixedSysStringMarshalInfo (); | |
if (CanReadMore ()) | |
sys_string.size = (int) ReadCompressedUInt32 (); | |
return sys_string; | |
} | |
case NativeType.CustomMarshaler: { | |
var marshaler = new CustomMarshalInfo (); | |
var guid_value = ReadUTF8String (); | |
marshaler.guid = !string.IsNullOrEmpty (guid_value) ? new Guid (guid_value) : Guid.Empty; | |
marshaler.unmanaged_type = ReadUTF8String (); | |
marshaler.managed_type = ReadTypeReference (); | |
marshaler.cookie = ReadUTF8String (); | |
return marshaler; | |
} | |
default: | |
return new MarshalInfo (native); | |
} | |
} | |
NativeType ReadNativeType () | |
{ | |
return (NativeType) ReadByte (); | |
} | |
VariantType ReadVariantType () | |
{ | |
return (VariantType) ReadByte (); | |
} | |
string ReadUTF8String () | |
{ | |
if (buffer [position] == 0xff) { | |
position++; | |
return null; | |
} | |
var length = (int) ReadCompressedUInt32 (); | |
if (length == 0) | |
return string.Empty; | |
if (position + length >= buffer.Length) | |
return string.Empty; | |
var @string = Encoding.UTF8.GetString (buffer, position, length); | |
position += length; | |
return @string; | |
} | |
public string ReadDocumentName () | |
{ | |
var separator = (char) buffer [position]; | |
position++; | |
var builder = new StringBuilder (); | |
for (int i = 0; CanReadMore (); i++) { | |
if (i > 0 && separator != 0) | |
builder.Append (separator); | |
uint part = ReadCompressedUInt32 (); | |
if (part != 0) | |
builder.Append (reader.ReadUTF8StringBlob (part)); | |
} | |
return builder.ToString (); | |
} | |
public Collection<SequencePoint> ReadSequencePoints (Document document) | |
{ | |
var sequence_points = new Collection<SequencePoint> (); | |
ReadCompressedUInt32 (); // local_sig_token | |
if (document == null) | |
document = reader.GetDocument (ReadCompressedUInt32 ()); | |
var offset = 0; | |
var start_line = 0; | |
var start_column = 0; | |
var first_non_hidden = true; | |
for (var i = 0; CanReadMore (); i++) { | |
var delta_il = (int) ReadCompressedUInt32 (); | |
if (i > 0 && delta_il == 0) { | |
document = reader.GetDocument (ReadCompressedUInt32 ()); | |
continue; | |
} | |
offset += delta_il; | |
var delta_lines = (int) ReadCompressedUInt32 (); | |
var delta_columns = delta_lines == 0 | |
? (int) ReadCompressedUInt32 () | |
: ReadCompressedInt32 (); | |
if (delta_lines == 0 && delta_columns == 0) { | |
sequence_points.Add (new SequencePoint (offset, document) { | |
StartLine = 0xfeefee, | |
EndLine = 0xfeefee, | |
StartColumn = 0, | |
EndColumn = 0, | |
}); | |
continue; | |
} | |
if (first_non_hidden) { | |
start_line = (int) ReadCompressedUInt32 (); | |
start_column = (int) ReadCompressedUInt32 (); | |
} else { | |
start_line += ReadCompressedInt32 (); | |
start_column += ReadCompressedInt32 (); | |
} | |
sequence_points.Add (new SequencePoint (offset, document) { | |
StartLine = start_line, | |
StartColumn = start_column, | |
EndLine = start_line + delta_lines, | |
EndColumn = start_column + delta_columns, | |
}); | |
first_non_hidden = false; | |
} | |
return sequence_points; | |
} | |
public bool CanReadMore () | |
{ | |
return position - start < sig_length; | |
} | |
} | |
} | |
} | |
#endregion | |
#region Mono.Cecil\*.cs | |
namespace Internal { | |
// | |
// Author: | |
// Jb Evain (jbevain@gmail.com) | |
// | |
// Copyright (c) 2008 - 2015 Jb Evain | |
// Copyright (c) 2008 - 2011 Novell, Inc. | |
// | |
// Licensed under the MIT/X11 license. | |
// | |
using System; | |
using System.Collections.Generic; | |
using System.IO; | |
using System.IO.Compression; | |
using System.Text; | |
using Mono; | |
using Mono.Collections.Generic; | |
using Mono.Cecil.Cil; | |
using Mono.Cecil.Metadata; | |
using Mono.Cecil.PE; | |
using RVA = System.UInt32; | |
using RID = System.UInt32; | |
using CodedRID = System.UInt32; | |
using StringIndex = System.UInt32; | |
using BlobIndex = System.UInt32; | |
using GuidIndex = System.UInt32; | |
namespace Mono.Cecil { | |
#if !READ_ONLY | |
using ModuleRow = Row<StringIndex, GuidIndex>; | |
using TypeRefRow = Row<CodedRID, StringIndex, StringIndex>; | |
using TypeDefRow = Row<TypeAttributes, StringIndex, StringIndex, CodedRID, RID, RID>; | |
using FieldRow = Row<FieldAttributes, StringIndex, BlobIndex>; | |
using MethodRow = Row<RVA, MethodImplAttributes, MethodAttributes, StringIndex, BlobIndex, RID>; | |
using ParamRow = Row<ParameterAttributes, ushort, StringIndex>; | |
using InterfaceImplRow = Row<uint, CodedRID>; | |
using MemberRefRow = Row<CodedRID, StringIndex, BlobIndex>; | |
using ConstantRow = Row<ElementType, CodedRID, BlobIndex>; | |
using CustomAttributeRow = Row<CodedRID, CodedRID, BlobIndex>; | |
using FieldMarshalRow = Row<CodedRID, BlobIndex>; | |
using DeclSecurityRow = Row<SecurityAction, CodedRID, BlobIndex>; | |
using ClassLayoutRow = Row<ushort, uint, RID>; | |
using FieldLayoutRow = Row<uint, RID>; | |
using EventMapRow = Row<RID, RID>; | |
using EventRow = Row<EventAttributes, StringIndex, CodedRID>; | |
using PropertyMapRow = Row<RID, RID>; | |
using PropertyRow = Row<PropertyAttributes, StringIndex, BlobIndex>; | |
using MethodSemanticsRow = Row<MethodSemanticsAttributes, RID, CodedRID>; | |
using MethodImplRow = Row<RID, CodedRID, CodedRID>; | |
using ImplMapRow = Row<PInvokeAttributes, CodedRID, StringIndex, RID>; | |
using FieldRVARow = Row<RVA, RID>; | |
using AssemblyRow = Row<AssemblyHashAlgorithm, ushort, ushort, ushort, ushort, AssemblyAttributes, uint, uint, uint>; | |
using AssemblyRefRow = Row<ushort, ushort, ushort, ushort, AssemblyAttributes, uint, uint, uint, uint>; | |
using FileRow = Row<FileAttributes, StringIndex, BlobIndex>; | |
using ExportedTypeRow = Row<TypeAttributes, uint, StringIndex, StringIndex, CodedRID>; | |
using ManifestResourceRow = Row<uint, ManifestResourceAttributes, StringIndex, CodedRID>; | |
using NestedClassRow = Row<RID, RID>; | |
using GenericParamRow = Row<ushort, GenericParameterAttributes, CodedRID, StringIndex>; | |
using MethodSpecRow = Row<CodedRID, BlobIndex>; | |
using GenericParamConstraintRow = Row<RID, CodedRID>; | |
using DocumentRow = Row<BlobIndex, GuidIndex, BlobIndex, GuidIndex>; | |
using MethodDebugInformationRow = Row<RID, BlobIndex>; | |
using LocalScopeRow = Row<RID, RID, RID, RID, uint, uint>; | |
using LocalVariableRow = Row<VariableAttributes, ushort, StringIndex>; | |
using LocalConstantRow = Row<StringIndex, BlobIndex>; | |
using ImportScopeRow = Row<RID, BlobIndex>; | |
using StateMachineMethodRow = Row<RID, RID>; | |
using CustomDebugInformationRow = Row<CodedRID, GuidIndex, BlobIndex>; | |
static class ModuleWriter { | |
public static void WriteModule (ModuleDefinition module, Disposable<Stream> stream, WriterParameters parameters) | |
{ | |
using (stream) | |
Write (module, stream, parameters); | |
} | |
static void Write (ModuleDefinition module, Disposable<Stream> stream, WriterParameters parameters) | |
{ | |
if ((module.Attributes & ModuleAttributes.ILOnly) == 0) | |
throw new NotSupportedException ("Writing mixed-mode assemblies is not supported"); | |
if (module.HasImage && module.ReadingMode == ReadingMode.Deferred) { | |
var immediate_reader = new ImmediateModuleReader (module.Image); | |
immediate_reader.ReadModule (module, resolve_attributes: false); | |
immediate_reader.ReadSymbols (module); | |
} | |
module.MetadataSystem.Clear (); | |
if (module.symbol_reader != null) | |
module.symbol_reader.Dispose (); | |
var name = module.assembly != null ? module.assembly.Name : null; | |
var fq_name = stream.value.GetFileName (); | |
var timestamp = parameters.Timestamp ?? module.timestamp; | |
var symbol_writer_provider = parameters.SymbolWriterProvider; | |
if (symbol_writer_provider == null && parameters.WriteSymbols) | |
symbol_writer_provider = new DefaultSymbolWriterProvider (); | |
#if !NET_CORE | |
if (parameters.StrongNameKeyPair != null && name != null) { | |
name.PublicKey = parameters.StrongNameKeyPair.PublicKey; | |
module.Attributes |= ModuleAttributes.StrongNameSigned; | |
} | |
#endif | |
using (var symbol_writer = GetSymbolWriter (module, fq_name, symbol_writer_provider, parameters)) { | |
var metadata = new MetadataBuilder (module, fq_name, timestamp, symbol_writer_provider, symbol_writer); | |
BuildMetadata (module, metadata); | |
var writer = ImageWriter.CreateWriter (module, metadata, stream); | |
stream.value.SetLength (0); | |
writer.WriteImage (); | |
#if !NET_CORE | |
if (parameters.StrongNameKeyPair != null) | |
CryptoService.StrongName (stream.value, writer, parameters.StrongNameKeyPair); | |
#endif | |
} | |
} | |
static void BuildMetadata (ModuleDefinition module, MetadataBuilder metadata) | |
{ | |
if (!module.HasImage) { | |
metadata.BuildMetadata (); | |
return; | |
} | |
module.Read (metadata, (builder, _) => { | |
builder.BuildMetadata (); | |
return builder; | |
}); | |
} | |
static ISymbolWriter GetSymbolWriter (ModuleDefinition module, string fq_name, ISymbolWriterProvider symbol_writer_provider, WriterParameters parameters) | |
{ | |
if (symbol_writer_provider == null) | |
return null; | |
if (parameters.SymbolStream != null) | |
return symbol_writer_provider.GetSymbolWriter (module, parameters.SymbolStream); | |
return symbol_writer_provider.GetSymbolWriter (module, fq_name); | |
} | |
} | |
abstract class MetadataTable { | |
public abstract int Length { get; } | |
public bool IsLarge { | |
get { return Length > ushort.MaxValue; } | |
} | |
public abstract void Write (TableHeapBuffer buffer); | |
public abstract void Sort (); | |
} | |
abstract class OneRowTable<TRow> : MetadataTable where TRow : struct { | |
internal TRow row; | |
public sealed override int Length { | |
get { return 1; } | |
} | |
public sealed override void Sort () | |
{ | |
} | |
} | |
abstract class MetadataTable<TRow> : MetadataTable where TRow : struct { | |
internal TRow [] rows = new TRow [2]; | |
internal int length; | |
public sealed override int Length { | |
get { return length; } | |
} | |
public int AddRow (TRow row) | |
{ | |
if (rows.Length == length) | |
Grow (); | |
rows [length++] = row; | |
return length; | |
} | |
void Grow () | |
{ | |
var rows = new TRow [this.rows.Length * 2]; | |
Array.Copy (this.rows, rows, this.rows.Length); | |
this.rows = rows; | |
} | |
public override void Sort () | |
{ | |
} | |
} | |
abstract class SortedTable<TRow> : MetadataTable<TRow>, IComparer<TRow> where TRow : struct { | |
public sealed override void Sort () | |
{ | |
Array.Sort (rows, 0, length, this); | |
} | |
protected int Compare (uint x, uint y) | |
{ | |
return x == y ? 0 : x > y ? 1 : -1; | |
} | |
public abstract int Compare (TRow x, TRow y); | |
} | |
sealed class ModuleTable : OneRowTable<ModuleRow> { | |
public override void Write (TableHeapBuffer buffer) | |
{ | |
buffer.WriteUInt16 (0); // Generation | |
buffer.WriteString (row.Col1); // Name | |
buffer.WriteGuid (row.Col2); // Mvid | |
buffer.WriteUInt16 (0); // EncId | |
buffer.WriteUInt16 (0); // EncBaseId | |
} | |
} | |
sealed class TypeRefTable : MetadataTable<TypeRefRow> { | |
public override void Write (TableHeapBuffer buffer) | |
{ | |
for (int i = 0; i < length; i++) { | |
buffer.WriteCodedRID ( | |
rows [i].Col1, CodedIndex.ResolutionScope); // Scope | |
buffer.WriteString (rows [i].Col2); // Name | |
buffer.WriteString (rows [i].Col3); // Namespace | |
} | |
} | |
} | |
sealed class TypeDefTable : MetadataTable<TypeDefRow> { | |
public override void Write (TableHeapBuffer buffer) | |
{ | |
for (int i = 0; i < length; i++) { | |
buffer.WriteUInt32 ((uint) rows [i].Col1); // Attributes | |
buffer.WriteString (rows [i].Col2); // Name | |
buffer.WriteString (rows [i].Col3); // Namespace | |
buffer.WriteCodedRID ( | |
rows [i].Col4, CodedIndex.TypeDefOrRef); // Extends | |
buffer.WriteRID (rows [i].Col5, Table.Field); // FieldList | |
buffer.WriteRID (rows [i].Col6, Table.Method); // MethodList | |
} | |
} | |
} | |
sealed class FieldTable : MetadataTable<FieldRow> { | |
public override void Write (TableHeapBuffer buffer) | |
{ | |
for (int i = 0; i < length; i++) { | |
buffer.WriteUInt16 ((ushort) rows [i].Col1); // Attributes | |
buffer.WriteString (rows [i].Col2); // Name | |
buffer.WriteBlob (rows [i].Col3); // Signature | |
} | |
} | |
} | |
sealed class MethodTable : MetadataTable<MethodRow> { | |
public override void Write (TableHeapBuffer buffer) | |
{ | |
for (int i = 0; i < length; i++) { | |
buffer.WriteUInt32 (rows [i].Col1); // RVA | |
buffer.WriteUInt16 ((ushort) rows [i].Col2); // ImplFlags | |
buffer.WriteUInt16 ((ushort) rows [i].Col3); // Flags | |
buffer.WriteString (rows [i].Col4); // Name | |
buffer.WriteBlob (rows [i].Col5); // Signature | |
buffer.WriteRID (rows [i].Col6, Table.Param); // ParamList | |
} | |
} | |
} | |
sealed class ParamTable : MetadataTable<ParamRow> { | |
public override void Write (TableHeapBuffer buffer) | |
{ | |
for (int i = 0; i < length; i++) { | |
buffer.WriteUInt16 ((ushort) rows [i].Col1); // Attributes | |
buffer.WriteUInt16 (rows [i].Col2); // Sequence | |
buffer.WriteString (rows [i].Col3); // Name | |
} | |
} | |
} | |
sealed class InterfaceImplTable : MetadataTable<InterfaceImplRow> { | |
public override void Write (TableHeapBuffer buffer) | |
{ | |
for (int i = 0; i < length; i++) { | |
buffer.WriteRID (rows [i].Col1, Table.TypeDef); // Class | |
buffer.WriteCodedRID (rows [i].Col2, CodedIndex.TypeDefOrRef); // Interface | |
} | |
} | |
/*public override int Compare (InterfaceImplRow x, InterfaceImplRow y) | |
{ | |
return (int) (x.Col1 == y.Col1 ? y.Col2 - x.Col2 : x.Col1 - y.Col1); | |
}*/ | |
} | |
sealed class MemberRefTable : MetadataTable<MemberRefRow> { | |
public override void Write (TableHeapBuffer buffer) | |
{ | |
for (int i = 0; i < length; i++) { | |
buffer.WriteCodedRID (rows [i].Col1, CodedIndex.MemberRefParent); | |
buffer.WriteString (rows [i].Col2); | |
buffer.WriteBlob (rows [i].Col3); | |
} | |
} | |
} | |
sealed class ConstantTable : SortedTable<ConstantRow> { | |
public override void Write (TableHeapBuffer buffer) | |
{ | |
for (int i = 0; i < length; i++) { | |
buffer.WriteUInt16 ((ushort) rows [i].Col1); | |
buffer.WriteCodedRID (rows [i].Col2, CodedIndex.HasConstant); | |
buffer.WriteBlob (rows [i].Col3); | |
} | |
} | |
public override int Compare (ConstantRow x, ConstantRow y) | |
{ | |
return Compare (x.Col2, y.Col2); | |
} | |
} | |
sealed class CustomAttributeTable : SortedTable<CustomAttributeRow> { | |
public override void Write (TableHeapBuffer buffer) | |
{ | |
for (int i = 0; i < length; i++) { | |
buffer.WriteCodedRID (rows [i].Col1, CodedIndex.HasCustomAttribute); // Parent | |
buffer.WriteCodedRID (rows [i].Col2, CodedIndex.CustomAttributeType); // Type | |
buffer.WriteBlob (rows [i].Col3); | |
} | |
} | |
public override int Compare (CustomAttributeRow x, CustomAttributeRow y) | |
{ | |
return Compare (x.Col1, y.Col1); | |
} | |
} | |
sealed class FieldMarshalTable : SortedTable<FieldMarshalRow> { | |
public override void Write (TableHeapBuffer buffer) | |
{ | |
for (int i = 0; i < length; i++) { | |
buffer.WriteCodedRID (rows [i].Col1, CodedIndex.HasFieldMarshal); | |
buffer.WriteBlob (rows [i].Col2); | |
} | |
} | |
public override int Compare (FieldMarshalRow x, FieldMarshalRow y) | |
{ | |
return Compare (x.Col1, y.Col1); | |
} | |
} | |
sealed class DeclSecurityTable : SortedTable<DeclSecurityRow> { | |
public override void Write (TableHeapBuffer buffer) | |
{ | |
for (int i = 0; i < length; i++) { | |
buffer.WriteUInt16 ((ushort) rows [i].Col1); | |
buffer.WriteCodedRID (rows [i].Col2, CodedIndex.HasDeclSecurity); | |
buffer.WriteBlob (rows [i].Col3); | |
} | |
} | |
public override int Compare (DeclSecurityRow x, DeclSecurityRow y) | |
{ | |
return Compare (x.Col2, y.Col2); | |
} | |
} | |
sealed class ClassLayoutTable : SortedTable<ClassLayoutRow> { | |
public override void Write (TableHeapBuffer buffer) | |
{ | |
for (int i = 0; i < length; i++) { | |
buffer.WriteUInt16 (rows [i].Col1); // PackingSize | |
buffer.WriteUInt32 (rows [i].Col2); // ClassSize | |
buffer.WriteRID (rows [i].Col3, Table.TypeDef); // Parent | |
} | |
} | |
public override int Compare (ClassLayoutRow x, ClassLayoutRow y) | |
{ | |
return Compare (x.Col3, y.Col3); | |
} | |
} | |
sealed class FieldLayoutTable : SortedTable<FieldLayoutRow> { | |
public override void Write (TableHeapBuffer buffer) | |
{ | |
for (int i = 0; i < length; i++) { | |
buffer.WriteUInt32 (rows [i].Col1); // Offset | |
buffer.WriteRID (rows [i].Col2, Table.Field); // Parent | |
} | |
} | |
public override int Compare (FieldLayoutRow x, FieldLayoutRow y) | |
{ | |
return Compare (x.Col2, y.Col2); | |
} | |
} | |
sealed class StandAloneSigTable : MetadataTable<uint> { | |
public override void Write (TableHeapBuffer buffer) | |
{ | |
for (int i = 0; i < length; i++) | |
buffer.WriteBlob (rows [i]); | |
} | |
} | |
sealed class EventMapTable : MetadataTable<EventMapRow> { | |
public override void Write (TableHeapBuffer buffer) | |
{ | |
for (int i = 0; i < length; i++) { | |
buffer.WriteRID (rows [i].Col1, Table.TypeDef); // Parent | |
buffer.WriteRID (rows [i].Col2, Table.Event); // EventList | |
} | |
} | |
} | |
sealed class EventTable : MetadataTable<EventRow> { | |
public override void Write (TableHeapBuffer buffer) | |
{ | |
for (int i = 0; i < length; i++) { | |
buffer.WriteUInt16 ((ushort) rows [i].Col1); // Flags | |
buffer.WriteString (rows [i].Col2); // Name | |
buffer.WriteCodedRID (rows [i].Col3, CodedIndex.TypeDefOrRef); // EventType | |
} | |
} | |
} | |
sealed class PropertyMapTable : MetadataTable<PropertyMapRow> { | |
public override void Write (TableHeapBuffer buffer) | |
{ | |
for (int i = 0; i < length; i++) { | |
buffer.WriteRID (rows [i].Col1, Table.TypeDef); // Parent | |
buffer.WriteRID (rows [i].Col2, Table.Property); // PropertyList | |
} | |
} | |
} | |
sealed class PropertyTable : MetadataTable<PropertyRow> { | |
public override void Write (TableHeapBuffer buffer) | |
{ | |
for (int i = 0; i < length; i++) { | |
buffer.WriteUInt16 ((ushort) rows [i].Col1); // Flags | |
buffer.WriteString (rows [i].Col2); // Name | |
buffer.WriteBlob (rows [i].Col3); // Type | |
} | |
} | |
} | |
sealed class MethodSemanticsTable : SortedTable<MethodSemanticsRow> { | |
public override void Write (TableHeapBuffer buffer) | |
{ | |
for (int i = 0; i < length; i++) { | |
buffer.WriteUInt16 ((ushort) rows [i].Col1); // Flags | |
buffer.WriteRID (rows [i].Col2, Table.Method); // Method | |
buffer.WriteCodedRID (rows [i].Col3, CodedIndex.HasSemantics); // Association | |
} | |
} | |
public override int Compare (MethodSemanticsRow x, MethodSemanticsRow y) | |
{ | |
return Compare (x.Col3, y.Col3); | |
} | |
} | |
sealed class MethodImplTable : MetadataTable<MethodImplRow> { | |
public override void Write (TableHeapBuffer buffer) | |
{ | |
for (int i = 0; i < length; i++) { | |
buffer.WriteRID (rows [i].Col1, Table.TypeDef); // Class | |
buffer.WriteCodedRID (rows [i].Col2, CodedIndex.MethodDefOrRef); // MethodBody | |
buffer.WriteCodedRID (rows [i].Col3, CodedIndex.MethodDefOrRef); // MethodDeclaration | |
} | |
} | |
} | |
sealed class ModuleRefTable : MetadataTable<uint> { | |
public override void Write (TableHeapBuffer buffer) | |
{ | |
for (int i = 0; i < length; i++) | |
buffer.WriteString (rows [i]); // Name | |
} | |
} | |
sealed class TypeSpecTable : MetadataTable<uint> { | |
public override void Write (TableHeapBuffer buffer) | |
{ | |
for (int i = 0; i < length; i++) | |
buffer.WriteBlob (rows [i]); // Signature | |
} | |
} | |
sealed class ImplMapTable : SortedTable<ImplMapRow> { | |
public override void Write (TableHeapBuffer buffer) | |
{ | |
for (int i = 0; i < length; i++) { | |
buffer.WriteUInt16 ((ushort) rows [i].Col1); // Flags | |
buffer.WriteCodedRID (rows [i].Col2, CodedIndex.MemberForwarded); // MemberForwarded | |
buffer.WriteString (rows [i].Col3); // ImportName | |
buffer.WriteRID (rows [i].Col4, Table.ModuleRef); // ImportScope | |
} | |
} | |
public override int Compare (ImplMapRow x, ImplMapRow y) | |
{ | |
return Compare (x.Col2, y.Col2); | |
} | |
} | |
sealed class FieldRVATable : SortedTable<FieldRVARow> { | |
internal int position; | |
public override void Write (TableHeapBuffer buffer) | |
{ | |
position = buffer.position; | |
for (int i = 0; i < length; i++) { | |
buffer.WriteUInt32 (rows [i].Col1); // RVA | |
buffer.WriteRID (rows [i].Col2, Table.Field); // Field | |
} | |
} | |
public override int Compare (FieldRVARow x, FieldRVARow y) | |
{ | |
return Compare (x.Col2, y.Col2); | |
} | |
} | |
sealed class AssemblyTable : OneRowTable<AssemblyRow> { | |
public override void Write (TableHeapBuffer buffer) | |
{ | |
buffer.WriteUInt32 ((uint) row.Col1); // AssemblyHashAlgorithm | |
buffer.WriteUInt16 (row.Col2); // MajorVersion | |
buffer.WriteUInt16 (row.Col3); // MinorVersion | |
buffer.WriteUInt16 (row.Col4); // Build | |
buffer.WriteUInt16 (row.Col5); // Revision | |
buffer.WriteUInt32 ((uint) row.Col6); // Flags | |
buffer.WriteBlob (row.Col7); // PublicKey | |
buffer.WriteString (row.Col8); // Name | |
buffer.WriteString (row.Col9); // Culture | |
} | |
} | |
sealed class AssemblyRefTable : MetadataTable<AssemblyRefRow> { | |
public override void Write (TableHeapBuffer buffer) | |
{ | |
for (int i = 0; i < length; i++) { | |
buffer.WriteUInt16 (rows [i].Col1); // MajorVersion | |
buffer.WriteUInt16 (rows [i].Col2); // MinorVersion | |
buffer.WriteUInt16 (rows [i].Col3); // Build | |
buffer.WriteUInt16 (rows [i].Col4); // Revision | |
buffer.WriteUInt32 ((uint) rows [i].Col5); // Flags | |
buffer.WriteBlob (rows [i].Col6); // PublicKeyOrToken | |
buffer.WriteString (rows [i].Col7); // Name | |
buffer.WriteString (rows [i].Col8); // Culture | |
buffer.WriteBlob (rows [i].Col9); // Hash | |
} | |
} | |
} | |
sealed class FileTable : MetadataTable<FileRow> { | |
public override void Write (TableHeapBuffer buffer) | |
{ | |
for (int i = 0; i < length; i++) { | |
buffer.WriteUInt32 ((uint) rows [i].Col1); | |
buffer.WriteString (rows [i].Col2); | |
buffer.WriteBlob (rows [i].Col3); | |
} | |
} | |
} | |
sealed class ExportedTypeTable : MetadataTable<ExportedTypeRow> { | |
public override void Write (TableHeapBuffer buffer) | |
{ | |
for (int i = 0; i < length; i++) { | |
buffer.WriteUInt32 ((uint) rows [i].Col1); | |
buffer.WriteUInt32 (rows [i].Col2); | |
buffer.WriteString (rows [i].Col3); | |
buffer.WriteString (rows [i].Col4); | |
buffer.WriteCodedRID (rows [i].Col5, CodedIndex.Implementation); | |
} | |
} | |
} | |
sealed class ManifestResourceTable : MetadataTable<ManifestResourceRow> { | |
public override void Write (TableHeapBuffer buffer) | |
{ | |
for (int i = 0; i < length; i++) { | |
buffer.WriteUInt32 (rows [i].Col1); | |
buffer.WriteUInt32 ((uint) rows [i].Col2); | |
buffer.WriteString (rows [i].Col3); | |
buffer.WriteCodedRID (rows [i].Col4, CodedIndex.Implementation); | |
} | |
} | |
} | |
sealed class NestedClassTable : SortedTable<NestedClassRow> { | |
public override void Write (TableHeapBuffer buffer) | |
{ | |
for (int i = 0; i < length; i++) { | |
buffer.WriteRID (rows [i].Col1, Table.TypeDef); // NestedClass | |
buffer.WriteRID (rows [i].Col2, Table.TypeDef); // EnclosingClass | |
} | |
} | |
public override int Compare (NestedClassRow x, NestedClassRow y) | |
{ | |
return Compare (x.Col1, y.Col1); | |
} | |
} | |
sealed class GenericParamTable : MetadataTable<GenericParamRow> { | |
public override void Write (TableHeapBuffer buffer) | |
{ | |
for (int i = 0; i < length; i++) { | |
buffer.WriteUInt16 (rows [i].Col1); // Number | |
buffer.WriteUInt16 ((ushort) rows [i].Col2); // Flags | |
buffer.WriteCodedRID (rows [i].Col3, CodedIndex.TypeOrMethodDef); // Owner | |
buffer.WriteString (rows [i].Col4); // Name | |
} | |
} | |
} | |
sealed class MethodSpecTable : MetadataTable<MethodSpecRow> { | |
public override void Write (TableHeapBuffer buffer) | |
{ | |
for (int i = 0; i < length; i++) { | |
buffer.WriteCodedRID (rows [i].Col1, CodedIndex.MethodDefOrRef); // Method | |
buffer.WriteBlob (rows [i].Col2); // Instantiation | |
} | |
} | |
} | |
sealed class GenericParamConstraintTable : MetadataTable<GenericParamConstraintRow> { | |
public override void Write (TableHeapBuffer buffer) | |
{ | |
for (int i = 0; i < length; i++) { | |
buffer.WriteRID (rows [i].Col1, Table.GenericParam); // Owner | |
buffer.WriteCodedRID (rows [i].Col2, CodedIndex.TypeDefOrRef); // Constraint | |
} | |
} | |
} | |
sealed class DocumentTable : MetadataTable<DocumentRow> { | |
public override void Write (TableHeapBuffer buffer) | |
{ | |
for (int i = 0; i < length; i++) { | |
buffer.WriteBlob (rows [i].Col1); // Name | |
buffer.WriteGuid (rows [i].Col2); // HashAlgorithm | |
buffer.WriteBlob (rows [i].Col3); // Hash | |
buffer.WriteGuid (rows [i].Col4); // Language | |
} | |
} | |
} | |
sealed class MethodDebugInformationTable : MetadataTable<MethodDebugInformationRow> { | |
public override void Write (TableHeapBuffer buffer) | |
{ | |
for (int i = 0; i < length; i++) { | |
buffer.WriteRID (rows [i].Col1, Table.Document); // Document | |
buffer.WriteBlob (rows [i].Col2); // SequencePoints | |
} | |
} | |
} | |
sealed class LocalScopeTable : MetadataTable<LocalScopeRow> { | |
public override void Write (TableHeapBuffer buffer) | |
{ | |
for (int i = 0; i < length; i++) { | |
buffer.WriteRID (rows [i].Col1, Table.Method); // Method | |
buffer.WriteRID (rows [i].Col2, Table.ImportScope); // ImportScope | |
buffer.WriteRID (rows [i].Col3, Table.LocalVariable); // VariableList | |
buffer.WriteRID (rows [i].Col4, Table.LocalConstant); // ConstantList | |
buffer.WriteUInt32 (rows [i].Col5); // StartOffset | |
buffer.WriteUInt32 (rows [i].Col6); // Length | |
} | |
} | |
} | |
sealed class LocalVariableTable : MetadataTable<LocalVariableRow> { | |
public override void Write (TableHeapBuffer buffer) | |
{ | |
for (int i = 0; i < length; i++) { | |
buffer.WriteUInt16 ((ushort) rows [i].Col1); // Attributes | |
buffer.WriteUInt16 (rows [i].Col2); // Index | |
buffer.WriteString (rows [i].Col3); // Name | |
} | |
} | |
} | |
sealed class LocalConstantTable : MetadataTable<LocalConstantRow> { | |
public override void Write (TableHeapBuffer buffer) | |
{ | |
for (int i = 0; i < length; i++) { | |
buffer.WriteString (rows [i].Col1); // Name | |
buffer.WriteBlob (rows [i].Col2); // Signature | |
} | |
} | |
} | |
sealed class ImportScopeTable : MetadataTable<ImportScopeRow> { | |
public override void Write (TableHeapBuffer buffer) | |
{ | |
for (int i = 0; i < length; i++) { | |
buffer.WriteRID (rows [i].Col1, Table.ImportScope); // Parent | |
buffer.WriteBlob (rows [i].Col2); // Imports | |
} | |
} | |
} | |
sealed class StateMachineMethodTable : MetadataTable<StateMachineMethodRow> { | |
public override void Write (TableHeapBuffer buffer) | |
{ | |
for (int i = 0; i < length; i++) { | |
buffer.WriteRID (rows [i].Col1, Table.Method); // MoveNextMethod | |
buffer.WriteRID (rows [i].Col2, Table.Method); // KickoffMethod | |
} | |
} | |
} | |
sealed class CustomDebugInformationTable : SortedTable<CustomDebugInformationRow> { | |
public override void Write (TableHeapBuffer buffer) | |
{ | |
for (int i = 0; i < length; i++) { | |
buffer.WriteCodedRID (rows [i].Col1, CodedIndex.HasCustomDebugInformation); // Parent | |
buffer.WriteGuid (rows [i].Col2); // Kind | |
buffer.WriteBlob (rows [i].Col3); // Value | |
} | |
} | |
public override int Compare (CustomDebugInformationRow x, CustomDebugInformationRow y) | |
{ | |
return Compare(x.Col1, y.Col1); | |
} | |
} | |
sealed class MetadataBuilder { | |
readonly internal ModuleDefinition module; | |
readonly internal ISymbolWriterProvider symbol_writer_provider; | |
readonly internal ISymbolWriter symbol_writer; | |
readonly internal TextMap text_map; | |
readonly internal string fq_name; | |
readonly internal uint timestamp; | |
readonly Dictionary<TypeRefRow, MetadataToken> type_ref_map; | |
readonly Dictionary<uint, MetadataToken> type_spec_map; | |
readonly Dictionary<MemberRefRow, MetadataToken> member_ref_map; | |
readonly Dictionary<MethodSpecRow, MetadataToken> method_spec_map; | |
readonly Collection<GenericParameter> generic_parameters; | |
readonly internal CodeWriter code; | |
readonly internal DataBuffer data; | |
readonly internal ResourceBuffer resources; | |
readonly internal StringHeapBuffer string_heap; | |
readonly internal GuidHeapBuffer guid_heap; | |
readonly internal UserStringHeapBuffer user_string_heap; | |
readonly internal BlobHeapBuffer blob_heap; | |
readonly internal TableHeapBuffer table_heap; | |
readonly internal PdbHeapBuffer pdb_heap; | |
internal MetadataToken entry_point; | |
internal RID type_rid = 1; | |
internal RID field_rid = 1; | |
internal RID method_rid = 1; | |
internal RID param_rid = 1; | |
internal RID property_rid = 1; | |
internal RID event_rid = 1; | |
internal RID local_variable_rid = 1; | |
internal RID local_constant_rid = 1; | |
readonly TypeRefTable type_ref_table; | |
readonly TypeDefTable type_def_table; | |
readonly FieldTable field_table; | |
readonly MethodTable method_table; | |
readonly ParamTable param_table; | |
readonly InterfaceImplTable iface_impl_table; | |
readonly MemberRefTable member_ref_table; | |
readonly ConstantTable constant_table; | |
readonly CustomAttributeTable custom_attribute_table; | |
readonly DeclSecurityTable declsec_table; | |
readonly StandAloneSigTable standalone_sig_table; | |
readonly EventMapTable event_map_table; | |
readonly EventTable event_table; | |
readonly PropertyMapTable property_map_table; | |
readonly PropertyTable property_table; | |
readonly TypeSpecTable typespec_table; | |
readonly MethodSpecTable method_spec_table; | |
readonly bool portable_pdb; | |
internal MetadataBuilder metadata_builder; | |
readonly DocumentTable document_table; | |
readonly MethodDebugInformationTable method_debug_information_table; | |
readonly LocalScopeTable local_scope_table; | |
readonly LocalVariableTable local_variable_table; | |
readonly LocalConstantTable local_constant_table; | |
readonly ImportScopeTable import_scope_table; | |
readonly StateMachineMethodTable state_machine_method_table; | |
readonly CustomDebugInformationTable custom_debug_information_table; | |
readonly Dictionary<ImportScopeRow, MetadataToken> import_scope_map; | |
readonly Dictionary<string, MetadataToken> document_map; | |
public MetadataBuilder (ModuleDefinition module, string fq_name, uint timestamp, ISymbolWriterProvider symbol_writer_provider, ISymbolWriter symbol_writer) | |
{ | |
this.module = module; | |
this.text_map = CreateTextMap (); | |
this.fq_name = fq_name; | |
this.timestamp = timestamp; | |
this.symbol_writer_provider = symbol_writer_provider; | |
if (symbol_writer == null && module.HasImage && module.Image.HasDebugTables ()) { | |
symbol_writer = new PortablePdbWriter (this, module); | |
} | |
this.symbol_writer = symbol_writer; | |
var pdb_writer = symbol_writer as IMetadataSymbolWriter; | |
if (pdb_writer != null) { | |
portable_pdb = true; | |
pdb_writer.SetMetadata (this); | |
} | |
this.code = new CodeWriter (this); | |
this.data = new DataBuffer (); | |
this.resources = new ResourceBuffer (); | |
this.string_heap = new StringHeapBuffer (); | |
this.guid_heap = new GuidHeapBuffer (); | |
this.user_string_heap = new UserStringHeapBuffer (); | |
this.blob_heap = new BlobHeapBuffer (); | |
this.table_heap = new TableHeapBuffer (module, this); | |
this.type_ref_table = GetTable<TypeRefTable> (Table.TypeRef); | |
this.type_def_table = GetTable<TypeDefTable> (Table.TypeDef); | |
this.field_table = GetTable<FieldTable> (Table.Field); | |
this.method_table = GetTable<MethodTable> (Table.Method); | |
this.param_table = GetTable<ParamTable> (Table.Param); | |
this.iface_impl_table = GetTable<InterfaceImplTable> (Table.InterfaceImpl); | |
this.member_ref_table = GetTable<MemberRefTable> (Table.MemberRef); | |
this.constant_table = GetTable<ConstantTable> (Table.Constant); | |
this.custom_attribute_table = GetTable<CustomAttributeTable> (Table.CustomAttribute); | |
this.declsec_table = GetTable<DeclSecurityTable> (Table.DeclSecurity); | |
this.standalone_sig_table = GetTable<StandAloneSigTable> (Table.StandAloneSig); | |
this.event_map_table = GetTable<EventMapTable> (Table.EventMap); | |
this.event_table = GetTable<EventTable> (Table.Event); | |
this.property_map_table = GetTable<PropertyMapTable> (Table.PropertyMap); | |
this.property_table = GetTable<PropertyTable> (Table.Property); | |
this.typespec_table = GetTable<TypeSpecTable> (Table.TypeSpec); | |
this.method_spec_table = GetTable<MethodSpecTable> (Table.MethodSpec); | |
var row_equality_comparer = new RowEqualityComparer (); | |
type_ref_map = new Dictionary<TypeRefRow, MetadataToken> (row_equality_comparer); | |
type_spec_map = new Dictionary<uint, MetadataToken> (); | |
member_ref_map = new Dictionary<MemberRefRow, MetadataToken> (row_equality_comparer); | |
method_spec_map = new Dictionary<MethodSpecRow, MetadataToken> (row_equality_comparer); | |
generic_parameters = new Collection<GenericParameter> (); | |
if (!portable_pdb) | |
return; | |
this.document_table = GetTable<DocumentTable> (Table.Document); | |
this.method_debug_information_table = GetTable<MethodDebugInformationTable> (Table.MethodDebugInformation); | |
this.local_scope_table = GetTable<LocalScopeTable> (Table.LocalScope); | |
this.local_variable_table = GetTable<LocalVariableTable> (Table.LocalVariable); | |
this.local_constant_table = GetTable<LocalConstantTable> (Table.LocalConstant); | |
this.import_scope_table = GetTable<ImportScopeTable> (Table.ImportScope); | |
this.state_machine_method_table = GetTable<StateMachineMethodTable> (Table.StateMachineMethod); | |
this.custom_debug_information_table = GetTable<CustomDebugInformationTable> (Table.CustomDebugInformation); | |
this.document_map = new Dictionary<string, MetadataToken> (StringComparer.Ordinal); | |
this.import_scope_map = new Dictionary<ImportScopeRow, MetadataToken> (row_equality_comparer); | |
} | |
public MetadataBuilder (ModuleDefinition module, PortablePdbWriterProvider writer_provider) | |
{ | |
this.module = module; | |
this.text_map = new TextMap (); | |
this.symbol_writer_provider = writer_provider; | |
this.portable_pdb = true; | |
this.string_heap = new StringHeapBuffer (); | |
this.guid_heap = new GuidHeapBuffer (); | |
this.user_string_heap = new UserStringHeapBuffer (); | |
this.blob_heap = new BlobHeapBuffer (); | |
this.table_heap = new TableHeapBuffer (module, this); | |
this.pdb_heap = new PdbHeapBuffer(); | |
this.document_table = GetTable<DocumentTable> (Table.Document); | |
this.method_debug_information_table = GetTable<MethodDebugInformationTable> (Table.MethodDebugInformation); | |
this.local_scope_table = GetTable<LocalScopeTable> (Table.LocalScope); | |
this.local_variable_table = GetTable<LocalVariableTable> (Table.LocalVariable); | |
this.local_constant_table = GetTable<LocalConstantTable> (Table.LocalConstant); | |
this.import_scope_table = GetTable<ImportScopeTable> (Table.ImportScope); | |
this.state_machine_method_table = GetTable<StateMachineMethodTable> (Table.StateMachineMethod); | |
this.custom_debug_information_table = GetTable<CustomDebugInformationTable> (Table.CustomDebugInformation); | |
var row_equality_comparer = new RowEqualityComparer (); | |
this.document_map = new Dictionary<string, MetadataToken> (); | |
this.import_scope_map = new Dictionary<ImportScopeRow, MetadataToken> (row_equality_comparer); | |
} | |
TextMap CreateTextMap () | |
{ | |
var map = new TextMap (); | |
map.AddMap (TextSegment.ImportAddressTable, module.Architecture == TargetArchitecture.I386 ? 8 : 0); | |
map.AddMap (TextSegment.CLIHeader, 0x48, 8); | |
return map; | |
} | |
TTable GetTable<TTable> (Table table) where TTable : MetadataTable, new () | |
{ | |
return table_heap.GetTable<TTable> (table); | |
} | |
uint GetStringIndex (string @string) | |
{ | |
if (string.IsNullOrEmpty (@string)) | |
return 0; | |
return string_heap.GetStringIndex (@string); | |
} | |
uint GetGuidIndex (Guid guid) | |
{ | |
return guid_heap.GetGuidIndex (guid); | |
} | |
uint GetBlobIndex (ByteBuffer blob) | |
{ | |
if (blob.length == 0) | |
return 0; | |
return blob_heap.GetBlobIndex (blob); | |
} | |
uint GetBlobIndex (byte [] blob) | |
{ | |
if (blob.IsNullOrEmpty ()) | |
return 0; | |
return GetBlobIndex (new ByteBuffer (blob)); | |
} | |
public void BuildMetadata () | |
{ | |
BuildModule (); | |
table_heap.string_offsets = string_heap.WriteStrings (); | |
table_heap.ComputeTableInformations (); | |
table_heap.WriteTableHeap (); | |
} | |
void BuildModule () | |
{ | |
var table = GetTable<ModuleTable> (Table.Module); | |
table.row.Col1 = GetStringIndex (module.Name); | |
table.row.Col2 = GetGuidIndex (module.Mvid); | |
var assembly = module.Assembly; | |
if (assembly != null) | |
BuildAssembly (); | |
if (module.HasAssemblyReferences) | |
AddAssemblyReferences (); | |
if (module.HasModuleReferences) | |
AddModuleReferences (); | |
if (module.HasResources) | |
AddResources (); | |
if (module.HasExportedTypes) | |
AddExportedTypes (); | |
BuildTypes (); | |
if (assembly != null) { | |
if (assembly.HasCustomAttributes) | |
AddCustomAttributes (assembly); | |
if (assembly.HasSecurityDeclarations) | |
AddSecurityDeclarations (assembly); | |
} | |
if (module.HasCustomAttributes) | |
AddCustomAttributes (module); | |
if (module.EntryPoint != null) | |
entry_point = LookupToken (module.EntryPoint); | |
var pdb_writer = symbol_writer as IMetadataSymbolWriter; | |
if (pdb_writer != null) | |
pdb_writer.WriteModule (); | |
} | |
void BuildAssembly () | |
{ | |
var assembly = module.Assembly; | |
var name = assembly.Name; | |
var table = GetTable<AssemblyTable> (Table.Assembly); | |
table.row = new AssemblyRow ( | |
name.HashAlgorithm, | |
(ushort) name.Version.Major, | |
(ushort) name.Version.Minor, | |
(ushort) name.Version.Build, | |
(ushort) name.Version.Revision, | |
name.Attributes, | |
GetBlobIndex (name.PublicKey), | |
GetStringIndex (name.Name), | |
GetStringIndex (name.Culture)); | |
if (assembly.Modules.Count > 1) | |
BuildModules (); | |
} | |
void BuildModules () | |
{ | |
var modules = this.module.Assembly.Modules; | |
var table = GetTable<FileTable> (Table.File); | |
for (int i = 0; i < modules.Count; i++) { | |
var module = modules [i]; | |
if (module.IsMain) | |
continue; | |
#if NET_CORE | |
throw new NotSupportedException (); | |
#else | |
var parameters = new WriterParameters { | |
SymbolWriterProvider = symbol_writer_provider, | |
}; | |
var file_name = GetModuleFileName (module.Name); | |
module.Write (file_name, parameters); | |
var hash = CryptoService.ComputeHash (file_name); | |
table.AddRow (new FileRow ( | |
FileAttributes.ContainsMetaData, | |
GetStringIndex (module.Name), | |
GetBlobIndex (hash))); | |
#endif | |
} | |
} | |
#if !NET_CORE | |
string GetModuleFileName (string name) | |
{ | |
if (string.IsNullOrEmpty (name)) | |
throw new NotSupportedException (); | |
var path = Path.GetDirectoryName (fq_name); | |
return Path.Combine (path, name); | |
} | |
#endif | |
void AddAssemblyReferences () | |
{ | |
var references = module.AssemblyReferences; | |
var table = GetTable<AssemblyRefTable> (Table.AssemblyRef); | |
if (module.IsWindowsMetadata ()) | |
module.Projections.RemoveVirtualReferences (references); | |
for (int i = 0; i < references.Count; i++) { | |
var reference = references [i]; | |
var key_or_token = reference.PublicKey.IsNullOrEmpty () | |
? reference.PublicKeyToken | |
: reference.PublicKey; | |
var version = reference.Version; | |
var rid = table.AddRow (new AssemblyRefRow ( | |
(ushort) version.Major, | |
(ushort) version.Minor, | |
(ushort) version.Build, | |
(ushort) version.Revision, | |
reference.Attributes, | |
GetBlobIndex (key_or_token), | |
GetStringIndex (reference.Name), | |
GetStringIndex (reference.Culture), | |
GetBlobIndex (reference.Hash))); | |
reference.token = new MetadataToken (TokenType.AssemblyRef, rid); | |
} | |
if (module.IsWindowsMetadata ()) | |
module.Projections.AddVirtualReferences (references); | |
} | |
void AddModuleReferences () | |
{ | |
var references = module.ModuleReferences; | |
var table = GetTable<ModuleRefTable> (Table.ModuleRef); | |
for (int i = 0; i < references.Count; i++) { | |
var reference = references [i]; | |
reference.token = new MetadataToken ( | |
TokenType.ModuleRef, | |
table.AddRow (GetStringIndex (reference.Name))); | |
} | |
} | |
void AddResources () | |
{ | |
var resources = module.Resources; | |
var table = GetTable<ManifestResourceTable> (Table.ManifestResource); | |
for (int i = 0; i < resources.Count; i++) { | |
var resource = resources [i]; | |
var row = new ManifestResourceRow ( | |
0, | |
resource.Attributes, | |
GetStringIndex (resource.Name), | |
0); | |
switch (resource.ResourceType) { | |
case ResourceType.Embedded: | |
row.Col1 = AddEmbeddedResource ((EmbeddedResource) resource); | |
break; | |
case ResourceType.Linked: | |
row.Col4 = CodedIndex.Implementation.CompressMetadataToken ( | |
new MetadataToken ( | |
TokenType.File, | |
AddLinkedResource ((LinkedResource) resource))); | |
break; | |
case ResourceType.AssemblyLinked: | |
row.Col4 = CodedIndex.Implementation.CompressMetadataToken ( | |
((AssemblyLinkedResource) resource).Assembly.MetadataToken); | |
break; | |
default: | |
throw new NotSupportedException (); | |
} | |
table.AddRow (row); | |
} | |
} | |
uint AddLinkedResource (LinkedResource resource) | |
{ | |
var table = GetTable<FileTable> (Table.File); | |
var hash = resource.Hash; | |
#if !NET_CORE | |
if (hash.IsNullOrEmpty ()) | |
hash = CryptoService.ComputeHash (resource.File); | |
#endif | |
return (uint) table.AddRow (new FileRow ( | |
FileAttributes.ContainsNoMetaData, | |
GetStringIndex (resource.File), | |
GetBlobIndex (hash))); | |
} | |
uint AddEmbeddedResource (EmbeddedResource resource) | |
{ | |
return resources.AddResource (resource.GetResourceData ()); | |
} | |
void AddExportedTypes () | |
{ | |
var exported_types = module.ExportedTypes; | |
var table = GetTable<ExportedTypeTable> (Table.ExportedType); | |
for (int i = 0; i < exported_types.Count; i++) { | |
var exported_type = exported_types [i]; | |
var rid = table.AddRow (new ExportedTypeRow ( | |
exported_type.Attributes, | |
(uint) exported_type.Identifier, | |
GetStringIndex (exported_type.Name), | |
GetStringIndex (exported_type.Namespace), | |
MakeCodedRID (GetExportedTypeScope (exported_type), CodedIndex.Implementation))); | |
exported_type.token = new MetadataToken (TokenType.ExportedType, rid); | |
} | |
} | |
MetadataToken GetExportedTypeScope (ExportedType exported_type) | |
{ | |
if (exported_type.DeclaringType != null) | |
return exported_type.DeclaringType.MetadataToken; | |
var scope = exported_type.Scope; | |
switch (scope.MetadataToken.TokenType) { | |
case TokenType.AssemblyRef: | |
return scope.MetadataToken; | |
case TokenType.ModuleRef: | |
var file_table = GetTable<FileTable> (Table.File); | |
for (int i = 0; i < file_table.length; i++) | |
if (file_table.rows [i].Col2 == GetStringIndex (scope.Name)) | |
return new MetadataToken (TokenType.File, i + 1); | |
break; | |
} | |
throw new NotSupportedException (); | |
} | |
void BuildTypes () | |
{ | |
if (!module.HasTypes) | |
return; | |
AttachTokens (); | |
AddTypes (); | |
AddGenericParameters (); | |
} | |
void AttachTokens () | |
{ | |
var types = module.Types; | |
for (int i = 0; i < types.Count; i++) | |
AttachTypeToken (types [i]); | |
} | |
void AttachTypeToken (TypeDefinition type) | |
{ | |
type.token = new MetadataToken (TokenType.TypeDef, type_rid++); | |
type.fields_range.Start = field_rid; | |
type.methods_range.Start = method_rid; | |
if (type.HasFields) | |
AttachFieldsToken (type); | |
if (type.HasMethods) | |
AttachMethodsToken (type); | |
if (type.HasNestedTypes) | |
AttachNestedTypesToken (type); | |
} | |
void AttachNestedTypesToken (TypeDefinition type) | |
{ | |
var nested_types = type.NestedTypes; | |
for (int i = 0; i < nested_types.Count; i++) | |
AttachTypeToken (nested_types [i]); | |
} | |
void AttachFieldsToken (TypeDefinition type) | |
{ | |
var fields = type.Fields; | |
type.fields_range.Length = (uint) fields.Count; | |
for (int i = 0; i < fields.Count; i++) | |
fields [i].token = new MetadataToken (TokenType.Field, field_rid++); | |
} | |
void AttachMethodsToken (TypeDefinition type) | |
{ | |
var methods = type.Methods; | |
type.methods_range.Length = (uint) methods.Count; | |
for (int i = 0; i < methods.Count; i++) | |
methods [i].token = new MetadataToken (TokenType.Method, method_rid++); | |
} | |
MetadataToken GetTypeToken (TypeReference type) | |
{ | |
if (type == null) | |
return MetadataToken.Zero; | |
if (type.IsDefinition) | |
return type.token; | |
if (type.IsTypeSpecification ()) | |
return GetTypeSpecToken (type); | |
return GetTypeRefToken (type); | |
} | |
MetadataToken GetTypeSpecToken (TypeReference type) | |
{ | |
var row = GetBlobIndex (GetTypeSpecSignature (type)); | |
MetadataToken token; | |
if (type_spec_map.TryGetValue (row, out token)) | |
return token; | |
return AddTypeSpecification (type, row); | |
} | |
MetadataToken AddTypeSpecification (TypeReference type, uint row) | |
{ | |
type.token = new MetadataToken (TokenType.TypeSpec, typespec_table.AddRow (row)); | |
var token = type.token; | |
type_spec_map.Add (row, token); | |
return token; | |
} | |
MetadataToken GetTypeRefToken (TypeReference type) | |
{ | |
var projection = WindowsRuntimeProjections.RemoveProjection (type); | |
var row = CreateTypeRefRow (type); | |
MetadataToken token; | |
if (!type_ref_map.TryGetValue (row, out token)) | |
token = AddTypeReference (type, row); | |
WindowsRuntimeProjections.ApplyProjection (type, projection); | |
return token; | |
} | |
TypeRefRow CreateTypeRefRow (TypeReference type) | |
{ | |
var scope_token = GetScopeToken (type); | |
return new TypeRefRow ( | |
MakeCodedRID (scope_token, CodedIndex.ResolutionScope), | |
GetStringIndex (type.Name), | |
GetStringIndex (type.Namespace)); | |
} | |
MetadataToken GetScopeToken (TypeReference type) | |
{ | |
if (type.IsNested) | |
return GetTypeRefToken (type.DeclaringType); | |
var scope = type.Scope; | |
if (scope == null) | |
return MetadataToken.Zero; | |
return scope.MetadataToken; | |
} | |
static CodedRID MakeCodedRID (IMetadataTokenProvider provider, CodedIndex index) | |
{ | |
return MakeCodedRID (provider.MetadataToken, index); | |
} | |
static CodedRID MakeCodedRID (MetadataToken token, CodedIndex index) | |
{ | |
return index.CompressMetadataToken (token); | |
} | |
MetadataToken AddTypeReference (TypeReference type, TypeRefRow row) | |
{ | |
type.token = new MetadataToken (TokenType.TypeRef, type_ref_table.AddRow (row)); | |
var token = type.token; | |
type_ref_map.Add (row, token); | |
return token; | |
} | |
void AddTypes () | |
{ | |
var types = module.Types; | |
for (int i = 0; i < types.Count; i++) | |
AddType (types [i]); | |
} | |
void AddType (TypeDefinition type) | |
{ | |
var treatment = WindowsRuntimeProjections.RemoveProjection (type); | |
type_def_table.AddRow (new TypeDefRow ( | |
type.Attributes, | |
GetStringIndex (type.Name), | |
GetStringIndex (type.Namespace), | |
MakeCodedRID (GetTypeToken (type.BaseType), CodedIndex.TypeDefOrRef), | |
type.fields_range.Start, | |
type.methods_range.Start)); | |
if (type.HasGenericParameters) | |
AddGenericParameters (type); | |
if (type.HasInterfaces) | |
AddInterfaces (type); | |
AddLayoutInfo (type); | |
if (type.HasFields) | |
AddFields (type); | |
if (type.HasMethods) | |
AddMethods (type); | |
if (type.HasProperties) | |
AddProperties (type); | |
if (type.HasEvents) | |
AddEvents (type); | |
if (type.HasCustomAttributes) | |
AddCustomAttributes (type); | |
if (type.HasSecurityDeclarations) | |
AddSecurityDeclarations (type); | |
if (type.HasNestedTypes) | |
AddNestedTypes (type); | |
WindowsRuntimeProjections.ApplyProjection (type, treatment); | |
} | |
void AddGenericParameters (IGenericParameterProvider owner) | |
{ | |
var parameters = owner.GenericParameters; | |
for (int i = 0; i < parameters.Count; i++) | |
generic_parameters.Add (parameters [i]); | |
} | |
sealed class GenericParameterComparer : IComparer<GenericParameter> { | |
public int Compare (GenericParameter a, GenericParameter b) | |
{ | |
var a_owner = MakeCodedRID (a.Owner, CodedIndex.TypeOrMethodDef); | |
var b_owner = MakeCodedRID (b.Owner, CodedIndex.TypeOrMethodDef); | |
if (a_owner == b_owner) { | |
var a_pos = a.Position; | |
var b_pos = b.Position; | |
return a_pos == b_pos ? 0 : a_pos > b_pos ? 1 : -1; | |
} | |
return a_owner > b_owner ? 1 : -1; | |
} | |
} | |
void AddGenericParameters () | |
{ | |
var items = this.generic_parameters.items; | |
var size = this.generic_parameters.size; | |
Array.Sort (items, 0, size, new GenericParameterComparer ()); | |
var generic_param_table = GetTable<GenericParamTable> (Table.GenericParam); | |
var generic_param_constraint_table = GetTable<GenericParamConstraintTable> (Table.GenericParamConstraint); | |
for (int i = 0; i < size; i++) { | |
var generic_parameter = items [i]; | |
var rid = generic_param_table.AddRow (new GenericParamRow ( | |
(ushort) generic_parameter.Position, | |
generic_parameter.Attributes, | |
MakeCodedRID (generic_parameter.Owner, CodedIndex.TypeOrMethodDef), | |
GetStringIndex (generic_parameter.Name))); | |
generic_parameter.token = new MetadataToken (TokenType.GenericParam, rid); | |
if (generic_parameter.HasConstraints) | |
AddConstraints (generic_parameter, generic_param_constraint_table); | |
if (generic_parameter.HasCustomAttributes) | |
AddCustomAttributes (generic_parameter); | |
} | |
} | |
void AddConstraints (GenericParameter generic_parameter, GenericParamConstraintTable table) | |
{ | |
var constraints = generic_parameter.Constraints; | |
var rid = generic_parameter.token.RID; | |
for (int i = 0; i < constraints.Count; i++) | |
table.AddRow (new GenericParamConstraintRow ( | |
rid, | |
MakeCodedRID (GetTypeToken (constraints [i]), CodedIndex.TypeDefOrRef))); | |
} | |
void AddInterfaces (TypeDefinition type) | |
{ | |
var interfaces = type.Interfaces; | |
var type_rid = type.token.RID; | |
for (int i = 0; i < interfaces.Count; i++) { | |
var iface_impl = interfaces [i]; | |
var rid = iface_impl_table.AddRow (new InterfaceImplRow ( | |
type_rid, | |
MakeCodedRID (GetTypeToken (iface_impl.InterfaceType), CodedIndex.TypeDefOrRef))); | |
iface_impl.token = new MetadataToken (TokenType.InterfaceImpl, rid); | |
if (iface_impl.HasCustomAttributes) | |
AddCustomAttributes (iface_impl); | |
} | |
} | |
void AddLayoutInfo (TypeDefinition type) | |
{ | |
if (type.HasLayoutInfo) { | |
var table = GetTable<ClassLayoutTable> (Table.ClassLayout); | |
table.AddRow (new ClassLayoutRow ( | |
(ushort) type.PackingSize, | |
(uint) type.ClassSize, | |
type.token.RID)); | |
return; | |
} | |
if (type.IsValueType && HasNoInstanceField (type)) { | |
var table = GetTable<ClassLayoutTable> (Table.ClassLayout); | |
table.AddRow (new ClassLayoutRow (0, 1, type.token.RID)); | |
} | |
} | |
static bool HasNoInstanceField (TypeDefinition type) | |
{ | |
if (!type.HasFields) | |
return true; | |
var fields = type.Fields; | |
for (int i = 0; i < fields.Count; i++) | |
if (!fields [i].IsStatic) | |
return false; | |
return true; | |
} | |
void AddNestedTypes (TypeDefinition type) | |
{ | |
var nested_types = type.NestedTypes; | |
var nested_table = GetTable<NestedClassTable> (Table.NestedClass); | |
for (int i = 0; i < nested_types.Count; i++) { | |
var nested = nested_types [i]; | |
AddType (nested); | |
nested_table.AddRow (new NestedClassRow (nested.token.RID, type.token.RID)); | |
} | |
} | |
void AddFields (TypeDefinition type) | |
{ | |
var fields = type.Fields; | |
for (int i = 0; i < fields.Count; i++) | |
AddField (fields [i]); | |
} | |
void AddField (FieldDefinition field) | |
{ | |
var projection = WindowsRuntimeProjections.RemoveProjection (field); | |
field_table.AddRow (new FieldRow ( | |
field.Attributes, | |
GetStringIndex (field.Name), | |
GetBlobIndex (GetFieldSignature (field)))); | |
if (!field.InitialValue.IsNullOrEmpty ()) | |
AddFieldRVA (field); | |
if (field.HasLayoutInfo) | |
AddFieldLayout (field); | |
if (field.HasCustomAttributes) | |
AddCustomAttributes (field); | |
if (field.HasConstant) | |
AddConstant (field, field.FieldType); | |
if (field.HasMarshalInfo) | |
AddMarshalInfo (field); | |
WindowsRuntimeProjections.ApplyProjection (field, projection); | |
} | |
void AddFieldRVA (FieldDefinition field) | |
{ | |
var table = GetTable<FieldRVATable> (Table.FieldRVA); | |
table.AddRow (new FieldRVARow ( | |
data.AddData (field.InitialValue), | |
field.token.RID)); | |
} | |
void AddFieldLayout (FieldDefinition field) | |
{ | |
var table = GetTable<FieldLayoutTable> (Table.FieldLayout); | |
table.AddRow (new FieldLayoutRow ((uint) field.Offset, field.token.RID)); | |
} | |
void AddMethods (TypeDefinition type) | |
{ | |
var methods = type.Methods; | |
for (int i = 0; i < methods.Count; i++) | |
AddMethod (methods [i]); | |
} | |
void AddMethod (MethodDefinition method) | |
{ | |
var projection = WindowsRuntimeProjections.RemoveProjection (method); | |
method_table.AddRow (new MethodRow ( | |
method.HasBody ? code.WriteMethodBody (method) : 0, | |
method.ImplAttributes, | |
method.Attributes, | |
GetStringIndex (method.Name), | |
GetBlobIndex (GetMethodSignature (method)), | |
param_rid)); | |
AddParameters (method); | |
if (method.HasGenericParameters) | |
AddGenericParameters (method); | |
if (method.IsPInvokeImpl) | |
AddPInvokeInfo (method); | |
if (method.HasCustomAttributes) | |
AddCustomAttributes (method); | |
if (method.HasSecurityDeclarations) | |
AddSecurityDeclarations (method); | |
if (method.HasOverrides) | |
AddOverrides (method); | |
WindowsRuntimeProjections.ApplyProjection (method, projection); | |
} | |
void AddParameters (MethodDefinition method) | |
{ | |
var return_parameter = method.MethodReturnType.parameter; | |
if (return_parameter != null && RequiresParameterRow (return_parameter)) | |
AddParameter (0, return_parameter, param_table); | |
if (!method.HasParameters) | |
return; | |
var parameters = method.Parameters; | |
for (int i = 0; i < parameters.Count; i++) { | |
var parameter = parameters [i]; | |
if (!RequiresParameterRow (parameter)) | |
continue; | |
AddParameter ((ushort) (i + 1), parameter, param_table); | |
} | |
} | |
void AddPInvokeInfo (MethodDefinition method) | |
{ | |
var pinvoke = method.PInvokeInfo; | |
if (pinvoke == null) | |
return; | |
var table = GetTable<ImplMapTable> (Table.ImplMap); | |
table.AddRow (new ImplMapRow ( | |
pinvoke.Attributes, | |
MakeCodedRID (method, CodedIndex.MemberForwarded), | |
GetStringIndex (pinvoke.EntryPoint), | |
pinvoke.Module.MetadataToken.RID)); | |
} | |
void AddOverrides (MethodDefinition method) | |
{ | |
var overrides = method.Overrides; | |
var table = GetTable<MethodImplTable> (Table.MethodImpl); | |
for (int i = 0; i < overrides.Count; i++) { | |
table.AddRow (new MethodImplRow ( | |
method.DeclaringType.token.RID, | |
MakeCodedRID (method, CodedIndex.MethodDefOrRef), | |
MakeCodedRID (LookupToken (overrides [i]), CodedIndex.MethodDefOrRef))); | |
} | |
} | |
static bool RequiresParameterRow (ParameterDefinition parameter) | |
{ | |
return !string.IsNullOrEmpty (parameter.Name) | |
|| parameter.Attributes != ParameterAttributes.None | |
|| parameter.HasMarshalInfo | |
|| parameter.HasConstant | |
|| parameter.HasCustomAttributes; | |
} | |
void AddParameter (ushort sequence, ParameterDefinition parameter, ParamTable table) | |
{ | |
table.AddRow (new ParamRow ( | |
parameter.Attributes, | |
sequence, | |
GetStringIndex (parameter.Name))); | |
parameter.token = new MetadataToken (TokenType.Param, param_rid++); | |
if (parameter.HasCustomAttributes) | |
AddCustomAttributes (parameter); | |
if (parameter.HasConstant) | |
AddConstant (parameter, parameter.ParameterType); | |
if (parameter.HasMarshalInfo) | |
AddMarshalInfo (parameter); | |
} | |
void AddMarshalInfo (IMarshalInfoProvider owner) | |
{ | |
var table = GetTable<FieldMarshalTable> (Table.FieldMarshal); | |
table.AddRow (new FieldMarshalRow ( | |
MakeCodedRID (owner, CodedIndex.HasFieldMarshal), | |
GetBlobIndex (GetMarshalInfoSignature (owner)))); | |
} | |
void AddProperties (TypeDefinition type) | |
{ | |
var properties = type.Properties; | |
property_map_table.AddRow (new PropertyMapRow (type.token.RID, property_rid)); | |
for (int i = 0; i < properties.Count; i++) | |
AddProperty (properties [i]); | |
} | |
void AddProperty (PropertyDefinition property) | |
{ | |
property_table.AddRow (new PropertyRow ( | |
property.Attributes, | |
GetStringIndex (property.Name), | |
GetBlobIndex (GetPropertySignature (property)))); | |
property.token = new MetadataToken (TokenType.Property, property_rid++); | |
var method = property.GetMethod; | |
if (method != null) | |
AddSemantic (MethodSemanticsAttributes.Getter, property, method); | |
method = property.SetMethod; | |
if (method != null) | |
AddSemantic (MethodSemanticsAttributes.Setter, property, method); | |
if (property.HasOtherMethods) | |
AddOtherSemantic (property, property.OtherMethods); | |
if (property.HasCustomAttributes) | |
AddCustomAttributes (property); | |
if (property.HasConstant) | |
AddConstant (property, property.PropertyType); | |
} | |
void AddOtherSemantic (IMetadataTokenProvider owner, Collection<MethodDefinition> others) | |
{ | |
for (int i = 0; i < others.Count; i++) | |
AddSemantic (MethodSemanticsAttributes.Other, owner, others [i]); | |
} | |
void AddEvents (TypeDefinition type) | |
{ | |
var events = type.Events; | |
event_map_table.AddRow (new EventMapRow (type.token.RID, event_rid)); | |
for (int i = 0; i < events.Count; i++) | |
AddEvent (events [i]); | |
} | |
void AddEvent (EventDefinition @event) | |
{ | |
event_table.AddRow (new EventRow ( | |
@event.Attributes, | |
GetStringIndex (@event.Name), | |
MakeCodedRID (GetTypeToken (@event.EventType), CodedIndex.TypeDefOrRef))); | |
@event.token = new MetadataToken (TokenType.Event, event_rid++); | |
var method = @event.AddMethod; | |
if (method != null) | |
AddSemantic (MethodSemanticsAttributes.AddOn, @event, method); | |
method = @event.InvokeMethod; | |
if (method != null) | |
AddSemantic (MethodSemanticsAttributes.Fire, @event, method); | |
method = @event.RemoveMethod; | |
if (method != null) | |
AddSemantic (MethodSemanticsAttributes.RemoveOn, @event, method); | |
if (@event.HasOtherMethods) | |
AddOtherSemantic (@event, @event.OtherMethods); | |
if (@event.HasCustomAttributes) | |
AddCustomAttributes (@event); | |
} | |
void AddSemantic (MethodSemanticsAttributes semantics, IMetadataTokenProvider provider, MethodDefinition method) | |
{ | |
method.SemanticsAttributes = semantics; | |
var table = GetTable<MethodSemanticsTable> (Table.MethodSemantics); | |
table.AddRow (new MethodSemanticsRow ( | |
semantics, | |
method.token.RID, | |
MakeCodedRID (provider, CodedIndex.HasSemantics))); | |
} | |
void AddConstant (IConstantProvider owner, TypeReference type) | |
{ | |
var constant = owner.Constant; | |
var etype = GetConstantType (type, constant); | |
constant_table.AddRow (new ConstantRow ( | |
etype, | |
MakeCodedRID (owner.MetadataToken, CodedIndex.HasConstant), | |
GetBlobIndex (GetConstantSignature (etype, constant)))); | |
} | |
static ElementType GetConstantType (TypeReference constant_type, object constant) | |
{ | |
if (constant == null) | |
return ElementType.Class; | |
var etype = constant_type.etype; | |
switch (etype) { | |
case ElementType.None: | |
var type = constant_type.CheckedResolve (); | |
if (type.IsEnum) | |
return GetConstantType (type.GetEnumUnderlyingType (), constant); | |
return ElementType.Class; | |
case ElementType.String: | |
return ElementType.String; | |
case ElementType.Object: | |
return GetConstantType (constant.GetType ()); | |
case ElementType.Array: | |
case ElementType.SzArray: | |
case ElementType.MVar: | |
case ElementType.Var: | |
return ElementType.Class; | |
case ElementType.GenericInst: | |
var generic_instance = (GenericInstanceType) constant_type; | |
if (generic_instance.ElementType.IsTypeOf ("System", "Nullable`1")) | |
return GetConstantType (generic_instance.GenericArguments [0], constant); | |
return GetConstantType (((TypeSpecification) constant_type).ElementType, constant); | |
case ElementType.CModOpt: | |
case ElementType.CModReqD: | |
case ElementType.ByRef: | |
case ElementType.Sentinel: | |
return GetConstantType (((TypeSpecification) constant_type).ElementType, constant); | |
case ElementType.Boolean: | |
case ElementType.Char: | |
case ElementType.I: | |
case ElementType.I1: | |
case ElementType.I2: | |
case ElementType.I4: | |
case ElementType.I8: | |
case ElementType.U: | |
case ElementType.U1: | |
case ElementType.U2: | |
case ElementType.U4: | |
case ElementType.U8: | |
case ElementType.R4: | |
case ElementType.R8: | |
return GetConstantType (constant.GetType ()); | |
default: | |
return etype; | |
} | |
} | |
static ElementType GetConstantType (Type type) | |
{ | |
switch (type.GetTypeCode ()) { | |
case TypeCode.Boolean: | |
return ElementType.Boolean; | |
case TypeCode.Byte: | |
return ElementType.U1; | |
case TypeCode.SByte: | |
return ElementType.I1; | |
case TypeCode.Char: | |
return ElementType.Char; | |
case TypeCode.Int16: | |
return ElementType.I2; | |
case TypeCode.UInt16: | |
return ElementType.U2; | |
case TypeCode.Int32: | |
return ElementType.I4; | |
case TypeCode.UInt32: | |
return ElementType.U4; | |
case TypeCode.Int64: | |
return ElementType.I8; | |
case TypeCode.UInt64: | |
return ElementType.U8; | |
case TypeCode.Single: | |
return ElementType.R4; | |
case TypeCode.Double: | |
return ElementType.R8; | |
case TypeCode.String: | |
return ElementType.String; | |
default: | |
throw new NotSupportedException (type.FullName); | |
} | |
} | |
void AddCustomAttributes (ICustomAttributeProvider owner) | |
{ | |
var custom_attributes = owner.CustomAttributes; | |
for (int i = 0; i < custom_attributes.Count; i++) { | |
var attribute = custom_attributes [i]; | |
var projection = WindowsRuntimeProjections.RemoveProjection (attribute); | |
custom_attribute_table.AddRow (new CustomAttributeRow ( | |
MakeCodedRID (owner, CodedIndex.HasCustomAttribute), | |
MakeCodedRID (LookupToken (attribute.Constructor), CodedIndex.CustomAttributeType), | |
GetBlobIndex (GetCustomAttributeSignature (attribute)))); | |
WindowsRuntimeProjections.ApplyProjection (attribute, projection); | |
} | |
} | |
void AddSecurityDeclarations (ISecurityDeclarationProvider owner) | |
{ | |
var declarations = owner.SecurityDeclarations; | |
for (int i = 0; i < declarations.Count; i++) { | |
var declaration = declarations [i]; | |
declsec_table.AddRow (new DeclSecurityRow ( | |
declaration.Action, | |
MakeCodedRID (owner, CodedIndex.HasDeclSecurity), | |
GetBlobIndex (GetSecurityDeclarationSignature (declaration)))); | |
} | |
} | |
MetadataToken GetMemberRefToken (MemberReference member) | |
{ | |
var projection = WindowsRuntimeProjections.RemoveProjection (member); | |
var row = CreateMemberRefRow (member); | |
MetadataToken token; | |
if (!member_ref_map.TryGetValue (row, out token)) | |
token = AddMemberReference (member, row); | |
WindowsRuntimeProjections.ApplyProjection (member, projection); | |
return token; | |
} | |
MemberRefRow CreateMemberRefRow (MemberReference member) | |
{ | |
return new MemberRefRow ( | |
MakeCodedRID (GetTypeToken (member.DeclaringType), CodedIndex.MemberRefParent), | |
GetStringIndex (member.Name), | |
GetBlobIndex (GetMemberRefSignature (member))); | |
} | |
MetadataToken AddMemberReference (MemberReference member, MemberRefRow row) | |
{ | |
member.token = new MetadataToken (TokenType.MemberRef, member_ref_table.AddRow (row)); | |
var token = member.token; | |
member_ref_map.Add (row, token); | |
return token; | |
} | |
MetadataToken GetMethodSpecToken (MethodSpecification method_spec) | |
{ | |
var row = CreateMethodSpecRow (method_spec); | |
MetadataToken token; | |
if (method_spec_map.TryGetValue (row, out token)) | |
return token; | |
AddMethodSpecification (method_spec, row); | |
return method_spec.token; | |
} | |
void AddMethodSpecification (MethodSpecification method_spec, MethodSpecRow row) | |
{ | |
method_spec.token = new MetadataToken (TokenType.MethodSpec, method_spec_table.AddRow (row)); | |
method_spec_map.Add (row, method_spec.token); | |
} | |
MethodSpecRow CreateMethodSpecRow (MethodSpecification method_spec) | |
{ | |
return new MethodSpecRow ( | |
MakeCodedRID (LookupToken (method_spec.ElementMethod), CodedIndex.MethodDefOrRef), | |
GetBlobIndex (GetMethodSpecSignature (method_spec))); | |
} | |
SignatureWriter CreateSignatureWriter () | |
{ | |
return new SignatureWriter (this); | |
} | |
SignatureWriter GetMethodSpecSignature (MethodSpecification method_spec) | |
{ | |
if (!method_spec.IsGenericInstance) | |
throw new NotSupportedException (); | |
var generic_instance = (GenericInstanceMethod) method_spec; | |
var signature = CreateSignatureWriter (); | |
signature.WriteByte (0x0a); | |
signature.WriteGenericInstanceSignature (generic_instance); | |
return signature; | |
} | |
public uint AddStandAloneSignature (uint signature) | |
{ | |
return (uint) standalone_sig_table.AddRow (signature); | |
} | |
public uint GetLocalVariableBlobIndex (Collection<VariableDefinition> variables) | |
{ | |
return GetBlobIndex (GetVariablesSignature (variables)); | |
} | |
public uint GetCallSiteBlobIndex (CallSite call_site) | |
{ | |
return GetBlobIndex (GetMethodSignature (call_site)); | |
} | |
public uint GetConstantTypeBlobIndex (TypeReference constant_type) | |
{ | |
return GetBlobIndex (GetConstantTypeSignature (constant_type)); | |
} | |
SignatureWriter GetVariablesSignature (Collection<VariableDefinition> variables) | |
{ | |
var signature = CreateSignatureWriter (); | |
signature.WriteByte (0x7); | |
signature.WriteCompressedUInt32 ((uint) variables.Count); | |
for (int i = 0; i < variables.Count; i++) | |
signature.WriteTypeSignature (variables [i].VariableType); | |
return signature; | |
} | |
SignatureWriter GetConstantTypeSignature (TypeReference constant_type) | |
{ | |
var signature = CreateSignatureWriter (); | |
signature.WriteByte (0x6); | |
signature.WriteTypeSignature (constant_type); | |
return signature; | |
} | |
SignatureWriter GetFieldSignature (FieldReference field) | |
{ | |
var signature = CreateSignatureWriter (); | |
signature.WriteByte (0x6); | |
signature.WriteTypeSignature (field.FieldType); | |
return signature; | |
} | |
SignatureWriter GetMethodSignature (IMethodSignature method) | |
{ | |
var signature = CreateSignatureWriter (); | |
signature.WriteMethodSignature (method); | |
return signature; | |
} | |
SignatureWriter GetMemberRefSignature (MemberReference member) | |
{ | |
var field = member as FieldReference; | |
if (field != null) | |
return GetFieldSignature (field); | |
var method = member as MethodReference; | |
if (method != null) | |
return GetMethodSignature (method); | |
throw new NotSupportedException (); | |
} | |
SignatureWriter GetPropertySignature (PropertyDefinition property) | |
{ | |
var signature = CreateSignatureWriter (); | |
byte calling_convention = 0x8; | |
if (property.HasThis) | |
calling_convention |= 0x20; | |
uint param_count = 0; | |
Collection<ParameterDefinition> parameters = null; | |
if (property.HasParameters) { | |
parameters = property.Parameters; | |
param_count = (uint) parameters.Count; | |
} | |
signature.WriteByte (calling_convention); | |
signature.WriteCompressedUInt32 (param_count); | |
signature.WriteTypeSignature (property.PropertyType); | |
if (param_count == 0) | |
return signature; | |
for (int i = 0; i < param_count; i++) | |
signature.WriteTypeSignature (parameters [i].ParameterType); | |
return signature; | |
} | |
SignatureWriter GetTypeSpecSignature (TypeReference type) | |
{ | |
var signature = CreateSignatureWriter (); | |
signature.WriteTypeSignature (type); | |
return signature; | |
} | |
SignatureWriter GetConstantSignature (ElementType type, object value) | |
{ | |
var signature = CreateSignatureWriter (); | |
switch (type) { | |
case ElementType.Array: | |
case ElementType.SzArray: | |
case ElementType.Class: | |
case ElementType.Object: | |
case ElementType.None: | |
case ElementType.Var: | |
case ElementType.MVar: | |
signature.WriteInt32 (0); | |
break; | |
case ElementType.String: | |
signature.WriteConstantString ((string) value); | |
break; | |
default: | |
signature.WriteConstantPrimitive (value); | |
break; | |
} | |
return signature; | |
} | |
SignatureWriter GetCustomAttributeSignature (CustomAttribute attribute) | |
{ | |
var signature = CreateSignatureWriter (); | |
if (!attribute.resolved) { | |
signature.WriteBytes (attribute.GetBlob ()); | |
return signature; | |
} | |
signature.WriteUInt16 (0x0001); | |
signature.WriteCustomAttributeConstructorArguments (attribute); | |
signature.WriteCustomAttributeNamedArguments (attribute); | |
return signature; | |
} | |
SignatureWriter GetSecurityDeclarationSignature (SecurityDeclaration declaration) | |
{ | |
var signature = CreateSignatureWriter (); | |
if (!declaration.resolved) | |
signature.WriteBytes (declaration.GetBlob ()); | |
else if (module.Runtime < TargetRuntime.Net_2_0) | |
signature.WriteXmlSecurityDeclaration (declaration); | |
else | |
signature.WriteSecurityDeclaration (declaration); | |
return signature; | |
} | |
SignatureWriter GetMarshalInfoSignature (IMarshalInfoProvider owner) | |
{ | |
var signature = CreateSignatureWriter (); | |
signature.WriteMarshalInfo (owner.MarshalInfo); | |
return signature; | |
} | |
static Exception CreateForeignMemberException (MemberReference member) | |
{ | |
return new ArgumentException (string.Format ("Member '{0}' is declared in another module and needs to be imported", member)); | |
} | |
public MetadataToken LookupToken (IMetadataTokenProvider provider) | |
{ | |
if (provider == null) | |
throw new ArgumentNullException (); | |
if (metadata_builder != null) | |
return metadata_builder.LookupToken (provider); | |
var member = provider as MemberReference; | |
if (member == null || member.Module != module) | |
throw CreateForeignMemberException (member); | |
var token = provider.MetadataToken; | |
switch (token.TokenType) { | |
case TokenType.TypeDef: | |
case TokenType.Method: | |
case TokenType.Field: | |
case TokenType.Event: | |
case TokenType.Property: | |
return token; | |
case TokenType.TypeRef: | |
case TokenType.TypeSpec: | |
case TokenType.GenericParam: | |
return GetTypeToken ((TypeReference) provider); | |
case TokenType.MethodSpec: | |
return GetMethodSpecToken ((MethodSpecification) provider); | |
case TokenType.MemberRef: | |
return GetMemberRefToken (member); | |
default: | |
throw new NotSupportedException (); | |
} | |
} | |
public void AddMethodDebugInformation (MethodDebugInformation method_info) | |
{ | |
if (method_info.HasSequencePoints) | |
AddSequencePoints (method_info); | |
if (method_info.Scope != null) | |
AddLocalScope (method_info, method_info.Scope); | |
if (method_info.StateMachineKickOffMethod != null) | |
AddStateMachineMethod (method_info); | |
AddCustomDebugInformations (method_info.Method); | |
} | |
void AddStateMachineMethod (MethodDebugInformation method_info) | |
{ | |
state_machine_method_table.AddRow (new StateMachineMethodRow (method_info.Method.MetadataToken.RID, method_info.StateMachineKickOffMethod.MetadataToken.RID)); | |
} | |
void AddLocalScope (MethodDebugInformation method_info, ScopeDebugInformation scope) | |
{ | |
var rid = local_scope_table.AddRow (new LocalScopeRow ( | |
method_info.Method.MetadataToken.RID, | |
scope.import != null ? AddImportScope (scope.import) : 0, | |
local_variable_rid, | |
local_constant_rid, | |
(uint) scope.Start.Offset, | |
(uint) ((scope.End.IsEndOfMethod ? method_info.code_size : scope.End.Offset) - scope.Start.Offset))); | |
scope.token = new MetadataToken (TokenType.LocalScope, rid); | |
AddCustomDebugInformations (scope); | |
if (scope.HasVariables) | |
AddLocalVariables (scope); | |
if (scope.HasConstants) | |
AddLocalConstants (scope); | |
for (int i = 0; i < scope.Scopes.Count; i++) | |
AddLocalScope (method_info, scope.Scopes [i]); | |
} | |
void AddLocalVariables (ScopeDebugInformation scope) | |
{ | |
for (int i = 0; i < scope.Variables.Count; i++) { | |
var variable = scope.Variables [i]; | |
local_variable_table.AddRow (new LocalVariableRow (variable.Attributes, (ushort) variable.Index, GetStringIndex (variable.Name))); | |
variable.token = new MetadataToken (TokenType.LocalVariable, local_variable_rid); | |
local_variable_rid++; | |
AddCustomDebugInformations (variable); | |
} | |
} | |
void AddLocalConstants (ScopeDebugInformation scope) | |
{ | |
for (int i = 0; i < scope.Constants.Count; i++) { | |
var constant = scope.Constants [i]; | |
local_constant_table.AddRow (new LocalConstantRow (GetStringIndex (constant.Name), GetBlobIndex (GetConstantSignature(constant)))); | |
constant.token = new MetadataToken (TokenType.LocalConstant, local_constant_rid); | |
local_constant_rid++; | |
} | |
} | |
SignatureWriter GetConstantSignature (ConstantDebugInformation constant) | |
{ | |
var type = constant.ConstantType; | |
var signature = CreateSignatureWriter (); | |
signature.WriteTypeSignature (type); | |
if (type.IsTypeOf ("System", "Decimal")) { | |
var bits = decimal.GetBits ((decimal) constant.Value); | |
var low = (uint) bits [0]; | |
var mid = (uint) bits [1]; | |
var high = (uint) bits [2]; | |
var scale = (byte) (bits [3] >> 16); | |
var negative = (bits [3] & 0x80000000) != 0; | |
signature.WriteByte ((byte) (scale | (negative ? 0x80 : 0x00))); | |
signature.WriteUInt32 (low); | |
signature.WriteUInt32 (mid); | |
signature.WriteUInt32 (high); | |
return signature; | |
} | |
if (type.IsTypeOf ("System", "DateTime")) { | |
var date = (DateTime) constant.Value; | |
signature.WriteInt64 (date.Ticks); | |
return signature; | |
} | |
signature.WriteBytes (GetConstantSignature (type.etype, constant.Value)); | |
return signature; | |
} | |
public void AddCustomDebugInformations (ICustomDebugInformationProvider provider) | |
{ | |
if (!provider.HasCustomDebugInformations) | |
return; | |
var custom_infos = provider.CustomDebugInformations; | |
for (int i = 0; i < custom_infos.Count; i++) { | |
var custom_info = custom_infos [i]; | |
switch (custom_info.Kind) { | |
case CustomDebugInformationKind.Binary: | |
var binary_info = (BinaryCustomDebugInformation) custom_info; | |
AddCustomDebugInformation (provider, binary_info, GetBlobIndex (binary_info.Data)); | |
break; | |
case CustomDebugInformationKind.AsyncMethodBody: | |
AddAsyncMethodBodyDebugInformation (provider, (AsyncMethodBodyDebugInformation) custom_info); | |
break; | |
case CustomDebugInformationKind.StateMachineScope: | |
AddStateMachineScopeDebugInformation (provider, (StateMachineScopeDebugInformation) custom_info); | |
break; | |
case CustomDebugInformationKind.EmbeddedSource: | |
AddEmbeddedSourceDebugInformation (provider, (EmbeddedSourceDebugInformation) custom_info); | |
break; | |
case CustomDebugInformationKind.SourceLink: | |
AddSourceLinkDebugInformation (provider, (SourceLinkDebugInformation) custom_info); | |
break; | |
default: | |
throw new NotImplementedException (); | |
} | |
} | |
} | |
void AddStateMachineScopeDebugInformation (ICustomDebugInformationProvider provider, StateMachineScopeDebugInformation state_machine_scope) | |
{ | |
var method_info = ((MethodDefinition) provider).DebugInformation; | |
var signature = CreateSignatureWriter (); | |
var scopes = state_machine_scope.Scopes; | |
for (int i = 0; i < scopes.Count; i++) { | |
var scope = scopes [i]; | |
signature.WriteUInt32 ((uint) scope.Start.Offset); | |
var end_offset = scope.End.IsEndOfMethod | |
? method_info.code_size | |
: scope.End.Offset; | |
signature.WriteUInt32 ((uint) (end_offset - scope.Start.Offset)); | |
} | |
AddCustomDebugInformation (provider, state_machine_scope, signature); | |
} | |
void AddAsyncMethodBodyDebugInformation (ICustomDebugInformationProvider provider, AsyncMethodBodyDebugInformation async_method) | |
{ | |
var signature = CreateSignatureWriter (); | |
signature.WriteUInt32 ((uint) async_method.catch_handler.Offset + 1); | |
if (!async_method.yields.IsNullOrEmpty ()) { | |
for (int i = 0; i < async_method.yields.Count; i++) { | |
signature.WriteUInt32 ((uint) async_method.yields [i].Offset); | |
signature.WriteUInt32 ((uint) async_method.resumes [i].Offset); | |
signature.WriteCompressedUInt32 (async_method.resume_methods [i].MetadataToken.RID); | |
} | |
} | |
AddCustomDebugInformation (provider, async_method, signature); | |
} | |
void AddEmbeddedSourceDebugInformation (ICustomDebugInformationProvider provider, EmbeddedSourceDebugInformation embedded_source) | |
{ | |
var signature = CreateSignatureWriter (); | |
var content = embedded_source.content ?? Empty<byte>.Array; | |
if (embedded_source.compress) { | |
signature.WriteInt32 (content.Length); | |
var decompressed_stream = new MemoryStream (content); | |
var content_stream = new MemoryStream (); | |
using (var compress_stream = new DeflateStream (content_stream, CompressionMode.Compress, leaveOpen: true)) | |
decompressed_stream.CopyTo (compress_stream); | |
signature.WriteBytes (content_stream.ToArray ()); | |
} else { | |
signature.WriteInt32 (0); | |
signature.WriteBytes (content); | |
} | |
AddCustomDebugInformation (provider, embedded_source, signature); | |
} | |
void AddSourceLinkDebugInformation (ICustomDebugInformationProvider provider, SourceLinkDebugInformation source_link) | |
{ | |
var signature = CreateSignatureWriter (); | |
signature.WriteBytes (Encoding.UTF8.GetBytes (source_link.content)); | |
AddCustomDebugInformation (provider, source_link, signature); | |
} | |
void AddCustomDebugInformation (ICustomDebugInformationProvider provider, CustomDebugInformation custom_info, SignatureWriter signature) | |
{ | |
AddCustomDebugInformation (provider, custom_info, GetBlobIndex (signature)); | |
} | |
void AddCustomDebugInformation (ICustomDebugInformationProvider provider, CustomDebugInformation custom_info, uint blob_index) | |
{ | |
var rid = custom_debug_information_table.AddRow (new CustomDebugInformationRow ( | |
MakeCodedRID (provider.MetadataToken, CodedIndex.HasCustomDebugInformation), | |
GetGuidIndex (custom_info.Identifier), | |
blob_index)); | |
custom_info.token = new MetadataToken (TokenType.CustomDebugInformation, rid); | |
} | |
uint AddImportScope (ImportDebugInformation import) | |
{ | |
uint parent = 0; | |
if (import.Parent != null) | |
parent = AddImportScope (import.Parent); | |
uint targets_index = 0; | |
if (import.HasTargets) { | |
var signature = CreateSignatureWriter (); | |
for (int i = 0; i < import.Targets.Count; i++) | |
AddImportTarget (import.Targets [i], signature); | |
targets_index = GetBlobIndex (signature); | |
} | |
var row = new ImportScopeRow (parent, targets_index); | |
MetadataToken import_token; | |
if (import_scope_map.TryGetValue (row, out import_token)) | |
return import_token.RID; | |
import_token = new MetadataToken (TokenType.ImportScope, import_scope_table.AddRow (row)); | |
import_scope_map.Add (row, import_token); | |
return import_token.RID; | |
} | |
void AddImportTarget (ImportTarget target, SignatureWriter signature) | |
{ | |
signature.WriteCompressedUInt32 ((uint)target.kind); | |
switch (target.kind) { | |
case ImportTargetKind.ImportNamespace: | |
signature.WriteCompressedUInt32 (GetUTF8StringBlobIndex (target.@namespace)); | |
break; | |
case ImportTargetKind.ImportNamespaceInAssembly: | |
signature.WriteCompressedUInt32 (target.reference.MetadataToken.RID); | |
signature.WriteCompressedUInt32 (GetUTF8StringBlobIndex (target.@namespace)); | |
break; | |
case ImportTargetKind.ImportType: | |
signature.WriteTypeToken (target.type); | |
break; | |
case ImportTargetKind.ImportXmlNamespaceWithAlias: | |
signature.WriteCompressedUInt32 (GetUTF8StringBlobIndex (target.alias)); | |
signature.WriteCompressedUInt32 (GetUTF8StringBlobIndex (target.@namespace)); | |
break; | |
case ImportTargetKind.ImportAlias: | |
signature.WriteCompressedUInt32 (GetUTF8StringBlobIndex (target.alias)); | |
break; | |
case ImportTargetKind.DefineAssemblyAlias: | |
signature.WriteCompressedUInt32 (GetUTF8StringBlobIndex (target.alias)); | |
signature.WriteCompressedUInt32 (target.reference.MetadataToken.RID); | |
break; | |
case ImportTargetKind.DefineNamespaceAlias: | |
signature.WriteCompressedUInt32 (GetUTF8StringBlobIndex (target.alias)); | |
signature.WriteCompressedUInt32 (GetUTF8StringBlobIndex (target.@namespace)); | |
break; | |
case ImportTargetKind.DefineNamespaceInAssemblyAlias: | |
signature.WriteCompressedUInt32 (GetUTF8StringBlobIndex (target.alias)); | |
signature.WriteCompressedUInt32 (target.reference.MetadataToken.RID); | |
signature.WriteCompressedUInt32 (GetUTF8StringBlobIndex (target.@namespace)); | |
break; | |
case ImportTargetKind.DefineTypeAlias: | |
signature.WriteCompressedUInt32 (GetUTF8StringBlobIndex (target.alias)); | |
signature.WriteTypeToken (target.type); | |
break; | |
} | |
} | |
uint GetUTF8StringBlobIndex (string s) | |
{ | |
return GetBlobIndex (Encoding.UTF8.GetBytes (s)); | |
} | |
public MetadataToken GetDocumentToken (Document document) | |
{ | |
MetadataToken token; | |
if (document_map.TryGetValue (document.Url, out token)) | |
return token; | |
token = new MetadataToken (TokenType.Document, document_table.AddRow ( | |
new DocumentRow (GetBlobIndex (GetDocumentNameSignature (document)), | |
GetGuidIndex (document.HashAlgorithm.ToGuid ()), | |
GetBlobIndex (document.Hash), | |
GetGuidIndex (document.Language.ToGuid ())))); | |
document.token = token; | |
AddCustomDebugInformations (document); | |
document_map.Add (document.Url, token); | |
return token; | |
} | |
SignatureWriter GetDocumentNameSignature (Document document) | |
{ | |
var name = document.Url; | |
var signature = CreateSignatureWriter (); | |
char separator; | |
if (!TryGetDocumentNameSeparator (name, out separator)) { | |
signature.WriteByte (0); | |
signature.WriteCompressedUInt32 (GetUTF8StringBlobIndex (name)); | |
return signature; | |
} | |
signature.WriteByte ((byte) separator); | |
var parts = name.Split (new [] { separator }); | |
for (int i = 0; i < parts.Length; i++) { | |
if (parts [i] == String.Empty) | |
signature.WriteCompressedUInt32 (0); | |
else | |
signature.WriteCompressedUInt32 (GetUTF8StringBlobIndex (parts [i])); | |
} | |
return signature; | |
} | |
static bool TryGetDocumentNameSeparator (string path, out char separator) | |
{ | |
const char unix = '/'; | |
const char win = '\\'; | |
const char zero = (char) 0; | |
separator = zero; | |
if (string.IsNullOrEmpty (path)) | |
return false; | |
int unix_count = 0; | |
int win_count = 0; | |
for (int i = 0; i < path.Length; i++) { | |
if (path [i] == unix) | |
unix_count++; | |
else if (path [i] == win) | |
win_count++; | |
} | |
if (unix_count == 0 && win_count == 0) | |
return false; | |
if (unix_count >= win_count) { | |
separator = unix; | |
return true; | |
} | |
separator = win; | |
return true; | |
} | |
void AddSequencePoints (MethodDebugInformation info) | |
{ | |
var rid = info.Method.MetadataToken.RID; | |
Document document; | |
if (info.TryGetUniqueDocument (out document)) | |
method_debug_information_table.rows [rid - 1].Col1 = GetDocumentToken (document).RID; | |
var signature = CreateSignatureWriter (); | |
signature.WriteSequencePoints (info); | |
method_debug_information_table.rows [rid - 1].Col2 = GetBlobIndex (signature); | |
} | |
} | |
sealed class SignatureWriter : ByteBuffer { | |
readonly MetadataBuilder metadata; | |
public SignatureWriter (MetadataBuilder metadata) | |
: base (6) | |
{ | |
this.metadata = metadata; | |
} | |
public void WriteElementType (ElementType element_type) | |
{ | |
WriteByte ((byte) element_type); | |
} | |
public void WriteUTF8String (string @string) | |
{ | |
if (@string == null) { | |
WriteByte (0xff); | |
return; | |
} | |
var bytes = Encoding.UTF8.GetBytes (@string); | |
WriteCompressedUInt32 ((uint) bytes.Length); | |
WriteBytes (bytes); | |
} | |
public void WriteMethodSignature (IMethodSignature method) | |
{ | |
byte calling_convention = (byte) method.CallingConvention; | |
if (method.HasThis) | |
calling_convention |= 0x20; | |
if (method.ExplicitThis) | |
calling_convention |= 0x40; | |
var generic_provider = method as IGenericParameterProvider; | |
var generic_arity = generic_provider != null && generic_provider.HasGenericParameters | |
? generic_provider.GenericParameters.Count | |
: 0; | |
if (generic_arity > 0) | |
calling_convention |= 0x10; | |
var param_count = method.HasParameters ? method.Parameters.Count : 0; | |
WriteByte (calling_convention); | |
if (generic_arity > 0) | |
WriteCompressedUInt32 ((uint) generic_arity); | |
WriteCompressedUInt32 ((uint) param_count); | |
WriteTypeSignature (method.ReturnType); | |
if (param_count == 0) | |
return; | |
var parameters = method.Parameters; | |
for (int i = 0; i < param_count; i++) | |
WriteTypeSignature (parameters [i].ParameterType); | |
} | |
uint MakeTypeDefOrRefCodedRID (TypeReference type) | |
{ | |
return CodedIndex.TypeDefOrRef.CompressMetadataToken (metadata.LookupToken (type)); | |
} | |
public void WriteTypeToken (TypeReference type) | |
{ | |
WriteCompressedUInt32 (MakeTypeDefOrRefCodedRID (type)); | |
} | |
public void WriteTypeSignature (TypeReference type) | |
{ | |
if (type == null) | |
throw new ArgumentNullException (); | |
var etype = type.etype; | |
switch (etype) { | |
case ElementType.MVar: | |
case ElementType.Var: { | |
var generic_parameter = (GenericParameter) type; | |
WriteElementType (etype); | |
var position = generic_parameter.Position; | |
if (position == -1) | |
throw new NotSupportedException (); | |
WriteCompressedUInt32 ((uint) position); | |
break; | |
} | |
case ElementType.GenericInst: { | |
var generic_instance = (GenericInstanceType) type; | |
WriteElementType (ElementType.GenericInst); | |
WriteElementType (generic_instance.IsValueType ? ElementType.ValueType : ElementType.Class); | |
WriteCompressedUInt32 (MakeTypeDefOrRefCodedRID (generic_instance.ElementType)); | |
WriteGenericInstanceSignature (generic_instance); | |
break; | |
} | |
case ElementType.Ptr: | |
case ElementType.ByRef: | |
case ElementType.Pinned: | |
case ElementType.Sentinel: { | |
var type_spec = (TypeSpecification) type; | |
WriteElementType (etype); | |
WriteTypeSignature (type_spec.ElementType); | |
break; | |
} | |
case ElementType.FnPtr: { | |
var fptr = (FunctionPointerType) type; | |
WriteElementType (ElementType.FnPtr); | |
WriteMethodSignature (fptr); | |
break; | |
} | |
case ElementType.CModOpt: | |
case ElementType.CModReqD: { | |
var modifier = (IModifierType) type; | |
WriteModifierSignature (etype, modifier); | |
break; | |
} | |
case ElementType.Array: { | |
var array = (ArrayType) type; | |
if (!array.IsVector) { | |
WriteArrayTypeSignature (array); | |
break; | |
} | |
WriteElementType (ElementType.SzArray); | |
WriteTypeSignature (array.ElementType); | |
break; | |
} | |
case ElementType.None: { | |
WriteElementType (type.IsValueType ? ElementType.ValueType : ElementType.Class); | |
WriteCompressedUInt32 (MakeTypeDefOrRefCodedRID (type)); | |
break; | |
} | |
default: | |
if (!TryWriteElementType (type)) | |
throw new NotSupportedException (); | |
break; | |
} | |
} | |
void WriteArrayTypeSignature (ArrayType array) | |
{ | |
WriteElementType (ElementType.Array); | |
WriteTypeSignature (array.ElementType); | |
var dimensions = array.Dimensions; | |
var rank = dimensions.Count; | |
WriteCompressedUInt32 ((uint) rank); | |
var sized = 0; | |
var lbounds = 0; | |
for (int i = 0; i < rank; i++) { | |
var dimension = dimensions [i]; | |
if (dimension.UpperBound.HasValue) { | |
sized++; | |
lbounds++; | |
} else if (dimension.LowerBound.HasValue) | |
lbounds++; | |
} | |
var sizes = new int [sized]; | |
var low_bounds = new int [lbounds]; | |
for (int i = 0; i < lbounds; i++) { | |
var dimension = dimensions [i]; | |
low_bounds [i] = dimension.LowerBound.GetValueOrDefault (); | |
if (dimension.UpperBound.HasValue) | |
sizes [i] = dimension.UpperBound.Value - low_bounds [i] + 1; | |
} | |
WriteCompressedUInt32 ((uint) sized); | |
for (int i = 0; i < sized; i++) | |
WriteCompressedUInt32 ((uint) sizes [i]); | |
WriteCompressedUInt32 ((uint) lbounds); | |
for (int i = 0; i < lbounds; i++) | |
WriteCompressedInt32 (low_bounds [i]); | |
} | |
public void WriteGenericInstanceSignature (IGenericInstance instance) | |
{ | |
var generic_arguments = instance.GenericArguments; | |
var arity = generic_arguments.Count; | |
WriteCompressedUInt32 ((uint) arity); | |
for (int i = 0; i < arity; i++) | |
WriteTypeSignature (generic_arguments [i]); | |
} | |
void WriteModifierSignature (ElementType element_type, IModifierType type) | |
{ | |
WriteElementType (element_type); | |
WriteCompressedUInt32 (MakeTypeDefOrRefCodedRID (type.ModifierType)); | |
WriteTypeSignature (type.ElementType); | |
} | |
bool TryWriteElementType (TypeReference type) | |
{ | |
var element = type.etype; | |
if (element == ElementType.None) | |
return false; | |
WriteElementType (element); | |
return true; | |
} | |
public void WriteConstantString (string value) | |
{ | |
if (value != null) | |
WriteBytes (Encoding.Unicode.GetBytes (value)); | |
else | |
WriteByte (0xff); | |
} | |
public void WriteConstantPrimitive (object value) | |
{ | |
WritePrimitiveValue (value); | |
} | |
public void WriteCustomAttributeConstructorArguments (CustomAttribute attribute) | |
{ | |
if (!attribute.HasConstructorArguments) | |
return; | |
var arguments = attribute.ConstructorArguments; | |
var parameters = attribute.Constructor.Parameters; | |
if (parameters.Count != arguments.Count) | |
throw new InvalidOperationException (); | |
for (int i = 0; i < arguments.Count; i++) | |
WriteCustomAttributeFixedArgument (parameters [i].ParameterType, arguments [i]); | |
} | |
void WriteCustomAttributeFixedArgument (TypeReference type, CustomAttributeArgument argument) | |
{ | |
if (type.IsArray) { | |
WriteCustomAttributeFixedArrayArgument ((ArrayType) type, argument); | |
return; | |
} | |
WriteCustomAttributeElement (type, argument); | |
} | |
void WriteCustomAttributeFixedArrayArgument (ArrayType type, CustomAttributeArgument argument) | |
{ | |
var values = argument.Value as CustomAttributeArgument []; | |
if (values == null) { | |
WriteUInt32 (0xffffffff); | |
return; | |
} | |
WriteInt32 (values.Length); | |
if (values.Length == 0) | |
return; | |
var element_type = type.ElementType; | |
for (int i = 0; i < values.Length; i++) | |
WriteCustomAttributeElement (element_type, values [i]); | |
} | |
void WriteCustomAttributeElement (TypeReference type, CustomAttributeArgument argument) | |
{ | |
if (type.IsArray) { | |
WriteCustomAttributeFixedArrayArgument ((ArrayType) type, argument); | |
return; | |
} | |
if (type.etype == ElementType.Object) { | |
argument = (CustomAttributeArgument) argument.Value; | |
type = argument.Type; | |
WriteCustomAttributeFieldOrPropType (type); | |
WriteCustomAttributeElement (type, argument); | |
return; | |
} | |
WriteCustomAttributeValue (type, argument.Value); | |
} | |
void WriteCustomAttributeValue (TypeReference type, object value) | |
{ | |
var etype = type.etype; | |
switch (etype) { | |
case ElementType.String: | |
var @string = (string) value; | |
if (@string == null) | |
WriteByte (0xff); | |
else | |
WriteUTF8String (@string); | |
break; | |
case ElementType.None: | |
if (type.IsTypeOf ("System", "Type")) | |
WriteTypeReference ((TypeReference) value); | |
else | |
WriteCustomAttributeEnumValue (type, value); | |
break; | |
default: | |
WritePrimitiveValue (value); | |
break; | |
} | |
} | |
void WritePrimitiveValue (object value) | |
{ | |
if (value == null) | |
throw new ArgumentNullException (); | |
switch (value.GetType ().GetTypeCode ()) { | |
case TypeCode.Boolean: | |
WriteByte ((byte) (((bool) value) ? 1 : 0)); | |
break; | |
case TypeCode.Byte: | |
WriteByte ((byte) value); | |
break; | |
case TypeCode.SByte: | |
WriteSByte ((sbyte) value); | |
break; | |
case TypeCode.Int16: | |
WriteInt16 ((short) value); | |
break; | |
case TypeCode.UInt16: | |
WriteUInt16 ((ushort) value); | |
break; | |
case TypeCode.Char: | |
WriteInt16 ((short) (char) value); | |
break; | |
case TypeCode.Int32: | |
WriteInt32 ((int) value); | |
break; | |
case TypeCode.UInt32: | |
WriteUInt32 ((uint) value); | |
break; | |
case TypeCode.Single: | |
WriteSingle ((float) value); | |
break; | |
case TypeCode.Int64: | |
WriteInt64 ((long) value); | |
break; | |
case TypeCode.UInt64: | |
WriteUInt64 ((ulong) value); | |
break; | |
case TypeCode.Double: | |
WriteDouble ((double) value); | |
break; | |
default: | |
throw new NotSupportedException (value.GetType ().FullName); | |
} | |
} | |
void WriteCustomAttributeEnumValue (TypeReference enum_type, object value) | |
{ | |
var type = enum_type.CheckedResolve (); | |
if (!type.IsEnum) | |
throw new ArgumentException (); | |
WriteCustomAttributeValue (type.GetEnumUnderlyingType (), value); | |
} | |
void WriteCustomAttributeFieldOrPropType (TypeReference type) | |
{ | |
if (type.IsArray) { | |
var array = (ArrayType) type; | |
WriteElementType (ElementType.SzArray); | |
WriteCustomAttributeFieldOrPropType (array.ElementType); | |
return; | |
} | |
var etype = type.etype; | |
switch (etype) { | |
case ElementType.Object: | |
WriteElementType (ElementType.Boxed); | |
return; | |
case ElementType.None: | |
if (type.IsTypeOf ("System", "Type")) | |
WriteElementType (ElementType.Type); | |
else { | |
WriteElementType (ElementType.Enum); | |
WriteTypeReference (type); | |
} | |
return; | |
default: | |
WriteElementType (etype); | |
return; | |
} | |
} | |
public void WriteCustomAttributeNamedArguments (CustomAttribute attribute) | |
{ | |
var count = GetNamedArgumentCount (attribute); | |
WriteUInt16 ((ushort) count); | |
if (count == 0) | |
return; | |
WriteICustomAttributeNamedArguments (attribute); | |
} | |
static int GetNamedArgumentCount (ICustomAttribute attribute) | |
{ | |
int count = 0; | |
if (attribute.HasFields) | |
count += attribute.Fields.Count; | |
if (attribute.HasProperties) | |
count += attribute.Properties.Count; | |
return count; | |
} | |
void WriteICustomAttributeNamedArguments (ICustomAttribute attribute) | |
{ | |
if (attribute.HasFields) | |
WriteCustomAttributeNamedArguments (0x53, attribute.Fields); | |
if (attribute.HasProperties) | |
WriteCustomAttributeNamedArguments (0x54, attribute.Properties); | |
} | |
void WriteCustomAttributeNamedArguments (byte kind, Collection<CustomAttributeNamedArgument> named_arguments) | |
{ | |
for (int i = 0; i < named_arguments.Count; i++) | |
WriteCustomAttributeNamedArgument (kind, named_arguments [i]); | |
} | |
void WriteCustomAttributeNamedArgument (byte kind, CustomAttributeNamedArgument named_argument) | |
{ | |
var argument = named_argument.Argument; | |
WriteByte (kind); | |
WriteCustomAttributeFieldOrPropType (argument.Type); | |
WriteUTF8String (named_argument.Name); | |
WriteCustomAttributeFixedArgument (argument.Type, argument); | |
} | |
void WriteSecurityAttribute (SecurityAttribute attribute) | |
{ | |
WriteTypeReference (attribute.AttributeType); | |
var count = GetNamedArgumentCount (attribute); | |
if (count == 0) { | |
WriteCompressedUInt32 (1); // length | |
WriteCompressedUInt32 (0); // count | |
return; | |
} | |
var buffer = new SignatureWriter (metadata); | |
buffer.WriteCompressedUInt32 ((uint) count); | |
buffer.WriteICustomAttributeNamedArguments (attribute); | |
WriteCompressedUInt32 ((uint) buffer.length); | |
WriteBytes (buffer); | |
} | |
public void WriteSecurityDeclaration (SecurityDeclaration declaration) | |
{ | |
WriteByte ((byte) '.'); | |
var attributes = declaration.security_attributes; | |
if (attributes == null) | |
throw new NotSupportedException (); | |
WriteCompressedUInt32 ((uint) attributes.Count); | |
for (int i = 0; i < attributes.Count; i++) | |
WriteSecurityAttribute (attributes [i]); | |
} | |
public void WriteXmlSecurityDeclaration (SecurityDeclaration declaration) | |
{ | |
var xml = GetXmlSecurityDeclaration (declaration); | |
if (xml == null) | |
throw new NotSupportedException (); | |
WriteBytes (Encoding.Unicode.GetBytes (xml)); | |
} | |
static string GetXmlSecurityDeclaration (SecurityDeclaration declaration) | |
{ | |
if (declaration.security_attributes == null || declaration.security_attributes.Count != 1) | |
return null; | |
var attribute = declaration.security_attributes [0]; | |
if (!attribute.AttributeType.IsTypeOf ("System.Security.Permissions", "PermissionSetAttribute")) | |
return null; | |
if (attribute.properties == null || attribute.properties.Count != 1) | |
return null; | |
var property = attribute.properties [0]; | |
if (property.Name != "XML") | |
return null; | |
return (string) property.Argument.Value; | |
} | |
void WriteTypeReference (TypeReference type) | |
{ | |
WriteUTF8String (TypeParser.ToParseable (type, top_level: false)); | |
} | |
public void WriteMarshalInfo (MarshalInfo marshal_info) | |
{ | |
WriteNativeType (marshal_info.native); | |
switch (marshal_info.native) { | |
case NativeType.Array: { | |
var array = (ArrayMarshalInfo) marshal_info; | |
if (array.element_type != NativeType.None) | |
WriteNativeType (array.element_type); | |
if (array.size_parameter_index > -1) | |
WriteCompressedUInt32 ((uint) array.size_parameter_index); | |
if (array.size > -1) | |
WriteCompressedUInt32 ((uint) array.size); | |
if (array.size_parameter_multiplier > -1) | |
WriteCompressedUInt32 ((uint) array.size_parameter_multiplier); | |
return; | |
} | |
case NativeType.SafeArray: { | |
var array = (SafeArrayMarshalInfo) marshal_info; | |
if (array.element_type != VariantType.None) | |
WriteVariantType (array.element_type); | |
return; | |
} | |
case NativeType.FixedArray: { | |
var array = (FixedArrayMarshalInfo) marshal_info; | |
if (array.size > -1) | |
WriteCompressedUInt32 ((uint) array.size); | |
if (array.element_type != NativeType.None) | |
WriteNativeType (array.element_type); | |
return; | |
} | |
case NativeType.FixedSysString: | |
var sys_string = (FixedSysStringMarshalInfo) marshal_info; | |
if (sys_string.size > -1) | |
WriteCompressedUInt32 ((uint) sys_string.size); | |
return; | |
case NativeType.CustomMarshaler: | |
var marshaler = (CustomMarshalInfo) marshal_info; | |
WriteUTF8String (marshaler.guid != Guid.Empty ? marshaler.guid.ToString () : string.Empty); | |
WriteUTF8String (marshaler.unmanaged_type); | |
WriteTypeReference (marshaler.managed_type); | |
WriteUTF8String (marshaler.cookie); | |
return; | |
} | |
} | |
void WriteNativeType (NativeType native) | |
{ | |
WriteByte ((byte) native); | |
} | |
void WriteVariantType (VariantType variant) | |
{ | |
WriteByte ((byte) variant); | |
} | |
public void WriteSequencePoints (MethodDebugInformation info) | |
{ | |
var start_line = -1; | |
var start_column = -1; | |
WriteCompressedUInt32 (info.local_var_token.RID); | |
Document previous_document; | |
if (!info.TryGetUniqueDocument (out previous_document)) | |
previous_document = null; | |
for (int i = 0; i < info.SequencePoints.Count; i++) { | |
var sequence_point = info.SequencePoints [i]; | |
var document = sequence_point.Document; | |
if (previous_document != document) { | |
var document_token = metadata.GetDocumentToken (document); | |
if (previous_document != null) | |
WriteCompressedUInt32 (0); | |
WriteCompressedUInt32 (document_token.RID); | |
previous_document = document; | |
} | |
if (i > 0) | |
WriteCompressedUInt32 ((uint) (sequence_point.Offset - info.SequencePoints [i - 1].Offset)); | |
else | |
WriteCompressedUInt32 ((uint) sequence_point.Offset); | |
if (sequence_point.IsHidden) { | |
WriteInt16 (0); | |
continue; | |
} | |
var delta_lines = sequence_point.EndLine - sequence_point.StartLine; | |
var delta_columns = sequence_point.EndColumn - sequence_point.StartColumn; | |
WriteCompressedUInt32 ((uint) delta_lines); | |
if (delta_lines == 0) | |
WriteCompressedUInt32((uint) delta_columns); | |
else | |
WriteCompressedInt32 (delta_columns); | |
if (start_line < 0) { | |
WriteCompressedUInt32 ((uint) sequence_point.StartLine); | |
WriteCompressedUInt32 ((uint) sequence_point.StartColumn); | |
} else { | |
WriteCompressedInt32 (sequence_point.StartLine - start_line); | |
WriteCompressedInt32 (sequence_point.StartColumn - start_column); | |
} | |
start_line = sequence_point.StartLine; | |
start_column = sequence_point.StartColumn; | |
} | |
} | |
} | |
#endif | |
static partial class Mixin { | |
public static bool TryGetUniqueDocument (this MethodDebugInformation info, out Document document) | |
{ | |
document = info.SequencePoints [0].Document; | |
for (int i = 1; i < info.SequencePoints.Count; i++) { | |
var sequence_point = info.SequencePoints [i]; | |
if (sequence_point.Document != document) | |
return false; | |
} | |
return true; | |
} | |
} | |
} | |
} | |
#endregion | |
#region Mono.Cecil\*.cs | |
namespace Internal { | |
// | |
// Author: | |
// Jb Evain (jbevain@gmail.com) | |
// | |
// Copyright (c) 2008 - 2015 Jb Evain | |
// Copyright (c) 2008 - 2011 Novell, Inc. | |
// | |
// Licensed under the MIT/X11 license. | |
// | |
using System; | |
using System.Collections.Generic; | |
using System.IO; | |
using System.Reflection; | |
using System.Text; | |
using Mono.Collections.Generic; | |
namespace Mono.Cecil { | |
internal delegate AssemblyDefinition AssemblyResolveEventHandler (object sender, AssemblyNameReference reference); | |
internal sealed class AssemblyResolveEventArgs : EventArgs { | |
readonly AssemblyNameReference reference; | |
public AssemblyNameReference AssemblyReference { | |
get { return reference; } | |
} | |
public AssemblyResolveEventArgs (AssemblyNameReference reference) | |
{ | |
this.reference = reference; | |
} | |
} | |
#if !NET_CORE | |
[Serializable] | |
#endif | |
internal sealed class AssemblyResolutionException : FileNotFoundException { | |
readonly AssemblyNameReference reference; | |
public AssemblyNameReference AssemblyReference { | |
get { return reference; } | |
} | |
public AssemblyResolutionException (AssemblyNameReference reference) | |
: this (reference, null) | |
{ | |
} | |
public AssemblyResolutionException (AssemblyNameReference reference, Exception innerException) | |
: base (string.Format ("Failed to resolve assembly: '{0}'", reference), innerException) | |
{ | |
this.reference = reference; | |
} | |
#if !NET_CORE | |
AssemblyResolutionException ( | |
System.Runtime.Serialization.SerializationInfo info, | |
System.Runtime.Serialization.StreamingContext context) | |
: base (info, context) | |
{ | |
} | |
#endif | |
} | |
internal abstract class BaseAssemblyResolver : IAssemblyResolver { | |
static readonly bool on_mono = Type.GetType ("Mono.Runtime") != null; | |
readonly Collection<string> directories; | |
#if NET_CORE | |
// Maps file names of available trusted platform assemblies to their full paths. | |
// Internal for testing. | |
internal static readonly Lazy<Dictionary<string, string>> TrustedPlatformAssemblies = new Lazy<Dictionary<string, string>> (CreateTrustedPlatformAssemblyMap); | |
#else | |
Collection<string> gac_paths; | |
#endif | |
public void AddSearchDirectory (string directory) | |
{ | |
directories.Add (directory); | |
} | |
public void RemoveSearchDirectory (string directory) | |
{ | |
directories.Remove (directory); | |
} | |
public string [] GetSearchDirectories () | |
{ | |
var directories = new string [this.directories.size]; | |
Array.Copy (this.directories.items, directories, directories.Length); | |
return directories; | |
} | |
public event AssemblyResolveEventHandler ResolveFailure; | |
protected BaseAssemblyResolver () | |
{ | |
directories = new Collection<string> (2) { ".", "bin" }; | |
} | |
AssemblyDefinition GetAssembly (string file, ReaderParameters parameters) | |
{ | |
if (parameters.AssemblyResolver == null) | |
parameters.AssemblyResolver = this; | |
return ModuleDefinition.ReadModule (file, parameters).Assembly; | |
} | |
public virtual AssemblyDefinition Resolve (AssemblyNameReference name) | |
{ | |
return Resolve (name, new ReaderParameters ()); | |
} | |
public virtual AssemblyDefinition Resolve (AssemblyNameReference name, ReaderParameters parameters) | |
{ | |
Mixin.CheckName (name); | |
Mixin.CheckParameters (parameters); | |
var assembly = SearchDirectory (name, directories, parameters); | |
if (assembly != null) | |
return assembly; | |
if (name.IsRetargetable) { | |
// if the reference is retargetable, zero it | |
name = new AssemblyNameReference (name.Name, Mixin.ZeroVersion) { | |
PublicKeyToken = Empty<byte>.Array, | |
}; | |
} | |
#if NET_CORE | |
assembly = SearchTrustedPlatformAssemblies (name, parameters); | |
if (assembly != null) | |
return assembly; | |
#else | |
var framework_dir = Path.GetDirectoryName (typeof (object).Module.FullyQualifiedName); | |
var framework_dirs = on_mono | |
? new [] { framework_dir, Path.Combine (framework_dir, "Facades") } | |
: new [] { framework_dir }; | |
if (IsZero (name.Version)) { | |
assembly = SearchDirectory (name, framework_dirs, parameters); | |
if (assembly != null) | |
return assembly; | |
} | |
if (name.Name == "mscorlib") { | |
assembly = GetCorlib (name, parameters); | |
if (assembly != null) | |
return assembly; | |
} | |
assembly = GetAssemblyInGac (name, parameters); | |
if (assembly != null) | |
return assembly; | |
assembly = SearchDirectory (name, framework_dirs, parameters); | |
if (assembly != null) | |
return assembly; | |
#endif | |
if (ResolveFailure != null) { | |
assembly = ResolveFailure (this, name); | |
if (assembly != null) | |
return assembly; | |
} | |
throw new AssemblyResolutionException (name); | |
} | |
#if NET_CORE | |
AssemblyDefinition SearchTrustedPlatformAssemblies (AssemblyNameReference name, ReaderParameters parameters) | |
{ | |
if (name.IsWindowsRuntime) | |
return null; | |
if (TrustedPlatformAssemblies.Value.TryGetValue (name.Name, out string path)) | |
return GetAssembly (path, parameters); | |
return null; | |
} | |
static Dictionary<string, string> CreateTrustedPlatformAssemblyMap () | |
{ | |
var result = new Dictionary<string, string> (StringComparer.OrdinalIgnoreCase); | |
string paths; | |
try { | |
// AppContext is only available on platforms that implement .NET Standard 1.6 | |
var appContextType = Type.GetType ("System.AppContext, System.AppContext, Version=4.1.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a", throwOnError: false); | |
var getData = appContextType?.GetTypeInfo ().GetDeclaredMethod ("GetData"); | |
paths = (string) getData?.Invoke (null, new [] { "TRUSTED_PLATFORM_ASSEMBLIES" }); | |
} catch { | |
paths = null; | |
} | |
if (paths == null) | |
return result; | |
foreach (var path in paths.Split (Path.PathSeparator)) | |
if (string.Equals (Path.GetExtension (path), ".dll", StringComparison.OrdinalIgnoreCase)) | |
result [Path.GetFileNameWithoutExtension (path)] = path; | |
return result; | |
} | |
#endif | |
protected virtual AssemblyDefinition SearchDirectory (AssemblyNameReference name, IEnumerable<string> directories, ReaderParameters parameters) | |
{ | |
var extensions = name.IsWindowsRuntime ? new [] { ".winmd", ".dll" } : new [] { ".exe", ".dll" }; | |
foreach (var directory in directories) { | |
foreach (var extension in extensions) { | |
string file = Path.Combine (directory, name.Name + extension); | |
if (!File.Exists (file)) | |
continue; | |
try { | |
return GetAssembly (file, parameters); | |
} catch (System.BadImageFormatException) { | |
continue; | |
} | |
} | |
} | |
return null; | |
} | |
static bool IsZero (Version version) | |
{ | |
return version.Major == 0 && version.Minor == 0 && version.Build == 0 && version.Revision == 0; | |
} | |
#if !NET_CORE | |
AssemblyDefinition GetCorlib (AssemblyNameReference reference, ReaderParameters parameters) | |
{ | |
var version = reference.Version; | |
var corlib = typeof (object).Assembly.GetName (); | |
if (corlib.Version == version || IsZero (version)) | |
return GetAssembly (typeof (object).Module.FullyQualifiedName, parameters); | |
var path = Directory.GetParent ( | |
Directory.GetParent ( | |
typeof (object).Module.FullyQualifiedName).FullName | |
).FullName; | |
if (on_mono) { | |
if (version.Major == 1) | |
path = Path.Combine (path, "1.0"); | |
else if (version.Major == 2) { | |
if (version.MajorRevision == 5) | |
path = Path.Combine (path, "2.1"); | |
else | |
path = Path.Combine (path, "2.0"); | |
} else if (version.Major == 4) | |
path = Path.Combine (path, "4.0"); | |
else | |
throw new NotSupportedException ("Version not supported: " + version); | |
} else { | |
switch (version.Major) { | |
case 1: | |
if (version.MajorRevision == 3300) | |
path = Path.Combine (path, "v1.0.3705"); | |
else | |
path = Path.Combine (path, "v1.0.5000.0"); | |
break; | |
case 2: | |
path = Path.Combine (path, "v2.0.50727"); | |
break; | |
case 4: | |
path = Path.Combine (path, "v4.0.30319"); | |
break; | |
default: | |
throw new NotSupportedException ("Version not supported: " + version); | |
} | |
} | |
var file = Path.Combine (path, "mscorlib.dll"); | |
if (File.Exists (file)) | |
return GetAssembly (file, parameters); | |
if (on_mono && Directory.Exists (path + "-api")) { | |
file = Path.Combine (path + "-api", "mscorlib.dll"); | |
if (File.Exists (file)) | |
return GetAssembly (file, parameters); | |
} | |
return null; | |
} | |
static Collection<string> GetGacPaths () | |
{ | |
if (on_mono) | |
return GetDefaultMonoGacPaths (); | |
var paths = new Collection<string> (2); | |
var windir = Environment.GetEnvironmentVariable ("WINDIR"); | |
if (windir == null) | |
return paths; | |
paths.Add (Path.Combine (windir, "assembly")); | |
paths.Add (Path.Combine (windir, Path.Combine ("Microsoft.NET", "assembly"))); | |
return paths; | |
} | |
static Collection<string> GetDefaultMonoGacPaths () | |
{ | |
var paths = new Collection<string> (1); | |
var gac = GetCurrentMonoGac (); | |
if (gac != null) | |
paths.Add (gac); | |
var gac_paths_env = Environment.GetEnvironmentVariable ("MONO_GAC_PREFIX"); | |
if (string.IsNullOrEmpty (gac_paths_env)) | |
return paths; | |
var prefixes = gac_paths_env.Split (Path.PathSeparator); | |
foreach (var prefix in prefixes) { | |
if (string.IsNullOrEmpty (prefix)) | |
continue; | |
var gac_path = Path.Combine (Path.Combine (Path.Combine (prefix, "lib"), "mono"), "gac"); | |
if (Directory.Exists (gac_path) && !paths.Contains (gac)) | |
paths.Add (gac_path); | |
} | |
return paths; | |
} | |
static string GetCurrentMonoGac () | |
{ | |
return Path.Combine ( | |
Directory.GetParent ( | |
Path.GetDirectoryName (typeof (object).Module.FullyQualifiedName)).FullName, | |
"gac"); | |
} | |
AssemblyDefinition GetAssemblyInGac (AssemblyNameReference reference, ReaderParameters parameters) | |
{ | |
if (reference.PublicKeyToken == null || reference.PublicKeyToken.Length == 0) | |
return null; | |
if (gac_paths == null) | |
gac_paths = GetGacPaths (); | |
if (on_mono) | |
return GetAssemblyInMonoGac (reference, parameters); | |
return GetAssemblyInNetGac (reference, parameters); | |
} | |
AssemblyDefinition GetAssemblyInMonoGac (AssemblyNameReference reference, ReaderParameters parameters) | |
{ | |
for (int i = 0; i < gac_paths.Count; i++) { | |
var gac_path = gac_paths [i]; | |
var file = GetAssemblyFile (reference, string.Empty, gac_path); | |
if (File.Exists (file)) | |
return GetAssembly (file, parameters); | |
} | |
return null; | |
} | |
AssemblyDefinition GetAssemblyInNetGac (AssemblyNameReference reference, ReaderParameters parameters) | |
{ | |
var gacs = new [] { "GAC_MSIL", "GAC_32", "GAC_64", "GAC" }; | |
var prefixes = new [] { string.Empty, "v4.0_" }; | |
for (int i = 0; i < 2; i++) { | |
for (int j = 0; j < gacs.Length; j++) { | |
var gac = Path.Combine (gac_paths [i], gacs [j]); | |
var file = GetAssemblyFile (reference, prefixes [i], gac); | |
if (Directory.Exists (gac) && File.Exists (file)) | |
return GetAssembly (file, parameters); | |
} | |
} | |
return null; | |
} | |
#endif | |
static string GetAssemblyFile (AssemblyNameReference reference, string prefix, string gac) | |
{ | |
var gac_folder = new StringBuilder () | |
.Append (prefix) | |
.Append (reference.Version) | |
.Append ("__"); | |
for (int i = 0; i < reference.PublicKeyToken.Length; i++) | |
gac_folder.Append (reference.PublicKeyToken [i].ToString ("x2")); | |
return Path.Combine ( | |
Path.Combine ( | |
Path.Combine (gac, reference.Name), gac_folder.ToString ()), | |
reference.Name + ".dll"); | |
} | |
public void Dispose () | |
{ | |
Dispose (true); | |
GC.SuppressFinalize (this); | |
} | |
protected virtual void Dispose (bool disposing) | |
{ | |
} | |
} | |
} | |
} | |
#endregion | |
#region Mono.Cecil\*.cs | |
namespace Internal { | |
// | |
// Author: | |
// Jb Evain (jbevain@gmail.com) | |
// | |
// Copyright (c) 2008 - 2015 Jb Evain | |
// Copyright (c) 2008 - 2011 Novell, Inc. | |
// | |
// Licensed under the MIT/X11 license. | |
// | |
using System; | |
using System.Text; | |
using Mono.Collections.Generic; | |
namespace Mono.Cecil { | |
internal sealed class CallSite : IMethodSignature { | |
readonly MethodReference signature; | |
public bool HasThis { | |
get { return signature.HasThis; } | |
set { signature.HasThis = value; } | |
} | |
public bool ExplicitThis { | |
get { return signature.ExplicitThis; } | |
set { signature.ExplicitThis = value; } | |
} | |
public MethodCallingConvention CallingConvention { | |
get { return signature.CallingConvention; } | |
set { signature.CallingConvention = value; } | |
} | |
public bool HasParameters { | |
get { return signature.HasParameters; } | |
} | |
public Collection<ParameterDefinition> Parameters { | |
get { return signature.Parameters; } | |
} | |
public TypeReference ReturnType { | |
get { return signature.MethodReturnType.ReturnType; } | |
set { signature.MethodReturnType.ReturnType = value; } | |
} | |
public MethodReturnType MethodReturnType { | |
get { return signature.MethodReturnType; } | |
} | |
public string Name { | |
get { return string.Empty; } | |
set { throw new InvalidOperationException (); } | |
} | |
public string Namespace { | |
get { return string.Empty; } | |
set { throw new InvalidOperationException (); } | |
} | |
public ModuleDefinition Module { | |
get { return ReturnType.Module; } | |
} | |
public IMetadataScope Scope { | |
get { return signature.ReturnType.Scope; } | |
} | |
public MetadataToken MetadataToken { | |
get { return signature.token; } | |
set { signature.token = value; } | |
} | |
public string FullName { | |
get { | |
var signature = new StringBuilder (); | |
signature.Append (ReturnType.FullName); | |
this.MethodSignatureFullName (signature); | |
return signature.ToString (); | |
} | |
} | |
internal CallSite () | |
{ | |
this.signature = new MethodReference (); | |
this.signature.token = new MetadataToken (TokenType.Signature, 0); | |
} | |
public CallSite (TypeReference returnType) | |
: this () | |
{ | |
if (returnType == null) | |
throw new ArgumentNullException ("returnType"); | |
this.signature.ReturnType = returnType; | |
} | |
public override string ToString () | |
{ | |
return FullName; | |
} | |
} | |
} | |
} | |
#endregion | |
#region Mono.Cecil\*.cs | |
namespace Internal { | |
static class Consts | |
{ | |
public const string AssemblyName = "Mono.Cecil"; | |
public const string PublicKey = "00240000048000009400000006020000002400005253413100040000010001002b5c9f7f04346c324a3176f8d3ee823bbf2d60efdbc35f86fd9e65ea3e6cd11bcdcba3a353e55133c8ac5c4caaba581b2c6dfff2cc2d0edc43959ddb86b973300a479a82419ef489c3225f1fe429a708507bd515835160e10bc743d20ca33ab9570cfd68d479fcf0bc797a763bec5d1000f0159ef619e709d915975e87beebaf"; | |
} | |
} | |
#endregion | |
#region Mono.Cecil\*.cs | |
namespace Internal { | |
// | |
// Author: | |
// Jb Evain (jbevain@gmail.com) | |
// | |
// Copyright (c) 2008 - 2015 Jb Evain | |
// Copyright (c) 2008 - 2011 Novell, Inc. | |
// | |
// Licensed under the MIT/X11 license. | |
// | |
using System; | |
using System.Diagnostics; | |
using Mono.Collections.Generic; | |
namespace Mono.Cecil { | |
internal struct CustomAttributeArgument { | |
readonly TypeReference type; | |
readonly object value; | |
public TypeReference Type { | |
get { return type; } | |
} | |
public object Value { | |
get { return value; } | |
} | |
public CustomAttributeArgument (TypeReference type, object value) | |
{ | |
Mixin.CheckType (type); | |
this.type = type; | |
this.value = value; | |
} | |
} | |
internal struct CustomAttributeNamedArgument { | |
readonly string name; | |
readonly CustomAttributeArgument argument; | |
public string Name { | |
get { return name; } | |
} | |
public CustomAttributeArgument Argument { | |
get { return argument; } | |
} | |
public CustomAttributeNamedArgument (string name, CustomAttributeArgument argument) | |
{ | |
Mixin.CheckName (name); | |
this.name = name; | |
this.argument = argument; | |
} | |
} | |
internal interface ICustomAttribute { | |
TypeReference AttributeType { get; } | |
bool HasFields { get; } | |
bool HasProperties { get; } | |
bool HasConstructorArguments { get; } | |
Collection<CustomAttributeNamedArgument> Fields { get; } | |
Collection<CustomAttributeNamedArgument> Properties { get; } | |
Collection<CustomAttributeArgument> ConstructorArguments { get; } | |
} | |
[DebuggerDisplay ("{AttributeType}")] | |
internal sealed class CustomAttribute : ICustomAttribute { | |
internal CustomAttributeValueProjection projection; | |
readonly internal uint signature; | |
internal bool resolved; | |
MethodReference constructor; | |
byte [] blob; | |
internal Collection<CustomAttributeArgument> arguments; | |
internal Collection<CustomAttributeNamedArgument> fields; | |
internal Collection<CustomAttributeNamedArgument> properties; | |
public MethodReference Constructor { | |
get { return constructor; } | |
set { constructor = value; } | |
} | |
public TypeReference AttributeType { | |
get { return constructor.DeclaringType; } | |
} | |
public bool IsResolved { | |
get { return resolved; } | |
} | |
public bool HasConstructorArguments { | |
get { | |
Resolve (); | |
return !arguments.IsNullOrEmpty (); | |
} | |
} | |
public Collection<CustomAttributeArgument> ConstructorArguments { | |
get { | |
Resolve (); | |
return arguments ?? (arguments = new Collection<CustomAttributeArgument> ()); | |
} | |
} | |
public bool HasFields { | |
get { | |
Resolve (); | |
return !fields.IsNullOrEmpty (); | |
} | |
} | |
public Collection<CustomAttributeNamedArgument> Fields { | |
get { | |
Resolve (); | |
return fields ?? (fields = new Collection<CustomAttributeNamedArgument> ()); | |
} | |
} | |
public bool HasProperties { | |
get { | |
Resolve (); | |
return !properties.IsNullOrEmpty (); | |
} | |
} | |
public Collection<CustomAttributeNamedArgument> Properties { | |
get { | |
Resolve (); | |
return properties ?? (properties = new Collection<CustomAttributeNamedArgument> ()); | |
} | |
} | |
internal bool HasImage { | |
get { return constructor != null && constructor.HasImage; } | |
} | |
internal ModuleDefinition Module { | |
get { return constructor.Module; } | |
} | |
internal CustomAttribute (uint signature, MethodReference constructor) | |
{ | |
this.signature = signature; | |
this.constructor = constructor; | |
this.resolved = false; | |
} | |
public CustomAttribute (MethodReference constructor) | |
{ | |
this.constructor = constructor; | |
this.resolved = true; | |
} | |
public CustomAttribute (MethodReference constructor, byte [] blob) | |
{ | |
this.constructor = constructor; | |
this.resolved = false; | |
this.blob = blob; | |
} | |
public byte [] GetBlob () | |
{ | |
if (blob != null) | |
return blob; | |
if (!HasImage) | |
throw new NotSupportedException (); | |
return Module.Read (ref blob, this, (attribute, reader) => reader.ReadCustomAttributeBlob (attribute.signature)); | |
} | |
void Resolve () | |
{ | |
if (resolved || !HasImage) | |
return; | |
Module.Read (this, (attribute, reader) => { | |
try { | |
reader.ReadCustomAttributeSignature (attribute); | |
resolved = true; | |
} catch (ResolutionException) { | |
if (arguments != null) | |
arguments.Clear (); | |
if (fields != null) | |
fields.Clear (); | |
if (properties != null) | |
properties.Clear (); | |
resolved = false; | |
} | |
}); | |
} | |
} | |
} | |
} | |
#endregion | |
#region Mono.Cecil\*.cs | |
namespace Internal { | |
// | |
// Author: | |
// Jb Evain (jbevain@gmail.com) | |
// | |
// Copyright (c) 2008 - 2015 Jb Evain | |
// Copyright (c) 2008 - 2011 Novell, Inc. | |
// | |
// Licensed under the MIT/X11 license. | |
// | |
using System; | |
using System.Collections.Generic; | |
namespace Mono.Cecil { | |
internal class DefaultAssemblyResolver : BaseAssemblyResolver { | |
readonly IDictionary<string, AssemblyDefinition> cache; | |
public DefaultAssemblyResolver () | |
{ | |
cache = new Dictionary<string, AssemblyDefinition> (StringComparer.Ordinal); | |
} | |
public override AssemblyDefinition Resolve (AssemblyNameReference name) | |
{ | |
Mixin.CheckName (name); | |
AssemblyDefinition assembly; | |
if (cache.TryGetValue (name.FullName, out assembly)) | |
return assembly; | |
assembly = base.Resolve (name); | |
cache [name.FullName] = assembly; | |
return assembly; | |
} | |
protected void RegisterAssembly (AssemblyDefinition assembly) | |
{ | |
if (assembly == null) | |
throw new ArgumentNullException ("assembly"); | |
var name = assembly.Name.FullName; | |
if (cache.ContainsKey (name)) | |
return; | |
cache [name] = assembly; | |
} | |
protected override void Dispose (bool disposing) | |
{ | |
foreach (var assembly in cache.Values) | |
assembly.Dispose (); | |
cache.Clear (); | |
base.Dispose (disposing); | |
} | |
} | |
} | |
} | |
#endregion | |
#region Mono.Cecil\*.cs | |
namespace Internal { | |
// | |
// Author: | |
// Jb Evain (jbevain@gmail.com) | |
// | |
// Copyright (c) 2008 - 2015 Jb Evain | |
// Copyright (c) 2008 - 2011 Novell, Inc. | |
// | |
// Licensed under the MIT/X11 license. | |
// | |
using System; | |
using System.IO; | |
namespace Mono.Cecil { | |
internal sealed class EmbeddedResource : Resource { | |
readonly MetadataReader reader; | |
uint? offset; | |
byte [] data; | |
Stream stream; | |
public override ResourceType ResourceType { | |
get { return ResourceType.Embedded; } | |
} | |
public EmbeddedResource (string name, ManifestResourceAttributes attributes, byte [] data) : | |
base (name, attributes) | |
{ | |
this.data = data; | |
} | |
public EmbeddedResource (string name, ManifestResourceAttributes attributes, Stream stream) : | |
base (name, attributes) | |
{ | |
this.stream = stream; | |
} | |
internal EmbeddedResource (string name, ManifestResourceAttributes attributes, uint offset, MetadataReader reader) | |
: base (name, attributes) | |
{ | |
this.offset = offset; | |
this.reader = reader; | |
} | |
public Stream GetResourceStream () | |
{ | |
if (stream != null) | |
return stream; | |
if (data != null) | |
return new MemoryStream (data); | |
if (offset.HasValue) | |
return new MemoryStream (reader.GetManagedResource (offset.Value)); | |
throw new InvalidOperationException (); | |
} | |
public byte [] GetResourceData () | |
{ | |
if (stream != null) | |
return ReadStream (stream); | |
if (data != null) | |
return data; | |
if (offset.HasValue) | |
return reader.GetManagedResource (offset.Value); | |
throw new InvalidOperationException (); | |
} | |
static byte [] ReadStream (Stream stream) | |
{ | |
int read; | |
if (stream.CanSeek) { | |
var length = (int) stream.Length; | |
var data = new byte [length]; | |
int offset = 0; | |
while ((read = stream.Read (data, offset, length - offset)) > 0) | |
offset += read; | |
return data; | |
} | |
var buffer = new byte [1024 * 8]; | |
var memory = new MemoryStream (); | |
while ((read = stream.Read (buffer, 0, buffer.Length)) > 0) | |
memory.Write (buffer, 0, read); | |
return memory.ToArray (); | |
} | |
} | |
} | |
} | |
#endregion | |
#region Mono.Cecil\*.cs | |
namespace Internal { | |
// | |
// Author: | |
// Jb Evain (jbevain@gmail.com) | |
// | |
// Copyright (c) 2008 - 2015 Jb Evain | |
// Copyright (c) 2008 - 2011 Novell, Inc. | |
// | |
// Licensed under the MIT/X11 license. | |
// | |
using System; | |
namespace Mono.Cecil { | |
[Flags] | |
internal enum EventAttributes : ushort { | |
None = 0x0000, | |
SpecialName = 0x0200, // Event is special | |
RTSpecialName = 0x0400 // CLI provides 'special' behavior, depending upon the name of the event | |
} | |
} | |
} | |
#endregion | |
#region Mono.Cecil\*.cs | |
namespace Internal { | |
// | |
// Author: | |
// Jb Evain (jbevain@gmail.com) | |
// | |
// Copyright (c) 2008 - 2015 Jb Evain | |
// Copyright (c) 2008 - 2011 Novell, Inc. | |
// | |
// Licensed under the MIT/X11 license. | |
// | |
using Mono.Collections.Generic; | |
namespace Mono.Cecil { | |
internal sealed class EventDefinition : EventReference, IMemberDefinition { | |
ushort attributes; | |
Collection<CustomAttribute> custom_attributes; | |
internal MethodDefinition add_method; | |
internal MethodDefinition invoke_method; | |
internal MethodDefinition remove_method; | |
internal Collection<MethodDefinition> other_methods; | |
public EventAttributes Attributes { | |
get { return (EventAttributes) attributes; } | |
set { attributes = (ushort) value; } | |
} | |
public MethodDefinition AddMethod { | |
get { | |
if (add_method != null) | |
return add_method; | |
InitializeMethods (); | |
return add_method; | |
} | |
set { add_method = value; } | |
} | |
public MethodDefinition InvokeMethod { | |
get { | |
if (invoke_method != null) | |
return invoke_method; | |
InitializeMethods (); | |
return invoke_method; | |
} | |
set { invoke_method = value; } | |
} | |
public MethodDefinition RemoveMethod { | |
get { | |
if (remove_method != null) | |
return remove_method; | |
InitializeMethods (); | |
return remove_method; | |
} | |
set { remove_method = value; } | |
} | |
public bool HasOtherMethods { | |
get { | |
if (other_methods != null) | |
return other_methods.Count > 0; | |
InitializeMethods (); | |
return !other_methods.IsNullOrEmpty (); | |
} | |
} | |
public Collection<MethodDefinition> OtherMethods { | |
get { | |
if (other_methods != null) | |
return other_methods; | |
InitializeMethods (); | |
if (other_methods != null) | |
return other_methods; | |
return other_methods = new Collection<MethodDefinition> (); | |
} | |
} | |
public bool HasCustomAttributes { | |
get { | |
if (custom_attributes != null) | |
return custom_attributes.Count > 0; | |
return this.GetHasCustomAttributes (Module); | |
} | |
} | |
public Collection<CustomAttribute> CustomAttributes { | |
get { return custom_attributes ?? (this.GetCustomAttributes (ref custom_attributes, Module)); } | |
} | |
#region EventAttributes | |
public bool IsSpecialName { | |
get { return attributes.GetAttributes ((ushort) EventAttributes.SpecialName); } | |
set { attributes = attributes.SetAttributes ((ushort) EventAttributes.SpecialName, value); } | |
} | |
public bool IsRuntimeSpecialName { | |
get { return attributes.GetAttributes ((ushort) EventAttributes.RTSpecialName); } | |
set { attributes = attributes.SetAttributes ((ushort) EventAttributes.RTSpecialName, value); } | |
} | |
#endregion | |
public new TypeDefinition DeclaringType { | |
get { return (TypeDefinition) base.DeclaringType; } | |
set { base.DeclaringType = value; } | |
} | |
public override bool IsDefinition { | |
get { return true; } | |
} | |
public EventDefinition (string name, EventAttributes attributes, TypeReference eventType) | |
: base (name, eventType) | |
{ | |
this.attributes = (ushort) attributes; | |
this.token = new MetadataToken (TokenType.Event); | |
} | |
void InitializeMethods () | |
{ | |
var module = this.Module; | |
if (module == null) | |
return; | |
lock (module.SyncRoot) { | |
if (add_method != null | |
|| invoke_method != null | |
|| remove_method != null) | |
return; | |
if (!module.HasImage ()) | |
return; | |
module.Read (this, (@event, reader) => reader.ReadMethods (@event)); | |
} | |
} | |
public override EventDefinition Resolve () | |
{ | |
return this; | |
} | |
} | |
} | |
} | |
#endregion | |
#region Mono.Cecil\*.cs | |
namespace Internal { | |
// | |
// Author: | |
// Jb Evain (jbevain@gmail.com) | |
// | |
// Copyright (c) 2008 - 2015 Jb Evain | |
// Copyright (c) 2008 - 2011 Novell, Inc. | |
// | |
// Licensed under the MIT/X11 license. | |
// | |
using System; | |
namespace Mono.Cecil { | |
internal abstract class EventReference : MemberReference { | |
TypeReference event_type; | |
public TypeReference EventType { | |
get { return event_type; } | |
set { event_type = value; } | |
} | |
public override string FullName { | |
get { return event_type.FullName + " " + MemberFullName (); } | |
} | |
protected EventReference (string name, TypeReference eventType) | |
: base (name) | |
{ | |
Mixin.CheckType (eventType, Mixin.Argument.eventType); | |
event_type = eventType; | |
} | |
protected override IMemberDefinition ResolveDefinition () | |
{ | |
return this.Resolve (); | |
} | |
public new abstract EventDefinition Resolve (); | |
} | |
} | |
} | |
#endregion | |
#region Mono.Cecil\*.cs | |
namespace Internal { | |
// | |
// Author: | |
// Jb Evain (jbevain@gmail.com) | |
// | |
// Copyright (c) 2008 - 2015 Jb Evain | |
// Copyright (c) 2008 - 2011 Novell, Inc. | |
// | |
// Licensed under the MIT/X11 license. | |
// | |
using System; | |
namespace Mono.Cecil { | |
internal sealed class ExportedType : IMetadataTokenProvider { | |
string @namespace; | |
string name; | |
uint attributes; | |
IMetadataScope scope; | |
ModuleDefinition module; | |
int identifier; | |
ExportedType declaring_type; | |
internal MetadataToken token; | |
public string Namespace { | |
get { return @namespace; } | |
set { @namespace = value; } | |
} | |
public string Name { | |
get { return name; } | |
set { name = value; } | |
} | |
public TypeAttributes Attributes { | |
get { return (TypeAttributes) attributes; } | |
set { attributes = (uint) value; } | |
} | |
public IMetadataScope Scope { | |
get { | |
if (declaring_type != null) | |
return declaring_type.Scope; | |
return scope; | |
} | |
set { | |
if (declaring_type != null) { | |
declaring_type.Scope = value; | |
return; | |
} | |
scope = value; | |
} | |
} | |
public ExportedType DeclaringType { | |
get { return declaring_type; } | |
set { declaring_type = value; } | |
} | |
public MetadataToken MetadataToken { | |
get { return token; } | |
set { token = value; } | |
} | |
public int Identifier { | |
get { return identifier; } | |
set { identifier = value; } | |
} | |
#region TypeAttributes | |
public bool IsNotPublic { | |
get { return attributes.GetMaskedAttributes ((uint) TypeAttributes.VisibilityMask, (uint) TypeAttributes.NotPublic); } | |
set { attributes = attributes.SetMaskedAttributes ((uint) TypeAttributes.VisibilityMask, (uint) TypeAttributes.NotPublic, value); } | |
} | |
public bool IsPublic { | |
get { return attributes.GetMaskedAttributes ((uint) TypeAttributes.VisibilityMask, (uint) TypeAttributes.Public); } | |
set { attributes = attributes.SetMaskedAttributes ((uint) TypeAttributes.VisibilityMask, (uint) TypeAttributes.Public, value); } | |
} | |
public bool IsNestedPublic { | |
get { return attributes.GetMaskedAttributes ((uint) TypeAttributes.VisibilityMask, (uint) TypeAttributes.NestedPublic); } | |
set { attributes = attributes.SetMaskedAttributes ((uint) TypeAttributes.VisibilityMask, (uint) TypeAttributes.NestedPublic, value); } | |
} | |
public bool IsNestedPrivate { | |
get { return attributes.GetMaskedAttributes ((uint) TypeAttributes.VisibilityMask, (uint) TypeAttributes.NestedPrivate); } | |
set { attributes = attributes.SetMaskedAttributes ((uint) TypeAttributes.VisibilityMask, (uint) TypeAttributes.NestedPrivate, value); } | |
} | |
public bool IsNestedFamily { | |
get { return attributes.GetMaskedAttributes ((uint) TypeAttributes.VisibilityMask, (uint) TypeAttributes.NestedFamily); } | |
set { attributes = attributes.SetMaskedAttributes ((uint) TypeAttributes.VisibilityMask, (uint) TypeAttributes.NestedFamily, value); } | |
} | |
public bool IsNestedAssembly { | |
get { return attributes.GetMaskedAttributes ((uint) TypeAttributes.VisibilityMask, (uint) TypeAttributes.NestedAssembly); } | |
set { attributes = attributes.SetMaskedAttributes ((uint) TypeAttributes.VisibilityMask, (uint) TypeAttributes.NestedAssembly, value); } | |
} | |
public bool IsNestedFamilyAndAssembly { | |
get { return attributes.GetMaskedAttributes ((uint) TypeAttributes.VisibilityMask, (uint) TypeAttributes.NestedFamANDAssem); } | |
set { attributes = attributes.SetMaskedAttributes ((uint) TypeAttributes.VisibilityMask, (uint) TypeAttributes.NestedFamANDAssem, value); } | |
} | |
public bool IsNestedFamilyOrAssembly { | |
get { return attributes.GetMaskedAttributes ((uint) TypeAttributes.VisibilityMask, (uint) TypeAttributes.NestedFamORAssem); } | |
set { attributes = attributes.SetMaskedAttributes ((uint) TypeAttributes.VisibilityMask, (uint) TypeAttributes.NestedFamORAssem, value); } | |
} | |
public bool IsAutoLayout { | |
get { return attributes.GetMaskedAttributes ((uint) TypeAttributes.LayoutMask, (uint) TypeAttributes.AutoLayout); } | |
set { attributes = attributes.SetMaskedAttributes ((uint) TypeAttributes.LayoutMask, (uint) TypeAttributes.AutoLayout, value); } | |
} | |
public bool IsSequentialLayout { | |
get { return attributes.GetMaskedAttributes ((uint) TypeAttributes.LayoutMask, (uint) TypeAttributes.SequentialLayout); } | |
set { attributes = attributes.SetMaskedAttributes ((uint) TypeAttributes.LayoutMask, (uint) TypeAttributes.SequentialLayout, value); } | |
} | |
public bool IsExplicitLayout { | |
get { return attributes.GetMaskedAttributes ((uint) TypeAttributes.LayoutMask, (uint) TypeAttributes.ExplicitLayout); } | |
set { attributes = attributes.SetMaskedAttributes ((uint) TypeAttributes.LayoutMask, (uint) TypeAttributes.ExplicitLayout, value); } | |
} | |
public bool IsClass { | |
get { return attributes.GetMaskedAttributes ((uint) TypeAttributes.ClassSemanticMask, (uint) TypeAttributes.Class); } | |
set { attributes = attributes.SetMaskedAttributes ((uint) TypeAttributes.ClassSemanticMask, (uint) TypeAttributes.Class, value); } | |
} | |
public bool IsInterface { | |
get { return attributes.GetMaskedAttributes ((uint) TypeAttributes.ClassSemanticMask, (uint) TypeAttributes.Interface); } | |
set { attributes = attributes.SetMaskedAttributes ((uint) TypeAttributes.ClassSemanticMask, (uint) TypeAttributes.Interface, value); } | |
} | |
public bool IsAbstract { | |
get { return attributes.GetAttributes ((uint) TypeAttributes.Abstract); } | |
set { attributes = attributes.SetAttributes ((uint) TypeAttributes.Abstract, value); } | |
} | |
public bool IsSealed { | |
get { return attributes.GetAttributes ((uint) TypeAttributes.Sealed); } | |
set { attributes = attributes.SetAttributes ((uint) TypeAttributes.Sealed, value); } | |
} | |
public bool IsSpecialName { | |
get { return attributes.GetAttributes ((uint) TypeAttributes.SpecialName); } | |
set { attributes = attributes.SetAttributes ((uint) TypeAttributes.SpecialName, value); } | |
} | |
public bool IsImport { | |
get { return attributes.GetAttributes ((uint) TypeAttributes.Import); } | |
set { attributes = attributes.SetAttributes ((uint) TypeAttributes.Import, value); } | |
} | |
public bool IsSerializable { | |
get { return attributes.GetAttributes ((uint) TypeAttributes.Serializable); } | |
set { attributes = attributes.SetAttributes ((uint) TypeAttributes.Serializable, value); } | |
} | |
public bool IsAnsiClass { | |
get { return attributes.GetMaskedAttributes ((uint) TypeAttributes.StringFormatMask, (uint) TypeAttributes.AnsiClass); } | |
set { attributes = attributes.SetMaskedAttributes ((uint) TypeAttributes.StringFormatMask, (uint) TypeAttributes.AnsiClass, value); } | |
} | |
public bool IsUnicodeClass { | |
get { return attributes.GetMaskedAttributes ((uint) TypeAttributes.StringFormatMask, (uint) TypeAttributes.UnicodeClass); } | |
set { attributes = attributes.SetMaskedAttributes ((uint) TypeAttributes.StringFormatMask, (uint) TypeAttributes.UnicodeClass, value); } | |
} | |
public bool IsAutoClass { | |
get { return attributes.GetMaskedAttributes ((uint) TypeAttributes.StringFormatMask, (uint) TypeAttributes.AutoClass); } | |
set { attributes = attributes.SetMaskedAttributes ((uint) TypeAttributes.StringFormatMask, (uint) TypeAttributes.AutoClass, value); } | |
} | |
public bool IsBeforeFieldInit { | |
get { return attributes.GetAttributes ((uint) TypeAttributes.BeforeFieldInit); } | |
set { attributes = attributes.SetAttributes ((uint) TypeAttributes.BeforeFieldInit, value); } | |
} | |
public bool IsRuntimeSpecialName { | |
get { return attributes.GetAttributes ((uint) TypeAttributes.RTSpecialName); } | |
set { attributes = attributes.SetAttributes ((uint) TypeAttributes.RTSpecialName, value); } | |
} | |
public bool HasSecurity { | |
get { return attributes.GetAttributes ((uint) TypeAttributes.HasSecurity); } | |
set { attributes = attributes.SetAttributes ((uint) TypeAttributes.HasSecurity, value); } | |
} | |
#endregion | |
public bool IsForwarder { | |
get { return attributes.GetAttributes ((uint) TypeAttributes.Forwarder); } | |
set { attributes = attributes.SetAttributes ((uint) TypeAttributes.Forwarder, value); } | |
} | |
public string FullName { | |
get { | |
var fullname = string.IsNullOrEmpty (@namespace) | |
? name | |
: @namespace + '.' + name; | |
if (declaring_type != null) | |
return declaring_type.FullName + "/" + fullname; | |
return fullname; | |
} | |
} | |
public ExportedType (string @namespace, string name, ModuleDefinition module, IMetadataScope scope) | |
{ | |
this.@namespace = @namespace; | |
this.name = name; | |
this.scope = scope; | |
this.module = module; | |
} | |
public override string ToString () | |
{ | |
return FullName; | |
} | |
public TypeDefinition Resolve () | |
{ | |
return module.Resolve (CreateReference ()); | |
} | |
internal TypeReference CreateReference () | |
{ | |
return new TypeReference (@namespace, name, module, scope) { | |
DeclaringType = declaring_type != null ? declaring_type.CreateReference () : null, | |
}; | |
} | |
} | |
} | |
} | |
#endregion | |
#region Mono.Cecil\*.cs | |
namespace Internal { | |
// | |
// Author: | |
// Jb Evain (jbevain@gmail.com) | |
// | |
// Copyright (c) 2008 - 2015 Jb Evain | |
// Copyright (c) 2008 - 2011 Novell, Inc. | |
// | |
// Licensed under the MIT/X11 license. | |
// | |
using System; | |
namespace Mono.Cecil { | |
[Flags] | |
internal enum FieldAttributes : ushort { | |
FieldAccessMask = 0x0007, | |
CompilerControlled = 0x0000, // Member not referenceable | |
Private = 0x0001, // Accessible only by the parent type | |
FamANDAssem = 0x0002, // Accessible by sub-types only in this assembly | |
Assembly = 0x0003, // Accessible by anyone in the Assembly | |
Family = 0x0004, // Accessible only by type and sub-types | |
FamORAssem = 0x0005, // Accessible by sub-types anywhere, plus anyone in the assembly | |
Public = 0x0006, // Accessible by anyone who has visibility to this scope field contract attributes | |
Static = 0x0010, // Defined on type, else per instance | |
InitOnly = 0x0020, // Field may only be initialized, not written after init | |
Literal = 0x0040, // Value is compile time constant | |
NotSerialized = 0x0080, // Field does not have to be serialized when type is remoted | |
SpecialName = 0x0200, // Field is special | |
// Interop Attributes | |
PInvokeImpl = 0x2000, // Implementation is forwarded through PInvoke | |
// Additional flags | |
RTSpecialName = 0x0400, // CLI provides 'special' behavior, depending upon the name of the field | |
HasFieldMarshal = 0x1000, // Field has marshalling information | |
HasDefault = 0x8000, // Field has default | |
HasFieldRVA = 0x0100 // Field has RVA | |
} | |
} | |
} | |
#endregion | |
#region Mono.Cecil\*.cs | |
namespace Internal { | |
// | |
// Author: | |
// Jb Evain (jbevain@gmail.com) | |
// | |
// Copyright (c) 2008 - 2015 Jb Evain | |
// Copyright (c) 2008 - 2011 Novell, Inc. | |
// | |
// Licensed under the MIT/X11 license. | |
// | |
using System; | |
using Mono.Collections.Generic; | |
namespace Mono.Cecil { | |
internal sealed class FieldDefinition : FieldReference, IMemberDefinition, IConstantProvider, IMarshalInfoProvider { | |
ushort attributes; | |
Collection<CustomAttribute> custom_attributes; | |
int offset = Mixin.NotResolvedMarker; | |
internal int rva = Mixin.NotResolvedMarker; | |
byte [] initial_value; | |
object constant = Mixin.NotResolved; | |
MarshalInfo marshal_info; | |
void ResolveLayout () | |
{ | |
if (offset != Mixin.NotResolvedMarker) | |
return; | |
if (!HasImage) { | |
offset = Mixin.NoDataMarker; | |
return; | |
} | |
offset = Module.Read (this, (field, reader) => reader.ReadFieldLayout (field)); | |
} | |
public bool HasLayoutInfo { | |
get { | |
if (offset >= 0) | |
return true; | |
ResolveLayout (); | |
return offset >= 0; | |
} | |
} | |
public int Offset { | |
get { | |
if (offset >= 0) | |
return offset; | |
ResolveLayout (); | |
return offset >= 0 ? offset : -1; | |
} | |
set { offset = value; } | |
} | |
internal new FieldDefinitionProjection WindowsRuntimeProjection { | |
get { return (FieldDefinitionProjection) projection; } | |
set { projection = value; } | |
} | |
void ResolveRVA () | |
{ | |
if (rva != Mixin.NotResolvedMarker) | |
return; | |
if (!HasImage) | |
return; | |
rva = Module.Read (this, (field, reader) => reader.ReadFieldRVA (field)); | |
} | |
public int RVA { | |
get { | |
if (rva > 0) | |
return rva; | |
ResolveRVA (); | |
return rva > 0 ? rva : 0; | |
} | |
} | |
public byte [] InitialValue { | |
get { | |
if (initial_value != null) | |
return initial_value; | |
ResolveRVA (); | |
if (initial_value == null) | |
initial_value = Empty<byte>.Array; | |
return initial_value; | |
} | |
set { | |
initial_value = value; | |
rva = 0; | |
} | |
} | |
public FieldAttributes Attributes { | |
get { return (FieldAttributes) attributes; } | |
set { | |
if (IsWindowsRuntimeProjection && (ushort) value != attributes) | |
throw new InvalidOperationException (); | |
attributes = (ushort) value; | |
} | |
} | |
public bool HasConstant { | |
get { | |
this.ResolveConstant (ref constant, Module); | |
return constant != Mixin.NoValue; | |
} | |
set { if (!value) constant = Mixin.NoValue; } | |
} | |
public object Constant { | |
get { return HasConstant ? constant : null; } | |
set { constant = value; } | |
} | |
public bool HasCustomAttributes { | |
get { | |
if (custom_attributes != null) | |
return custom_attributes.Count > 0; | |
return this.GetHasCustomAttributes (Module); | |
} | |
} | |
public Collection<CustomAttribute> CustomAttributes { | |
get { return custom_attributes ?? (this.GetCustomAttributes (ref custom_attributes, Module)); } | |
} | |
public bool HasMarshalInfo { | |
get { | |
if (marshal_info != null) | |
return true; | |
return this.GetHasMarshalInfo (Module); | |
} | |
} | |
public MarshalInfo MarshalInfo { | |
get { return marshal_info ?? (this.GetMarshalInfo (ref marshal_info, Module)); } | |
set { marshal_info = value; } | |
} | |
#region FieldAttributes | |
public bool IsCompilerControlled { | |
get { return attributes.GetMaskedAttributes ((ushort) FieldAttributes.FieldAccessMask, (ushort) FieldAttributes.CompilerControlled); } | |
set { attributes = attributes.SetMaskedAttributes ((ushort) FieldAttributes.FieldAccessMask, (ushort) FieldAttributes.CompilerControlled, value); } | |
} | |
public bool IsPrivate { | |
get { return attributes.GetMaskedAttributes ((ushort) FieldAttributes.FieldAccessMask, (ushort) FieldAttributes.Private); } | |
set { attributes = attributes.SetMaskedAttributes ((ushort) FieldAttributes.FieldAccessMask, (ushort) FieldAttributes.Private, value); } | |
} | |
public bool IsFamilyAndAssembly { | |
get { return attributes.GetMaskedAttributes ((ushort) FieldAttributes.FieldAccessMask, (ushort) FieldAttributes.FamANDAssem); } | |
set { attributes = attributes.SetMaskedAttributes ((ushort) FieldAttributes.FieldAccessMask, (ushort) FieldAttributes.FamANDAssem, value); } | |
} | |
public bool IsAssembly { | |
get { return attributes.GetMaskedAttributes ((ushort) FieldAttributes.FieldAccessMask, (ushort) FieldAttributes.Assembly); } | |
set { attributes = attributes.SetMaskedAttributes ((ushort) FieldAttributes.FieldAccessMask, (ushort) FieldAttributes.Assembly, value); } | |
} | |
public bool IsFamily { | |
get { return attributes.GetMaskedAttributes ((ushort) FieldAttributes.FieldAccessMask, (ushort) FieldAttributes.Family); } | |
set { attributes = attributes.SetMaskedAttributes ((ushort) FieldAttributes.FieldAccessMask, (ushort) FieldAttributes.Family, value); } | |
} | |
public bool IsFamilyOrAssembly { | |
get { return attributes.GetMaskedAttributes ((ushort) FieldAttributes.FieldAccessMask, (ushort) FieldAttributes.FamORAssem); } | |
set { attributes = attributes.SetMaskedAttributes ((ushort) FieldAttributes.FieldAccessMask, (ushort) FieldAttributes.FamORAssem, value); } | |
} | |
public bool IsPublic { | |
get { return attributes.GetMaskedAttributes ((ushort) FieldAttributes.FieldAccessMask, (ushort) FieldAttributes.Public); } | |
set { attributes = attributes.SetMaskedAttributes ((ushort) FieldAttributes.FieldAccessMask, (ushort) FieldAttributes.Public, value); } | |
} | |
public bool IsStatic { | |
get { return attributes.GetAttributes ((ushort) FieldAttributes.Static); } | |
set { attributes = attributes.SetAttributes ((ushort) FieldAttributes.Static, value); } | |
} | |
public bool IsInitOnly { | |
get { return attributes.GetAttributes ((ushort) FieldAttributes.InitOnly); } | |
set { attributes = attributes.SetAttributes ((ushort) FieldAttributes.InitOnly, value); } | |
} | |
public bool IsLiteral { | |
get { return attributes.GetAttributes ((ushort) FieldAttributes.Literal); } | |
set { attributes = attributes.SetAttributes ((ushort) FieldAttributes.Literal, value); } | |
} | |
public bool IsNotSerialized { | |
get { return attributes.GetAttributes ((ushort) FieldAttributes.NotSerialized); } | |
set { attributes = attributes.SetAttributes ((ushort) FieldAttributes.NotSerialized, value); } | |
} | |
public bool IsSpecialName { | |
get { return attributes.GetAttributes ((ushort) FieldAttributes.SpecialName); } | |
set { attributes = attributes.SetAttributes ((ushort) FieldAttributes.SpecialName, value); } | |
} | |
public bool IsPInvokeImpl { | |
get { return attributes.GetAttributes ((ushort) FieldAttributes.PInvokeImpl); } | |
set { attributes = attributes.SetAttributes ((ushort) FieldAttributes.PInvokeImpl, value); } | |
} | |
public bool IsRuntimeSpecialName { | |
get { return attributes.GetAttributes ((ushort) FieldAttributes.RTSpecialName); } | |
set { attributes = attributes.SetAttributes ((ushort) FieldAttributes.RTSpecialName, value); } | |
} | |
public bool HasDefault { | |
get { return attributes.GetAttributes ((ushort) FieldAttributes.HasDefault); } | |
set { attributes = attributes.SetAttributes ((ushort) FieldAttributes.HasDefault, value); } | |
} | |
#endregion | |
public override bool IsDefinition { | |
get { return true; } | |
} | |
public new TypeDefinition DeclaringType { | |
get { return (TypeDefinition) base.DeclaringType; } | |
set { base.DeclaringType = value; } | |
} | |
public FieldDefinition (string name, FieldAttributes attributes, TypeReference fieldType) | |
: base (name, fieldType) | |
{ | |
this.attributes = (ushort) attributes; | |
} | |
public override FieldDefinition Resolve () | |
{ | |
return this; | |
} | |
} | |
static partial class Mixin { | |
public const int NotResolvedMarker = -2; | |
public const int NoDataMarker = -1; | |
} | |
} | |
} | |
#endregion | |
#region Mono.Cecil\*.cs | |
namespace Internal { | |
// | |
// Author: | |
// Jb Evain (jbevain@gmail.com) | |
// | |
// Copyright (c) 2008 - 2015 Jb Evain | |
// Copyright (c) 2008 - 2011 Novell, Inc. | |
// | |
// Licensed under the MIT/X11 license. | |
// | |
using System; | |
namespace Mono.Cecil { | |
internal class FieldReference : MemberReference { | |
TypeReference field_type; | |
public TypeReference FieldType { | |
get { return field_type; } | |
set { field_type = value; } | |
} | |
public override string FullName { | |
get { return field_type.FullName + " " + MemberFullName (); } | |
} | |
public override bool ContainsGenericParameter { | |
get { return field_type.ContainsGenericParameter || base.ContainsGenericParameter; } | |
} | |
internal FieldReference () | |
{ | |
this.token = new MetadataToken (TokenType.MemberRef); | |
} | |
public FieldReference (string name, TypeReference fieldType) | |
: base (name) | |
{ | |
Mixin.CheckType (fieldType, Mixin.Argument.fieldType); | |
this.field_type = fieldType; | |
this.token = new MetadataToken (TokenType.MemberRef); | |
} | |
public FieldReference (string name, TypeReference fieldType, TypeReference declaringType) | |
: this (name, fieldType) | |
{ | |
Mixin.CheckType (declaringType, Mixin.Argument.declaringType); | |
this.DeclaringType = declaringType; | |
} | |
protected override IMemberDefinition ResolveDefinition () | |
{ | |
return this.Resolve (); | |
} | |
public new virtual FieldDefinition Resolve () | |
{ | |
var module = this.Module; | |
if (module == null) | |
throw new NotSupportedException (); | |
return module.Resolve (this); | |
} | |
} | |
} | |
} | |
#endregion | |
#region Mono.Cecil\*.cs | |
namespace Internal { | |
// | |
// Author: | |
// Jb Evain (jbevain@gmail.com) | |
// | |
// Copyright (c) 2008 - 2015 Jb Evain | |
// Copyright (c) 2008 - 2011 Novell, Inc. | |
// | |
// Licensed under the MIT/X11 license. | |
// | |
namespace Mono.Cecil { | |
enum FileAttributes : uint { | |
ContainsMetaData = 0x0000, // This is not a resource file | |
ContainsNoMetaData = 0x0001, // This is a resource file or other non-metadata-containing file | |
} | |
} | |
} | |
#endregion | |
#region Mono.Cecil\*.cs | |
namespace Internal { | |
// | |
// Author: | |
// Jb Evain (jbevain@gmail.com) | |
// | |
// Copyright (c) 2008 - 2015 Jb Evain | |
// Copyright (c) 2008 - 2011 Novell, Inc. | |
// | |
// Licensed under the MIT/X11 license. | |
// | |
using System; | |
using System.Text; | |
using Mono.Collections.Generic; | |
using MD = Mono.Cecil.Metadata; | |
namespace Mono.Cecil { | |
internal sealed class FunctionPointerType : TypeSpecification, IMethodSignature { | |
readonly MethodReference function; | |
public bool HasThis { | |
get { return function.HasThis; } | |
set { function.HasThis = value; } | |
} | |
public bool ExplicitThis { | |
get { return function.ExplicitThis; } | |
set { function.ExplicitThis = value; } | |
} | |
public MethodCallingConvention CallingConvention { | |
get { return function.CallingConvention; } | |
set { function.CallingConvention = value; } | |
} | |
public bool HasParameters { | |
get { return function.HasParameters; } | |
} | |
public Collection<ParameterDefinition> Parameters { | |
get { return function.Parameters; } | |
} | |
public TypeReference ReturnType { | |
get { return function.MethodReturnType.ReturnType; } | |
set { function.MethodReturnType.ReturnType = value; } | |
} | |
public MethodReturnType MethodReturnType { | |
get { return function.MethodReturnType; } | |
} | |
public override string Name { | |
get { return function.Name; } | |
set { throw new InvalidOperationException (); } | |
} | |
public override string Namespace { | |
get { return string.Empty; } | |
set { throw new InvalidOperationException (); } | |
} | |
public override ModuleDefinition Module { | |
get { return ReturnType.Module; } | |
} | |
public override IMetadataScope Scope { | |
get { return function.ReturnType.Scope; } | |
set { throw new InvalidOperationException (); } | |
} | |
public override bool IsFunctionPointer { | |
get { return true; } | |
} | |
public override bool ContainsGenericParameter { | |
get { return function.ContainsGenericParameter; } | |
} | |
public override string FullName { | |
get { | |
var signature = new StringBuilder (); | |
signature.Append (function.Name); | |
signature.Append (" "); | |
signature.Append (function.ReturnType.FullName); | |
signature.Append (" *"); | |
this.MethodSignatureFullName (signature); | |
return signature.ToString (); | |
} | |
} | |
public FunctionPointerType () | |
: base (null) | |
{ | |
this.function = new MethodReference (); | |
this.function.Name = "method"; | |
this.etype = MD.ElementType.FnPtr; | |
} | |
public override TypeDefinition Resolve () | |
{ | |
return null; | |
} | |
public override TypeReference GetElementType () | |
{ | |
return this; | |
} | |
} | |
} | |
} | |
#endregion | |
#region Mono.Cecil\*.cs | |
namespace Internal { | |
// | |
// Author: | |
// Jb Evain (jbevain@gmail.com) | |
// | |
// Copyright (c) 2008 - 2015 Jb Evain | |
// Copyright (c) 2008 - 2011 Novell, Inc. | |
// | |
// Licensed under the MIT/X11 license. | |
// | |
using System; | |
using System.Text; | |
using Mono.Collections.Generic; | |
namespace Mono.Cecil { | |
internal sealed class GenericInstanceMethod : MethodSpecification, IGenericInstance, IGenericContext { | |
Collection<TypeReference> arguments; | |
public bool HasGenericArguments { | |
get { return !arguments.IsNullOrEmpty (); } | |
} | |
public Collection<TypeReference> GenericArguments { | |
get { return arguments ?? (arguments = new Collection<TypeReference> ()); } | |
} | |
public override bool IsGenericInstance { | |
get { return true; } | |
} | |
IGenericParameterProvider IGenericContext.Method { | |
get { return ElementMethod; } | |
} | |
IGenericParameterProvider IGenericContext.Type { | |
get { return ElementMethod.DeclaringType; } | |
} | |
public override bool ContainsGenericParameter { | |
get { return this.ContainsGenericParameter () || base.ContainsGenericParameter; } | |
} | |
public override string FullName { | |
get { | |
var signature = new StringBuilder (); | |
var method = this.ElementMethod; | |
signature.Append (method.ReturnType.FullName) | |
.Append (" ") | |
.Append (method.DeclaringType.FullName) | |
.Append ("::") | |
.Append (method.Name); | |
this.GenericInstanceFullName (signature); | |
this.MethodSignatureFullName (signature); | |
return signature.ToString (); | |
} | |
} | |
public GenericInstanceMethod (MethodReference method) | |
: base (method) | |
{ | |
} | |
} | |
} | |
} | |
#endregion | |
#region Mono.Cecil\*.cs | |
namespace Internal { | |
// | |
// Author: | |
// Jb Evain (jbevain@gmail.com) | |
// | |
// Copyright (c) 2008 - 2015 Jb Evain | |
// Copyright (c) 2008 - 2011 Novell, Inc. | |
// | |
// Licensed under the MIT/X11 license. | |
// | |
using System; | |
using System.Text; | |
using Mono.Collections.Generic; | |
using MD = Mono.Cecil.Metadata; | |
namespace Mono.Cecil { | |
internal sealed class GenericInstanceType : TypeSpecification, IGenericInstance, IGenericContext { | |
Collection<TypeReference> arguments; | |
public bool HasGenericArguments { | |
get { return !arguments.IsNullOrEmpty (); } | |
} | |
public Collection<TypeReference> GenericArguments { | |
get { return arguments ?? (arguments = new Collection<TypeReference> ()); } | |
} | |
public override TypeReference DeclaringType { | |
get { return ElementType.DeclaringType; } | |
set { throw new NotSupportedException (); } | |
} | |
public override string FullName { | |
get { | |
var name = new StringBuilder (); | |
name.Append (base.FullName); | |
this.GenericInstanceFullName (name); | |
return name.ToString (); | |
} | |
} | |
public override bool IsGenericInstance { | |
get { return true; } | |
} | |
public override bool ContainsGenericParameter { | |
get { return this.ContainsGenericParameter () || base.ContainsGenericParameter; } | |
} | |
IGenericParameterProvider IGenericContext.Type { | |
get { return ElementType; } | |
} | |
public GenericInstanceType (TypeReference type) | |
: base (type) | |
{ | |
base.IsValueType = type.IsValueType; | |
this.etype = MD.ElementType.GenericInst; | |
} | |
} | |
} | |
} | |
#endregion | |
#region Mono.Cecil\*.cs | |
namespace Internal { | |
// | |
// Author: | |
// Jb Evain (jbevain@gmail.com) | |
// | |
// Copyright (c) 2008 - 2015 Jb Evain | |
// Copyright (c) 2008 - 2011 Novell, Inc. | |
// | |
// Licensed under the MIT/X11 license. | |
// | |
using System; | |
using Mono.Collections.Generic; | |
using Mono.Cecil.Metadata; | |
namespace Mono.Cecil { | |
internal sealed class GenericParameter : TypeReference, ICustomAttributeProvider { | |
internal int position; | |
internal GenericParameterType type; | |
internal IGenericParameterProvider owner; | |
ushort attributes; | |
Collection<TypeReference> constraints; | |
Collection<CustomAttribute> custom_attributes; | |
public GenericParameterAttributes Attributes { | |
get { return (GenericParameterAttributes) attributes; } | |
set { attributes = (ushort) value; } | |
} | |
public int Position { | |
get { return position; } | |
} | |
public GenericParameterType Type { | |
get { return type; } | |
} | |
public IGenericParameterProvider Owner { | |
get { return owner; } | |
} | |
public bool HasConstraints { | |
get { | |
if (constraints != null) | |
return constraints.Count > 0; | |
return HasImage && Module.Read (this, (generic_parameter, reader) => reader.HasGenericConstraints (generic_parameter)); | |
} | |
} | |
public Collection<TypeReference> Constraints { | |
get { | |
if (constraints != null) | |
return constraints; | |
if (HasImage) | |
return Module.Read (ref constraints, this, (generic_parameter, reader) => reader.ReadGenericConstraints (generic_parameter)); | |
return constraints = new Collection<TypeReference> (); | |
} | |
} | |
public bool HasCustomAttributes { | |
get { | |
if (custom_attributes != null) | |
return custom_attributes.Count > 0; | |
return this.GetHasCustomAttributes (Module); | |
} | |
} | |
public Collection<CustomAttribute> CustomAttributes { | |
get { return custom_attributes ?? (this.GetCustomAttributes (ref custom_attributes, Module)); } | |
} | |
public override IMetadataScope Scope { | |
get { | |
if (owner == null) | |
return null; | |
return owner.GenericParameterType == GenericParameterType.Method | |
? ((MethodReference) owner).DeclaringType.Scope | |
: ((TypeReference) owner).Scope; | |
} | |
set { throw new InvalidOperationException (); } | |
} | |
public override TypeReference DeclaringType { | |
get { return owner as TypeReference; } | |
set { throw new InvalidOperationException (); } | |
} | |
public MethodReference DeclaringMethod { | |
get { return owner as MethodReference; } | |
} | |
public override ModuleDefinition Module { | |
get { return module ?? owner.Module; } | |
} | |
public override string Name { | |
get { | |
if (!string.IsNullOrEmpty (base.Name)) | |
return base.Name; | |
return base.Name = (type == GenericParameterType.Method ? "!!" : "!") + position; | |
} | |
} | |
public override string Namespace { | |
get { return string.Empty; } | |
set { throw new InvalidOperationException (); } | |
} | |
public override string FullName { | |
get { return Name; } | |
} | |
public override bool IsGenericParameter { | |
get { return true; } | |
} | |
public override bool ContainsGenericParameter { | |
get { return true; } | |
} | |
public override MetadataType MetadataType { | |
get { return (MetadataType) etype; } | |
} | |
#region GenericParameterAttributes | |
public bool IsNonVariant { | |
get { return attributes.GetMaskedAttributes ((ushort) GenericParameterAttributes.VarianceMask, (ushort) GenericParameterAttributes.NonVariant); } | |
set { attributes = attributes.SetMaskedAttributes ((ushort) GenericParameterAttributes.VarianceMask, (ushort) GenericParameterAttributes.NonVariant, value); } | |
} | |
public bool IsCovariant { | |
get { return attributes.GetMaskedAttributes ((ushort) GenericParameterAttributes.VarianceMask, (ushort) GenericParameterAttributes.Covariant); } | |
set { attributes = attributes.SetMaskedAttributes ((ushort) GenericParameterAttributes.VarianceMask, (ushort) GenericParameterAttributes.Covariant, value); } | |
} | |
public bool IsContravariant { | |
get { return attributes.GetMaskedAttributes ((ushort) GenericParameterAttributes.VarianceMask, (ushort) GenericParameterAttributes.Contravariant); } | |
set { attributes = attributes.SetMaskedAttributes ((ushort) GenericParameterAttributes.VarianceMask, (ushort) GenericParameterAttributes.Contravariant, value); } | |
} | |
public bool HasReferenceTypeConstraint { | |
get { return attributes.GetAttributes ((ushort) GenericParameterAttributes.ReferenceTypeConstraint); } | |
set { attributes = attributes.SetAttributes ((ushort) GenericParameterAttributes.ReferenceTypeConstraint, value); } | |
} | |
public bool HasNotNullableValueTypeConstraint { | |
get { return attributes.GetAttributes ((ushort) GenericParameterAttributes.NotNullableValueTypeConstraint); } | |
set { attributes = attributes.SetAttributes ((ushort) GenericParameterAttributes.NotNullableValueTypeConstraint, value); } | |
} | |
public bool HasDefaultConstructorConstraint { | |
get { return attributes.GetAttributes ((ushort) GenericParameterAttributes.DefaultConstructorConstraint); } | |
set { attributes = attributes.SetAttributes ((ushort) GenericParameterAttributes.DefaultConstructorConstraint, value); } | |
} | |
#endregion | |
public GenericParameter (IGenericParameterProvider owner) | |
: this (string.Empty, owner) | |
{ | |
} | |
public GenericParameter (string name, IGenericParameterProvider owner) | |
: base (string.Empty, name) | |
{ | |
if (owner == null) | |
throw new ArgumentNullException (); | |
this.position = -1; | |
this.owner = owner; | |
this.type = owner.GenericParameterType; | |
this.etype = ConvertGenericParameterType (this.type); | |
this.token = new MetadataToken (TokenType.GenericParam); | |
} | |
internal GenericParameter (int position, GenericParameterType type, ModuleDefinition module) | |
: base (string.Empty, string.Empty) | |
{ | |
Mixin.CheckModule (module); | |
this.position = position; | |
this.type = type; | |
this.etype = ConvertGenericParameterType (type); | |
this.module = module; | |
this.token = new MetadataToken (TokenType.GenericParam); | |
} | |
static ElementType ConvertGenericParameterType (GenericParameterType type) | |
{ | |
switch (type) { | |
case GenericParameterType.Type: | |
return ElementType.Var; | |
case GenericParameterType.Method: | |
return ElementType.MVar; | |
} | |
throw new ArgumentOutOfRangeException (); | |
} | |
public override TypeDefinition Resolve () | |
{ | |
return null; | |
} | |
} | |
sealed class GenericParameterCollection : Collection<GenericParameter> { | |
readonly IGenericParameterProvider owner; | |
internal GenericParameterCollection (IGenericParameterProvider owner) | |
{ | |
this.owner = owner; | |
} | |
internal GenericParameterCollection (IGenericParameterProvider owner, int capacity) | |
: base (capacity) | |
{ | |
this.owner = owner; | |
} | |
protected override void OnAdd (GenericParameter item, int index) | |
{ | |
UpdateGenericParameter (item, index); | |
} | |
protected override void OnInsert (GenericParameter item, int index) | |
{ | |
UpdateGenericParameter (item, index); | |
for (int i = index; i < size; i++) | |
items[i].position = i + 1; | |
} | |
protected override void OnSet (GenericParameter item, int index) | |
{ | |
UpdateGenericParameter (item, index); | |
} | |
void UpdateGenericParameter (GenericParameter item, int index) | |
{ | |
item.owner = owner; | |
item.position = index; | |
item.type = owner.GenericParameterType; | |
} | |
protected override void OnRemove (GenericParameter item, int index) | |
{ | |
item.owner = null; | |
item.position = -1; | |
item.type = GenericParameterType.Type; | |
for (int i = index + 1; i < size; i++) | |
items[i].position = i - 1; | |
} | |
} | |
} | |
} | |
#endregion | |
#region Mono.Cecil\*.cs | |
namespace Internal { | |
// | |
// Author: | |
// Jb Evain (jbevain@gmail.com) | |
// | |
// Copyright (c) 2008 - 2015 Jb Evain | |
// Copyright (c) 2008 - 2011 Novell, Inc. | |
// | |
// Licensed under the MIT/X11 license. | |
// | |
using System; | |
namespace Mono.Cecil { | |
[Flags] | |
internal enum GenericParameterAttributes : ushort { | |
VarianceMask = 0x0003, | |
NonVariant = 0x0000, | |
Covariant = 0x0001, | |
Contravariant = 0x0002, | |
SpecialConstraintMask = 0x001c, | |
ReferenceTypeConstraint = 0x0004, | |
NotNullableValueTypeConstraint = 0x0008, | |
DefaultConstructorConstraint = 0x0010 | |
} | |
} | |
} | |
#endregion | |
#region Mono.Cecil\*.cs | |
namespace Internal { | |
// | |
// Author: | |
// Jb Evain (jbevain@gmail.com) | |
// | |
// Copyright (c) 2008 - 2015 Jb Evain | |
// Copyright (c) 2008 - 2011 Novell, Inc. | |
// | |
// Licensed under the MIT/X11 license. | |
// | |
namespace Mono.Cecil { | |
internal interface IConstantProvider : IMetadataTokenProvider { | |
bool HasConstant { get; set; } | |
object Constant { get; set; } | |
} | |
static partial class Mixin { | |
internal static object NoValue = new object (); | |
internal static object NotResolved = new object (); | |
public static void ResolveConstant ( | |
this IConstantProvider self, | |
ref object constant, | |
ModuleDefinition module) | |
{ | |
if (module == null) { | |
constant = Mixin.NoValue; | |
return; | |
} | |
lock (module.SyncRoot) { | |
if (constant != Mixin.NotResolved) | |
return; | |
if (module.HasImage ()) | |
constant = module.Read (self, (provider, reader) => reader.ReadConstant (provider)); | |
else | |
constant = Mixin.NoValue; | |
} | |
} | |
} | |
} | |
} | |
#endregion | |
#region Mono.Cecil\*.cs | |
namespace Internal { | |
// | |
// Author: | |
// Jb Evain (jbevain@gmail.com) | |
// | |
// Copyright (c) 2008 - 2015 Jb Evain | |
// Copyright (c) 2008 - 2011 Novell, Inc. | |
// | |
// Licensed under the MIT/X11 license. | |
// | |
using System; | |
using Mono.Collections.Generic; | |
namespace Mono.Cecil { | |
internal interface ICustomAttributeProvider : IMetadataTokenProvider { | |
Collection<CustomAttribute> CustomAttributes { get; } | |
bool HasCustomAttributes { get; } | |
} | |
static partial class Mixin { | |
public static bool GetHasCustomAttributes ( | |
this ICustomAttributeProvider self, | |
ModuleDefinition module) | |
{ | |
return module.HasImage () && module.Read (self, (provider, reader) => reader.HasCustomAttributes (provider)); | |
} | |
public static Collection<CustomAttribute> GetCustomAttributes ( | |
this ICustomAttributeProvider self, | |
ref Collection<CustomAttribute> variable, | |
ModuleDefinition module) | |
{ | |
return module.HasImage () | |
? module.Read (ref variable, self, (provider, reader) => reader.ReadCustomAttributes (provider)) | |
: variable = new Collection<CustomAttribute>(); | |
} | |
} | |
} | |
} | |
#endregion | |
#region Mono.Cecil\*.cs | |
namespace Internal { | |
// | |
// Author: | |
// Jb Evain (jbevain@gmail.com) | |
// | |
// Copyright (c) 2008 - 2015 Jb Evain | |
// Copyright (c) 2008 - 2011 Novell, Inc. | |
// | |
// Licensed under the MIT/X11 license. | |
// | |
using System.Text; | |
using Mono.Collections.Generic; | |
namespace Mono.Cecil { | |
internal interface IGenericInstance : IMetadataTokenProvider { | |
bool HasGenericArguments { get; } | |
Collection<TypeReference> GenericArguments { get; } | |
} | |
static partial class Mixin { | |
public static bool ContainsGenericParameter (this IGenericInstance self) | |
{ | |
var arguments = self.GenericArguments; | |
for (int i = 0; i < arguments.Count; i++) | |
if (arguments [i].ContainsGenericParameter) | |
return true; | |
return false; | |
} | |
public static void GenericInstanceFullName (this IGenericInstance self, StringBuilder builder) | |
{ | |
builder.Append ("<"); | |
var arguments = self.GenericArguments; | |
for (int i = 0; i < arguments.Count; i++) { | |
if (i > 0) | |
builder.Append (","); | |
builder.Append (arguments [i].FullName); | |
} | |
builder.Append (">"); | |
} | |
} | |
} | |
} | |
#endregion | |
#region Mono.Cecil\*.cs | |
namespace Internal { | |
// | |
// Author: | |
// Jb Evain (jbevain@gmail.com) | |
// | |
// Copyright (c) 2008 - 2015 Jb Evain | |
// Copyright (c) 2008 - 2011 Novell, Inc. | |
// | |
// Licensed under the MIT/X11 license. | |
// | |
using Mono.Collections.Generic; | |
namespace Mono.Cecil { | |
internal interface IGenericParameterProvider : IMetadataTokenProvider { | |
bool HasGenericParameters { get; } | |
bool IsDefinition { get; } | |
ModuleDefinition Module { get; } | |
Collection<GenericParameter> GenericParameters { get; } | |
GenericParameterType GenericParameterType { get; } | |
} | |
internal enum GenericParameterType { | |
Type, | |
Method | |
} | |
interface IGenericContext { | |
bool IsDefinition { get; } | |
IGenericParameterProvider Type { get; } | |
IGenericParameterProvider Method { get; } | |
} | |
static partial class Mixin { | |
public static bool GetHasGenericParameters ( | |
this IGenericParameterProvider self, | |
ModuleDefinition module) | |
{ | |
return module.HasImage () && module.Read (self, (provider, reader) => reader.HasGenericParameters (provider)); | |
} | |
public static Collection<GenericParameter> GetGenericParameters ( | |
this IGenericParameterProvider self, | |
ref Collection<GenericParameter> collection, | |
ModuleDefinition module) | |
{ | |
return module.HasImage () | |
? module.Read (ref collection, self, (provider, reader) => reader.ReadGenericParameters (provider)) | |
: collection = new GenericParameterCollection (self); | |
} | |
} | |
} | |
} | |
#endregion | |
#region Mono.Cecil\*.cs | |
namespace Internal { | |
// | |
// Author: | |
// Jb Evain (jbevain@gmail.com) | |
// | |
// Copyright (c) 2008 - 2015 Jb Evain | |
// Copyright (c) 2008 - 2011 Novell, Inc. | |
// | |
// Licensed under the MIT/X11 license. | |
// | |
namespace Mono.Cecil { | |
internal interface IMarshalInfoProvider : IMetadataTokenProvider { | |
bool HasMarshalInfo { get; } | |
MarshalInfo MarshalInfo { get; set; } | |
} | |
static partial class Mixin { | |
public static bool GetHasMarshalInfo ( | |
this IMarshalInfoProvider self, | |
ModuleDefinition module) | |
{ | |
return module.HasImage () && module.Read (self, (provider, reader) => reader.HasMarshalInfo (provider)); | |
} | |
public static MarshalInfo GetMarshalInfo ( | |
this IMarshalInfoProvider self, | |
ref MarshalInfo variable, | |
ModuleDefinition module) | |
{ | |
return module.HasImage () | |
? module.Read (ref variable, self, (provider, reader) => reader.ReadMarshalInfo (provider)) | |
: null; | |
} | |
} | |
} | |
} | |
#endregion | |
#region Mono.Cecil\*.cs | |
namespace Internal { | |
// | |
// Author: | |
// Jb Evain (jbevain@gmail.com) | |
// | |
// Copyright (c) 2008 - 2015 Jb Evain | |
// Copyright (c) 2008 - 2011 Novell, Inc. | |
// | |
// Licensed under the MIT/X11 license. | |
// | |
namespace Mono.Cecil { | |
internal interface IMemberDefinition : ICustomAttributeProvider { | |
string Name { get; set; } | |
string FullName { get; } | |
bool IsSpecialName { get; set; } | |
bool IsRuntimeSpecialName { get; set; } | |
TypeDefinition DeclaringType { get; set; } | |
} | |
static partial class Mixin { | |
public static bool GetAttributes (this uint self, uint attributes) | |
{ | |
return (self & attributes) != 0; | |
} | |
public static uint SetAttributes (this uint self, uint attributes, bool value) | |
{ | |
if (value) | |
return self | attributes; | |
return self & ~attributes; | |
} | |
public static bool GetMaskedAttributes (this uint self, uint mask, uint attributes) | |
{ | |
return (self & mask) == attributes; | |
} | |
public static uint SetMaskedAttributes (this uint self, uint mask, uint attributes, bool value) | |
{ | |
if (value) { | |
self &= ~mask; | |
return self | attributes; | |
} | |
return self & ~(mask & attributes); | |
} | |
public static bool GetAttributes (this ushort self, ushort attributes) | |
{ | |
return (self & attributes) != 0; | |
} | |
public static ushort SetAttributes (this ushort self, ushort attributes, bool value) | |
{ | |
if (value) | |
return (ushort) (self | attributes); | |
return (ushort) (self & ~attributes); | |
} | |
public static bool GetMaskedAttributes (this ushort self, ushort mask, uint attributes) | |
{ | |
return (self & mask) == attributes; | |
} | |
public static ushort SetMaskedAttributes (this ushort self, ushort mask, uint attributes, bool value) | |
{ | |
if (value) { | |
self = (ushort) (self & ~mask); | |
return (ushort) (self | attributes); | |
} | |
return (ushort) (self & ~(mask & attributes)); | |
} | |
} | |
} | |
} | |
#endregion | |
#region Mono.Cecil\*.cs | |
namespace Internal { | |
// | |
// Author: | |
// Jb Evain (jbevain@gmail.com) | |
// | |
// Copyright (c) 2008 - 2015 Jb Evain | |
// Copyright (c) 2008 - 2011 Novell, Inc. | |
// | |
// Licensed under the MIT/X11 license. | |
// | |
namespace Mono.Cecil { | |
internal enum MetadataScopeType { | |
AssemblyNameReference, | |
ModuleReference, | |
ModuleDefinition, | |
} | |
internal interface IMetadataScope : IMetadataTokenProvider { | |
MetadataScopeType MetadataScopeType { get; } | |
string Name { get; set; } | |
} | |
} | |
} | |
#endregion | |
#region Mono.Cecil\*.cs | |
namespace Internal { | |
// | |
// Author: | |
// Jb Evain (jbevain@gmail.com) | |
// | |
// Copyright (c) 2008 - 2015 Jb Evain | |
// Copyright (c) 2008 - 2011 Novell, Inc. | |
// | |
// Licensed under the MIT/X11 license. | |
// | |
namespace Mono.Cecil { | |
internal interface IMetadataTokenProvider { | |
MetadataToken MetadataToken { get; set; } | |
} | |
} | |
} | |
#endregion | |
#region Mono.Cecil\*.cs | |
namespace Internal { | |
// | |
// Author: | |
// Jb Evain (jbevain@gmail.com) | |
// | |
// Copyright (c) 2008 - 2015 Jb Evain | |
// Copyright (c) 2008 - 2011 Novell, Inc. | |
// | |
// Licensed under the MIT/X11 license. | |
// | |
using System.Text; | |
using Mono.Collections.Generic; | |
namespace Mono.Cecil { | |
internal interface IMethodSignature : IMetadataTokenProvider { | |
bool HasThis { get; set; } | |
bool ExplicitThis { get; set; } | |
MethodCallingConvention CallingConvention { get; set; } | |
bool HasParameters { get; } | |
Collection<ParameterDefinition> Parameters { get; } | |
TypeReference ReturnType { get; set; } | |
MethodReturnType MethodReturnType { get; } | |
} | |
static partial class Mixin { | |
public static bool HasImplicitThis (this IMethodSignature self) | |
{ | |
return self.HasThis && !self.ExplicitThis; | |
} | |
public static void MethodSignatureFullName (this IMethodSignature self, StringBuilder builder) | |
{ | |
builder.Append ("("); | |
if (self.HasParameters) { | |
var parameters = self.Parameters; | |
for (int i = 0; i < parameters.Count; i++) { | |
var parameter = parameters [i]; | |
if (i > 0) | |
builder.Append (","); | |
if (parameter.ParameterType.IsSentinel) | |
builder.Append ("...,"); | |
builder.Append (parameter.ParameterType.FullName); | |
} | |
} | |
builder.Append (")"); | |
} | |
} | |
} | |
} | |
#endregion | |
#region Mono.Cecil\*.cs | |
namespace Internal { | |
// | |
// Author: | |
// Jb Evain (jbevain@gmail.com) | |
// | |
// Copyright (c) 2008 - 2015 Jb Evain | |
// Copyright (c) 2008 - 2011 Novell, Inc. | |
// | |
// Licensed under the MIT/X11 license. | |
// | |
using System; | |
using System.Collections.Generic; | |
using Mono.Collections.Generic; | |
using SR = System.Reflection; | |
using Mono.Cecil.Metadata; | |
namespace Mono.Cecil { | |
#if !READ_ONLY | |
internal interface IMetadataImporterProvider { | |
IMetadataImporter GetMetadataImporter (ModuleDefinition module); | |
} | |
internal interface IMetadataImporter { | |
AssemblyNameReference ImportReference (AssemblyNameReference reference); | |
TypeReference ImportReference (TypeReference type, IGenericParameterProvider context); | |
FieldReference ImportReference (FieldReference field, IGenericParameterProvider context); | |
MethodReference ImportReference (MethodReference method, IGenericParameterProvider context); | |
} | |
internal interface IReflectionImporterProvider { | |
IReflectionImporter GetReflectionImporter (ModuleDefinition module); | |
} | |
internal interface IReflectionImporter { | |
AssemblyNameReference ImportReference (SR.AssemblyName reference); | |
TypeReference ImportReference (Type type, IGenericParameterProvider context); | |
FieldReference ImportReference (SR.FieldInfo field, IGenericParameterProvider context); | |
MethodReference ImportReference (SR.MethodBase method, IGenericParameterProvider context); | |
} | |
struct ImportGenericContext { | |
Collection<IGenericParameterProvider> stack; | |
public bool IsEmpty { get { return stack == null; } } | |
public ImportGenericContext (IGenericParameterProvider provider) | |
{ | |
if (provider == null) | |
throw new ArgumentNullException ("provider"); | |
stack = null; | |
Push (provider); | |
} | |
public void Push (IGenericParameterProvider provider) | |
{ | |
if (stack == null) | |
stack = new Collection<IGenericParameterProvider> (1) { provider }; | |
else | |
stack.Add (provider); | |
} | |
public void Pop () | |
{ | |
stack.RemoveAt (stack.Count - 1); | |
} | |
public TypeReference MethodParameter (string method, int position) | |
{ | |
for (int i = stack.Count - 1; i >= 0; i--) { | |
var candidate = stack [i] as MethodReference; | |
if (candidate == null) | |
continue; | |
if (method != NormalizeMethodName (candidate)) | |
continue; | |
return candidate.GenericParameters [position]; | |
} | |
throw new InvalidOperationException (); | |
} | |
public string NormalizeMethodName (MethodReference method) | |
{ | |
return method.DeclaringType.GetElementType ().FullName + "." + method.Name; | |
} | |
public TypeReference TypeParameter (string type, int position) | |
{ | |
for (int i = stack.Count - 1; i >= 0; i--) { | |
var candidate = GenericTypeFor (stack [i]); | |
if (candidate.FullName != type) | |
continue; | |
return candidate.GenericParameters [position]; | |
} | |
throw new InvalidOperationException (); | |
} | |
static TypeReference GenericTypeFor (IGenericParameterProvider context) | |
{ | |
var type = context as TypeReference; | |
if (type != null) | |
return type.GetElementType (); | |
var method = context as MethodReference; | |
if (method != null) | |
return method.DeclaringType.GetElementType (); | |
throw new InvalidOperationException (); | |
} | |
public static ImportGenericContext For (IGenericParameterProvider context) | |
{ | |
return context != null ? new ImportGenericContext (context) : default (ImportGenericContext); | |
} | |
} | |
internal class DefaultReflectionImporter : IReflectionImporter { | |
readonly protected ModuleDefinition module; | |
public DefaultReflectionImporter (ModuleDefinition module) | |
{ | |
Mixin.CheckModule (module); | |
this.module = module; | |
} | |
enum ImportGenericKind { | |
Definition, | |
Open, | |
} | |
static readonly Dictionary<Type, ElementType> type_etype_mapping = new Dictionary<Type, ElementType> (18) { | |
{ typeof (void), ElementType.Void }, | |
{ typeof (bool), ElementType.Boolean }, | |
{ typeof (char), ElementType.Char }, | |
{ typeof (sbyte), ElementType.I1 }, | |
{ typeof (byte), ElementType.U1 }, | |
{ typeof (short), ElementType.I2 }, | |
{ typeof (ushort), ElementType.U2 }, | |
{ typeof (int), ElementType.I4 }, | |
{ typeof (uint), ElementType.U4 }, | |
{ typeof (long), ElementType.I8 }, | |
{ typeof (ulong), ElementType.U8 }, | |
{ typeof (float), ElementType.R4 }, | |
{ typeof (double), ElementType.R8 }, | |
{ typeof (string), ElementType.String }, | |
#if !NET_CORE | |
{ typeof (TypedReference), ElementType.TypedByRef }, | |
#endif | |
{ typeof (IntPtr), ElementType.I }, | |
{ typeof (UIntPtr), ElementType.U }, | |
{ typeof (object), ElementType.Object }, | |
}; | |
TypeReference ImportType (Type type, ImportGenericContext context) | |
{ | |
return ImportType (type, context, ImportGenericKind.Open); | |
} | |
TypeReference ImportType (Type type, ImportGenericContext context, ImportGenericKind import_kind) | |
{ | |
if (IsTypeSpecification (type) || ImportOpenGenericType (type, import_kind)) | |
return ImportTypeSpecification (type, context); | |
var reference = new TypeReference ( | |
string.Empty, | |
type.Name, | |
module, | |
ImportScope (type), | |
type.IsValueType ()); | |
reference.etype = ImportElementType (type); | |
if (IsNestedType (type)) | |
reference.DeclaringType = ImportType (type.DeclaringType, context, import_kind); | |
else | |
reference.Namespace = type.Namespace ?? string.Empty; | |
if (type.IsGenericType ()) | |
ImportGenericParameters (reference, type.GetGenericArguments ()); | |
return reference; | |
} | |
protected virtual IMetadataScope ImportScope (Type type) | |
{ | |
return ImportScope (type.Assembly ()); | |
} | |
static bool ImportOpenGenericType (Type type, ImportGenericKind import_kind) | |
{ | |
return type.IsGenericType () && type.IsGenericTypeDefinition () && import_kind == ImportGenericKind.Open; | |
} | |
static bool ImportOpenGenericMethod (SR.MethodBase method, ImportGenericKind import_kind) | |
{ | |
return method.IsGenericMethod && method.IsGenericMethodDefinition && import_kind == ImportGenericKind.Open; | |
} | |
static bool IsNestedType (Type type) | |
{ | |
return type.IsNested; | |
} | |
TypeReference ImportTypeSpecification (Type type, ImportGenericContext context) | |
{ | |
if (type.IsByRef) | |
return new ByReferenceType (ImportType (type.GetElementType (), context)); | |
if (type.IsPointer) | |
return new PointerType (ImportType (type.GetElementType (), context)); | |
if (type.IsArray) | |
return new ArrayType (ImportType (type.GetElementType (), context), type.GetArrayRank ()); | |
if (type.IsGenericType ()) | |
return ImportGenericInstance (type, context); | |
if (type.IsGenericParameter) | |
return ImportGenericParameter (type, context); | |
throw new NotSupportedException (type.FullName); | |
} | |
static TypeReference ImportGenericParameter (Type type, ImportGenericContext context) | |
{ | |
if (context.IsEmpty) | |
throw new InvalidOperationException (); | |
if (type.DeclaringMethod () != null) | |
return context.MethodParameter (NormalizeMethodName (type.DeclaringMethod ()), type.GenericParameterPosition); | |
if (type.DeclaringType != null) | |
return context.TypeParameter (NormalizeTypeFullName (type.DeclaringType), type.GenericParameterPosition); | |
throw new InvalidOperationException(); | |
} | |
static string NormalizeMethodName (SR.MethodBase method) | |
{ | |
return NormalizeTypeFullName (method.DeclaringType) + "." + method.Name; | |
} | |
static string NormalizeTypeFullName (Type type) | |
{ | |
if (IsNestedType (type)) | |
return NormalizeTypeFullName (type.DeclaringType) + "/" + type.Name; | |
return type.FullName; | |
} | |
TypeReference ImportGenericInstance (Type type, ImportGenericContext context) | |
{ | |
var element_type = ImportType (type.GetGenericTypeDefinition (), context, ImportGenericKind.Definition); | |
var instance = new GenericInstanceType (element_type); | |
var arguments = type.GetGenericArguments (); | |
var instance_arguments = instance.GenericArguments; | |
context.Push (element_type); | |
try { | |
for (int i = 0; i < arguments.Length; i++) | |
instance_arguments.Add (ImportType (arguments [i], context)); | |
return instance; | |
} finally { | |
context.Pop (); | |
} | |
} | |
static bool IsTypeSpecification (Type type) | |
{ | |
return type.HasElementType | |
|| IsGenericInstance (type) | |
|| type.IsGenericParameter; | |
} | |
static bool IsGenericInstance (Type type) | |
{ | |
return type.IsGenericType () && !type.IsGenericTypeDefinition (); | |
} | |
static ElementType ImportElementType (Type type) | |
{ | |
ElementType etype; | |
if (!type_etype_mapping.TryGetValue (type, out etype)) | |
return ElementType.None; | |
return etype; | |
} | |
protected AssemblyNameReference ImportScope (SR.Assembly assembly) | |
{ | |
return ImportReference (assembly.GetName ()); | |
} | |
public virtual AssemblyNameReference ImportReference (SR.AssemblyName name) | |
{ | |
Mixin.CheckName (name); | |
AssemblyNameReference reference; | |
if (TryGetAssemblyNameReference (name, out reference)) | |
return reference; | |
reference = new AssemblyNameReference (name.Name, name.Version) | |
{ | |
PublicKeyToken = name.GetPublicKeyToken (), | |
#if !NET_CORE | |
Culture = name.CultureInfo.Name, | |
HashAlgorithm = (AssemblyHashAlgorithm) name.HashAlgorithm, | |
#endif | |
}; | |
module.AssemblyReferences.Add (reference); | |
return reference; | |
} | |
bool TryGetAssemblyNameReference (SR.AssemblyName name, out AssemblyNameReference assembly_reference) | |
{ | |
var references = module.AssemblyReferences; | |
for (int i = 0; i < references.Count; i++) { | |
var reference = references [i]; | |
if (name.FullName != reference.FullName) // TODO compare field by field | |
continue; | |
assembly_reference = reference; | |
return true; | |
} | |
assembly_reference = null; | |
return false; | |
} | |
FieldReference ImportField (SR.FieldInfo field, ImportGenericContext context) | |
{ | |
var declaring_type = ImportType (field.DeclaringType, context); | |
if (IsGenericInstance (field.DeclaringType)) | |
field = ResolveFieldDefinition (field); | |
context.Push (declaring_type); | |
try { | |
return new FieldReference { | |
Name = field.Name, | |
DeclaringType = declaring_type, | |
FieldType = ImportType (field.FieldType, context), | |
}; | |
} finally { | |
context.Pop (); | |
} | |
} | |
static SR.FieldInfo ResolveFieldDefinition (SR.FieldInfo field) | |
{ | |
#if NET_CORE | |
throw new NotImplementedException (); | |
#else | |
return field.Module.ResolveField (field.MetadataToken); | |
#endif | |
} | |
static SR.MethodBase ResolveMethodDefinition (SR.MethodBase method) | |
{ | |
#if NET_CORE | |
throw new NotImplementedException (); | |
#else | |
return method.Module.ResolveMethod (method.MetadataToken); | |
#endif | |
} | |
MethodReference ImportMethod (SR.MethodBase method, ImportGenericContext context, ImportGenericKind import_kind) | |
{ | |
if (IsMethodSpecification (method) || ImportOpenGenericMethod (method, import_kind)) | |
return ImportMethodSpecification (method, context); | |
var declaring_type = ImportType (method.DeclaringType, context); | |
if (IsGenericInstance (method.DeclaringType)) | |
method = ResolveMethodDefinition (method); | |
var reference = new MethodReference { | |
Name = method.Name, | |
HasThis = HasCallingConvention (method, SR.CallingConventions.HasThis), | |
ExplicitThis = HasCallingConvention (method, SR.CallingConventions.ExplicitThis), | |
DeclaringType = ImportType (method.DeclaringType, context, ImportGenericKind.Definition), | |
}; | |
if (HasCallingConvention (method, SR.CallingConventions.VarArgs)) | |
reference.CallingConvention &= MethodCallingConvention.VarArg; | |
if (method.IsGenericMethod) | |
ImportGenericParameters (reference, method.GetGenericArguments ()); | |
context.Push (reference); | |
try { | |
var method_info = method as SR.MethodInfo; | |
reference.ReturnType = method_info != null | |
? ImportType (method_info.ReturnType, context) | |
: ImportType (typeof (void), default (ImportGenericContext)); | |
var parameters = method.GetParameters (); | |
var reference_parameters = reference.Parameters; | |
for (int i = 0; i < parameters.Length; i++) | |
reference_parameters.Add ( | |
new ParameterDefinition (ImportType (parameters [i].ParameterType, context))); | |
reference.DeclaringType = declaring_type; | |
return reference; | |
} finally { | |
context.Pop (); | |
} | |
} | |
static void ImportGenericParameters (IGenericParameterProvider provider, Type [] arguments) | |
{ | |
var provider_parameters = provider.GenericParameters; | |
for (int i = 0; i < arguments.Length; i++) | |
provider_parameters.Add (new GenericParameter (arguments [i].Name, provider)); | |
} | |
static bool IsMethodSpecification (SR.MethodBase method) | |
{ | |
return method.IsGenericMethod && !method.IsGenericMethodDefinition; | |
} | |
MethodReference ImportMethodSpecification (SR.MethodBase method, ImportGenericContext context) | |
{ | |
var method_info = method as SR.MethodInfo; | |
if (method_info == null) | |
throw new InvalidOperationException (); | |
var element_method = ImportMethod (method_info.GetGenericMethodDefinition (), context, ImportGenericKind.Definition); | |
var instance = new GenericInstanceMethod (element_method); | |
var arguments = method.GetGenericArguments (); | |
var instance_arguments = instance.GenericArguments; | |
context.Push (element_method); | |
try { | |
for (int i = 0; i < arguments.Length; i++) | |
instance_arguments.Add (ImportType (arguments [i], context)); | |
return instance; | |
} finally { | |
context.Pop (); | |
} | |
} | |
static bool HasCallingConvention (SR.MethodBase method, SR.CallingConventions conventions) | |
{ | |
return (method.CallingConvention & conventions) != 0; | |
} | |
public virtual TypeReference ImportReference (Type type, IGenericParameterProvider context) | |
{ | |
Mixin.CheckType (type); | |
return ImportType ( | |
type, | |
ImportGenericContext.For (context), | |
context != null ? ImportGenericKind.Open : ImportGenericKind.Definition); | |
} | |
public virtual FieldReference ImportReference (SR.FieldInfo field, IGenericParameterProvider context) | |
{ | |
Mixin.CheckField (field); | |
return ImportField (field, ImportGenericContext.For (context)); | |
} | |
public virtual MethodReference ImportReference (SR.MethodBase method, IGenericParameterProvider context) | |
{ | |
Mixin.CheckMethod (method); | |
return ImportMethod (method, | |
ImportGenericContext.For (context), | |
context != null ? ImportGenericKind.Open : ImportGenericKind.Definition); | |
} | |
} | |
internal class DefaultMetadataImporter : IMetadataImporter { | |
readonly protected ModuleDefinition module; | |
public DefaultMetadataImporter (ModuleDefinition module) | |
{ | |
Mixin.CheckModule (module); | |
this.module = module; | |
} | |
TypeReference ImportType (TypeReference type, ImportGenericContext context) | |
{ | |
if (type.IsTypeSpecification ()) | |
return ImportTypeSpecification (type, context); | |
var reference = new TypeReference ( | |
type.Namespace, | |
type.Name, | |
module, | |
ImportScope (type), | |
type.IsValueType); | |
MetadataSystem.TryProcessPrimitiveTypeReference (reference); | |
if (type.IsNested) | |
reference.DeclaringType = ImportType (type.DeclaringType, context); | |
if (type.HasGenericParameters) | |
ImportGenericParameters (reference, type); | |
return reference; | |
} | |
protected virtual IMetadataScope ImportScope (TypeReference type) | |
{ | |
return ImportScope (type.Scope); | |
} | |
protected IMetadataScope ImportScope (IMetadataScope scope) | |
{ | |
switch (scope.MetadataScopeType) { | |
case MetadataScopeType.AssemblyNameReference: | |
return ImportReference ((AssemblyNameReference) scope); | |
case MetadataScopeType.ModuleDefinition: | |
if (scope == module) return scope; | |
return ImportReference (((ModuleDefinition) scope).Assembly.Name); | |
case MetadataScopeType.ModuleReference: | |
throw new NotImplementedException (); | |
} | |
throw new NotSupportedException (); | |
} | |
public virtual AssemblyNameReference ImportReference (AssemblyNameReference name) | |
{ | |
Mixin.CheckName (name); | |
AssemblyNameReference reference; | |
if (module.TryGetAssemblyNameReference (name, out reference)) | |
return reference; | |
reference = new AssemblyNameReference (name.Name, name.Version) { | |
Culture = name.Culture, | |
HashAlgorithm = name.HashAlgorithm, | |
IsRetargetable = name.IsRetargetable, | |
IsWindowsRuntime = name.IsWindowsRuntime, | |
}; | |
var pk_token = !name.PublicKeyToken.IsNullOrEmpty () | |
? new byte [name.PublicKeyToken.Length] | |
: Empty<byte>.Array; | |
if (pk_token.Length > 0) | |
Buffer.BlockCopy (name.PublicKeyToken, 0, pk_token, 0, pk_token.Length); | |
reference.PublicKeyToken = pk_token; | |
module.AssemblyReferences.Add (reference); | |
return reference; | |
} | |
static void ImportGenericParameters (IGenericParameterProvider imported, IGenericParameterProvider original) | |
{ | |
var parameters = original.GenericParameters; | |
var imported_parameters = imported.GenericParameters; | |
for (int i = 0; i < parameters.Count; i++) | |
imported_parameters.Add (new GenericParameter (parameters [i].Name, imported)); | |
} | |
TypeReference ImportTypeSpecification (TypeReference type, ImportGenericContext context) | |
{ | |
switch (type.etype) { | |
case ElementType.SzArray: | |
var vector = (ArrayType) type; | |
return new ArrayType (ImportType (vector.ElementType, context)); | |
case ElementType.Ptr: | |
var pointer = (PointerType) type; | |
return new PointerType (ImportType (pointer.ElementType, context)); | |
case ElementType.ByRef: | |
var byref = (ByReferenceType) type; | |
return new ByReferenceType (ImportType (byref.ElementType, context)); | |
case ElementType.Pinned: | |
var pinned = (PinnedType) type; | |
return new PinnedType (ImportType (pinned.ElementType, context)); | |
case ElementType.Sentinel: | |
var sentinel = (SentinelType) type; | |
return new SentinelType (ImportType (sentinel.ElementType, context)); | |
case ElementType.FnPtr: | |
var fnptr = (FunctionPointerType) type; | |
var imported_fnptr = new FunctionPointerType () { | |
HasThis = fnptr.HasThis, | |
ExplicitThis = fnptr.ExplicitThis, | |
CallingConvention = fnptr.CallingConvention, | |
ReturnType = ImportType (fnptr.ReturnType, context), | |
}; | |
if (!fnptr.HasParameters) | |
return imported_fnptr; | |
for (int i = 0; i < fnptr.Parameters.Count; i++) | |
imported_fnptr.Parameters.Add (new ParameterDefinition ( | |
ImportType (fnptr.Parameters [i].ParameterType, context))); | |
return imported_fnptr; | |
case ElementType.CModOpt: | |
var modopt = (OptionalModifierType) type; | |
return new OptionalModifierType ( | |
ImportType (modopt.ModifierType, context), | |
ImportType (modopt.ElementType, context)); | |
case ElementType.CModReqD: | |
var modreq = (RequiredModifierType) type; | |
return new RequiredModifierType ( | |
ImportType (modreq.ModifierType, context), | |
ImportType (modreq.ElementType, context)); | |
case ElementType.Array: | |
var array = (ArrayType) type; | |
var imported_array = new ArrayType (ImportType (array.ElementType, context)); | |
if (array.IsVector) | |
return imported_array; | |
var dimensions = array.Dimensions; | |
var imported_dimensions = imported_array.Dimensions; | |
imported_dimensions.Clear (); | |
for (int i = 0; i < dimensions.Count; i++) { | |
var dimension = dimensions [i]; | |
imported_dimensions.Add (new ArrayDimension (dimension.LowerBound, dimension.UpperBound)); | |
} | |
return imported_array; | |
case ElementType.GenericInst: | |
var instance = (GenericInstanceType) type; | |
var element_type = ImportType (instance.ElementType, context); | |
var imported_instance = new GenericInstanceType (element_type); | |
var arguments = instance.GenericArguments; | |
var imported_arguments = imported_instance.GenericArguments; | |
for (int i = 0; i < arguments.Count; i++) | |
imported_arguments.Add (ImportType (arguments [i], context)); | |
return imported_instance; | |
case ElementType.Var: | |
var var_parameter = (GenericParameter) type; | |
if (var_parameter.DeclaringType == null) | |
throw new InvalidOperationException (); | |
return context.TypeParameter (var_parameter.DeclaringType.FullName, var_parameter.Position); | |
case ElementType.MVar: | |
var mvar_parameter = (GenericParameter) type; | |
if (mvar_parameter.DeclaringMethod == null) | |
throw new InvalidOperationException (); | |
return context.MethodParameter (context.NormalizeMethodName (mvar_parameter.DeclaringMethod), mvar_parameter.Position); | |
} | |
throw new NotSupportedException (type.etype.ToString ()); | |
} | |
FieldReference ImportField (FieldReference field, ImportGenericContext context) | |
{ | |
var declaring_type = ImportType (field.DeclaringType, context); | |
context.Push (declaring_type); | |
try { | |
return new FieldReference { | |
Name = field.Name, | |
DeclaringType = declaring_type, | |
FieldType = ImportType (field.FieldType, context), | |
}; | |
} finally { | |
context.Pop (); | |
} | |
} | |
MethodReference ImportMethod (MethodReference method, ImportGenericContext context) | |
{ | |
if (method.IsGenericInstance) | |
return ImportMethodSpecification (method, context); | |
var declaring_type = ImportType (method.DeclaringType, context); | |
var reference = new MethodReference { | |
Name = method.Name, | |
HasThis = method.HasThis, | |
ExplicitThis = method.ExplicitThis, | |
DeclaringType = declaring_type, | |
CallingConvention = method.CallingConvention, | |
}; | |
if (method.HasGenericParameters) | |
ImportGenericParameters (reference, method); | |
context.Push (reference); | |
try { | |
reference.ReturnType = ImportType (method.ReturnType, context); | |
if (!method.HasParameters) | |
return reference; | |
var parameters = method.Parameters; | |
var reference_parameters = reference.parameters = new ParameterDefinitionCollection (reference, parameters.Count); | |
for (int i = 0; i < parameters.Count; i++) | |
reference_parameters.Add ( | |
new ParameterDefinition (ImportType (parameters [i].ParameterType, context))); | |
return reference; | |
} finally { | |
context.Pop(); | |
} | |
} | |
MethodSpecification ImportMethodSpecification (MethodReference method, ImportGenericContext context) | |
{ | |
if (!method.IsGenericInstance) | |
throw new NotSupportedException (); | |
var instance = (GenericInstanceMethod) method; | |
var element_method = ImportMethod (instance.ElementMethod, context); | |
var imported_instance = new GenericInstanceMethod (element_method); | |
var arguments = instance.GenericArguments; | |
var imported_arguments = imported_instance.GenericArguments; | |
for (int i = 0; i < arguments.Count; i++) | |
imported_arguments.Add (ImportType (arguments [i], context)); | |
return imported_instance; | |
} | |
public virtual TypeReference ImportReference (TypeReference type, IGenericParameterProvider context) | |
{ | |
Mixin.CheckType (type); | |
return ImportType (type, ImportGenericContext.For (context)); | |
} | |
public virtual FieldReference ImportReference (FieldReference field, IGenericParameterProvider context) | |
{ | |
Mixin.CheckField (field); | |
return ImportField (field, ImportGenericContext.For (context)); | |
} | |
public virtual MethodReference ImportReference (MethodReference method, IGenericParameterProvider context) | |
{ | |
Mixin.CheckMethod (method); | |
return ImportMethod (method, ImportGenericContext.For (context)); | |
} | |
} | |
#endif | |
static partial class Mixin { | |
public static void CheckModule (ModuleDefinition module) | |
{ | |
if (module == null) | |
throw new ArgumentNullException (Argument.module.ToString ()); | |
} | |
public static bool TryGetAssemblyNameReference (this ModuleDefinition module, AssemblyNameReference name_reference, out AssemblyNameReference assembly_reference) | |
{ | |
var references = module.AssemblyReferences; | |
for (int i = 0; i < references.Count; i++) { | |
var reference = references [i]; | |
if (!Equals (name_reference, reference)) | |
continue; | |
assembly_reference = reference; | |
return true; | |
} | |
assembly_reference = null; | |
return false; | |
} | |
static bool Equals (byte [] a, byte [] b) | |
{ | |
if (ReferenceEquals (a, b)) | |
return true; | |
if (a == null) | |
return false; | |
if (a.Length != b.Length) | |
return false; | |
for (int i = 0; i < a.Length; i++) | |
if (a [i] != b [i]) | |
return false; | |
return true; | |
} | |
static bool Equals<T> (T a, T b) where T : class, IEquatable<T> | |
{ | |
if (ReferenceEquals (a, b)) | |
return true; | |
if (a == null) | |
return false; | |
return a.Equals (b); | |
} | |
static bool Equals (AssemblyNameReference a, AssemblyNameReference b) | |
{ | |
if (ReferenceEquals (a, b)) | |
return true; | |
if (a.Name != b.Name) | |
return false; | |
if (!Equals (a.Version, b.Version)) | |
return false; | |
if (a.Culture != b.Culture) | |
return false; | |
if (!Equals (a.PublicKeyToken, b.PublicKeyToken)) | |
return false; | |
return true; | |
} | |
} | |
} | |
} | |
#endregion | |
#region Mono.Cecil\*.cs | |
namespace Internal { | |
// | |
// Author: | |
// Jb Evain (jbevain@gmail.com) | |
// | |
// Copyright (c) 2008 - 2015 Jb Evain | |
// Copyright (c) 2008 - 2011 Novell, Inc. | |
// | |
// Licensed under the MIT/X11 license. | |
// | |
namespace Mono.Cecil { | |
internal sealed class LinkedResource : Resource { | |
internal byte [] hash; | |
string file; | |
public byte [] Hash { | |
get { return hash; } | |
} | |
public string File { | |
get { return file; } | |
set { file = value; } | |
} | |
public override ResourceType ResourceType { | |
get { return ResourceType.Linked; } | |
} | |
public LinkedResource (string name, ManifestResourceAttributes flags) | |
: base (name, flags) | |
{ | |
} | |
public LinkedResource (string name, ManifestResourceAttributes flags, string file) | |
: base (name, flags) | |
{ | |
this.file = file; | |
} | |
} | |
} | |
} | |
#endregion | |
#region Mono.Cecil\*.cs | |
namespace Internal { | |
// | |
// Author: | |
// Jb Evain (jbevain@gmail.com) | |
// | |
// Copyright (c) 2008 - 2015 Jb Evain | |
// Copyright (c) 2008 - 2011 Novell, Inc. | |
// | |
// Licensed under the MIT/X11 license. | |
// | |
using System; | |
namespace Mono.Cecil { | |
[Flags] | |
internal enum ManifestResourceAttributes : uint { | |
VisibilityMask = 0x0007, | |
Public = 0x0001, // The resource is exported from the Assembly | |
Private = 0x0002 // The resource is private to the Assembly | |
} | |
} | |
} | |
#endregion | |
#region Mono.Cecil\*.cs | |
namespace Internal { | |
// | |
// Author: | |
// Jb Evain (jbevain@gmail.com) | |
// | |
// Copyright (c) 2008 - 2015 Jb Evain | |
// Copyright (c) 2008 - 2011 Novell, Inc. | |
// | |
// Licensed under the MIT/X11 license. | |
// | |
using System; | |
namespace Mono.Cecil { | |
internal class MarshalInfo { | |
internal NativeType native; | |
public NativeType NativeType { | |
get { return native; } | |
set { native = value; } | |
} | |
public MarshalInfo (NativeType native) | |
{ | |
this.native = native; | |
} | |
} | |
internal sealed class ArrayMarshalInfo : MarshalInfo { | |
internal NativeType element_type; | |
internal int size_parameter_index; | |
internal int size; | |
internal int size_parameter_multiplier; | |
public NativeType ElementType { | |
get { return element_type; } | |
set { element_type = value; } | |
} | |
public int SizeParameterIndex { | |
get { return size_parameter_index; } | |
set { size_parameter_index = value; } | |
} | |
public int Size { | |
get { return size; } | |
set { size = value; } | |
} | |
public int SizeParameterMultiplier { | |
get { return size_parameter_multiplier; } | |
set { size_parameter_multiplier = value; } | |
} | |
public ArrayMarshalInfo () | |
: base (NativeType.Array) | |
{ | |
element_type = NativeType.None; | |
size_parameter_index = -1; | |
size = -1; | |
size_parameter_multiplier = -1; | |
} | |
} | |
internal sealed class CustomMarshalInfo : MarshalInfo { | |
internal Guid guid; | |
internal string unmanaged_type; | |
internal TypeReference managed_type; | |
internal string cookie; | |
public Guid Guid { | |
get { return guid; } | |
set { guid = value; } | |
} | |
public string UnmanagedType { | |
get { return unmanaged_type; } | |
set { unmanaged_type = value; } | |
} | |
public TypeReference ManagedType { | |
get { return managed_type; } | |
set { managed_type = value; } | |
} | |
public string Cookie { | |
get { return cookie; } | |
set { cookie = value; } | |
} | |
public CustomMarshalInfo () | |
: base (NativeType.CustomMarshaler) | |
{ | |
} | |
} | |
internal sealed class SafeArrayMarshalInfo : MarshalInfo { | |
internal VariantType element_type; | |
public VariantType ElementType { | |
get { return element_type; } | |
set { element_type = value; } | |
} | |
public SafeArrayMarshalInfo () | |
: base (NativeType.SafeArray) | |
{ | |
element_type = VariantType.None; | |
} | |
} | |
internal sealed class FixedArrayMarshalInfo : MarshalInfo { | |
internal NativeType element_type; | |
internal int size; | |
public NativeType ElementType { | |
get { return element_type; } | |
set { element_type = value; } | |
} | |
public int Size { | |
get { return size; } | |
set { size = value; } | |
} | |
public FixedArrayMarshalInfo () | |
: base (NativeType.FixedArray) | |
{ | |
element_type = NativeType.None; | |
} | |
} | |
internal sealed class FixedSysStringMarshalInfo : MarshalInfo { | |
internal int size; | |
public int Size { | |
get { return size; } | |
set { size = value; } | |
} | |
public FixedSysStringMarshalInfo () | |
: base (NativeType.FixedSysString) | |
{ | |
size = -1; | |
} | |
} | |
} | |
} | |
#endregion | |
#region Mono.Cecil\*.cs | |
namespace Internal { | |
// | |
// Author: | |
// Jb Evain (jbevain@gmail.com) | |
// | |
// Copyright (c) 2008 - 2015 Jb Evain | |
// Copyright (c) 2008 - 2011 Novell, Inc. | |
// | |
// Licensed under the MIT/X11 license. | |
// | |
using System; | |
using Mono.Collections.Generic; | |
namespace Mono.Cecil { | |
sealed class MemberDefinitionCollection<T> : Collection<T> where T : IMemberDefinition { | |
TypeDefinition container; | |
internal MemberDefinitionCollection (TypeDefinition container) | |
{ | |
this.container = container; | |
} | |
internal MemberDefinitionCollection (TypeDefinition container, int capacity) | |
: base (capacity) | |
{ | |
this.container = container; | |
} | |
protected override void OnAdd (T item, int index) | |
{ | |
Attach (item); | |
} | |
protected sealed override void OnSet (T item, int index) | |
{ | |
Attach (item); | |
} | |
protected sealed override void OnInsert (T item, int index) | |
{ | |
Attach (item); | |
} | |
protected sealed override void OnRemove (T item, int index) | |
{ | |
Detach (item); | |
} | |
protected sealed override void OnClear () | |
{ | |
foreach (var definition in this) | |
Detach (definition); | |
} | |
void Attach (T element) | |
{ | |
if (element.DeclaringType == container) | |
return; | |
if (element.DeclaringType != null) | |
throw new ArgumentException ("Member already attached"); | |
element.DeclaringType = this.container; | |
} | |
static void Detach (T element) | |
{ | |
element.DeclaringType = null; | |
} | |
} | |
} | |
} | |
#endregion | |
#region Mono.Cecil\*.cs | |
namespace Internal { | |
// | |
// Author: | |
// Jb Evain (jbevain@gmail.com) | |
// | |
// Copyright (c) 2008 - 2015 Jb Evain | |
// Copyright (c) 2008 - 2011 Novell, Inc. | |
// | |
// Licensed under the MIT/X11 license. | |
// | |
using System; | |
namespace Mono.Cecil { | |
internal abstract class MemberReference : IMetadataTokenProvider { | |
string name; | |
TypeReference declaring_type; | |
internal MetadataToken token; | |
internal object projection; | |
public virtual string Name { | |
get { return name; } | |
set { | |
if (IsWindowsRuntimeProjection && value != name) | |
throw new InvalidOperationException (); | |
name = value; | |
} | |
} | |
public abstract string FullName { | |
get; | |
} | |
public virtual TypeReference DeclaringType { | |
get { return declaring_type; } | |
set { declaring_type = value; } | |
} | |
public MetadataToken MetadataToken { | |
get { return token; } | |
set { token = value; } | |
} | |
public bool IsWindowsRuntimeProjection { | |
get { return projection != null; } | |
} | |
internal MemberReferenceProjection WindowsRuntimeProjection { | |
get { return (MemberReferenceProjection) projection; } | |
set { projection = value; } | |
} | |
internal bool HasImage { | |
get { | |
var module = Module; | |
if (module == null) | |
return false; | |
return module.HasImage; | |
} | |
} | |
public virtual ModuleDefinition Module { | |
get { return declaring_type != null ? declaring_type.Module : null; } | |
} | |
public virtual bool IsDefinition { | |
get { return false; } | |
} | |
public virtual bool ContainsGenericParameter { | |
get { return declaring_type != null && declaring_type.ContainsGenericParameter; } | |
} | |
internal MemberReference () | |
{ | |
} | |
internal MemberReference (string name) | |
{ | |
this.name = name ?? string.Empty; | |
} | |
internal string MemberFullName () | |
{ | |
if (declaring_type == null) | |
return name; | |
return declaring_type.FullName + "::" + name; | |
} | |
public IMemberDefinition Resolve () | |
{ | |
return ResolveDefinition (); | |
} | |
protected abstract IMemberDefinition ResolveDefinition (); | |
public override string ToString () | |
{ | |
return FullName; | |
} | |
} | |
} | |
} | |
#endregion | |
#region Mono.Cecil\*.cs | |
namespace Internal { | |
// | |
// Author: | |
// Jb Evain (jbevain@gmail.com) | |
// | |
// Copyright (c) 2008 - 2015 Jb Evain | |
// Copyright (c) 2008 - 2011 Novell, Inc. | |
// | |
// Licensed under the MIT/X11 license. | |
// | |
using System; | |
using Mono.Collections.Generic; | |
namespace Mono.Cecil { | |
internal interface IAssemblyResolver : IDisposable { | |
AssemblyDefinition Resolve (AssemblyNameReference name); | |
AssemblyDefinition Resolve (AssemblyNameReference name, ReaderParameters parameters); | |
} | |
internal interface IMetadataResolver { | |
TypeDefinition Resolve (TypeReference type); | |
FieldDefinition Resolve (FieldReference field); | |
MethodDefinition Resolve (MethodReference method); | |
} | |
#if !NET_CORE | |
[Serializable] | |
#endif | |
internal sealed class ResolutionException : Exception { | |
readonly MemberReference member; | |
public MemberReference Member { | |
get { return member; } | |
} | |
public IMetadataScope Scope { | |
get { | |
var type = member as TypeReference; | |
if (type != null) | |
return type.Scope; | |
var declaring_type = member.DeclaringType; | |
if (declaring_type != null) | |
return declaring_type.Scope; | |
throw new NotSupportedException (); | |
} | |
} | |
public ResolutionException (MemberReference member) | |
: base ("Failed to resolve " + member.FullName) | |
{ | |
if (member == null) | |
throw new ArgumentNullException ("member"); | |
this.member = member; | |
} | |
public ResolutionException (MemberReference member, Exception innerException) | |
: base ("Failed to resolve " + member.FullName, innerException) | |
{ | |
if (member == null) | |
throw new ArgumentNullException ("member"); | |
this.member = member; | |
} | |
#if !NET_CORE | |
ResolutionException ( | |
System.Runtime.Serialization.SerializationInfo info, | |
System.Runtime.Serialization.StreamingContext context) | |
: base (info, context) | |
{ | |
} | |
#endif | |
} | |
internal class MetadataResolver : IMetadataResolver { | |
readonly IAssemblyResolver assembly_resolver; | |
public IAssemblyResolver AssemblyResolver { | |
get { return assembly_resolver; } | |
} | |
public MetadataResolver (IAssemblyResolver assemblyResolver) | |
{ | |
if (assemblyResolver == null) | |
throw new ArgumentNullException ("assemblyResolver"); | |
assembly_resolver = assemblyResolver; | |
} | |
public virtual TypeDefinition Resolve (TypeReference type) | |
{ | |
Mixin.CheckType (type); | |
type = type.GetElementType (); | |
var scope = type.Scope; | |
if (scope == null) | |
return null; | |
switch (scope.MetadataScopeType) { | |
case MetadataScopeType.AssemblyNameReference: | |
var assembly = assembly_resolver.Resolve ((AssemblyNameReference) scope); | |
if (assembly == null) | |
return null; | |
return GetType (assembly.MainModule, type); | |
case MetadataScopeType.ModuleDefinition: | |
return GetType ((ModuleDefinition) scope, type); | |
case MetadataScopeType.ModuleReference: | |
var modules = type.Module.Assembly.Modules; | |
var module_ref = (ModuleReference) scope; | |
for (int i = 0; i < modules.Count; i++) { | |
var netmodule = modules [i]; | |
if (netmodule.Name == module_ref.Name) | |
return GetType (netmodule, type); | |
} | |
break; | |
} | |
throw new NotSupportedException (); | |
} | |
static TypeDefinition GetType (ModuleDefinition module, TypeReference reference) | |
{ | |
var type = GetTypeDefinition (module, reference); | |
if (type != null) | |
return type; | |
if (!module.HasExportedTypes) | |
return null; | |
var exported_types = module.ExportedTypes; | |
for (int i = 0; i < exported_types.Count; i++) { | |
var exported_type = exported_types [i]; | |
if (exported_type.Name != reference.Name) | |
continue; | |
if (exported_type.Namespace != reference.Namespace) | |
continue; | |
return exported_type.Resolve (); | |
} | |
return null; | |
} | |
static TypeDefinition GetTypeDefinition (ModuleDefinition module, TypeReference type) | |
{ | |
if (!type.IsNested) | |
return module.GetType (type.Namespace, type.Name); | |
var declaring_type = type.DeclaringType.Resolve (); | |
if (declaring_type == null) | |
return null; | |
return declaring_type.GetNestedType (type.TypeFullName ()); | |
} | |
public virtual FieldDefinition Resolve (FieldReference field) | |
{ | |
Mixin.CheckField (field); | |
var type = Resolve (field.DeclaringType); | |
if (type == null) | |
return null; | |
if (!type.HasFields) | |
return null; | |
return GetField (type, field); | |
} | |
FieldDefinition GetField (TypeDefinition type, FieldReference reference) | |
{ | |
while (type != null) { | |
var field = GetField (type.Fields, reference); | |
if (field != null) | |
return field; | |
if (type.BaseType == null) | |
return null; | |
type = Resolve (type.BaseType); | |
} | |
return null; | |
} | |
static FieldDefinition GetField (Collection<FieldDefinition> fields, FieldReference reference) | |
{ | |
for (int i = 0; i < fields.Count; i++) { | |
var field = fields [i]; | |
if (field.Name != reference.Name) | |
continue; | |
if (!AreSame (field.FieldType, reference.FieldType)) | |
continue; | |
return field; | |
} | |
return null; | |
} | |
public virtual MethodDefinition Resolve (MethodReference method) | |
{ | |
Mixin.CheckMethod (method); | |
var type = Resolve (method.DeclaringType); | |
if (type == null) | |
return null; | |
method = method.GetElementMethod (); | |
if (!type.HasMethods) | |
return null; | |
return GetMethod (type, method); | |
} | |
MethodDefinition GetMethod (TypeDefinition type, MethodReference reference) | |
{ | |
while (type != null) { | |
var method = GetMethod (type.Methods, reference); | |
if (method != null) | |
return method; | |
if (type.BaseType == null) | |
return null; | |
type = Resolve (type.BaseType); | |
} | |
return null; | |
} | |
public static MethodDefinition GetMethod (Collection<MethodDefinition> methods, MethodReference reference) | |
{ | |
for (int i = 0; i < methods.Count; i++) { | |
var method = methods [i]; | |
if (method.Name != reference.Name) | |
continue; | |
if (method.HasGenericParameters != reference.HasGenericParameters) | |
continue; | |
if (method.HasGenericParameters && method.GenericParameters.Count != reference.GenericParameters.Count) | |
continue; | |
if (!AreSame (method.ReturnType, reference.ReturnType)) | |
continue; | |
if (method.IsVarArg () != reference.IsVarArg ()) | |
continue; | |
if (method.IsVarArg () && IsVarArgCallTo (method, reference)) | |
return method; | |
if (method.HasParameters != reference.HasParameters) | |
continue; | |
if (!method.HasParameters && !reference.HasParameters) | |
return method; | |
if (!AreSame (method.Parameters, reference.Parameters)) | |
continue; | |
return method; | |
} | |
return null; | |
} | |
static bool AreSame (Collection<ParameterDefinition> a, Collection<ParameterDefinition> b) | |
{ | |
var count = a.Count; | |
if (count != b.Count) | |
return false; | |
if (count == 0) | |
return true; | |
for (int i = 0; i < count; i++) | |
if (!AreSame (a [i].ParameterType, b [i].ParameterType)) | |
return false; | |
return true; | |
} | |
static bool IsVarArgCallTo (MethodDefinition method, MethodReference reference) | |
{ | |
if (method.Parameters.Count >= reference.Parameters.Count) | |
return false; | |
if (reference.GetSentinelPosition () != method.Parameters.Count) | |
return false; | |
for (int i = 0; i < method.Parameters.Count; i++) | |
if (!AreSame (method.Parameters [i].ParameterType, reference.Parameters [i].ParameterType)) | |
return false; | |
return true; | |
} | |
static bool AreSame (TypeSpecification a, TypeSpecification b) | |
{ | |
if (!AreSame (a.ElementType, b.ElementType)) | |
return false; | |
if (a.IsGenericInstance) | |
return AreSame ((GenericInstanceType) a, (GenericInstanceType) b); | |
if (a.IsRequiredModifier || a.IsOptionalModifier) | |
return AreSame ((IModifierType) a, (IModifierType) b); | |
if (a.IsArray) | |
return AreSame ((ArrayType) a, (ArrayType) b); | |
return true; | |
} | |
static bool AreSame (ArrayType a, ArrayType b) | |
{ | |
if (a.Rank != b.Rank) | |
return false; | |
// TODO: dimensions | |
return true; | |
} | |
static bool AreSame (IModifierType a, IModifierType b) | |
{ | |
return AreSame (a.ModifierType, b.ModifierType); | |
} | |
static bool AreSame (GenericInstanceType a, GenericInstanceType b) | |
{ | |
if (a.GenericArguments.Count != b.GenericArguments.Count) | |
return false; | |
for (int i = 0; i < a.GenericArguments.Count; i++) | |
if (!AreSame (a.GenericArguments [i], b.GenericArguments [i])) | |
return false; | |
return true; | |
} | |
static bool AreSame (GenericParameter a, GenericParameter b) | |
{ | |
return a.Position == b.Position; | |
} | |
static bool AreSame (TypeReference a, TypeReference b) | |
{ | |
if (ReferenceEquals (a, b)) | |
return true; | |
if (a == null || b == null) | |
return false; | |
if (a.etype != b.etype) | |
return false; | |
if (a.IsGenericParameter) | |
return AreSame ((GenericParameter) a, (GenericParameter) b); | |
if (a.IsTypeSpecification ()) | |
return AreSame ((TypeSpecification) a, (TypeSpecification) b); | |
if (a.Name != b.Name || a.Namespace != b.Namespace) | |
return false; | |
//TODO: check scope | |
return AreSame (a.DeclaringType, b.DeclaringType); | |
} | |
} | |
} | |
} | |
#endregion | |
#region Mono.Cecil\*.cs | |
namespace Internal { | |
// | |
// Author: | |
// Jb Evain (jbevain@gmail.com) | |
// | |
// Copyright (c) 2008 - 2015 Jb Evain | |
// Copyright (c) 2008 - 2011 Novell, Inc. | |
// | |
// Licensed under the MIT/X11 license. | |
// | |
using System; | |
using System.Collections.Generic; | |
using Mono.Cecil.Cil; | |
using Mono.Cecil.Metadata; | |
using Mono.Collections.Generic; | |
namespace Mono.Cecil { | |
struct Range { | |
public uint Start; | |
public uint Length; | |
public Range (uint index, uint length) | |
{ | |
this.Start = index; | |
this.Length = length; | |
} | |
} | |
sealed class MetadataSystem { | |
internal AssemblyNameReference [] AssemblyReferences; | |
internal ModuleReference [] ModuleReferences; | |
internal TypeDefinition [] Types; | |
internal TypeReference [] TypeReferences; | |
internal FieldDefinition [] Fields; | |
internal MethodDefinition [] Methods; | |
internal MemberReference [] MemberReferences; | |
internal Dictionary<uint, Collection<uint>> NestedTypes; | |
internal Dictionary<uint, uint> ReverseNestedTypes; | |
internal Dictionary<uint, Collection<Row<uint, MetadataToken>>> Interfaces; | |
internal Dictionary<uint, Row<ushort, uint>> ClassLayouts; | |
internal Dictionary<uint, uint> FieldLayouts; | |
internal Dictionary<uint, uint> FieldRVAs; | |
internal Dictionary<MetadataToken, uint> FieldMarshals; | |
internal Dictionary<MetadataToken, Row<ElementType, uint>> Constants; | |
internal Dictionary<uint, Collection<MetadataToken>> Overrides; | |
internal Dictionary<MetadataToken, Range []> CustomAttributes; | |
internal Dictionary<MetadataToken, Range []> SecurityDeclarations; | |
internal Dictionary<uint, Range> Events; | |
internal Dictionary<uint, Range> Properties; | |
internal Dictionary<uint, Row<MethodSemanticsAttributes, MetadataToken>> Semantics; | |
internal Dictionary<uint, Row<PInvokeAttributes, uint, uint>> PInvokes; | |
internal Dictionary<MetadataToken, Range []> GenericParameters; | |
internal Dictionary<uint, Collection<MetadataToken>> GenericConstraints; | |
internal Document [] Documents; | |
internal Dictionary<uint, Collection<Row<uint, Range, Range, uint, uint, uint>>> LocalScopes; | |
internal ImportDebugInformation [] ImportScopes; | |
internal Dictionary<uint, uint> StateMachineMethods; | |
internal Dictionary<MetadataToken, Row<Guid, uint, uint> []> CustomDebugInformations; | |
static Dictionary<string, Row<ElementType, bool>> primitive_value_types; | |
static void InitializePrimitives () | |
{ | |
primitive_value_types = new Dictionary<string, Row<ElementType, bool>> (18, StringComparer.Ordinal) { | |
{ "Void", new Row<ElementType, bool> (ElementType.Void, false) }, | |
{ "Boolean", new Row<ElementType, bool> (ElementType.Boolean, true) }, | |
{ "Char", new Row<ElementType, bool> (ElementType.Char, true) }, | |
{ "SByte", new Row<ElementType, bool> (ElementType.I1, true) }, | |
{ "Byte", new Row<ElementType, bool> (ElementType.U1, true) }, | |
{ "Int16", new Row<ElementType, bool> (ElementType.I2, true) }, | |
{ "UInt16", new Row<ElementType, bool> (ElementType.U2, true) }, | |
{ "Int32", new Row<ElementType, bool> (ElementType.I4, true) }, | |
{ "UInt32", new Row<ElementType, bool> (ElementType.U4, true) }, | |
{ "Int64", new Row<ElementType, bool> (ElementType.I8, true) }, | |
{ "UInt64", new Row<ElementType, bool> (ElementType.U8, true) }, | |
{ "Single", new Row<ElementType, bool> (ElementType.R4, true) }, | |
{ "Double", new Row<ElementType, bool> (ElementType.R8, true) }, | |
{ "String", new Row<ElementType, bool> (ElementType.String, false) }, | |
{ "TypedReference", new Row<ElementType, bool> (ElementType.TypedByRef, false) }, | |
{ "IntPtr", new Row<ElementType, bool> (ElementType.I, true) }, | |
{ "UIntPtr", new Row<ElementType, bool> (ElementType.U, true) }, | |
{ "Object", new Row<ElementType, bool> (ElementType.Object, false) }, | |
}; | |
} | |
public static void TryProcessPrimitiveTypeReference (TypeReference type) | |
{ | |
if (type.Namespace != "System") | |
return; | |
var scope = type.scope; | |
if (scope == null || scope.MetadataScopeType != MetadataScopeType.AssemblyNameReference) | |
return; | |
Row<ElementType, bool> primitive_data; | |
if (!TryGetPrimitiveData (type, out primitive_data)) | |
return; | |
type.etype = primitive_data.Col1; | |
type.IsValueType = primitive_data.Col2; | |
} | |
public static bool TryGetPrimitiveElementType (TypeDefinition type, out ElementType etype) | |
{ | |
etype = ElementType.None; | |
if (type.Namespace != "System") | |
return false; | |
Row<ElementType, bool> primitive_data; | |
if (TryGetPrimitiveData (type, out primitive_data)) { | |
etype = primitive_data.Col1; | |
return true; | |
} | |
return false; | |
} | |
static bool TryGetPrimitiveData (TypeReference type, out Row<ElementType, bool> primitive_data) | |
{ | |
if (primitive_value_types == null) | |
InitializePrimitives (); | |
return primitive_value_types.TryGetValue (type.Name, out primitive_data); | |
} | |
public void Clear () | |
{ | |
if (NestedTypes != null) NestedTypes = new Dictionary<uint, Collection<uint>> (capacity: 0); | |
if (ReverseNestedTypes != null) ReverseNestedTypes = new Dictionary<uint, uint> (capacity: 0); | |
if (Interfaces != null) Interfaces = new Dictionary<uint, Collection<Row<uint, MetadataToken>>> (capacity: 0); | |
if (ClassLayouts != null) ClassLayouts = new Dictionary<uint, Row<ushort, uint>> (capacity: 0); | |
if (FieldLayouts != null) FieldLayouts = new Dictionary<uint, uint> (capacity: 0); | |
if (FieldRVAs != null) FieldRVAs = new Dictionary<uint, uint> (capacity: 0); | |
if (FieldMarshals != null) FieldMarshals = new Dictionary<MetadataToken, uint> (capacity: 0); | |
if (Constants != null) Constants = new Dictionary<MetadataToken, Row<ElementType, uint>> (capacity: 0); | |
if (Overrides != null) Overrides = new Dictionary<uint, Collection<MetadataToken>> (capacity: 0); | |
if (CustomAttributes != null) CustomAttributes = new Dictionary<MetadataToken, Range []> (capacity: 0); | |
if (SecurityDeclarations != null) SecurityDeclarations = new Dictionary<MetadataToken, Range []> (capacity: 0); | |
if (Events != null) Events = new Dictionary<uint, Range> (capacity: 0); | |
if (Properties != null) Properties = new Dictionary<uint, Range> (capacity: 0); | |
if (Semantics != null) Semantics = new Dictionary<uint, Row<MethodSemanticsAttributes, MetadataToken>> (capacity: 0); | |
if (PInvokes != null) PInvokes = new Dictionary<uint, Row<PInvokeAttributes, uint, uint>> (capacity: 0); | |
if (GenericParameters != null) GenericParameters = new Dictionary<MetadataToken, Range []> (capacity: 0); | |
if (GenericConstraints != null) GenericConstraints = new Dictionary<uint, Collection<MetadataToken>> (capacity: 0); | |
Documents = Empty<Document>.Array; | |
ImportScopes = Empty<ImportDebugInformation>.Array; | |
if (LocalScopes != null) LocalScopes = new Dictionary<uint, Collection<Row<uint, Range, Range, uint, uint, uint>>> (capacity: 0); | |
if (StateMachineMethods != null) StateMachineMethods = new Dictionary<uint, uint> (capacity: 0); | |
} | |
public AssemblyNameReference GetAssemblyNameReference (uint rid) | |
{ | |
if (rid < 1 || rid > AssemblyReferences.Length) | |
return null; | |
return AssemblyReferences [rid - 1]; | |
} | |
public TypeDefinition GetTypeDefinition (uint rid) | |
{ | |
if (rid < 1 || rid > Types.Length) | |
return null; | |
return Types [rid - 1]; | |
} | |
public void AddTypeDefinition (TypeDefinition type) | |
{ | |
Types [type.token.RID - 1] = type; | |
} | |
public TypeReference GetTypeReference (uint rid) | |
{ | |
if (rid < 1 || rid > TypeReferences.Length) | |
return null; | |
return TypeReferences [rid - 1]; | |
} | |
public void AddTypeReference (TypeReference type) | |
{ | |
TypeReferences [type.token.RID - 1] = type; | |
} | |
public FieldDefinition GetFieldDefinition (uint rid) | |
{ | |
if (rid < 1 || rid > Fields.Length) | |
return null; | |
return Fields [rid - 1]; | |
} | |
public void AddFieldDefinition (FieldDefinition field) | |
{ | |
Fields [field.token.RID - 1] = field; | |
} | |
public MethodDefinition GetMethodDefinition (uint rid) | |
{ | |
if (rid < 1 || rid > Methods.Length) | |
return null; | |
return Methods [rid - 1]; | |
} | |
public void AddMethodDefinition (MethodDefinition method) | |
{ | |
Methods [method.token.RID - 1] = method; | |
} | |
public MemberReference GetMemberReference (uint rid) | |
{ | |
if (rid < 1 || rid > MemberReferences.Length) | |
return null; | |
return MemberReferences [rid - 1]; | |
} | |
public void AddMemberReference (MemberReference member) | |
{ | |
MemberReferences [member.token.RID - 1] = member; | |
} | |
public bool TryGetNestedTypeMapping (TypeDefinition type, out Collection<uint> mapping) | |
{ | |
return NestedTypes.TryGetValue (type.token.RID, out mapping); | |
} | |
public void SetNestedTypeMapping (uint type_rid, Collection<uint> mapping) | |
{ | |
NestedTypes [type_rid] = mapping; | |
} | |
public void RemoveNestedTypeMapping (TypeDefinition type) | |
{ | |
NestedTypes.Remove (type.token.RID); | |
} | |
public bool TryGetReverseNestedTypeMapping (TypeDefinition type, out uint declaring) | |
{ | |
return ReverseNestedTypes.TryGetValue (type.token.RID, out declaring); | |
} | |
public void SetReverseNestedTypeMapping (uint nested, uint declaring) | |
{ | |
ReverseNestedTypes [nested] = declaring; | |
} | |
public void RemoveReverseNestedTypeMapping (TypeDefinition type) | |
{ | |
ReverseNestedTypes.Remove (type.token.RID); | |
} | |
public bool TryGetInterfaceMapping (TypeDefinition type, out Collection<Row<uint, MetadataToken>> mapping) | |
{ | |
return Interfaces.TryGetValue (type.token.RID, out mapping); | |
} | |
public void SetInterfaceMapping (uint type_rid, Collection<Row<uint, MetadataToken>> mapping) | |
{ | |
Interfaces [type_rid] = mapping; | |
} | |
public void RemoveInterfaceMapping (TypeDefinition type) | |
{ | |
Interfaces.Remove (type.token.RID); | |
} | |
public void AddPropertiesRange (uint type_rid, Range range) | |
{ | |
Properties.Add (type_rid, range); | |
} | |
public bool TryGetPropertiesRange (TypeDefinition type, out Range range) | |
{ | |
return Properties.TryGetValue (type.token.RID, out range); | |
} | |
public void RemovePropertiesRange (TypeDefinition type) | |
{ | |
Properties.Remove (type.token.RID); | |
} | |
public void AddEventsRange (uint type_rid, Range range) | |
{ | |
Events.Add (type_rid, range); | |
} | |
public bool TryGetEventsRange (TypeDefinition type, out Range range) | |
{ | |
return Events.TryGetValue (type.token.RID, out range); | |
} | |
public void RemoveEventsRange (TypeDefinition type) | |
{ | |
Events.Remove (type.token.RID); | |
} | |
public bool TryGetGenericParameterRanges (IGenericParameterProvider owner, out Range [] ranges) | |
{ | |
return GenericParameters.TryGetValue (owner.MetadataToken, out ranges); | |
} | |
public void RemoveGenericParameterRange (IGenericParameterProvider owner) | |
{ | |
GenericParameters.Remove (owner.MetadataToken); | |
} | |
public bool TryGetCustomAttributeRanges (ICustomAttributeProvider owner, out Range [] ranges) | |
{ | |
return CustomAttributes.TryGetValue (owner.MetadataToken, out ranges); | |
} | |
public void RemoveCustomAttributeRange (ICustomAttributeProvider owner) | |
{ | |
CustomAttributes.Remove (owner.MetadataToken); | |
} | |
public bool TryGetSecurityDeclarationRanges (ISecurityDeclarationProvider owner, out Range [] ranges) | |
{ | |
return SecurityDeclarations.TryGetValue (owner.MetadataToken, out ranges); | |
} | |
public void RemoveSecurityDeclarationRange (ISecurityDeclarationProvider owner) | |
{ | |
SecurityDeclarations.Remove (owner.MetadataToken); | |
} | |
public bool TryGetGenericConstraintMapping (GenericParameter generic_parameter, out Collection<MetadataToken> mapping) | |
{ | |
return GenericConstraints.TryGetValue (generic_parameter.token.RID, out mapping); | |
} | |
public void SetGenericConstraintMapping (uint gp_rid, Collection<MetadataToken> mapping) | |
{ | |
GenericConstraints [gp_rid] = mapping; | |
} | |
public void RemoveGenericConstraintMapping (GenericParameter generic_parameter) | |
{ | |
GenericConstraints.Remove (generic_parameter.token.RID); | |
} | |
public bool TryGetOverrideMapping (MethodDefinition method, out Collection<MetadataToken> mapping) | |
{ | |
return Overrides.TryGetValue (method.token.RID, out mapping); | |
} | |
public void SetOverrideMapping (uint rid, Collection<MetadataToken> mapping) | |
{ | |
Overrides [rid] = mapping; | |
} | |
public void RemoveOverrideMapping (MethodDefinition method) | |
{ | |
Overrides.Remove (method.token.RID); | |
} | |
public Document GetDocument (uint rid) | |
{ | |
if (rid < 1 || rid > Documents.Length) | |
return null; | |
return Documents [rid - 1]; | |
} | |
public bool TryGetLocalScopes (MethodDefinition method, out Collection<Row<uint, Range, Range, uint, uint, uint>> scopes) | |
{ | |
return LocalScopes.TryGetValue (method.MetadataToken.RID, out scopes); | |
} | |
public void SetLocalScopes (uint method_rid, Collection<Row<uint, Range, Range, uint, uint, uint>> records) | |
{ | |
LocalScopes [method_rid] = records; | |
} | |
public ImportDebugInformation GetImportScope (uint rid) | |
{ | |
if (rid < 1 || rid > ImportScopes.Length) | |
return null; | |
return ImportScopes [rid - 1]; | |
} | |
public bool TryGetStateMachineKickOffMethod (MethodDefinition method, out uint rid) | |
{ | |
return StateMachineMethods.TryGetValue (method.MetadataToken.RID, out rid); | |
} | |
public TypeDefinition GetFieldDeclaringType (uint field_rid) | |
{ | |
return BinaryRangeSearch (Types, field_rid, true); | |
} | |
public TypeDefinition GetMethodDeclaringType (uint method_rid) | |
{ | |
return BinaryRangeSearch (Types, method_rid, false); | |
} | |
static TypeDefinition BinaryRangeSearch (TypeDefinition [] types, uint rid, bool field) | |
{ | |
int min = 0; | |
int max = types.Length - 1; | |
while (min <= max) { | |
int mid = min + ((max - min) / 2); | |
var type = types [mid]; | |
var range = field ? type.fields_range : type.methods_range; | |
if (rid < range.Start) | |
max = mid - 1; | |
else if (rid >= range.Start + range.Length) | |
min = mid + 1; | |
else | |
return type; | |
} | |
return null; | |
} | |
} | |
} | |
} | |
#endregion | |
#region Mono.Cecil\*.cs | |
namespace Internal { | |
// | |
// Author: | |
// Jb Evain (jbevain@gmail.com) | |
// | |
// Copyright (c) 2008 - 2015 Jb Evain | |
// Copyright (c) 2008 - 2011 Novell, Inc. | |
// | |
// Licensed under the MIT/X11 license. | |
// | |
using System; | |
namespace Mono.Cecil { | |
[Flags] | |
internal enum MethodAttributes : ushort { | |
MemberAccessMask = 0x0007, | |
CompilerControlled = 0x0000, // Member not referenceable | |
Private = 0x0001, // Accessible only by the parent type | |
FamANDAssem = 0x0002, // Accessible by sub-types only in this Assembly | |
Assembly = 0x0003, // Accessibly by anyone in the Assembly | |
Family = 0x0004, // Accessible only by type and sub-types | |
FamORAssem = 0x0005, // Accessibly by sub-types anywhere, plus anyone in assembly | |
Public = 0x0006, // Accessibly by anyone who has visibility to this scope | |
Static = 0x0010, // Defined on type, else per instance | |
Final = 0x0020, // Method may not be overridden | |
Virtual = 0x0040, // Method is virtual | |
HideBySig = 0x0080, // Method hides by name+sig, else just by name | |
VtableLayoutMask = 0x0100, // Use this mask to retrieve vtable attributes | |
ReuseSlot = 0x0000, // Method reuses existing slot in vtable | |
NewSlot = 0x0100, // Method always gets a new slot in the vtable | |
CheckAccessOnOverride = 0x0200, // Method can only be overriden if also accessible | |
Abstract = 0x0400, // Method does not provide an implementation | |
SpecialName = 0x0800, // Method is special | |
// Interop Attributes | |
PInvokeImpl = 0x2000, // Implementation is forwarded through PInvoke | |
UnmanagedExport = 0x0008, // Reserved: shall be zero for conforming implementations | |
// Additional flags | |
RTSpecialName = 0x1000, // CLI provides 'special' behavior, depending upon the name of the method | |
HasSecurity = 0x4000, // Method has security associate with it | |
RequireSecObject = 0x8000 // Method calls another method containing security code | |
} | |
} | |
} | |
#endregion | |
#region Mono.Cecil\*.cs | |
namespace Internal { | |
// | |
// Author: | |
// Jb Evain (jbevain@gmail.com) | |
// | |
// Copyright (c) 2008 - 2015 Jb Evain | |
// Copyright (c) 2008 - 2011 Novell, Inc. | |
// | |
// Licensed under the MIT/X11 license. | |
// | |
namespace Mono.Cecil { | |
internal enum MethodCallingConvention : byte { | |
Default = 0x0, | |
C = 0x1, | |
StdCall = 0x2, | |
ThisCall = 0x3, | |
FastCall = 0x4, | |
VarArg = 0x5, | |
Generic = 0x10, | |
} | |
} | |
} | |
#endregion | |
#region Mono.Cecil\*.cs | |
namespace Internal { | |
// | |
// Author: | |
// Jb Evain (jbevain@gmail.com) | |
// | |
// Copyright (c) 2008 - 2015 Jb Evain | |
// Copyright (c) 2008 - 2011 Novell, Inc. | |
// | |
// Licensed under the MIT/X11 license. | |
// | |
using System; | |
using Mono.Cecil.Cil; | |
using Mono.Collections.Generic; | |
using RVA = System.UInt32; | |
namespace Mono.Cecil { | |
internal sealed class MethodDefinition : MethodReference, IMemberDefinition, ISecurityDeclarationProvider, ICustomDebugInformationProvider { | |
ushort attributes; | |
ushort impl_attributes; | |
internal volatile bool sem_attrs_ready; | |
internal MethodSemanticsAttributes sem_attrs; | |
Collection<CustomAttribute> custom_attributes; | |
Collection<SecurityDeclaration> security_declarations; | |
internal RVA rva; | |
internal PInvokeInfo pinvoke; | |
Collection<MethodReference> overrides; | |
internal MethodBody body; | |
internal MethodDebugInformation debug_info; | |
internal Collection<CustomDebugInformation> custom_infos; | |
public override string Name { | |
get { return base.Name; } | |
set { | |
if (IsWindowsRuntimeProjection && value != base.Name) | |
throw new InvalidOperationException (); | |
base.Name = value; | |
} | |
} | |
public MethodAttributes Attributes { | |
get { return (MethodAttributes) attributes; } | |
set { | |
if (IsWindowsRuntimeProjection && (ushort) value != attributes) | |
throw new InvalidOperationException (); | |
attributes = (ushort) value; | |
} | |
} | |
public MethodImplAttributes ImplAttributes { | |
get { return (MethodImplAttributes) impl_attributes; } | |
set { | |
if (IsWindowsRuntimeProjection && (ushort) value != impl_attributes) | |
throw new InvalidOperationException (); | |
impl_attributes = (ushort) value; | |
} | |
} | |
public MethodSemanticsAttributes SemanticsAttributes { | |
get { | |
if (sem_attrs_ready) | |
return sem_attrs; | |
if (HasImage) { | |
ReadSemantics (); | |
return sem_attrs; | |
} | |
sem_attrs = MethodSemanticsAttributes.None; | |
sem_attrs_ready = true; | |
return sem_attrs; | |
} | |
set { sem_attrs = value; } | |
} | |
internal new MethodDefinitionProjection WindowsRuntimeProjection { | |
get { return (MethodDefinitionProjection) projection; } | |
set { projection = value; } | |
} | |
internal void ReadSemantics () | |
{ | |
if (sem_attrs_ready) | |
return; | |
var module = this.Module; | |
if (module == null) | |
return; | |
if (!module.HasImage) | |
return; | |
module.Read (this, (method, reader) => reader.ReadAllSemantics (method)); | |
} | |
public bool HasSecurityDeclarations { | |
get { | |
if (security_declarations != null) | |
return security_declarations.Count > 0; | |
return this.GetHasSecurityDeclarations (Module); | |
} | |
} | |
public Collection<SecurityDeclaration> SecurityDeclarations { | |
get { return security_declarations ?? (this.GetSecurityDeclarations (ref security_declarations, Module)); } | |
} | |
public bool HasCustomAttributes { | |
get { | |
if (custom_attributes != null) | |
return custom_attributes.Count > 0; | |
return this.GetHasCustomAttributes (Module); | |
} | |
} | |
public Collection<CustomAttribute> CustomAttributes { | |
get { return custom_attributes ?? (this.GetCustomAttributes (ref custom_attributes, Module)); } | |
} | |
public int RVA { | |
get { return (int) rva; } | |
} | |
public bool HasBody { | |
get { | |
return (attributes & (ushort) MethodAttributes.Abstract) == 0 && | |
(attributes & (ushort) MethodAttributes.PInvokeImpl) == 0 && | |
(impl_attributes & (ushort) MethodImplAttributes.InternalCall) == 0 && | |
(impl_attributes & (ushort) MethodImplAttributes.Native) == 0 && | |
(impl_attributes & (ushort) MethodImplAttributes.Unmanaged) == 0 && | |
(impl_attributes & (ushort) MethodImplAttributes.Runtime) == 0; | |
} | |
} | |
public MethodBody Body { | |
get { | |
var local = this.body; | |
if (local != null) | |
return local; | |
if (!HasBody) | |
return null; | |
if (HasImage && rva != 0) | |
return Module.Read (ref body, this, (method, reader) => reader.ReadMethodBody (method)); | |
return body = new MethodBody (this); | |
} | |
set { | |
var module = this.Module; | |
if (module == null) { | |
body = value; | |
return; | |
} | |
// we reset Body to null in ILSpy to save memory; so we need that operation to be thread-safe | |
lock (module.SyncRoot) { | |
body = value; | |
if (value == null) | |
this.debug_info = null; | |
} | |
} | |
} | |
public MethodDebugInformation DebugInformation { | |
get { | |
Mixin.Read (Body); | |
if (debug_info != null) | |
return debug_info; | |
return debug_info ?? (debug_info = new MethodDebugInformation (this)); | |
} | |
} | |
public bool HasPInvokeInfo { | |
get { | |
if (pinvoke != null) | |
return true; | |
return IsPInvokeImpl; | |
} | |
} | |
public PInvokeInfo PInvokeInfo { | |
get { | |
if (pinvoke != null) | |
return pinvoke; | |
if (HasImage && IsPInvokeImpl) | |
return Module.Read (ref pinvoke, this, (method, reader) => reader.ReadPInvokeInfo (method)); | |
return null; | |
} | |
set { | |
IsPInvokeImpl = true; | |
pinvoke = value; | |
} | |
} | |
public bool HasOverrides { | |
get { | |
if (overrides != null) | |
return overrides.Count > 0; | |
return HasImage && Module.Read (this, (method, reader) => reader.HasOverrides (method)); | |
} | |
} | |
public Collection<MethodReference> Overrides { | |
get { | |
if (overrides != null) | |
return overrides; | |
if (HasImage) | |
return Module.Read (ref overrides, this, (method, reader) => reader.ReadOverrides (method)); | |
return overrides = new Collection<MethodReference> (); | |
} | |
} | |
public override bool HasGenericParameters { | |
get { | |
if (generic_parameters != null) | |
return generic_parameters.Count > 0; | |
return this.GetHasGenericParameters (Module); | |
} | |
} | |
public override Collection<GenericParameter> GenericParameters { | |
get { return generic_parameters ?? (this.GetGenericParameters (ref generic_parameters, Module)); } | |
} | |
public bool HasCustomDebugInformations { | |
get { | |
Mixin.Read (Body); | |
return !custom_infos.IsNullOrEmpty (); | |
} | |
} | |
public Collection<CustomDebugInformation> CustomDebugInformations { | |
get { | |
Mixin.Read (Body); | |
return custom_infos ?? (custom_infos = new Collection<CustomDebugInformation> ()); | |
} | |
} | |
#region MethodAttributes | |
public bool IsCompilerControlled { | |
get { return attributes.GetMaskedAttributes ((ushort) MethodAttributes.MemberAccessMask, (ushort) MethodAttributes.CompilerControlled); } | |
set { attributes = attributes.SetMaskedAttributes ((ushort) MethodAttributes.MemberAccessMask, (ushort) MethodAttributes.CompilerControlled, value); } | |
} | |
public bool IsPrivate { | |
get { return attributes.GetMaskedAttributes ((ushort) MethodAttributes.MemberAccessMask, (ushort) MethodAttributes.Private); } | |
set { attributes = attributes.SetMaskedAttributes ((ushort) MethodAttributes.MemberAccessMask, (ushort) MethodAttributes.Private, value); } | |
} | |
public bool IsFamilyAndAssembly { | |
get { return attributes.GetMaskedAttributes ((ushort) MethodAttributes.MemberAccessMask, (ushort) MethodAttributes.FamANDAssem); } | |
set { attributes = attributes.SetMaskedAttributes ((ushort) MethodAttributes.MemberAccessMask, (ushort) MethodAttributes.FamANDAssem, value); } | |
} | |
public bool IsAssembly { | |
get { return attributes.GetMaskedAttributes ((ushort) MethodAttributes.MemberAccessMask, (ushort) MethodAttributes.Assembly); } | |
set { attributes = attributes.SetMaskedAttributes ((ushort) MethodAttributes.MemberAccessMask, (ushort) MethodAttributes.Assembly, value); } | |
} | |
public bool IsFamily { | |
get { return attributes.GetMaskedAttributes ((ushort) MethodAttributes.MemberAccessMask, (ushort) MethodAttributes.Family); } | |
set { attributes = attributes.SetMaskedAttributes ((ushort) MethodAttributes.MemberAccessMask, (ushort) MethodAttributes.Family, value); } | |
} | |
public bool IsFamilyOrAssembly { | |
get { return attributes.GetMaskedAttributes ((ushort) MethodAttributes.MemberAccessMask, (ushort) MethodAttributes.FamORAssem); } | |
set { attributes = attributes.SetMaskedAttributes ((ushort) MethodAttributes.MemberAccessMask, (ushort) MethodAttributes.FamORAssem, value); } | |
} | |
public bool IsPublic { | |
get { return attributes.GetMaskedAttributes ((ushort) MethodAttributes.MemberAccessMask, (ushort) MethodAttributes.Public); } | |
set { attributes = attributes.SetMaskedAttributes ((ushort) MethodAttributes.MemberAccessMask, (ushort) MethodAttributes.Public, value); } | |
} | |
public bool IsStatic { | |
get { return attributes.GetAttributes ((ushort) MethodAttributes.Static); } | |
set { attributes = attributes.SetAttributes ((ushort) MethodAttributes.Static, value); } | |
} | |
public bool IsFinal { | |
get { return attributes.GetAttributes ((ushort) MethodAttributes.Final); } | |
set { attributes = attributes.SetAttributes ((ushort) MethodAttributes.Final, value); } | |
} | |
public bool IsVirtual { | |
get { return attributes.GetAttributes ((ushort) MethodAttributes.Virtual); } | |
set { attributes = attributes.SetAttributes ((ushort) MethodAttributes.Virtual, value); } | |
} | |
public bool IsHideBySig { | |
get { return attributes.GetAttributes ((ushort) MethodAttributes.HideBySig); } | |
set { attributes = attributes.SetAttributes ((ushort) MethodAttributes.HideBySig, value); } | |
} | |
public bool IsReuseSlot { | |
get { return attributes.GetMaskedAttributes ((ushort) MethodAttributes.VtableLayoutMask, (ushort) MethodAttributes.ReuseSlot); } | |
set { attributes = attributes.SetMaskedAttributes ((ushort) MethodAttributes.VtableLayoutMask, (ushort) MethodAttributes.ReuseSlot, value); } | |
} | |
public bool IsNewSlot { | |
get { return attributes.GetMaskedAttributes ((ushort) MethodAttributes.VtableLayoutMask, (ushort) MethodAttributes.NewSlot); } | |
set { attributes = attributes.SetMaskedAttributes ((ushort) MethodAttributes.VtableLayoutMask, (ushort) MethodAttributes.NewSlot, value); } | |
} | |
public bool IsCheckAccessOnOverride { | |
get { return attributes.GetAttributes ((ushort) MethodAttributes.CheckAccessOnOverride); } | |
set { attributes = attributes.SetAttributes ((ushort) MethodAttributes.CheckAccessOnOverride, value); } | |
} | |
public bool IsAbstract { | |
get { return attributes.GetAttributes ((ushort) MethodAttributes.Abstract); } | |
set { attributes = attributes.SetAttributes ((ushort) MethodAttributes.Abstract, value); } | |
} | |
public bool IsSpecialName { | |
get { return attributes.GetAttributes ((ushort) MethodAttributes.SpecialName); } | |
set { attributes = attributes.SetAttributes ((ushort) MethodAttributes.SpecialName, value); } | |
} | |
public bool IsPInvokeImpl { | |
get { return attributes.GetAttributes ((ushort) MethodAttributes.PInvokeImpl); } | |
set { attributes = attributes.SetAttributes ((ushort) MethodAttributes.PInvokeImpl, value); } | |
} | |
public bool IsUnmanagedExport { | |
get { return attributes.GetAttributes ((ushort) MethodAttributes.UnmanagedExport); } | |
set { attributes = attributes.SetAttributes ((ushort) MethodAttributes.UnmanagedExport, value); } | |
} | |
public bool IsRuntimeSpecialName { | |
get { return attributes.GetAttributes ((ushort) MethodAttributes.RTSpecialName); } | |
set { attributes = attributes.SetAttributes ((ushort) MethodAttributes.RTSpecialName, value); } | |
} | |
public bool HasSecurity { | |
get { return attributes.GetAttributes ((ushort) MethodAttributes.HasSecurity); } | |
set { attributes = attributes.SetAttributes ((ushort) MethodAttributes.HasSecurity, value); } | |
} | |
#endregion | |
#region MethodImplAttributes | |
public bool IsIL { | |
get { return impl_attributes.GetMaskedAttributes ((ushort) MethodImplAttributes.CodeTypeMask, (ushort) MethodImplAttributes.IL); } | |
set { impl_attributes = impl_attributes.SetMaskedAttributes ((ushort) MethodImplAttributes.CodeTypeMask, (ushort) MethodImplAttributes.IL, value); } | |
} | |
public bool IsNative { | |
get { return impl_attributes.GetMaskedAttributes ((ushort) MethodImplAttributes.CodeTypeMask, (ushort) MethodImplAttributes.Native); } | |
set { impl_attributes = impl_attributes.SetMaskedAttributes ((ushort) MethodImplAttributes.CodeTypeMask, (ushort) MethodImplAttributes.Native, value); } | |
} | |
public bool IsRuntime { | |
get { return impl_attributes.GetMaskedAttributes ((ushort) MethodImplAttributes.CodeTypeMask, (ushort) MethodImplAttributes.Runtime); } | |
set { impl_attributes = impl_attributes.SetMaskedAttributes ((ushort) MethodImplAttributes.CodeTypeMask, (ushort) MethodImplAttributes.Runtime, value); } | |
} | |
public bool IsUnmanaged { | |
get { return impl_attributes.GetMaskedAttributes ((ushort) MethodImplAttributes.ManagedMask, (ushort) MethodImplAttributes.Unmanaged); } | |
set { impl_attributes = impl_attributes.SetMaskedAttributes ((ushort) MethodImplAttributes.ManagedMask, (ushort) MethodImplAttributes.Unmanaged, value); } | |
} | |
public bool IsManaged { | |
get { return impl_attributes.GetMaskedAttributes ((ushort) MethodImplAttributes.ManagedMask, (ushort) MethodImplAttributes.Managed); } | |
set { impl_attributes = impl_attributes.SetMaskedAttributes ((ushort) MethodImplAttributes.ManagedMask, (ushort) MethodImplAttributes.Managed, value); } | |
} | |
public bool IsForwardRef { | |
get { return impl_attributes.GetAttributes ((ushort) MethodImplAttributes.ForwardRef); } | |
set { impl_attributes = impl_attributes.SetAttributes ((ushort) MethodImplAttributes.ForwardRef, value); } | |
} | |
public bool IsPreserveSig { | |
get { return impl_attributes.GetAttributes ((ushort) MethodImplAttributes.PreserveSig); } | |
set { impl_attributes = impl_attributes.SetAttributes ((ushort) MethodImplAttributes.PreserveSig, value); } | |
} | |
public bool IsInternalCall { | |
get { return impl_attributes.GetAttributes ((ushort) MethodImplAttributes.InternalCall); } | |
set { impl_attributes = impl_attributes.SetAttributes ((ushort) MethodImplAttributes.InternalCall, value); } | |
} | |
public bool IsSynchronized { | |
get { return impl_attributes.GetAttributes ((ushort) MethodImplAttributes.Synchronized); } | |
set { impl_attributes = impl_attributes.SetAttributes ((ushort) MethodImplAttributes.Synchronized, value); } | |
} | |
public bool NoInlining { | |
get { return impl_attributes.GetAttributes ((ushort) MethodImplAttributes.NoInlining); } | |
set { impl_attributes = impl_attributes.SetAttributes ((ushort) MethodImplAttributes.NoInlining, value); } | |
} | |
public bool NoOptimization { | |
get { return impl_attributes.GetAttributes ((ushort) MethodImplAttributes.NoOptimization); } | |
set { impl_attributes = impl_attributes.SetAttributes ((ushort) MethodImplAttributes.NoOptimization, value); } | |
} | |
public bool AggressiveInlining { | |
get { return impl_attributes.GetAttributes ((ushort) MethodImplAttributes.AggressiveInlining); } | |
set { impl_attributes = impl_attributes.SetAttributes ((ushort) MethodImplAttributes.AggressiveInlining, value); } | |
} | |
#endregion | |
#region MethodSemanticsAttributes | |
public bool IsSetter { | |
get { return this.GetSemantics (MethodSemanticsAttributes.Setter); } | |
set { this.SetSemantics (MethodSemanticsAttributes.Setter, value); } | |
} | |
public bool IsGetter { | |
get { return this.GetSemantics (MethodSemanticsAttributes.Getter); } | |
set { this.SetSemantics (MethodSemanticsAttributes.Getter, value); } | |
} | |
public bool IsOther { | |
get { return this.GetSemantics (MethodSemanticsAttributes.Other); } | |
set { this.SetSemantics (MethodSemanticsAttributes.Other, value); } | |
} | |
public bool IsAddOn { | |
get { return this.GetSemantics (MethodSemanticsAttributes.AddOn); } | |
set { this.SetSemantics (MethodSemanticsAttributes.AddOn, value); } | |
} | |
public bool IsRemoveOn { | |
get { return this.GetSemantics (MethodSemanticsAttributes.RemoveOn); } | |
set { this.SetSemantics (MethodSemanticsAttributes.RemoveOn, value); } | |
} | |
public bool IsFire { | |
get { return this.GetSemantics (MethodSemanticsAttributes.Fire); } | |
set { this.SetSemantics (MethodSemanticsAttributes.Fire, value); } | |
} | |
#endregion | |
public new TypeDefinition DeclaringType { | |
get { return (TypeDefinition) base.DeclaringType; } | |
set { base.DeclaringType = value; } | |
} | |
public bool IsConstructor { | |
get { | |
return this.IsRuntimeSpecialName | |
&& this.IsSpecialName | |
&& (this.Name == ".cctor" || this.Name == ".ctor"); | |
} | |
} | |
public override bool IsDefinition { | |
get { return true; } | |
} | |
internal MethodDefinition () | |
{ | |
this.token = new MetadataToken (TokenType.Method); | |
} | |
public MethodDefinition (string name, MethodAttributes attributes, TypeReference returnType) | |
: base (name, returnType) | |
{ | |
this.attributes = (ushort) attributes; | |
this.HasThis = !this.IsStatic; | |
this.token = new MetadataToken (TokenType.Method); | |
} | |
public override MethodDefinition Resolve () | |
{ | |
return this; | |
} | |
} | |
static partial class Mixin { | |
public static ParameterDefinition GetParameter (this MethodBody self, int index) | |
{ | |
var method = self.method; | |
if (method.HasThis) { | |
if (index == 0) | |
return self.ThisParameter; | |
index--; | |
} | |
var parameters = method.Parameters; | |
if (index < 0 || index >= parameters.size) | |
return null; | |
return parameters [index]; | |
} | |
public static VariableDefinition GetVariable (this MethodBody self, int index) | |
{ | |
var variables = self.Variables; | |
if (index < 0 || index >= variables.size) | |
return null; | |
return variables [index]; | |
} | |
public static bool GetSemantics (this MethodDefinition self, MethodSemanticsAttributes semantics) | |
{ | |
return (self.SemanticsAttributes & semantics) != 0; | |
} | |
public static void SetSemantics (this MethodDefinition self, MethodSemanticsAttributes semantics, bool value) | |
{ | |
if (value) | |
self.SemanticsAttributes |= semantics; | |
else | |
self.SemanticsAttributes &= ~semantics; | |
} | |
} | |
} | |
} | |
#endregion | |
#region Mono.Cecil\*.cs | |
namespace Internal { | |
// | |
// Author: | |
// Jb Evain (jbevain@gmail.com) | |
// | |
// Copyright (c) 2008 - 2015 Jb Evain | |
// Copyright (c) 2008 - 2011 Novell, Inc. | |
// | |
// Licensed under the MIT/X11 license. | |
// | |
using System; | |
namespace Mono.Cecil { | |
[Flags] | |
internal enum MethodImplAttributes : ushort { | |
CodeTypeMask = 0x0003, | |
IL = 0x0000, // Method impl is CIL | |
Native = 0x0001, // Method impl is native | |
OPTIL = 0x0002, // Reserved: shall be zero in conforming implementations | |
Runtime = 0x0003, // Method impl is provided by the runtime | |
ManagedMask = 0x0004, // Flags specifying whether the code is managed or unmanaged | |
Unmanaged = 0x0004, // Method impl is unmanaged, otherwise managed | |
Managed = 0x0000, // Method impl is managed | |
// Implementation info and interop | |
ForwardRef = 0x0010, // Indicates method is defined; used primarily in merge scenarios | |
PreserveSig = 0x0080, // Reserved: conforming implementations may ignore | |
InternalCall = 0x1000, // Reserved: shall be zero in conforming implementations | |
Synchronized = 0x0020, // Method is single threaded through the body | |
NoOptimization = 0x0040, // Method is not optimized by the JIT. | |
NoInlining = 0x0008, // Method may not be inlined | |
AggressiveInlining = 0x0100, // Method should be inlined, if possible. | |
} | |
} | |
} | |
#endregion | |
#region Mono.Cecil\*.cs | |
namespace Internal { | |
// | |
// Author: | |
// Jb Evain (jbevain@gmail.com) | |
// | |
// Copyright (c) 2008 - 2015 Jb Evain | |
// Copyright (c) 2008 - 2011 Novell, Inc. | |
// | |
// Licensed under the MIT/X11 license. | |
// | |
using System; | |
using System.Text; | |
using Mono.Collections.Generic; | |
namespace Mono.Cecil { | |
internal class MethodReference : MemberReference, IMethodSignature, IGenericParameterProvider, IGenericContext { | |
internal ParameterDefinitionCollection parameters; | |
MethodReturnType return_type; | |
bool has_this; | |
bool explicit_this; | |
MethodCallingConvention calling_convention; | |
internal Collection<GenericParameter> generic_parameters; | |
public virtual bool HasThis { | |
get { return has_this; } | |
set { has_this = value; } | |
} | |
public virtual bool ExplicitThis { | |
get { return explicit_this; } | |
set { explicit_this = value; } | |
} | |
public virtual MethodCallingConvention CallingConvention { | |
get { return calling_convention; } | |
set { calling_convention = value; } | |
} | |
public virtual bool HasParameters { | |
get { return !parameters.IsNullOrEmpty (); } | |
} | |
public virtual Collection<ParameterDefinition> Parameters { | |
get { | |
if (parameters == null) | |
parameters = new ParameterDefinitionCollection (this); | |
return parameters; | |
} | |
} | |
IGenericParameterProvider IGenericContext.Type { | |
get { | |
var declaring_type = this.DeclaringType; | |
var instance = declaring_type as GenericInstanceType; | |
if (instance != null) | |
return instance.ElementType; | |
return declaring_type; | |
} | |
} | |
IGenericParameterProvider IGenericContext.Method { | |
get { return this; } | |
} | |
GenericParameterType IGenericParameterProvider.GenericParameterType { | |
get { return GenericParameterType.Method; } | |
} | |
public virtual bool HasGenericParameters { | |
get { return !generic_parameters.IsNullOrEmpty (); } | |
} | |
public virtual Collection<GenericParameter> GenericParameters { | |
get { | |
if (generic_parameters != null) | |
return generic_parameters; | |
return generic_parameters = new GenericParameterCollection (this); | |
} | |
} | |
public TypeReference ReturnType { | |
get { | |
var return_type = MethodReturnType; | |
return return_type != null ? return_type.ReturnType : null; | |
} | |
set { | |
var return_type = MethodReturnType; | |
if (return_type != null) | |
return_type.ReturnType = value; | |
} | |
} | |
public virtual MethodReturnType MethodReturnType { | |
get { return return_type; } | |
set { return_type = value; } | |
} | |
public override string FullName { | |
get { | |
var builder = new StringBuilder (); | |
builder.Append (ReturnType.FullName) | |
.Append (" ") | |
.Append (MemberFullName ()); | |
this.MethodSignatureFullName (builder); | |
return builder.ToString (); | |
} | |
} | |
public virtual bool IsGenericInstance { | |
get { return false; } | |
} | |
public override bool ContainsGenericParameter { | |
get { | |
if (this.ReturnType.ContainsGenericParameter || base.ContainsGenericParameter) | |
return true; | |
if (!HasParameters) | |
return false; | |
var parameters = this.Parameters; | |
for (int i = 0; i < parameters.Count; i++) | |
if (parameters [i].ParameterType.ContainsGenericParameter) | |
return true; | |
return false; | |
} | |
} | |
internal MethodReference () | |
{ | |
this.return_type = new MethodReturnType (this); | |
this.token = new MetadataToken (TokenType.MemberRef); | |
} | |
public MethodReference (string name, TypeReference returnType) | |
: base (name) | |
{ | |
Mixin.CheckType (returnType, Mixin.Argument.returnType); | |
this.return_type = new MethodReturnType (this); | |
this.return_type.ReturnType = returnType; | |
this.token = new MetadataToken (TokenType.MemberRef); | |
} | |
public MethodReference (string name, TypeReference returnType, TypeReference declaringType) | |
: this (name, returnType) | |
{ | |
Mixin.CheckType (declaringType, Mixin.Argument.declaringType); | |
this.DeclaringType = declaringType; | |
} | |
public virtual MethodReference GetElementMethod () | |
{ | |
return this; | |
} | |
protected override IMemberDefinition ResolveDefinition () | |
{ | |
return this.Resolve (); | |
} | |
public new virtual MethodDefinition Resolve () | |
{ | |
var module = this.Module; | |
if (module == null) | |
throw new NotSupportedException (); | |
return module.Resolve (this); | |
} | |
} | |
static partial class Mixin { | |
public static bool IsVarArg (this IMethodSignature self) | |
{ | |
return (self.CallingConvention & MethodCallingConvention.VarArg) != 0; | |
} | |
public static int GetSentinelPosition (this IMethodSignature self) | |
{ | |
if (!self.HasParameters) | |
return -1; | |
var parameters = self.Parameters; | |
for (int i = 0; i < parameters.Count; i++) | |
if (parameters [i].ParameterType.IsSentinel) | |
return i; | |
return -1; | |
} | |
} | |
} | |
} | |
#endregion | |
#region Mono.Cecil\*.cs | |
namespace Internal { | |
// | |
// Author: | |
// Jb Evain (jbevain@gmail.com) | |
// | |
// Copyright (c) 2008 - 2015 Jb Evain | |
// Copyright (c) 2008 - 2011 Novell, Inc. | |
// | |
// Licensed under the MIT/X11 license. | |
// | |
using System.Threading; | |
using Mono.Collections.Generic; | |
namespace Mono.Cecil { | |
internal sealed class MethodReturnType : IConstantProvider, ICustomAttributeProvider, IMarshalInfoProvider { | |
internal IMethodSignature method; | |
internal ParameterDefinition parameter; | |
TypeReference return_type; | |
public IMethodSignature Method { | |
get { return method; } | |
} | |
public TypeReference ReturnType { | |
get { return return_type; } | |
set { return_type = value; } | |
} | |
internal ParameterDefinition Parameter { | |
get { | |
if (parameter == null) | |
Interlocked.CompareExchange (ref parameter, new ParameterDefinition (return_type, method), null); | |
return parameter; | |
} | |
} | |
public MetadataToken MetadataToken { | |
get { return Parameter.MetadataToken; } | |
set { Parameter.MetadataToken = value; } | |
} | |
public ParameterAttributes Attributes { | |
get { return Parameter.Attributes; } | |
set { Parameter.Attributes = value; } | |
} | |
public string Name { | |
get { return Parameter.Name; } | |
set { Parameter.Name = value; } | |
} | |
public bool HasCustomAttributes { | |
get { return parameter != null && parameter.HasCustomAttributes; } | |
} | |
public Collection<CustomAttribute> CustomAttributes { | |
get { return Parameter.CustomAttributes; } | |
} | |
public bool HasDefault { | |
get { return parameter != null && parameter.HasDefault; } | |
set { Parameter.HasDefault = value; } | |
} | |
public bool HasConstant { | |
get { return parameter != null && parameter.HasConstant; } | |
set { Parameter.HasConstant = value; } | |
} | |
public object Constant { | |
get { return Parameter.Constant; } | |
set { Parameter.Constant = value; } | |
} | |
public bool HasFieldMarshal { | |
get { return parameter != null && parameter.HasFieldMarshal; } | |
set { Parameter.HasFieldMarshal = value; } | |
} | |
public bool HasMarshalInfo { | |
get { return parameter != null && parameter.HasMarshalInfo; } | |
} | |
public MarshalInfo MarshalInfo { | |
get { return Parameter.MarshalInfo; } | |
set { Parameter.MarshalInfo = value; } | |
} | |
public MethodReturnType (IMethodSignature method) | |
{ | |
this.method = method; | |
} | |
} | |
} | |
} | |
#endregion | |
#region Mono.Cecil\*.cs | |
namespace Internal { | |
// | |
// Author: | |
// Jb Evain (jbevain@gmail.com) | |
// | |
// Copyright (c) 2008 - 2015 Jb Evain | |
// Copyright (c) 2008 - 2011 Novell, Inc. | |
// | |
// Licensed under the MIT/X11 license. | |
// | |
using System; | |
namespace Mono.Cecil { | |
[Flags] | |
internal enum MethodSemanticsAttributes : ushort { | |
None = 0x0000, | |
Setter = 0x0001, // Setter for property | |
Getter = 0x0002, // Getter for property | |
Other = 0x0004, // Other method for property or event | |
AddOn = 0x0008, // AddOn method for event | |
RemoveOn = 0x0010, // RemoveOn method for event | |
Fire = 0x0020 // Fire method for event | |
} | |
} | |
} | |
#endregion | |
#region Mono.Cecil\*.cs | |
namespace Internal { | |
// | |
// Author: | |
// Jb Evain (jbevain@gmail.com) | |
// | |
// Copyright (c) 2008 - 2015 Jb Evain | |
// Copyright (c) 2008 - 2011 Novell, Inc. | |
// | |
// Licensed under the MIT/X11 license. | |
// | |
using System; | |
using Mono.Collections.Generic; | |
namespace Mono.Cecil { | |
internal abstract class MethodSpecification : MethodReference { | |
readonly MethodReference method; | |
public MethodReference ElementMethod { | |
get { return method; } | |
} | |
public override string Name { | |
get { return method.Name; } | |
set { throw new InvalidOperationException (); } | |
} | |
public override MethodCallingConvention CallingConvention { | |
get { return method.CallingConvention; } | |
set { throw new InvalidOperationException (); } | |
} | |
public override bool HasThis { | |
get { return method.HasThis; } | |
set { throw new InvalidOperationException (); } | |
} | |
public override bool ExplicitThis { | |
get { return method.ExplicitThis; } | |
set { throw new InvalidOperationException (); } | |
} | |
public override MethodReturnType MethodReturnType { | |
get { return method.MethodReturnType; } | |
set { throw new InvalidOperationException (); } | |
} | |
public override TypeReference DeclaringType { | |
get { return method.DeclaringType; } | |
set { throw new InvalidOperationException (); } | |
} | |
public override ModuleDefinition Module { | |
get { return method.Module; } | |
} | |
public override bool HasParameters { | |
get { return method.HasParameters; } | |
} | |
public override Collection<ParameterDefinition> Parameters { | |
get { return method.Parameters; } | |
} | |
public override bool ContainsGenericParameter { | |
get { return method.ContainsGenericParameter; } | |
} | |
internal MethodSpecification (MethodReference method) | |
{ | |
Mixin.CheckMethod (method); | |
this.method = method; | |
this.token = new MetadataToken (TokenType.MethodSpec); | |
} | |
public sealed override MethodReference GetElementMethod () | |
{ | |
return method.GetElementMethod (); | |
} | |
} | |
} | |
} | |
#endregion | |
#region Mono.Cecil\*.cs | |
namespace Internal { | |
// | |
// Author: | |
// Jb Evain (jbevain@gmail.com) | |
// | |
// Copyright (c) 2008 - 2015 Jb Evain | |
// Copyright (c) 2008 - 2011 Novell, Inc. | |
// | |
// Licensed under the MIT/X11 license. | |
// | |
using System; | |
using MD = Mono.Cecil.Metadata; | |
namespace Mono.Cecil { | |
internal interface IModifierType { | |
TypeReference ModifierType { get; } | |
TypeReference ElementType { get; } | |
} | |
internal sealed class OptionalModifierType : TypeSpecification, IModifierType { | |
TypeReference modifier_type; | |
public TypeReference ModifierType { | |
get { return modifier_type; } | |
set { modifier_type = value; } | |
} | |
public override string Name { | |
get { return base.Name + Suffix; } | |
} | |
public override string FullName { | |
get { return base.FullName + Suffix; } | |
} | |
string Suffix { | |
get { return " modopt(" + modifier_type + ")"; } | |
} | |
public override bool IsValueType { | |
get { return false; } | |
set { throw new InvalidOperationException (); } | |
} | |
public override bool IsOptionalModifier { | |
get { return true; } | |
} | |
public override bool ContainsGenericParameter { | |
get { return modifier_type.ContainsGenericParameter || base.ContainsGenericParameter; } | |
} | |
public OptionalModifierType (TypeReference modifierType, TypeReference type) | |
: base (type) | |
{ | |
if (modifierType == null) | |
throw new ArgumentNullException (Mixin.Argument.modifierType.ToString ()); | |
Mixin.CheckType (type); | |
this.modifier_type = modifierType; | |
this.etype = MD.ElementType.CModOpt; | |
} | |
} | |
internal sealed class RequiredModifierType : TypeSpecification, IModifierType { | |
TypeReference modifier_type; | |
public TypeReference ModifierType { | |
get { return modifier_type; } | |
set { modifier_type = value; } | |
} | |
public override string Name { | |
get { return base.Name + Suffix; } | |
} | |
public override string FullName { | |
get { return base.FullName + Suffix; } | |
} | |
string Suffix { | |
get { return " modreq(" + modifier_type + ")"; } | |
} | |
public override bool IsValueType { | |
get { return false; } | |
set { throw new InvalidOperationException (); } | |
} | |
public override bool IsRequiredModifier { | |
get { return true; } | |
} | |
public override bool ContainsGenericParameter { | |
get { return modifier_type.ContainsGenericParameter || base.ContainsGenericParameter; } | |
} | |
public RequiredModifierType (TypeReference modifierType, TypeReference type) | |
: base (type) | |
{ | |
if (modifierType == null) | |
throw new ArgumentNullException (Mixin.Argument.modifierType.ToString ()); | |
Mixin.CheckType (type); | |
this.modifier_type = modifierType; | |
this.etype = MD.ElementType.CModReqD; | |
} | |
} | |
} | |
} | |
#endregion | |
#region Mono.Cecil\*.cs | |
namespace Internal { | |
// | |
// Author: | |
// Jb Evain (jbevain@gmail.com) | |
// | |
// Copyright (c) 2008 - 2015 Jb Evain | |
// Copyright (c) 2008 - 2011 Novell, Inc. | |
// | |
// Licensed under the MIT/X11 license. | |
// | |
using System; | |
using System.Collections.Generic; | |
using System.IO; | |
using System.Threading; | |
using SR = System.Reflection; | |
using Mono.Cecil.Cil; | |
using Mono.Cecil.Metadata; | |
using Mono.Cecil.PE; | |
using Mono.Collections.Generic; | |
namespace Mono.Cecil { | |
internal enum ReadingMode { | |
Immediate = 1, | |
Deferred = 2, | |
} | |
internal sealed class ReaderParameters { | |
ReadingMode reading_mode; | |
internal IAssemblyResolver assembly_resolver; | |
internal IMetadataResolver metadata_resolver; | |
#if !READ_ONLY | |
internal IMetadataImporterProvider metadata_importer_provider; | |
internal IReflectionImporterProvider reflection_importer_provider; | |
#endif | |
Stream symbol_stream; | |
ISymbolReaderProvider symbol_reader_provider; | |
bool read_symbols; | |
bool throw_symbols_mismatch; | |
bool projections; | |
bool in_memory; | |
bool read_write; | |
public ReadingMode ReadingMode { | |
get { return reading_mode; } | |
set { reading_mode = value; } | |
} | |
public bool InMemory { | |
get { return in_memory; } | |
set { in_memory = value; } | |
} | |
public IAssemblyResolver AssemblyResolver { | |
get { return assembly_resolver; } | |
set { assembly_resolver = value; } | |
} | |
public IMetadataResolver MetadataResolver { | |
get { return metadata_resolver; } | |
set { metadata_resolver = value; } | |
} | |
#if !READ_ONLY | |
public IMetadataImporterProvider MetadataImporterProvider { | |
get { return metadata_importer_provider; } | |
set { metadata_importer_provider = value; } | |
} | |
public IReflectionImporterProvider ReflectionImporterProvider { | |
get { return reflection_importer_provider; } | |
set { reflection_importer_provider = value; } | |
} | |
#endif | |
public Stream SymbolStream { | |
get { return symbol_stream; } | |
set { symbol_stream = value; } | |
} | |
public ISymbolReaderProvider SymbolReaderProvider { | |
get { return symbol_reader_provider; } | |
set { symbol_reader_provider = value; } | |
} | |
public bool ReadSymbols { | |
get { return read_symbols; } | |
set { read_symbols = value; } | |
} | |
public bool ThrowIfSymbolsAreNotMatching { | |
get { return throw_symbols_mismatch; } | |
set { throw_symbols_mismatch = value; } | |
} | |
public bool ReadWrite { | |
get { return read_write; } | |
set { read_write = value; } | |
} | |
public bool ApplyWindowsRuntimeProjections { | |
get { return projections; } | |
set { projections = value; } | |
} | |
public ReaderParameters () | |
: this (ReadingMode.Deferred) | |
{ | |
} | |
public ReaderParameters (ReadingMode readingMode) | |
{ | |
this.reading_mode = readingMode; | |
this.throw_symbols_mismatch = true; | |
} | |
} | |
#if !READ_ONLY | |
internal sealed class ModuleParameters { | |
ModuleKind kind; | |
TargetRuntime runtime; | |
uint? timestamp; | |
TargetArchitecture architecture; | |
IAssemblyResolver assembly_resolver; | |
IMetadataResolver metadata_resolver; | |
#if !READ_ONLY | |
IMetadataImporterProvider metadata_importer_provider; | |
IReflectionImporterProvider reflection_importer_provider; | |
#endif | |
public ModuleKind Kind { | |
get { return kind; } | |
set { kind = value; } | |
} | |
public TargetRuntime Runtime { | |
get { return runtime; } | |
set { runtime = value; } | |
} | |
public uint? Timestamp { | |
get { return timestamp; } | |
set { timestamp = value; } | |
} | |
public TargetArchitecture Architecture { | |
get { return architecture; } | |
set { architecture = value; } | |
} | |
public IAssemblyResolver AssemblyResolver { | |
get { return assembly_resolver; } | |
set { assembly_resolver = value; } | |
} | |
public IMetadataResolver MetadataResolver { | |
get { return metadata_resolver; } | |
set { metadata_resolver = value; } | |
} | |
#if !READ_ONLY | |
public IMetadataImporterProvider MetadataImporterProvider { | |
get { return metadata_importer_provider; } | |
set { metadata_importer_provider = value; } | |
} | |
public IReflectionImporterProvider ReflectionImporterProvider { | |
get { return reflection_importer_provider; } | |
set { reflection_importer_provider = value; } | |
} | |
#endif | |
public ModuleParameters () | |
{ | |
this.kind = ModuleKind.Dll; | |
this.Runtime = GetCurrentRuntime (); | |
this.architecture = TargetArchitecture.I386; | |
} | |
static TargetRuntime GetCurrentRuntime () | |
{ | |
#if !NET_CORE | |
return typeof (object).Assembly.ImageRuntimeVersion.ParseRuntime (); | |
#else | |
var corlib_name = AssemblyNameReference.Parse (typeof (object).Assembly ().FullName); | |
var corlib_version = corlib_name.Version; | |
switch (corlib_version.Major) { | |
case 1: | |
return corlib_version.Minor == 0 | |
? TargetRuntime.Net_1_0 | |
: TargetRuntime.Net_1_1; | |
case 2: | |
return TargetRuntime.Net_2_0; | |
case 4: | |
return TargetRuntime.Net_4_0; | |
default: | |
throw new NotSupportedException (); | |
} | |
#endif | |
} | |
} | |
internal sealed class WriterParameters { | |
uint? timestamp; | |
Stream symbol_stream; | |
ISymbolWriterProvider symbol_writer_provider; | |
bool write_symbols; | |
#if !NET_CORE | |
SR.StrongNameKeyPair key_pair; | |
#endif | |
public uint? Timestamp { | |
get { return timestamp; } | |
set { timestamp = value; } | |
} | |
public Stream SymbolStream { | |
get { return symbol_stream; } | |
set { symbol_stream = value; } | |
} | |
public ISymbolWriterProvider SymbolWriterProvider { | |
get { return symbol_writer_provider; } | |
set { symbol_writer_provider = value; } | |
} | |
public bool WriteSymbols { | |
get { return write_symbols; } | |
set { write_symbols = value; } | |
} | |
#if !NET_CORE | |
public SR.StrongNameKeyPair StrongNameKeyPair { | |
get { return key_pair; } | |
set { key_pair = value; } | |
} | |
#endif | |
} | |
#endif | |
internal sealed class ModuleDefinition : ModuleReference, ICustomAttributeProvider, ICustomDebugInformationProvider, IDisposable { | |
internal Image Image; | |
internal MetadataSystem MetadataSystem; | |
internal ReadingMode ReadingMode; | |
internal ISymbolReaderProvider SymbolReaderProvider; | |
internal ISymbolReader symbol_reader; | |
internal Disposable<IAssemblyResolver> assembly_resolver; | |
internal IMetadataResolver metadata_resolver; | |
internal TypeSystem type_system; | |
internal readonly MetadataReader reader; | |
readonly string file_name; | |
internal string runtime_version; | |
internal ModuleKind kind; | |
WindowsRuntimeProjections projections; | |
MetadataKind metadata_kind; | |
TargetRuntime runtime; | |
TargetArchitecture architecture; | |
ModuleAttributes attributes; | |
ModuleCharacteristics characteristics; | |
internal ushort linker_version = 8; | |
Guid mvid; | |
internal uint timestamp; | |
internal AssemblyDefinition assembly; | |
MethodDefinition entry_point; | |
#if !READ_ONLY | |
internal IReflectionImporter reflection_importer; | |
internal IMetadataImporter metadata_importer; | |
#endif | |
Collection<CustomAttribute> custom_attributes; | |
Collection<AssemblyNameReference> references; | |
Collection<ModuleReference> modules; | |
Collection<Resource> resources; | |
Collection<ExportedType> exported_types; | |
TypeDefinitionCollection types; | |
internal Collection<CustomDebugInformation> custom_infos; | |
public bool IsMain { | |
get { return kind != ModuleKind.NetModule; } | |
} | |
public ModuleKind Kind { | |
get { return kind; } | |
set { kind = value; } | |
} | |
public MetadataKind MetadataKind { | |
get { return metadata_kind; } | |
set { metadata_kind = value; } | |
} | |
internal WindowsRuntimeProjections Projections { | |
get { | |
if (projections == null) | |
Interlocked.CompareExchange (ref projections, new WindowsRuntimeProjections (this), null); | |
return projections; | |
} | |
} | |
public TargetRuntime Runtime { | |
get { return runtime; } | |
set { | |
runtime = value; | |
runtime_version = runtime.RuntimeVersionString (); | |
} | |
} | |
public string RuntimeVersion { | |
get { return runtime_version; } | |
set { | |
runtime_version = value; | |
runtime = runtime_version.ParseRuntime (); | |
} | |
} | |
public TargetArchitecture Architecture { | |
get { return architecture; } | |
set { architecture = value; } | |
} | |
public ModuleAttributes Attributes { | |
get { return attributes; } | |
set { attributes = value; } | |
} | |
public ModuleCharacteristics Characteristics { | |
get { return characteristics; } | |
set { characteristics = value; } | |
} | |
[Obsolete ("Use FileName")] | |
public string FullyQualifiedName { | |
get { return file_name; } | |
} | |
public string FileName { | |
get { return file_name; } | |
} | |
public Guid Mvid { | |
get { return mvid; } | |
set { mvid = value; } | |
} | |
internal bool HasImage { | |
get { return Image != null; } | |
} | |
public bool HasSymbols { | |
get { return symbol_reader != null; } | |
} | |
public ISymbolReader SymbolReader { | |
get { return symbol_reader; } | |
} | |
public override MetadataScopeType MetadataScopeType { | |
get { return MetadataScopeType.ModuleDefinition; } | |
} | |
public AssemblyDefinition Assembly { | |
get { return assembly; } | |
} | |
#if !READ_ONLY | |
internal IReflectionImporter ReflectionImporter { | |
get { | |
if (reflection_importer == null) | |
Interlocked.CompareExchange (ref reflection_importer, new DefaultReflectionImporter (this), null); | |
return reflection_importer; | |
} | |
} | |
internal IMetadataImporter MetadataImporter { | |
get { | |
if (metadata_importer == null) | |
Interlocked.CompareExchange (ref metadata_importer, new DefaultMetadataImporter (this), null); | |
return metadata_importer; | |
} | |
} | |
#endif | |
public IAssemblyResolver AssemblyResolver { | |
get { | |
if (assembly_resolver.value == null) { | |
lock (module_lock) { | |
assembly_resolver = Disposable.Owned (new DefaultAssemblyResolver () as IAssemblyResolver); | |
} | |
} | |
return assembly_resolver.value; | |
} | |
} | |
public IMetadataResolver MetadataResolver { | |
get { | |
if (metadata_resolver == null) | |
Interlocked.CompareExchange (ref metadata_resolver, new MetadataResolver (this.AssemblyResolver), null); | |
return metadata_resolver; | |
} | |
} | |
public TypeSystem TypeSystem { | |
get { | |
if (type_system == null) | |
Interlocked.CompareExchange (ref type_system, TypeSystem.CreateTypeSystem (this), null); | |
return type_system; | |
} | |
} | |
public bool HasAssemblyReferences { | |
get { | |
if (references != null) | |
return references.Count > 0; | |
return HasImage && Image.HasTable (Table.AssemblyRef); | |
} | |
} | |
public Collection<AssemblyNameReference> AssemblyReferences { | |
get { | |
if (references != null) | |
return references; | |
if (HasImage) | |
return Read (ref references, this, (_, reader) => reader.ReadAssemblyReferences ()); | |
return references = new Collection<AssemblyNameReference> (); | |
} | |
} | |
public bool HasModuleReferences { | |
get { | |
if (modules != null) | |
return modules.Count > 0; | |
return HasImage && Image.HasTable (Table.ModuleRef); | |
} | |
} | |
public Collection<ModuleReference> ModuleReferences { | |
get { | |
if (modules != null) | |
return modules; | |
if (HasImage) | |
return Read (ref modules, this, (_, reader) => reader.ReadModuleReferences ()); | |
return modules = new Collection<ModuleReference> (); | |
} | |
} | |
public bool HasResources { | |
get { | |
if (resources != null) | |
return resources.Count > 0; | |
if (HasImage) | |
return Image.HasTable (Table.ManifestResource) || Read (this, (_, reader) => reader.HasFileResource ()); | |
return false; | |
} | |
} | |
public Collection<Resource> Resources { | |
get { | |
if (resources != null) | |
return resources; | |
if (HasImage) | |
return Read (ref resources, this, (_, reader) => reader.ReadResources ()); | |
return resources = new Collection<Resource> (); | |
} | |
} | |
public bool HasCustomAttributes { | |
get { | |
if (custom_attributes != null) | |
return custom_attributes.Count > 0; | |
return this.GetHasCustomAttributes (this); | |
} | |
} | |
public Collection<CustomAttribute> CustomAttributes { | |
get { return custom_attributes ?? (this.GetCustomAttributes (ref custom_attributes, this)); } | |
} | |
public bool HasTypes { | |
get { | |
if (types != null) | |
return types.Count > 0; | |
return HasImage && Image.HasTable (Table.TypeDef); | |
} | |
} | |
public Collection<TypeDefinition> Types { | |
get { | |
if (types != null) | |
return types; | |
if (HasImage) | |
return Read (ref types, this, (_, reader) => reader.ReadTypes ()); | |
return types = new TypeDefinitionCollection (this); | |
} | |
} | |
public bool HasExportedTypes { | |
get { | |
if (exported_types != null) | |
return exported_types.Count > 0; | |
return HasImage && Image.HasTable (Table.ExportedType); | |
} | |
} | |
public Collection<ExportedType> ExportedTypes { | |
get { | |
if (exported_types != null) | |
return exported_types; | |
if (HasImage) | |
return Read (ref exported_types, this, (_, reader) => reader.ReadExportedTypes ()); | |
return exported_types = new Collection<ExportedType> (); | |
} | |
} | |
public MethodDefinition EntryPoint { | |
get { | |
if (entry_point != null) | |
return entry_point; | |
if (HasImage) | |
return Read (ref entry_point, this, (_, reader) => reader.ReadEntryPoint ()); | |
return entry_point = null; | |
} | |
set { entry_point = value; } | |
} | |
public bool HasCustomDebugInformations { | |
get { | |
return custom_infos != null && custom_infos.Count > 0; | |
} | |
} | |
public Collection<CustomDebugInformation> CustomDebugInformations { | |
get { | |
return custom_infos ?? (custom_infos = new Collection<CustomDebugInformation> ()); | |
} | |
} | |
internal ModuleDefinition () | |
{ | |
this.MetadataSystem = new MetadataSystem (); | |
this.token = new MetadataToken (TokenType.Module, 1); | |
} | |
internal ModuleDefinition (Image image) | |
: this () | |
{ | |
this.Image = image; | |
this.kind = image.Kind; | |
this.RuntimeVersion = image.RuntimeVersion; | |
this.architecture = image.Architecture; | |
this.attributes = image.Attributes; | |
this.characteristics = image.Characteristics; | |
this.linker_version = image.LinkerVersion; | |
this.file_name = image.FileName; | |
this.timestamp = image.Timestamp; | |
this.reader = new MetadataReader (this); | |
} | |
public void Dispose () | |
{ | |
if (Image != null) | |
Image.Dispose (); | |
if (symbol_reader != null) | |
symbol_reader.Dispose (); | |
if (assembly_resolver.value != null) | |
assembly_resolver.Dispose (); | |
} | |
public bool HasTypeReference (string fullName) | |
{ | |
return HasTypeReference (string.Empty, fullName); | |
} | |
public bool HasTypeReference (string scope, string fullName) | |
{ | |
Mixin.CheckFullName (fullName); | |
if (!HasImage) | |
return false; | |
return GetTypeReference (scope, fullName) != null; | |
} | |
public bool TryGetTypeReference (string fullName, out TypeReference type) | |
{ | |
return TryGetTypeReference (string.Empty, fullName, out type); | |
} | |
public bool TryGetTypeReference (string scope, string fullName, out TypeReference type) | |
{ | |
Mixin.CheckFullName (fullName); | |
if (!HasImage) { | |
type = null; | |
return false; | |
} | |
return (type = GetTypeReference (scope, fullName)) != null; | |
} | |
TypeReference GetTypeReference (string scope, string fullname) | |
{ | |
return Read (new Row<string, string> (scope, fullname), (row, reader) => reader.GetTypeReference (row.Col1, row.Col2)); | |
} | |
public IEnumerable<TypeReference> GetTypeReferences () | |
{ | |
if (!HasImage) | |
return Empty<TypeReference>.Array; | |
return Read (this, (_, reader) => reader.GetTypeReferences ()); | |
} | |
public IEnumerable<MemberReference> GetMemberReferences () | |
{ | |
if (!HasImage) | |
return Empty<MemberReference>.Array; | |
return Read (this, (_, reader) => reader.GetMemberReferences ()); | |
} | |
public IEnumerable<CustomAttribute> GetCustomAttributes () | |
{ | |
if (!HasImage) | |
return Empty<CustomAttribute>.Array; | |
return Read (this, (_, reader) => reader.GetCustomAttributes ()); | |
} | |
public TypeReference GetType (string fullName, bool runtimeName) | |
{ | |
return runtimeName | |
? TypeParser.ParseType (this, fullName, typeDefinitionOnly: true) | |
: GetType (fullName); | |
} | |
public TypeDefinition GetType (string fullName) | |
{ | |
Mixin.CheckFullName (fullName); | |
var position = fullName.IndexOf ('/'); | |
if (position > 0) | |
return GetNestedType (fullName); | |
return ((TypeDefinitionCollection) this.Types).GetType (fullName); | |
} | |
public TypeDefinition GetType (string @namespace, string name) | |
{ | |
Mixin.CheckName (name); | |
return ((TypeDefinitionCollection) this.Types).GetType (@namespace ?? string.Empty, name); | |
} | |
public IEnumerable<TypeDefinition> GetTypes () | |
{ | |
return GetTypes (Types); | |
} | |
static IEnumerable<TypeDefinition> GetTypes (Collection<TypeDefinition> types) | |
{ | |
for (int i = 0; i < types.Count; i++) { | |
var type = types [i]; | |
yield return type; | |
if (!type.HasNestedTypes) | |
continue; | |
foreach (var nested in GetTypes (type.NestedTypes)) | |
yield return nested; | |
} | |
} | |
TypeDefinition GetNestedType (string fullname) | |
{ | |
var names = fullname.Split ('/'); | |
var type = GetType (names [0]); | |
if (type == null) | |
return null; | |
for (int i = 1; i < names.Length; i++) { | |
var nested_type = type.GetNestedType (names [i]); | |
if (nested_type == null) | |
return null; | |
type = nested_type; | |
} | |
return type; | |
} | |
internal FieldDefinition Resolve (FieldReference field) | |
{ | |
return MetadataResolver.Resolve (field); | |
} | |
internal MethodDefinition Resolve (MethodReference method) | |
{ | |
return MetadataResolver.Resolve (method); | |
} | |
internal TypeDefinition Resolve (TypeReference type) | |
{ | |
return MetadataResolver.Resolve (type); | |
} | |
#if !READ_ONLY | |
static void CheckContext (IGenericParameterProvider context, ModuleDefinition module) | |
{ | |
if (context == null) | |
return; | |
if (context.Module != module) | |
throw new ArgumentException (); | |
} | |
[Obsolete ("Use ImportReference", error: false)] | |
public TypeReference Import (Type type) | |
{ | |
return ImportReference (type, null); | |
} | |
public TypeReference ImportReference (Type type) | |
{ | |
return ImportReference (type, null); | |
} | |
[Obsolete ("Use ImportReference", error: false)] | |
public TypeReference Import (Type type, IGenericParameterProvider context) | |
{ | |
return ImportReference (type, context); | |
} | |
public TypeReference ImportReference (Type type, IGenericParameterProvider context) | |
{ | |
Mixin.CheckType (type); | |
CheckContext (context, this); | |
return ReflectionImporter.ImportReference (type, context); | |
} | |
[Obsolete ("Use ImportReference", error: false)] | |
public FieldReference Import (SR.FieldInfo field) | |
{ | |
return ImportReference (field, null); | |
} | |
[Obsolete ("Use ImportReference", error: false)] | |
public FieldReference Import (SR.FieldInfo field, IGenericParameterProvider context) | |
{ | |
return ImportReference (field, context); | |
} | |
public FieldReference ImportReference (SR.FieldInfo field) | |
{ | |
return ImportReference (field, null); | |
} | |
public FieldReference ImportReference (SR.FieldInfo field, IGenericParameterProvider context) | |
{ | |
Mixin.CheckField (field); | |
CheckContext (context, this); | |
return ReflectionImporter.ImportReference (field, context); | |
} | |
[Obsolete ("Use ImportReference", error: false)] | |
public MethodReference Import (SR.MethodBase method) | |
{ | |
return ImportReference (method, null); | |
} | |
[Obsolete ("Use ImportReference", error: false)] | |
public MethodReference Import (SR.MethodBase method, IGenericParameterProvider context) | |
{ | |
return ImportReference (method, context); | |
} | |
public MethodReference ImportReference (SR.MethodBase method) | |
{ | |
return ImportReference (method, null); | |
} | |
public MethodReference ImportReference (SR.MethodBase method, IGenericParameterProvider context) | |
{ | |
Mixin.CheckMethod (method); | |
CheckContext (context, this); | |
return ReflectionImporter.ImportReference (method, context); | |
} | |
[Obsolete ("Use ImportReference", error: false)] | |
public TypeReference Import (TypeReference type) | |
{ | |
return ImportReference (type, null); | |
} | |
[Obsolete ("Use ImportReference", error: false)] | |
public TypeReference Import (TypeReference type, IGenericParameterProvider context) | |
{ | |
return ImportReference (type, context); | |
} | |
public TypeReference ImportReference (TypeReference type) | |
{ | |
return ImportReference (type, null); | |
} | |
public TypeReference ImportReference (TypeReference type, IGenericParameterProvider context) | |
{ | |
Mixin.CheckType (type); | |
if (type.Module == this) | |
return type; | |
CheckContext (context, this); | |
return MetadataImporter.ImportReference (type, context); | |
} | |
[Obsolete ("Use ImportReference", error: false)] | |
public FieldReference Import (FieldReference field) | |
{ | |
return ImportReference (field, null); | |
} | |
[Obsolete ("Use ImportReference", error: false)] | |
public FieldReference Import (FieldReference field, IGenericParameterProvider context) | |
{ | |
return ImportReference (field, context); | |
} | |
public FieldReference ImportReference (FieldReference field) | |
{ | |
return ImportReference (field, null); | |
} | |
public FieldReference ImportReference (FieldReference field, IGenericParameterProvider context) | |
{ | |
Mixin.CheckField (field); | |
if (field.Module == this) | |
return field; | |
CheckContext (context, this); | |
return MetadataImporter.ImportReference (field, context); | |
} | |
[Obsolete ("Use ImportReference", error: false)] | |
public MethodReference Import (MethodReference method) | |
{ | |
return ImportReference (method, null); | |
} | |
[Obsolete ("Use ImportReference", error: false)] | |
public MethodReference Import (MethodReference method, IGenericParameterProvider context) | |
{ | |
return ImportReference (method, context); | |
} | |
public MethodReference ImportReference (MethodReference method) | |
{ | |
return ImportReference (method, null); | |
} | |
public MethodReference ImportReference (MethodReference method, IGenericParameterProvider context) | |
{ | |
Mixin.CheckMethod (method); | |
if (method.Module == this) | |
return method; | |
CheckContext (context, this); | |
return MetadataImporter.ImportReference (method, context); | |
} | |
#endif | |
public IMetadataTokenProvider LookupToken (int token) | |
{ | |
return LookupToken (new MetadataToken ((uint) token)); | |
} | |
public IMetadataTokenProvider LookupToken (MetadataToken token) | |
{ | |
return Read (token, (t, reader) => reader.LookupToken (t)); | |
} | |
readonly object module_lock = new object(); | |
internal object SyncRoot { | |
get { return module_lock; } | |
} | |
internal void Read<TItem> (TItem item, Action<TItem, MetadataReader> read) | |
{ | |
lock (module_lock) { | |
var position = reader.position; | |
var context = reader.context; | |
read (item, reader); | |
reader.position = position; | |
reader.context = context; | |
} | |
} | |
internal TRet Read<TItem, TRet> (TItem item, Func<TItem, MetadataReader, TRet> read) | |
{ | |
lock (module_lock) { | |
var position = reader.position; | |
var context = reader.context; | |
var ret = read (item, reader); | |
reader.position = position; | |
reader.context = context; | |
return ret; | |
} | |
} | |
internal TRet Read<TItem, TRet> (ref TRet variable, TItem item, Func<TItem, MetadataReader, TRet> read) where TRet : class | |
{ | |
lock (module_lock) { | |
if (variable != null) | |
return variable; | |
var position = reader.position; | |
var context = reader.context; | |
var ret = read (item, reader); | |
reader.position = position; | |
reader.context = context; | |
return variable = ret; | |
} | |
} | |
public bool HasDebugHeader { | |
get { return Image != null && Image.DebugHeader != null; } | |
} | |
public ImageDebugHeader GetDebugHeader () | |
{ | |
return Image.DebugHeader ?? new ImageDebugHeader (); | |
} | |
#if !READ_ONLY | |
public static ModuleDefinition CreateModule (string name, ModuleKind kind) | |
{ | |
return CreateModule (name, new ModuleParameters { Kind = kind }); | |
} | |
public static ModuleDefinition CreateModule (string name, ModuleParameters parameters) | |
{ | |
Mixin.CheckName (name); | |
Mixin.CheckParameters (parameters); | |
var module = new ModuleDefinition { | |
Name = name, | |
kind = parameters.Kind, | |
timestamp = parameters.Timestamp ?? Mixin.GetTimestamp (), | |
Runtime = parameters.Runtime, | |
architecture = parameters.Architecture, | |
mvid = Guid.NewGuid (), | |
Attributes = ModuleAttributes.ILOnly, | |
Characteristics = (ModuleCharacteristics) 0x8540, | |
}; | |
if (parameters.AssemblyResolver != null) | |
module.assembly_resolver = Disposable.NotOwned (parameters.AssemblyResolver); | |
if (parameters.MetadataResolver != null) | |
module.metadata_resolver = parameters.MetadataResolver; | |
#if !READ_ONLY | |
if (parameters.MetadataImporterProvider != null) | |
module.metadata_importer = parameters.MetadataImporterProvider.GetMetadataImporter (module); | |
if (parameters.ReflectionImporterProvider != null) | |
module.reflection_importer = parameters.ReflectionImporterProvider.GetReflectionImporter (module); | |
#endif | |
if (parameters.Kind != ModuleKind.NetModule) { | |
var assembly = new AssemblyDefinition (); | |
module.assembly = assembly; | |
module.assembly.Name = CreateAssemblyName (name); | |
assembly.main_module = module; | |
} | |
module.Types.Add (new TypeDefinition (string.Empty, "<Module>", TypeAttributes.NotPublic)); | |
return module; | |
} | |
static AssemblyNameDefinition CreateAssemblyName (string name) | |
{ | |
if (name.EndsWith (".dll") || name.EndsWith (".exe")) | |
name = name.Substring (0, name.Length - 4); | |
return new AssemblyNameDefinition (name, Mixin.ZeroVersion); | |
} | |
#endif | |
public void ReadSymbols () | |
{ | |
if (string.IsNullOrEmpty (file_name)) | |
throw new InvalidOperationException (); | |
var provider = new DefaultSymbolReaderProvider (throwIfNoSymbol: true); | |
ReadSymbols (provider.GetSymbolReader (this, file_name), throwIfSymbolsAreNotMaching: true); | |
} | |
public void ReadSymbols (ISymbolReader reader) | |
{ | |
ReadSymbols(reader, throwIfSymbolsAreNotMaching: true); | |
} | |
public void ReadSymbols (ISymbolReader reader, bool throwIfSymbolsAreNotMaching) | |
{ | |
if (reader == null) | |
throw new ArgumentNullException ("reader"); | |
symbol_reader = reader; | |
if (!symbol_reader.ProcessDebugHeader (GetDebugHeader ())) { | |
symbol_reader = null; | |
if (throwIfSymbolsAreNotMaching) | |
throw new SymbolsNotMatchingException ("Symbols were found but are not matching the assembly"); | |
return; | |
} | |
if (HasImage && ReadingMode == ReadingMode.Immediate) { | |
var immediate_reader = new ImmediateModuleReader (Image); | |
immediate_reader.ReadSymbols (this); | |
} | |
} | |
public static ModuleDefinition ReadModule (string fileName) | |
{ | |
return ReadModule (fileName, new ReaderParameters (ReadingMode.Deferred)); | |
} | |
public static ModuleDefinition ReadModule (string fileName, ReaderParameters parameters) | |
{ | |
var stream = GetFileStream (fileName, FileMode.Open, parameters.ReadWrite ? FileAccess.ReadWrite : FileAccess.Read, FileShare.Read); | |
if (parameters.InMemory) { | |
var memory = new MemoryStream (stream.CanSeek ? (int) stream.Length : 0); | |
using (stream) | |
stream.CopyTo (memory); | |
memory.Position = 0; | |
stream = memory; | |
} | |
try { | |
return ReadModule (Disposable.Owned (stream), fileName, parameters); | |
} catch (Exception) { | |
stream.Dispose (); | |
throw; | |
} | |
} | |
static Stream GetFileStream (string fileName, FileMode mode, FileAccess access, FileShare share) | |
{ | |
Mixin.CheckFileName (fileName); | |
return new FileStream (fileName, mode, access, share); | |
} | |
public static ModuleDefinition ReadModule (Stream stream) | |
{ | |
return ReadModule (stream, new ReaderParameters (ReadingMode.Deferred)); | |
} | |
public static ModuleDefinition ReadModule (Stream stream, ReaderParameters parameters) | |
{ | |
Mixin.CheckStream (stream); | |
Mixin.CheckReadSeek (stream); | |
return ReadModule (Disposable.NotOwned (stream), stream.GetFileName (), parameters); | |
} | |
static ModuleDefinition ReadModule (Disposable<Stream> stream, string fileName, ReaderParameters parameters) | |
{ | |
Mixin.CheckParameters (parameters); | |
return ModuleReader.CreateModule ( | |
ImageReader.ReadImage (stream, fileName), | |
parameters); | |
} | |
#if !READ_ONLY | |
public void Write (string fileName) | |
{ | |
Write (fileName, new WriterParameters ()); | |
} | |
public void Write (string fileName, WriterParameters parameters) | |
{ | |
Mixin.CheckParameters (parameters); | |
var file = GetFileStream (fileName, FileMode.Create, FileAccess.ReadWrite, FileShare.Read); | |
ModuleWriter.WriteModule (this, Disposable.Owned (file), parameters); | |
} | |
public void Write () | |
{ | |
Write (new WriterParameters ()); | |
} | |
public void Write (WriterParameters parameters) | |
{ | |
if (!HasImage) | |
throw new InvalidOperationException (); | |
Write (Image.Stream.value, parameters); | |
} | |
public void Write (Stream stream) | |
{ | |
Write (stream, new WriterParameters ()); | |
} | |
public void Write (Stream stream, WriterParameters parameters) | |
{ | |
Mixin.CheckStream (stream); | |
Mixin.CheckWriteSeek (stream); | |
Mixin.CheckParameters (parameters); | |
ModuleWriter.WriteModule (this, Disposable.NotOwned (stream), parameters); | |
} | |
#endif | |
} | |
static partial class Mixin { | |
internal enum Argument { | |
name, | |
fileName, | |
fullName, | |
stream, | |
type, | |
method, | |
field, | |
parameters, | |
module, | |
modifierType, | |
eventType, | |
fieldType, | |
declaringType, | |
returnType, | |
propertyType, | |
interfaceType, | |
} | |
public static void CheckName (object name) | |
{ | |
if (name == null) | |
throw new ArgumentNullException (Argument.name.ToString ()); | |
} | |
public static void CheckName (string name) | |
{ | |
if (string.IsNullOrEmpty (name)) | |
throw new ArgumentNullOrEmptyException (Argument.name.ToString ()); | |
} | |
public static void CheckFileName (string fileName) | |
{ | |
if (string.IsNullOrEmpty (fileName)) | |
throw new ArgumentNullOrEmptyException (Argument.fileName.ToString ()); | |
} | |
public static void CheckFullName (string fullName) | |
{ | |
if (string.IsNullOrEmpty (fullName)) | |
throw new ArgumentNullOrEmptyException (Argument.fullName.ToString ()); | |
} | |
public static void CheckStream (object stream) | |
{ | |
if (stream == null) | |
throw new ArgumentNullException (Argument.stream.ToString ()); | |
} | |
public static void CheckWriteSeek (Stream stream) | |
{ | |
if (!stream.CanWrite || !stream.CanSeek) | |
throw new ArgumentException ("Stream must be writable and seekable."); | |
} | |
public static void CheckReadSeek (Stream stream) | |
{ | |
if (!stream.CanRead || !stream.CanSeek) | |
throw new ArgumentException ("Stream must be readable and seekable."); | |
} | |
public static void CheckType (object type) | |
{ | |
if (type == null) | |
throw new ArgumentNullException (Argument.type.ToString ()); | |
} | |
public static void CheckType (object type, Argument argument) | |
{ | |
if (type == null) | |
throw new ArgumentNullException (argument.ToString ()); | |
} | |
public static void CheckField (object field) | |
{ | |
if (field == null) | |
throw new ArgumentNullException (Argument.field.ToString ()); | |
} | |
public static void CheckMethod (object method) | |
{ | |
if (method == null) | |
throw new ArgumentNullException (Argument.method.ToString ()); | |
} | |
public static void CheckParameters (object parameters) | |
{ | |
if (parameters == null) | |
throw new ArgumentNullException (Argument.parameters.ToString ()); | |
} | |
public static uint GetTimestamp () | |
{ | |
return (uint) DateTime.UtcNow.Subtract (new DateTime (1970, 1, 1)).TotalSeconds; | |
} | |
public static bool HasImage (this ModuleDefinition self) | |
{ | |
return self != null && self.HasImage; | |
} | |
public static string GetFileName (this Stream self) | |
{ | |
var file_stream = self as FileStream; | |
if (file_stream == null) | |
return string.Empty; | |
return Path.GetFullPath (file_stream.Name); | |
} | |
#if !NET_4_0 | |
public static void CopyTo (this Stream self, Stream target) | |
{ | |
var buffer = new byte [1024 * 8]; | |
int read; | |
while ((read = self.Read (buffer, 0, buffer.Length)) > 0) | |
target.Write (buffer, 0, read); | |
} | |
#endif | |
public static TargetRuntime ParseRuntime (this string self) | |
{ | |
if (string.IsNullOrEmpty (self)) | |
return TargetRuntime.Net_4_0; | |
switch (self [1]) { | |
case '1': | |
return self [3] == '0' | |
? TargetRuntime.Net_1_0 | |
: TargetRuntime.Net_1_1; | |
case '2': | |
return TargetRuntime.Net_2_0; | |
case '4': | |
default: | |
return TargetRuntime.Net_4_0; | |
} | |
} | |
public static string RuntimeVersionString (this TargetRuntime runtime) | |
{ | |
switch (runtime) { | |
case TargetRuntime.Net_1_0: | |
return "v1.0.3705"; | |
case TargetRuntime.Net_1_1: | |
return "v1.1.4322"; | |
case TargetRuntime.Net_2_0: | |
return "v2.0.50727"; | |
case TargetRuntime.Net_4_0: | |
default: | |
return "v4.0.30319"; | |
} | |
} | |
public static bool IsWindowsMetadata (this ModuleDefinition module) | |
{ | |
return module.MetadataKind != MetadataKind.Ecma335; | |
} | |
public static byte [] ReadAll (this Stream self) | |
{ | |
int read; | |
var memory = new MemoryStream ((int) self.Length); | |
var buffer = new byte [1024]; | |
while ((read = self.Read (buffer, 0, buffer.Length)) != 0) | |
memory.Write (buffer, 0, read); | |
return memory.ToArray (); | |
} | |
public static void Read (object o) | |
{ | |
} | |
} | |
} | |
} | |
#endregion | |
#region Mono.Cecil\*.cs | |
namespace Internal { | |
// | |
// Author: | |
// Jb Evain (jbevain@gmail.com) | |
// | |
// Copyright (c) 2008 - 2015 Jb Evain | |
// Copyright (c) 2008 - 2011 Novell, Inc. | |
// | |
// Licensed under the MIT/X11 license. | |
// | |
using System; | |
namespace Mono.Cecil { | |
internal enum ModuleKind { | |
Dll, | |
Console, | |
Windows, | |
NetModule, | |
} | |
internal enum MetadataKind { | |
Ecma335, | |
WindowsMetadata, | |
ManagedWindowsMetadata, | |
} | |
internal enum TargetArchitecture { | |
I386 = 0x014c, | |
AMD64 = 0x8664, | |
IA64 = 0x0200, | |
ARM = 0x01c0, | |
ARMv7 = 0x01c4, | |
ARM64 = 0xaa64, | |
} | |
[Flags] | |
internal enum ModuleAttributes { | |
ILOnly = 1, | |
Required32Bit = 2, | |
ILLibrary = 4, | |
StrongNameSigned = 8, | |
Preferred32Bit = 0x00020000, | |
} | |
[Flags] | |
internal enum ModuleCharacteristics { | |
HighEntropyVA = 0x0020, | |
DynamicBase = 0x0040, | |
NoSEH = 0x0400, | |
NXCompat = 0x0100, | |
AppContainer = 0x1000, | |
TerminalServerAware = 0x8000, | |
} | |
} | |
} | |
#endregion | |
#region Mono.Cecil\*.cs | |
namespace Internal { | |
// | |
// Author: | |
// Jb Evain (jbevain@gmail.com) | |
// | |
// Copyright (c) 2008 - 2015 Jb Evain | |
// Copyright (c) 2008 - 2011 Novell, Inc. | |
// | |
// Licensed under the MIT/X11 license. | |
// | |
namespace Mono.Cecil { | |
internal class ModuleReference : IMetadataScope { | |
string name; | |
internal MetadataToken token; | |
public string Name { | |
get { return name; } | |
set { name = value; } | |
} | |
public virtual MetadataScopeType MetadataScopeType { | |
get { return MetadataScopeType.ModuleReference; } | |
} | |
public MetadataToken MetadataToken { | |
get { return token; } | |
set { token = value; } | |
} | |
internal ModuleReference () | |
{ | |
this.token = new MetadataToken (TokenType.ModuleRef); | |
} | |
public ModuleReference (string name) | |
: this () | |
{ | |
this.name = name; | |
} | |
public override string ToString () | |
{ | |
return name; | |
} | |
} | |
} | |
} | |
#endregion | |
#region Mono.Cecil\*.cs | |
namespace Internal { | |
// | |
// Author: | |
// Jb Evain (jbevain@gmail.com) | |
// | |
// Copyright (c) 2008 - 2015 Jb Evain | |
// Copyright (c) 2008 - 2011 Novell, Inc. | |
// | |
// Licensed under the MIT/X11 license. | |
// | |
namespace Mono.Cecil { | |
internal enum NativeType { | |
None = 0x66, | |
Boolean = 0x02, | |
I1 = 0x03, | |
U1 = 0x04, | |
I2 = 0x05, | |
U2 = 0x06, | |
I4 = 0x07, | |
U4 = 0x08, | |
I8 = 0x09, | |
U8 = 0x0a, | |
R4 = 0x0b, | |
R8 = 0x0c, | |
LPStr = 0x14, | |
Int = 0x1f, | |
UInt = 0x20, | |
Func = 0x26, | |
Array = 0x2a, | |
// Msft specific | |
Currency = 0x0f, | |
BStr = 0x13, | |
LPWStr = 0x15, | |
LPTStr = 0x16, | |
FixedSysString = 0x17, | |
IUnknown = 0x19, | |
IDispatch = 0x1a, | |
Struct = 0x1b, | |
IntF = 0x1c, | |
SafeArray = 0x1d, | |
FixedArray = 0x1e, | |
ByValStr = 0x22, | |
ANSIBStr = 0x23, | |
TBStr = 0x24, | |
VariantBool = 0x25, | |
ASAny = 0x28, | |
LPStruct = 0x2b, | |
CustomMarshaler = 0x2c, | |
Error = 0x2d, | |
Max = 0x50 | |
} | |
} | |
} | |
#endregion | |
#region Mono.Cecil\*.cs | |
namespace Internal { | |
// | |
// Author: | |
// Jb Evain (jbevain@gmail.com) | |
// | |
// Copyright (c) 2008 - 2015 Jb Evain | |
// Copyright (c) 2008 - 2011 Novell, Inc. | |
// | |
// Licensed under the MIT/X11 license. | |
// | |
using System; | |
namespace Mono.Cecil { | |
[Flags] | |
internal enum ParameterAttributes : ushort { | |
None = 0x0000, | |
In = 0x0001, // Param is [In] | |
Out = 0x0002, // Param is [Out] | |
Lcid = 0x0004, | |
Retval = 0x0008, | |
Optional = 0x0010, // Param is optional | |
HasDefault = 0x1000, // Param has default value | |
HasFieldMarshal = 0x2000, // Param has field marshal | |
Unused = 0xcfe0 // Reserved: shall be zero in a conforming implementation | |
} | |
} | |
} | |
#endregion | |
#region Mono.Cecil\*.cs | |
namespace Internal { | |
// | |
// Author: | |
// Jb Evain (jbevain@gmail.com) | |
// | |
// Copyright (c) 2008 - 2015 Jb Evain | |
// Copyright (c) 2008 - 2011 Novell, Inc. | |
// | |
// Licensed under the MIT/X11 license. | |
// | |
using Mono.Collections.Generic; | |
namespace Mono.Cecil { | |
internal sealed class ParameterDefinition : ParameterReference, ICustomAttributeProvider, IConstantProvider, IMarshalInfoProvider { | |
ushort attributes; | |
internal IMethodSignature method; | |
object constant = Mixin.NotResolved; | |
Collection<CustomAttribute> custom_attributes; | |
MarshalInfo marshal_info; | |
public ParameterAttributes Attributes { | |
get { return (ParameterAttributes) attributes; } | |
set { attributes = (ushort) value; } | |
} | |
public IMethodSignature Method { | |
get { return method; } | |
} | |
public int Sequence { | |
get { | |
if (method == null) | |
return -1; | |
return method.HasImplicitThis () ? index + 1 : index; | |
} | |
} | |
public bool HasConstant { | |
get { | |
this.ResolveConstant (ref constant, parameter_type.Module); | |
return constant != Mixin.NoValue; | |
} | |
set { if (!value) constant = Mixin.NoValue; } | |
} | |
public object Constant { | |
get { return HasConstant ? constant : null; } | |
set { constant = value; } | |
} | |
public bool HasCustomAttributes { | |
get { | |
if (custom_attributes != null) | |
return custom_attributes.Count > 0; | |
return this.GetHasCustomAttributes (parameter_type.Module); | |
} | |
} | |
public Collection<CustomAttribute> CustomAttributes { | |
get { return custom_attributes ?? (this.GetCustomAttributes (ref custom_attributes, parameter_type.Module)); } | |
} | |
public bool HasMarshalInfo { | |
get { | |
if (marshal_info != null) | |
return true; | |
return this.GetHasMarshalInfo (parameter_type.Module); | |
} | |
} | |
public MarshalInfo MarshalInfo { | |
get { return marshal_info ?? (this.GetMarshalInfo (ref marshal_info, parameter_type.Module)); } | |
set { marshal_info = value; } | |
} | |
#region ParameterAttributes | |
public bool IsIn { | |
get { return attributes.GetAttributes ((ushort) ParameterAttributes.In); } | |
set { attributes = attributes.SetAttributes ((ushort) ParameterAttributes.In, value); } | |
} | |
public bool IsOut { | |
get { return attributes.GetAttributes ((ushort) ParameterAttributes.Out); } | |
set { attributes = attributes.SetAttributes ((ushort) ParameterAttributes.Out, value); } | |
} | |
public bool IsLcid { | |
get { return attributes.GetAttributes ((ushort) ParameterAttributes.Lcid); } | |
set { attributes = attributes.SetAttributes ((ushort) ParameterAttributes.Lcid, value); } | |
} | |
public bool IsReturnValue { | |
get { return attributes.GetAttributes ((ushort) ParameterAttributes.Retval); } | |
set { attributes = attributes.SetAttributes ((ushort) ParameterAttributes.Retval, value); } | |
} | |
public bool IsOptional { | |
get { return attributes.GetAttributes ((ushort) ParameterAttributes.Optional); } | |
set { attributes = attributes.SetAttributes ((ushort) ParameterAttributes.Optional, value); } | |
} | |
public bool HasDefault { | |
get { return attributes.GetAttributes ((ushort) ParameterAttributes.HasDefault); } | |
set { attributes = attributes.SetAttributes ((ushort) ParameterAttributes.HasDefault, value); } | |
} | |
public bool HasFieldMarshal { | |
get { return attributes.GetAttributes ((ushort) ParameterAttributes.HasFieldMarshal); } | |
set { attributes = attributes.SetAttributes ((ushort) ParameterAttributes.HasFieldMarshal, value); } | |
} | |
#endregion | |
internal ParameterDefinition (TypeReference parameterType, IMethodSignature method) | |
: this (string.Empty, ParameterAttributes.None, parameterType) | |
{ | |
this.method = method; | |
} | |
public ParameterDefinition (TypeReference parameterType) | |
: this (string.Empty, ParameterAttributes.None, parameterType) | |
{ | |
} | |
public ParameterDefinition (string name, ParameterAttributes attributes, TypeReference parameterType) | |
: base (name, parameterType) | |
{ | |
this.attributes = (ushort) attributes; | |
this.token = new MetadataToken (TokenType.Param); | |
} | |
public override ParameterDefinition Resolve () | |
{ | |
return this; | |
} | |
} | |
} | |
} | |
#endregion | |
#region Mono.Cecil\*.cs | |
namespace Internal { | |
// | |
// Author: | |
// Jb Evain (jbevain@gmail.com) | |
// | |
// Copyright (c) 2008 - 2015 Jb Evain | |
// Copyright (c) 2008 - 2011 Novell, Inc. | |
// | |
// Licensed under the MIT/X11 license. | |
// | |
using System; | |
using Mono.Collections.Generic; | |
namespace Mono.Cecil { | |
sealed class ParameterDefinitionCollection : Collection<ParameterDefinition> { | |
readonly IMethodSignature method; | |
internal ParameterDefinitionCollection (IMethodSignature method) | |
{ | |
this.method = method; | |
} | |
internal ParameterDefinitionCollection (IMethodSignature method, int capacity) | |
: base (capacity) | |
{ | |
this.method = method; | |
} | |
protected override void OnAdd (ParameterDefinition item, int index) | |
{ | |
item.method = method; | |
item.index = index; | |
} | |
protected override void OnInsert (ParameterDefinition item, int index) | |
{ | |
item.method = method; | |
item.index = index; | |
for (int i = index; i < size; i++) | |
items [i].index = i + 1; | |
} | |
protected override void OnSet (ParameterDefinition item, int index) | |
{ | |
item.method = method; | |
item.index = index; | |
} | |
protected override void OnRemove (ParameterDefinition item, int index) | |
{ | |
item.method = null; | |
item.index = -1; | |
for (int i = index + 1; i < size; i++) | |
items [i].index = i - 1; | |
} | |
} | |
} | |
} | |
#endregion | |
#region Mono.Cecil\*.cs | |
namespace Internal { | |
// | |
// Author: | |
// Jb Evain (jbevain@gmail.com) | |
// | |
// Copyright (c) 2008 - 2015 Jb Evain | |
// Copyright (c) 2008 - 2011 Novell, Inc. | |
// | |
// Licensed under the MIT/X11 license. | |
// | |
using System; | |
namespace Mono.Cecil { | |
internal abstract class ParameterReference : IMetadataTokenProvider { | |
string name; | |
internal int index = -1; | |
protected TypeReference parameter_type; | |
internal MetadataToken token; | |
public string Name { | |
get { return name; } | |
set { name = value; } | |
} | |
public int Index { | |
get { return index; } | |
} | |
public TypeReference ParameterType { | |
get { return parameter_type; } | |
set { parameter_type = value; } | |
} | |
public MetadataToken MetadataToken { | |
get { return token; } | |
set { token = value; } | |
} | |
internal ParameterReference (string name, TypeReference parameterType) | |
{ | |
if (parameterType == null) | |
throw new ArgumentNullException ("parameterType"); | |
this.name = name ?? string.Empty; | |
this.parameter_type = parameterType; | |
} | |
public override string ToString () | |
{ | |
return name; | |
} | |
public abstract ParameterDefinition Resolve (); | |
} | |
} | |
} | |
#endregion | |
#region Mono.Cecil\*.cs | |
namespace Internal { | |
// | |
// Author: | |
// Jb Evain (jbevain@gmail.com) | |
// | |
// Copyright (c) 2008 - 2015 Jb Evain | |
// Copyright (c) 2008 - 2011 Novell, Inc. | |
// | |
// Licensed under the MIT/X11 license. | |
// | |
using System; | |
using MD = Mono.Cecil.Metadata; | |
namespace Mono.Cecil { | |
internal sealed class PinnedType : TypeSpecification { | |
public override bool IsValueType { | |
get { return false; } | |
set { throw new InvalidOperationException (); } | |
} | |
public override bool IsPinned { | |
get { return true; } | |
} | |
public PinnedType (TypeReference type) | |
: base (type) | |
{ | |
Mixin.CheckType (type); | |
this.etype = MD.ElementType.Pinned; | |
} | |
} | |
} | |
} | |
#endregion | |
#region Mono.Cecil\*.cs | |
namespace Internal { | |
// | |
// Author: | |
// Jb Evain (jbevain@gmail.com) | |
// | |
// Copyright (c) 2008 - 2015 Jb Evain | |
// Copyright (c) 2008 - 2011 Novell, Inc. | |
// | |
// Licensed under the MIT/X11 license. | |
// | |
using System; | |
namespace Mono.Cecil { | |
[Flags] | |
internal enum PInvokeAttributes : ushort { | |
NoMangle = 0x0001, // PInvoke is to use the member name as specified | |
// Character set | |
CharSetMask = 0x0006, | |
CharSetNotSpec = 0x0000, | |
CharSetAnsi = 0x0002, | |
CharSetUnicode = 0x0004, | |
CharSetAuto = 0x0006, | |
SupportsLastError = 0x0040, // Information about target function. Not relevant for fields | |
// Calling convetion | |
CallConvMask = 0x0700, | |
CallConvWinapi = 0x0100, | |
CallConvCdecl = 0x0200, | |
CallConvStdCall = 0x0300, | |
CallConvThiscall = 0x0400, | |
CallConvFastcall = 0x0500, | |
BestFitMask = 0x0030, | |
BestFitEnabled = 0x0010, | |
BestFitDisabled = 0x0020, | |
ThrowOnUnmappableCharMask = 0x3000, | |
ThrowOnUnmappableCharEnabled = 0x1000, | |
ThrowOnUnmappableCharDisabled = 0x2000, | |
} | |
} | |
} | |
#endregion | |
#region Mono.Cecil\*.cs | |
namespace Internal { | |
// | |
// Author: | |
// Jb Evain (jbevain@gmail.com) | |
// | |
// Copyright (c) 2008 - 2015 Jb Evain | |
// Copyright (c) 2008 - 2011 Novell, Inc. | |
// | |
// Licensed under the MIT/X11 license. | |
// | |
namespace Mono.Cecil { | |
internal sealed class PInvokeInfo { | |
ushort attributes; | |
string entry_point; | |
ModuleReference module; | |
public PInvokeAttributes Attributes { | |
get { return (PInvokeAttributes) attributes; } | |
set { attributes = (ushort) value; } | |
} | |
public string EntryPoint { | |
get { return entry_point; } | |
set { entry_point = value; } | |
} | |
public ModuleReference Module { | |
get { return module; } | |
set { module = value; } | |
} | |
#region PInvokeAttributes | |
public bool IsNoMangle { | |
get { return attributes.GetAttributes ((ushort) PInvokeAttributes.NoMangle); } | |
set { attributes = attributes.SetAttributes ((ushort) PInvokeAttributes.NoMangle, value); } | |
} | |
public bool IsCharSetNotSpec { | |
get { return attributes.GetMaskedAttributes((ushort) PInvokeAttributes.CharSetMask, (ushort) PInvokeAttributes.CharSetNotSpec); } | |
set { attributes = attributes.SetMaskedAttributes ((ushort) PInvokeAttributes.CharSetMask, (ushort) PInvokeAttributes.CharSetNotSpec, value); } | |
} | |
public bool IsCharSetAnsi { | |
get { return attributes.GetMaskedAttributes ((ushort) PInvokeAttributes.CharSetMask, (ushort) PInvokeAttributes.CharSetAnsi); } | |
set { attributes = attributes.SetMaskedAttributes ((ushort) PInvokeAttributes.CharSetMask, (ushort) PInvokeAttributes.CharSetAnsi, value); } | |
} | |
public bool IsCharSetUnicode { | |
get { return attributes.GetMaskedAttributes ((ushort) PInvokeAttributes.CharSetMask, (ushort) PInvokeAttributes.CharSetUnicode); } | |
set { attributes = attributes.SetMaskedAttributes ((ushort) PInvokeAttributes.CharSetMask, (ushort) PInvokeAttributes.CharSetUnicode, value); } | |
} | |
public bool IsCharSetAuto { | |
get { return attributes.GetMaskedAttributes ((ushort) PInvokeAttributes.CharSetMask, (ushort) PInvokeAttributes.CharSetAuto); } | |
set { attributes = attributes.SetMaskedAttributes ((ushort) PInvokeAttributes.CharSetMask, (ushort) PInvokeAttributes.CharSetAuto, value); } | |
} | |
public bool SupportsLastError { | |
get { return attributes.GetAttributes ((ushort) PInvokeAttributes.SupportsLastError); } | |
set { attributes = attributes.SetAttributes ((ushort) PInvokeAttributes.SupportsLastError, value); } | |
} | |
public bool IsCallConvWinapi { | |
get { return attributes.GetMaskedAttributes((ushort) PInvokeAttributes.CallConvMask, (ushort) PInvokeAttributes.CallConvWinapi); } | |
set { attributes = attributes.SetMaskedAttributes ((ushort) PInvokeAttributes.CallConvMask, (ushort) PInvokeAttributes.CallConvWinapi, value); } | |
} | |
public bool IsCallConvCdecl { | |
get { return attributes.GetMaskedAttributes ((ushort) PInvokeAttributes.CallConvMask, (ushort) PInvokeAttributes.CallConvCdecl); } | |
set { attributes = attributes.SetMaskedAttributes ((ushort) PInvokeAttributes.CallConvMask, (ushort) PInvokeAttributes.CallConvCdecl, value); } | |
} | |
public bool IsCallConvStdCall { | |
get { return attributes.GetMaskedAttributes ((ushort) PInvokeAttributes.CallConvMask, (ushort) PInvokeAttributes.CallConvStdCall); } | |
set { attributes = attributes.SetMaskedAttributes ((ushort) PInvokeAttributes.CallConvMask, (ushort) PInvokeAttributes.CallConvStdCall, value); } | |
} | |
public bool IsCallConvThiscall { | |
get { return attributes.GetMaskedAttributes ((ushort) PInvokeAttributes.CallConvMask, (ushort) PInvokeAttributes.CallConvThiscall); } | |
set { attributes = attributes.SetMaskedAttributes ((ushort) PInvokeAttributes.CallConvMask, (ushort) PInvokeAttributes.CallConvThiscall, value); } | |
} | |
public bool IsCallConvFastcall { | |
get { return attributes.GetMaskedAttributes ((ushort) PInvokeAttributes.CallConvMask, (ushort) PInvokeAttributes.CallConvFastcall); } | |
set { attributes = attributes.SetMaskedAttributes ((ushort) PInvokeAttributes.CallConvMask, (ushort) PInvokeAttributes.CallConvFastcall, value); } | |
} | |
public bool IsBestFitEnabled { | |
get { return attributes.GetMaskedAttributes ((ushort) PInvokeAttributes.BestFitMask, (ushort) PInvokeAttributes.BestFitEnabled); } | |
set { attributes = attributes.SetMaskedAttributes ((ushort) PInvokeAttributes.BestFitMask, (ushort) PInvokeAttributes.BestFitEnabled, value); } | |
} | |
public bool IsBestFitDisabled { | |
get { return attributes.GetMaskedAttributes ((ushort) PInvokeAttributes.BestFitMask, (ushort) PInvokeAttributes.BestFitDisabled); } | |
set { attributes = attributes.SetMaskedAttributes ((ushort) PInvokeAttributes.BestFitMask, (ushort) PInvokeAttributes.BestFitDisabled, value); } | |
} | |
public bool IsThrowOnUnmappableCharEnabled { | |
get { return attributes.GetMaskedAttributes ((ushort) PInvokeAttributes.ThrowOnUnmappableCharMask, (ushort) PInvokeAttributes.ThrowOnUnmappableCharEnabled); } | |
set { attributes = attributes.SetMaskedAttributes ((ushort) PInvokeAttributes.ThrowOnUnmappableCharMask, (ushort) PInvokeAttributes.ThrowOnUnmappableCharEnabled, value); } | |
} | |
public bool IsThrowOnUnmappableCharDisabled { | |
get { return attributes.GetMaskedAttributes ((ushort) PInvokeAttributes.ThrowOnUnmappableCharMask, (ushort) PInvokeAttributes.ThrowOnUnmappableCharDisabled); } | |
set { attributes = attributes.SetMaskedAttributes ((ushort) PInvokeAttributes.ThrowOnUnmappableCharMask, (ushort) PInvokeAttributes.ThrowOnUnmappableCharDisabled, value); } | |
} | |
#endregion | |
public PInvokeInfo (PInvokeAttributes attributes, string entryPoint, ModuleReference module) | |
{ | |
this.attributes = (ushort) attributes; | |
this.entry_point = entryPoint; | |
this.module = module; | |
} | |
} | |
} | |
} | |
#endregion | |
#region Mono.Cecil\*.cs | |
namespace Internal { | |
// | |
// Author: | |
// Jb Evain (jbevain@gmail.com) | |
// | |
// Copyright (c) 2008 - 2015 Jb Evain | |
// Copyright (c) 2008 - 2011 Novell, Inc. | |
// | |
// Licensed under the MIT/X11 license. | |
// | |
using System; | |
using MD = Mono.Cecil.Metadata; | |
namespace Mono.Cecil { | |
internal sealed class PointerType : TypeSpecification { | |
public override string Name { | |
get { return base.Name + "*"; } | |
} | |
public override string FullName { | |
get { return base.FullName + "*"; } | |
} | |
public override bool IsValueType { | |
get { return false; } | |
set { throw new InvalidOperationException (); } | |
} | |
public override bool IsPointer { | |
get { return true; } | |
} | |
public PointerType (TypeReference type) | |
: base (type) | |
{ | |
Mixin.CheckType (type); | |
this.etype = MD.ElementType.Ptr; | |
} | |
} | |
} | |
} | |
#endregion | |
#region Mono.Cecil\*.cs | |
namespace Internal { | |
// | |
// Author: | |
// Jb Evain (jbevain@gmail.com) | |
// | |
// Copyright (c) 2008 - 2015 Jb Evain | |
// Copyright (c) 2008 - 2011 Novell, Inc. | |
// | |
// Licensed under the MIT/X11 license. | |
// | |
using System; | |
namespace Mono.Cecil { | |
[Flags] | |
internal enum PropertyAttributes : ushort { | |
None = 0x0000, | |
SpecialName = 0x0200, // Property is special | |
RTSpecialName = 0x0400, // Runtime(metadata internal APIs) should check name encoding | |
HasDefault = 0x1000, // Property has default | |
Unused = 0xe9ff // Reserved: shall be zero in a conforming implementation | |
} | |
} | |
} | |
#endregion | |
#region Mono.Cecil\*.cs | |
namespace Internal { | |
// | |
// Author: | |
// Jb Evain (jbevain@gmail.com) | |
// | |
// Copyright (c) 2008 - 2015 Jb Evain | |
// Copyright (c) 2008 - 2011 Novell, Inc. | |
// | |
// Licensed under the MIT/X11 license. | |
// | |
using System.Text; | |
using Mono.Collections.Generic; | |
namespace Mono.Cecil { | |
internal sealed class PropertyDefinition : PropertyReference, IMemberDefinition, IConstantProvider { | |
bool? has_this; | |
ushort attributes; | |
Collection<CustomAttribute> custom_attributes; | |
internal MethodDefinition get_method; | |
internal MethodDefinition set_method; | |
internal Collection<MethodDefinition> other_methods; | |
object constant = Mixin.NotResolved; | |
public PropertyAttributes Attributes { | |
get { return (PropertyAttributes) attributes; } | |
set { attributes = (ushort) value; } | |
} | |
public bool HasThis { | |
get { | |
if (has_this.HasValue) | |
return has_this.Value; | |
if (GetMethod != null) | |
return get_method.HasThis; | |
if (SetMethod != null) | |
return set_method.HasThis; | |
return false; | |
} | |
set { has_this = value; } | |
} | |
public bool HasCustomAttributes { | |
get { | |
if (custom_attributes != null) | |
return custom_attributes.Count > 0; | |
return this.GetHasCustomAttributes (Module); | |
} | |
} | |
public Collection<CustomAttribute> CustomAttributes { | |
get { return custom_attributes ?? (this.GetCustomAttributes (ref custom_attributes, Module)); } | |
} | |
public MethodDefinition GetMethod { | |
get { | |
if (get_method != null) | |
return get_method; | |
InitializeMethods (); | |
return get_method; | |
} | |
set { get_method = value; } | |
} | |
public MethodDefinition SetMethod { | |
get { | |
if (set_method != null) | |
return set_method; | |
InitializeMethods (); | |
return set_method; | |
} | |
set { set_method = value; } | |
} | |
public bool HasOtherMethods { | |
get { | |
if (other_methods != null) | |
return other_methods.Count > 0; | |
InitializeMethods (); | |
return !other_methods.IsNullOrEmpty (); | |
} | |
} | |
public Collection<MethodDefinition> OtherMethods { | |
get { | |
if (other_methods != null) | |
return other_methods; | |
InitializeMethods (); | |
if (other_methods != null) | |
return other_methods; | |
return other_methods = new Collection<MethodDefinition> (); | |
} | |
} | |
public bool HasParameters { | |
get { | |
InitializeMethods (); | |
if (get_method != null) | |
return get_method.HasParameters; | |
if (set_method != null) | |
return set_method.HasParameters && set_method.Parameters.Count > 1; | |
return false; | |
} | |
} | |
public override Collection<ParameterDefinition> Parameters { | |
get { | |
InitializeMethods (); | |
if (get_method != null) | |
return MirrorParameters (get_method, 0); | |
if (set_method != null) | |
return MirrorParameters (set_method, 1); | |
return new Collection<ParameterDefinition> (); | |
} | |
} | |
static Collection<ParameterDefinition> MirrorParameters (MethodDefinition method, int bound) | |
{ | |
var parameters = new Collection<ParameterDefinition> (); | |
if (!method.HasParameters) | |
return parameters; | |
var original_parameters = method.Parameters; | |
var end = original_parameters.Count - bound; | |
for (int i = 0; i < end; i++) | |
parameters.Add (original_parameters [i]); | |
return parameters; | |
} | |
public bool HasConstant { | |
get { | |
this.ResolveConstant (ref constant, Module); | |
return constant != Mixin.NoValue; | |
} | |
set { if (!value) constant = Mixin.NoValue; } | |
} | |
public object Constant { | |
get { return HasConstant ? constant : null; } | |
set { constant = value; } | |
} | |
#region PropertyAttributes | |
public bool IsSpecialName { | |
get { return attributes.GetAttributes ((ushort) PropertyAttributes.SpecialName); } | |
set { attributes = attributes.SetAttributes ((ushort) PropertyAttributes.SpecialName, value); } | |
} | |
public bool IsRuntimeSpecialName { | |
get { return attributes.GetAttributes ((ushort) PropertyAttributes.RTSpecialName); } | |
set { attributes = attributes.SetAttributes ((ushort) PropertyAttributes.RTSpecialName, value); } | |
} | |
public bool HasDefault { | |
get { return attributes.GetAttributes ((ushort) PropertyAttributes.HasDefault); } | |
set { attributes = attributes.SetAttributes ((ushort) PropertyAttributes.HasDefault, value); } | |
} | |
#endregion | |
public new TypeDefinition DeclaringType { | |
get { return (TypeDefinition) base.DeclaringType; } | |
set { base.DeclaringType = value; } | |
} | |
public override bool IsDefinition { | |
get { return true; } | |
} | |
public override string FullName { | |
get { | |
var builder = new StringBuilder (); | |
builder.Append (PropertyType.ToString ()); | |
builder.Append (' '); | |
builder.Append (MemberFullName ()); | |
builder.Append ('('); | |
if (HasParameters) { | |
var parameters = Parameters; | |
for (int i = 0; i < parameters.Count; i++) { | |
if (i > 0) | |
builder.Append (','); | |
builder.Append (parameters [i].ParameterType.FullName); | |
} | |
} | |
builder.Append (')'); | |
return builder.ToString (); | |
} | |
} | |
public PropertyDefinition (string name, PropertyAttributes attributes, TypeReference propertyType) | |
: base (name, propertyType) | |
{ | |
this.attributes = (ushort) attributes; | |
this.token = new MetadataToken (TokenType.Property); | |
} | |
void InitializeMethods () | |
{ | |
var module = this.Module; | |
if (module == null) | |
return; | |
lock (module.SyncRoot) { | |
if (get_method != null || set_method != null) | |
return; | |
if (!module.HasImage ()) | |
return; | |
module.Read (this, (property, reader) => reader.ReadMethods (property)); | |
} | |
} | |
public override PropertyDefinition Resolve () | |
{ | |
return this; | |
} | |
} | |
} | |
} | |
#endregion | |
#region Mono.Cecil\*.cs | |
namespace Internal { | |
// | |
// Author: | |
// Jb Evain (jbevain@gmail.com) | |
// | |
// Copyright (c) 2008 - 2015 Jb Evain | |
// Copyright (c) 2008 - 2011 Novell, Inc. | |
// | |
// Licensed under the MIT/X11 license. | |
// | |
using System; | |
using Mono.Collections.Generic; | |
namespace Mono.Cecil { | |
internal abstract class PropertyReference : MemberReference { | |
TypeReference property_type; | |
public TypeReference PropertyType { | |
get { return property_type; } | |
set { property_type = value; } | |
} | |
public abstract Collection<ParameterDefinition> Parameters { | |
get; | |
} | |
internal PropertyReference (string name, TypeReference propertyType) | |
: base (name) | |
{ | |
Mixin.CheckType (propertyType, Mixin.Argument.propertyType); | |
property_type = propertyType; | |
} | |
protected override IMemberDefinition ResolveDefinition () | |
{ | |
return this.Resolve (); | |
} | |
public new abstract PropertyDefinition Resolve (); | |
} | |
} | |
} | |
#endregion | |
#region Mono.Cecil\*.cs | |
namespace Internal { | |
// | |
// Author: | |
// Jb Evain (jbevain@gmail.com) | |
// | |
// Copyright (c) 2008 - 2015 Jb Evain | |
// Copyright (c) 2008 - 2011 Novell, Inc. | |
// | |
// Licensed under the MIT/X11 license. | |
// | |
using System; | |
using MD = Mono.Cecil.Metadata; | |
namespace Mono.Cecil { | |
internal sealed class ByReferenceType : TypeSpecification { | |
public override string Name { | |
get { return base.Name + "&"; } | |
} | |
public override string FullName { | |
get { return base.FullName + "&"; } | |
} | |
public override bool IsValueType { | |
get { return false; } | |
set { throw new InvalidOperationException (); } | |
} | |
public override bool IsByReference { | |
get { return true; } | |
} | |
public ByReferenceType (TypeReference type) | |
: base (type) | |
{ | |
Mixin.CheckType (type); | |
this.etype = MD.ElementType.ByRef; | |
} | |
} | |
} | |
} | |
#endregion | |
#region Mono.Cecil\*.cs | |
namespace Internal { | |
// | |
// Author: | |
// Jb Evain (jbevain@gmail.com) | |
// | |
// Copyright (c) 2008 - 2015 Jb Evain | |
// Copyright (c) 2008 - 2011 Novell, Inc. | |
// | |
// Licensed under the MIT/X11 license. | |
// | |
namespace Mono.Cecil { | |
internal enum ResourceType { | |
Linked, | |
Embedded, | |
AssemblyLinked, | |
} | |
internal abstract class Resource { | |
string name; | |
uint attributes; | |
public string Name { | |
get { return name; } | |
set { name = value; } | |
} | |
public ManifestResourceAttributes Attributes { | |
get { return (ManifestResourceAttributes) attributes; } | |
set { attributes = (uint) value; } | |
} | |
public abstract ResourceType ResourceType { | |
get; | |
} | |
#region ManifestResourceAttributes | |
public bool IsPublic { | |
get { return attributes.GetMaskedAttributes ((uint) ManifestResourceAttributes.VisibilityMask, (uint) ManifestResourceAttributes.Public); } | |
set { attributes = attributes.SetMaskedAttributes ((uint) ManifestResourceAttributes.VisibilityMask, (uint) ManifestResourceAttributes.Public, value); } | |
} | |
public bool IsPrivate { | |
get { return attributes.GetMaskedAttributes ((uint) ManifestResourceAttributes.VisibilityMask, (uint) ManifestResourceAttributes.Private); } | |
set { attributes = attributes.SetMaskedAttributes ((uint) ManifestResourceAttributes.VisibilityMask, (uint) ManifestResourceAttributes.Private, value); } | |
} | |
#endregion | |
internal Resource (string name, ManifestResourceAttributes attributes) | |
{ | |
this.name = name; | |
this.attributes = (uint) attributes; | |
} | |
} | |
} | |
} | |
#endregion | |
#region Mono.Cecil\*.cs | |
namespace Internal { | |
// | |
// Author: | |
// Jb Evain (jbevain@gmail.com) | |
// | |
// Copyright (c) 2008 - 2015 Jb Evain | |
// Copyright (c) 2008 - 2011 Novell, Inc. | |
// | |
// Licensed under the MIT/X11 license. | |
// | |
using System; | |
using System.Diagnostics; | |
using Mono.Collections.Generic; | |
namespace Mono.Cecil { | |
internal enum SecurityAction : ushort { | |
Request = 1, | |
Demand = 2, | |
Assert = 3, | |
Deny = 4, | |
PermitOnly = 5, | |
LinkDemand = 6, | |
InheritDemand = 7, | |
RequestMinimum = 8, | |
RequestOptional = 9, | |
RequestRefuse = 10, | |
PreJitGrant = 11, | |
PreJitDeny = 12, | |
NonCasDemand = 13, | |
NonCasLinkDemand = 14, | |
NonCasInheritance = 15 | |
} | |
internal interface ISecurityDeclarationProvider : IMetadataTokenProvider { | |
bool HasSecurityDeclarations { get; } | |
Collection<SecurityDeclaration> SecurityDeclarations { get; } | |
} | |
[DebuggerDisplay ("{AttributeType}")] | |
internal sealed class SecurityAttribute : ICustomAttribute { | |
TypeReference attribute_type; | |
internal Collection<CustomAttributeNamedArgument> fields; | |
internal Collection<CustomAttributeNamedArgument> properties; | |
public TypeReference AttributeType { | |
get { return attribute_type; } | |
set { attribute_type = value; } | |
} | |
public bool HasFields { | |
get { return !fields.IsNullOrEmpty (); } | |
} | |
public Collection<CustomAttributeNamedArgument> Fields { | |
get { return fields ?? (fields = new Collection<CustomAttributeNamedArgument> ()); } | |
} | |
public bool HasProperties { | |
get { return !properties.IsNullOrEmpty (); } | |
} | |
public Collection<CustomAttributeNamedArgument> Properties { | |
get { return properties ?? (properties = new Collection<CustomAttributeNamedArgument> ()); } | |
} | |
public SecurityAttribute (TypeReference attributeType) | |
{ | |
this.attribute_type = attributeType; | |
} | |
bool ICustomAttribute.HasConstructorArguments { | |
get { return false; } | |
} | |
Collection<CustomAttributeArgument> ICustomAttribute.ConstructorArguments { | |
get { throw new NotSupportedException (); } | |
} | |
} | |
internal sealed class SecurityDeclaration { | |
readonly internal uint signature; | |
byte [] blob; | |
readonly ModuleDefinition module; | |
internal bool resolved; | |
SecurityAction action; | |
internal Collection<SecurityAttribute> security_attributes; | |
public SecurityAction Action { | |
get { return action; } | |
set { action = value; } | |
} | |
public bool HasSecurityAttributes { | |
get { | |
Resolve (); | |
return !security_attributes.IsNullOrEmpty (); | |
} | |
} | |
public Collection<SecurityAttribute> SecurityAttributes { | |
get { | |
Resolve (); | |
return security_attributes ?? (security_attributes = new Collection<SecurityAttribute> ()); | |
} | |
} | |
internal bool HasImage { | |
get { return module != null && module.HasImage; } | |
} | |
internal SecurityDeclaration (SecurityAction action, uint signature, ModuleDefinition module) | |
{ | |
this.action = action; | |
this.signature = signature; | |
this.module = module; | |
} | |
public SecurityDeclaration (SecurityAction action) | |
{ | |
this.action = action; | |
this.resolved = true; | |
} | |
public SecurityDeclaration (SecurityAction action, byte [] blob) | |
{ | |
this.action = action; | |
this.resolved = false; | |
this.blob = blob; | |
} | |
public byte [] GetBlob () | |
{ | |
if (blob != null) | |
return blob; | |
if (!HasImage || signature == 0) | |
throw new NotSupportedException (); | |
return blob = module.Read (this, (declaration, reader) => reader.ReadSecurityDeclarationBlob (declaration.signature)); | |
} | |
void Resolve () | |
{ | |
if (resolved || !HasImage) | |
return; | |
module.Read (this, (declaration, reader) => reader.ReadSecurityDeclarationSignature (declaration)); | |
resolved = true; | |
} | |
} | |
static partial class Mixin { | |
public static bool GetHasSecurityDeclarations ( | |
this ISecurityDeclarationProvider self, | |
ModuleDefinition module) | |
{ | |
return module.HasImage () && module.Read (self, (provider, reader) => reader.HasSecurityDeclarations (provider)); | |
} | |
public static Collection<SecurityDeclaration> GetSecurityDeclarations ( | |
this ISecurityDeclarationProvider self, | |
ref Collection<SecurityDeclaration> variable, | |
ModuleDefinition module) | |
{ | |
return module.HasImage () | |
? module.Read (ref variable, self, (provider, reader) => reader.ReadSecurityDeclarations (provider)) | |
: variable = new Collection<SecurityDeclaration>(); | |
} | |
} | |
} | |
} | |
#endregion | |
#region Mono.Cecil\*.cs | |
namespace Internal { | |
// | |
// Author: | |
// Jb Evain (jbevain@gmail.com) | |
// | |
// Copyright (c) 2008 - 2015 Jb Evain | |
// Copyright (c) 2008 - 2011 Novell, Inc. | |
// | |
// Licensed under the MIT/X11 license. | |
// | |
using System; | |
using MD = Mono.Cecil.Metadata; | |
namespace Mono.Cecil { | |
internal sealed class SentinelType : TypeSpecification { | |
public override bool IsValueType { | |
get { return false; } | |
set { throw new InvalidOperationException (); } | |
} | |
public override bool IsSentinel { | |
get { return true; } | |
} | |
public SentinelType (TypeReference type) | |
: base (type) | |
{ | |
Mixin.CheckType (type); | |
this.etype = MD.ElementType.Sentinel; | |
} | |
} | |
} | |
} | |
#endregion | |
#region Mono.Cecil\*.cs | |
namespace Internal { | |
// | |
// Author: | |
// Jb Evain (jbevain@gmail.com) | |
// | |
// Copyright (c) 2008 - 2015 Jb Evain | |
// Copyright (c) 2008 - 2011 Novell, Inc. | |
// | |
// Licensed under the MIT/X11 license. | |
// | |
namespace Mono.Cecil { | |
internal enum TargetRuntime { | |
Net_1_0, | |
Net_1_1, | |
Net_2_0, | |
Net_4_0, | |
} | |
} | |
} | |
#endregion | |
#region Mono.Cecil\*.cs | |
namespace Internal { | |
// | |
// Author: | |
// Jb Evain (jbevain@gmail.com) | |
// | |
// Copyright (c) 2008 - 2015 Jb Evain | |
// Copyright (c) 2008 - 2011 Novell, Inc. | |
// | |
// Licensed under the MIT/X11 license. | |
// | |
using System; | |
namespace Mono.Cecil { | |
[Flags] | |
enum TypeDefinitionTreatment { | |
None = 0x0, | |
KindMask = 0xf, | |
NormalType = 0x1, | |
NormalAttribute = 0x2, | |
UnmangleWindowsRuntimeName = 0x3, | |
PrefixWindowsRuntimeName = 0x4, | |
RedirectToClrType = 0x5, | |
RedirectToClrAttribute = 0x6, | |
Abstract = 0x10, | |
Internal = 0x20, | |
} | |
enum TypeReferenceTreatment { | |
None = 0x0, | |
SystemDelegate = 0x1, | |
SystemAttribute = 0x2, | |
UseProjectionInfo = 0x3, | |
} | |
[Flags] | |
enum MethodDefinitionTreatment { | |
None = 0x0, | |
Dispose = 0x1, | |
Abstract = 0x2, | |
Private = 0x4, | |
Public = 0x8, | |
Runtime = 0x10, | |
InternalCall = 0x20, | |
} | |
enum FieldDefinitionTreatment { | |
None = 0x0, | |
Public = 0x1, | |
} | |
enum MemberReferenceTreatment { | |
None = 0x0, | |
Dispose = 0x1, | |
} | |
enum CustomAttributeValueTreatment { | |
None = 0x0, | |
AllowSingle = 0x1, | |
AllowMultiple = 0x2, | |
VersionAttribute = 0x3, | |
DeprecatedAttribute = 0x4, | |
} | |
} | |
} | |
#endregion | |
#region Mono.Cecil\*.cs | |
namespace Internal { | |
// | |
// Author: | |
// Jb Evain (jbevain@gmail.com) | |
// | |
// Copyright (c) 2008 - 2015 Jb Evain | |
// Copyright (c) 2008 - 2011 Novell, Inc. | |
// | |
// Licensed under the MIT/X11 license. | |
// | |
using System; | |
namespace Mono.Cecil { | |
[Flags] | |
internal enum TypeAttributes : uint { | |
// Visibility attributes | |
VisibilityMask = 0x00000007, // Use this mask to retrieve visibility information | |
NotPublic = 0x00000000, // Class has no public scope | |
Public = 0x00000001, // Class has public scope | |
NestedPublic = 0x00000002, // Class is nested with public visibility | |
NestedPrivate = 0x00000003, // Class is nested with private visibility | |
NestedFamily = 0x00000004, // Class is nested with family visibility | |
NestedAssembly = 0x00000005, // Class is nested with assembly visibility | |
NestedFamANDAssem = 0x00000006, // Class is nested with family and assembly visibility | |
NestedFamORAssem = 0x00000007, // Class is nested with family or assembly visibility | |
// Class layout attributes | |
LayoutMask = 0x00000018, // Use this mask to retrieve class layout information | |
AutoLayout = 0x00000000, // Class fields are auto-laid out | |
SequentialLayout = 0x00000008, // Class fields are laid out sequentially | |
ExplicitLayout = 0x00000010, // Layout is supplied explicitly | |
// Class semantics attributes | |
ClassSemanticMask = 0x00000020, // Use this mask to retrieve class semantics information | |
Class = 0x00000000, // Type is a class | |
Interface = 0x00000020, // Type is an interface | |
// Special semantics in addition to class semantics | |
Abstract = 0x00000080, // Class is abstract | |
Sealed = 0x00000100, // Class cannot be extended | |
SpecialName = 0x00000400, // Class name is special | |
// Implementation attributes | |
Import = 0x00001000, // Class/Interface is imported | |
Serializable = 0x00002000, // Class is serializable | |
WindowsRuntime = 0x00004000, // Windows Runtime type | |
// String formatting attributes | |
StringFormatMask = 0x00030000, // Use this mask to retrieve string information for native interop | |
AnsiClass = 0x00000000, // LPSTR is interpreted as ANSI | |
UnicodeClass = 0x00010000, // LPSTR is interpreted as Unicode | |
AutoClass = 0x00020000, // LPSTR is interpreted automatically | |
// Class initialization attributes | |
BeforeFieldInit = 0x00100000, // Initialize the class before first static field access | |
// Additional flags | |
RTSpecialName = 0x00000800, // CLI provides 'special' behavior, depending upon the name of the Type | |
HasSecurity = 0x00040000, // Type has security associate with it | |
Forwarder = 0x00200000, // Exported type is a type forwarder | |
} | |
} | |
} | |
#endregion | |
#region Mono.Cecil\*.cs | |
namespace Internal { | |
// | |
// Author: | |
// Jb Evain (jbevain@gmail.com) | |
// | |
// Copyright (c) 2008 - 2015 Jb Evain | |
// Copyright (c) 2008 - 2011 Novell, Inc. | |
// | |
// Licensed under the MIT/X11 license. | |
// | |
using System; | |
using Mono.Cecil.Metadata; | |
using Mono.Collections.Generic; | |
namespace Mono.Cecil { | |
internal sealed class TypeDefinition : TypeReference, IMemberDefinition, ISecurityDeclarationProvider { | |
uint attributes; | |
TypeReference base_type; | |
internal Range fields_range; | |
internal Range methods_range; | |
short packing_size = Mixin.NotResolvedMarker; | |
int class_size = Mixin.NotResolvedMarker; | |
InterfaceImplementationCollection interfaces; | |
Collection<TypeDefinition> nested_types; | |
Collection<MethodDefinition> methods; | |
Collection<FieldDefinition> fields; | |
Collection<EventDefinition> events; | |
Collection<PropertyDefinition> properties; | |
Collection<CustomAttribute> custom_attributes; | |
Collection<SecurityDeclaration> security_declarations; | |
public TypeAttributes Attributes { | |
get { return (TypeAttributes) attributes; } | |
set { | |
if (IsWindowsRuntimeProjection && (ushort) value != attributes) | |
throw new InvalidOperationException (); | |
attributes = (uint) value; | |
} | |
} | |
public TypeReference BaseType { | |
get { return base_type; } | |
set { base_type = value; } | |
} | |
public override string Name { | |
get { return base.Name; } | |
set { | |
if (IsWindowsRuntimeProjection && value != base.Name) | |
throw new InvalidOperationException (); | |
base.Name = value; | |
} | |
} | |
void ResolveLayout () | |
{ | |
if (packing_size != Mixin.NotResolvedMarker || class_size != Mixin.NotResolvedMarker) | |
return; | |
if (!HasImage) { | |
packing_size = Mixin.NoDataMarker; | |
class_size = Mixin.NoDataMarker; | |
return; | |
} | |
var row = Module.Read (this, (type, reader) => reader.ReadTypeLayout (type)); | |
packing_size = row.Col1; | |
class_size = row.Col2; | |
} | |
public bool HasLayoutInfo { | |
get { | |
if (packing_size >= 0 || class_size >= 0) | |
return true; | |
ResolveLayout (); | |
return packing_size >= 0 || class_size >= 0; | |
} | |
} | |
public short PackingSize { | |
get { | |
if (packing_size >= 0) | |
return packing_size; | |
ResolveLayout (); | |
return packing_size >= 0 ? packing_size : (short) -1; | |
} | |
set { packing_size = value; } | |
} | |
public int ClassSize { | |
get { | |
if (class_size >= 0) | |
return class_size; | |
ResolveLayout (); | |
return class_size >= 0 ? class_size : -1; | |
} | |
set { class_size = value; } | |
} | |
public bool HasInterfaces { | |
get { | |
if (interfaces != null) | |
return interfaces.Count > 0; | |
return HasImage && Module.Read (this, (type, reader) => reader.HasInterfaces (type)); | |
} | |
} | |
public Collection<InterfaceImplementation> Interfaces { | |
get { | |
if (interfaces != null) | |
return interfaces; | |
if (HasImage) | |
return Module.Read (ref interfaces, this, (type, reader) => reader.ReadInterfaces (type)); | |
return interfaces = new InterfaceImplementationCollection (this); | |
} | |
} | |
public bool HasNestedTypes { | |
get { | |
if (nested_types != null) | |
return nested_types.Count > 0; | |
return HasImage && Module.Read (this, (type, reader) => reader.HasNestedTypes (type)); | |
} | |
} | |
public Collection<TypeDefinition> NestedTypes { | |
get { | |
if (nested_types != null) | |
return nested_types; | |
if (HasImage) | |
return Module.Read (ref nested_types, this, (type, reader) => reader.ReadNestedTypes (type)); | |
return nested_types = new MemberDefinitionCollection<TypeDefinition> (this); | |
} | |
} | |
public bool HasMethods { | |
get { | |
if (methods != null) | |
return methods.Count > 0; | |
return HasImage && methods_range.Length > 0; | |
} | |
} | |
public Collection<MethodDefinition> Methods { | |
get { | |
if (methods != null) | |
return methods; | |
if (HasImage) | |
return Module.Read (ref methods, this, (type, reader) => reader.ReadMethods (type)); | |
return methods = new MemberDefinitionCollection<MethodDefinition> (this); | |
} | |
} | |
public bool HasFields { | |
get { | |
if (fields != null) | |
return fields.Count > 0; | |
return HasImage && fields_range.Length > 0; | |
} | |
} | |
public Collection<FieldDefinition> Fields { | |
get { | |
if (fields != null) | |
return fields; | |
if (HasImage) | |
return Module.Read (ref fields, this, (type, reader) => reader.ReadFields (type)); | |
return fields = new MemberDefinitionCollection<FieldDefinition> (this); | |
} | |
} | |
public bool HasEvents { | |
get { | |
if (events != null) | |
return events.Count > 0; | |
return HasImage && Module.Read (this, (type, reader) => reader.HasEvents (type)); | |
} | |
} | |
public Collection<EventDefinition> Events { | |
get { | |
if (events != null) | |
return events; | |
if (HasImage) | |
return Module.Read (ref events, this, (type, reader) => reader.ReadEvents (type)); | |
return events = new MemberDefinitionCollection<EventDefinition> (this); | |
} | |
} | |
public bool HasProperties { | |
get { | |
if (properties != null) | |
return properties.Count > 0; | |
return HasImage && Module.Read (this, (type, reader) => reader.HasProperties (type)); | |
} | |
} | |
public Collection<PropertyDefinition> Properties { | |
get { | |
if (properties != null) | |
return properties; | |
if (HasImage) | |
return Module.Read (ref properties, this, (type, reader) => reader.ReadProperties (type)); | |
return properties = new MemberDefinitionCollection<PropertyDefinition> (this); | |
} | |
} | |
public bool HasSecurityDeclarations { | |
get { | |
if (security_declarations != null) | |
return security_declarations.Count > 0; | |
return this.GetHasSecurityDeclarations (Module); | |
} | |
} | |
public Collection<SecurityDeclaration> SecurityDeclarations { | |
get { return security_declarations ?? (this.GetSecurityDeclarations (ref security_declarations, Module)); } | |
} | |
public bool HasCustomAttributes { | |
get { | |
if (custom_attributes != null) | |
return custom_attributes.Count > 0; | |
return this.GetHasCustomAttributes (Module); | |
} | |
} | |
public Collection<CustomAttribute> CustomAttributes { | |
get { return custom_attributes ?? (this.GetCustomAttributes (ref custom_attributes, Module)); } | |
} | |
public override bool HasGenericParameters { | |
get { | |
if (generic_parameters != null) | |
return generic_parameters.Count > 0; | |
return this.GetHasGenericParameters (Module); | |
} | |
} | |
public override Collection<GenericParameter> GenericParameters { | |
get { return generic_parameters ?? (this.GetGenericParameters (ref generic_parameters, Module)); } | |
} | |
#region TypeAttributes | |
public bool IsNotPublic { | |
get { return attributes.GetMaskedAttributes ((uint) TypeAttributes.VisibilityMask, (uint) TypeAttributes.NotPublic); } | |
set { attributes = attributes.SetMaskedAttributes ((uint) TypeAttributes.VisibilityMask, (uint) TypeAttributes.NotPublic, value); } | |
} | |
public bool IsPublic { | |
get { return attributes.GetMaskedAttributes ((uint) TypeAttributes.VisibilityMask, (uint) TypeAttributes.Public); } | |
set { attributes = attributes.SetMaskedAttributes ((uint) TypeAttributes.VisibilityMask, (uint) TypeAttributes.Public, value); } | |
} | |
public bool IsNestedPublic { | |
get { return attributes.GetMaskedAttributes ((uint) TypeAttributes.VisibilityMask, (uint) TypeAttributes.NestedPublic); } | |
set { attributes = attributes.SetMaskedAttributes ((uint) TypeAttributes.VisibilityMask, (uint) TypeAttributes.NestedPublic, value); } | |
} | |
public bool IsNestedPrivate { | |
get { return attributes.GetMaskedAttributes ((uint) TypeAttributes.VisibilityMask, (uint) TypeAttributes.NestedPrivate); } | |
set { attributes = attributes.SetMaskedAttributes ((uint) TypeAttributes.VisibilityMask, (uint) TypeAttributes.NestedPrivate, value); } | |
} | |
public bool IsNestedFamily { | |
get { return attributes.GetMaskedAttributes ((uint) TypeAttributes.VisibilityMask, (uint) TypeAttributes.NestedFamily); } | |
set { attributes = attributes.SetMaskedAttributes ((uint) TypeAttributes.VisibilityMask, (uint) TypeAttributes.NestedFamily, value); } | |
} | |
public bool IsNestedAssembly { | |
get { return attributes.GetMaskedAttributes ((uint) TypeAttributes.VisibilityMask, (uint) TypeAttributes.NestedAssembly); } | |
set { attributes = attributes.SetMaskedAttributes ((uint) TypeAttributes.VisibilityMask, (uint) TypeAttributes.NestedAssembly, value); } | |
} | |
public bool IsNestedFamilyAndAssembly { | |
get { return attributes.GetMaskedAttributes ((uint) TypeAttributes.VisibilityMask, (uint) TypeAttributes.NestedFamANDAssem); } | |
set { attributes = attributes.SetMaskedAttributes ((uint) TypeAttributes.VisibilityMask, (uint) TypeAttributes.NestedFamANDAssem, value); } | |
} | |
public bool IsNestedFamilyOrAssembly { | |
get { return attributes.GetMaskedAttributes ((uint) TypeAttributes.VisibilityMask, (uint) TypeAttributes.NestedFamORAssem); } | |
set { attributes = attributes.SetMaskedAttributes ((uint) TypeAttributes.VisibilityMask, (uint) TypeAttributes.NestedFamORAssem, value); } | |
} | |
public bool IsAutoLayout { | |
get { return attributes.GetMaskedAttributes ((uint) TypeAttributes.LayoutMask, (uint) TypeAttributes.AutoLayout); } | |
set { attributes = attributes.SetMaskedAttributes ((uint) TypeAttributes.LayoutMask, (uint) TypeAttributes.AutoLayout, value); } | |
} | |
public bool IsSequentialLayout { | |
get { return attributes.GetMaskedAttributes ((uint) TypeAttributes.LayoutMask, (uint) TypeAttributes.SequentialLayout); } | |
set { attributes = attributes.SetMaskedAttributes ((uint) TypeAttributes.LayoutMask, (uint) TypeAttributes.SequentialLayout, value); } | |
} | |
public bool IsExplicitLayout { | |
get { return attributes.GetMaskedAttributes ((uint) TypeAttributes.LayoutMask, (uint) TypeAttributes.ExplicitLayout); } | |
set { attributes = attributes.SetMaskedAttributes ((uint) TypeAttributes.LayoutMask, (uint) TypeAttributes.ExplicitLayout, value); } | |
} | |
public bool IsClass { | |
get { return attributes.GetMaskedAttributes ((uint) TypeAttributes.ClassSemanticMask, (uint) TypeAttributes.Class); } | |
set { attributes = attributes.SetMaskedAttributes ((uint) TypeAttributes.ClassSemanticMask, (uint) TypeAttributes.Class, value); } | |
} | |
public bool IsInterface { | |
get { return attributes.GetMaskedAttributes ((uint) TypeAttributes.ClassSemanticMask, (uint) TypeAttributes.Interface); } | |
set { attributes = attributes.SetMaskedAttributes ((uint) TypeAttributes.ClassSemanticMask, (uint) TypeAttributes.Interface, value); } | |
} | |
public bool IsAbstract { | |
get { return attributes.GetAttributes ((uint) TypeAttributes.Abstract); } | |
set { attributes = attributes.SetAttributes ((uint) TypeAttributes.Abstract, value); } | |
} | |
public bool IsSealed { | |
get { return attributes.GetAttributes ((uint) TypeAttributes.Sealed); } | |
set { attributes = attributes.SetAttributes ((uint) TypeAttributes.Sealed, value); } | |
} | |
public bool IsSpecialName { | |
get { return attributes.GetAttributes ((uint) TypeAttributes.SpecialName); } | |
set { attributes = attributes.SetAttributes ((uint) TypeAttributes.SpecialName, value); } | |
} | |
public bool IsImport { | |
get { return attributes.GetAttributes ((uint) TypeAttributes.Import); } | |
set { attributes = attributes.SetAttributes ((uint) TypeAttributes.Import, value); } | |
} | |
public bool IsSerializable { | |
get { return attributes.GetAttributes ((uint) TypeAttributes.Serializable); } | |
set { attributes = attributes.SetAttributes ((uint) TypeAttributes.Serializable, value); } | |
} | |
public bool IsWindowsRuntime { | |
get { return attributes.GetAttributes ((uint) TypeAttributes.WindowsRuntime); } | |
set { attributes = attributes.SetAttributes ((uint) TypeAttributes.WindowsRuntime, value); } | |
} | |
public bool IsAnsiClass { | |
get { return attributes.GetMaskedAttributes ((uint) TypeAttributes.StringFormatMask, (uint) TypeAttributes.AnsiClass); } | |
set { attributes = attributes.SetMaskedAttributes ((uint) TypeAttributes.StringFormatMask, (uint) TypeAttributes.AnsiClass, value); } | |
} | |
public bool IsUnicodeClass { | |
get { return attributes.GetMaskedAttributes ((uint) TypeAttributes.StringFormatMask, (uint) TypeAttributes.UnicodeClass); } | |
set { attributes = attributes.SetMaskedAttributes ((uint) TypeAttributes.StringFormatMask, (uint) TypeAttributes.UnicodeClass, value); } | |
} | |
public bool IsAutoClass { | |
get { return attributes.GetMaskedAttributes ((uint) TypeAttributes.StringFormatMask, (uint) TypeAttributes.AutoClass); } | |
set { attributes = attributes.SetMaskedAttributes ((uint) TypeAttributes.StringFormatMask, (uint) TypeAttributes.AutoClass, value); } | |
} | |
public bool IsBeforeFieldInit { | |
get { return attributes.GetAttributes ((uint) TypeAttributes.BeforeFieldInit); } | |
set { attributes = attributes.SetAttributes ((uint) TypeAttributes.BeforeFieldInit, value); } | |
} | |
public bool IsRuntimeSpecialName { | |
get { return attributes.GetAttributes ((uint) TypeAttributes.RTSpecialName); } | |
set { attributes = attributes.SetAttributes ((uint) TypeAttributes.RTSpecialName, value); } | |
} | |
public bool HasSecurity { | |
get { return attributes.GetAttributes ((uint) TypeAttributes.HasSecurity); } | |
set { attributes = attributes.SetAttributes ((uint) TypeAttributes.HasSecurity, value); } | |
} | |
#endregion | |
public bool IsEnum { | |
get { return base_type != null && base_type.IsTypeOf ("System", "Enum"); } | |
} | |
public override bool IsValueType { | |
get { | |
if (base_type == null) | |
return false; | |
return base_type.IsTypeOf ("System", "Enum") || (base_type.IsTypeOf ("System", "ValueType") && !this.IsTypeOf ("System", "Enum")); | |
} | |
set { | |
throw new NotSupportedException (); | |
} | |
} | |
public override bool IsPrimitive { | |
get { | |
ElementType primitive_etype; | |
return MetadataSystem.TryGetPrimitiveElementType (this, out primitive_etype) && primitive_etype.IsPrimitive (); | |
} | |
} | |
public override MetadataType MetadataType { | |
get { | |
ElementType primitive_etype; | |
if (MetadataSystem.TryGetPrimitiveElementType (this, out primitive_etype)) | |
return (MetadataType) primitive_etype; | |
return base.MetadataType; | |
} | |
} | |
public override bool IsDefinition { | |
get { return true; } | |
} | |
public new TypeDefinition DeclaringType { | |
get { return (TypeDefinition) base.DeclaringType; } | |
set { base.DeclaringType = value; } | |
} | |
internal new TypeDefinitionProjection WindowsRuntimeProjection { | |
get { return (TypeDefinitionProjection) projection; } | |
set { projection = value; } | |
} | |
public TypeDefinition (string @namespace, string name, TypeAttributes attributes) | |
: base (@namespace, name) | |
{ | |
this.attributes = (uint) attributes; | |
this.token = new MetadataToken (TokenType.TypeDef); | |
} | |
public TypeDefinition (string @namespace, string name, TypeAttributes attributes, TypeReference baseType) : | |
this (@namespace, name, attributes) | |
{ | |
this.BaseType = baseType; | |
} | |
protected override void ClearFullName () | |
{ | |
base.ClearFullName (); | |
if (!HasNestedTypes) | |
return; | |
var nested_types = this.NestedTypes; | |
for (int i = 0; i < nested_types.Count; i++) | |
nested_types [i].ClearFullName (); | |
} | |
public override TypeDefinition Resolve () | |
{ | |
return this; | |
} | |
} | |
internal sealed class InterfaceImplementation : ICustomAttributeProvider | |
{ | |
internal TypeDefinition type; | |
internal MetadataToken token; | |
TypeReference interface_type; | |
Collection<CustomAttribute> custom_attributes; | |
public TypeReference InterfaceType { | |
get { return interface_type; } | |
set { interface_type = value; } | |
} | |
public bool HasCustomAttributes { | |
get { | |
if (custom_attributes != null) | |
return custom_attributes.Count > 0; | |
if (type == null) | |
return false; | |
return this.GetHasCustomAttributes (type.Module); | |
} | |
} | |
public Collection<CustomAttribute> CustomAttributes { | |
get { | |
if (type == null) | |
return custom_attributes = new Collection<CustomAttribute> (); | |
return custom_attributes ?? (this.GetCustomAttributes (ref custom_attributes, type.Module)); | |
} | |
} | |
public MetadataToken MetadataToken { | |
get { return token; } | |
set { token = value; } | |
} | |
internal InterfaceImplementation (TypeReference interfaceType, MetadataToken token) | |
{ | |
this.interface_type = interfaceType; | |
this.token = token; | |
} | |
public InterfaceImplementation (TypeReference interfaceType) | |
{ | |
Mixin.CheckType (interfaceType, Mixin.Argument.interfaceType); | |
this.interface_type = interfaceType; | |
this.token = new MetadataToken (TokenType.InterfaceImpl); | |
} | |
} | |
class InterfaceImplementationCollection : Collection<InterfaceImplementation> | |
{ | |
readonly TypeDefinition type; | |
internal InterfaceImplementationCollection (TypeDefinition type) | |
{ | |
this.type = type; | |
} | |
internal InterfaceImplementationCollection (TypeDefinition type, int length) | |
: base (length) | |
{ | |
this.type = type; | |
} | |
protected override void OnAdd (InterfaceImplementation item, int index) | |
{ | |
item.type = type; | |
} | |
protected override void OnInsert (InterfaceImplementation item, int index) | |
{ | |
item.type = type; | |
} | |
protected override void OnSet (InterfaceImplementation item, int index) | |
{ | |
item.type = type; | |
} | |
protected override void OnRemove (InterfaceImplementation item, int index) | |
{ | |
item.type = null; | |
} | |
} | |
static partial class Mixin { | |
public static TypeReference GetEnumUnderlyingType (this TypeDefinition self) | |
{ | |
var fields = self.Fields; | |
for (int i = 0; i < fields.Count; i++) { | |
var field = fields [i]; | |
if (!field.IsStatic) | |
return field.FieldType; | |
} | |
throw new ArgumentException (); | |
} | |
public static TypeDefinition GetNestedType (this TypeDefinition self, string fullname) | |
{ | |
if (!self.HasNestedTypes) | |
return null; | |
var nested_types = self.NestedTypes; | |
for (int i = 0; i < nested_types.Count; i++) { | |
var nested_type = nested_types [i]; | |
if (nested_type.TypeFullName () == fullname) | |
return nested_type; | |
} | |
return null; | |
} | |
} | |
} | |
} | |
#endregion | |
#region Mono.Cecil\*.cs | |
namespace Internal { | |
// | |
// Author: | |
// Jb Evain (jbevain@gmail.com) | |
// | |
// Copyright (c) 2008 - 2015 Jb Evain | |
// Copyright (c) 2008 - 2011 Novell, Inc. | |
// | |
// Licensed under the MIT/X11 license. | |
// | |
using System; | |
using System.Collections.Generic; | |
using Mono.Cecil.Metadata; | |
using Mono.Collections.Generic; | |
namespace Mono.Cecil { | |
using Slot = Row<string, string>; | |
sealed class TypeDefinitionCollection : Collection<TypeDefinition> { | |
readonly ModuleDefinition container; | |
readonly Dictionary<Slot, TypeDefinition> name_cache; | |
internal TypeDefinitionCollection (ModuleDefinition container) | |
{ | |
this.container = container; | |
this.name_cache = new Dictionary<Slot, TypeDefinition> (new RowEqualityComparer ()); | |
} | |
internal TypeDefinitionCollection (ModuleDefinition container, int capacity) | |
: base (capacity) | |
{ | |
this.container = container; | |
this.name_cache = new Dictionary<Slot, TypeDefinition> (capacity, new RowEqualityComparer ()); | |
} | |
protected override void OnAdd (TypeDefinition item, int index) | |
{ | |
Attach (item); | |
} | |
protected override void OnSet (TypeDefinition item, int index) | |
{ | |
Attach (item); | |
} | |
protected override void OnInsert (TypeDefinition item, int index) | |
{ | |
Attach (item); | |
} | |
protected override void OnRemove (TypeDefinition item, int index) | |
{ | |
Detach (item); | |
} | |
protected override void OnClear () | |
{ | |
foreach (var type in this) | |
Detach (type); | |
} | |
void Attach (TypeDefinition type) | |
{ | |
if (type.Module != null && type.Module != container) | |
throw new ArgumentException ("Type already attached"); | |
type.module = container; | |
type.scope = container; | |
name_cache [new Slot (type.Namespace, type.Name)] = type; | |
} | |
void Detach (TypeDefinition type) | |
{ | |
type.module = null; | |
type.scope = null; | |
name_cache.Remove (new Slot (type.Namespace, type.Name)); | |
} | |
public TypeDefinition GetType (string fullname) | |
{ | |
string @namespace, name; | |
TypeParser.SplitFullName (fullname, out @namespace, out name); | |
return GetType (@namespace, name); | |
} | |
public TypeDefinition GetType (string @namespace, string name) | |
{ | |
TypeDefinition type; | |
if (name_cache.TryGetValue (new Slot (@namespace, name), out type)) | |
return type; | |
return null; | |
} | |
} | |
} | |
} | |
#endregion | |
#region Mono.Cecil\*.cs | |
namespace Internal { | |
// | |
// Author: | |
// Jb Evain (jbevain@gmail.com) | |
// | |
// Copyright (c) 2008 - 2015 Jb Evain | |
// Copyright (c) 2008 - 2011 Novell, Inc. | |
// | |
// Licensed under the MIT/X11 license. | |
// | |
using System; | |
using System.Text; | |
using Mono.Cecil.Metadata; | |
namespace Mono.Cecil { | |
class TypeParser { | |
class Type { | |
public const int Ptr = -1; | |
public const int ByRef = -2; | |
public const int SzArray = -3; | |
public string type_fullname; | |
public string [] nested_names; | |
public int arity; | |
public int [] specs; | |
public Type [] generic_arguments; | |
public string assembly; | |
} | |
readonly string fullname; | |
readonly int length; | |
int position; | |
TypeParser (string fullname) | |
{ | |
this.fullname = fullname; | |
this.length = fullname.Length; | |
} | |
Type ParseType (bool fq_name) | |
{ | |
var type = new Type (); | |
type.type_fullname = ParsePart (); | |
type.nested_names = ParseNestedNames (); | |
if (TryGetArity (type)) | |
type.generic_arguments = ParseGenericArguments (type.arity); | |
type.specs = ParseSpecs (); | |
if (fq_name) | |
type.assembly = ParseAssemblyName (); | |
return type; | |
} | |
static bool TryGetArity (Type type) | |
{ | |
int arity = 0; | |
TryAddArity (type.type_fullname, ref arity); | |
var nested_names = type.nested_names; | |
if (!nested_names.IsNullOrEmpty ()) { | |
for (int i = 0; i < nested_names.Length; i++) | |
TryAddArity (nested_names [i], ref arity); | |
} | |
type.arity = arity; | |
return arity > 0; | |
} | |
static bool TryGetArity (string name, out int arity) | |
{ | |
arity = 0; | |
var index = name.LastIndexOf ('`'); | |
if (index == -1) | |
return false; | |
return ParseInt32 (name.Substring (index + 1), out arity); | |
} | |
static bool ParseInt32 (string value, out int result) | |
{ | |
return int.TryParse (value, out result); | |
} | |
static void TryAddArity (string name, ref int arity) | |
{ | |
int type_arity; | |
if (!TryGetArity (name, out type_arity)) | |
return; | |
arity += type_arity; | |
} | |
string ParsePart () | |
{ | |
var part = new StringBuilder (); | |
while (position < length && !IsDelimiter (fullname [position])) { | |
if (fullname [position] == '\\') | |
position++; | |
part.Append (fullname [position++]); | |
} | |
return part.ToString (); | |
} | |
static bool IsDelimiter (char chr) | |
{ | |
return "+,[]*&".IndexOf (chr) != -1; | |
} | |
void TryParseWhiteSpace () | |
{ | |
while (position < length && Char.IsWhiteSpace (fullname [position])) | |
position++; | |
} | |
string [] ParseNestedNames () | |
{ | |
string [] nested_names = null; | |
while (TryParse ('+')) | |
Add (ref nested_names, ParsePart ()); | |
return nested_names; | |
} | |
bool TryParse (char chr) | |
{ | |
if (position < length && fullname [position] == chr) { | |
position++; | |
return true; | |
} | |
return false; | |
} | |
static void Add<T> (ref T [] array, T item) | |
{ | |
array = array.Add (item); | |
} | |
int [] ParseSpecs () | |
{ | |
int [] specs = null; | |
while (position < length) { | |
switch (fullname [position]) { | |
case '*': | |
position++; | |
Add (ref specs, Type.Ptr); | |
break; | |
case '&': | |
position++; | |
Add (ref specs, Type.ByRef); | |
break; | |
case '[': | |
position++; | |
switch (fullname [position]) { | |
case ']': | |
position++; | |
Add (ref specs, Type.SzArray); | |
break; | |
case '*': | |
position++; | |
Add (ref specs, 1); | |
break; | |
default: | |
var rank = 1; | |
while (TryParse (',')) | |
rank++; | |
Add (ref specs, rank); | |
TryParse (']'); | |
break; | |
} | |
break; | |
default: | |
return specs; | |
} | |
} | |
return specs; | |
} | |
Type [] ParseGenericArguments (int arity) | |
{ | |
Type [] generic_arguments = null; | |
if (position == length || fullname [position] != '[') | |
return generic_arguments; | |
TryParse ('['); | |
for (int i = 0; i < arity; i++) { | |
var fq_argument = TryParse ('['); | |
Add (ref generic_arguments, ParseType (fq_argument)); | |
if (fq_argument) | |
TryParse (']'); | |
TryParse (','); | |
TryParseWhiteSpace (); | |
} | |
TryParse (']'); | |
return generic_arguments; | |
} | |
string ParseAssemblyName () | |
{ | |
if (!TryParse (',')) | |
return string.Empty; | |
TryParseWhiteSpace (); | |
var start = position; | |
while (position < length) { | |
var chr = fullname [position]; | |
if (chr == '[' || chr == ']') | |
break; | |
position++; | |
} | |
return fullname.Substring (start, position - start); | |
} | |
public static TypeReference ParseType (ModuleDefinition module, string fullname, bool typeDefinitionOnly = false) | |
{ | |
if (string.IsNullOrEmpty (fullname)) | |
return null; | |
var parser = new TypeParser (fullname); | |
return GetTypeReference (module, parser.ParseType (true), typeDefinitionOnly); | |
} | |
static TypeReference GetTypeReference (ModuleDefinition module, Type type_info, bool type_def_only) | |
{ | |
TypeReference type; | |
if (!TryGetDefinition (module, type_info, out type)) { | |
if (type_def_only) | |
return null; | |
type = CreateReference (type_info, module, GetMetadataScope (module, type_info)); | |
} | |
return CreateSpecs (type, type_info); | |
} | |
static TypeReference CreateSpecs (TypeReference type, Type type_info) | |
{ | |
type = TryCreateGenericInstanceType (type, type_info); | |
var specs = type_info.specs; | |
if (specs.IsNullOrEmpty ()) | |
return type; | |
for (int i = 0; i < specs.Length; i++) { | |
switch (specs [i]) { | |
case Type.Ptr: | |
type = new PointerType (type); | |
break; | |
case Type.ByRef: | |
type = new ByReferenceType (type); | |
break; | |
case Type.SzArray: | |
type = new ArrayType (type); | |
break; | |
default: | |
var array = new ArrayType (type); | |
array.Dimensions.Clear (); | |
for (int j = 0; j < specs [i]; j++) | |
array.Dimensions.Add (new ArrayDimension ()); | |
type = array; | |
break; | |
} | |
} | |
return type; | |
} | |
static TypeReference TryCreateGenericInstanceType (TypeReference type, Type type_info) | |
{ | |
var generic_arguments = type_info.generic_arguments; | |
if (generic_arguments.IsNullOrEmpty ()) | |
return type; | |
var instance = new GenericInstanceType (type); | |
var instance_arguments = instance.GenericArguments; | |
for (int i = 0; i < generic_arguments.Length; i++) | |
instance_arguments.Add (GetTypeReference (type.Module, generic_arguments [i], false)); | |
return instance; | |
} | |
public static void SplitFullName (string fullname, out string @namespace, out string name) | |
{ | |
var last_dot = fullname.LastIndexOf ('.'); | |
if (last_dot == -1) { | |
@namespace = string.Empty; | |
name = fullname; | |
} else { | |
@namespace = fullname.Substring (0, last_dot); | |
name = fullname.Substring (last_dot + 1); | |
} | |
} | |
static TypeReference CreateReference (Type type_info, ModuleDefinition module, IMetadataScope scope) | |
{ | |
string @namespace, name; | |
SplitFullName (type_info.type_fullname, out @namespace, out name); | |
var type = new TypeReference (@namespace, name, module, scope); | |
MetadataSystem.TryProcessPrimitiveTypeReference (type); | |
AdjustGenericParameters (type); | |
var nested_names = type_info.nested_names; | |
if (nested_names.IsNullOrEmpty ()) | |
return type; | |
for (int i = 0; i < nested_names.Length; i++) { | |
type = new TypeReference (string.Empty, nested_names [i], module, null) { | |
DeclaringType = type, | |
}; | |
AdjustGenericParameters (type); | |
} | |
return type; | |
} | |
static void AdjustGenericParameters (TypeReference type) | |
{ | |
int arity; | |
if (!TryGetArity (type.Name, out arity)) | |
return; | |
for (int i = 0; i < arity; i++) | |
type.GenericParameters.Add (new GenericParameter (type)); | |
} | |
static IMetadataScope GetMetadataScope (ModuleDefinition module, Type type_info) | |
{ | |
if (string.IsNullOrEmpty (type_info.assembly)) | |
return module.TypeSystem.CoreLibrary; | |
AssemblyNameReference match; | |
var reference = AssemblyNameReference.Parse (type_info.assembly); | |
return module.TryGetAssemblyNameReference (reference, out match) | |
? match | |
: reference; | |
} | |
static bool TryGetDefinition (ModuleDefinition module, Type type_info, out TypeReference type) | |
{ | |
type = null; | |
if (!TryCurrentModule (module, type_info)) | |
return false; | |
var typedef = module.GetType (type_info.type_fullname); | |
if (typedef == null) | |
return false; | |
var nested_names = type_info.nested_names; | |
if (!nested_names.IsNullOrEmpty ()) { | |
for (int i = 0; i < nested_names.Length; i++) { | |
var nested_type = typedef.GetNestedType (nested_names [i]); | |
if (nested_type == null) | |
return false; | |
typedef = nested_type; | |
} | |
} | |
type = typedef; | |
return true; | |
} | |
static bool TryCurrentModule (ModuleDefinition module, Type type_info) | |
{ | |
if (string.IsNullOrEmpty (type_info.assembly)) | |
return true; | |
if (module.assembly != null && module.assembly.Name.FullName == type_info.assembly) | |
return true; | |
return false; | |
} | |
public static string ToParseable (TypeReference type, bool top_level = true) | |
{ | |
if (type == null) | |
return null; | |
var name = new StringBuilder (); | |
AppendType (type, name, true, top_level); | |
return name.ToString (); | |
} | |
static void AppendNamePart (string part, StringBuilder name) | |
{ | |
foreach (var c in part) { | |
if (IsDelimiter (c)) | |
name.Append ('\\'); | |
name.Append (c); | |
} | |
} | |
static void AppendType (TypeReference type, StringBuilder name, bool fq_name, bool top_level) | |
{ | |
var element_type = type.GetElementType (); | |
var declaring_type = element_type.DeclaringType; | |
if (declaring_type != null) { | |
AppendType (declaring_type, name, false, top_level); | |
name.Append ('+'); | |
} | |
var @namespace = type.Namespace; | |
if (!string.IsNullOrEmpty (@namespace)) { | |
AppendNamePart (@namespace, name); | |
name.Append ('.'); | |
} | |
AppendNamePart (element_type.Name, name); | |
if (!fq_name) | |
return; | |
if (type.IsTypeSpecification ()) | |
AppendTypeSpecification ((TypeSpecification) type, name); | |
if (RequiresFullyQualifiedName (type, top_level)) { | |
name.Append (", "); | |
name.Append (GetScopeFullName (type)); | |
} | |
} | |
static string GetScopeFullName (TypeReference type) | |
{ | |
var scope = type.Scope; | |
switch (scope.MetadataScopeType) { | |
case MetadataScopeType.AssemblyNameReference: | |
return ((AssemblyNameReference) scope).FullName; | |
case MetadataScopeType.ModuleDefinition: | |
return ((ModuleDefinition) scope).Assembly.Name.FullName; | |
} | |
throw new ArgumentException (); | |
} | |
static void AppendTypeSpecification (TypeSpecification type, StringBuilder name) | |
{ | |
if (type.ElementType.IsTypeSpecification ()) | |
AppendTypeSpecification ((TypeSpecification) type.ElementType, name); | |
switch (type.etype) { | |
case ElementType.Ptr: | |
name.Append ('*'); | |
break; | |
case ElementType.ByRef: | |
name.Append ('&'); | |
break; | |
case ElementType.SzArray: | |
case ElementType.Array: | |
var array = (ArrayType) type; | |
if (array.IsVector) { | |
name.Append ("[]"); | |
} else { | |
name.Append ('['); | |
for (int i = 1; i < array.Rank; i++) | |
name.Append (','); | |
name.Append (']'); | |
} | |
break; | |
case ElementType.GenericInst: | |
var instance = (GenericInstanceType) type; | |
var arguments = instance.GenericArguments; | |
name.Append ('['); | |
for (int i = 0; i < arguments.Count; i++) { | |
if (i > 0) | |
name.Append (','); | |
var argument = arguments [i]; | |
var requires_fqname = argument.Scope != argument.Module; | |
if (requires_fqname) | |
name.Append ('['); | |
AppendType (argument, name, true, false); | |
if (requires_fqname) | |
name.Append (']'); | |
} | |
name.Append (']'); | |
break; | |
default: | |
return; | |
} | |
} | |
static bool RequiresFullyQualifiedName (TypeReference type, bool top_level) | |
{ | |
if (type.Scope == type.Module) | |
return false; | |
if (type.Scope.Name == "mscorlib" && top_level) | |
return false; | |
return true; | |
} | |
} | |
} | |
} | |
#endregion | |
#region Mono.Cecil\*.cs | |
namespace Internal { | |
// | |
// Author: | |
// Jb Evain (jbevain@gmail.com) | |
// | |
// Copyright (c) 2008 - 2015 Jb Evain | |
// Copyright (c) 2008 - 2011 Novell, Inc. | |
// | |
// Licensed under the MIT/X11 license. | |
// | |
using System; | |
using Mono.Cecil.Metadata; | |
using Mono.Collections.Generic; | |
namespace Mono.Cecil { | |
internal enum MetadataType : byte { | |
Void = ElementType.Void, | |
Boolean = ElementType.Boolean, | |
Char = ElementType.Char, | |
SByte = ElementType.I1, | |
Byte = ElementType.U1, | |
Int16 = ElementType.I2, | |
UInt16 = ElementType.U2, | |
Int32 = ElementType.I4, | |
UInt32 = ElementType.U4, | |
Int64 = ElementType.I8, | |
UInt64 = ElementType.U8, | |
Single = ElementType.R4, | |
Double = ElementType.R8, | |
String = ElementType.String, | |
Pointer = ElementType.Ptr, | |
ByReference = ElementType.ByRef, | |
ValueType = ElementType.ValueType, | |
Class = ElementType.Class, | |
Var = ElementType.Var, | |
Array = ElementType.Array, | |
GenericInstance = ElementType.GenericInst, | |
TypedByReference = ElementType.TypedByRef, | |
IntPtr = ElementType.I, | |
UIntPtr = ElementType.U, | |
FunctionPointer = ElementType.FnPtr, | |
Object = ElementType.Object, | |
MVar = ElementType.MVar, | |
RequiredModifier = ElementType.CModReqD, | |
OptionalModifier = ElementType.CModOpt, | |
Sentinel = ElementType.Sentinel, | |
Pinned = ElementType.Pinned, | |
} | |
internal class TypeReference : MemberReference, IGenericParameterProvider, IGenericContext { | |
string @namespace; | |
bool value_type; | |
internal IMetadataScope scope; | |
internal ModuleDefinition module; | |
internal ElementType etype = ElementType.None; | |
string fullname; | |
protected Collection<GenericParameter> generic_parameters; | |
public override string Name { | |
get { return base.Name; } | |
set { | |
if (IsWindowsRuntimeProjection && value != base.Name) | |
throw new InvalidOperationException ("Projected type reference name can't be changed."); | |
base.Name = value; | |
ClearFullName (); | |
} | |
} | |
public virtual string Namespace { | |
get { return @namespace; } | |
set { | |
if (IsWindowsRuntimeProjection && value != @namespace) | |
throw new InvalidOperationException ("Projected type reference namespace can't be changed."); | |
@namespace = value; | |
ClearFullName (); | |
} | |
} | |
public virtual bool IsValueType { | |
get { return value_type; } | |
set { value_type = value; } | |
} | |
public override ModuleDefinition Module { | |
get { | |
if (module != null) | |
return module; | |
var declaring_type = this.DeclaringType; | |
if (declaring_type != null) | |
return declaring_type.Module; | |
return null; | |
} | |
} | |
internal new TypeReferenceProjection WindowsRuntimeProjection { | |
get { return (TypeReferenceProjection) projection; } | |
set { projection = value; } | |
} | |
IGenericParameterProvider IGenericContext.Type { | |
get { return this; } | |
} | |
IGenericParameterProvider IGenericContext.Method { | |
get { return null; } | |
} | |
GenericParameterType IGenericParameterProvider.GenericParameterType { | |
get { return GenericParameterType.Type; } | |
} | |
public virtual bool HasGenericParameters { | |
get { return !generic_parameters.IsNullOrEmpty (); } | |
} | |
public virtual Collection<GenericParameter> GenericParameters { | |
get { | |
if (generic_parameters != null) | |
return generic_parameters; | |
return generic_parameters = new GenericParameterCollection (this); | |
} | |
} | |
public virtual IMetadataScope Scope { | |
get { | |
var declaring_type = this.DeclaringType; | |
if (declaring_type != null) | |
return declaring_type.Scope; | |
return scope; | |
} | |
set { | |
var declaring_type = this.DeclaringType; | |
if (declaring_type != null) { | |
if (IsWindowsRuntimeProjection && value != declaring_type.Scope) | |
throw new InvalidOperationException ("Projected type scope can't be changed."); | |
declaring_type.Scope = value; | |
return; | |
} | |
if (IsWindowsRuntimeProjection && value != scope) | |
throw new InvalidOperationException ("Projected type scope can't be changed."); | |
scope = value; | |
} | |
} | |
public bool IsNested { | |
get { return this.DeclaringType != null; } | |
} | |
public override TypeReference DeclaringType { | |
get { return base.DeclaringType; } | |
set { | |
if (IsWindowsRuntimeProjection && value != base.DeclaringType) | |
throw new InvalidOperationException ("Projected type declaring type can't be changed."); | |
base.DeclaringType = value; | |
ClearFullName (); | |
} | |
} | |
public override string FullName { | |
get { | |
if (fullname != null) | |
return fullname; | |
fullname = this.TypeFullName (); | |
if (IsNested) | |
fullname = DeclaringType.FullName + "/" + fullname; | |
return fullname; | |
} | |
} | |
public virtual bool IsByReference { | |
get { return false; } | |
} | |
public virtual bool IsPointer { | |
get { return false; } | |
} | |
public virtual bool IsSentinel { | |
get { return false; } | |
} | |
public virtual bool IsArray { | |
get { return false; } | |
} | |
public virtual bool IsGenericParameter { | |
get { return false; } | |
} | |
public virtual bool IsGenericInstance { | |
get { return false; } | |
} | |
public virtual bool IsRequiredModifier { | |
get { return false; } | |
} | |
public virtual bool IsOptionalModifier { | |
get { return false; } | |
} | |
public virtual bool IsPinned { | |
get { return false; } | |
} | |
public virtual bool IsFunctionPointer { | |
get { return false; } | |
} | |
public virtual bool IsPrimitive { | |
get { return etype.IsPrimitive (); } | |
} | |
public virtual MetadataType MetadataType { | |
get { | |
switch (etype) { | |
case ElementType.None: | |
return IsValueType ? MetadataType.ValueType : MetadataType.Class; | |
default: | |
return (MetadataType) etype; | |
} | |
} | |
} | |
protected TypeReference (string @namespace, string name) | |
: base (name) | |
{ | |
this.@namespace = @namespace ?? string.Empty; | |
this.token = new MetadataToken (TokenType.TypeRef, 0); | |
} | |
public TypeReference (string @namespace, string name, ModuleDefinition module, IMetadataScope scope) | |
: this (@namespace, name) | |
{ | |
this.module = module; | |
this.scope = scope; | |
} | |
public TypeReference (string @namespace, string name, ModuleDefinition module, IMetadataScope scope, bool valueType) : | |
this (@namespace, name, module, scope) | |
{ | |
value_type = valueType; | |
} | |
protected virtual void ClearFullName () | |
{ | |
this.fullname = null; | |
} | |
public virtual TypeReference GetElementType () | |
{ | |
return this; | |
} | |
protected override IMemberDefinition ResolveDefinition () | |
{ | |
return this.Resolve (); | |
} | |
public new virtual TypeDefinition Resolve () | |
{ | |
var module = this.Module; | |
if (module == null) | |
throw new NotSupportedException (); | |
return module.Resolve (this); | |
} | |
} | |
static partial class Mixin { | |
public static bool IsPrimitive (this ElementType self) | |
{ | |
switch (self) { | |
case ElementType.Boolean: | |
case ElementType.Char: | |
case ElementType.I: | |
case ElementType.U: | |
case ElementType.I1: | |
case ElementType.U1: | |
case ElementType.I2: | |
case ElementType.U2: | |
case ElementType.I4: | |
case ElementType.U4: | |
case ElementType.I8: | |
case ElementType.U8: | |
case ElementType.R4: | |
case ElementType.R8: | |
return true; | |
default: | |
return false; | |
} | |
} | |
public static string TypeFullName (this TypeReference self) | |
{ | |
return string.IsNullOrEmpty (self.Namespace) | |
? self.Name | |
: self.Namespace + '.' + self.Name; | |
} | |
public static bool IsTypeOf (this TypeReference self, string @namespace, string name) | |
{ | |
return self.Name == name | |
&& self.Namespace == @namespace; | |
} | |
public static bool IsTypeSpecification (this TypeReference type) | |
{ | |
switch (type.etype) { | |
case ElementType.Array: | |
case ElementType.ByRef: | |
case ElementType.CModOpt: | |
case ElementType.CModReqD: | |
case ElementType.FnPtr: | |
case ElementType.GenericInst: | |
case ElementType.MVar: | |
case ElementType.Pinned: | |
case ElementType.Ptr: | |
case ElementType.SzArray: | |
case ElementType.Sentinel: | |
case ElementType.Var: | |
return true; | |
} | |
return false; | |
} | |
public static TypeDefinition CheckedResolve (this TypeReference self) | |
{ | |
var type = self.Resolve (); | |
if (type == null) | |
throw new ResolutionException (self); | |
return type; | |
} | |
} | |
} | |
} | |
#endregion | |
#region Mono.Cecil\*.cs | |
namespace Internal { | |
// | |
// Author: | |
// Jb Evain (jbevain@gmail.com) | |
// | |
// Copyright (c) 2008 - 2015 Jb Evain | |
// Copyright (c) 2008 - 2011 Novell, Inc. | |
// | |
// Licensed under the MIT/X11 license. | |
// | |
using System; | |
using Mono.Cecil.Metadata; | |
namespace Mono.Cecil { | |
internal abstract class TypeSpecification : TypeReference { | |
readonly TypeReference element_type; | |
public TypeReference ElementType { | |
get { return element_type; } | |
} | |
public override string Name { | |
get { return element_type.Name; } | |
set { throw new InvalidOperationException (); } | |
} |