Skip to content

Develop/issue 863 #864

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 10 commits into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
741 changes: 413 additions & 328 deletions Mono.Cecil/AssemblyReader.cs

Large diffs are not rendered by default.

137 changes: 80 additions & 57 deletions Mono.Cecil/BaseAssemblyResolver.cs
Original file line number Diff line number Diff line change
@@ -21,8 +21,7 @@ namespace Mono.Cecil {
public delegate AssemblyDefinition AssemblyResolveEventHandler (object sender, AssemblyNameReference reference);

public sealed class AssemblyResolveEventArgs : EventArgs {

readonly AssemblyNameReference reference;
private readonly AssemblyNameReference reference;

public AssemblyNameReference AssemblyReference {
get { return reference; }
@@ -37,9 +36,9 @@ public AssemblyResolveEventArgs (AssemblyNameReference reference)
#if !NET_CORE
[Serializable]
#endif
public sealed class AssemblyResolutionException : FileNotFoundException {

readonly AssemblyNameReference reference;
public sealed class AssemblyResolutionException : FileNotFoundException {
private readonly AssemblyNameReference reference;

public AssemblyNameReference AssemblyReference {
get { return reference; }
@@ -67,18 +66,15 @@ public AssemblyResolutionException (AssemblyNameReference reference, Exception i
}

public abstract class BaseAssemblyResolver : IAssemblyResolver {
private static readonly bool on_mono = Type.GetType ("Mono.Runtime") != null;

static readonly bool on_mono = Type.GetType ("Mono.Runtime") != null;

readonly Collection<string> directories;
private 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

private Collection<string> gac_paths;

public void AddSearchDirectory (string directory)
{
@@ -90,6 +86,12 @@ public void RemoveSearchDirectory (string directory)
directories.Remove (directory);
}

protected bool NetCore { get; set; }

protected bool AsMono { get; set; }

protected Module CoreModule { get; set; }

public string [] GetSearchDirectories ()
{
var directories = new string [this.directories.size];
@@ -102,9 +104,17 @@ public string [] GetSearchDirectories ()
protected BaseAssemblyResolver ()
{
directories = new Collection<string> (2) { ".", "bin" };
#if NET_CORE
NetCore = true;
#else
NetCore = false;
#endif

AsMono = on_mono;
CoreModule = typeof (object).Module;
}

AssemblyDefinition GetAssembly (string file, ReaderParameters parameters)
private AssemblyDefinition GetAssembly (string file, ReaderParameters parameters)
{
if (parameters.AssemblyResolver == null)
parameters.AssemblyResolver = this;
@@ -133,13 +143,33 @@ public virtual AssemblyDefinition Resolve (AssemblyNameReference name, ReaderPar
};
}

#if NET_CORE
assembly = SearchTrustedPlatformAssemblies (name, parameters);
assembly = NetCore ? SearchTrustedPlatformAssemblies (name, parameters) :
SearchFrameworkAssemblies (name, parameters);
if (assembly != null)
return assembly;
#else
var framework_dir = Path.GetDirectoryName (typeof (object).Module.FullyQualifiedName);
var framework_dirs = on_mono

assembly = LastChanceResolution (assembly, name, parameters);
if (assembly != null)
return assembly;

throw new AssemblyResolutionException (name);
}

protected virtual AssemblyDefinition LastChanceResolution (AssemblyDefinition assembly, AssemblyNameReference name, ReaderParameters parameters)
{
if (ResolveFailure != null) {
assembly = ResolveFailure (this, name);
}

return assembly;
}

protected AssemblyDefinition SearchFrameworkAssemblies (AssemblyNameReference name, ReaderParameters parameters)
{
AssemblyDefinition assembly = null;

var framework_dir = Path.GetDirectoryName (CoreModule.FullyQualifiedName);
var framework_dirs = AsMono
? new [] { framework_dir, Path.Combine (framework_dir, "Facades") }
: new [] { framework_dir };

@@ -160,20 +190,10 @@ public virtual AssemblyDefinition Resolve (AssemblyNameReference name, ReaderPar
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);
return assembly;
}

#if NET_CORE
AssemblyDefinition SearchTrustedPlatformAssemblies (AssemblyNameReference name, ReaderParameters parameters)
protected AssemblyDefinition SearchTrustedPlatformAssemblies (AssemblyNameReference name, ReaderParameters parameters)
{
if (name.IsWindowsRuntime)
return null;
@@ -184,15 +204,16 @@ AssemblyDefinition SearchTrustedPlatformAssemblies (AssemblyNameReference name,
return null;
}

static Dictionary<string, string> CreateTrustedPlatformAssemblyMap ()
private static Dictionary<string, string> CreateTrustedPlatformAssemblyMap ()
{
var result = new Dictionary<string, string> (StringComparer.OrdinalIgnoreCase);

string paths;

try {
paths = (string) AppDomain.CurrentDomain.GetData ("TRUSTED_PLATFORM_ASSEMBLIES");
} catch {
paths = (string)AppDomain.CurrentDomain.GetData ("TRUSTED_PLATFORM_ASSEMBLIES");
}
catch {
paths = null;
}

@@ -205,7 +226,6 @@ static Dictionary<string, string> CreateTrustedPlatformAssemblyMap ()

return result;
}
#endif

protected virtual AssemblyDefinition SearchDirectory (AssemblyNameReference name, IEnumerable<string> directories, ReaderParameters parameters)
{
@@ -217,7 +237,8 @@ protected virtual AssemblyDefinition SearchDirectory (AssemblyNameReference name
continue;
try {
return GetAssembly (file, parameters);
} catch (System.BadImageFormatException) {
}
catch (System.BadImageFormatException) {
continue;
}
}
@@ -226,25 +247,24 @@ protected virtual AssemblyDefinition SearchDirectory (AssemblyNameReference name
return null;
}

static bool IsZero (Version version)
private 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)
private AssemblyDefinition GetCorlib (AssemblyNameReference reference, ReaderParameters parameters)
{
var version = reference.Version;
var corlib = typeof (object).Assembly.GetName ();
var corlib = CoreModule.Assembly.GetName (); // GetFramework
if (corlib.Version == version || IsZero (version))
return GetAssembly (typeof (object).Module.FullyQualifiedName, parameters);
return GetAssembly (CoreModule.FullyQualifiedName, parameters);

var path = Directory.GetParent (
Directory.GetParent (
typeof (object).Module.FullyQualifiedName).FullName
CoreModule.FullyQualifiedName).FullName
).FullName;

if (on_mono) {
if (AsMono) {
if (version.Major == 1)
path = Path.Combine (path, "1.0");
else if (version.Major == 2) {
@@ -264,12 +284,15 @@ AssemblyDefinition GetCorlib (AssemblyNameReference reference, ReaderParameters
else
path = Path.Combine (path, "v1.1.4322");
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);
}
@@ -279,7 +302,7 @@ AssemblyDefinition GetCorlib (AssemblyNameReference reference, ReaderParameters
if (File.Exists (file))
return GetAssembly (file, parameters);

if (on_mono && Directory.Exists (path + "-api")) {
if (AsMono && Directory.Exists (path + "-api")) {
file = Path.Combine (path + "-api", "mscorlib.dll");
if (File.Exists (file))
return GetAssembly (file, parameters);
@@ -288,10 +311,10 @@ AssemblyDefinition GetCorlib (AssemblyNameReference reference, ReaderParameters
return null;
}

static Collection<string> GetGacPaths ()
private static Collection<string> GetGacPaths (bool mono, Module core)
{
if (on_mono)
return GetDefaultMonoGacPaths ();
if (mono)
return GetDefaultMonoGacPaths (core);

var paths = new Collection<string> (2);
var windir = Environment.GetEnvironmentVariable ("WINDIR");
@@ -303,10 +326,10 @@ static Collection<string> GetGacPaths ()
return paths;
}

static Collection<string> GetDefaultMonoGacPaths ()
private static Collection<string> GetDefaultMonoGacPaths (Module core)
{
var paths = new Collection<string> (1);
var gac = GetCurrentMonoGac ();
var gac = GetCurrentMonoGac (core);
if (gac != null)
paths.Add (gac);

@@ -327,29 +350,29 @@ static Collection<string> GetDefaultMonoGacPaths ()
return paths;
}

static string GetCurrentMonoGac ()
private static string GetCurrentMonoGac (Module core)
{
return Path.Combine (
Directory.GetParent (
Path.GetDirectoryName (typeof (object).Module.FullyQualifiedName)).FullName,
Path.GetDirectoryName (core.FullyQualifiedName)).FullName, // GetFrameworkDirectory
"gac");
}

AssemblyDefinition GetAssemblyInGac (AssemblyNameReference reference, ReaderParameters parameters)
private AssemblyDefinition GetAssemblyInGac (AssemblyNameReference reference, ReaderParameters parameters)
{
if (reference.PublicKeyToken == null || reference.PublicKeyToken.Length == 0)
return null;

if (gac_paths == null)
gac_paths = GetGacPaths ();
gac_paths = GetGacPaths (AsMono, CoreModule);

if (on_mono)
if (AsMono)
return GetAssemblyInMonoGac (reference, parameters);

return GetAssemblyInNetGac (reference, parameters);
}

AssemblyDefinition GetAssemblyInMonoGac (AssemblyNameReference reference, ReaderParameters parameters)
private AssemblyDefinition GetAssemblyInMonoGac (AssemblyNameReference reference, ReaderParameters parameters)
{
for (int i = 0; i < gac_paths.Count; i++) {
var gac_path = gac_paths [i];
@@ -361,7 +384,7 @@ AssemblyDefinition GetAssemblyInMonoGac (AssemblyNameReference reference, Reader
return null;
}

AssemblyDefinition GetAssemblyInNetGac (AssemblyNameReference reference, ReaderParameters parameters)
private AssemblyDefinition GetAssemblyInNetGac (AssemblyNameReference reference, ReaderParameters parameters)
{
var gacs = new [] { "GAC_MSIL", "GAC_32", "GAC_64", "GAC" };
var prefixes = new [] { string.Empty, "v4.0_" };
@@ -378,7 +401,7 @@ AssemblyDefinition GetAssemblyInNetGac (AssemblyNameReference reference, ReaderP
return null;
}

static string GetAssemblyFile (AssemblyNameReference reference, string prefix, string gac)
private static string GetAssemblyFile (AssemblyNameReference reference, string prefix, string gac)
{
var gac_folder = new StringBuilder ()
.Append (prefix)
@@ -393,7 +416,7 @@ static string GetAssemblyFile (AssemblyNameReference reference, string prefix, s
Path.Combine (gac, reference.Name), gac_folder.ToString ()),
reference.Name + ".dll");
}
#endif

public void Dispose ()
{
Dispose (true);
@@ -404,4 +427,4 @@ protected virtual void Dispose (bool disposing)
{
}
}
}
}
54 changes: 51 additions & 3 deletions Mono.Cecil/DefaultAssemblyResolver.cs
Original file line number Diff line number Diff line change
@@ -10,18 +10,32 @@

using System;
using System.Collections.Generic;
using System.Linq;

namespace Mono.Cecil {

public class DefaultAssemblyResolver : BaseAssemblyResolver {
public class DefaultAssemblyResolverProvider : IAssemblyResolverProvider {
public IAssemblyResolver Create (AssemblyDefinition assembly)
{
return new DefaultAssemblyResolver ();
}
}

readonly IDictionary<string, AssemblyDefinition> cache;
public class DefaultAssemblyResolver : BaseAssemblyResolver {
private readonly IDictionary<string, AssemblyDefinition> cache;

public DefaultAssemblyResolver ()
{
cache = new Dictionary<string, AssemblyDefinition> (StringComparer.Ordinal);
}

public DefaultAssemblyResolver (bool asNetCore, bool asMono, System.Reflection.Module core) : this ()
{
base.NetCore = asNetCore;
base.AsMono = asMono;
base.CoreModule = core;
}

public override AssemblyDefinition Resolve (AssemblyNameReference name)
{
Mixin.CheckName (name);
@@ -58,4 +72,38 @@ protected override void Dispose (bool disposing)
base.Dispose (disposing);
}
}
}

public class AdaptiveAssemblyResolverProvider : IAssemblyResolverProvider {
public IAssemblyResolver Create (AssemblyDefinition assembly)
{
var blob = assembly.CustomAttributes
.Where (a => a.AttributeType.FullName.Equals ("System.Runtime.Versioning.TargetFrameworkAttribute", StringComparison.Ordinal))
.FirstOrDefault ()?.GetBlob ();
var core = !System.Text.Encoding.ASCII.GetString ((blob ?? new byte [3]).Skip (3).ToArray ()).StartsWith (".NETFramework");
return new AdaptiveAssemblyResolver (core);
}
}

public class AdaptiveAssemblyResolver : DefaultAssemblyResolver {
public AdaptiveAssemblyResolver (bool core) :
base (core, false, typeof (object).Module) // harmless by experiment
{
}

protected override AssemblyDefinition LastChanceResolution (AssemblyDefinition assembly, AssemblyNameReference name, ReaderParameters parameters)
{
if (!base.NetCore) {
try // the mono gac
{
base.AsMono = true;
assembly = base.SearchFrameworkAssemblies (name, parameters);
if (assembly != null)
return assembly;
}
finally { base.AsMono = false; }
}

return base.LastChanceResolution (assembly, name, parameters);
}
}
}
58 changes: 33 additions & 25 deletions Mono.Cecil/MetadataResolver.cs
Original file line number Diff line number Diff line change
@@ -16,21 +16,28 @@ namespace Mono.Cecil {

public interface IAssemblyResolver : IDisposable {
AssemblyDefinition Resolve (AssemblyNameReference name);

AssemblyDefinition Resolve (AssemblyNameReference name, ReaderParameters parameters);
}

public interface IAssemblyResolverProvider {
IAssemblyResolver Create (AssemblyDefinition assembly);
}

public interface IMetadataResolver {
TypeDefinition Resolve (TypeReference type);

FieldDefinition Resolve (FieldReference field);

MethodDefinition Resolve (MethodReference method);
}

#if !NET_CORE
[Serializable]
#endif
public sealed class ResolutionException : Exception {

readonly MemberReference member;
public sealed class ResolutionException : Exception {
private readonly MemberReference member;

public MemberReference Member {
get { return member; }
@@ -79,8 +86,7 @@ public ResolutionException (MemberReference member, Exception innerException)
}

public class MetadataResolver : IMetadataResolver {

readonly IAssemblyResolver assembly_resolver;
private readonly IAssemblyResolver assembly_resolver;

public IAssemblyResolver AssemblyResolver {
get { return assembly_resolver; }
@@ -107,19 +113,21 @@ public virtual TypeDefinition Resolve (TypeReference type)

switch (scope.MetadataScopeType) {
case MetadataScopeType.AssemblyNameReference:
var assembly = assembly_resolver.Resolve ((AssemblyNameReference) scope);
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);
return GetType ((ModuleDefinition)scope, type);

case MetadataScopeType.ModuleReference:
if (type.Module.Assembly == null)
return null;

var modules = type.Module.Assembly.Modules;
var module_ref = (ModuleReference) scope;
var module_ref = (ModuleReference)scope;
for (int i = 0; i < modules.Count; i++) {
var netmodule = modules [i];
if (netmodule.Name == module_ref.Name)
@@ -131,7 +139,7 @@ public virtual TypeDefinition Resolve (TypeReference type)
throw new NotSupportedException ();
}

static TypeDefinition GetType (ModuleDefinition module, TypeReference reference)
private static TypeDefinition GetType (ModuleDefinition module, TypeReference reference)
{
var type = GetTypeDefinition (module, reference);
if (type != null)
@@ -156,7 +164,7 @@ static TypeDefinition GetType (ModuleDefinition module, TypeReference reference)
return null;
}

static TypeDefinition GetTypeDefinition (ModuleDefinition module, TypeReference type)
private static TypeDefinition GetTypeDefinition (ModuleDefinition module, TypeReference type)
{
if (!type.IsNested)
return module.GetType (type.Namespace, type.Name);
@@ -182,7 +190,7 @@ public virtual FieldDefinition Resolve (FieldReference field)
return GetField (type, field);
}

FieldDefinition GetField (TypeDefinition type, FieldReference reference)
private FieldDefinition GetField (TypeDefinition type, FieldReference reference)
{
while (type != null) {
var field = GetField (type.Fields, reference);
@@ -198,7 +206,7 @@ FieldDefinition GetField (TypeDefinition type, FieldReference reference)
return null;
}

static FieldDefinition GetField (Collection<FieldDefinition> fields, FieldReference reference)
private static FieldDefinition GetField (Collection<FieldDefinition> fields, FieldReference reference)
{
for (int i = 0; i < fields.Count; i++) {
var field = fields [i];
@@ -231,7 +239,7 @@ public virtual MethodDefinition Resolve (MethodReference method)
return GetMethod (type, method);
}

MethodDefinition GetMethod (TypeDefinition type, MethodReference reference)
private MethodDefinition GetMethod (TypeDefinition type, MethodReference reference)
{
while (type != null) {
var method = GetMethod (type.Methods, reference);
@@ -285,7 +293,7 @@ public static MethodDefinition GetMethod (Collection<MethodDefinition> methods,
return null;
}

static bool AreSame (Collection<ParameterDefinition> a, Collection<ParameterDefinition> b)
private static bool AreSame (Collection<ParameterDefinition> a, Collection<ParameterDefinition> b)
{
var count = a.Count;

@@ -302,7 +310,7 @@ static bool AreSame (Collection<ParameterDefinition> a, Collection<ParameterDefi
return true;
}

static bool IsVarArgCallTo (MethodDefinition method, MethodReference reference)
private static bool IsVarArgCallTo (MethodDefinition method, MethodReference reference)
{
if (method.Parameters.Count >= reference.Parameters.Count)
return false;
@@ -317,24 +325,24 @@ static bool IsVarArgCallTo (MethodDefinition method, MethodReference reference)
return true;
}

static bool AreSame (TypeSpecification a, TypeSpecification b)
private static bool AreSame (TypeSpecification a, TypeSpecification b)
{
if (!AreSame (a.ElementType, b.ElementType))
return false;

if (a.IsGenericInstance)
return AreSame ((GenericInstanceType) a, (GenericInstanceType) b);
return AreSame ((GenericInstanceType)a, (GenericInstanceType)b);

if (a.IsRequiredModifier || a.IsOptionalModifier)
return AreSame ((IModifierType) a, (IModifierType) b);
return AreSame ((IModifierType)a, (IModifierType)b);

if (a.IsArray)
return AreSame ((ArrayType) a, (ArrayType) b);
return AreSame ((ArrayType)a, (ArrayType)b);

return true;
}

static bool AreSame (ArrayType a, ArrayType b)
private static bool AreSame (ArrayType a, ArrayType b)
{
if (a.Rank != b.Rank)
return false;
@@ -344,12 +352,12 @@ static bool AreSame (ArrayType a, ArrayType b)
return true;
}

static bool AreSame (IModifierType a, IModifierType b)
private static bool AreSame (IModifierType a, IModifierType b)
{
return AreSame (a.ModifierType, b.ModifierType);
}

static bool AreSame (GenericInstanceType a, GenericInstanceType b)
private static bool AreSame (GenericInstanceType a, GenericInstanceType b)
{
if (a.GenericArguments.Count != b.GenericArguments.Count)
return false;
@@ -361,12 +369,12 @@ static bool AreSame (GenericInstanceType a, GenericInstanceType b)
return true;
}

static bool AreSame (GenericParameter a, GenericParameter b)
private static bool AreSame (GenericParameter a, GenericParameter b)
{
return a.Position == b.Position;
}

static bool AreSame (TypeReference a, TypeReference b)
private static bool AreSame (TypeReference a, TypeReference b)
{
if (ReferenceEquals (a, b))
return true;
@@ -378,10 +386,10 @@ static bool AreSame (TypeReference a, TypeReference b)
return false;

if (a.IsGenericParameter)
return AreSame ((GenericParameter) a, (GenericParameter) b);
return AreSame ((GenericParameter)a, (GenericParameter)b);

if (a.IsTypeSpecification ())
return AreSame ((TypeSpecification) a, (TypeSpecification) b);
return AreSame ((TypeSpecification)a, (TypeSpecification)b);

if (a.Name != b.Name || a.Namespace != b.Namespace)
return false;
143 changes: 78 additions & 65 deletions Mono.Cecil/ModuleDefinition.cs
Original file line number Diff line number Diff line change
@@ -27,19 +27,18 @@ public enum ReadingMode {
}

public sealed class ReaderParameters {

ReadingMode reading_mode;
private ReadingMode reading_mode;
internal IAssemblyResolver assembly_resolver;
internal IMetadataResolver metadata_resolver;
internal IMetadataImporterProvider metadata_importer_provider;
internal IReflectionImporterProvider reflection_importer_provider;
Stream symbol_stream;
ISymbolReaderProvider symbol_reader_provider;
bool read_symbols;
bool throw_symbols_mismatch;
bool projections;
bool in_memory;
bool read_write;
private Stream symbol_stream;
private ISymbolReaderProvider symbol_reader_provider;
private bool read_symbols;
private bool throw_symbols_mismatch;
private bool projections;
private bool in_memory;
private bool read_write;

public ReadingMode ReadingMode {
get { return reading_mode; }
@@ -51,6 +50,8 @@ public bool InMemory {
set { in_memory = value; }
}

public IAssemblyResolverProvider AssemblyResolverProvider { get; set; }

public IAssemblyResolver AssemblyResolver {
get { return assembly_resolver; }
set { assembly_resolver = value; }
@@ -114,15 +115,14 @@ public ReaderParameters (ReadingMode readingMode)
}

public sealed class ModuleParameters {

ModuleKind kind;
TargetRuntime runtime;
uint? timestamp;
TargetArchitecture architecture;
IAssemblyResolver assembly_resolver;
IMetadataResolver metadata_resolver;
IMetadataImporterProvider metadata_importer_provider;
IReflectionImporterProvider reflection_importer_provider;
private ModuleKind kind;
private TargetRuntime runtime;
private uint? timestamp;
private TargetArchitecture architecture;
private IAssemblyResolver assembly_resolver;
private IMetadataResolver metadata_resolver;
private IMetadataImporterProvider metadata_importer_provider;
private IReflectionImporterProvider reflection_importer_provider;

public ModuleKind Kind {
get { return kind; }
@@ -144,6 +144,8 @@ public TargetArchitecture Architecture {
set { architecture = value; }
}

public IAssemblyResolverProvider AssemblyResolverProvider { get; set; }

public IAssemblyResolver AssemblyResolver {
get { return assembly_resolver; }
set { assembly_resolver = value; }
@@ -171,21 +173,20 @@ public ModuleParameters ()
this.architecture = TargetArchitecture.I386;
}

static TargetRuntime GetCurrentRuntime ()
private static TargetRuntime GetCurrentRuntime ()
{
return typeof (object).Assembly.ImageRuntimeVersion.ParseRuntime ();
}
}

public sealed class WriterParameters {

uint? timestamp;
Stream symbol_stream;
ISymbolWriterProvider symbol_writer_provider;
bool write_symbols;
byte [] key_blob;
string key_container;
SR.StrongNameKeyPair key_pair;
private uint? timestamp;
private Stream symbol_stream;
private ISymbolWriterProvider symbol_writer_provider;
private bool write_symbols;
private byte [] key_blob;
private string key_container;
private SR.StrongNameKeyPair key_pair;

public uint? Timestamp {
get { return timestamp; }
@@ -230,7 +231,6 @@ public SR.StrongNameKeyPair StrongNameKeyPair {
}

public sealed class ModuleDefinition : ModuleReference, ICustomAttributeProvider, ICustomDebugInformationProvider, IDisposable {

internal Image Image;
internal MetadataSystem MetadataSystem;
internal ReadingMode ReadingMode;
@@ -241,36 +241,36 @@ public sealed class ModuleDefinition : ModuleReference, ICustomAttributeProvider
internal IMetadataResolver metadata_resolver;
internal TypeSystem type_system;
internal readonly MetadataReader reader;
readonly string file_name;
private readonly string file_name;

internal string runtime_version;
internal ModuleKind kind;
WindowsRuntimeProjections projections;
MetadataKind metadata_kind;
TargetRuntime runtime;
TargetArchitecture architecture;
ModuleAttributes attributes;
ModuleCharacteristics characteristics;
Guid mvid;
private WindowsRuntimeProjections projections;
private MetadataKind metadata_kind;
private TargetRuntime runtime;
private TargetArchitecture architecture;
private ModuleAttributes attributes;
private ModuleCharacteristics characteristics;
private Guid mvid;

internal ushort linker_version = 8;
internal ushort subsystem_major = 4;
internal ushort subsystem_minor = 0;
internal uint timestamp;

internal AssemblyDefinition assembly;
MethodDefinition entry_point;
bool entry_point_set;
private MethodDefinition entry_point;
private bool entry_point_set;

internal IReflectionImporter reflection_importer;
internal IMetadataImporter metadata_importer;

Collection<CustomAttribute> custom_attributes;
Collection<AssemblyNameReference> references;
Collection<ModuleReference> modules;
Collection<Resource> resources;
Collection<ExportedType> exported_types;
TypeDefinitionCollection types;
private Collection<CustomAttribute> custom_attributes;
private Collection<AssemblyNameReference> references;
private Collection<ModuleReference> modules;
private Collection<Resource> resources;
private Collection<ExportedType> exported_types;
private TypeDefinitionCollection types;

internal Collection<CustomDebugInformation> custom_infos;

@@ -382,11 +382,16 @@ internal IMetadataImporter MetadataImporter {
}
}

public IAssemblyResolverProvider AssemblyResolverProvider { get; internal set; }

public IAssemblyResolver AssemblyResolver {
get {
if (assembly_resolver.value == null) {
lock (module_lock) {
assembly_resolver = Disposable.Owned (new DefaultAssemblyResolver () as IAssemblyResolver);
assembly_resolver = Disposable.Owned (
(AssemblyResolverProvider != null) ?
AssemblyResolverProvider.Create (this.assembly) :
new DefaultAssemblyResolver () as IAssemblyResolver);
}
}

@@ -640,7 +645,7 @@ public bool TryGetTypeReference (string scope, string fullName, out TypeReferenc
return (type = GetTypeReference (scope, fullName)) != null;
}

TypeReference GetTypeReference (string scope, string fullname)
private TypeReference GetTypeReference (string scope, string fullname)
{
return Read (new Row<string, string> (scope, fullname), (row, reader) => reader.GetTypeReference (row.Col1, row.Col2));
}
@@ -684,22 +689,22 @@ public TypeDefinition GetType (string fullName)
if (position > 0)
return GetNestedType (fullName);

return ((TypeDefinitionCollection) this.Types).GetType (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);
return ((TypeDefinitionCollection)this.Types).GetType (@namespace ?? string.Empty, name);
}

public IEnumerable<TypeDefinition> GetTypes ()
{
return GetTypes (Types);
}

static IEnumerable<TypeDefinition> GetTypes (Collection<TypeDefinition> types)
private static IEnumerable<TypeDefinition> GetTypes (Collection<TypeDefinition> types)
{
for (int i = 0; i < types.Count; i++) {
var type = types [i];
@@ -714,7 +719,7 @@ static IEnumerable<TypeDefinition> GetTypes (Collection<TypeDefinition> types)
}
}

TypeDefinition GetNestedType (string fullname)
private TypeDefinition GetNestedType (string fullname)
{
var names = fullname.Split ('/');
var type = GetType (names [0]);
@@ -748,7 +753,7 @@ internal TypeDefinition Resolve (TypeReference type)
return MetadataResolver.Resolve (type);
}

static void CheckContext (IGenericParameterProvider context, ModuleDefinition module)
private static void CheckContext (IGenericParameterProvider context, ModuleDefinition module)
{
if (context == null)
return;
@@ -921,14 +926,14 @@ public MethodReference ImportReference (MethodReference method, IGenericParamete

public IMetadataTokenProvider LookupToken (int token)
{
return LookupToken (new MetadataToken ((uint) token));
return LookupToken (new MetadataToken ((uint)token));
}

public IMetadataTokenProvider LookupToken (MetadataToken token)
{
return Read (token, (t, reader) => reader.LookupToken (t));
}

public void ImmediateRead ()
{
if (!HasImage)
@@ -938,7 +943,7 @@ public void ImmediateRead ()
moduleReader.ReadModule (this, resolve_attributes: true);
}

readonly object module_lock = new object();
private readonly object module_lock = new object ();

internal object SyncRoot {
get { return module_lock; }
@@ -1017,11 +1022,13 @@ public static ModuleDefinition CreateModule (string name, ModuleParameters param
architecture = parameters.Architecture,
mvid = Guid.NewGuid (),
Attributes = ModuleAttributes.ILOnly,
Characteristics = (ModuleCharacteristics) 0x8540,
Characteristics = (ModuleCharacteristics)0x8540,
};

if (parameters.AssemblyResolver != null)
module.assembly_resolver = Disposable.NotOwned (parameters.AssemblyResolver);
else if (parameters.AssemblyResolverProvider != null)
module.AssemblyResolverProvider = parameters.AssemblyResolverProvider;

if (parameters.MetadataResolver != null)
module.metadata_resolver = parameters.MetadataResolver;
@@ -1044,7 +1051,7 @@ public static ModuleDefinition CreateModule (string name, ModuleParameters param
return module;
}

static AssemblyNameDefinition CreateAssemblyName (string name)
private static AssemblyNameDefinition CreateAssemblyName (string name)
{
if (name.EndsWith (".dll") || name.EndsWith (".exe"))
name = name.Substring (0, name.Length - 4);
@@ -1063,7 +1070,7 @@ public void ReadSymbols ()

public void ReadSymbols (ISymbolReader reader)
{
ReadSymbols(reader, throwIfSymbolsAreNotMaching: true);
ReadSymbols (reader, throwIfSymbolsAreNotMaching: true);
}

public void ReadSymbols (ISymbolReader reader, bool throwIfSymbolsAreNotMaching)
@@ -1098,7 +1105,7 @@ public static ModuleDefinition ReadModule (string fileName, ReaderParameters par
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);
var memory = new MemoryStream (stream.CanSeek ? (int)stream.Length : 0);
using (stream)
stream.CopyTo (memory);

@@ -1108,13 +1115,14 @@ public static ModuleDefinition ReadModule (string fileName, ReaderParameters par

try {
return ReadModule (Disposable.Owned (stream), fileName, parameters);
} catch (Exception) {
}
catch (Exception) {
stream.Dispose ();
throw;
}
}

static Stream GetFileStream (string fileName, FileMode mode, FileAccess access, FileShare share)
private static Stream GetFileStream (string fileName, FileMode mode, FileAccess access, FileShare share)
{
Mixin.CheckFileName (fileName);

@@ -1134,7 +1142,7 @@ public static ModuleDefinition ReadModule (Stream stream, ReaderParameters param
return ReadModule (Disposable.NotOwned (stream), stream.GetFileName (), parameters);
}

static ModuleDefinition ReadModule (Disposable<Stream> stream, string fileName, ReaderParameters parameters)
private static ModuleDefinition ReadModule (Disposable<Stream> stream, string fileName, ReaderParameters parameters)
{
Mixin.CheckParameters (parameters);

@@ -1183,7 +1191,7 @@ public void Write (Stream stream, WriterParameters parameters)
}
}

static partial class Mixin {
internal static partial class Mixin {

public enum Argument {
name,
@@ -1279,7 +1287,7 @@ public static void CheckParameters (object parameters)

public static uint GetTimestamp ()
{
return (uint) DateTime.UtcNow.Subtract (new DateTime (1970, 1, 1)).TotalSeconds;
return (uint)DateTime.UtcNow.Subtract (new DateTime (1970, 1, 1)).TotalSeconds;
}

public static bool HasImage (this ModuleDefinition self)
@@ -1306,8 +1314,10 @@ public static TargetRuntime ParseRuntime (this string self)
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;
@@ -1319,10 +1329,13 @@ 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";
@@ -1337,7 +1350,7 @@ public static bool IsWindowsMetadata (this ModuleDefinition module)
public static byte [] ReadAll (this Stream self)
{
int read;
var memory = new MemoryStream ((int) self.Length);
var memory = new MemoryStream ((int)self.Length);
var buffer = new byte [1024];

while ((read = self.Read (buffer, 0, buffer.Length)) != 0)
@@ -1350,4 +1363,4 @@ public static void Read (object o)
{
}
}
}
}
47 changes: 33 additions & 14 deletions Test/Mono.Cecil.Tests/ResolveTests.cs
Original file line number Diff line number Diff line change
@@ -12,7 +12,6 @@ namespace Mono.Cecil.Tests {

[TestFixture]
public class ResolveTests : BaseTestFixture {

[Test]
public void StringEmpty ()
{
@@ -26,11 +25,11 @@ public void StringEmpty ()
Assert.IsNotNull (definition);

Assert.AreEqual ("System.String System.String::Empty", definition.FullName);
Assert.AreEqual (Platform.OnCoreClr ? "System.Private.CoreLib" : "mscorlib",
Assert.AreEqual (Platform.OnCoreClr ? "System.Private.CoreLib" : "mscorlib",
definition.Module.Assembly.Name.Name);
}

delegate string GetSubstring (string str, int start, int length);
private delegate string GetSubstring (string str, int start, int length);

[Test]
public void StringSubstring ()
@@ -58,7 +57,7 @@ public void StringLength ()

Assert.AreEqual ("get_Length", definition.Name);
Assert.AreEqual ("System.String", definition.DeclaringType.FullName);
Assert.AreEqual (Platform.OnCoreClr ? "System.Private.CoreLib" : "mscorlib",
Assert.AreEqual (Platform.OnCoreClr ? "System.Private.CoreLib" : "mscorlib",
definition.Module.Assembly.Name.Name);
}

@@ -100,8 +99,7 @@ public void DictionaryOfStringTypeDefinitionTryGetValue ()
definition.Module.Assembly.Name.Name);
}

class CustomResolver : DefaultAssemblyResolver {

private class CustomResolver : DefaultAssemblyResolver {
public void Register (AssemblyDefinition assembly)
{
this.RegisterAssembly (assembly);
@@ -173,7 +171,7 @@ public void NestedTypeForwarder ()
[Test]
public void RectangularArrayResolveGetMethod ()
{
var get_a_b = GetReference<Func<int[,], int>, MethodReference> (matrix => matrix [2, 2]);
var get_a_b = GetReference<Func<int [,], int>, MethodReference> (matrix => matrix [2, 2]);

Assert.AreEqual ("Get", get_a_b.Name);
Assert.IsNotNull (get_a_b.Module);
@@ -201,7 +199,7 @@ public void ResolveFunctionPointer ()
var field = global.GetField ("__onexitbegin_app_domain");

var type = field.FieldType as PointerType;
Assert.IsNotNull(type);
Assert.IsNotNull (type);

var fnptr = type.ElementType as FunctionPointerType;
Assert.IsNotNull (fnptr);
@@ -247,6 +245,25 @@ public void ResolvePortableClassLibraryReference ()
}
}

[Test]
public void ResolveFrameworkGACReference ()
{
// only makes sense on Windows
OnlyOnWindows ();

var resolver = new AdaptiveAssemblyResolverProvider ();
var parameters = new ReaderParameters { AssemblyResolverProvider = resolver };

using (var module = GetResourceModule ("FrameworkWPF.dll", parameters)) {
var rt_folder = Path.Combine (Path.GetTempPath (), "FrameworkWPF");
if (!Directory.Exists (rt_folder))
Directory.CreateDirectory (rt_folder);
var rt_module = Path.Combine (rt_folder, Path.GetFileName ("FrameworkWPF.dll"));
var writer_parameters = new WriterParameters ();
module.Write (rt_module, writer_parameters);
}
}

[Test]
public void ResolveModuleReferenceFromMemberReferenceTest ()
{
@@ -282,20 +299,21 @@ public void ResolveModuleReferenceFromMemberReferenceOfSingleNetModuleTest ()
Assert.IsNull (methodTypeRef.Resolve ());
}
}
TRet GetReference<TDel, TRet> (TDel code)

private TRet GetReference<TDel, TRet> (TDel code)
{
var @delegate = code as Delegate;
if (@delegate == null)
throw new InvalidOperationException ();

var reference = (TRet) GetReturnee (GetMethodFromDelegate (@delegate));
var reference = (TRet)GetReturnee (GetMethodFromDelegate (@delegate));

Assert.IsNotNull (reference);

return reference;
}

static object GetReturnee (MethodDefinition method)
private static object GetReturnee (MethodDefinition method)
{
Assert.IsTrue (method.HasBody);

@@ -311,6 +329,7 @@ static object GetReturnee (MethodDefinition method)
case OperandType.InlineType:
case OperandType.InlineMethod:
return instruction.Operand;

default:
instruction = instruction.Previous;
break;
@@ -320,14 +339,14 @@ static object GetReturnee (MethodDefinition method)
throw new InvalidOperationException ();
}

MethodDefinition GetMethodFromDelegate (Delegate @delegate)
private MethodDefinition GetMethodFromDelegate (Delegate @delegate)
{
var method = @delegate.Method;
var type = (TypeDefinition) TypeParser.ParseType (GetCurrentModule (), method.DeclaringType.FullName);
var type = (TypeDefinition)TypeParser.ParseType (GetCurrentModule (), method.DeclaringType.FullName);

Assert.IsNotNull (type);

return type.Methods.Where (m => m.Name == method.Name).First ();
}
}
}
}
Binary file added Test/Resources/assemblies/FrameworkWPF.dll
Binary file not shown.
Binary file added Test/Resources/assemblies/FrameworkWPF.pdb
Binary file not shown.