2 Copyright (C) 2009-2010 Jeroen Frijters
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.
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:
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.
25 using System.Collections.Generic;
26 using IKVM.Reflection.Metadata;
27 using IKVM.Reflection.Reader;
29 namespace IKVM.Reflection
31 public sealed class RawModule : IDisposable
33 private readonly ModuleReader module;
34 private readonly bool isManifestModule;
35 private bool imported;
37 internal RawModule(ModuleReader module)
40 this.isManifestModule = module.Assembly != null;
43 public string Location
45 get { return module.FullyQualifiedName; }
48 public bool IsManifestModule
50 get { return isManifestModule; }
53 private void CheckManifestModule()
55 if (!IsManifestModule)
57 throw new BadImageFormatException("Module does not contain a manifest");
61 public AssemblyName GetAssemblyName()
63 CheckManifestModule();
64 return module.Assembly.GetName();
67 public AssemblyName[] GetReferencedAssemblies()
69 return module.__GetReferencedAssemblies();
76 module.stream.Dispose();
80 internal Assembly ToAssembly()
84 throw new InvalidOperationException();
87 return module.Assembly;
90 internal Module ToModule(Assembly assembly)
92 if (module.Assembly != null)
94 throw new InvalidOperationException();
97 module.SetAssembly(assembly);
102 public abstract class Module : ICustomAttributeProvider
104 internal readonly Universe universe;
105 internal readonly ModuleTable ModuleTable = new ModuleTable();
106 internal readonly TypeRefTable TypeRef = new TypeRefTable();
107 internal readonly TypeDefTable TypeDef = new TypeDefTable();
108 internal readonly FieldTable Field = new FieldTable();
109 internal readonly MemberRefTable MemberRef = new MemberRefTable();
110 internal readonly ConstantTable Constant = new ConstantTable();
111 internal readonly CustomAttributeTable CustomAttribute = new CustomAttributeTable();
112 internal readonly FieldMarshalTable FieldMarshal = new FieldMarshalTable();
113 internal readonly DeclSecurityTable DeclSecurity = new DeclSecurityTable();
114 internal readonly ClassLayoutTable ClassLayout = new ClassLayoutTable();
115 internal readonly FieldLayoutTable FieldLayout = new FieldLayoutTable();
116 internal readonly ParamTable Param = new ParamTable();
117 internal readonly InterfaceImplTable InterfaceImpl = new InterfaceImplTable();
118 internal readonly StandAloneSigTable StandAloneSig = new StandAloneSigTable();
119 internal readonly EventMapTable EventMap = new EventMapTable();
120 internal readonly EventTable Event = new EventTable();
121 internal readonly PropertyMapTable PropertyMap = new PropertyMapTable();
122 internal readonly PropertyTable Property = new PropertyTable();
123 internal readonly MethodSemanticsTable MethodSemantics = new MethodSemanticsTable();
124 internal readonly MethodImplTable MethodImpl = new MethodImplTable();
125 internal readonly ModuleRefTable ModuleRef = new ModuleRefTable();
126 internal readonly TypeSpecTable TypeSpec = new TypeSpecTable();
127 internal readonly ImplMapTable ImplMap = new ImplMapTable();
128 internal readonly FieldRVATable FieldRVA = new FieldRVATable();
129 internal readonly AssemblyTable AssemblyTable = new AssemblyTable();
130 internal readonly AssemblyRefTable AssemblyRef = new AssemblyRefTable();
131 internal readonly MethodDefTable MethodDef = new MethodDefTable();
132 internal readonly NestedClassTable NestedClass = new NestedClassTable();
133 internal readonly FileTable File = new FileTable();
134 internal readonly ExportedTypeTable ExportedType = new ExportedTypeTable();
135 internal readonly ManifestResourceTable ManifestResource = new ManifestResourceTable();
136 internal readonly GenericParamTable GenericParam = new GenericParamTable();
137 internal readonly MethodSpecTable MethodSpec = new MethodSpecTable();
138 internal readonly GenericParamConstraintTable GenericParamConstraint = new GenericParamConstraintTable();
140 internal Module(Universe universe)
142 this.universe = universe;
145 internal Table[] GetTables()
147 Table[] tables = new Table[64];
148 tables[ModuleTable.Index] = ModuleTable;
149 tables[TypeRefTable.Index] = TypeRef;
150 tables[TypeDefTable.Index] = TypeDef;
151 tables[FieldTable.Index] = Field;
152 tables[MemberRefTable.Index] = MemberRef;
153 tables[ConstantTable.Index] = Constant;
154 tables[CustomAttributeTable.Index] = CustomAttribute;
155 tables[FieldMarshalTable.Index] = FieldMarshal;
156 tables[DeclSecurityTable.Index] = DeclSecurity;
157 tables[ClassLayoutTable.Index] = ClassLayout;
158 tables[FieldLayoutTable.Index] = FieldLayout;
159 tables[ParamTable.Index] = Param;
160 tables[InterfaceImplTable.Index] = InterfaceImpl;
161 tables[StandAloneSigTable.Index] = StandAloneSig;
162 tables[EventMapTable.Index] = EventMap;
163 tables[EventTable.Index] = Event;
164 tables[PropertyMapTable.Index] = PropertyMap;
165 tables[PropertyTable.Index] = Property;
166 tables[MethodSemanticsTable.Index] = MethodSemantics;
167 tables[MethodImplTable.Index] = MethodImpl;
168 tables[ModuleRefTable.Index] = ModuleRef;
169 tables[TypeSpecTable.Index] = TypeSpec;
170 tables[ImplMapTable.Index] = ImplMap;
171 tables[FieldRVATable.Index] = FieldRVA;
172 tables[AssemblyTable.Index] = AssemblyTable;
173 tables[AssemblyRefTable.Index] = AssemblyRef;
174 tables[MethodDefTable.Index] = MethodDef;
175 tables[NestedClassTable.Index] = NestedClass;
176 tables[FileTable.Index] = File;
177 tables[ExportedTypeTable.Index] = ExportedType;
178 tables[ManifestResourceTable.Index] = ManifestResource;
179 tables[GenericParamTable.Index] = GenericParam;
180 tables[MethodSpecTable.Index] = MethodSpec;
181 tables[GenericParamConstraintTable.Index] = GenericParamConstraint;
185 public virtual void __GetDataDirectoryEntry(int index, out int rva, out int length)
187 throw new NotSupportedException();
190 public virtual long __RelativeVirtualAddressToFileOffset(int rva)
192 throw new NotSupportedException();
195 public virtual void GetPEKind(out PortableExecutableKinds peKind, out ImageFileMachine machine)
197 throw new NotSupportedException();
200 public virtual int __Subsystem
202 get { throw new NotSupportedException(); }
205 public FieldInfo GetField(string name)
207 return IsResource() ? null : GetModuleType().GetField(name);
210 public FieldInfo GetField(string name, BindingFlags bindingFlags)
212 return IsResource() ? null : GetModuleType().GetField(name, bindingFlags);
215 public FieldInfo[] GetFields()
217 return IsResource() ? Empty<FieldInfo>.Array : GetModuleType().GetFields();
220 public FieldInfo[] GetFields(BindingFlags bindingFlags)
222 return IsResource() ? Empty<FieldInfo>.Array : GetModuleType().GetFields(bindingFlags);
225 public MethodInfo GetMethod(string name)
227 return IsResource() ? null : GetModuleType().GetMethod(name);
230 public MethodInfo GetMethod(string name, Type[] types)
232 return IsResource() ? null : GetModuleType().GetMethod(name, types);
235 public MethodInfo GetMethod(string name, BindingFlags bindingAttr, Binder binder, CallingConventions callConv, Type[] types, ParameterModifier[] modifiers)
237 return IsResource() ? null : GetModuleType().GetMethod(name, bindingAttr, binder, callConv, types, modifiers);
240 public MethodInfo[] GetMethods()
242 return IsResource() ? Empty<MethodInfo>.Array : GetModuleType().GetMethods();
245 public MethodInfo[] GetMethods(BindingFlags bindingFlags)
247 return IsResource() ? Empty<MethodInfo>.Array : GetModuleType().GetMethods(bindingFlags);
250 public ConstructorInfo __ModuleInitializer
252 get { return IsResource() ? null : GetModuleType().TypeInitializer; }
255 public byte[] ResolveSignature(int metadataToken)
257 ModuleReader rdr = this as ModuleReader;
260 ByteReader br = rdr.ResolveSignature(metadataToken);
261 return br.ReadBytes(br.Length);
263 throw new NotSupportedException();
266 public virtual __StandAloneMethodSig __ResolveStandAloneMethodSig(int metadataToken, Type[] genericTypeArguments, Type[] genericMethodArguments)
268 throw new NotSupportedException();
271 public int MetadataToken
273 get { return IsResource() ? 0 : 1; }
276 public abstract int MDStreamVersion { get ;}
277 public abstract Assembly Assembly { get; }
278 public abstract string FullyQualifiedName { get; }
279 public abstract string Name { get; }
280 public abstract Guid ModuleVersionId { get; }
281 public abstract Type ResolveType(int metadataToken, Type[] genericTypeArguments, Type[] genericMethodArguments);
282 public abstract MethodBase ResolveMethod(int metadataToken, Type[] genericTypeArguments, Type[] genericMethodArguments);
283 public abstract FieldInfo ResolveField(int metadataToken, Type[] genericTypeArguments, Type[] genericMethodArguments);
284 public abstract MemberInfo ResolveMember(int metadataToken, Type[] genericTypeArguments, Type[] genericMethodArguments);
286 public abstract string ResolveString(int metadataToken);
287 public abstract Type[] __ResolveOptionalParameterTypes(int metadataToken);
288 public abstract string ScopeName { get; }
290 internal abstract Type GetTypeImpl(string typeName);
291 internal abstract void GetTypesImpl(List<Type> list);
293 public Type GetType(string className)
295 return GetType(className, false, false);
298 public Type GetType(string className, bool ignoreCase)
300 return GetType(className, false, ignoreCase);
303 public Type GetType(string className, bool throwOnError, bool ignoreCase)
307 throw new NotImplementedException();
309 TypeNameParser parser = TypeNameParser.Parse(className, throwOnError);
314 if (parser.AssemblyName != null)
318 throw new ArgumentException("Type names passed to Module.GetType() must not specify an assembly.");
325 return parser.Expand(GetTypeImpl(parser.FirstNamePart), this.Assembly, throwOnError, className);
328 public Type[] GetTypes()
330 List<Type> list = new List<Type>();
332 return list.ToArray();
335 public Type[] FindTypes(TypeFilter filter, object filterCriteria)
337 List<Type> list = new List<Type>();
338 foreach (Type type in GetTypes())
340 if (filter(type, filterCriteria))
345 return list.ToArray();
348 public virtual bool IsResource()
353 public Type ResolveType(int metadataToken)
355 return ResolveType(metadataToken, null, null);
358 public MethodBase ResolveMethod(int metadataToken)
360 return ResolveMethod(metadataToken, null, null);
363 public FieldInfo ResolveField(int metadataToken)
365 return ResolveField(metadataToken, null, null);
368 public MemberInfo ResolveMember(int metadataToken)
370 return ResolveMember(metadataToken, null, null);
373 public bool IsDefined(Type attributeType, bool inherit)
375 return CustomAttributeData.__GetCustomAttributes(this, attributeType, inherit).Count != 0;
378 public IList<CustomAttributeData> __GetCustomAttributes(Type attributeType, bool inherit)
380 return CustomAttributeData.__GetCustomAttributes(this, attributeType, inherit);
383 public virtual IList<CustomAttributeData> __GetPlaceholderAssemblyCustomAttributes(bool multiple, bool security)
385 return Empty<CustomAttributeData>.Array;
388 public abstract AssemblyName[] __GetReferencedAssemblies();
390 internal Type CanonicalizeType(Type type)
393 if (!universe.canonicalizedTypes.TryGetValue(type, out canon))
396 universe.canonicalizedTypes.Add(canon, canon);
401 internal abstract Type GetModuleType();
403 internal abstract ByteReader GetBlob(int blobIndex);
405 internal IList<CustomAttributeData> GetCustomAttributesData(Type attributeType)
407 return GetCustomAttributes(0x00000001, attributeType);
410 internal List<CustomAttributeData> GetCustomAttributes(int metadataToken, Type attributeType)
412 List<CustomAttributeData> list = new List<CustomAttributeData>();
413 // TODO use binary search?
414 for (int i = 0; i < CustomAttribute.records.Length; i++)
416 if (CustomAttribute.records[i].Parent == metadataToken)
418 if (attributeType == null)
420 list.Add(new CustomAttributeData(this, i));
424 ConstructorInfo constructor = (ConstructorInfo)ResolveMethod(CustomAttribute.records[i].Type);
425 if (attributeType.IsAssignableFrom(constructor.DeclaringType))
427 list.Add(new CustomAttributeData(this.Assembly, constructor, GetBlob(CustomAttribute.records[i].Value)));
435 internal IList<CustomAttributeData> GetDeclarativeSecurity(int metadataToken)
437 List<CustomAttributeData> list = new List<CustomAttributeData>();
438 // TODO use binary search?
439 for (int i = 0; i < DeclSecurity.records.Length; i++)
441 if (DeclSecurity.records[i].Parent == metadataToken)
443 int action = DeclSecurity.records[i].Action;
444 int permissionSet = DeclSecurity.records[i].PermissionSet;
445 CustomAttributeData.ReadDeclarativeSecurity(this.Assembly, list, action, GetBlob(permissionSet));
451 internal virtual void Dispose()
455 internal virtual void ExportTypes(int fileToken, IKVM.Reflection.Emit.ModuleBuilder manifestModule)
460 public delegate bool TypeFilter(Type m, object filterCriteria);
461 public delegate bool MemberFilter(MemberInfo m, object filterCriteria);