PageRenderTime 37ms CodeModel.GetById 1ms app.highlight 30ms RepoModel.GetById 1ms app.codeStats 0ms

/Mono.Cecil/Import.cs

http://github.com/jbevain/cecil
C# | 812 lines | 639 code | 164 blank | 9 comment | 111 complexity | 148e45ffd9d757421b72da4de657d02f MD5 | raw file
  1//
  2// Author:
  3//   Jb Evain (jbevain@gmail.com)
  4//
  5// Copyright (c) 2008 - 2015 Jb Evain
  6// Copyright (c) 2008 - 2011 Novell, Inc.
  7//
  8// Licensed under the MIT/X11 license.
  9//
 10
 11using System;
 12using System.Collections.Generic;
 13using Mono.Collections.Generic;
 14using SR = System.Reflection;
 15
 16using Mono.Cecil.Metadata;
 17
 18namespace Mono.Cecil {
 19
 20	public interface IMetadataImporterProvider {
 21		IMetadataImporter GetMetadataImporter (ModuleDefinition module);
 22	}
 23
 24	public interface IMetadataImporter {
 25		AssemblyNameReference ImportReference (AssemblyNameReference reference);
 26		TypeReference ImportReference (TypeReference type, IGenericParameterProvider context);
 27		FieldReference ImportReference (FieldReference field, IGenericParameterProvider context);
 28		MethodReference ImportReference (MethodReference method, IGenericParameterProvider context);
 29	}
 30
 31	public interface IReflectionImporterProvider {
 32		IReflectionImporter GetReflectionImporter (ModuleDefinition module);
 33	}
 34
 35	public interface IReflectionImporter {
 36		AssemblyNameReference ImportReference (SR.AssemblyName reference);
 37		TypeReference ImportReference (Type type, IGenericParameterProvider context);
 38		FieldReference ImportReference (SR.FieldInfo field, IGenericParameterProvider context);
 39		MethodReference ImportReference (SR.MethodBase method, IGenericParameterProvider context);
 40	}
 41
 42	struct ImportGenericContext {
 43
 44		Collection<IGenericParameterProvider> stack;
 45
 46		public bool IsEmpty { get { return stack == null; } }
 47
 48		public ImportGenericContext (IGenericParameterProvider provider)
 49		{
 50			if (provider == null)
 51				throw new ArgumentNullException ("provider");
 52
 53			stack = null;
 54
 55			Push (provider);
 56		}
 57
 58		public void Push (IGenericParameterProvider provider)
 59		{
 60			if (stack == null)
 61				stack = new Collection<IGenericParameterProvider> (1) { provider };
 62			else
 63				stack.Add (provider);
 64		}
 65
 66		public void Pop ()
 67		{
 68			stack.RemoveAt (stack.Count - 1);
 69		}
 70
 71		public TypeReference MethodParameter (string method, int position)
 72		{
 73			for (int i = stack.Count - 1; i >= 0; i--) {
 74				var candidate = stack [i] as MethodReference;
 75				if (candidate == null)
 76					continue;
 77
 78				if (method != NormalizeMethodName (candidate))
 79					continue;
 80
 81				return candidate.GenericParameters [position];
 82			}
 83
 84			throw new InvalidOperationException ();
 85		}
 86
 87		public string NormalizeMethodName (MethodReference method)
 88		{
 89			return method.DeclaringType.GetElementType ().FullName + "." + method.Name;
 90		}
 91
 92		public TypeReference TypeParameter (string type, int position)
 93		{
 94			for (int i = stack.Count - 1; i >= 0; i--) {
 95				var candidate = GenericTypeFor (stack [i]);
 96
 97				if (candidate.FullName != type)
 98					continue;
 99
100				return candidate.GenericParameters [position];
101			}
102
103			throw new InvalidOperationException ();
104		}
105
106		static TypeReference GenericTypeFor (IGenericParameterProvider context)
107		{
108			var type = context as TypeReference;
109			if (type != null)
110				return type.GetElementType ();
111
112			var method = context as MethodReference;
113			if (method != null)
114				return method.DeclaringType.GetElementType ();
115
116			throw new InvalidOperationException ();
117		}
118
119		public static ImportGenericContext For (IGenericParameterProvider context)
120		{
121			return context != null ? new ImportGenericContext (context) : default (ImportGenericContext);
122		}
123	}
124
125	public class DefaultReflectionImporter : IReflectionImporter {
126
127		readonly protected ModuleDefinition module;
128
129		public DefaultReflectionImporter (ModuleDefinition module)
130		{
131			Mixin.CheckModule (module);
132
133			this.module = module;
134		}
135
136		enum ImportGenericKind {
137			Definition,
138			Open,
139		}
140
141		static readonly Dictionary<Type, ElementType> type_etype_mapping = new Dictionary<Type, ElementType> (18) {
142			{ typeof (void), ElementType.Void },
143			{ typeof (bool), ElementType.Boolean },
144			{ typeof (char), ElementType.Char },
145			{ typeof (sbyte), ElementType.I1 },
146			{ typeof (byte), ElementType.U1 },
147			{ typeof (short), ElementType.I2 },
148			{ typeof (ushort), ElementType.U2 },
149			{ typeof (int), ElementType.I4 },
150			{ typeof (uint), ElementType.U4 },
151			{ typeof (long), ElementType.I8 },
152			{ typeof (ulong), ElementType.U8 },
153			{ typeof (float), ElementType.R4 },
154			{ typeof (double), ElementType.R8 },
155			{ typeof (string), ElementType.String },
156			{ typeof (TypedReference), ElementType.TypedByRef },
157			{ typeof (IntPtr), ElementType.I },
158			{ typeof (UIntPtr), ElementType.U },
159			{ typeof (object), ElementType.Object },
160		};
161
162		TypeReference ImportType (Type type, ImportGenericContext context)
163		{
164			return ImportType (type, context, ImportGenericKind.Open);
165		}
166
167		TypeReference ImportType (Type type, ImportGenericContext context, ImportGenericKind import_kind)
168		{
169			if (IsTypeSpecification (type) || ImportOpenGenericType (type, import_kind))
170				return ImportTypeSpecification (type, context);
171
172			var reference = new TypeReference (
173				string.Empty,
174				type.Name,
175				module,
176				ImportScope (type),
177				type.IsValueType);
178
179			reference.etype = ImportElementType (type);
180
181			if (IsNestedType (type))
182				reference.DeclaringType = ImportType (type.DeclaringType, context, import_kind);
183			else
184				reference.Namespace = type.Namespace ?? string.Empty;
185
186			if (type.IsGenericType)
187				ImportGenericParameters (reference, type.GetGenericArguments ());
188
189			return reference;
190		}
191
192		protected virtual IMetadataScope ImportScope (Type type)
193		{
194			return ImportScope (type.Assembly);
195		}
196
197		static bool ImportOpenGenericType (Type type, ImportGenericKind import_kind)
198		{
199			return type.IsGenericType && type.IsGenericTypeDefinition && import_kind == ImportGenericKind.Open;
200		}
201
202		static bool ImportOpenGenericMethod (SR.MethodBase method, ImportGenericKind import_kind)
203		{
204			return method.IsGenericMethod && method.IsGenericMethodDefinition && import_kind == ImportGenericKind.Open;
205		}
206
207		static bool IsNestedType (Type type)
208		{
209			return type.IsNested;
210		}
211
212		TypeReference ImportTypeSpecification (Type type, ImportGenericContext context)
213		{
214			if (type.IsByRef)
215				return new ByReferenceType (ImportType (type.GetElementType (), context));
216
217			if (type.IsPointer)
218				return new PointerType (ImportType (type.GetElementType (), context));
219
220			if (type.IsArray)
221				return new ArrayType (ImportType (type.GetElementType (), context), type.GetArrayRank ());
222
223			if (type.IsGenericType)
224				return ImportGenericInstance (type, context);
225
226			if (type.IsGenericParameter)
227				return ImportGenericParameter (type, context);
228
229			throw new NotSupportedException (type.FullName);
230		}
231
232		static TypeReference ImportGenericParameter (Type type, ImportGenericContext context)
233		{
234			if (context.IsEmpty)
235				throw new InvalidOperationException ();
236
237			if (type.DeclaringMethod != null)
238				return context.MethodParameter (NormalizeMethodName (type.DeclaringMethod), type.GenericParameterPosition);
239
240			if (type.DeclaringType != null)
241				return context.TypeParameter (NormalizeTypeFullName (type.DeclaringType), type.GenericParameterPosition);
242
243			throw new InvalidOperationException();
244		}
245
246		static string NormalizeMethodName (SR.MethodBase method)
247		{
248			return NormalizeTypeFullName (method.DeclaringType) + "." + method.Name;
249		}
250
251		static string NormalizeTypeFullName (Type type)
252		{
253			if (IsNestedType (type))
254				return NormalizeTypeFullName (type.DeclaringType) + "/" + type.Name;
255
256			return type.FullName;
257		}
258
259		TypeReference ImportGenericInstance (Type type, ImportGenericContext context)
260		{
261			var element_type = ImportType (type.GetGenericTypeDefinition (), context, ImportGenericKind.Definition);
262			var arguments = type.GetGenericArguments ();
263			var instance = new GenericInstanceType (element_type, arguments.Length);
264			var instance_arguments = instance.GenericArguments;
265
266			context.Push (element_type);
267			try {
268				for (int i = 0; i < arguments.Length; i++)
269					instance_arguments.Add (ImportType (arguments [i], context));
270
271				return instance;
272			} finally {
273				context.Pop ();
274			}
275		}
276
277		static bool IsTypeSpecification (Type type)
278		{
279			return type.HasElementType
280				|| IsGenericInstance (type)
281				|| type.IsGenericParameter;
282		}
283
284		static bool IsGenericInstance (Type type)
285		{
286			return type.IsGenericType && !type.IsGenericTypeDefinition;
287		}
288
289		static ElementType ImportElementType (Type type)
290		{
291			ElementType etype;
292			if (!type_etype_mapping.TryGetValue (type, out etype))
293				return ElementType.None;
294
295			return etype;
296		}
297
298		protected AssemblyNameReference ImportScope (SR.Assembly assembly)
299		{
300			return ImportReference (assembly.GetName ());
301		}
302
303		public virtual AssemblyNameReference ImportReference (SR.AssemblyName name)
304		{
305			Mixin.CheckName (name);
306
307			AssemblyNameReference reference;
308			if (TryGetAssemblyNameReference (name, out reference))
309				return reference;
310
311			reference = new AssemblyNameReference (name.Name, name.Version)
312			{
313				PublicKeyToken = name.GetPublicKeyToken (),
314				Culture = name.CultureInfo.Name,
315				HashAlgorithm = (AssemblyHashAlgorithm) name.HashAlgorithm,
316			};
317
318			module.AssemblyReferences.Add (reference);
319
320			return reference;
321		}
322
323		bool TryGetAssemblyNameReference (SR.AssemblyName name, out AssemblyNameReference assembly_reference)
324		{
325			var references = module.AssemblyReferences;
326
327			for (int i = 0; i < references.Count; i++) {
328				var reference = references [i];
329				if (name.FullName != reference.FullName) // TODO compare field by field
330					continue;
331
332				assembly_reference = reference;
333				return true;
334			}
335
336			assembly_reference = null;
337			return false;
338		}
339
340		FieldReference ImportField (SR.FieldInfo field, ImportGenericContext context)
341		{
342			var declaring_type = ImportType (field.DeclaringType, context);
343
344			if (IsGenericInstance (field.DeclaringType))
345				field = ResolveFieldDefinition (field);
346
347			context.Push (declaring_type);
348			try {
349				return new FieldReference {
350					Name = field.Name,
351					DeclaringType = declaring_type,
352					FieldType = ImportType (field.FieldType, context),
353				};
354			} finally {
355				context.Pop ();
356			}
357		}
358
359		static SR.FieldInfo ResolveFieldDefinition (SR.FieldInfo field)
360		{
361			return field.Module.ResolveField (field.MetadataToken);
362		}
363
364		static SR.MethodBase ResolveMethodDefinition (SR.MethodBase method)
365		{
366			return method.Module.ResolveMethod (method.MetadataToken);
367		}
368
369		MethodReference ImportMethod (SR.MethodBase method, ImportGenericContext context, ImportGenericKind import_kind)
370		{
371			if (IsMethodSpecification (method) || ImportOpenGenericMethod (method, import_kind))
372				return ImportMethodSpecification (method, context);
373
374			var declaring_type = ImportType (method.DeclaringType, context);
375
376			if (IsGenericInstance (method.DeclaringType))
377				method = ResolveMethodDefinition (method);
378
379			var reference = new MethodReference {
380				Name = method.Name,
381				HasThis = HasCallingConvention (method, SR.CallingConventions.HasThis),
382				ExplicitThis = HasCallingConvention (method, SR.CallingConventions.ExplicitThis),
383				DeclaringType = ImportType (method.DeclaringType, context, ImportGenericKind.Definition),
384			};
385
386			if (HasCallingConvention (method, SR.CallingConventions.VarArgs))
387				reference.CallingConvention &= MethodCallingConvention.VarArg;
388
389			if (method.IsGenericMethod)
390				ImportGenericParameters (reference, method.GetGenericArguments ());
391
392			context.Push (reference);
393			try {
394				var method_info = method as SR.MethodInfo;
395				reference.ReturnType = method_info != null
396					? ImportType (method_info.ReturnType, context)
397					: ImportType (typeof (void), default (ImportGenericContext));
398
399				var parameters = method.GetParameters ();
400				var reference_parameters = reference.Parameters;
401
402				for (int i = 0; i < parameters.Length; i++)
403					reference_parameters.Add (
404						new ParameterDefinition (ImportType (parameters [i].ParameterType, context)));
405
406				reference.DeclaringType = declaring_type;
407
408				return reference;
409			} finally {
410				context.Pop ();
411			}
412		}
413
414		static void ImportGenericParameters (IGenericParameterProvider provider, Type [] arguments)
415		{
416			var provider_parameters = provider.GenericParameters;
417
418			for (int i = 0; i < arguments.Length; i++)
419				provider_parameters.Add (new GenericParameter (arguments [i].Name, provider));
420		}
421
422		static bool IsMethodSpecification (SR.MethodBase method)
423		{
424			return method.IsGenericMethod && !method.IsGenericMethodDefinition;
425		}
426
427		MethodReference ImportMethodSpecification (SR.MethodBase method, ImportGenericContext context)
428		{
429			var method_info = method as SR.MethodInfo;
430			if (method_info == null)
431				throw new InvalidOperationException ();
432
433			var element_method = ImportMethod (method_info.GetGenericMethodDefinition (), context, ImportGenericKind.Definition);
434			var instance = new GenericInstanceMethod (element_method);
435			var arguments = method.GetGenericArguments ();
436			var instance_arguments = instance.GenericArguments;
437
438			context.Push (element_method);
439			try {
440				for (int i = 0; i < arguments.Length; i++)
441					instance_arguments.Add (ImportType (arguments [i], context));
442
443				return instance;
444			} finally {
445				context.Pop ();
446			}
447		}
448
449		static bool HasCallingConvention (SR.MethodBase method, SR.CallingConventions conventions)
450		{
451			return (method.CallingConvention & conventions) != 0;
452		}
453
454		public virtual TypeReference ImportReference (Type type, IGenericParameterProvider context)
455		{
456			Mixin.CheckType (type);
457			return ImportType (
458				type,
459				ImportGenericContext.For (context),
460				context != null ? ImportGenericKind.Open : ImportGenericKind.Definition);
461		}
462
463		public virtual FieldReference ImportReference (SR.FieldInfo field, IGenericParameterProvider context)
464		{
465			Mixin.CheckField (field);
466			return ImportField (field, ImportGenericContext.For (context));
467		}
468
469		public virtual MethodReference ImportReference (SR.MethodBase method, IGenericParameterProvider context)
470		{
471			Mixin.CheckMethod (method);
472			return ImportMethod (method,
473				ImportGenericContext.For (context),
474				context != null ? ImportGenericKind.Open : ImportGenericKind.Definition);
475		}
476	}
477
478	public class DefaultMetadataImporter : IMetadataImporter {
479
480		readonly protected ModuleDefinition module;
481
482		public DefaultMetadataImporter (ModuleDefinition module)
483		{
484			Mixin.CheckModule (module);
485
486			this.module = module;
487		}
488
489		TypeReference ImportType (TypeReference type, ImportGenericContext context)
490		{
491			if (type.IsTypeSpecification ())
492				return ImportTypeSpecification (type, context);
493
494			var reference = new TypeReference (
495				type.Namespace,
496				type.Name,
497				module,
498				ImportScope (type),
499				type.IsValueType);
500
501			MetadataSystem.TryProcessPrimitiveTypeReference (reference);
502
503			if (type.IsNested)
504				reference.DeclaringType = ImportType (type.DeclaringType, context);
505
506			if (type.HasGenericParameters)
507				ImportGenericParameters (reference, type);
508
509			return reference;
510		}
511
512		protected virtual IMetadataScope ImportScope (TypeReference type)
513		{
514			return ImportScope (type.Scope);
515		}
516
517		protected IMetadataScope ImportScope (IMetadataScope scope)
518		{
519			switch (scope.MetadataScopeType) {
520			case MetadataScopeType.AssemblyNameReference:
521				return ImportReference ((AssemblyNameReference) scope);
522			case MetadataScopeType.ModuleDefinition:
523				if (scope == module) return scope;
524				return ImportReference (((ModuleDefinition) scope).Assembly.Name);
525			case MetadataScopeType.ModuleReference:
526				throw new NotImplementedException ();
527			}
528
529			throw new NotSupportedException ();
530		}
531
532		public virtual AssemblyNameReference ImportReference (AssemblyNameReference name)
533		{
534			Mixin.CheckName (name);
535
536			AssemblyNameReference reference;
537			if (module.TryGetAssemblyNameReference (name, out reference))
538				return reference;
539
540			reference = new AssemblyNameReference (name.Name, name.Version) {
541				Culture = name.Culture,
542				HashAlgorithm = name.HashAlgorithm,
543				IsRetargetable = name.IsRetargetable,
544				IsWindowsRuntime = name.IsWindowsRuntime,
545			};
546
547			var pk_token = !name.PublicKeyToken.IsNullOrEmpty ()
548				? new byte [name.PublicKeyToken.Length]
549				: Empty<byte>.Array;
550
551			if (pk_token.Length > 0)
552				Buffer.BlockCopy (name.PublicKeyToken, 0, pk_token, 0, pk_token.Length);
553
554			reference.PublicKeyToken = pk_token;
555
556			module.AssemblyReferences.Add (reference);
557
558			return reference;
559		}
560
561		static void ImportGenericParameters (IGenericParameterProvider imported, IGenericParameterProvider original)
562		{
563			var parameters = original.GenericParameters;
564			var imported_parameters = imported.GenericParameters;
565
566			for (int i = 0; i < parameters.Count; i++)
567				imported_parameters.Add (new GenericParameter (parameters [i].Name, imported));
568		}
569
570		TypeReference ImportTypeSpecification (TypeReference type, ImportGenericContext context)
571		{
572			switch (type.etype) {
573			case ElementType.SzArray:
574				var vector = (ArrayType) type;
575				return new ArrayType (ImportType (vector.ElementType, context));
576			case ElementType.Ptr:
577				var pointer = (PointerType) type;
578				return new PointerType (ImportType (pointer.ElementType, context));
579			case ElementType.ByRef:
580				var byref = (ByReferenceType) type;
581				return new ByReferenceType (ImportType (byref.ElementType, context));
582			case ElementType.Pinned:
583				var pinned = (PinnedType) type;
584				return new PinnedType (ImportType (pinned.ElementType, context));
585			case ElementType.Sentinel:
586				var sentinel = (SentinelType) type;
587				return new SentinelType (ImportType (sentinel.ElementType, context));
588			case ElementType.FnPtr:
589				var fnptr = (FunctionPointerType) type;
590				var imported_fnptr = new FunctionPointerType () {
591					HasThis = fnptr.HasThis,
592					ExplicitThis = fnptr.ExplicitThis,
593					CallingConvention = fnptr.CallingConvention,
594					ReturnType = ImportType (fnptr.ReturnType, context),
595				};
596
597				if (!fnptr.HasParameters)
598					return imported_fnptr;
599
600				for (int i = 0; i < fnptr.Parameters.Count; i++)
601					imported_fnptr.Parameters.Add (new ParameterDefinition (
602						ImportType (fnptr.Parameters [i].ParameterType, context)));
603
604				return imported_fnptr;
605			case ElementType.CModOpt:
606				var modopt = (OptionalModifierType) type;
607				return new OptionalModifierType (
608					ImportType (modopt.ModifierType, context),
609					ImportType (modopt.ElementType, context));
610			case ElementType.CModReqD:
611				var modreq = (RequiredModifierType) type;
612				return new RequiredModifierType (
613					ImportType (modreq.ModifierType, context),
614					ImportType (modreq.ElementType, context));
615			case ElementType.Array:
616				var array = (ArrayType) type;
617				var imported_array = new ArrayType (ImportType (array.ElementType, context));
618				if (array.IsVector)
619					return imported_array;
620
621				var dimensions = array.Dimensions;
622				var imported_dimensions = imported_array.Dimensions;
623
624				imported_dimensions.Clear ();
625
626				for (int i = 0; i < dimensions.Count; i++) {
627					var dimension = dimensions [i];
628
629					imported_dimensions.Add (new ArrayDimension (dimension.LowerBound, dimension.UpperBound));
630				}
631
632				return imported_array;
633			case ElementType.GenericInst:
634				var instance = (GenericInstanceType) type;
635				var element_type = ImportType (instance.ElementType, context);
636				var arguments = instance.GenericArguments;
637				var imported_instance = new GenericInstanceType (element_type, arguments.Count);
638				var imported_arguments = imported_instance.GenericArguments;
639
640				for (int i = 0; i < arguments.Count; i++)
641					imported_arguments.Add (ImportType (arguments [i], context));
642
643				return imported_instance;
644			case ElementType.Var:
645				var var_parameter = (GenericParameter) type;
646				if (var_parameter.DeclaringType == null)
647					throw new InvalidOperationException ();
648				return context.TypeParameter (var_parameter.DeclaringType.FullName, var_parameter.Position);
649			case ElementType.MVar:
650				var mvar_parameter = (GenericParameter) type;
651				if (mvar_parameter.DeclaringMethod == null)
652					throw new InvalidOperationException ();
653				return context.MethodParameter (context.NormalizeMethodName (mvar_parameter.DeclaringMethod), mvar_parameter.Position);
654			}
655
656			throw new NotSupportedException (type.etype.ToString ());
657		}
658
659		FieldReference ImportField (FieldReference field, ImportGenericContext context)
660		{
661			var declaring_type = ImportType (field.DeclaringType, context);
662
663			context.Push (declaring_type);
664			try {
665				return new FieldReference {
666					Name = field.Name,
667					DeclaringType = declaring_type,
668					FieldType = ImportType (field.FieldType, context),
669				};
670			} finally {
671				context.Pop ();
672			}
673		}
674
675		MethodReference ImportMethod (MethodReference method, ImportGenericContext context)
676		{
677			if (method.IsGenericInstance)
678				return ImportMethodSpecification (method, context);
679
680			var declaring_type = ImportType (method.DeclaringType, context);
681
682			var reference = new MethodReference {
683				Name = method.Name,
684				HasThis = method.HasThis,
685				ExplicitThis = method.ExplicitThis,
686				DeclaringType = declaring_type,
687				CallingConvention = method.CallingConvention,
688			};
689
690			if (method.HasGenericParameters)
691				ImportGenericParameters (reference, method);
692
693			context.Push (reference);
694			try {
695				reference.ReturnType = ImportType (method.ReturnType, context);
696
697				if (!method.HasParameters)
698					return reference;
699
700				var parameters = method.Parameters;
701				var reference_parameters = reference.parameters = new ParameterDefinitionCollection (reference, parameters.Count);
702				for (int i = 0; i < parameters.Count; i++)
703					reference_parameters.Add (
704						new ParameterDefinition (ImportType (parameters [i].ParameterType, context)));
705
706				return reference;
707			} finally {
708				context.Pop();
709			}
710		}
711
712		MethodSpecification ImportMethodSpecification (MethodReference method, ImportGenericContext context)
713		{
714			if (!method.IsGenericInstance)
715				throw new NotSupportedException ();
716
717			var instance = (GenericInstanceMethod) method;
718			var element_method = ImportMethod (instance.ElementMethod, context);
719			var imported_instance = new GenericInstanceMethod (element_method);
720
721			var arguments = instance.GenericArguments;
722			var imported_arguments = imported_instance.GenericArguments;
723
724			for (int i = 0; i < arguments.Count; i++)
725				imported_arguments.Add (ImportType (arguments [i], context));
726
727			return imported_instance;
728		}
729
730		public virtual TypeReference ImportReference (TypeReference type, IGenericParameterProvider context)
731		{
732			Mixin.CheckType (type);
733			return ImportType (type, ImportGenericContext.For (context));
734		}
735
736		public virtual FieldReference ImportReference (FieldReference field, IGenericParameterProvider context)
737		{
738			Mixin.CheckField (field);
739			return ImportField (field, ImportGenericContext.For (context));
740		}
741
742		public virtual MethodReference ImportReference (MethodReference method, IGenericParameterProvider context)
743		{
744			Mixin.CheckMethod (method);
745			return ImportMethod (method, ImportGenericContext.For (context));
746		}
747	}
748
749	static partial class Mixin {
750
751		public static void CheckModule (ModuleDefinition module)
752		{
753			if (module == null)
754				throw new ArgumentNullException (Argument.module.ToString ());
755		}
756
757		public static bool TryGetAssemblyNameReference (this ModuleDefinition module, AssemblyNameReference name_reference, out AssemblyNameReference assembly_reference)
758		{
759			var references = module.AssemblyReferences;
760
761			for (int i = 0; i < references.Count; i++) {
762				var reference = references [i];
763				if (!Equals (name_reference, reference))
764					continue;
765
766				assembly_reference = reference;
767				return true;
768			}
769
770			assembly_reference = null;
771			return false;
772		}
773
774		static bool Equals (byte [] a, byte [] b)
775		{
776			if (ReferenceEquals (a, b))
777				return true;
778			if (a == null)
779				return false;
780			if (a.Length != b.Length)
781				return false;
782			for (int i = 0; i < a.Length; i++)
783				if (a [i] != b [i])
784					return false;
785			return true;
786		}
787
788		static bool Equals<T> (T a, T b) where T : class, IEquatable<T>
789		{
790			if (ReferenceEquals (a, b))
791				return true;
792			if (a == null)
793				return false;
794			return a.Equals (b);
795		}
796
797		static bool Equals (AssemblyNameReference a, AssemblyNameReference b)
798		{
799			if (ReferenceEquals (a, b))
800				return true;
801			if (a.Name != b.Name)
802				return false;
803			if (!Equals (a.Version, b.Version))
804				return false;
805			if (a.Culture != b.Culture)
806				return false;
807			if (!Equals (a.PublicKeyToken, b.PublicKeyToken))
808				return false;
809			return true;
810		}
811	}
812}