5a06e8ff3c9a8c37cd3dc274378c13021e86d852
[mono.git] / mcs / mcs / import.cs
1 //
2 // import.cs: System.Reflection conversions
3 //
4 // Authors: Marek Safar (marek.safar@gmail.com)
5 //
6 // Dual licensed under the terms of the MIT X11 or GNU GPL
7 //
8 // Copyright 2009, 2010 Novell, Inc
9 //
10
11 using System;
12 using System.Reflection;
13 using System.Runtime.CompilerServices;
14 using System.Linq;
15 using System.Collections.Generic;
16 using System.Diagnostics;
17 using System.Runtime.InteropServices;
18
19 namespace Mono.CSharp
20 {
21         public class ReflectionMetaImporter
22         {
23                 Dictionary<Type, TypeSpec> import_cache;
24                 Dictionary<Type, PredefinedTypeSpec> type_2_predefined;
25
26                 public ReflectionMetaImporter ()
27                 {
28                         import_cache = new Dictionary<Type, TypeSpec> (1024, ReferenceEquality<Type>.Default);
29                         IgnorePrivateMembers = true;
30                 }
31
32                 #region Properties
33
34                 public bool IgnorePrivateMembers { get; set; }
35
36                 #endregion
37
38                 public void Initialize ()
39                 {
40                         // Setup mapping for predefined types
41                         type_2_predefined = new Dictionary<Type, PredefinedTypeSpec> () {
42                                 { typeof (object), TypeManager.object_type },
43                                 { typeof (System.ValueType), TypeManager.value_type },
44                                 { typeof (System.Attribute), TypeManager.attribute_type },
45
46                                 { typeof (int), TypeManager.int32_type },
47                                 { typeof (long), TypeManager.int64_type },
48                                 { typeof (uint), TypeManager.uint32_type },
49                                 { typeof (ulong), TypeManager.uint64_type },
50                                 { typeof (byte), TypeManager.byte_type },
51                                 { typeof (sbyte), TypeManager.sbyte_type },
52                                 { typeof (short), TypeManager.short_type },
53                                 { typeof (ushort), TypeManager.ushort_type },
54
55                                 { typeof (System.Collections.IEnumerator), TypeManager.ienumerator_type },
56                                 { typeof (System.Collections.IEnumerable), TypeManager.ienumerable_type },
57                                 { typeof (System.IDisposable), TypeManager.idisposable_type },
58
59                                 { typeof (char), TypeManager.char_type },
60                                 { typeof (string), TypeManager.string_type },
61                                 { typeof (float), TypeManager.float_type },
62                                 { typeof (double), TypeManager.double_type },
63                                 { typeof (decimal), TypeManager.decimal_type },
64                                 { typeof (bool), TypeManager.bool_type },
65                                 { typeof (System.IntPtr), TypeManager.intptr_type },
66                                 { typeof (System.UIntPtr), TypeManager.uintptr_type },
67
68                                 { typeof (System.MulticastDelegate), TypeManager.multicast_delegate_type },
69                                 { typeof (System.Delegate), TypeManager.delegate_type },
70                                 { typeof (System.Enum), TypeManager.enum_type },
71                                 { typeof (System.Array), TypeManager.array_type },
72                                 { typeof (void), TypeManager.void_type },
73                                 { typeof (System.Type), TypeManager.type_type },
74                                 { typeof (System.Exception), TypeManager.exception_type },
75                                 { typeof (System.RuntimeFieldHandle), TypeManager.runtime_field_handle_type },
76                                 { typeof (System.RuntimeTypeHandle), TypeManager.runtime_handle_type }
77                         };
78                 }
79
80                 public FieldSpec CreateField (FieldInfo fi, TypeSpec declaringType)
81                 {
82                         Modifiers mod = 0;
83                         var fa = fi.Attributes;
84                         switch (fa & FieldAttributes.FieldAccessMask) {
85                                 case FieldAttributes.Public:
86                                         mod = Modifiers.PUBLIC;
87                                         break;
88                                 case FieldAttributes.Assembly:
89                                         mod = Modifiers.INTERNAL;
90                                         break;
91                                 case FieldAttributes.Family:
92                                         mod = Modifiers.PROTECTED;
93                                         break;
94                                 case FieldAttributes.FamORAssem:
95                                         mod = Modifiers.PROTECTED | Modifiers.INTERNAL;
96                                         break;
97                                 default:
98                                         // Ignore private fields (even for error reporting) to not require extra dependencies
99                                         if (IgnorePrivateMembers || fi.IsDefined (typeof (CompilerGeneratedAttribute), false))
100                                                 return null;
101
102                                         mod = Modifiers.PRIVATE;
103                                         break;
104                         }
105
106                         var definition = new ImportedMemberDefinition (fi);
107                         TypeSpec field_type;
108
109                         try {
110                                 field_type = ImportType (fi.FieldType);
111                         } catch (Exception e) {
112                                 // TODO: I should construct fake TypeSpec based on TypeRef signature
113                                 // but there is no way to do it with System.Reflection
114                                 throw new InternalErrorException (e, "Cannot import field `{0}.{1}' referenced in assembly `{2}'",
115                                         declaringType.GetSignatureForError (), fi.Name, declaringType.Assembly);
116                         }
117
118                         if ((fa & FieldAttributes.Literal) != 0) {
119                                 var c = Constant.CreateConstantFromValue (field_type, fi.GetValue (fi), Location.Null);
120                                 return new ConstSpec (declaringType, definition, field_type, fi, mod, c);
121                         }
122
123                         if ((fa & FieldAttributes.InitOnly) != 0) {
124                                 if (field_type == TypeManager.decimal_type) {
125                                         var dc = ReadDecimalConstant (fi);
126                                         if (dc != null)
127                                                 return new ConstSpec (declaringType, definition, field_type, fi, mod, dc);
128                                 }
129
130                                 mod |= Modifiers.READONLY;
131                         } else {
132                                 var reqs = fi.GetRequiredCustomModifiers ();
133                                 if (reqs.Length > 0) {
134                                         foreach (Type t in reqs) {
135                                                 if (t == typeof (System.Runtime.CompilerServices.IsVolatile)) {
136                                                         mod |= Modifiers.VOLATILE;
137                                                         break;
138                                                 }
139                                         }
140                                 }
141                         }
142
143                         if ((fa & FieldAttributes.Static) != 0)
144                                 mod |= Modifiers.STATIC;
145
146                         if (field_type.IsStruct) {
147                                  if (fi.IsDefined (typeof (FixedBufferAttribute), false)) {
148                                         var element_field = CreateField (fi.FieldType.GetField (FixedField.FixedElementName), declaringType);
149                                         return new FixedFieldSpec (declaringType, definition, fi, element_field, mod);
150                                 }
151                         }
152
153                         return new FieldSpec (declaringType, definition, field_type, fi, mod);
154                 }
155
156                 public EventSpec CreateEvent (EventInfo ei, TypeSpec declaringType, MethodSpec add, MethodSpec remove)
157                 {
158                         add.IsAccessor = true;
159                         remove.IsAccessor = true;
160
161                         if (add.Modifiers != remove.Modifiers)
162                                 throw new NotImplementedException ("Different accessor modifiers " + ei.Name);
163
164                         var definition = new ImportedMemberDefinition (ei);
165                         return new EventSpec (declaringType, definition, ImportType (ei.EventHandlerType), add.Modifiers, add, remove);
166                 }
167
168                 T[] CreateGenericParameters<T> (Type type, TypeSpec declaringType) where T : TypeSpec
169                 {
170                         Type[] tparams = type.GetGenericArguments ();
171
172                         int parent_owned_count;
173                         if (type.IsNested) {
174                                 parent_owned_count = type.DeclaringType.GetGenericArguments ().Length;
175
176                                 //
177                                 // System.Reflection duplicates parent type parameters for each
178                                 // nested type with slightly modified properties (eg. different owner)
179                                 // This just makes things more complicated (think of cloned constraints)
180                                 // therefore we remap any nested type owned by parent using `type_cache'
181                                 // to the single TypeParameterSpec
182                                 //
183                                 if (declaringType != null && parent_owned_count > 0) {
184                                         int read_count = 0;
185                                         while (read_count != parent_owned_count) {
186                                                 var tparams_count = declaringType.Arity;
187                                                 if (tparams_count != 0) {
188                                                         var parent_tp = declaringType.MemberDefinition.TypeParameters;
189                                                         read_count += tparams_count;
190                                                         for (int i = 0; i < tparams_count; i++) {
191                                                                 import_cache.Add (tparams[parent_owned_count - read_count + i], parent_tp[i]);
192                                                         }
193                                                 }
194
195                                                 declaringType = declaringType.DeclaringType;
196                                         }
197                                 }                       
198                         } else {
199                                 parent_owned_count = 0;
200                         }
201
202                         if (tparams.Length - parent_owned_count == 0)
203                                 return null;
204
205                         return CreateGenericParameters<T> (parent_owned_count, tparams);
206                 }
207
208                 T[] CreateGenericParameters<T> (int first, Type[] tparams) where T : TypeSpec
209                 {
210                         var tspec = new T [tparams.Length - first];
211                         for (int pos = first; pos < tparams.Length; ++pos) {
212                                 var type = tparams[pos];
213                                 if (type.HasElementType) {
214                                         var element = type.GetElementType ();
215                                         var spec = ImportType (element);
216
217                                         if (type.IsArray) {
218                                                 tspec[pos - first] = (T) (TypeSpec) ArrayContainer.MakeType (spec, type.GetArrayRank ());
219                                                 continue;
220                                         }
221
222                                         throw new NotImplementedException ("Unknown element type " + type.ToString ());
223                                 }
224
225                                 tspec [pos - first] = (T) CreateType (type);
226                         }
227
228                         return tspec;
229                 }
230
231                 public MethodSpec CreateMethod (MethodBase mb, TypeSpec declaringType)
232                 {
233                         Modifiers mod = ReadMethodModifiers (mb, declaringType);
234                         TypeParameterSpec[] tparams;
235                         ImportedMethodDefinition definition;
236
237                         var parameters = CreateParameters (declaringType, mb.GetParameters (), mb);
238
239                         if (mb.IsGenericMethod) {
240                                 if (!mb.IsGenericMethodDefinition)
241                                         throw new NotSupportedException ("assert");
242
243                                 tparams = CreateGenericParameters<TypeParameterSpec>(0, mb.GetGenericArguments ());
244                                 definition = new ImportedGenericMethodDefinition ((MethodInfo) mb, parameters, tparams);
245                         } else {
246                                 definition = new ImportedMethodDefinition (mb, parameters);
247                                 tparams = null;
248                         }
249
250                         MemberKind kind;
251                         TypeSpec returnType;
252                         if (mb.MemberType == MemberTypes.Constructor) {
253                                 kind = MemberKind.Constructor;
254                                 returnType = TypeManager.void_type;
255                         } else {
256                                 //
257                                 // Detect operators and destructors
258                                 //
259                                 string name = mb.Name;
260                                 kind = MemberKind.Method;
261                                 if (tparams == null && !mb.DeclaringType.IsInterface && name.Length > 6) {
262                                         if ((mod & (Modifiers.STATIC | Modifiers.PUBLIC)) == (Modifiers.STATIC | Modifiers.PUBLIC)) {
263                                                 if (name[2] == '_' && name[1] == 'p' && name[0] == 'o') {
264                                                         var op_type = Operator.GetType (name);
265                                                         if (op_type.HasValue && parameters.Count > 0 && parameters.Count < 3) {
266                                                                 kind = MemberKind.Operator;
267                                                         }
268                                                 }
269                                         } else if (parameters.IsEmpty && name == Destructor.MetadataName) {
270                                                 kind = MemberKind.Destructor;
271                                                 if (declaringType == TypeManager.object_type) {
272                                                         mod &= ~Modifiers.OVERRIDE;
273                                                         mod |= Modifiers.VIRTUAL;
274                                                 }
275                                         }
276                                 }
277
278                                 returnType = ImportType (((MethodInfo)mb).ReturnType);
279
280                                 // Cannot set to OVERRIDE without full hierarchy checks
281                                 // this flag indicates that the method could be override
282                                 // but further validation is needed
283                                 if ((mod & Modifiers.OVERRIDE) != 0 && kind == MemberKind.Method && declaringType.BaseType != null) {
284                                         var filter = MemberFilter.Method (name, tparams != null ? tparams.Length : 0, parameters, null);
285                                         var candidate = MemberCache.FindMember (declaringType.BaseType, filter, BindingRestriction.None);
286
287                                         //
288                                         // For imported class method do additional validation to be sure that metadata
289                                         // override flag was correct
290                                         // 
291                                         // Difference between protected internal and protected is ok
292                                         //
293                                         const Modifiers conflict_mask = Modifiers.AccessibilityMask & ~Modifiers.INTERNAL;
294                                         if (candidate == null || (candidate.Modifiers & conflict_mask) != (mod & conflict_mask) || candidate.IsStatic) {
295                                                 mod &= ~Modifiers.OVERRIDE;
296                                         }
297                                 }
298                         }
299
300                         MethodSpec ms = new MethodSpec (kind, declaringType, definition, returnType, mb, parameters, mod);
301                         if (tparams != null)
302                                 ms.IsGeneric = true;
303
304                         return ms;
305                 }
306
307                 //
308                 // Imports System.Reflection parameters
309                 //
310                 AParametersCollection CreateParameters (TypeSpec parent, ParameterInfo[] pi, MethodBase method)
311                 {
312                         int varargs = method != null && (method.CallingConvention & CallingConventions.VarArgs) != 0 ? 1 : 0;
313
314                         if (pi.Length == 0 && varargs == 0)
315                                 return ParametersCompiled.EmptyReadOnlyParameters;
316
317                         TypeSpec[] types = new TypeSpec[pi.Length + varargs];
318                         IParameterData[] par = new IParameterData[pi.Length + varargs];
319                         bool is_params = false;
320                         for (int i = 0; i < pi.Length; i++) {
321                                 ParameterInfo p = pi[i];
322                                 Parameter.Modifier mod = 0;
323                                 Expression default_value = null;
324                                 if (p.ParameterType.IsByRef) {
325                                         if ((p.Attributes & (ParameterAttributes.Out | ParameterAttributes.In)) == ParameterAttributes.Out)
326                                                 mod = Parameter.Modifier.OUT;
327                                         else
328                                                 mod = Parameter.Modifier.REF;
329
330                                         //
331                                         // Strip reference wrapping
332                                         //
333                                         types[i] = ImportType (p.ParameterType.GetElementType ());
334                                 } else if (i == 0 && method.IsStatic && parent.IsStatic && // TODO: parent.Assembly.IsExtension &&
335                                         HasExtensionAttribute (CustomAttributeData.GetCustomAttributes (method)) != null) {
336                                         mod = Parameter.Modifier.This;
337                                         types[i] = ImportType (p.ParameterType);
338                                 } else {
339                                         types[i] = ImportType (p.ParameterType);
340
341                                         if (i >= pi.Length - 2 && types[i] is ArrayContainer) {
342                                                 var cattrs = CustomAttributeData.GetCustomAttributes (p);
343                                                 if (cattrs != null && cattrs.Any (l => l.Constructor.DeclaringType == typeof (ParamArrayAttribute))) {
344                                                         mod = Parameter.Modifier.PARAMS;
345                                                         is_params = true;
346                                                 }
347                                         }
348
349                                         if (!is_params && p.IsOptional) {
350                                                 object value = p.DefaultValue;
351                                                 if (value == Missing.Value) {
352                                                         default_value = EmptyExpression.Null;
353                                                 } else if (value == null) {
354                                                         default_value = new NullLiteral (Location.Null);
355                                                 } else {
356                                                         default_value = Constant.CreateConstant (null, ImportType (value.GetType ()), value, Location.Null);
357                                                 }
358                                         }
359                                 }
360
361                                 par[i] = new ParameterData (p.Name, mod, default_value);
362                         }
363
364                         if (varargs != 0) {
365                                 par[par.Length - 1] = new ArglistParameter (Location.Null);
366                                 types[types.Length - 1] = InternalType.Arglist;
367                         }
368
369                         return method != null ?
370                                 new ParametersImported (par, types, varargs != 0, is_params) :
371                                 new ParametersImported (par, types, is_params);
372                 }
373
374
375                 //
376                 // Returns null when the property is not valid C# property
377                 //
378                 public PropertySpec CreateProperty (PropertyInfo pi, TypeSpec declaringType, MethodSpec get, MethodSpec set)
379                 {
380                         Modifiers mod = 0;
381                         AParametersCollection param = null;
382                         TypeSpec type = null;
383                         if (get != null) {
384                                 mod = get.Modifiers;
385                                 param = get.Parameters;
386                                 type = get.ReturnType;
387                         }
388
389                         bool is_valid_property = true;
390                         if (set != null) {
391                                 if (set.ReturnType != TypeManager.void_type)
392                                         is_valid_property = false;
393
394                                 var set_param_count = set.Parameters.Count - 1;
395
396                                 if (set_param_count < 0) {
397                                         set_param_count = 0;
398                                         is_valid_property = false;
399                                 }
400
401                                 var set_type = set.Parameters.Types[set_param_count];
402
403                                 if (mod == 0) {
404                                         AParametersCollection set_based_param;
405
406                                         if (set_param_count == 0) {
407                                                 set_based_param = ParametersCompiled.EmptyReadOnlyParameters;
408                                         } else {
409                                                 //
410                                                 // Create indexer parameters based on setter method parameters (the last parameter has to be removed)
411                                                 //
412                                                 var data = new IParameterData[set_param_count];
413                                                 var types = new TypeSpec[set_param_count];
414                                                 Array.Copy (set.Parameters.FixedParameters, data, set_param_count);
415                                                 Array.Copy (set.Parameters.Types, types, set_param_count);
416                                                 set_based_param = new ParametersImported (data, types, set.Parameters.HasParams);
417                                         }
418
419                                         mod = set.Modifiers;
420                                         param = set_based_param;
421                                         type = set_type;
422                                 } else {
423                                         if (set_param_count != get.Parameters.Count)
424                                                 is_valid_property = false;
425
426                                         if (get.ReturnType != set_type)
427                                                 is_valid_property = false;
428
429                                         // Possible custom accessor modifiers
430                                         if ((mod & Modifiers.AccessibilityMask) != (set.Modifiers & Modifiers.AccessibilityMask)) {
431                                                 var get_acc = mod & Modifiers.AccessibilityMask;
432                                                 if (get_acc != Modifiers.PUBLIC) {
433                                                         var set_acc = set.Modifiers & Modifiers.AccessibilityMask;
434                                                         // If the accessor modifiers are not same, do extra restriction checks
435                                                         if (get_acc != set_acc) {
436                                                                 var get_restr = ModifiersExtensions.IsRestrictedModifier (get_acc, set_acc);
437                                                                 var set_restr = ModifiersExtensions.IsRestrictedModifier (set_acc, get_acc);
438                                                                 if (get_restr && set_restr) {
439                                                                         is_valid_property = false; // Neither is more restrictive
440                                                                 }
441
442                                                                 if (get_restr) {
443                                                                         mod &= ~Modifiers.AccessibilityMask;
444                                                                         mod |= set_acc;
445                                                                 }
446                                                         }
447                                                 }
448                                         }
449                                 }
450                         }
451
452                         PropertySpec spec = null;
453                         if (!param.IsEmpty) {
454                                 var index_name = declaringType.MemberDefinition.GetAttributeDefaultMember ();
455                                 if (index_name == null) {
456                                         is_valid_property = false;
457                                 } else {
458                                         if (get != null) {
459                                                 if (get.IsStatic)
460                                                         is_valid_property = false;
461                                                 if (get.Name.IndexOf (index_name, StringComparison.Ordinal) != 4)
462                                                         is_valid_property = false;
463                                         }
464                                         if (set != null) {
465                                                 if (set.IsStatic)
466                                                         is_valid_property = false;
467                                                 if (set.Name.IndexOf (index_name, StringComparison.Ordinal) != 4)
468                                                         is_valid_property = false;
469                                         }
470                                 }
471
472                                 if (is_valid_property)
473                                         spec = new IndexerSpec (declaringType, new ImportedIndexerDefinition (pi, param), type, param, pi, mod);
474                         }
475
476                         if (spec == null)
477                                 spec = new PropertySpec (MemberKind.Property, declaringType, new ImportedMemberDefinition (pi), type, pi, mod);
478
479                         if (!is_valid_property) {
480                                 spec.IsNotRealProperty = true;
481                                 return spec;
482                         }
483
484                         if (set != null)
485                                 spec.Set = set;
486                         if (get != null)
487                                 spec.Get = get;
488
489                         return spec;
490                 }
491
492                 public TypeSpec CreateType (Type type)
493                 {
494                         TypeSpec declaring_type;
495                         if (type.IsNested && !type.IsGenericParameter)
496                                 declaring_type = CreateType (type.DeclaringType);
497                         else
498                                 declaring_type = null;
499
500                         return CreateType (type, declaring_type);
501                 }
502
503                 public TypeSpec CreateType (Type type, TypeSpec declaringType)
504                 {
505                         TypeSpec spec;
506                         if (import_cache.TryGetValue (type, out spec))
507                                 return spec;
508
509                         if (type.IsGenericType && !type.IsGenericTypeDefinition) {      
510                                 var type_def = type.GetGenericTypeDefinition ();
511                                 var targs = CreateGenericParameters<TypeSpec> (0, type.GetGenericArguments ());
512                                 if (declaringType == null) {
513                                         // Simple case, no nesting
514                                         spec = CreateType (type_def, null);
515                                         spec = spec.MakeGenericType (targs);
516                                 } else {
517                                         //
518                                         // Nested type case, converting .NET types like
519                                         // A`1.B`1.C`1<int, long, string> to typespec like
520                                         // A<int>.B<long>.C<string>
521                                         //
522                                         var nested_hierarchy = new List<TypeSpec> ();
523                                         while (declaringType.IsNested) {
524                                                 nested_hierarchy.Add (declaringType);
525                                                 declaringType = declaringType.DeclaringType;
526                                         }
527
528                                         int targs_pos = 0;
529                                         if (declaringType.Arity > 0) {
530                                                 spec = declaringType.MakeGenericType (targs.Skip (targs_pos).Take (declaringType.Arity).ToArray ());
531                                                 targs_pos = spec.Arity;
532                                         } else {
533                                                 spec = declaringType;
534                                         }
535
536                                         for (int i = nested_hierarchy.Count; i != 0; --i) {
537                                                 var t = nested_hierarchy [i - 1];
538                                                 spec = MemberCache.FindNestedType (spec, t.Name, t.Arity);
539                                                 if (t.Arity > 0) {
540                                                         spec = spec.MakeGenericType (targs.Skip (targs_pos).Take (spec.Arity).ToArray ());
541                                                         targs_pos += t.Arity;
542                                                 }
543                                         }
544
545                                         string name = type.Name;
546                                         int index = name.IndexOf ('`');
547                                         if (index > 0)
548                                                 name = name.Substring (0, index);
549
550                                         spec = MemberCache.FindNestedType (spec, name, targs.Length - targs_pos);
551                                         if (spec.Arity > 0) {
552                                                 spec = spec.MakeGenericType (targs.Skip (targs_pos).ToArray ());
553                                         }
554                                 }
555
556                                 // Add to reading cache to speed up reading
557                                 if (!import_cache.ContainsKey (type))
558                                         import_cache.Add (type, spec);
559
560                                 return spec;
561                         }
562
563                         Modifiers mod;
564                         MemberKind kind;
565
566                         var ma = type.Attributes;
567                         switch (ma & TypeAttributes.VisibilityMask) {
568                         case TypeAttributes.Public:
569                         case TypeAttributes.NestedPublic:
570                                 mod = Modifiers.PUBLIC;
571                                 break;
572                         case TypeAttributes.NestedPrivate:
573                                 mod = Modifiers.PRIVATE;
574                                 break;
575                         case TypeAttributes.NestedFamily:
576                                 mod = Modifiers.PROTECTED;
577                                 break;
578                         case TypeAttributes.NestedFamORAssem:
579                                 mod = Modifiers.PROTECTED | Modifiers.INTERNAL;
580                                 break;
581                         default:
582                                 mod = Modifiers.INTERNAL;
583                                 break;
584                         }
585
586                         if ((ma & TypeAttributes.Interface) != 0) {
587                                 kind = MemberKind.Interface;
588                         } else if (type.IsGenericParameter) {
589                                 kind = MemberKind.TypeParameter;
590                         } else if (type.IsClass || type.IsAbstract) {                           // SRE: System.Enum returns false for IsClass
591                                 if ((ma & TypeAttributes.Sealed) != 0 && type.IsSubclassOf (typeof (MulticastDelegate))) {
592                                         kind = MemberKind.Delegate;
593                                         mod |= Modifiers.SEALED;
594                                 } else {
595                                         kind = MemberKind.Class;
596
597 #if NET_4_0
598                                         if (type == typeof (object) && type.IsDefined (typeof (DynamicAttribute), false)) {
599                                                 return InternalType.Dynamic;
600                                         }
601 #endif
602
603                                         if ((ma & TypeAttributes.Sealed) != 0) {
604                                                 mod |= Modifiers.SEALED;
605                                                 if ((ma & TypeAttributes.Abstract) != 0)
606                                                         mod |= Modifiers.STATIC;
607                                         } else if ((ma & TypeAttributes.Abstract) != 0) {
608                                                 mod |= Modifiers.ABSTRACT;
609                                         }
610                                 }
611                         } else if (type.IsEnum) {
612                                 kind = MemberKind.Enum;
613                         } else {
614                                 kind = MemberKind.Struct;
615                                 mod |= Modifiers.SEALED;
616                         }
617
618                         var definition = new ImportedTypeDefinition (this, type);
619                         PredefinedTypeSpec pt;
620
621                         if (kind == MemberKind.Enum) {
622                                 const BindingFlags underlying_member = BindingFlags.DeclaredOnly |
623                                         BindingFlags.Instance |
624                                         BindingFlags.Public | BindingFlags.NonPublic;
625
626                                 var type_members = type.GetFields (underlying_member);
627                                 foreach (var type_member in type_members) {
628                                         spec = new EnumSpec (declaringType, definition, CreateType (type_member.FieldType), type, mod);
629                                         break;
630                                 }
631
632                                 if (spec == null)
633                                         kind = MemberKind.Class;
634
635                         } else if (kind == MemberKind.TypeParameter) {
636                                 // Return as type_cache was updated
637                                 return CreateTypeParameter (type, declaringType);
638                         } else if (type.IsGenericTypeDefinition) {
639                                 definition.TypeParameters = CreateGenericParameters<TypeParameterSpec>(type, declaringType);
640
641                                 // Constraints are not loaded on demand and can reference this type
642                                 if (import_cache.TryGetValue (type, out spec))
643                                         return spec;
644
645                         } else if (type_2_predefined.TryGetValue (type, out pt)) {
646                                 spec = pt;
647                                 pt.SetDefinition (definition, type);
648                         }
649
650                         if (spec == null)
651                                 spec = new TypeSpec (kind, declaringType, definition, type, mod);
652
653                         import_cache.Add (type, spec);
654
655                         //
656                         // Two stage setup as the base type can be inflated declaring type
657                         //
658                         if (declaringType == null)
659                                 ImportTypeBase (spec, type);
660
661                         return spec;
662                 }
663
664                 public void ImportTypeBase (Type type)
665                 {
666                         TypeSpec spec = import_cache[type];
667                         if (spec != null)
668                                 ImportTypeBase (spec, type);
669                 }
670
671                 void ImportTypeBase (TypeSpec spec, Type type)
672                 {
673                         if (spec.Kind == MemberKind.Interface)
674                                 spec.BaseType = TypeManager.object_type;
675                         else if (type.BaseType != null)
676                                 spec.BaseType = CreateType (type.BaseType);
677
678                         var ifaces = type.GetInterfaces ();
679                         if (ifaces.Length > 0) {
680                                 foreach (Type iface in ifaces) {
681                                         spec.AddInterface (CreateType (iface));
682                                 }
683                         }
684                 }
685
686                 TypeParameterSpec CreateTypeParameter (Type type, TypeSpec declaringType)
687                 {
688                         Variance variance;
689                         switch (type.GenericParameterAttributes & GenericParameterAttributes.VarianceMask) {
690                         case GenericParameterAttributes.Covariant:
691                                 variance = Variance.Covariant;
692                                 break;
693                         case GenericParameterAttributes.Contravariant:
694                                 variance = Variance.Contravariant;
695                                 break;
696                         default:
697                                 variance = Variance.None;
698                                 break;
699                         }
700
701                         SpecialConstraint special = SpecialConstraint.None;
702                         var import_special = type.GenericParameterAttributes & GenericParameterAttributes.SpecialConstraintMask;
703
704                         if ((import_special & GenericParameterAttributes.NotNullableValueTypeConstraint) != 0) {
705                                 special |= SpecialConstraint.Struct;
706                         } else if ((import_special & GenericParameterAttributes.DefaultConstructorConstraint) != 0) {
707                                 special = SpecialConstraint.Constructor;
708                         }
709
710                         if ((import_special & GenericParameterAttributes.ReferenceTypeConstraint) != 0) {
711                                 special |= SpecialConstraint.Class;
712                         }
713
714                         TypeParameterSpec spec;
715                         var def = new ImportedTypeParameterDefinition (type);
716                         if (type.DeclaringMethod != null)
717                                 spec = new TypeParameterSpec (type.GenericParameterPosition, def, special, variance, type);
718                         else
719                                 spec = new TypeParameterSpec (declaringType, type.GenericParameterPosition, def, special, variance, type);
720
721                         // Add it now, so any constraint can reference it and get same instance
722                         import_cache.Add (type, spec);
723
724                         var constraints = type.GetGenericParameterConstraints ();
725                         List<TypeSpec> tparams = null;
726                         foreach (var ct in constraints) {
727                                 if (ct.IsGenericParameter) {
728                                         if (tparams == null)
729                                                 tparams = new List<TypeSpec> ();
730
731                                         tparams.Add (CreateType (ct));
732                                         continue;
733                                 }
734
735                                 if (ct.IsClass) {
736                                         if (ct == typeof (ValueType)) {
737                                                 spec.BaseType = TypeManager.value_type;
738                                         } else {
739                                                 spec.BaseType = CreateType (ct);
740                                         }
741
742                                         continue;
743                                 }
744
745                                 spec.AddInterface (CreateType (ct));
746                         }
747
748                         if (spec.BaseType == null)
749                                 spec.BaseType = TypeManager.object_type;
750
751                         if (tparams != null)
752                                 spec.TypeArguments = tparams.ToArray ();
753
754                         return spec;
755                 }
756
757                 static Type HasExtensionAttribute (IList<CustomAttributeData> attributes)
758                 {
759                         foreach (var attr in attributes) {
760                                 var dt = attr.Constructor.DeclaringType;
761                                 if (dt.Name == "ExtensionAttribute" && dt.Namespace == "System.Runtime.CompilerServices") {
762                                         return dt;
763                                 }
764                         }
765
766                         return null;
767                 }
768
769                 public void ImportAssembly (Assembly assembly, Namespace targetNamespace)
770                 {
771                         Type extension_type = HasExtensionAttribute (CustomAttributeData.GetCustomAttributes (assembly));
772
773                         //
774                         // This part tries to simulate loading of top-level
775                         // types only, any missing dependencies are ignores here.
776                         // Full error report is reported later when the type is
777                         // actually used
778                         //
779                         Type[] all_types;
780                         try {
781                                 all_types = assembly.GetTypes ();
782                         } catch (ReflectionTypeLoadException e) {
783                                 all_types = e.Types;
784                         }
785
786                         Namespace ns = targetNamespace;
787                         string prev_namespace = null;
788                         foreach (var t in all_types) {
789                                 if (t == null || t.IsNested)
790                                         continue;
791
792                                 if (t.Name[0] == '<')
793                                         continue;
794
795                                 var it = CreateType (t, null);
796                                 if (it == null)
797                                         continue;
798
799                                 if (prev_namespace != t.Namespace) {
800                                         ns = t.Namespace == null ? targetNamespace : targetNamespace.GetNamespace (t.Namespace, true);
801                                         prev_namespace = t.Namespace;
802                                 }
803
804                                 ns.AddType (it);
805
806                                 if (it.IsStatic && extension_type != null && t.IsDefined (extension_type, false)) {
807                                         it.SetExtensionMethodContainer ();
808                                 }
809                         }
810                 }
811
812                 public TypeSpec ImportType (Type type)
813                 {
814                         if (type.HasElementType) {
815                                 var element = type.GetElementType ();
816                                 var spec = ImportType (element);
817
818                                 if (type.IsArray)
819                                         return ArrayContainer.MakeType (spec, type.GetArrayRank ());
820                                 if (type.IsByRef)
821                                         return ReferenceContainer.MakeType (spec);
822                                 if (type.IsPointer)
823                                         return PointerContainer.MakeType (spec);
824
825                                 throw new NotImplementedException ("Unknown element type " + type.ToString ());
826                         }
827
828                         return CreateType (type);
829                 }
830
831                 //
832                 // Decimal constants cannot be encoded in the constant blob, and thus are marked
833                 // as IsInitOnly ('readonly' in C# parlance).  We get its value from the 
834                 // DecimalConstantAttribute metadata.
835                 //
836                 static Constant ReadDecimalConstant (FieldInfo fi)
837                 {
838                         object[] attrs = fi.GetCustomAttributes (typeof (DecimalConstantAttribute), false);
839                         if (attrs.Length != 1)
840                                 return null;
841
842                         return new DecimalConstant (((DecimalConstantAttribute) attrs [0]).Value, Location.Null);
843                 }
844
845                 static Modifiers ReadMethodModifiers (MethodBase mb, TypeSpec declaringType)
846                 {
847                         Modifiers mod;
848                         var ma = mb.Attributes;
849                         switch (ma & MethodAttributes.MemberAccessMask) {
850                         case MethodAttributes.Public:
851                                 mod = Modifiers.PUBLIC;
852                                 break;
853                         case MethodAttributes.Assembly:
854                                 mod = Modifiers.INTERNAL;
855                                 break;
856                         case MethodAttributes.Family:
857                                 mod = Modifiers.PROTECTED;
858                                 break;
859                         case MethodAttributes.FamORAssem:
860                                 mod = Modifiers.PROTECTED | Modifiers.INTERNAL;
861                                 break;
862                         default:
863                                 mod = Modifiers.PRIVATE;
864                                 break;
865                         }
866
867                         if ((ma & MethodAttributes.Static) != 0) {
868                                 mod |= Modifiers.STATIC;
869                                 return mod;
870                         }
871                         if ((ma & MethodAttributes.Abstract) != 0 && declaringType.IsClass) {
872                                 mod |= Modifiers.ABSTRACT;
873                                 return mod;
874                         }
875
876                         if ((ma & MethodAttributes.Final) != 0)
877                                 mod |= Modifiers.SEALED;
878
879                         // It can be sealed and override
880                         if ((ma & MethodAttributes.Virtual) != 0) {
881                                 if ((ma & MethodAttributes.NewSlot) != 0 || !declaringType.IsClass) {
882                                         // No private virtual or sealed virtual
883                                         if ((mod & (Modifiers.PRIVATE | Modifiers.SEALED)) == 0)
884                                                 mod |= Modifiers.VIRTUAL;
885                                 } else {
886                                         mod |= Modifiers.OVERRIDE;
887                                 }
888                         }
889
890                         return mod;
891                 }
892         }
893
894         class ImportedMemberDefinition : IMemberDefinition
895         {
896                 protected class AttributesBag
897                 {
898                         public static readonly AttributesBag Default = new AttributesBag ();
899
900                         public AttributeUsageAttribute AttributeUsage;
901                         public ObsoleteAttribute Obsolete;
902                         public string[] Conditionals;
903                         public string DefaultIndexerName;
904                         public bool IsNotCLSCompliant;
905
906                         public static AttributesBag Read (MemberInfo mi)
907                         {
908                                 AttributesBag bag = null;
909                                 List<string> conditionals = null;
910
911                                 // It should not throw any loading exception
912                                 IList<CustomAttributeData> attrs = CustomAttributeData.GetCustomAttributes (mi);
913
914                                 foreach (var a in attrs) {
915                                         var type = a.Constructor.DeclaringType;
916                                         if (type == typeof (ObsoleteAttribute)) {
917                                                 if (bag == null)
918                                                         bag = new AttributesBag ();
919
920                                                 var args = a.ConstructorArguments;
921
922                                                 if (args.Count == 1) {
923                                                         bag.Obsolete = new ObsoleteAttribute ((string) args[0].Value);
924                                                 } else if (args.Count == 2) {
925                                                         bag.Obsolete = new ObsoleteAttribute ((string) args[0].Value, (bool) args[1].Value);
926                                                 } else {
927                                                         bag.Obsolete = new ObsoleteAttribute ();
928                                                 }
929
930                                                 continue;
931                                         }
932
933                                         if (type == typeof (ConditionalAttribute)) {
934                                                 if (bag == null)
935                                                         bag = new AttributesBag ();
936
937                                                 if (conditionals == null)
938                                                         conditionals = new List<string> (2);
939
940                                                 conditionals.Add ((string) a.ConstructorArguments[0].Value);
941                                                 continue;
942                                         }
943
944                                         if (type == typeof (CLSCompliantAttribute)) {
945                                                 if (bag == null)
946                                                         bag = new AttributesBag ();
947
948                                                 bag.IsNotCLSCompliant = !(bool) a.ConstructorArguments[0].Value;
949                                                 continue;
950                                         }
951
952                                         // Type only attributes
953                                         if (type == typeof (DefaultMemberAttribute)) {
954                                                 if (bag == null)
955                                                         bag = new AttributesBag ();
956
957                                                 bag.DefaultIndexerName = (string) a.ConstructorArguments[0].Value;
958                                                 continue;
959                                         }
960
961                                         if (type == typeof (AttributeUsageAttribute)) {
962                                                 if (bag == null)
963                                                         bag = new AttributesBag ();
964
965                                                 bag.AttributeUsage = new AttributeUsageAttribute ((AttributeTargets) a.ConstructorArguments[0].Value);
966                                                 foreach (var named in a.NamedArguments) {
967                                                         if (named.MemberInfo.Name == "AllowMultiple")
968                                                                 bag.AttributeUsage.AllowMultiple = (bool) named.TypedValue.Value;
969                                                         else if (named.MemberInfo.Name == "Inherited")
970                                                                 bag.AttributeUsage.Inherited = (bool) named.TypedValue.Value;
971                                                 }
972                                                 continue;
973                                         }
974                                 }
975
976                                 if (bag == null)
977                                         return Default;
978
979                                 if (conditionals != null)
980                                         bag.Conditionals = conditionals.ToArray ();
981
982                                 return bag;
983                         }
984                 }
985
986                 protected readonly MemberInfo provider;
987                 protected AttributesBag cattrs;
988
989                 public ImportedMemberDefinition (MemberInfo provider)
990                 {
991                         this.provider = provider;
992                 }
993
994                 #region Properties
995
996                 public Assembly Assembly {
997                         get { 
998                                 return provider.Module.Assembly;
999                         }
1000                 }
1001
1002                 public bool IsImported {
1003                         get {
1004                                 return true;
1005                         }
1006                 }
1007
1008                 public virtual string Name {
1009                         get {
1010                                 return provider.Name;
1011                         }
1012                 }
1013
1014                 #endregion
1015
1016                 public string[] ConditionalConditions ()
1017                 {
1018                         if (cattrs == null)
1019                                 ReadAttributes ();
1020
1021                         return cattrs.Conditionals;
1022                 }
1023
1024                 public ObsoleteAttribute GetAttributeObsolete ()
1025                 {
1026                         if (cattrs == null)
1027                                 ReadAttributes ();
1028
1029                         return cattrs.Obsolete;
1030                 }
1031
1032                 public bool IsNotCLSCompliant ()
1033                 {
1034                         if (cattrs == null)
1035                                 ReadAttributes ();
1036
1037                         return cattrs.IsNotCLSCompliant;
1038                 }
1039
1040                 protected void ReadAttributes ()
1041                 {
1042                         cattrs = AttributesBag.Read (provider);
1043                 }
1044
1045                 public void SetIsAssigned ()
1046                 {
1047                         // Unused for imported members
1048                 }
1049
1050                 public void SetIsUsed ()
1051                 {
1052                         // Unused for imported members
1053                 }
1054         }
1055
1056         class ImportedMethodDefinition : ImportedMemberDefinition, IParametersMember
1057         {
1058                 readonly AParametersCollection parameters;
1059
1060                 public ImportedMethodDefinition (MethodBase provider, AParametersCollection parameters)
1061                         : base (provider)
1062                 {
1063                         this.parameters = parameters;
1064                 }
1065
1066                 #region Properties
1067
1068                 public AParametersCollection Parameters {
1069                         get {
1070                                 return parameters;
1071                         }
1072                 }
1073
1074                 public TypeSpec MemberType {
1075                         get {
1076                                 throw new NotImplementedException ();
1077                         }
1078                 }
1079
1080                 #endregion
1081         }
1082
1083         class ImportedIndexerDefinition : ImportedMemberDefinition, IParametersMember
1084         {
1085                 readonly AParametersCollection parameters;
1086
1087                 public ImportedIndexerDefinition (PropertyInfo provider, AParametersCollection parameters)
1088                         : base (provider)
1089                 {
1090                         this.parameters = parameters;
1091                 }
1092
1093                 #region Properties
1094
1095                 public AParametersCollection Parameters {
1096                         get {
1097                                 return parameters;
1098                         }
1099                 }
1100
1101                 public TypeSpec MemberType {
1102                         get {
1103                                 throw new NotImplementedException ();
1104                         }
1105                 }
1106
1107                 #endregion
1108         }
1109
1110         class ImportedGenericMethodDefinition : ImportedMethodDefinition, IGenericMethodDefinition
1111         {
1112                 TypeParameterSpec[] tparams;
1113
1114                 public ImportedGenericMethodDefinition (MethodInfo provider, AParametersCollection parameters, TypeParameterSpec[] tparams)
1115                         : base (provider, parameters)
1116                 {
1117                         this.tparams = tparams;
1118                 }
1119
1120                 #region Properties
1121
1122                 public TypeParameterSpec[] TypeParameters {
1123                         get {
1124                                 return tparams;
1125                         }
1126                 }
1127
1128                 public int TypeParametersCount {
1129                         get {
1130                                 return tparams.Length;
1131                         }
1132                 }
1133
1134                 #endregion
1135         }
1136
1137         class ImportedTypeDefinition : ImportedMemberDefinition, ITypeDefinition
1138         {
1139                 TypeParameterSpec[] tparams;
1140                 string name;
1141                 ReflectionMetaImporter meta_import;
1142
1143                 public ImportedTypeDefinition (ReflectionMetaImporter metaImport, Type type)
1144                         : base (type)
1145                 {
1146                         this.meta_import = metaImport;
1147                 }
1148
1149                 #region Properties
1150
1151                 public override string Name {
1152                         get {
1153                                 if (name == null) {
1154                                         name = base.Name;
1155                                         if (tparams != null)
1156                                                 name = name.Substring (0, name.IndexOf ('`'));
1157                                 }
1158
1159                                 return name;
1160                         }
1161                 }
1162
1163                 public string Namespace {
1164                         get {
1165                                 return ((Type) provider).Namespace;
1166                         }
1167                 }
1168
1169                 public int TypeParametersCount {
1170                         get {
1171                                 return tparams == null ? 0 : tparams.Length;
1172                         }
1173                 }
1174
1175                 public TypeParameterSpec[] TypeParameters {
1176                         get {
1177                                 return tparams;
1178                         }
1179                         set {
1180                                 tparams = value;
1181                         }
1182                 }
1183
1184                 #endregion
1185
1186                 public TypeSpec GetAttributeCoClass ()
1187                 {
1188                         // TODO: Use ReadAttributes
1189                         var attr =  provider.GetCustomAttributes (typeof (CoClassAttribute), false);
1190                         if (attr.Length < 1)
1191                                 return null;
1192
1193                         return meta_import.CreateType (((CoClassAttribute) attr[0]).CoClass);
1194                 }
1195
1196                 public string GetAttributeDefaultMember ()
1197                 {
1198                         if (cattrs == null)
1199                                 ReadAttributes ();
1200
1201                         return cattrs.DefaultIndexerName;
1202                 }
1203
1204                 public AttributeUsageAttribute GetAttributeUsage (PredefinedAttribute pa)
1205                 {
1206                         if (cattrs == null)
1207                                 ReadAttributes ();
1208
1209                         return cattrs.AttributeUsage;
1210                 }
1211
1212                 public void LoadMembers (TypeSpec declaringType, ref MemberCache cache)
1213                 {
1214                         //
1215                         // Not interested in members of nested private types unless the importer needs them
1216                         //
1217                         if (declaringType.IsPrivate && meta_import.IgnorePrivateMembers) {
1218                                 cache = MemberCache.Empty;
1219                                 return;
1220                         }
1221
1222                         var loading_type = (Type) provider;
1223                         const BindingFlags all_members = BindingFlags.DeclaredOnly |
1224                                 BindingFlags.Static | BindingFlags.Instance |
1225                                 BindingFlags.Public | BindingFlags.NonPublic;
1226
1227                         const MethodAttributes explicit_impl = MethodAttributes.NewSlot |
1228                                         MethodAttributes.Virtual | MethodAttributes.HideBySig |
1229                                         MethodAttributes.Final;
1230
1231                         Dictionary<MethodBase, MethodSpec> possible_accessors = null;
1232                         List<EventSpec> imported_events = null;
1233                         EventSpec event_spec;
1234                         MemberSpec imported;
1235                         MethodInfo m;
1236                         MemberInfo[] all;
1237                         try {
1238                                 all = loading_type.GetMembers (all_members);
1239                         } catch (Exception e) {
1240                                 throw new InternalErrorException (e, "Could not import type `{0}' from `{1}'",
1241                                         declaringType.GetSignatureForError (), declaringType.Assembly.Location);
1242                         }
1243
1244                         cache = new MemberCache (all.Length);
1245
1246                         //
1247                         // Do the types first as they can be referenced by the members before
1248                         // they are found or inflated
1249                         //
1250                         foreach (var member in all) {
1251                                 if (member.MemberType != MemberTypes.NestedType)
1252                                         continue;
1253
1254                                 Type t = (Type) member;
1255
1256                                 // Ignore compiler generated types, mostly lambda containers
1257                                 if (t.IsNotPublic && t.IsDefined (typeof (CompilerGeneratedAttribute), false))
1258                                         continue;
1259
1260                                 imported = meta_import.CreateType (t, declaringType);
1261                                 cache.AddMember (imported);
1262                         }
1263
1264                         //
1265                         // The logic here requires methods to be returned first which seems to work for both Mono and .NET
1266                         //
1267                         foreach (var member in all) {
1268                                 switch (member.MemberType) {
1269                                 case MemberTypes.Constructor:
1270                                 case MemberTypes.Method:
1271                                         MethodBase mb = (MethodBase) member;
1272
1273                                         // Ignore explicitly implemented members
1274                                         if ((mb.Attributes & explicit_impl) == explicit_impl && (mb.Attributes & MethodAttributes.MemberAccessMask) == MethodAttributes.Private)
1275                                                 continue;
1276
1277                                         // Ignore compiler generated methods
1278                                         if (mb.IsPrivate && mb.IsDefined (typeof (CompilerGeneratedAttribute), false))
1279                                                 continue;
1280
1281                                         imported = meta_import.CreateMethod (mb, declaringType);
1282                                         if (imported.Kind == MemberKind.Method && !imported.IsGeneric) {
1283                                                 if (possible_accessors == null)
1284                                                         possible_accessors = new Dictionary<MethodBase, MethodSpec> (ReferenceEquality<MethodBase>.Default);
1285
1286                                                 // There are no metadata rules for accessors, we have to consider any method as possible candidate
1287                                                 possible_accessors.Add (mb, (MethodSpec) imported);
1288                                         }
1289
1290                                         break;
1291                                 case MemberTypes.Property:
1292                                         if (possible_accessors == null)
1293                                                 continue;
1294
1295                                         var p = (PropertyInfo) member;
1296                                         //
1297                                         // Links possible accessors with property
1298                                         //
1299                                         MethodSpec get, set;
1300                                         m = p.GetGetMethod (true);
1301                                         if (m == null || !possible_accessors.TryGetValue (m, out get))
1302                                                 get = null;
1303
1304                                         m = p.GetSetMethod (true);
1305                                         if (m == null || !possible_accessors.TryGetValue (m, out set))
1306                                                 set = null;
1307
1308                                         // No accessors registered (e.g. explicit implementation)
1309                                         if (get == null && set == null)
1310                                                 continue;
1311
1312                                         imported = meta_import.CreateProperty (p, declaringType, get, set);
1313                                         if (imported == null)
1314                                                 continue;
1315
1316                                         break;
1317                                 case MemberTypes.Event:
1318                                         if (possible_accessors == null)
1319                                                 continue;
1320
1321                                         var e = (EventInfo) member;
1322                                         //
1323                                         // Links accessors with event
1324                                         //
1325                                         MethodSpec add, remove;
1326                                         m = e.GetAddMethod (true);
1327                                         if (m == null || !possible_accessors.TryGetValue (m, out add))
1328                                                 add = null;
1329
1330                                         m = e.GetRemoveMethod (true);
1331                                         if (m == null || !possible_accessors.TryGetValue (m, out remove))
1332                                                 remove = null;
1333
1334                                         // Both accessors are required
1335                                         if (add == null || remove == null)
1336                                                 continue;
1337
1338                                         event_spec = meta_import.CreateEvent (e, declaringType, add, remove);
1339                                         if (!meta_import.IgnorePrivateMembers) {
1340                                                 if (imported_events == null)
1341                                                         imported_events = new List<EventSpec> ();
1342
1343                                                 imported_events.Add (event_spec);
1344                                         }
1345
1346                                         imported = event_spec;
1347                                         break;
1348                                 case MemberTypes.Field:
1349                                         var fi = (FieldInfo) member;
1350
1351                                         imported = meta_import.CreateField (fi, declaringType);
1352                                         if (imported == null)
1353                                                 continue;
1354
1355                                         //
1356                                         // For dynamic binder event has to be fully restored to allow operations
1357                                         // within the type container to work correctly
1358                                         //
1359                                         if (imported_events != null) {
1360                                                 // The backing event field should be private but it may not
1361                                                 int index = imported_events.FindIndex (l => l.Name == fi.Name);
1362                                                 if (index >= 0) {
1363                                                         event_spec = imported_events[index];
1364                                                         event_spec.BackingField = (FieldSpec) imported;
1365                                                         imported_events.RemoveAt (index);
1366                                                         continue;
1367                                                 }
1368                                         }
1369
1370                                         break;
1371                                 case MemberTypes.NestedType:
1372                                         meta_import.ImportTypeBase ((Type) member);
1373                                         continue;
1374                                 default:
1375                                         throw new NotImplementedException (member.ToString ());
1376                                 }
1377
1378                                 cache.AddMember (imported);
1379                         }
1380
1381                         if (declaringType.IsInterface && declaringType.Interfaces != null) {
1382                                 foreach (var iface in declaringType.Interfaces) {
1383                                         cache.AddInterface (iface);
1384                                 }
1385                         }
1386                 }
1387         }
1388
1389         class ImportedTypeParameterDefinition : ImportedMemberDefinition, ITypeDefinition
1390         {
1391                 public ImportedTypeParameterDefinition (Type type)
1392                         : base (type)
1393                 {
1394                 }
1395
1396                 #region Properties
1397
1398                 public string Namespace {
1399                         get {
1400                                 return null;
1401                         }
1402                 }
1403
1404                 public int TypeParametersCount {
1405                         get {
1406                                 return 0;
1407                         }
1408                 }
1409
1410                 public TypeParameterSpec[] TypeParameters {
1411                         get {
1412                                 return null;
1413                         }
1414                 }
1415
1416                 #endregion
1417
1418                 public TypeSpec GetAttributeCoClass ()
1419                 {
1420                         return null;
1421                 }
1422
1423                 public string GetAttributeDefaultMember ()
1424                 {
1425                         throw new NotSupportedException ();
1426                 }
1427
1428                 public AttributeUsageAttribute GetAttributeUsage (PredefinedAttribute pa)
1429                 {
1430                         throw new NotSupportedException ();
1431                 }
1432
1433                 public void LoadMembers (TypeSpec declaringType, ref MemberCache cache)
1434                 {
1435                         throw new NotImplementedException ();
1436                 }
1437         }
1438 }