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