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