BOO-503: Some love for compiler-generated callable definition names so that they...
[boo.git] / src / Boo.Lang.Compiler / CompilerPipeline.cs
blob12001ac4ae443ac207f4af7de2b3df0726123264
1 #region license
2 // Copyright (c) 2004, Rodrigo B. de Oliveira (rbo@acm.org)
3 // All rights reserved.
4 //
5 // Redistribution and use in source and binary forms, with or without modification,
6 // are permitted provided that the following conditions are met:
7 //
8 // * Redistributions of source code must retain the above copyright notice,
9 // this list of conditions and the following disclaimer.
10 // * Redistributions in binary form must reproduce the above copyright notice,
11 // this list of conditions and the following disclaimer in the documentation
12 // and/or other materials provided with the distribution.
13 // * Neither the name of Rodrigo B. de Oliveira nor the names of its
14 // contributors may be used to endorse or promote products derived from this
15 // software without specific prior written permission.
17 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
18 // ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
19 // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
20 // DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
21 // FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 // DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
23 // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
24 // CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
25 // OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 // THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 #endregion
29 namespace Boo.Lang.Compiler
31 using System;
32 using System.Reflection;
34 public class CompilerStepEventArgs : EventArgs
36 public CompilerContext Context;
37 public ICompilerStep Step;
39 public CompilerStepEventArgs(CompilerContext context, ICompilerStep step)
41 this.Context = context;
42 this.Step = step;
46 public delegate void CompilerStepEventHandler(object sender, CompilerStepEventArgs args);
48 /// <summary>
49 /// A ordered set of <see cref="ICompilerStep"/> implementations
50 /// that should be executed in sequence.
51 /// </summary>
52 public class CompilerPipeline
54 public event CompilerStepEventHandler BeforeStep;
56 public event CompilerStepEventHandler AfterStep;
58 public static CompilerPipeline GetPipeline(string name)
60 if (null == name) throw new ArgumentNullException("name");
61 switch (name)
63 case "parse": return new Pipelines.Parse();
64 case "compile": return new Pipelines.Compile();
65 case "run": return new Pipelines.Run();
66 case "default": return new Pipelines.CompileToFile();
67 case "verify": return new Pipelines.CompileToFileAndVerify();
68 case "roundtrip": return new Pipelines.ParseAndPrint();
69 case "boo": return new Pipelines.CompileToBoo();
70 case "ast": return new Pipelines.ParseAndPrintAst();
71 case "xml": return new Pipelines.ParseAndPrintXml();
72 case "checkforerrors": return new Pipelines.CheckForErrors();
73 case "dumpreferences":
75 CompilerPipeline pipeline = new Pipelines.CompileToBoo();
76 pipeline.Add(new Boo.Lang.Compiler.Steps.DumpReferences());
77 return pipeline;
80 return LoadCustomPipeline(name);
83 private static CompilerPipeline LoadCustomPipeline(string typeName)
85 if (typeName.IndexOf(',') < 0)
86 throw new ArgumentException(Boo.Lang.ResourceManager.Format("BooC.InvalidPipeline", typeName));
87 return (CompilerPipeline)Activator.CreateInstance(FindPipelineType(typeName));
90 private static System.Type FindPipelineType(string typeName)
92 Assembly loaded = FindLoadedAssembly(AssemblySimpleNameFromFullTypeName(typeName));
93 if (null != loaded) return loaded.GetType(SimpleTypeNameFromFullTypeName(typeName));
94 return Type.GetType(typeName, true);
97 private static string SimpleTypeNameFromFullTypeName(string name)
99 return name.Split(',')[0].Trim();
102 private static string AssemblySimpleNameFromFullTypeName(string name)
104 return name.Split(',')[1].Trim();
107 private static Assembly FindLoadedAssembly(string assemblyName)
109 foreach (Assembly loaded in AppDomain.CurrentDomain.GetAssemblies())
111 if (loaded.GetName().Name == assemblyName) return loaded;
113 return null;
116 protected Boo.Lang.List _items;
118 protected bool _breakOnErrors;
120 public CompilerPipeline()
122 _items = new Boo.Lang.List();
123 _breakOnErrors = true;
126 public bool BreakOnErrors
130 return _breakOnErrors;
135 _breakOnErrors = value;
139 public CompilerPipeline Add(ICompilerStep step)
141 if (null == step)
143 throw new ArgumentNullException("step");
146 _items.Add(step);
147 return this;
150 public CompilerPipeline RemoveAt(int index)
152 _items.RemoveAt(index);
153 return this;
156 public CompilerPipeline Insert(int index, ICompilerStep step)
158 if (null == step)
160 throw new ArgumentNullException("step");
163 _items.Insert(index, step);
164 return this;
167 public CompilerPipeline InsertAfter(Type stepExactType, ICompilerStep step)
169 return Insert(Find(stepExactType)+1, step);
172 public CompilerPipeline InsertBefore(Type stepExactType, ICompilerStep step)
174 return Insert(Find(stepExactType)-1, step);
177 public CompilerPipeline Replace(Type stepExactType, ICompilerStep step)
179 if (null == step)
181 throw new ArgumentNullException("step");
184 int index = Find(stepExactType);
185 if (-1 == index)
187 throw new ArgumentException("stepExactType");
189 _items[index] = step;
190 return this;
193 public int Find(Type stepExactType)
195 if (null == stepExactType)
197 throw new ArgumentNullException("stepExactType");
199 for (int i=0; i<_items.Count; ++i)
201 if (_items[i].GetType() == stepExactType)
203 return i;
206 return -1;
209 public ICompilerStep Get(Type stepExactType)
211 int index = Find(stepExactType);
212 if (-1 == index) return null;
213 return (ICompilerStep)_items[index];
216 public int Count
220 return _items.Count;
224 public ICompilerStep this[int index]
228 return (ICompilerStep)_items[index];
233 if (null == value)
235 throw new ArgumentNullException("value");
237 _items[index] = value;
241 virtual public void Clear()
243 _items.Clear();
246 virtual protected void OnBeforeStep(CompilerContext context, ICompilerStep step)
248 if (null != BeforeStep)
250 BeforeStep(this, new CompilerStepEventArgs(context, step));
254 virtual protected void OnAfterStep(CompilerContext context, ICompilerStep step)
256 if (null != AfterStep)
258 AfterStep(this, new CompilerStepEventArgs(context, step));
262 virtual protected void Prepare(CompilerContext context)
266 virtual public void Run(CompilerContext context)
268 Prepare(context);
270 foreach (ICompilerStep step in _items)
272 RunStep(context, step);
274 if (_breakOnErrors && context.Errors.Count > 0)
276 break;
280 foreach (ICompilerStep step in _items)
282 step.Dispose();
286 protected void RunStep(CompilerContext context, ICompilerStep step)
288 OnBeforeStep(context, step);
290 step.Initialize(context);
293 step.Run();
295 catch (Boo.Lang.Compiler.CompilerError error)
297 context.Errors.Add(error);
299 catch (System.Exception x)
301 context.Errors.Add(CompilerErrorFactory.StepExecutionError(x, step));
303 finally
305 OnAfterStep(context, step);