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