2003/11/10 Rafael Teixeira <rafaelteixeirabr@hotmail.com>
[mono.git] / mcs / mbas / driver.cs
1 //
2 // driver.cs: The compiler command line driver.
3 //
4 // Author: Rafael Teixeira (rafaelteixeirabr@hotmail.com)
5 // Based on mcs by : Miguel de Icaza (miguel@gnu.org)
6 //
7 // Licensed under the terms of the GNU GPL
8 //
9 // (C) 2002 Rafael Teixeira
10 //
11
12 namespace Mono.Languages
13 {
14         using System;
15         using System.Reflection;
16         using System.Reflection.Emit;
17         using System.Collections;
18         using System.IO;
19         using System.Globalization;
20         using Mono.MonoBASIC;
21         using Mono.GetOptions;
22
23         enum Target 
24         {
25                 Library, Exe, Module, WinExe
26         };
27         
28         enum OptionCompare
29         {
30                 Binary, Text
31         };
32         
33         /// <summary>
34         ///    The compiler driver.
35         /// </summary>
36         public class Driver : Options
37         {
38                 // Temporary options
39                 //------------------------------------------------------------------
40                 [Option("[Mono] Only parses the source file (for debugging the tokenizer)", "parse")]
41                 public bool parse_only = false;
42
43                 [Option("[Mono] Only tokenizes source files")]
44                 public bool tokenize = false;
45
46                 [Option("[Mono] Shows stack trace at Error location")]
47                 public bool stacktrace { set { Report.Stacktrace = value; } }
48
49                 [Option("[Mono] Displays time stamps of various compiler events")]
50                 public bool timestamp
51                 {
52                         set
53                         {
54                                 timestamps = true;
55                                 last_time = DateTime.Now;
56                                 debug_arglist.Add("timestamp");
57                         }
58                 }
59
60                 // Mono-specific options
61                 //------------------------------------------------------------------
62                 [Option("About the MonoBASIC compiler", "about")]
63                 public override WhatToDoNext DoAbout()
64                 {
65                         return base.DoAbout();
66                 }
67
68                 [Option("[Mono] Don\'t assume the standard library", "nostdlib")]
69                 public bool NoStandardLibraries { set { RootContext.StdLib = !value; } }
70
71                 [Option("[Mono] Disables implicit references to assemblies", "noconfig")]
72                 public bool NoConfig { set { load_default_config = !value; } }
73
74                 [Option("[Mono] Allows unsafe code", "unsafe")]
75                 public bool AllowUnsafeCode { set { RootContext.Unsafe = value; } }
76
77                 [Option("[Mono] Set default context to checked", "checked")]
78                 public bool Checked { set { RootContext.Checked = value; } }
79
80                 [Option("[Mono] Debugger {arguments}", "debug-args")]
81                 public WhatToDoNext SetDebugArgs(string args)
82                 {
83                         char[] sep = { ',' };
84                         debug_arglist.AddRange (args.Split (sep));
85                         return WhatToDoNext.GoAhead;
86                 }
87
88                 [Option("[Mono] Ignores warning number {XXXX}", "ignorewarn")]
89                 public WhatToDoNext SetIgnoreWarning(int warn)
90                 {
91                         Report.SetIgnoreWarning(warn);
92                         return WhatToDoNext.GoAhead;
93                 }       
94
95                 [Option("[Mono] Sets warning {level} (the highest is 4, the default)", "wlevel")]
96                 public int WarningLevel { set { RootContext.WarningLevel = value; } }
97
98                 [Option("[Mono] Makes errors fatal", "fatal")]
99                 public bool Fatal { set { Report.Fatal = value; } }
100
101                 // Output file options
102                 //------------------------------------------------------------------
103                 [Option("Specifies the output {file} name", 'o', "out")]
104                 public string OutputFileName = null;
105
106                 [Option("Specifies the target {type} for the output file (exe [default], winexe, library, module)", "target")]
107                 public WhatToDoNext SetTarget(string type)
108                 {
109                         switch (type.ToLower())
110                         {
111                                 case "library":
112                                         target = Target.Library;
113                                         target_ext = ".dll";
114                                         break;
115                                                         
116                                 case "exe":
117                                         target = Target.Exe;
118                                         break;
119                                                         
120                                 case "winexe":
121                                         target = Target.WinExe;
122                                         break;
123                                                         
124                                 case "module":
125                                         target = Target.Module;
126                                         target_ext = ".dll";
127                                         break;
128                         }
129                         return WhatToDoNext.GoAhead;
130                 }
131
132                 // input file options
133                 //------------------------------------------------------------------
134                 public ArrayList AddedModules = new ArrayList();
135
136                 [Option("[NOT IMPLEMENTED YET]References metadata from specified {module}", "addmodule")]
137                 public string AddedModule { set { AddedModules.Add(value); } }
138
139                 [Option("[NOT IMPLEMENTED YET]Include all files in the current directory and subdirectories according to the {wildcard}", "recurse")]
140                 public WhatToDoNext Recurse(string wildcard)
141                 {
142                         //AddFiles (DirName, true); // TODO wrong semantics
143                         return WhatToDoNext.GoAhead;
144                 }
145
146                 [Option(-1, "References metadata from the specified {assembly}", 'r', "reference")]
147                 public string AddedReference { set { references.Add(value); } }
148
149                 // resource options
150                 //------------------------------------------------------------------
151                 public ArrayList EmbeddedResources = new ArrayList();
152                 
153                 [Option(-1, "Adds the specified {file} as an embedded assembly resource", "resource", "res")]
154                 public string AddedResource { set { EmbeddedResources.Add(value); } }
155
156                 public ArrayList LinkedResources = new ArrayList();
157                 
158                 [Option(-1, "[NOT IMPLEMENTED YET]Adds the specified {file} as a linked assembly resource", "linkresource", "linkres")]
159                 public string AddedLinkresource { set { LinkedResources.Add(value); } }
160
161                 public ArrayList Win32Resources = new ArrayList();
162                 
163                 [Option(-1, "[NOT IMPLEMENTED YET]Specifies a Win32 resource {file} (.res)", "win32resource")]
164                 public string AddedWin32resource { set { Win32Resources.Add(value); } }
165
166                 public ArrayList Win32Icons = new ArrayList();
167                 
168                 [Option(-1, "[NOT IMPLEMENTED YET]Specifies a Win32 icon {file} (.ico) for the default Win32 resources", "win32icon")]
169                 public string AddedWin32icon { set { Win32Icons.Add(value); } }
170
171                 // code generation options
172                 //------------------------------------------------------------------
173                 [Option("[NOT IMPLEMENTED YET]Enable optimizations", "optimize")]
174                 public bool optimize = false;
175
176                 [Option("[NOT IMPLEMENTED YET]Remove integer checks. Default off.")]
177                 public bool removeintchecks = false;
178
179                 // TODO: handle VB.NET [+|-] boolean syntax
180                 [Option("Emit debugging information", 'g', "debug")]
181                 public bool want_debugging_support = false;
182
183                 [Option("Emit full debugging information (default)", "debug:full")]
184                 public bool fullDebugging = false;
185
186                 [Option("[IGNORED]Emit PDB file only", "debug:pdbonly")]
187                 public bool pdbOnly = false;
188
189                 // errors and warnings options
190                 //------------------------------------------------------------------
191                 [Option("Treat warnings as errors", "warnaserror")]
192                 public bool WarningsAreErrors { set { Report.WarningsAreErrors = value; } }
193
194                 [Option("Disable warnings", "nowarn")]
195                 public bool NoWarnings { set { if (value) RootContext.WarningLevel = 0; } }
196
197
198                 // language options
199                 //------------------------------------------------------------------
200                 public Hashtable Defines = new Hashtable();
201                 
202                 [Option(-1, "Declares global conditional compilation symbol(s). {symbol-list}:name=value,...", 'd', "define")]
203                 public string define { 
204                         set 
205                         {
206                                 foreach(string item in value.Split(',')) 
207                                 {       
208                                         string[] dados = item.Split('=');
209                                         try
210                                         {
211                                                 if (dados.Length > 1)
212                                                         Defines.Add(dados[0], dados[1]); 
213                                                 else
214                                                         Defines.Add(dados[0], string.Empty);
215                                         }
216                                         catch 
217                                         {
218                                                 Error ("Could not define symbol" + dados[0]);
219                                         }
220                                 }
221                         } 
222                 }
223                 
224                 private string[] importsList = null;
225                 
226                 [Option("[NOT IMPLEMENTED YET]Declare global Imports for namespaces in referenced metadata files. {import-list}:namespace,...", "imports")]
227                 public WhatToDoNext imports(string importslist)
228                 {
229                         importsList = importslist.Split(',');
230                         return WhatToDoNext.GoAhead;
231                 }
232
233                 // TODO: handle VB.NET [+|-] boolean syntax
234                 [Option("[NOT IMPLEMENTED YET]Require explicit declaration of variables")]
235                 public bool optionexplicit { set { Mono.MonoBASIC.Parser.InitialOptionExplicit = value; } }
236
237                 // TODO: handle VB.NET [+|-] boolean syntax
238                 [Option("[NOT IMPLEMENTED YET]Enforce strict language semantics")]
239                 public bool optionstrict { set { Mono.MonoBASIC.Parser.InitialOptionStrict = value; } }
240                 
241                 [Option("[NOT IMPLEMENTED YET]Specifies binary-style string comparisons. This is the default", "optioncompare:binary")]
242                 public bool optioncomparebinary { set { Mono.MonoBASIC.Parser.InitialOptionCompareBinary = true; } }
243
244                 [Option("[NOT IMPLEMENTED YET]Specifies text-style string comparisons.", "optioncompare:text")]
245                 public bool optioncomparetext { set { Mono.MonoBASIC.Parser.InitialOptionCompareBinary = false; } }
246
247                 [Option("Specifies de root {namespace} for all type declarations")]
248                 public string rootnamespace { set { RootContext.RootNamespace = value; } }
249                 
250                 // Miscellaneous options        
251                 //------------------------------------------------------------------
252                 
253                 [Option("[IGNORED]Do not display compiler copyright banner")]
254                 public bool nologo = false;
255                 
256                 [Option("[NOT IMPLEMENTED YET]Quiet output mode")]
257                 public bool quiet = false;
258                 
259                 // TODO: semantics are different and should be adjusted
260                 [Option("Display verbose messages", 'v')] 
261                 public bool verbose     { set { GenericParser.yacc_verbose_flag = value; } }
262
263                 // Advanced options     
264                 //------------------------------------------------------------------
265                 // TODO: force option to accept number in hex format
266                 [Option("[NOT IMPLEMENTED YET]The base {address} for a library or module (hex)")]
267                 public int baseaddress;
268                 
269                 [Option("[NOT IMPLEMENTED YET]Create bug report {file}")]
270                 public string bugreport;
271                 
272                 // TODO: handle VB.NET [+|-] boolean syntax
273                 [Option("[NOT IMPLEMENTED YET]Delay-sign the assembly using only the public portion of the strong name key")]
274                 public bool delaysign;
275                 
276                 [Option("[NOT IMPLEMENTED YET]Specifies a strong name key {container}")]
277                 public string keycontainer;
278                 
279                 [Option("[NOT IMPLEMENTED YET]Specifies a strong name key {file}")]
280                 public string keyfile;
281
282                 public string[] libpath = null;
283                 
284                 [Option("List of directories to search for metadata references {path-list}:path;...", "libpath")]
285                 public WhatToDoNext setlibpath(string pathlist)
286                 {
287                         libpath = pathlist.Split(';');
288                         return WhatToDoNext.GoAhead;
289                 }
290
291                 [Option(@"Specifies the Class or Module that contains Sub Main.
292                         It can also be a {class} that inherits from System.Windows.Forms.Form.",
293                         'm', "main")]
294                 public string main { set { RootContext.MainClass = value; } }
295
296                 // TODO: handle VB.NET [+|-] boolean syntax
297                 [Option("[IGNORED]Emit compiler output in UTF8 character encoding")]
298                 public bool utf8output;
299
300                 // TODO : response file support
301                 
302                 ArrayList defines = new ArrayList();
303                 ArrayList references = new ArrayList();
304                 ArrayList soft_references = new ArrayList();
305                 string first_source = null;
306                 Target target = Target.Exe;
307                 string target_ext = ".exe";
308                 ArrayList debug_arglist = new ArrayList ();
309                 bool timestamps = false;
310                 Hashtable source_files = new Hashtable ();
311                 bool load_default_config = true;
312
313                 //
314                 // Last time we took the time
315                 //
316                 DateTime last_time;
317                 void ShowTime (string msg)
318                 {
319                         DateTime now = DateTime.Now;
320                         TimeSpan span = now - last_time;
321                         last_time = now;
322
323                         Console.WriteLine (
324                                 "[{0:00}:{1:000}] {2}",
325                                 (int) span.TotalSeconds, span.Milliseconds, msg);
326                 }
327                         
328                 public int LoadAssembly (string assembly, bool soft)
329                 {
330                         Assembly a;
331                         string total_log = "";
332
333                         try 
334                         {
335                                 char[] path_chars = { '/', '\\' };
336
337                                 if (assembly.IndexOfAny (path_chars) != -1)
338                                         a = Assembly.LoadFrom(assembly);
339                                 else
340                                         a = Assembly.Load(assembly);
341                                 TypeManager.AddAssembly (a);
342                                 return 0;
343                         }
344                         catch (FileNotFoundException)
345                         {
346                                 if (libpath != null)
347                                 {
348                                         foreach (string dir in libpath)
349                                         {
350                                                 string full_path = dir + "/" + assembly + ".dll";
351
352                                                 try 
353                                                 {
354                                                         a = Assembly.LoadFrom (full_path);
355                                                         TypeManager.AddAssembly (a);
356                                                         return 0;
357                                                 } 
358                                                 catch (FileNotFoundException ff) 
359                                                 {
360                                                         total_log += ff.FusionLog;
361                                                         continue;
362                                                 }
363                                         }
364                                 }
365                                 if (soft)
366                                         return 0;
367                         }
368                         catch (BadImageFormatException f) 
369                         {
370                                 Error ("// Bad file format while loading assembly");
371                                 Error ("Log: " + f.FusionLog);
372                                 return 1;
373                         } catch (FileLoadException f){
374                                 Error ("File Load Exception: " + assembly);
375                                 Error ("Log: " + f.FusionLog);
376                                 return 1;
377                         } catch (ArgumentNullException){
378                                 Error ("// Argument Null exception ");
379                                 return 1;
380                         }
381                         
382                         Report.Error (6, "Can not find assembly `" + assembly + "'" );
383                         Console.WriteLine ("Log: \n" + total_log);
384
385                         return 0;
386                 }
387
388                 void Error(string message)
389                 {
390                         Console.WriteLine(message);
391                 }
392
393                 /// <summary>
394                 ///   Loads all assemblies referenced on the command line
395                 /// </summary>
396                 public int LoadReferences ()
397                 {
398                         int errors = 0;
399
400                         foreach (string r in references)
401                                 errors += LoadAssembly (r, false);
402
403                         foreach (string r in soft_references)
404                                 errors += LoadAssembly (r, true);
405                         
406                         return errors;
407                 }
408
409                 void SetupDefaultDefines ()
410                 {
411                         defines = new ArrayList ();
412                         defines.Add ("__MonoBASIC__");
413                 }
414
415
416                 //
417                 // Returns the directory where the system assemblies are installed
418                 //
419                 string GetSystemDir ()
420                 {
421                         Assembly [] assemblies = AppDomain.CurrentDomain.GetAssemblies ();
422
423                         foreach (Assembly a in assemblies){
424                                 string codebase = a.CodeBase;
425                                 if (codebase.EndsWith ("corlib.dll")){
426                                         return codebase.Substring (0, codebase.LastIndexOf ("/"));
427                                 }
428                         }
429
430                         Report.Error (-15, "Can not compute my system path");
431                         return "";
432                 }
433
434                 //
435                 // Given a path specification, splits the path from the file/pattern
436                 //
437                 void SplitPathAndPattern (string spec, out string path, out string pattern)
438                 {
439                         int p = spec.LastIndexOf ("/");
440                         if (p != -1){
441                                 //
442                                 // Windows does not like /file.cs, switch that to:
443                                 // "\", "file.cs"
444                                 //
445                                 if (p == 0){
446                                         path = "\\";
447                                         pattern = spec.Substring (1);
448                                 } else {
449                                         path = spec.Substring (0, p);
450                                         pattern = spec.Substring (p + 1);
451                                 }
452                                 return;
453                         }
454
455                         p = spec.LastIndexOf ("\\");
456                         if (p != -1){
457                                 path = spec.Substring (0, p);
458                                 pattern = spec.Substring (p + 1);
459                                 return;
460                         }
461
462                         path = ".";
463                         pattern = spec;
464                 }
465
466                 bool AddFiles (string spec, bool recurse)
467                 {
468                         string path, pattern;
469
470                         SplitPathAndPattern(spec, out path, out pattern);
471                         if (pattern.IndexOf("*") == -1)
472                         {
473                                 AddFile(spec);
474                                 return true;
475                         }
476
477                         string [] files = null;
478                         try {
479                                 files = Directory.GetFiles(path, pattern);
480                         } catch (System.IO.DirectoryNotFoundException) {
481                                 Report.Error (2001, "Source file `" + spec + "' could not be found");
482                                 return false;
483                         } catch (System.IO.IOException){
484                                 Report.Error (2001, "Source file `" + spec + "' could not be found");
485                                 return false;
486                         }
487                         foreach (string f in files)
488                                 AddFile (f);
489
490                         if (!recurse)
491                                 return true;
492                         
493                         string [] dirs = null;
494
495                         try {
496                                 dirs = Directory.GetDirectories(path);
497                         } catch {
498                         }
499                         
500                         foreach (string d in dirs) {
501                                         
502                                 // Don't include path in this string, as each
503                                 // directory entry already does
504                                 AddFiles (d + "/" + pattern, true);
505                         }
506
507                         return true;
508                 }
509
510                 void DefineDefaultConfig ()
511                 {
512                         //
513                         // For now the "default config" is harcoded into the compiler
514                         // we can move this outside later
515                         //
516                         string [] default_config = 
517                         {
518                                 "System",
519                                 "System.Data",
520                                 "System.Xml",
521                                 "Microsoft.VisualBasic" , 
522 #if EXTRA_DEFAULT_REFS
523                                 //
524                                 // Is it worth pre-loading all this stuff?
525                                 //
526                                 "Accessibility",
527                                 "System.Configuration.Install",
528                                 "System.Design",
529                                 "System.DirectoryServices",
530                                 "System.Drawing.Design",
531                                 "System.Drawing",
532                                 "System.EnterpriseServices",
533                                 "System.Management",
534                                 "System.Messaging",
535                                 "System.Runtime.Remoting",
536                                 "System.Runtime.Serialization.Formatters.Soap",
537                                 "System.Security",
538                                 "System.ServiceProcess",
539                                 "System.Web",
540                                 "System.Web.RegularExpressions",
541                                 "System.Web.Services" ,
542                                 "System.Windows.Forms"
543 #endif
544                         };
545                         
546                         foreach (string def in default_config)
547                                 soft_references.Add(def);
548                 }
549
550                 [ArgumentProcessor]
551                 public void AddFile(string fileName)
552                 {
553                         string f = fileName;
554                         if (first_source == null)
555                                 first_source = f;
556
557                         if (source_files.Contains(f))
558                                 Report.Error(1516, "Source file '" + f + "' specified multiple times");
559                         else
560                                 source_files.Add(f, f);
561                 }
562
563                 void ProcessSourceFile(string filename)
564                 {
565                         if (tokenize)
566                                 GenericParser.Tokenize(filename);
567                         else
568                                 GenericParser.Parse(filename);
569                 }
570
571                 string outputFile_Name = null;
572
573                 string outputFileName
574                 {
575                         get 
576                         {
577                                 if (outputFile_Name == null)
578                                 {
579                                         if (OutputFileName == null)
580                                         {
581                                                 int pos = first_source.LastIndexOf(".");
582
583                                                 if (pos > 0)
584                                                         OutputFileName = first_source.Substring(0, pos);
585                                                 else
586                                                         OutputFileName = first_source;
587                                         }
588                                         string bname = CodeGen.Basename(OutputFileName);
589                                         if (bname.IndexOf(".") == -1)
590                                                 OutputFileName +=  target_ext;
591                                         outputFile_Name = OutputFileName;
592                                 }
593                                 return outputFile_Name;
594                         }
595                 }
596
597                 bool ParseAll() // Phase 1
598                 {
599                         if (first_source == null)
600                         {
601                                 Report.Error(2008, "No files to compile were specified");
602                                 return false;
603                         }
604
605                         foreach(string filename in source_files.Values)
606                                 ProcessSourceFile(filename);
607
608                         if (tokenize || parse_only || (Report.Errors > 0))
609                                 return false;           
610
611                         return true; // everything went well go ahead
612                 }
613
614                 void InitializeDebuggingSupport()
615                 {
616                         string[] debug_args = new string [debug_arglist.Count];
617                         debug_arglist.CopyTo(debug_args);
618                         CodeGen.Init(outputFileName, outputFileName, want_debugging_support, debug_args);
619                         TypeManager.AddModule(CodeGen.ModuleBuilder);
620                 }
621
622                 public bool ResolveAllTypes() // Phase 2
623                 {
624                         // Load Core Library for default compilation
625                         if (RootContext.StdLib)
626                                 references.Insert(0, "mscorlib");
627
628                         if (load_default_config)
629                                 DefineDefaultConfig();
630
631                         if (timestamps)
632                                 ShowTime("Loading references");
633
634                         // Load assemblies required
635                         if (LoadReferences() > 0)
636                         {
637                                 Error ("Could not load one or more assemblies");
638                                 return false;
639                         }
640
641                         if (timestamps)
642                                 ShowTime("References loaded");
643
644                         InitializeDebuggingSupport();
645
646                         //
647                         // Before emitting, we need to get the core
648                         // types emitted from the user defined types
649                         // or from the system ones.
650                         //
651                         if (timestamps)
652                                 ShowTime ("Initializing Core Types");
653
654                         if (!RootContext.StdLib)
655                                 RootContext.ResolveCore ();
656                         if (Report.Errors > 0)
657                                 return false;
658                         
659                         TypeManager.InitCoreTypes();
660                         if (Report.Errors > 0)
661                                 return false;
662
663                         if (timestamps)
664                                 ShowTime ("   Core Types done");
665
666                         if (timestamps)
667                                 ShowTime ("Resolving tree");
668
669                         // The second pass of the compiler
670                         RootContext.ResolveTree ();
671                         if (Report.Errors > 0)
672                                 return false;
673                         
674                         if (timestamps)
675                                 ShowTime ("Populate tree");
676
677                         if (!RootContext.StdLib)
678                                 RootContext.BootCorlib_PopulateCoreTypes();
679                         if (Report.Errors > 0)
680                                 return false;
681
682                         RootContext.PopulateTypes();
683                         if (Report.Errors > 0)
684                                 return false;
685                         
686                         TypeManager.InitCodeHelpers();
687                         if (Report.Errors > 0)
688                                 return false;
689
690                         return true;
691                 }
692                 
693                 bool IsSWFApp()
694                 {
695                         bool hasSWF = false, isForm = false;
696                         string mainclass = GetFQMainClass();
697                         
698                         foreach (string r in references) {
699                                 if (r.IndexOf ("System.Windows.Forms") >= 0) {
700                                         hasSWF = true;
701                                         break;  
702                                 }       
703                         }       
704                         if (mainclass != ".") {
705                                 Type t = TypeManager.LookupType(mainclass);
706                                 if (t != null) 
707                                         isForm = t.IsSubclassOf (TypeManager.LookupType("System.Windows.Forms.Form"));
708                         }
709                         return (hasSWF && isForm);
710                 }
711                 
712                 string GetFQMainClass()
713                 {       
714                         if (RootContext.RootNamespace != "")
715                                 return RootContext.RootNamespace + "." + RootContext.MainClass;
716                         else
717                                 return RootContext.MainClass;                   
718                 }
719                 
720                 void FixEntryPoint()
721                 {
722                         if (target == Target.Exe || target == Target.WinExe)
723                         {
724                                 MethodInfo ep = RootContext.EntryPoint;
725                         
726                                 if (ep == null)
727                                 {
728                                         // If we don't have a valid entry point yet
729                                         // AND if System.Windows.Forms is included
730                                         // among the dependencies, we have to build
731                                         // a new entry point on-the-fly. Otherwise we
732                                         // won't be able to compile SWF code out of the box.
733
734                                         if (IsSWFApp()) 
735                                         {                                                                                               
736                                                 Type t = TypeManager.LookupType(GetFQMainClass());
737                                                 if (t != null) 
738                                                 {                                                       
739                                                         TypeBuilder tb = t as TypeBuilder;
740                                                         MethodBuilder mb = tb.DefineMethod ("Main", MethodAttributes.Public | MethodAttributes.Static, CallingConventions.Standard, 
741                                                                 typeof(void), new Type[0]);
742
743                                                         Type SWFA = TypeManager.LookupType("System.Windows.Forms.Application");
744                                                         Type SWFF = TypeManager.LookupType("System.Windows.Forms.Form");
745                                                         Type[] args = new Type[1];
746                                                         args[0] = SWFF;
747                                                         MethodInfo mi = SWFA.GetMethod("Run", args);
748                                                         ILGenerator ig = mb.GetILGenerator();
749                                                         ConstructorInfo ci = TypeManager.GetConstructor (TypeManager.LookupType(t.FullName), new Type[0]);
750                                                         
751                                                         ig.Emit (OpCodes.Newobj, ci);
752                                                         ig.Emit (OpCodes.Call, mi);
753                                                         ig.Emit (OpCodes.Ret);
754
755                                                         RootContext.EntryPoint = mb as MethodInfo;
756                                                 }
757                                         }
758                                 }
759                         }
760                 }
761
762                 bool GenerateAssembly()
763                 {
764                         //
765                         // The code generator
766                         //
767                         if (timestamps)
768                                 ShowTime ("Emitting code");
769                         
770                         
771
772                         RootContext.EmitCode();
773                         FixEntryPoint();
774                         if (Report.Errors > 0)
775                                 return false;
776
777                         if (timestamps)
778                                 ShowTime ("   done");
779
780
781                         if (timestamps)
782                                 ShowTime ("Closing types");
783
784                         RootContext.CloseTypes ();
785                         if (Report.Errors > 0)
786                                 return false;
787
788                         if (timestamps)
789                                 ShowTime ("   done");
790
791                         PEFileKinds k = PEFileKinds.ConsoleApplication;
792                                                         
793                         if (target == Target.Library || target == Target.Module)
794                                 k = PEFileKinds.Dll;
795                         else if (target == Target.Exe)
796                                 k = PEFileKinds.ConsoleApplication;
797                         else if (target == Target.WinExe)
798                                 k = PEFileKinds.WindowApplication;
799                         
800                         if (target == Target.Exe || target == Target.WinExe)
801                         {
802                                 MethodInfo ep = RootContext.EntryPoint;
803                         
804                                 if (ep == null)
805                                 {
806                                         Report.Error (5001, "Program " + outputFileName +
807                                                 " does not have an entry point defined");
808                                         return false;
809                                 }
810                                                         
811                                 CodeGen.AssemblyBuilder.SetEntryPoint (ep, k);
812                         }
813
814                         // Add the resources
815                         if (EmbeddedResources != null)
816                                 foreach (string file in EmbeddedResources)
817                                         CodeGen.AssemblyBuilder.AddResourceFile (file, file);
818                         
819                         CodeGen.Save(outputFileName);
820
821                         if (timestamps)
822                                 ShowTime ("Saved output");
823
824                         
825                         if (want_debugging_support) 
826                         {
827                                 CodeGen.SaveSymbols ();
828                                 if (timestamps)
829                                         ShowTime ("Saved symbols");
830                         }
831
832                         return true;
833                 }
834
835                 public void CompileAll()
836                 {
837 /* 
838                     VB.NET expects the default namespace to be "" (empty string)                
839                     
840                     if (RootContext.RootNamespace == "")
841                     {
842                       RootContext.RootNamespace = System.IO.Path.GetFileNameWithoutExtension(outputFileName);
843                     }
844 */
845                         if (!ParseAll()) // Phase 1
846                                 return;
847
848                         if (!ResolveAllTypes()) // Phase 2
849                                 return;
850
851                         GenerateAssembly(); // Phase 3 
852                 }
853
854                 /// <summary>
855                 ///    Parses the arguments, and calls the compilation process.
856                 /// </summary>
857                 int MainDriver(string [] args)
858                 {
859                         SetupDefaultDefines();  
860
861                         ProcessArgs(args);
862                         
863                         if (first_source == null)
864                         {
865                                 if (!quiet) 
866                                         DoHelp();
867                                 return 2;
868                         }
869
870                         CompileAll();
871
872                         return Report.ProcessResults(quiet);
873                 }
874
875                 public static int Main (string[] args)
876                 {
877                         Driver Exec = new Driver();
878                         
879                         Report.Stacktrace = false;
880
881                         return Exec.MainDriver(args);
882                 }
883
884         }
885 }