Skip to content

Instantly share code, notes, and snippets.

@jcansdale
Created October 17, 2018 18:13
Show Gist options
  • Save jcansdale/2d97240b53b23e14ec5324c4fe0916bb to your computer and use it in GitHub Desktop.
Save jcansdale/2d97240b53b23e14ec5324c4fe0916bb to your computer and use it in GitHub Desktop.
proj2src Mono.Cecil.csproj Mono.Cecil.cs
#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 (); }
}