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