Update IKVM sources
[mono.git] / mcs / class / IKVM.Reflection / Emit / AssemblyBuilder.cs
1 /*
2   Copyright (C) 2008-2011 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 System.Configuration.Assemblies;
27 using System.IO;
28 using System.Diagnostics;
29 using System.Globalization;
30 using System.Security.Cryptography;
31 using System.Security;
32 using IKVM.Reflection.Metadata;
33 using IKVM.Reflection.Impl;
34 using IKVM.Reflection.Writer;
35
36 namespace IKVM.Reflection.Emit
37 {
38         public sealed class AssemblyBuilder : Assembly
39         {
40                 private readonly string name;
41                 private ushort majorVersion;
42                 private ushort minorVersion;
43                 private ushort buildVersion;
44                 private ushort revisionVersion;
45                 private string culture;
46                 private AssemblyNameFlags flags;
47                 private AssemblyHashAlgorithm hashAlgorithm;
48                 private StrongNameKeyPair keyPair;
49                 private byte[] publicKey;
50                 internal readonly string dir;
51                 private readonly PermissionSet requiredPermissions;
52                 private readonly PermissionSet optionalPermissions;
53                 private readonly PermissionSet refusedPermissions;
54                 private PEFileKinds fileKind = PEFileKinds.Dll;
55                 private MethodInfo entryPoint;
56                 private VersionInfo versionInfo;
57                 private ResourceSection unmanagedResources;
58                 private string imageRuntimeVersion;
59                 internal int mdStreamVersion = 0x20000;
60                 private Module pseudoManifestModule;
61                 private readonly List<ResourceFile> resourceFiles = new List<ResourceFile>();
62                 private readonly List<ModuleBuilder> modules = new List<ModuleBuilder>();
63                 private readonly List<Module> addedModules = new List<Module>();
64                 private readonly List<CustomAttributeBuilder> customAttributes = new List<CustomAttributeBuilder>();
65                 private readonly List<CustomAttributeBuilder> declarativeSecurity = new List<CustomAttributeBuilder>();
66                 private readonly List<Type> typeForwarders = new List<Type>();
67                 private Dictionary<string, Type> missingTypes;
68
69                 private struct ResourceFile
70                 {
71                         internal string Name;
72                         internal string FileName;
73                         internal ResourceAttributes Attributes;
74                 }
75
76                 internal AssemblyBuilder(Universe universe, AssemblyName name, string dir, PermissionSet requiredPermissions, PermissionSet optionalPermissions, PermissionSet refusedPermissions)
77                         : base(universe)
78                 {
79                         this.name = name.Name;
80                         SetVersionHelper(name.Version);
81                         if (name.CultureInfo != null && !string.IsNullOrEmpty(name.CultureInfo.Name))
82                         {
83                                 this.culture = name.CultureInfo.Name;
84                         }
85                         this.flags = name.Flags;
86                         this.hashAlgorithm = name.HashAlgorithm;
87                         if (this.hashAlgorithm == AssemblyHashAlgorithm.None)
88                         {
89                                 this.hashAlgorithm = AssemblyHashAlgorithm.SHA1;
90                         }
91                         this.keyPair = name.KeyPair;
92                         if (this.keyPair != null)
93                         {
94                                 this.publicKey = this.keyPair.PublicKey;
95                         }
96                         else
97                         {
98                                 byte[] publicKey = name.GetPublicKey();
99                                 if (publicKey != null && publicKey.Length != 0)
100                                 {
101                                         this.publicKey = (byte[])publicKey.Clone();
102                                 }
103                         }
104                         this.dir = dir ?? ".";
105                         this.requiredPermissions = requiredPermissions;
106                         this.optionalPermissions = optionalPermissions;
107                         this.refusedPermissions = refusedPermissions;
108                         if (universe.HasMscorlib && universe.Mscorlib.ImageRuntimeVersion != null)
109                         {
110                                 this.imageRuntimeVersion = universe.Mscorlib.ImageRuntimeVersion;
111                         }
112                         else
113                         {
114                                 this.imageRuntimeVersion = typeof(object).Assembly.ImageRuntimeVersion;
115                         }
116                 }
117
118                 private void SetVersionHelper(Version version)
119                 {
120                         if (version == null)
121                         {
122                                 majorVersion = 0;
123                                 minorVersion = 0;
124                                 buildVersion = 0;
125                                 revisionVersion = 0;
126                         }
127                         else
128                         {
129                                 majorVersion = (ushort)version.Major;
130                                 minorVersion = (ushort)version.Minor;
131                                 buildVersion = version.Build == -1 ? (ushort)0 : (ushort)version.Build;
132                                 revisionVersion = version.Revision == -1 ? (ushort)0 : (ushort)version.Revision;
133                         }
134                 }
135
136                 public void __SetAssemblyVersion(Version version)
137                 {
138                         AssemblyName oldName = GetName();
139                         SetVersionHelper(version);
140                         universe.RenameAssembly(this, oldName);
141                 }
142
143                 public void __SetAssemblyCulture(string cultureName)
144                 {
145                         AssemblyName oldName = GetName();
146                         this.culture = cultureName;
147                         universe.RenameAssembly(this, oldName);
148                 }
149
150                 public void __SetAssemblyKeyPair(StrongNameKeyPair keyPair)
151                 {
152                         AssemblyName oldName = GetName();
153                         this.keyPair = keyPair;
154                         if (keyPair != null)
155                         {
156                                 this.publicKey = keyPair.PublicKey;
157                         }
158                         universe.RenameAssembly(this, oldName);
159                 }
160
161                 // this is used in combination with delay signing
162                 public void __SetAssemblyPublicKey(byte[] publicKey)
163                 {
164                         AssemblyName oldName = GetName();
165                         this.publicKey = publicKey == null ? null : (byte[])publicKey.Clone();
166                         universe.RenameAssembly(this, oldName);
167                 }
168
169                 public void __SetAssemblyAlgorithmId(AssemblyHashAlgorithm hashAlgorithm)
170                 {
171                         this.hashAlgorithm = hashAlgorithm;
172                 }
173
174                 public void __SetAssemblyFlags(AssemblyNameFlags flags)
175                 {
176                         this.flags = flags;
177                 }
178
179                 public override AssemblyName GetName()
180                 {
181                         AssemblyName n = new AssemblyName();
182                         n.Name = name;
183                         n.Version = new Version(majorVersion, minorVersion, buildVersion, revisionVersion);
184                         n.Culture = culture;
185                         n.HashAlgorithm = hashAlgorithm;
186                         n.Flags = flags;
187                         n.SetPublicKey(publicKey != null ? (byte[])publicKey.Clone() : Empty<byte>.Array);
188                         n.KeyPair = keyPair;
189                         return n;
190                 }
191
192                 public override string FullName
193                 {
194                         get { return GetName().FullName; }
195                 }
196
197                 public override string Location
198                 {
199                         get { throw new NotSupportedException(); }
200                 }
201
202                 public ModuleBuilder DefineDynamicModule(string name, string fileName)
203                 {
204                         return DefineDynamicModule(name, fileName, false);
205                 }
206
207                 public ModuleBuilder DefineDynamicModule(string name, string fileName, bool emitSymbolInfo)
208                 {
209                         ModuleBuilder module = new ModuleBuilder(this, name, fileName, emitSymbolInfo);
210                         modules.Add(module);
211                         return module;
212                 }
213
214                 public ModuleBuilder GetDynamicModule(string name)
215                 {
216                         foreach (ModuleBuilder module in modules)
217                         {
218                                 if (module.Name == name)
219                                 {
220                                         return module;
221                                 }
222                         }
223                         return null;
224                 }
225
226                 public void SetCustomAttribute(ConstructorInfo con, byte[] binaryAttribute)
227                 {
228                         SetCustomAttribute(new CustomAttributeBuilder(con, binaryAttribute));
229                 }
230
231                 public void SetCustomAttribute(CustomAttributeBuilder customBuilder)
232                 {
233                         customAttributes.Add(customBuilder);
234                 }
235
236                 public void __AddDeclarativeSecurity(CustomAttributeBuilder customBuilder)
237                 {
238                         declarativeSecurity.Add(customBuilder);
239                 }
240
241                 public void __AddTypeForwarder(Type type)
242                 {
243                         typeForwarders.Add(type);
244                 }
245
246                 public void SetEntryPoint(MethodInfo entryMethod)
247                 {
248                         SetEntryPoint(entryMethod, PEFileKinds.ConsoleApplication);
249                 }
250
251                 public void SetEntryPoint(MethodInfo entryMethod, PEFileKinds fileKind)
252                 {
253                         this.entryPoint = entryMethod;
254                         this.fileKind = fileKind;
255                 }
256
257                 public void __Save(Stream stream, PortableExecutableKinds portableExecutableKind, ImageFileMachine imageFileMachine)
258                 {
259                         if (!stream.CanRead || !stream.CanWrite || !stream.CanSeek || stream.Position != 0)
260                         {
261                                 throw new ArgumentException("Stream must support read/write/seek and current position must be zero.", "stream");
262                         }
263                         if (modules.Count != 1)
264                         {
265                                 throw new NotSupportedException("Saving to a stream is only supported for single module assemblies.");
266                         }
267                         SaveImpl(modules[0].fileName, stream, portableExecutableKind, imageFileMachine);
268                 }
269
270                 public void Save(string assemblyFileName)
271                 {
272                         Save(assemblyFileName, PortableExecutableKinds.ILOnly, ImageFileMachine.I386);
273                 }
274
275                 public void Save(string assemblyFileName, PortableExecutableKinds portableExecutableKind, ImageFileMachine imageFileMachine)
276                 {
277                         SaveImpl(assemblyFileName, null, portableExecutableKind, imageFileMachine);
278                 }
279
280                 private void SaveImpl(string assemblyFileName, Stream streamOrNull, PortableExecutableKinds portableExecutableKind, ImageFileMachine imageFileMachine)
281                 {
282                         ModuleBuilder manifestModule = null;
283
284                         foreach (ModuleBuilder moduleBuilder in modules)
285                         {
286                                 moduleBuilder.PopulatePropertyAndEventTables();
287
288                                 if (manifestModule == null
289                                         && string.Compare(moduleBuilder.fileName, assemblyFileName, StringComparison.OrdinalIgnoreCase) == 0)
290                                 {
291                                         manifestModule = moduleBuilder;
292                                 }
293                         }
294
295                         if (manifestModule == null)
296                         {
297                                 manifestModule = DefineDynamicModule("RefEmit_OnDiskManifestModule", assemblyFileName, false);
298                         }
299
300                         AssemblyTable.Record assemblyRecord = new AssemblyTable.Record();
301                         assemblyRecord.HashAlgId = (int)hashAlgorithm;
302                         assemblyRecord.Name = manifestModule.Strings.Add(name);
303                         assemblyRecord.MajorVersion = majorVersion;
304                         assemblyRecord.MinorVersion = minorVersion;
305                         assemblyRecord.BuildNumber = buildVersion;
306                         assemblyRecord.RevisionNumber = revisionVersion;
307                         if (publicKey != null)
308                         {
309                                 assemblyRecord.PublicKey = manifestModule.Blobs.Add(ByteBuffer.Wrap(publicKey));
310                                 assemblyRecord.Flags = (int)(flags | AssemblyNameFlags.PublicKey);
311                         }
312                         else
313                         {
314                                 assemblyRecord.Flags = (int)(flags & ~AssemblyNameFlags.PublicKey);
315                         }
316                         if (culture != null)
317                         {
318                                 assemblyRecord.Culture = manifestModule.Strings.Add(culture);
319                         }
320                         int token = 0x20000000 + manifestModule.AssemblyTable.AddRecord(assemblyRecord);
321
322 #pragma warning disable 618
323                         // this values are obsolete, but we already know that so we disable the warning
324                         System.Security.Permissions.SecurityAction requestMinimum = System.Security.Permissions.SecurityAction.RequestMinimum;
325                         System.Security.Permissions.SecurityAction requestOptional = System.Security.Permissions.SecurityAction.RequestOptional;
326                         System.Security.Permissions.SecurityAction requestRefuse = System.Security.Permissions.SecurityAction.RequestRefuse;
327 #pragma warning restore 618
328                         if (requiredPermissions != null)
329                         {
330                                 manifestModule.AddDeclarativeSecurity(token, requestMinimum, requiredPermissions);
331                         }
332                         if (optionalPermissions != null)
333                         {
334                                 manifestModule.AddDeclarativeSecurity(token, requestOptional, optionalPermissions);
335                         }
336                         if (refusedPermissions != null)
337                         {
338                                 manifestModule.AddDeclarativeSecurity(token, requestRefuse, refusedPermissions);
339                         }
340
341                         if (versionInfo != null)
342                         {
343                                 versionInfo.SetName(GetName());
344                                 versionInfo.SetFileName(assemblyFileName);
345                                 foreach (CustomAttributeBuilder cab in customAttributes)
346                                 {
347                                         // .NET doesn't support copying blob custom attributes into the version info
348                                         if (!cab.HasBlob)
349                                         {
350                                                 versionInfo.SetAttribute(cab);
351                                         }
352                                 }
353                                 ByteBuffer versionInfoData = new ByteBuffer(512);
354                                 versionInfo.Write(versionInfoData);
355                                 if (unmanagedResources == null)
356                                 {
357                                         unmanagedResources = new ResourceSection();
358                                 }
359                                 unmanagedResources.AddVersionInfo(versionInfoData);
360                         }
361
362                         foreach (CustomAttributeBuilder cab in customAttributes)
363                         {
364                                 // we intentionally don't filter out the version info (pseudo) custom attributes (to be compatible with .NET)
365                                 manifestModule.SetCustomAttribute(0x20000001, cab);
366                         }
367
368                         manifestModule.AddDeclarativeSecurity(0x20000001, declarativeSecurity);
369
370                         foreach (Type type in typeForwarders)
371                         {
372                                 manifestModule.AddTypeForwarder(type);
373                         }
374
375                         foreach (ResourceFile resfile in resourceFiles)
376                         {
377                                 int fileToken = AddFile(manifestModule, resfile.FileName, 1 /*ContainsNoMetaData*/);
378                                 ManifestResourceTable.Record rec = new ManifestResourceTable.Record();
379                                 rec.Offset = 0;
380                                 rec.Flags = (int)resfile.Attributes;
381                                 rec.Name = manifestModule.Strings.Add(resfile.Name);
382                                 rec.Implementation = fileToken;
383                                 manifestModule.ManifestResource.AddRecord(rec);
384                         }
385
386                         int entryPointToken = 0;
387
388                         foreach (ModuleBuilder moduleBuilder in modules)
389                         {
390                                 moduleBuilder.FillAssemblyRefTable();
391                                 if (moduleBuilder != manifestModule)
392                                 {
393                                         int fileToken;
394                                         if (entryPoint != null && entryPoint.Module == moduleBuilder)
395                                         {
396                                                 ModuleWriter.WriteModule(null, null, moduleBuilder, fileKind, portableExecutableKind, imageFileMachine, moduleBuilder.unmanagedResources, entryPoint.MetadataToken);
397                                                 entryPointToken = fileToken = AddFile(manifestModule, moduleBuilder.fileName, 0 /*ContainsMetaData*/);
398                                         }
399                                         else
400                                         {
401                                                 ModuleWriter.WriteModule(null, null, moduleBuilder, fileKind, portableExecutableKind, imageFileMachine, moduleBuilder.unmanagedResources, 0);
402                                                 fileToken = AddFile(manifestModule, moduleBuilder.fileName, 0 /*ContainsMetaData*/);
403                                         }
404                                         moduleBuilder.ExportTypes(fileToken, manifestModule);
405                                 }
406                         }
407
408                         foreach (Module module in addedModules)
409                         {
410                                 int fileToken = AddFile(manifestModule, module.FullyQualifiedName, 0 /*ContainsMetaData*/);
411                                 module.ExportTypes(fileToken, manifestModule);
412                         }
413
414                         if (entryPointToken == 0 && entryPoint != null)
415                         {
416                                 entryPointToken = entryPoint.MetadataToken;
417                         }
418
419                         // finally, write the manifest module
420                         ModuleWriter.WriteModule(keyPair, publicKey, manifestModule, fileKind, portableExecutableKind, imageFileMachine, unmanagedResources ?? manifestModule.unmanagedResources, entryPointToken, streamOrNull);
421                 }
422
423                 private int AddFile(ModuleBuilder manifestModule, string fileName, int flags)
424                 {
425                         SHA1Managed hash = new SHA1Managed();
426                         string fullPath = fileName;
427                         if (dir != null)
428                         {
429                                 fullPath = Path.Combine(dir, fileName);
430                         }
431                         using (FileStream fs = new FileStream(fullPath, FileMode.Open, FileAccess.Read))
432                         {
433                                 using (CryptoStream cs = new CryptoStream(Stream.Null, hash, CryptoStreamMode.Write))
434                                 {
435                                         byte[] buf = new byte[8192];
436                                         ModuleWriter.HashChunk(fs, cs, buf, (int)fs.Length);
437                                 }
438                         }
439                         FileTable.Record file = new FileTable.Record();
440                         file.Flags = flags;
441                         file.Name = manifestModule.Strings.Add(Path.GetFileName(fileName));
442                         file.HashValue = manifestModule.Blobs.Add(ByteBuffer.Wrap(hash.Hash));
443                         return 0x26000000 + manifestModule.File.AddRecord(file);
444                 }
445
446                 public void AddResourceFile(string name, string fileName)
447                 {
448                         AddResourceFile(name, fileName, ResourceAttributes.Public);
449                 }
450
451                 public void AddResourceFile(string name, string fileName, ResourceAttributes attribs)
452                 {
453                         ResourceFile resfile = new ResourceFile();
454                         resfile.Name = name;
455                         resfile.FileName = fileName;
456                         resfile.Attributes = attribs;
457                         resourceFiles.Add(resfile);
458                 }
459
460                 public void DefineVersionInfoResource()
461                 {
462                         versionInfo = new VersionInfo();
463                 }
464
465                 public void DefineVersionInfoResource(string product, string productVersion, string company, string copyright, string trademark)
466                 {
467                         versionInfo = new VersionInfo();
468                         versionInfo.product = product;
469                         versionInfo.informationalVersion = productVersion;
470                         versionInfo.company = company;
471                         versionInfo.copyright = copyright;
472                         versionInfo.trademark = trademark;
473                 }
474
475                 public void __DefineIconResource(byte[] iconFile)
476                 {
477                         unmanagedResources = new ResourceSection();
478                         unmanagedResources.AddIcon(iconFile);
479                 }
480
481                 public void __DefineUnmanagedResource(byte[] resource)
482                 {
483                         // The standard .NET DefineUnmanagedResource(byte[]) is useless, because it embeds "resource" (as-is) as the .rsrc section,
484                         // but it doesn't set the PE file Resource Directory entry to point to it. That's why we have a renamed version, which behaves
485                         // like DefineUnmanagedResource(string).
486                         unmanagedResources = new ResourceSection();
487                         unmanagedResources.ExtractResources(resource);
488                 }
489
490                 public void DefineUnmanagedResource(string resourceFileName)
491                 {
492                         // This method reads the specified resource file (Win32 .res file) and converts it into the appropriate format and embeds it in the .rsrc section,
493                         // also setting the Resource Directory entry.
494                         __DefineUnmanagedResource(File.ReadAllBytes(resourceFileName));
495                 }
496
497                 public override Type[] GetTypes()
498                 {
499                         List<Type> list = new List<Type>();
500                         foreach (ModuleBuilder module in modules)
501                         {
502                                 module.GetTypesImpl(list);
503                         }
504                         foreach (Module module in addedModules)
505                         {
506                                 module.GetTypesImpl(list);
507                         }
508                         return list.ToArray();
509                 }
510
511                 internal override Type GetTypeImpl(string typeName)
512                 {
513                         foreach (ModuleBuilder mb in modules)
514                         {
515                                 Type type = mb.GetTypeImpl(typeName);
516                                 if (type != null)
517                                 {
518                                         return type;
519                                 }
520                         }
521                         foreach (Module module in addedModules)
522                         {
523                                 Type type = module.GetTypeImpl(typeName);
524                                 if (type != null)
525                                 {
526                                         return type;
527                                 }
528                         }
529                         return null;
530                 }
531
532                 internal override Type ResolveType(string ns, string name)
533                 {
534                         return base.ResolveType(ns, name) ?? GetMissingType(this.ManifestModule, null, ns, name);
535                 }
536
537                 internal Type GetMissingType(Module module, Type declaringType, string ns, string name)
538                 {
539                         if (missingTypes == null)
540                         {
541                                 return null;
542                         }
543                         Type mt = new MissingType(module, declaringType, ns, name);
544                         Type type;
545                         if (!missingTypes.TryGetValue(mt.FullName, out type))
546                         {
547                                 missingTypes.Add(mt.FullName, mt);
548                                 type = mt;
549                         }
550                         return type;
551                 }
552
553                 public void __EnableMissingTypeResolution()
554                 {
555                         if (missingTypes == null)
556                         {
557                                 missingTypes = new Dictionary<string, Type>();
558                         }
559                 }
560
561                 public override string ImageRuntimeVersion
562                 {
563                         get { return imageRuntimeVersion; }
564                 }
565
566                 public void __SetImageRuntimeVersion(string imageRuntimeVersion, int mdStreamVersion)
567                 {
568                         this.imageRuntimeVersion = imageRuntimeVersion;
569                         this.mdStreamVersion = mdStreamVersion;
570                 }
571
572                 public override Module ManifestModule
573                 {
574                         get
575                         {
576                                 if (pseudoManifestModule == null)
577                                 {
578                                         pseudoManifestModule = new ManifestModule(this);
579                                 }
580                                 return pseudoManifestModule;
581                         }
582                 }
583
584                 public override MethodInfo EntryPoint
585                 {
586                         get { return entryPoint; }
587                 }
588
589                 public override AssemblyName[] GetReferencedAssemblies()
590                 {
591                         return Empty<AssemblyName>.Array;
592                 }
593
594                 public override Module[] GetLoadedModules(bool getResourceModules)
595                 {
596                         return GetModules(getResourceModules);
597                 }
598
599                 public override Module[] GetModules(bool getResourceModules)
600                 {
601                         List<Module> list = new List<Module>();
602                         foreach (ModuleBuilder module in modules)
603                         {
604                                 if (getResourceModules || !module.IsResource())
605                                 {
606                                         list.Add(module);
607                                 }
608                         }
609                         foreach (Module module in addedModules)
610                         {
611                                 if (getResourceModules || !module.IsResource())
612                                 {
613                                         list.Add(module);
614                                 }
615                         }
616                         return list.ToArray();
617                 }
618
619                 public override Module GetModule(string name)
620                 {
621                         foreach (ModuleBuilder module in modules)
622                         {
623                                 if (module.Name.Equals(name, StringComparison.InvariantCultureIgnoreCase))
624                                 {
625                                         return module;
626                                 }
627                         }
628                         foreach (Module module in addedModules)
629                         {
630                                 if (module.Name.Equals(name, StringComparison.InvariantCultureIgnoreCase))
631                                 {
632                                         return module;
633                                 }
634                         }
635                         return null;
636                 }
637
638                 public Module __AddModule(RawModule module)
639                 {
640                         Module mod = module.ToModule(this);
641                         addedModules.Add(mod);
642                         return mod;
643                 }
644
645                 public override ManifestResourceInfo GetManifestResourceInfo(string resourceName)
646                 {
647                         throw new NotSupportedException();
648                 }
649
650                 public override string[] GetManifestResourceNames()
651                 {
652                         throw new NotSupportedException();
653                 }
654
655                 public override Stream GetManifestResourceStream(string resourceName)
656                 {
657                         throw new NotSupportedException();
658                 }
659
660                 internal override IList<CustomAttributeData> GetCustomAttributesData(Type attributeType)
661                 {
662                         List<CustomAttributeData> list = new List<CustomAttributeData>();
663                         foreach (CustomAttributeBuilder cab in customAttributes)
664                         {
665                                 if (attributeType == null || attributeType.IsAssignableFrom(cab.Constructor.DeclaringType))
666                                 {
667                                         list.Add(cab.ToData(this));
668                                 }
669                         }
670                         return list;
671                 }
672         }
673
674         sealed class ManifestModule : Module
675         {
676                 private readonly AssemblyBuilder assembly;
677                 private readonly Guid guid = Guid.NewGuid();
678
679                 internal ManifestModule(AssemblyBuilder assembly)
680                         : base(assembly.universe)
681                 {
682                         this.assembly = assembly;
683                 }
684
685                 public override int MDStreamVersion
686                 {
687                         get { return assembly.mdStreamVersion; }
688                 }
689
690                 public override Assembly Assembly
691                 {
692                         get { return assembly; }
693                 }
694
695                 internal override Type GetTypeImpl(string typeName)
696                 {
697                         return null;
698                 }
699
700                 internal override void  GetTypesImpl(List<Type> list)
701                 {
702                 }
703
704                 public override string FullyQualifiedName
705                 {
706                         get { return Path.Combine(assembly.dir, "RefEmit_InMemoryManifestModule"); }
707                 }
708
709                 public override string Name
710                 {
711                         get { return "<In Memory Module>"; }
712                 }
713
714                 public override Guid ModuleVersionId
715                 {
716                         get { return guid; }
717                 }
718
719                 public override Type ResolveType(int metadataToken, Type[] genericTypeArguments, Type[] genericMethodArguments)
720                 {
721                         throw new ArgumentException();
722                 }
723
724                 public override MethodBase ResolveMethod(int metadataToken, Type[] genericTypeArguments, Type[] genericMethodArguments)
725                 {
726                         throw new ArgumentException();
727                 }
728
729                 public override FieldInfo ResolveField(int metadataToken, Type[] genericTypeArguments, Type[] genericMethodArguments)
730                 {
731                         throw new ArgumentException();
732                 }
733
734                 public override MemberInfo ResolveMember(int metadataToken, Type[] genericTypeArguments, Type[] genericMethodArguments)
735                 {
736                         throw new ArgumentException();
737                 }
738
739                 public override string ResolveString(int metadataToken)
740                 {
741                         throw new ArgumentException();
742                 }
743
744                 public override Type[] __ResolveOptionalParameterTypes(int metadataToken)
745                 {
746                         throw new ArgumentException();
747                 }
748
749                 public override string ScopeName
750                 {
751                         get { return "RefEmit_InMemoryManifestModule"; }
752                 }
753
754                 public override AssemblyName[] __GetReferencedAssemblies()
755                 {
756                         throw new InvalidOperationException();
757                 }
758
759                 internal override Type GetModuleType()
760                 {
761                         throw new InvalidOperationException();
762                 }
763
764                 internal override IKVM.Reflection.Reader.ByteReader GetBlob(int blobIndex)
765                 {
766                         throw new InvalidOperationException();
767                 }
768         }
769 }