2 // System.CodeDom.Compiler.CodeCompiler.cs
5 // Jackson Harper (Jackson@LatitudeGeo.com)
6 // Andreas Nahr (ClassDevelopment@A-SoftTech.com)
8 // (C) 2002 Jackson Harper, All rights reserved
9 // (C) 2003 Andreas Nahr
13 // Permission is hereby granted, free of charge, to any person obtaining
14 // a copy of this software and associated documentation files (the
15 // "Software"), to deal in the Software without restriction, including
16 // without limitation the rights to use, copy, modify, merge, publish,
17 // distribute, sublicense, and/or sell copies of the Software, and to
18 // permit persons to whom the Software is furnished to do so, subject to
19 // the following conditions:
21 // The above copyright notice and this permission notice shall be
22 // included in all copies or substantial portions of the Software.
24 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
25 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
26 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
27 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
28 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
29 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
30 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
36 using System
.Reflection
;
37 using System
.Collections
;
38 using System
.Collections
.Specialized
;
39 using System
.Diagnostics
;
41 namespace System
.CodeDom
.Compiler
{
43 public abstract class CodeCompiler
: CodeGenerator
, ICodeCompiler
46 protected CodeCompiler ()
50 protected abstract string CompilerName
{
54 protected abstract string FileExtension
{
58 protected abstract string CmdArgsFromParameters (CompilerParameters options
);
60 protected virtual CompilerResults
FromDom (CompilerParameters options
, CodeCompileUnit e
)
62 return FromDomBatch (options
, new CodeCompileUnit
[]{e}
);
65 protected virtual CompilerResults
FromDomBatch (CompilerParameters options
, CodeCompileUnit
[] ea
)
67 string[] fileNames
= new string[ea
.Length
];
70 options
= new CompilerParameters ();
72 StringCollection assemblies
= options
.ReferencedAssemblies
;
74 foreach (CodeCompileUnit e
in ea
) {
75 fileNames
[i
] = Path
.ChangeExtension (Path
.GetTempFileName(), FileExtension
);
76 FileStream f
= new FileStream (fileNames
[i
], FileMode
.OpenOrCreate
);
77 StreamWriter s
= new StreamWriter (f
);
78 if (e
.ReferencedAssemblies
!= null) {
79 foreach (string str
in e
.ReferencedAssemblies
) {
80 if (!assemblies
.Contains (str
))
85 ((ICodeGenerator
)this).GenerateCodeFromCompileUnit (e
, s
, new CodeGeneratorOptions());
90 return Compile (options
, fileNames
, false);
93 protected virtual CompilerResults
FromFile (CompilerParameters options
, string fileName
)
95 return FromFileBatch (options
, new string[] {fileName}
);
98 protected virtual CompilerResults
FromFileBatch (CompilerParameters options
, string[] fileNames
)
100 return Compile (options
, fileNames
, true);
103 protected virtual CompilerResults
FromSource (CompilerParameters options
, string source
)
105 return FromSourceBatch(options
, new string[]{source}
);
108 protected virtual CompilerResults
FromSourceBatch (CompilerParameters options
, string[] sources
)
110 string[] fileNames
= new string[sources
.Length
];
112 foreach (string source
in sources
) {
113 fileNames
[i
] = Path
.ChangeExtension (Path
.GetTempFileName(), FileExtension
);
114 FileStream f
= new FileStream (fileNames
[i
], FileMode
.OpenOrCreate
);
115 StreamWriter s
= new StreamWriter (f
);
121 return Compile (options
, fileNames
, false);
124 private CompilerResults
Compile (CompilerParameters options
, string[] fileNames
, bool keepFiles
)
127 throw new ArgumentNullException ("options");
128 if (null == fileNames
)
129 throw new ArgumentNullException ("fileNames");
131 options
.TempFiles
= new TempFileCollection ();
132 foreach (string file
in fileNames
)
134 options
.TempFiles
.AddFile (file
, keepFiles
);
136 options
.TempFiles
.KeepFiles
= keepFiles
;
138 CompilerResults results
= new CompilerResults (new TempFileCollection());
140 // FIXME this should probably be done by the System.CodeDom.Compiler.Executor class
141 Process compiler
= new Process();
143 string compiler_output
;
144 string[] compiler_output_lines
;
145 compiler
.StartInfo
.FileName
= CompilerName
;
146 compiler
.StartInfo
.Arguments
= CmdArgsFromParameters (options
);
147 compiler
.StartInfo
.CreateNoWindow
= true;
148 compiler
.StartInfo
.UseShellExecute
= false;
149 compiler
.StartInfo
.RedirectStandardOutput
= true;
152 compiler_output
= compiler
.StandardOutput
.ReadToEnd();
153 compiler
.WaitForExit();
156 results
.NativeCompilerReturnValue
= compiler
.ExitCode
;
162 compiler_output_lines
= compiler_output
.Split(
163 System
.Environment
.NewLine
.ToCharArray());
164 foreach (string error_line
in compiler_output_lines
)
165 ProcessCompilerOutputLine (results
, error_line
);
166 if (results
.Errors
.Count
== 0)
167 results
.CompiledAssembly
= Assembly
.LoadFrom (options
.OutputAssembly
);
169 results
.CompiledAssembly
= null;
174 protected virtual string GetResponseFileCmdArgs (CompilerParameters options
, string cmdArgs
)
176 // FIXME I'm not sure what this function should do...
177 throw new NotImplementedException ();
180 CompilerResults ICodeCompiler
.CompileAssemblyFromDom (CompilerParameters options
, CodeCompileUnit e
)
182 return FromDom (options
, e
);
185 CompilerResults ICodeCompiler
.CompileAssemblyFromDomBatch (CompilerParameters options
, CodeCompileUnit
[] ea
)
187 return FromDomBatch (options
, ea
);
190 CompilerResults ICodeCompiler
.CompileAssemblyFromFile (CompilerParameters options
, string fileName
)
192 return FromFile (options
, fileName
);
195 CompilerResults ICodeCompiler
.CompileAssemblyFromFileBatch (CompilerParameters options
, string[] fileNames
)
197 return FromFileBatch (options
, fileNames
);
201 CompilerResults ICodeCompiler
.CompileAssemblyFromSource (CompilerParameters options
, string source
)
203 return FromSource (options
, source
);
207 CompilerResults ICodeCompiler
.CompileAssemblyFromSourceBatch (CompilerParameters options
, string[] sources
)
209 return FromSourceBatch (options
, sources
);
212 protected static string JoinStringArray (string[] sa
, string separator
)
214 StringBuilder sb
= new StringBuilder ();
216 foreach (string s
in sa
)
217 sb
.Append (s
+ separator
);
218 return sb
.ToString ();
221 protected abstract void ProcessCompilerOutputLine (CompilerResults results
, string line
);