Simplify the profiler line in the spec file
[mono.git] / mcs / mcs / ikvm.cs
1 //
2 // ikvm.cs: IKVM.Reflection and IKVM.Reflection.Emit specific implementations
3 //
4 // Author: Marek Safar (marek.safar@gmail.com)
5 //
6 // Dual licensed under the terms of the MIT X11 or GNU GPL
7 //
8 // Copyright 2009-2010 Novell, Inc. 
9 //
10 //
11
12 using System;
13 using System.Collections.Generic;
14 using MetaType = IKVM.Reflection.Type;
15 using IKVM.Reflection;
16 using IKVM.Reflection.Emit;
17 using System.IO;
18 using System.Configuration.Assemblies;
19
20 namespace Mono.CSharp
21 {
22 #if !STATIC
23         public class StaticImporter
24         {
25                 public StaticImporter (BuildinTypes buildin)
26                 {
27                         throw new NotSupportedException ();
28                 }
29
30                 public void ImportAssembly (Assembly assembly, RootNamespace targetNamespace)
31                 {
32                         throw new NotSupportedException ();
33                 }
34
35                 public void ImportModule (Module module, RootNamespace targetNamespace)
36                 {
37                         throw new NotSupportedException ();
38                 }
39
40                 public TypeSpec ImportType (System.Type type)
41                 {
42                         throw new NotSupportedException ();
43                 }
44         }
45
46 #else
47
48         sealed class StaticImporter : MetadataImporter
49         {
50                 public StaticImporter ()
51                 {
52                 }
53
54                 protected override MemberKind DetermineKindFromBaseType (MetaType baseType)
55                 {
56                         string name = baseType.Name;
57
58                         // TODO: namespace check
59                         if (name == "ValueType")
60                                 return MemberKind.Struct;
61
62                         if (name == "Enum")
63                                 return MemberKind.Enum;
64
65                         if (name == "MulticastDelegate")
66                                 return MemberKind.Delegate;
67
68                         return MemberKind.Class;
69                 }
70
71                 protected override bool HasVolatileModifier (MetaType[] modifiers)
72                 {
73                         foreach (var t in modifiers) {
74                                 if (t.Name == "IsVolatile" && t.Namespace == CompilerServicesNamespace)
75                                         return true;
76                         }
77
78                         return false;
79                 }
80
81                 public override void GetCustomAttributeTypeName (CustomAttributeData cad, out string typeNamespace, out string typeName)
82                 {
83                         cad.__ReadTypeName (out typeNamespace, out typeName);
84                 }
85
86                 public void ImportAssembly (Assembly assembly, RootNamespace targetNamespace)
87                 {
88                         // It can be used more than once when importing same assembly
89                         // into 2 or more global aliases
90                         var definition = GetAssemblyDefinition (assembly);
91
92                         var all_types = assembly.GetTypes ();
93                         ImportTypes (all_types, targetNamespace, definition.HasExtensionMethod);
94                 }
95
96                 public ImportedModuleDefinition ImportModule (Module module, RootNamespace targetNamespace)
97                 {
98                         var module_definition = new ImportedModuleDefinition (module, this);
99                         module_definition.ReadAttributes ();
100
101                         var all_types = module.GetTypes ();
102                         ImportTypes (all_types, targetNamespace, false);
103
104                         return module_definition;
105                 }
106
107                 public void InitializeBuildinTypes (BuildinTypes buildin, Assembly corlib)
108                 {
109                         //
110                         // Setup mapping for build-in types to avoid duplication of their definition
111                         //
112                         foreach (var type in buildin.AllTypes) {
113                                 buildin_types.Add (corlib.GetType (type.FullName), type);
114                         }
115                 }
116         }
117 #endif
118
119         class AssemblyDefinitionStatic : AssemblyDefinition
120         {
121                 //
122                 // Assembly container with file output
123                 //
124                 public AssemblyDefinitionStatic (ModuleContainer module, string name, string fileName)
125                         : base (module, name, fileName)
126                 {
127                 }
128
129                 //
130                 // Initializes the code generator
131                 //
132                 public bool Create (Universe domain)
133                 {
134                         ResolveAssemblySecurityAttributes ();
135                         var an = CreateAssemblyName ();
136
137                         Builder = domain.DefineDynamicAssembly (an, AssemblyBuilderAccess.Save, Path.GetDirectoryName (file_name));
138
139                         // Sets output file metadata version, this makes sense for mscorlib
140                         // compilation only but won't restrict that for now
141                         switch (RootContext.StdLibRuntimeVersion){
142                         case RuntimeVersion.v4:
143                                 Builder.__SetImageRuntimeVersion ("v4.0.30319", 0x20000);
144                                 break;
145                         case RuntimeVersion.v2:
146                                 Builder.__SetImageRuntimeVersion ("v2.0.50727", 0x20000);
147                                 break;
148                         case RuntimeVersion.v1:
149                                 // Compiler does not do any checks whether the produced metadata
150                                 // are valid in the context of 1.0 stream version
151                                 Builder.__SetImageRuntimeVersion ("v1.1.4322", 0x10000);
152                                 break;
153                         default:
154                                 throw new NotImplementedException ();
155                         }
156
157                         builder_extra = new AssemblyBuilderIKVM (Builder, Compiler);
158                         return true;
159                 }
160
161                 public Module IncludeModule (RawModule moduleFile)
162                 {
163                         return Builder.__AddModule (moduleFile);
164                 }
165
166                 protected override void SaveModule (PortableExecutableKinds pekind, ImageFileMachine machine)
167                 {
168                         module.Builder.__Save (pekind, machine);
169                 }
170         }
171
172         class StaticLoader : AssemblyReferencesLoader<Assembly>, IDisposable
173         {
174                 readonly StaticImporter importer;
175                 readonly Universe domain;
176                 Assembly corlib;
177
178                 public StaticLoader (StaticImporter importer, CompilerContext compiler)
179                         : base (compiler)
180                 {
181                         this.importer = importer;
182                         domain = new Universe ();
183                         domain.AssemblyResolve += AssemblyReferenceResolver;
184                 }
185
186                 public Assembly Corlib {
187                         get {
188                                 return corlib;
189                         }
190                         set {
191                                 corlib = value;
192                         }
193                 }
194
195                 public Universe Domain {
196                         get {
197                                 return domain;
198                         }
199                 }
200
201                 Assembly AssemblyReferenceResolver (object sender, IKVM.Reflection.ResolveEventArgs args)
202                 {
203                         if (args.Name == "mscorlib")
204                                 return corlib;
205
206                         // AssemblyReference has not been found in the domain
207                         // create missing reference and continue
208                         return new MissingAssembly (domain, args.Name);
209                 }
210
211                 public void Dispose ()
212                 {
213                         domain.Dispose ();
214                 }
215
216                 protected override string[] GetDefaultReferences ()
217                 {
218                         //
219                         // For now the "default config" is harcoded into the compiler
220                         // we can move this outside later
221                         //
222                         var default_references = new List<string> (8);
223
224                         default_references.Add ("System.dll");
225                         default_references.Add ("System.Xml.dll");
226 #if NET_2_1
227                         default_references.Add ("System.Net.dll");
228                         default_references.Add ("System.Windows.dll");
229                         default_references.Add ("System.Windows.Browser.dll");
230 #endif
231
232                         // TODO: Will have to do it based on mscorlib version or something like that
233
234                         if (RootContext.Version > LanguageVersion.ISO_2)
235                                 default_references.Add ("System.Core.dll");
236                         if (RootContext.Version > LanguageVersion.V_3)
237                                 default_references.Add ("Microsoft.CSharp.dll");
238
239                         return default_references.ToArray ();
240                 }
241
242                 public override bool HasObjectType (Assembly assembly)
243                 {
244                         return assembly.GetType (compiler.BuildinTypes.Object.FullName) != null;
245                 }
246
247                 public override Assembly LoadAssemblyFile (string fileName)
248                 {
249                         bool? has_extension = null;
250                         foreach (var path in paths) {
251                                 var file = Path.Combine (path, fileName);
252                                 if (!File.Exists (file)) {
253                                         if (!has_extension.HasValue)
254                                                 has_extension = fileName.EndsWith (".dll", StringComparison.Ordinal) || fileName.EndsWith (".exe", StringComparison.Ordinal);
255
256                                         if (has_extension.Value)
257                                                 continue;
258
259                                         file += ".dll";
260                                         if (!File.Exists (file))
261                                                 continue;
262                                 }
263
264                                 try {
265                                         using (RawModule module = domain.OpenRawModule (file)) {
266                                                 if (!module.IsManifestModule) {
267                                                         Error_AssemblyIsModule (fileName);
268                                                         return null;
269                                                 }
270
271                                                 return domain.LoadAssembly (module);
272                                         }
273                                 } catch {
274                                         Error_FileCorrupted (file);
275                                         return null;
276                                 }
277                         }
278
279                         Error_FileNotFound (fileName);
280                         return null;
281                 }
282
283                 public RawModule LoadModuleFile (string moduleName)
284                 {
285                         foreach (var path in paths) {
286                                 var file = Path.Combine (path, moduleName);
287                                 if (!File.Exists (file)) {
288                                         if (moduleName.EndsWith (".netmodule", StringComparison.Ordinal))
289                                                 continue;
290
291                                         file += ".netmodule";
292                                         if (!File.Exists (file))
293                                                 continue;
294                                 }
295
296                                 try {
297                                         return domain.OpenRawModule (file);
298                                 } catch {
299                                         Error_FileCorrupted (file);
300                                         return null;
301                                 }
302                         }
303
304                         Error_FileNotFound (moduleName);
305                         return null;                            
306                 }
307
308                 //
309                 // Optimized default assembly loader version
310                 //
311                 public override Assembly LoadAssemblyDefault (string assembly)
312                 {
313                         foreach (var path in paths) {
314                                 var file = Path.Combine (path, assembly);
315                                 if (!File.Exists (file))
316                                         continue;
317
318                                 try {
319                                         return domain.LoadFile (file);
320                                 } catch {
321                                         // Default assemblies can fail to load without error
322                                         return null;
323                                 }
324                         }
325
326                         return null;
327                 }
328
329                 public override void LoadReferences (ModuleContainer module)
330                 {
331                         List<Tuple<RootNamespace, Assembly>> loaded;
332                         base.LoadReferencesCore (module, out corlib, out loaded);
333
334                         if (corlib != null) {
335                                 importer.InitializeBuildinTypes (compiler.BuildinTypes, corlib);
336                                 importer.ImportAssembly (corlib, module.GlobalRootNamespace);
337                         }
338
339                         foreach (var entry in loaded) {
340                                 importer.ImportAssembly (entry.Item2, entry.Item1);
341                         }
342                 }
343
344                 public void LoadModules (AssemblyDefinitionStatic assembly, RootNamespace targetNamespace)
345                 {
346                         if (RootContext.Modules.Count == 0)
347                                 return;
348
349                         foreach (var moduleName in RootContext.Modules) {
350                                 var m = LoadModuleFile (moduleName);
351                                 if (m == null)
352                                         continue;
353
354                                 if (m.IsManifestModule) {
355                                         Error_FileCorrupted (moduleName);
356                                         continue;
357                                 }
358
359                                 var md = importer.ImportModule (assembly.IncludeModule (m), targetNamespace);
360                                 assembly.AddModule (md);
361                         }
362                 }
363         }
364
365         //
366         // Represents missing assembly reference
367         //
368         class MissingAssembly : Assembly
369         {
370                 class MissingModule : Module
371                 {
372                         readonly Assembly assembly;
373
374                         public MissingModule (Universe universe, Assembly assembly)
375                                 : base (universe)
376                         {
377                                 this.assembly = assembly;
378                         }
379
380                         public override int MDStreamVersion {
381                                 get {
382                                         throw new NotImplementedException ();
383                                 }
384                         }
385
386                         public override Assembly Assembly {
387                                 get {
388                                         return assembly;
389                                 }
390                         }
391
392                         public override string FullyQualifiedName {
393                                 get {
394                                         throw new NotImplementedException ();
395                                 }
396                         }
397
398                         public override string Name {
399                                 get {
400                                         throw new NotImplementedException ();
401                                 }
402                         }
403
404                         public override Guid ModuleVersionId {
405                                 get {
406                                         throw new NotImplementedException ();
407                                 }
408                         }
409
410                         public override MetaType ResolveType (int metadataToken, MetaType[] genericTypeArguments, MetaType[] genericMethodArguments)
411                         {
412                                 throw new NotImplementedException ();
413                         }
414
415                         public override MethodBase ResolveMethod (int metadataToken, MetaType[] genericTypeArguments, MetaType[] genericMethodArguments)
416                         {
417                                 throw new NotImplementedException ();
418                         }
419
420                         public override FieldInfo ResolveField (int metadataToken, MetaType[] genericTypeArguments, MetaType[] genericMethodArguments)
421                         {
422                                 throw new NotImplementedException ();
423                         }
424
425                         public override MemberInfo ResolveMember (int metadataToken, MetaType[] genericTypeArguments, MetaType[] genericMethodArguments)
426                         {
427                                 throw new NotImplementedException ();
428                         }
429
430                         public override string ResolveString (int metadataToken)
431                         {
432                                 throw new NotImplementedException ();
433                         }
434
435                         public override MetaType[] __ResolveOptionalParameterTypes (int metadataToken)
436                         {
437                                 throw new NotImplementedException ();
438                         }
439
440                         public override string ScopeName {
441                                 get {
442                                         throw new NotImplementedException ();
443                                 }
444                         }
445
446                         internal override MetaType GetTypeImpl (string typeName)
447                         {
448                                 throw new NotImplementedException ();
449                         }
450
451                         internal override void GetTypesImpl (List<MetaType> list)
452                         {
453                                 throw new NotImplementedException ();
454                         }
455
456                         public override AssemblyName[] __GetReferencedAssemblies ()
457                         {
458                                 throw new NotImplementedException ();
459                         }
460
461                         internal override MetaType GetModuleType ()
462                         {
463                                 throw new NotImplementedException ();
464                         }
465
466                         internal override IKVM.Reflection.Reader.ByteReader GetBlob (int blobIndex)
467                         {
468                                 throw new NotImplementedException ();
469                         }
470                 }
471
472                 readonly string full_name;
473                 readonly Module module;
474                 Dictionary<string, MetaType> types;
475
476                 public MissingAssembly (Universe universe, string fullName)
477                         : base (universe)
478                 {
479                         this.full_name = fullName;
480                         this.module = new MissingModule (universe, this);
481                         types = new Dictionary<string, MetaType> ();
482                 }
483
484                 public override MetaType[] GetTypes ()
485                 {
486                         throw new NotImplementedException ();
487                 }
488
489                 public override string FullName {
490                         get {
491                                 return full_name;
492                         }
493                 }
494
495                 public override AssemblyName GetName ()
496                 {
497                         throw new NotImplementedException ();
498                 }
499
500                 public override string ImageRuntimeVersion {
501                         get {
502                                 throw new NotImplementedException ();
503                         }
504                 }
505
506                 public override Module ManifestModule {
507                         get {
508                                 return module;
509                         }
510                 }
511
512                 public override MethodInfo EntryPoint {
513                         get {
514                                 throw new NotImplementedException ();
515                         }
516                 }
517
518                 public override string Location {
519                         get {
520                                 throw new NotImplementedException ();
521                         }
522                 }
523
524                 public override AssemblyName[] GetReferencedAssemblies ()
525                 {
526                         throw new NotImplementedException ();
527                 }
528
529                 public override Module[] GetModules (bool getResourceModules)
530                 {
531                         throw new NotImplementedException ();
532                 }
533
534                 public override Module[] GetLoadedModules (bool getResourceModules)
535                 {
536                         throw new NotImplementedException ();
537                 }
538
539                 public override Module GetModule (string name)
540                 {
541                         throw new NotImplementedException ();
542                 }
543
544                 public override string[] GetManifestResourceNames ()
545                 {
546                         throw new NotImplementedException ();
547                 }
548
549                 public override ManifestResourceInfo GetManifestResourceInfo (string resourceName)
550                 {
551                         throw new NotImplementedException ();
552                 }
553
554                 public override Stream GetManifestResourceStream (string resourceName)
555                 {
556                         throw new NotImplementedException ();
557                 }
558
559                 internal override MetaType GetTypeImpl (string typeName)
560                 {
561                         //
562                         // We are loading a type from missing reference
563                         // this itself is fine. The error will be reported
564                         // later when the type is actually used
565                         //
566                         MetaType t;
567                         if (!types.TryGetValue (typeName, out t)) {
568                                 t = new MissingType (typeName, this);
569                                 types.Add (typeName, t);
570                         }
571
572                         return t;
573                 }
574
575                 internal override IList<CustomAttributeData> GetCustomAttributesData (MetaType attributeType)
576                 {
577                         throw new NotImplementedException ();
578                 }
579         }
580
581         class MissingType : MetaType
582         {
583                 readonly string full_name;
584                 readonly MissingAssembly assembly;
585
586                 public MissingType (string typeName, MissingAssembly assembly)
587                 {
588                         this.full_name = typeName;
589                         this.assembly = assembly;
590                 }
591
592                 public override TypeAttributes Attributes {
593                         get {
594                                 // TODO: Don't know yet
595                                 return TypeAttributes.Public;
596                         }
597                 }
598
599                 public override MetaType BaseType {
600                         get {
601                                 return null;
602                         }
603                 }
604
605                 public override string FullName {
606                         get {
607                                 return full_name;
608                         }
609                 }
610
611                 internal override MetaType GetGenericTypeArgument (int index)
612                 {
613                         return new MissingType ("#" + index.ToString (), assembly);
614                 }
615
616                 public override bool IsGenericTypeDefinition {
617                         get {
618                                 return full_name.IndexOf ('`') > 0;
619                         }
620                 }
621
622                 public override Module Module {
623                         get {
624                                 return assembly.ManifestModule;
625                         }
626                 }
627         }
628
629         class AssemblyBuilderIKVM : AssemblyBuilderExtension
630         {
631                 readonly AssemblyBuilder builder;
632
633                 public AssemblyBuilderIKVM (AssemblyBuilder builder, CompilerContext ctx)
634                         : base (ctx)
635                 {
636                         this.builder = builder;
637                 }
638
639                 public override void AddTypeForwarder (TypeSpec type, Location loc)
640                 {
641                         builder.__AddTypeForwarder (type.GetMetaInfo ());
642                 }
643
644                 public override void DefineWin32IconResource (string fileName)
645                 {
646                         builder.__DefineIconResource (File.ReadAllBytes (fileName));
647                 }
648
649                 public override void SetAlgorithmId (uint value, Location loc)
650                 {
651                         builder.__SetAssemblyAlgorithmId ((AssemblyHashAlgorithm) value);
652                 }
653
654                 public override void SetCulture (string culture, Location loc)
655                 {
656                         builder.__SetAssemblyCulture (culture);
657                 }
658
659                 public override void SetFlags (uint flags, Location loc)
660                 {
661                         builder.__SetAssemblyFlags ((AssemblyNameFlags) flags);
662                 }
663
664                 public override void SetVersion (Version version, Location loc)
665                 {
666                         builder.__SetAssemblyVersion (version);
667                 }
668         }
669 }