Jo Shields a575963da9 Imported Upstream version 3.6.0
Former-commit-id: da6be194a6b1221998fc28233f2503bd61dd9d14
2014-08-13 10:39:27 +01:00

602 lines
16 KiB
C#

//
// ModuleDefinition.cs
//
// Author:
// Jb Evain (jbevain@gmail.com)
//
// (C) 2005 Jb Evain
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
namespace Mono.Cecil {
using System;
using SR = System.Reflection;
using SS = System.Security;
using SSP = System.Security.Permissions;
using System.Text;
using Mono.Cecil.Cil;
using Mono.Cecil.Binary;
using Mono.Cecil.Metadata;
internal sealed class ModuleDefinition : ModuleReference, ICustomAttributeProvider, IMetadataScope,
IReflectionStructureVisitable, IReflectionVisitable {
Guid m_mvid;
bool m_main;
bool m_manifestOnly;
AssemblyNameReferenceCollection m_asmRefs;
ModuleReferenceCollection m_modRefs;
ResourceCollection m_res;
TypeDefinitionCollection m_types;
TypeReferenceCollection m_refs;
ExternTypeCollection m_externs;
MemberReferenceCollection m_members;
CustomAttributeCollection m_customAttrs;
AssemblyDefinition m_asm;
Image m_image;
ImageReader m_imgReader;
ReflectionController m_controller;
MetadataResolver m_resolver;
SecurityDeclarationReader m_secReader;
public Guid Mvid {
get { return m_mvid; }
set { m_mvid = value; }
}
public bool Main {
get { return m_main; }
set { m_main = value; }
}
public AssemblyNameReferenceCollection AssemblyReferences {
get { return m_asmRefs; }
}
public ModuleReferenceCollection ModuleReferences {
get { return m_modRefs; }
}
public ResourceCollection Resources {
get { return m_res; }
}
public TypeDefinitionCollection Types {
get { return m_types; }
}
public TypeReferenceCollection TypeReferences {
get { return m_refs; }
}
public MemberReferenceCollection MemberReferences {
get { return m_members; }
}
public ExternTypeCollection ExternTypes {
get {
if (m_externs == null)
m_externs = new ExternTypeCollection (this);
return m_externs;
}
}
public bool HasCustomAttributes {
get { return (m_customAttrs == null) ? false : (m_customAttrs.Count > 0); }
}
public CustomAttributeCollection CustomAttributes {
get {
if (m_customAttrs == null)
m_customAttrs = new CustomAttributeCollection (this);
return m_customAttrs;
}
}
public AssemblyDefinition Assembly {
get { return m_asm; }
}
internal ReflectionController Controller {
get { return m_controller; }
}
internal MetadataResolver Resolver {
get { return m_resolver; }
}
internal ImageReader ImageReader {
get { return m_imgReader; }
}
public Image Image {
get { return m_image; }
set {
m_image = value;
m_secReader = null;
}
}
public ModuleDefinition (string name, AssemblyDefinition asm) :
this (name, asm, null, false)
{
}
public ModuleDefinition (string name, AssemblyDefinition asm, bool main) :
this (name, asm, null, main)
{
}
internal ModuleDefinition (string name, AssemblyDefinition asm, StructureReader reader, bool main) : base (name)
{
if (asm == null)
throw new ArgumentNullException ("asm");
if (name == null || name.Length == 0)
throw new ArgumentNullException ("name");
m_asm = asm;
m_main = main;
#if !CF_1_0
m_mvid = Guid.NewGuid ();
#endif
if (reader != null) {
m_image = reader.Image;
m_imgReader = reader.ImageReader;
m_manifestOnly = reader.ManifestOnly;
} else
m_image = Image.CreateImage ();
m_modRefs = new ModuleReferenceCollection (this);
m_asmRefs = new AssemblyNameReferenceCollection (this);
m_res = new ResourceCollection (this);
m_types = new TypeDefinitionCollection (this);
m_refs = new TypeReferenceCollection (this);
m_members = new MemberReferenceCollection (this);
m_controller = new ReflectionController (this);
m_resolver = new MetadataResolver (asm);
}
public IMetadataTokenProvider LookupByToken (MetadataToken token)
{
return m_controller.Reader.LookupByToken (token);
}
public IMetadataTokenProvider LookupByToken (TokenType table, int rid)
{
return LookupByToken (new MetadataToken (table, (uint) rid));
}
void CheckContext (TypeDefinition context)
{
if (context.Module != this)
throw new ArgumentException ("The context parameter does not belongs to this module");
CheckGenericParameterProvider (context);
}
void CheckContext (MethodDefinition context)
{
CheckGenericParameterProvider (context);
}
static void CheckGenericParameterProvider (IGenericParameterProvider context)
{
if (context == null)
throw new ArgumentNullException ("context");
if (context.GenericParameters.Count == 0)
throw new ArgumentException ("The context parameter is not a generic type");
}
ImportContext GetContext ()
{
return new ImportContext (m_controller.Importer);
}
static ImportContext GetContext (IImporter importer)
{
return new ImportContext (importer);
}
ImportContext GetContext (TypeDefinition context)
{
return new ImportContext (m_controller.Importer, context);
}
ImportContext GetContext (MethodDefinition context)
{
return new ImportContext (m_controller.Importer, context);
}
static ImportContext GetContext (IImporter importer, TypeDefinition context)
{
return new ImportContext (importer, context);
}
public TypeReference Import (Type type)
{
if (type == null)
throw new ArgumentNullException ("type");
return m_controller.Helper.ImportSystemType (type, GetContext ());
}
public TypeReference Import (Type type, TypeDefinition context)
{
if (type == null)
throw new ArgumentNullException ("type");
CheckContext (context);
return m_controller.Helper.ImportSystemType (type, GetContext (context));
}
public TypeReference Import (Type type, MethodDefinition context)
{
if (type == null)
throw new ArgumentNullException ("type");
CheckContext (context);
return m_controller.Helper.ImportSystemType (type, GetContext (context));
}
public MethodReference Import (SR.MethodBase meth)
{
if (meth == null)
throw new ArgumentNullException ("meth");
if (meth is SR.ConstructorInfo)
return m_controller.Helper.ImportConstructorInfo (
meth as SR.ConstructorInfo, GetContext ());
else
return m_controller.Helper.ImportMethodInfo (
meth as SR.MethodInfo, GetContext ());
}
public MethodReference Import (SR.MethodBase meth, TypeDefinition context)
{
if (meth == null)
throw new ArgumentNullException ("meth");
CheckContext (context);
ImportContext import_context = GetContext (context);
if (meth is SR.ConstructorInfo)
return m_controller.Helper.ImportConstructorInfo (
meth as SR.ConstructorInfo, import_context);
else
return m_controller.Helper.ImportMethodInfo (
meth as SR.MethodInfo, import_context);
}
public FieldReference Import (SR.FieldInfo field)
{
if (field == null)
throw new ArgumentNullException ("field");
return m_controller.Helper.ImportFieldInfo (field, GetContext ());
}
public FieldReference Import (SR.FieldInfo field, TypeDefinition context)
{
if (field == null)
throw new ArgumentNullException ("field");
CheckContext (context);
return m_controller.Helper.ImportFieldInfo (field, GetContext (context));
}
public FieldReference Import (SR.FieldInfo field, MethodDefinition context)
{
if (field == null)
throw new ArgumentNullException ("field");
CheckContext (context);
return m_controller.Helper.ImportFieldInfo (field, GetContext (context));
}
public TypeReference Import (TypeReference type)
{
if (type == null)
throw new ArgumentNullException ("type");
return m_controller.Importer.ImportTypeReference (type, GetContext ());
}
public TypeReference Import (TypeReference type, TypeDefinition context)
{
if (type == null)
throw new ArgumentNullException ("type");
CheckContext (context);
return m_controller.Importer.ImportTypeReference (type, GetContext (context));
}
public TypeReference Import (TypeReference type, MethodDefinition context)
{
if (type == null)
throw new ArgumentNullException ("type");
CheckContext (context);
return m_controller.Importer.ImportTypeReference (type, GetContext (context));
}
public MethodReference Import (MethodReference meth)
{
if (meth == null)
throw new ArgumentNullException ("meth");
return m_controller.Importer.ImportMethodReference (meth, GetContext ());
}
public MethodReference Import (MethodReference meth, TypeDefinition context)
{
if (meth == null)
throw new ArgumentNullException ("meth");
CheckContext (context);
return m_controller.Importer.ImportMethodReference (meth, GetContext (context));
}
public MethodReference Import (MethodReference meth, MethodDefinition context)
{
if (meth == null)
throw new ArgumentNullException ("meth");
CheckContext (context);
return m_controller.Importer.ImportMethodReference (meth, GetContext (context));
}
public FieldReference Import (FieldReference field)
{
if (field == null)
throw new ArgumentNullException ("field");
return m_controller.Importer.ImportFieldReference (field, GetContext ());
}
public FieldReference Import (FieldReference field, TypeDefinition context)
{
if (field == null)
throw new ArgumentNullException ("field");
CheckContext (context);
return m_controller.Importer.ImportFieldReference (field, GetContext (context));
}
public FieldReference Import (FieldReference field, MethodDefinition context)
{
if (field == null)
throw new ArgumentNullException ("field");
CheckContext (context);
return m_controller.Importer.ImportFieldReference (field, GetContext (context));
}
static FieldDefinition ImportFieldDefinition (FieldDefinition field, ImportContext context)
{
return FieldDefinition.Clone (field, context);
}
static MethodDefinition ImportMethodDefinition (MethodDefinition meth, ImportContext context)
{
return MethodDefinition.Clone (meth, context);
}
static TypeDefinition ImportTypeDefinition (TypeDefinition type, ImportContext context)
{
return TypeDefinition.Clone (type, context);
}
public TypeDefinition Inject (TypeDefinition type)
{
return Inject (type, m_controller.Importer);
}
public TypeDefinition Inject (TypeDefinition type, IImporter importer)
{
if (type == null)
throw new ArgumentNullException ("type");
if (importer == null)
throw new ArgumentNullException ("importer");
TypeDefinition definition = ImportTypeDefinition (type, GetContext (importer));
this.Types.Add (definition);
return definition;
}
public TypeDefinition Inject (TypeDefinition type, TypeDefinition context)
{
return Inject (type, context, m_controller.Importer);
}
public TypeDefinition Inject (TypeDefinition type, TypeDefinition context, IImporter importer)
{
Check (type, context, importer);
TypeDefinition definition = ImportTypeDefinition (type, GetContext (importer, context));
context.NestedTypes.Add (definition);
return definition;
}
public MethodDefinition Inject (MethodDefinition meth, TypeDefinition context)
{
return Inject (meth, context, m_controller.Importer);
}
void Check (IMemberDefinition definition, TypeDefinition context, IImporter importer)
{
if (definition == null)
throw new ArgumentNullException ("definition");
if (context == null)
throw new ArgumentNullException ("context");
if (importer == null)
throw new ArgumentNullException ("importer");
if (context.Module != this)
throw new ArgumentException ("The context parameter does not belongs to this module");
}
public MethodDefinition Inject (MethodDefinition meth, TypeDefinition context, IImporter importer)
{
Check (meth, context, importer);
MethodDefinition definition = ImportMethodDefinition (meth, GetContext (importer, context));
context.Methods.Add (definition);
return definition;
}
public FieldDefinition Inject (FieldDefinition field, TypeDefinition context)
{
return Inject (field, context, m_controller.Importer);
}
public FieldDefinition Inject (FieldDefinition field, TypeDefinition context, IImporter importer)
{
Check (field, context, importer);
FieldDefinition definition = ImportFieldDefinition (field, GetContext (importer, context));
context.Fields.Add (definition);
return definition;
}
public void FullLoad ()
{
if (m_manifestOnly)
m_controller.Reader.VisitModuleDefinition (this);
foreach (TypeDefinition type in this.Types) {
foreach (MethodDefinition meth in type.Methods)
meth.LoadBody ();
foreach (MethodDefinition ctor in type.Constructors)
ctor.LoadBody ();
}
if (m_controller.Reader.SymbolReader == null)
return;
m_controller.Reader.SymbolReader.Dispose ();
m_controller.Reader.SymbolReader = null;
}
public void LoadSymbols ()
{
m_controller.Reader.SymbolReader = SymbolStoreHelper.GetReader (this);
}
public void LoadSymbols (ISymbolReader reader)
{
m_controller.Reader.SymbolReader = reader;
}
public void SaveSymbols ()
{
m_controller.Writer.SaveSymbols = true;
}
public void SaveSymbols (ISymbolWriter writer)
{
SaveSymbols ();
m_controller.Writer.SymbolWriter = writer;
}
public void SaveSymbols (string outputDirectory)
{
SaveSymbols ();
m_controller.Writer.OutputFile = outputDirectory;
}
public void SaveSymbols (string outputDirectory, ISymbolWriter writer)
{
SaveSymbols (outputDirectory);
m_controller.Writer.SymbolWriter = writer;
}
public byte [] GetAsByteArray (CustomAttribute ca)
{
CustomAttribute customAttr = ca;
if (!ca.Resolved)
if (customAttr.Blob != null)
return customAttr.Blob;
else
return new byte [0];
return m_controller.Writer.SignatureWriter.CompressCustomAttribute (
ReflectionWriter.GetCustomAttributeSig (ca), ca.Constructor);
}
public byte [] GetAsByteArray (SecurityDeclaration dec)
{
// TODO - add support for 2.0 format
// note: the 1.x format is still supported in 2.0 so this isn't an immediate problem
if (!dec.Resolved)
return dec.Blob;
#if !CF_1_0 && !CF_2_0
if (dec.PermissionSet != null)
return Encoding.Unicode.GetBytes (dec.PermissionSet.ToXml ().ToString ());
#endif
return new byte [0];
}
public CustomAttribute FromByteArray (MethodReference ctor, byte [] data)
{
return m_controller.Reader.GetCustomAttribute (ctor, data);
}
public SecurityDeclaration FromByteArray (SecurityAction action, byte [] declaration)
{
if (m_secReader == null)
m_secReader = new SecurityDeclarationReader (Image.MetadataRoot, m_controller.Reader);
return m_secReader.FromByteArray (action, declaration);
}
public override void Accept (IReflectionStructureVisitor visitor)
{
visitor.VisitModuleDefinition (this);
this.AssemblyReferences.Accept (visitor);
this.ModuleReferences.Accept (visitor);
this.Resources.Accept (visitor);
}
public void Accept (IReflectionVisitor visitor)
{
visitor.VisitModuleDefinition (this);
this.Types.Accept (visitor);
this.TypeReferences.Accept (visitor);
}
public override string ToString ()
{
string s = (m_main ? "(main), Mvid=" : "Mvid=");
return s + m_mvid;
}
}
}