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
10 // Copyright (C) 2005 Novell, Inc (http://www.novell.com)
12 // Permission is hereby granted, free of charge, to any person obtaining
13 // a copy of this software and associated documentation files (the
14 // "Software"), to deal in the Software without restriction, including
15 // without limitation the rights to use, copy, modify, merge, publish,
16 // distribute, sublicense, and/or sell copies of the Software, and to
17 // permit persons to whom the Software is furnished to do so, subject to
18 // the following conditions:
20 // The above copyright notice and this permission notice shall be
21 // included in all copies or substantial portions of the Software.
23 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
24 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
25 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
26 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
27 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
28 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
29 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
34 using System
.Reflection
;
35 using System
.Collections
;
36 using System
.Collections
.Specialized
;
37 using System
.Diagnostics
;
38 using System
.Security
.Permissions
;
40 namespace System
.CodeDom
.Compiler
{
42 public abstract class CodeCompiler
: CodeGenerator
, ICodeCompiler
45 protected CodeCompiler ()
49 protected abstract string CompilerName
{
53 protected abstract string FileExtension
{
57 protected abstract string CmdArgsFromParameters (CompilerParameters options
);
59 protected virtual CompilerResults
FromDom (CompilerParameters options
, CodeCompileUnit e
)
61 return FromDomBatch (options
, new CodeCompileUnit
[]{e}
);
64 protected virtual CompilerResults
FromDomBatch (CompilerParameters options
, CodeCompileUnit
[] ea
)
66 string[] fileNames
= new string[ea
.Length
];
69 options
= new CompilerParameters ();
71 StringCollection assemblies
= options
.ReferencedAssemblies
;
73 foreach (CodeCompileUnit e
in ea
) {
74 fileNames
[i
] = Path
.ChangeExtension (Path
.GetTempFileName(), FileExtension
);
75 FileStream f
= new FileStream (fileNames
[i
], FileMode
.OpenOrCreate
);
76 StreamWriter s
= new StreamWriter (f
);
77 if (e
.ReferencedAssemblies
!= null) {
78 foreach (string str
in e
.ReferencedAssemblies
) {
79 if (!assemblies
.Contains (str
))
84 ((ICodeGenerator
)this).GenerateCodeFromCompileUnit (e
, s
, new CodeGeneratorOptions());
89 return Compile (options
, fileNames
, false);
92 protected virtual CompilerResults
FromFile (CompilerParameters options
, string fileName
)
94 return FromFileBatch (options
, new string[] {fileName}
);
97 protected virtual CompilerResults
FromFileBatch (CompilerParameters options
, string[] fileNames
)
99 return Compile (options
, fileNames
, true);
102 protected virtual CompilerResults
FromSource (CompilerParameters options
, string source
)
104 return FromSourceBatch(options
, new string[]{source}
);
107 protected virtual CompilerResults
FromSourceBatch (CompilerParameters options
, string[] sources
)
109 string[] fileNames
= new string[sources
.Length
];
111 foreach (string source
in sources
) {
112 fileNames
[i
] = Path
.ChangeExtension (Path
.GetTempFileName(), FileExtension
);
113 FileStream f
= new FileStream (fileNames
[i
], FileMode
.OpenOrCreate
);
114 StreamWriter s
= new StreamWriter (f
);
120 return Compile (options
, fileNames
, false);
123 [SecurityPermission (SecurityAction
.Demand
, UnmanagedCode
= true)]
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
) {
133 options
.TempFiles
.AddFile (file
, keepFiles
);
135 options
.TempFiles
.KeepFiles
= keepFiles
;
137 string std_output
= String
.Empty
;
138 string err_output
= String
.Empty
;
139 string cmd
= String
.Concat (CompilerName
, " ", CmdArgsFromParameters (options
));
141 CompilerResults results
= new CompilerResults (new TempFileCollection ());
142 results
.NativeCompilerReturnValue
= Executor
.ExecWaitWithCapture (cmd
,
143 options
.TempFiles
, ref std_output
, ref err_output
);
145 string[] compiler_output_lines
= std_output
.Split (Environment
.NewLine
.ToCharArray ());
146 foreach (string error_line
in compiler_output_lines
)
147 ProcessCompilerOutputLine (results
, error_line
);
149 if (results
.Errors
.Count
== 0)
150 results
.PathToAssembly
= options
.OutputAssembly
;
155 protected virtual string GetResponseFileCmdArgs (CompilerParameters options
, string cmdArgs
)
157 // FIXME I'm not sure what this function should do...
158 throw new NotImplementedException ();
161 CompilerResults ICodeCompiler
.CompileAssemblyFromDom (CompilerParameters options
, CodeCompileUnit e
)
163 return FromDom (options
, e
);
166 CompilerResults ICodeCompiler
.CompileAssemblyFromDomBatch (CompilerParameters options
, CodeCompileUnit
[] ea
)
168 return FromDomBatch (options
, ea
);
171 CompilerResults ICodeCompiler
.CompileAssemblyFromFile (CompilerParameters options
, string fileName
)
173 return FromFile (options
, fileName
);
176 CompilerResults ICodeCompiler
.CompileAssemblyFromFileBatch (CompilerParameters options
, string[] fileNames
)
178 return FromFileBatch (options
, fileNames
);
182 CompilerResults ICodeCompiler
.CompileAssemblyFromSource (CompilerParameters options
, string source
)
184 return FromSource (options
, source
);
188 CompilerResults ICodeCompiler
.CompileAssemblyFromSourceBatch (CompilerParameters options
, string[] sources
)
190 return FromSourceBatch (options
, sources
);
193 protected static string JoinStringArray (string[] sa
, string separator
)
195 StringBuilder sb
= new StringBuilder ();
196 int length
= sa
.Length
;
198 for (int i
=0; i
< length
- 1; i
++) {
202 sb
.Append (separator
);
207 sb
.Append (sa
[length
- 1]);
210 return sb
.ToString ();
213 protected abstract void ProcessCompilerOutputLine (CompilerResults results
, string line
);