typo (spotted by tamara)
[boo.git] / src / Boo.Lang.Compiler / CompilerParameters.cs
blob3b51dbe987d962a58e1eda3a38a4e611b17c6dda
1 #region license
3 // Copyright (c) 2004, Rodrigo B. de Oliveira (rbo@acm.org)
4 // All rights reserved.
5 //
6 // Redistribution and use in source and binary forms, with or without modification,
7 // are permitted provided that the following conditions are met:
8 //
9 // * Redistributions of source code must retain the above copyright notice,
10 // this list of conditions and the following disclaimer.
11 // * Redistributions in binary form must reproduce the above copyright notice,
12 // this list of conditions and the following disclaimer in the documentation
13 // and/or other materials provided with the distribution.
14 // * Neither the name of Rodrigo B. de Oliveira nor the names of its
15 // contributors may be used to endorse or promote products derived from this
16 // software without specific prior written permission.
17 //
18 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
19 // ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
20 // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21 // DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
22 // FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23 // DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
24 // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
25 // CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
26 // OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27 // THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 #endregion
31 using System;
32 using System.Collections;
33 using System.Diagnostics;
34 using System.IO;
35 using System.Reflection;
36 using System.Text.RegularExpressions;
38 namespace Boo.Lang.Compiler
40 /// <summary>
41 /// Compiler parameters.
42 /// </summary>
43 public class CompilerParameters
45 private static List _validFileExtensions = new List(new string[] {".dll", ".exe"});
47 private TextWriter _outputWriter;
49 private CompilerPipeline _pipeline;
51 private CompilerInputCollection _input;
53 private CompilerResourceCollection _resources;
55 private AssemblyCollection _assemblyReferences;
57 private int _maxAttributeSteps;
59 private string _outputAssembly;
61 private CompilerOutputType _outputType;
63 private bool _debug;
65 private bool _ducky;
67 private bool _checked;
69 private bool _generateInMemory;
71 private bool _StdLib;
73 private string _keyFile;
75 private string _keyContainer;
77 private bool _delaySign;
79 private ArrayList _libpaths;
81 private string _systemDir;
83 private Assembly _booAssembly;
85 private bool _whiteSpaceAgnostic;
87 public readonly TraceSwitch TraceSwitch = new TraceSwitch("booc", "boo compiler");
89 public CompilerParameters()
90 : this(true)
94 public CompilerParameters(bool loadDefaultReferences)
96 _libpaths = new ArrayList();
97 _systemDir = GetSystemDir();
98 _libpaths.Add(_systemDir);
99 _libpaths.Add(Directory.GetCurrentDirectory());
101 _pipeline = null;
102 _input = new CompilerInputCollection();
103 _resources = new CompilerResourceCollection();
104 _assemblyReferences = new AssemblyCollection();
106 _maxAttributeSteps = 2;
107 _outputAssembly = string.Empty;
108 _outputType = CompilerOutputType.ConsoleApplication;
109 _outputWriter = System.Console.Out;
110 _debug = true;
111 _checked = true;
112 _generateInMemory = true;
113 _StdLib = true;
115 _delaySign = false;
117 if (loadDefaultReferences) LoadDefaultReferences();
120 public void LoadDefaultReferences()
122 //mscorlib
123 _assemblyReferences.Add(
124 LoadAssembly("mscorlib", true)
126 //System
127 _assemblyReferences.Add(
128 LoadAssembly("System", true)
130 //boo.lang.dll
131 _booAssembly = typeof(Boo.Lang.Builtins).Assembly;
132 _assemblyReferences.Add(_booAssembly);
133 //boo.lang.compiler.dll
134 _assemblyReferences.Add(GetType().Assembly);
136 if (TraceSwitch.TraceInfo)
138 Trace.WriteLine("BOO LANG DLL: " + _booAssembly.Location);
139 Trace.WriteLine("BOO COMPILER DLL: " + GetType().Assembly.Location);
143 public Assembly BooAssembly
145 get { return _booAssembly; }
148 if (value != null)
150 (_assemblyReferences as IList).Remove(_booAssembly);
151 _booAssembly = value;
152 _assemblyReferences.Add(value);
157 public Assembly FindAssembly(string name)
159 return _assemblyReferences.Find(name);
162 public void AddAssembly(Assembly asm)
164 if (asm != null)
166 _assemblyReferences.Add(asm);
170 public Assembly LoadAssembly(string assembly)
172 return LoadAssembly(assembly, true);
175 public Assembly LoadAssembly(string assembly, bool throwOnError)
177 if (TraceSwitch.TraceInfo)
179 Trace.WriteLine("ATTEMPTING LOADASSEMBLY: " + assembly);
182 Assembly a = null;
185 if (assembly.IndexOfAny(new char[] {'/', '\\'}) != -1)
187 //nant passes full path to gac dlls, which compiler doesn't like:
188 //if (assembly.ToLower().StartsWith(_systemDir.ToLower()))
190 //return LoadAssemblyFromGac(Path.GetFileName(assembly));
192 //else //load using path
194 a = Assembly.LoadFrom(assembly);
197 else
199 a = LoadAssemblyFromGac(assembly);
202 catch (FileNotFoundException /*ignored*/)
204 return LoadAssemblyFromLibPaths(assembly, throwOnError);
206 catch (BadImageFormatException e)
208 if (throwOnError)
210 throw new ApplicationException(Boo.Lang.ResourceManager.Format(
211 "BooC.BadFormat",
212 e.FusionLog), e);
215 catch (FileLoadException e)
217 if (throwOnError)
219 throw new ApplicationException(Boo.Lang.ResourceManager.Format(
220 "BooC.UnableToLoadAssembly",
221 e.FusionLog), e);
224 catch (ArgumentNullException e)
226 if (throwOnError)
228 throw new ApplicationException(Boo.Lang.ResourceManager.Format(
229 "BooC.NullAssembly"), e);
232 if (a == null)
234 return LoadAssemblyFromLibPaths(assembly, throwOnError);
236 return a;
239 private Assembly LoadAssemblyFromLibPaths(string assembly, bool throwOnError)
241 Assembly a = null;
242 string fullLog = "";
243 foreach (string dir in _libpaths)
245 string full_path = Path.Combine(dir, assembly);
246 FileInfo file = new FileInfo(full_path);
247 if (!_validFileExtensions.Contains(file.Extension.ToLower()))
248 full_path += ".dll";
252 a = Assembly.LoadFrom(full_path);
253 if (a != null)
255 return a;
258 catch (FileNotFoundException ff)
260 fullLog += ff.FusionLog;
261 continue;
264 if (throwOnError)
266 throw new ApplicationException(Boo.Lang.ResourceManager.Format(
267 "BooC.CannotFindAssembly",
268 assembly));
269 //assembly, total_log)); //total_log contains the fusion log
271 return a;
274 private Assembly LoadAssemblyFromGac(string assemblyName)
276 assemblyName = NormalizeAssemblyName(assemblyName);
277 Assembly assembly = Assembly.LoadWithPartialName(assemblyName);
278 if (assembly != null) return assembly;
279 return Assembly.Load(assemblyName);
282 private static string NormalizeAssemblyName(string assembly)
284 if (assembly.EndsWith(".dll") || assembly.EndsWith(".exe"))
286 assembly = assembly.Substring(0, assembly.Length - 4);
288 return assembly;
291 public void LoadReferencesFromPackage(string package)
293 string[] libs = Regex.Split(pkgconfig(package), @"\-r\:", RegexOptions.CultureInvariant);
294 foreach (string r in libs)
296 string reference = r.Trim();
297 if (reference.Length == 0) continue;
298 Trace.WriteLine("LOADING REFERENCE FROM PKGCONFIG '" + package + "' : " + reference);
299 References.Add(LoadAssembly(reference));
303 private static string pkgconfig(string package)
305 #if NO_SYSTEM_DLL
306 throw new System.NotSupportedException();
307 #else
308 Process process;
311 process = Builtins.shellp("pkg-config", string.Format("--libs {0}", package));
313 catch (Exception e)
315 throw new ApplicationException(Boo.Lang.ResourceManager.GetString("BooC.PkgConfigNotFound"), e);
317 process.WaitForExit();
318 if (process.ExitCode != 0)
320 throw new ApplicationException(
321 Boo.Lang.ResourceManager.Format("BooC.PkgConfigReportedErrors", process.StandardError.ReadToEnd()));
323 return process.StandardOutput.ReadToEnd();
324 #endif
327 private string GetSystemDir()
329 return Path.GetDirectoryName(typeof(string).Assembly.Location);
332 /// <summary>
333 /// Max number of steps for the resolution of AST attributes.
334 /// </summary>
335 public int MaxAttributeSteps
337 get { return _maxAttributeSteps; }
339 set { _maxAttributeSteps = value; }
342 public CompilerInputCollection Input
344 get { return _input; }
347 public ArrayList LibPaths
349 get { return _libpaths; }
352 public CompilerResourceCollection Resources
354 get { return _resources; }
357 public AssemblyCollection References
359 get { return _assemblyReferences; }
363 if (null == value) throw new ArgumentNullException("References");
364 _assemblyReferences = value;
368 /// <summary>
369 /// The compilation pipeline.
370 /// </summary>
371 public CompilerPipeline Pipeline
373 get { return _pipeline; }
375 set { _pipeline = value; }
378 /// <summary>
379 /// The name (full or partial) for the file
380 /// that should receive the resulting assembly.
381 /// </summary>
382 public string OutputAssembly
384 get { return _outputAssembly; }
388 if (string.IsNullOrEmpty(value)) throw new ArgumentNullException("OutputAssembly");
389 _outputAssembly = value;
393 /// <summary>
394 /// Type and execution subsystem for the generated portable
395 /// executable file.
396 /// </summary>
397 public CompilerOutputType OutputType
399 get { return _outputType; }
401 set { _outputType = value; }
404 public bool GenerateInMemory
406 get { return _generateInMemory; }
408 set { _generateInMemory = value; }
411 public bool StdLib
413 get { return _StdLib; }
415 set { _StdLib = value; }
418 public TextWriter OutputWriter
420 get { return _outputWriter; }
424 if (null == value)
426 throw new ArgumentNullException("OutputWriter");
428 _outputWriter = value;
432 public bool Debug
434 get { return _debug; }
436 set { _debug = value; }
439 /// <summary>
440 /// Use duck instead of object as the most generic type.
441 /// </summary>
442 public bool Ducky
444 get { return _ducky; }
446 set { _ducky = value; }
449 public bool Checked
451 get { return _checked; }
453 set { _checked = value; }
456 public string KeyFile
458 get { return _keyFile; }
460 set { _keyFile = value; }
463 public string KeyContainer
465 get { return _keyContainer; }
467 set { _keyContainer = value; }
470 public bool DelaySign
472 get { return _delaySign; }
474 set { _delaySign = value; }
477 public bool WhiteSpaceAgnostic
481 return _whiteSpaceAgnostic;
485 _whiteSpaceAgnostic = value;