Merge pull request #439 from mono-soc-2012/garyb/iconfix
[mono.git] / mcs / class / IKVM.Reflection / Module.cs
1 /*
2   Copyright (C) 2009-2012 Jeroen Frijters
3
4   This software is provided 'as-is', without any express or implied
5   warranty.  In no event will the authors be held liable for any damages
6   arising from the use of this software.
7
8   Permission is granted to anyone to use this software for any purpose,
9   including commercial applications, and to alter it and redistribute it
10   freely, subject to the following restrictions:
11
12   1. The origin of this software must not be misrepresented; you must not
13      claim that you wrote the original software. If you use this software
14      in a product, an acknowledgment in the product documentation would be
15      appreciated but is not required.
16   2. Altered source versions must be plainly marked as such, and must not be
17      misrepresented as being the original software.
18   3. This notice may not be removed or altered from any source distribution.
19
20   Jeroen Frijters
21   jeroen@frijters.net
22   
23 */
24 using System;
25 using System.Collections.Generic;
26 using IKVM.Reflection.Metadata;
27 using IKVM.Reflection.Reader;
28
29 namespace IKVM.Reflection
30 {
31         public sealed class RawModule : IDisposable
32         {
33                 private readonly ModuleReader module;
34                 private readonly bool isManifestModule;
35                 private bool imported;
36
37                 internal RawModule(ModuleReader module)
38                 {
39                         this.module = module;
40                         this.isManifestModule = module.Assembly != null;
41                 }
42
43                 public string Location
44                 {
45                         get { return module.FullyQualifiedName; }
46                 }
47
48                 public bool IsManifestModule
49                 {
50                         get { return isManifestModule; }
51                 }
52
53                 public Guid ModuleVersionId
54                 {
55                         get { return module.ModuleVersionId; }
56                 }
57
58                 private void CheckManifestModule()
59                 {
60                         if (!IsManifestModule)
61                         {
62                                 throw new BadImageFormatException("Module does not contain a manifest");
63                         }
64                 }
65
66                 public AssemblyName GetAssemblyName()
67                 {
68                         CheckManifestModule();
69                         return module.Assembly.GetName();
70                 }
71
72                 public AssemblyName[] GetReferencedAssemblies()
73                 {
74                         return module.__GetReferencedAssemblies();
75                 }
76
77                 public void Dispose()
78                 {
79                         if (!imported)
80                         {
81                                 module.stream.Dispose();
82                         }
83                 }
84
85                 internal AssemblyReader ToAssembly()
86                 {
87                         if (imported)
88                         {
89                                 throw new InvalidOperationException();
90                         }
91                         imported = true;
92                         return (AssemblyReader)module.Assembly;
93                 }
94
95                 internal Module ToModule(Assembly assembly)
96                 {
97                         if (module.Assembly != null)
98                         {
99                                 throw new InvalidOperationException();
100                         }
101                         imported = true;
102                         module.SetAssembly(assembly);
103                         return module;
104                 }
105         }
106
107         public abstract class Module : ICustomAttributeProvider
108         {
109                 internal readonly Universe universe;
110                 internal readonly ModuleTable ModuleTable = new ModuleTable();
111                 internal readonly TypeRefTable TypeRef = new TypeRefTable();
112                 internal readonly TypeDefTable TypeDef = new TypeDefTable();
113                 internal readonly FieldPtrTable FieldPtr = new FieldPtrTable();
114                 internal readonly FieldTable Field = new FieldTable();
115                 internal readonly MemberRefTable MemberRef = new MemberRefTable();
116                 internal readonly ConstantTable Constant = new ConstantTable();
117                 internal readonly CustomAttributeTable CustomAttribute = new CustomAttributeTable();
118                 internal readonly FieldMarshalTable FieldMarshal = new FieldMarshalTable();
119                 internal readonly DeclSecurityTable DeclSecurity = new DeclSecurityTable();
120                 internal readonly ClassLayoutTable ClassLayout = new ClassLayoutTable();
121                 internal readonly FieldLayoutTable FieldLayout = new FieldLayoutTable();
122                 internal readonly ParamPtrTable ParamPtr = new ParamPtrTable();
123                 internal readonly ParamTable Param = new ParamTable();
124                 internal readonly InterfaceImplTable InterfaceImpl = new InterfaceImplTable();
125                 internal readonly StandAloneSigTable StandAloneSig = new StandAloneSigTable();
126                 internal readonly EventMapTable EventMap = new EventMapTable();
127                 internal readonly EventPtrTable EventPtr = new EventPtrTable();
128                 internal readonly EventTable Event = new EventTable();
129                 internal readonly PropertyMapTable PropertyMap = new PropertyMapTable();
130                 internal readonly PropertyPtrTable PropertyPtr = new PropertyPtrTable();
131                 internal readonly PropertyTable Property = new PropertyTable();
132                 internal readonly MethodSemanticsTable MethodSemantics = new MethodSemanticsTable();
133                 internal readonly MethodImplTable MethodImpl = new MethodImplTable();
134                 internal readonly ModuleRefTable ModuleRef = new ModuleRefTable();
135                 internal readonly TypeSpecTable TypeSpec = new TypeSpecTable();
136                 internal readonly ImplMapTable ImplMap = new ImplMapTable();
137                 internal readonly FieldRVATable FieldRVA = new FieldRVATable();
138                 internal readonly AssemblyTable AssemblyTable = new AssemblyTable();
139                 internal readonly AssemblyRefTable AssemblyRef = new AssemblyRefTable();
140                 internal readonly MethodPtrTable MethodPtr = new MethodPtrTable();
141                 internal readonly MethodDefTable MethodDef = new MethodDefTable();
142                 internal readonly NestedClassTable NestedClass = new NestedClassTable();
143                 internal readonly FileTable File = new FileTable();
144                 internal readonly ExportedTypeTable ExportedType = new ExportedTypeTable();
145                 internal readonly ManifestResourceTable ManifestResource = new ManifestResourceTable();
146                 internal readonly GenericParamTable GenericParam = new GenericParamTable();
147                 internal readonly MethodSpecTable MethodSpec = new MethodSpecTable();
148                 internal readonly GenericParamConstraintTable GenericParamConstraint = new GenericParamConstraintTable();
149
150                 protected Module(Universe universe)
151                 {
152                         this.universe = universe;
153                 }
154
155                 internal Table[] GetTables()
156                 {
157                         Table[] tables = new Table[64];
158                         tables[ModuleTable.Index] = ModuleTable;
159                         tables[TypeRefTable.Index] = TypeRef;
160                         tables[TypeDefTable.Index] = TypeDef;
161                         tables[FieldPtrTable.Index] = FieldPtr;
162                         tables[FieldTable.Index] = Field;
163                         tables[MemberRefTable.Index] = MemberRef;
164                         tables[ConstantTable.Index] = Constant;
165                         tables[CustomAttributeTable.Index] = CustomAttribute;
166                         tables[FieldMarshalTable.Index] = FieldMarshal;
167                         tables[DeclSecurityTable.Index] = DeclSecurity;
168                         tables[ClassLayoutTable.Index] = ClassLayout;
169                         tables[FieldLayoutTable.Index] = FieldLayout;
170                         tables[ParamPtrTable.Index] = ParamPtr;
171                         tables[ParamTable.Index] = Param;
172                         tables[InterfaceImplTable.Index] = InterfaceImpl;
173                         tables[StandAloneSigTable.Index] = StandAloneSig;
174                         tables[EventMapTable.Index] = EventMap;
175                         tables[EventPtrTable.Index] = EventPtr;
176                         tables[EventTable.Index] = Event;
177                         tables[PropertyMapTable.Index] = PropertyMap;
178                         tables[PropertyPtrTable.Index] = PropertyPtr;
179                         tables[PropertyTable.Index] = Property;
180                         tables[MethodSemanticsTable.Index] = MethodSemantics;
181                         tables[MethodImplTable.Index] = MethodImpl;
182                         tables[ModuleRefTable.Index] = ModuleRef;
183                         tables[TypeSpecTable.Index] = TypeSpec;
184                         tables[ImplMapTable.Index] = ImplMap;
185                         tables[FieldRVATable.Index] = FieldRVA;
186                         tables[AssemblyTable.Index] = AssemblyTable;
187                         tables[AssemblyRefTable.Index] = AssemblyRef;
188                         tables[MethodPtrTable.Index] = MethodPtr;
189                         tables[MethodDefTable.Index] = MethodDef;
190                         tables[NestedClassTable.Index] = NestedClass;
191                         tables[FileTable.Index] = File;
192                         tables[ExportedTypeTable.Index] = ExportedType;
193                         tables[ManifestResourceTable.Index] = ManifestResource;
194                         tables[GenericParamTable.Index] = GenericParam;
195                         tables[MethodSpecTable.Index] = MethodSpec;
196                         tables[GenericParamConstraintTable.Index] = GenericParamConstraint;
197                         return tables;
198                 }
199
200                 public virtual void __GetDataDirectoryEntry(int index, out int rva, out int length)
201                 {
202                         throw new NotSupportedException();
203                 }
204
205                 public virtual long __RelativeVirtualAddressToFileOffset(int rva)
206                 {
207                         throw new NotSupportedException();
208                 }
209
210                 public virtual bool __GetSectionInfo(int rva, out string name, out int characteristics)
211                 {
212                         throw new NotSupportedException();
213                 }
214
215                 public virtual int __ReadDataFromRVA(int rva, byte[] data, int offset, int length)
216                 {
217                         throw new NotSupportedException();
218                 }
219
220                 public virtual void GetPEKind(out PortableExecutableKinds peKind, out ImageFileMachine machine)
221                 {
222                         throw new NotSupportedException();
223                 }
224
225                 public virtual int __Subsystem
226                 {
227                         get { throw new NotSupportedException(); }
228                 }
229
230                 public FieldInfo GetField(string name)
231                 {
232                         return GetField(name, BindingFlags.Public | BindingFlags.Static | BindingFlags.Instance | BindingFlags.DeclaredOnly);
233                 }
234
235                 public FieldInfo GetField(string name, BindingFlags bindingFlags)
236                 {
237                         return IsResource() ? null : GetModuleType().GetField(name, bindingFlags | BindingFlags.DeclaredOnly);
238                 }
239
240                 public FieldInfo[] GetFields()
241                 {
242                         return GetFields(BindingFlags.Public | BindingFlags.Static | BindingFlags.Instance | BindingFlags.DeclaredOnly);
243                 }
244
245                 public FieldInfo[] GetFields(BindingFlags bindingFlags)
246                 {
247                         return IsResource() ? Empty<FieldInfo>.Array : GetModuleType().GetFields(bindingFlags | BindingFlags.DeclaredOnly);
248                 }
249
250                 public MethodInfo GetMethod(string name)
251                 {
252                         return IsResource() ? null : GetModuleType().GetMethod(name, BindingFlags.Public | BindingFlags.Static | BindingFlags.Instance | BindingFlags.DeclaredOnly);
253                 }
254
255                 public MethodInfo GetMethod(string name, Type[] types)
256                 {
257                         return IsResource() ? null : GetModuleType().GetMethod(name, BindingFlags.Public | BindingFlags.Static | BindingFlags.Instance | BindingFlags.DeclaredOnly, null, types, null);
258                 }
259
260                 public MethodInfo GetMethod(string name, BindingFlags bindingAttr, Binder binder, CallingConventions callConv, Type[] types, ParameterModifier[] modifiers)
261                 {
262                         return IsResource() ? null : GetModuleType().GetMethod(name, bindingAttr | BindingFlags.DeclaredOnly, binder, callConv, types, modifiers);
263                 }
264
265                 public MethodInfo[] GetMethods()
266                 {
267                         return GetMethods(BindingFlags.Public | BindingFlags.Static | BindingFlags.Instance | BindingFlags.DeclaredOnly);
268                 }
269
270                 public MethodInfo[] GetMethods(BindingFlags bindingFlags)
271                 {
272                         return IsResource() ? Empty<MethodInfo>.Array : GetModuleType().GetMethods(bindingFlags | BindingFlags.DeclaredOnly);
273                 }
274
275                 public ConstructorInfo __ModuleInitializer
276                 {
277                         get { return IsResource() ? null : GetModuleType().TypeInitializer; }
278                 }
279
280                 public virtual byte[] ResolveSignature(int metadataToken)
281                 {
282                         throw new NotSupportedException();
283                 }
284
285                 public virtual __StandAloneMethodSig __ResolveStandAloneMethodSig(int metadataToken, Type[] genericTypeArguments, Type[] genericMethodArguments)
286                 {
287                         throw new NotSupportedException();
288                 }
289
290                 public int MetadataToken
291                 {
292                         get { return IsResource() ? 0 : 1; }
293                 }
294
295                 public abstract int MDStreamVersion { get ;}
296                 public abstract Assembly Assembly { get; }
297                 public abstract string FullyQualifiedName { get; }
298                 public abstract string Name { get; }
299                 public abstract Guid ModuleVersionId { get; }
300                 public abstract MethodBase ResolveMethod(int metadataToken, Type[] genericTypeArguments, Type[] genericMethodArguments);
301                 public abstract FieldInfo ResolveField(int metadataToken, Type[] genericTypeArguments, Type[] genericMethodArguments);
302                 public abstract MemberInfo ResolveMember(int metadataToken, Type[] genericTypeArguments, Type[] genericMethodArguments);
303
304                 public abstract string ResolveString(int metadataToken);
305                 public abstract Type[] __ResolveOptionalParameterTypes(int metadataToken, Type[] genericTypeArguments, Type[] genericMethodArguments, out CustomModifiers[] customModifiers);
306                 public abstract string ScopeName { get; }
307
308                 internal abstract void GetTypesImpl(List<Type> list);
309
310                 internal abstract Type FindType(TypeName name);
311                 internal abstract Type FindTypeIgnoreCase(TypeName lowerCaseName);
312
313                 [Obsolete("Please use __ResolveOptionalParameterTypes(int, Type[], Type[], out CustomModifiers[]) instead.")]
314                 public Type[] __ResolveOptionalParameterTypes(int metadataToken)
315                 {
316                         CustomModifiers[] dummy;
317                         return __ResolveOptionalParameterTypes(metadataToken, null, null, out dummy);
318                 }
319
320                 public Type GetType(string className)
321                 {
322                         return GetType(className, false, false);
323                 }
324
325                 public Type GetType(string className, bool ignoreCase)
326                 {
327                         return GetType(className, false, ignoreCase);
328                 }
329
330                 public Type GetType(string className, bool throwOnError, bool ignoreCase)
331                 {
332                         TypeNameParser parser = TypeNameParser.Parse(className, throwOnError);
333                         if (parser.Error)
334                         {
335                                 return null;
336                         }
337                         if (parser.AssemblyName != null)
338                         {
339                                 if (throwOnError)
340                                 {
341                                         throw new ArgumentException("Type names passed to Module.GetType() must not specify an assembly.");
342                                 }
343                                 else
344                                 {
345                                         return null;
346                                 }
347                         }
348                         TypeName typeName = TypeName.Split(TypeNameParser.Unescape(parser.FirstNamePart));
349                         Type type = ignoreCase
350                                 ? FindTypeIgnoreCase(typeName.ToLowerInvariant())
351                                 : FindType(typeName);
352                         if (type == null && __IsMissing)
353                         {
354                                 throw new MissingModuleException((MissingModule)this);
355                         }
356                         return parser.Expand(type, this.Assembly, throwOnError, className, false, ignoreCase);
357                 }
358
359                 public Type[] GetTypes()
360                 {
361                         List<Type> list = new List<Type>();
362                         GetTypesImpl(list);
363                         return list.ToArray();
364                 }
365
366                 public Type[] FindTypes(TypeFilter filter, object filterCriteria)
367                 {
368                         List<Type> list = new List<Type>();
369                         foreach (Type type in GetTypes())
370                         {
371                                 if (filter(type, filterCriteria))
372                                 {
373                                         list.Add(type);
374                                 }
375                         }
376                         return list.ToArray();
377                 }
378
379                 public virtual bool IsResource()
380                 {
381                         return false;
382                 }
383
384                 public Type ResolveType(int metadataToken)
385                 {
386                         return ResolveType(metadataToken, null, null);
387                 }
388
389                 internal sealed class GenericContext : IGenericContext
390                 {
391                         private readonly Type[] genericTypeArguments;
392                         private readonly Type[] genericMethodArguments;
393
394                         internal GenericContext(Type[] genericTypeArguments, Type[] genericMethodArguments)
395                         {
396                                 this.genericTypeArguments = genericTypeArguments;
397                                 this.genericMethodArguments = genericMethodArguments;
398                         }
399
400                         public Type GetGenericTypeArgument(int index)
401                         {
402                                 return genericTypeArguments[index];
403                         }
404
405                         public Type GetGenericMethodArgument(int index)
406                         {
407                                 return genericMethodArguments[index];
408                         }
409                 }
410
411                 public Type ResolveType(int metadataToken, Type[] genericTypeArguments, Type[] genericMethodArguments)
412                 {
413                         if ((metadataToken >> 24) == TypeSpecTable.Index)
414                         {
415                                 return ResolveType(metadataToken, new GenericContext(genericTypeArguments, genericMethodArguments));
416                         }
417                         else
418                         {
419                                 return ResolveType(metadataToken, null);
420                         }
421                 }
422
423                 internal abstract Type ResolveType(int metadataToken, IGenericContext context);
424
425                 public MethodBase ResolveMethod(int metadataToken)
426                 {
427                         return ResolveMethod(metadataToken, null, null);
428                 }
429
430                 public FieldInfo ResolveField(int metadataToken)
431                 {
432                         return ResolveField(metadataToken, null, null);
433                 }
434
435                 public MemberInfo ResolveMember(int metadataToken)
436                 {
437                         return ResolveMember(metadataToken, null, null);
438                 }
439
440                 public bool IsDefined(Type attributeType, bool inherit)
441                 {
442                         return CustomAttributeData.__GetCustomAttributes(this, attributeType, inherit).Count != 0;
443                 }
444
445                 public IList<CustomAttributeData> __GetCustomAttributes(Type attributeType, bool inherit)
446                 {
447                         return CustomAttributeData.__GetCustomAttributes(this, attributeType, inherit);
448                 }
449
450                 public virtual IList<CustomAttributeData> __GetPlaceholderAssemblyCustomAttributes(bool multiple, bool security)
451                 {
452                         return Empty<CustomAttributeData>.Array;
453                 }
454
455                 public abstract AssemblyName[] __GetReferencedAssemblies();
456
457                 public virtual void __ResolveReferencedAssemblies(Assembly[] assemblies)
458                 {
459                         throw new NotSupportedException();
460                 }
461
462                 public abstract string[] __GetReferencedModules();
463
464                 public abstract Type[] __GetReferencedTypes();
465
466                 public abstract Type[] __GetExportedTypes();
467
468                 public virtual bool __IsMissing
469                 {
470                         get { return false; }
471                 }
472
473                 public long __ImageBase
474                 {
475                         get { return GetImageBaseImpl(); }
476                 }
477
478                 protected abstract long GetImageBaseImpl();
479
480                 public long __StackReserve
481                 {
482                         get { return GetStackReserveImpl(); }
483                 }
484
485                 protected abstract long GetStackReserveImpl();
486
487                 public int __FileAlignment
488                 {
489                         get { return GetFileAlignmentImpl(); }
490                 }
491
492                 protected abstract int GetFileAlignmentImpl();
493
494                 public DllCharacteristics __DllCharacteristics
495                 {
496                         get { return GetDllCharacteristicsImpl(); }
497                 }
498
499                 protected abstract DllCharacteristics GetDllCharacteristicsImpl();
500
501                 public virtual byte[] __ModuleHash
502                 {
503                         get { throw new NotSupportedException(); }
504                 }
505
506                 public virtual int __EntryPointRVA
507                 {
508                         get { throw new NotSupportedException(); }
509                 }
510
511                 public virtual int __EntryPointToken
512                 {
513                         get { throw new NotSupportedException(); }
514                 }
515
516                 public virtual string __ImageRuntimeVersion
517                 {
518                         get { throw new NotSupportedException(); }
519                 }
520
521                 public IEnumerable<CustomAttributeData> __EnumerateCustomAttributeTable()
522                 {
523                         List<CustomAttributeData> list = new List<CustomAttributeData>(CustomAttribute.RowCount);
524                         for (int i = 0; i < CustomAttribute.RowCount; i++)
525                         {
526                                 list.Add(new CustomAttributeData(this, i));
527                         }
528                         return list;
529                 }
530
531                 [Obsolete]
532                 public List<CustomAttributeData> __GetCustomAttributesFor(int token)
533                 {
534                         return CustomAttributeData.GetCustomAttributesImpl(new List<CustomAttributeData>(), this, token, null);
535                 }
536
537                 internal abstract Type GetModuleType();
538
539                 internal abstract ByteReader GetBlob(int blobIndex);
540
541                 internal IList<CustomAttributeData> GetDeclarativeSecurity(int metadataToken)
542                 {
543                         List<CustomAttributeData> list = new List<CustomAttributeData>();
544                         foreach (int i in DeclSecurity.Filter(metadataToken))
545                         {
546                                 CustomAttributeData.ReadDeclarativeSecurity(this, i, list);
547                         }
548                         return list;
549                 }
550
551                 internal virtual void Dispose()
552                 {
553                 }
554
555                 internal virtual void ExportTypes(int fileToken, IKVM.Reflection.Emit.ModuleBuilder manifestModule)
556                 {
557                 }
558
559                 internal virtual string GetString(int index)
560                 {
561                         throw new NotSupportedException();
562                 }
563         }
564
565         abstract class NonPEModule : Module
566         {
567                 protected NonPEModule(Universe universe)
568                         : base(universe)
569                 {
570                 }
571
572                 protected virtual Exception InvalidOperationException()
573                 {
574                         return new InvalidOperationException();
575                 }
576
577                 protected virtual Exception NotSupportedException()
578                 {
579                         return new NotSupportedException();
580                 }
581
582                 protected virtual Exception ArgumentOutOfRangeException()
583                 {
584                         return new ArgumentOutOfRangeException();
585                 }
586
587                 internal sealed override Type GetModuleType()
588                 {
589                         throw InvalidOperationException();
590                 }
591
592                 internal sealed override ByteReader GetBlob(int blobIndex)
593                 {
594                         throw InvalidOperationException();
595                 }
596
597                 public sealed override AssemblyName[] __GetReferencedAssemblies()
598                 {
599                         throw NotSupportedException();
600                 }
601
602                 public sealed override string[] __GetReferencedModules()
603                 {
604                         throw NotSupportedException();
605                 }
606
607                 public override Type[] __GetReferencedTypes()
608                 {
609                         throw NotSupportedException();
610                 }
611
612                 public override Type[] __GetExportedTypes()
613                 {
614                         throw NotSupportedException();
615                 }
616
617                 protected sealed override long GetImageBaseImpl()
618                 {
619                         throw NotSupportedException();
620                 }
621
622                 protected sealed override long GetStackReserveImpl()
623                 {
624                         throw NotSupportedException();
625                 }
626
627                 protected sealed override int GetFileAlignmentImpl()
628                 {
629                         throw NotSupportedException();
630                 }
631
632                 protected override DllCharacteristics GetDllCharacteristicsImpl()
633                 {
634                         throw NotSupportedException();
635                 }
636
637                 internal sealed override Type ResolveType(int metadataToken, IGenericContext context)
638                 {
639                         throw ArgumentOutOfRangeException();
640                 }
641
642                 public sealed override MethodBase ResolveMethod(int metadataToken, Type[] genericTypeArguments, Type[] genericMethodArguments)
643                 {
644                         throw ArgumentOutOfRangeException();
645                 }
646
647                 public sealed override FieldInfo ResolveField(int metadataToken, Type[] genericTypeArguments, Type[] genericMethodArguments)
648                 {
649                         throw ArgumentOutOfRangeException();
650                 }
651
652                 public sealed override MemberInfo ResolveMember(int metadataToken, Type[] genericTypeArguments, Type[] genericMethodArguments)
653                 {
654                         throw ArgumentOutOfRangeException();
655                 }
656
657                 public sealed override string ResolveString(int metadataToken)
658                 {
659                         throw ArgumentOutOfRangeException();
660                 }
661
662                 public sealed override Type[] __ResolveOptionalParameterTypes(int metadataToken, Type[] genericTypeArguments, Type[] genericMethodArguments, out CustomModifiers[] customModifiers)
663                 {
664                         throw ArgumentOutOfRangeException();
665                 }
666         }
667
668         public delegate bool TypeFilter(Type m, object filterCriteria);
669         public delegate bool MemberFilter(MemberInfo m, object filterCriteria);
670 }