Merge pull request #301 from directhex/master
[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 Type ResolveType(int metadataToken, Type[] genericTypeArguments, Type[] genericMethodArguments);
301                 public abstract MethodBase ResolveMethod(int metadataToken, Type[] genericTypeArguments, Type[] genericMethodArguments);
302                 public abstract FieldInfo ResolveField(int metadataToken, Type[] genericTypeArguments, Type[] genericMethodArguments);
303                 public abstract MemberInfo ResolveMember(int metadataToken, Type[] genericTypeArguments, Type[] genericMethodArguments);
304
305                 public abstract string ResolveString(int metadataToken);
306                 public abstract Type[] __ResolveOptionalParameterTypes(int metadataToken, Type[] genericTypeArguments, Type[] genericMethodArguments, out CustomModifiers[] customModifiers);
307                 public abstract string ScopeName { get; }
308
309                 internal abstract void GetTypesImpl(List<Type> list);
310
311                 internal abstract Type FindType(TypeName name);
312                 internal abstract Type FindTypeIgnoreCase(TypeName lowerCaseName);
313
314                 [Obsolete("Please use __ResolveOptionalParameterTypes(int, Type[], Type[], out CustomModifiers[]) instead.")]
315                 public Type[] __ResolveOptionalParameterTypes(int metadataToken)
316                 {
317                         CustomModifiers[] dummy;
318                         return __ResolveOptionalParameterTypes(metadataToken, null, null, out dummy);
319                 }
320
321                 public Type GetType(string className)
322                 {
323                         return GetType(className, false, false);
324                 }
325
326                 public Type GetType(string className, bool ignoreCase)
327                 {
328                         return GetType(className, false, ignoreCase);
329                 }
330
331                 public Type GetType(string className, bool throwOnError, bool ignoreCase)
332                 {
333                         TypeNameParser parser = TypeNameParser.Parse(className, throwOnError);
334                         if (parser.Error)
335                         {
336                                 return null;
337                         }
338                         if (parser.AssemblyName != null)
339                         {
340                                 if (throwOnError)
341                                 {
342                                         throw new ArgumentException("Type names passed to Module.GetType() must not specify an assembly.");
343                                 }
344                                 else
345                                 {
346                                         return null;
347                                 }
348                         }
349                         TypeName typeName = TypeName.Split(TypeNameParser.Unescape(parser.FirstNamePart));
350                         Type type = ignoreCase
351                                 ? FindTypeIgnoreCase(typeName.ToLowerInvariant())
352                                 : FindType(typeName);
353                         if (type == null && __IsMissing)
354                         {
355                                 throw new MissingModuleException((MissingModule)this);
356                         }
357                         return parser.Expand(type, this.Assembly, throwOnError, className, false, ignoreCase);
358                 }
359
360                 public Type[] GetTypes()
361                 {
362                         List<Type> list = new List<Type>();
363                         GetTypesImpl(list);
364                         return list.ToArray();
365                 }
366
367                 public Type[] FindTypes(TypeFilter filter, object filterCriteria)
368                 {
369                         List<Type> list = new List<Type>();
370                         foreach (Type type in GetTypes())
371                         {
372                                 if (filter(type, filterCriteria))
373                                 {
374                                         list.Add(type);
375                                 }
376                         }
377                         return list.ToArray();
378                 }
379
380                 public virtual bool IsResource()
381                 {
382                         return false;
383                 }
384
385                 public Type ResolveType(int metadataToken)
386                 {
387                         return ResolveType(metadataToken, null, null);
388                 }
389
390                 public MethodBase ResolveMethod(int metadataToken)
391                 {
392                         return ResolveMethod(metadataToken, null, null);
393                 }
394
395                 public FieldInfo ResolveField(int metadataToken)
396                 {
397                         return ResolveField(metadataToken, null, null);
398                 }
399
400                 public MemberInfo ResolveMember(int metadataToken)
401                 {
402                         return ResolveMember(metadataToken, null, null);
403                 }
404
405                 public bool IsDefined(Type attributeType, bool inherit)
406                 {
407                         return CustomAttributeData.__GetCustomAttributes(this, attributeType, inherit).Count != 0;
408                 }
409
410                 public IList<CustomAttributeData> __GetCustomAttributes(Type attributeType, bool inherit)
411                 {
412                         return CustomAttributeData.__GetCustomAttributes(this, attributeType, inherit);
413                 }
414
415                 public virtual IList<CustomAttributeData> __GetPlaceholderAssemblyCustomAttributes(bool multiple, bool security)
416                 {
417                         return Empty<CustomAttributeData>.Array;
418                 }
419
420                 public abstract AssemblyName[] __GetReferencedAssemblies();
421
422                 public virtual void __ResolveReferencedAssemblies(Assembly[] assemblies)
423                 {
424                         throw new NotSupportedException();
425                 }
426
427                 public abstract string[] __GetReferencedModules();
428
429                 public abstract Type[] __GetReferencedTypes();
430
431                 public abstract Type[] __GetExportedTypes();
432
433                 public virtual bool __IsMissing
434                 {
435                         get { return false; }
436                 }
437
438                 public long __ImageBase
439                 {
440                         get { return GetImageBaseImpl(); }
441                 }
442
443                 protected abstract long GetImageBaseImpl();
444
445                 public long __StackReserve
446                 {
447                         get { return GetStackReserveImpl(); }
448                 }
449
450                 protected abstract long GetStackReserveImpl();
451
452                 public int __FileAlignment
453                 {
454                         get { return GetFileAlignmentImpl(); }
455                 }
456
457                 protected abstract int GetFileAlignmentImpl();
458
459                 public DllCharacteristics __DllCharacteristics
460                 {
461                         get { return GetDllCharacteristicsImpl(); }
462                 }
463
464                 protected abstract DllCharacteristics GetDllCharacteristicsImpl();
465
466                 public virtual byte[] __ModuleHash
467                 {
468                         get { throw new NotSupportedException(); }
469                 }
470
471                 public virtual int __EntryPointRVA
472                 {
473                         get { throw new NotSupportedException(); }
474                 }
475
476                 public virtual int __EntryPointToken
477                 {
478                         get { throw new NotSupportedException(); }
479                 }
480
481                 public virtual string __ImageRuntimeVersion
482                 {
483                         get { throw new NotSupportedException(); }
484                 }
485
486                 public IEnumerable<CustomAttributeData> __EnumerateCustomAttributeTable()
487                 {
488                         List<CustomAttributeData> list = new List<CustomAttributeData>(CustomAttribute.RowCount);
489                         for (int i = 0; i < CustomAttribute.RowCount; i++)
490                         {
491                                 list.Add(new CustomAttributeData(this, i));
492                         }
493                         return list;
494                 }
495
496                 [Obsolete]
497                 public List<CustomAttributeData> __GetCustomAttributesFor(int token)
498                 {
499                         return GetCustomAttributes(token, null);
500                 }
501
502                 internal abstract Type GetModuleType();
503
504                 internal abstract ByteReader GetBlob(int blobIndex);
505
506                 internal virtual IList<CustomAttributeData> GetCustomAttributesData(Type attributeType)
507                 {
508                         return GetCustomAttributes(0x00000001, attributeType);
509                 }
510
511                 internal List<CustomAttributeData> GetCustomAttributes(int metadataToken, Type attributeType)
512                 {
513                         List<CustomAttributeData> list = new List<CustomAttributeData>();
514                         foreach (int i in CustomAttribute.Filter(metadataToken))
515                         {
516                                 if (attributeType == null)
517                                 {
518                                         list.Add(new CustomAttributeData(this, i));
519                                 }
520                                 else
521                                 {
522                                         ConstructorInfo constructor = (ConstructorInfo)ResolveMethod(CustomAttribute.records[i].Type);
523                                         if (attributeType.IsAssignableFrom(constructor.DeclaringType))
524                                         {
525                                                 list.Add(new CustomAttributeData(this, i));
526                                         }
527                                 }
528                         }
529                         return list;
530                 }
531
532                 internal IList<CustomAttributeData> GetDeclarativeSecurity(int metadataToken)
533                 {
534                         List<CustomAttributeData> list = new List<CustomAttributeData>();
535                         foreach (int i in DeclSecurity.Filter(metadataToken))
536                         {
537                                 CustomAttributeData.ReadDeclarativeSecurity(this, i, list);
538                         }
539                         return list;
540                 }
541
542                 internal virtual void Dispose()
543                 {
544                 }
545
546                 internal virtual void ExportTypes(int fileToken, IKVM.Reflection.Emit.ModuleBuilder manifestModule)
547                 {
548                 }
549         }
550
551         abstract class NonPEModule : Module
552         {
553                 protected NonPEModule(Universe universe)
554                         : base(universe)
555                 {
556                 }
557
558                 protected virtual Exception InvalidOperationException()
559                 {
560                         return new InvalidOperationException();
561                 }
562
563                 protected virtual Exception NotSupportedException()
564                 {
565                         return new NotSupportedException();
566                 }
567
568                 protected virtual Exception ArgumentOutOfRangeException()
569                 {
570                         return new ArgumentOutOfRangeException();
571                 }
572
573                 internal sealed override Type GetModuleType()
574                 {
575                         throw InvalidOperationException();
576                 }
577
578                 internal sealed override ByteReader GetBlob(int blobIndex)
579                 {
580                         throw InvalidOperationException();
581                 }
582
583                 public sealed override AssemblyName[] __GetReferencedAssemblies()
584                 {
585                         throw NotSupportedException();
586                 }
587
588                 public sealed override string[] __GetReferencedModules()
589                 {
590                         throw NotSupportedException();
591                 }
592
593                 public override Type[] __GetReferencedTypes()
594                 {
595                         throw NotSupportedException();
596                 }
597
598                 public override Type[] __GetExportedTypes()
599                 {
600                         throw NotSupportedException();
601                 }
602
603                 protected sealed override long GetImageBaseImpl()
604                 {
605                         throw NotSupportedException();
606                 }
607
608                 protected sealed override long GetStackReserveImpl()
609                 {
610                         throw NotSupportedException();
611                 }
612
613                 protected sealed override int GetFileAlignmentImpl()
614                 {
615                         throw NotSupportedException();
616                 }
617
618                 protected override DllCharacteristics GetDllCharacteristicsImpl()
619                 {
620                         throw NotSupportedException();
621                 }
622
623                 public sealed override Type ResolveType(int metadataToken, Type[] genericTypeArguments, Type[] genericMethodArguments)
624                 {
625                         throw ArgumentOutOfRangeException();
626                 }
627
628                 public sealed override MethodBase ResolveMethod(int metadataToken, Type[] genericTypeArguments, Type[] genericMethodArguments)
629                 {
630                         throw ArgumentOutOfRangeException();
631                 }
632
633                 public sealed override FieldInfo ResolveField(int metadataToken, Type[] genericTypeArguments, Type[] genericMethodArguments)
634                 {
635                         throw ArgumentOutOfRangeException();
636                 }
637
638                 public sealed override MemberInfo ResolveMember(int metadataToken, Type[] genericTypeArguments, Type[] genericMethodArguments)
639                 {
640                         throw ArgumentOutOfRangeException();
641                 }
642
643                 public sealed override string ResolveString(int metadataToken)
644                 {
645                         throw ArgumentOutOfRangeException();
646                 }
647
648                 public sealed override Type[] __ResolveOptionalParameterTypes(int metadataToken, Type[] genericTypeArguments, Type[] genericMethodArguments, out CustomModifiers[] customModifiers)
649                 {
650                         throw ArgumentOutOfRangeException();
651                 }
652         }
653
654         public delegate bool TypeFilter(Type m, object filterCriteria);
655         public delegate bool MemberFilter(MemberInfo m, object filterCriteria);
656 }