using System;
using System.Collections;
-
+using System.IO;
using Mono.Cecil;
namespace Mono.Linker {
public class AssemblyResolver : BaseAssemblyResolver {
- Hashtable _assemblies;
+ IDictionary _assemblies;
public IDictionary AssemblyCache {
get { return _assemblies; }
}
public AssemblyResolver ()
+ : this (new Hashtable ())
+ {
+ }
+
+ public AssemblyResolver (IDictionary assembly_cache)
{
- _assemblies = new Hashtable ();
+ _assemblies = assembly_cache;
}
- public override AssemblyDefinition Resolve (AssemblyNameReference name)
+ public override AssemblyDefinition Resolve (AssemblyNameReference name, ReaderParameters parameters)
{
AssemblyDefinition asm = (AssemblyDefinition) _assemblies [name.Name];
if (asm == null) {
- asm = base.Resolve (name);
- asm.Resolver = this;
+ asm = base.Resolve (name, parameters);
_assemblies [name.Name] = asm;
}
return asm;
}
- public TypeDefinition Resolve (TypeReference type)
- {
- if (type is TypeDefinition)
- return (TypeDefinition) type;
-
- AssemblyNameReference reference = type.Scope as AssemblyNameReference;
- if (reference != null) {
- AssemblyDefinition assembly = Resolve (reference);
- return assembly.MainModule.Types [type.FullName];
- }
-
- ModuleDefinition module = type.Scope as ModuleDefinition;
- if (module != null)
- return module.Types [type.FullName];
-
- throw new NotImplementedException ();
- }
-
- public FieldDefinition Resolve (FieldReference field)
- {
- TypeDefinition type = Resolve (GetDeclaringType (field.DeclaringType));
- return GetField (type.Fields, field);
- }
-
- static FieldDefinition GetField (ICollection collection, FieldReference reference)
- {
- foreach (FieldDefinition field in collection) {
- if (field.Name != reference.Name)
- continue;
-
- if (!AreSame (field.FieldType, reference.FieldType))
- continue;
-
- return field;
- }
-
- return null;
- }
-
- public MethodDefinition Resolve (MethodReference method)
- {
- TypeDefinition type = Resolve (GetDeclaringType (method.DeclaringType));
- if (method.Name == MethodDefinition.Cctor || method.Name == MethodDefinition.Ctor)
- return GetMethod (type.Constructors, method);
- else
- return GetMethod (type, method);
- }
-
- static TypeReference GetDeclaringType (TypeReference type)
- {
- TypeReference t = type;
- while (t is TypeSpecification)
- t = ((TypeSpecification) t).ElementType;
- return t;
- }
-
- MethodDefinition GetMethod (TypeDefinition type, MethodReference reference)
- {
- while (type != null) {
- MethodDefinition method = GetMethod (type.Methods, reference);
- if (method == null)
- type = Resolve (GetDeclaringType (type.BaseType));
- else
- return method;
- }
-
- return null;
- }
-
- static MethodDefinition GetMethod (ICollection collection, MethodReference reference)
- {
- foreach (MethodDefinition meth in collection) {
- if (meth.Name != reference.Name)
- continue;
-
- if (!AreSame (meth.ReturnType.ReturnType, reference.ReturnType.ReturnType))
- continue;
-
- if (!AreSame (meth.Parameters, reference.Parameters))
- continue;
-
- return meth;
- }
-
- return null;
- }
-
- static bool AreSame (ParameterDefinitionCollection a, ParameterDefinitionCollection b)
- {
- if (a.Count != b.Count)
- return false;
-
- if (a.Count == 0)
- return true;
-
- for (int i = 0; i < a.Count; i++)
- if (!AreSame (a [i].ParameterType, b [i].ParameterType))
- return false;
-
- return true;
- }
-
- static bool AreSame (TypeReference a, TypeReference b)
- {
- while (a is TypeSpecification || b is TypeSpecification) {
- if (a.GetType () != b.GetType ())
- return false;
-
- a = ((TypeSpecification) a).ElementType;
- b = ((TypeSpecification) b).ElementType;
- }
-
- if (a is GenericParameter || b is GenericParameter) {
- if (a.GetType() != b.GetType())
- return false;
-
- GenericParameter pa = (GenericParameter) a;
- GenericParameter pb = (GenericParameter) b;
-
- return pa.Position == pb.Position;
- }
-
- return a.FullName == b.FullName;
- }
-
public void CacheAssembly (AssemblyDefinition assembly)
{
- _assemblies [assembly.Name.FullName] = assembly;
- assembly.Resolver = this;
+ _assemblies [assembly.Name.Name] = assembly;
+ base.AddSearchDirectory (Path.GetDirectoryName (assembly.MainModule.FileName));
}
}
}