CodeCompiler.cs 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204
  1. //
  2. // System.CodeDom.Compiler.CodeCompiler.cs
  3. //
  4. // Authors:
  5. // Jackson Harper ([email protected])
  6. // Andreas Nahr ([email protected])
  7. //
  8. // (C) 2002 Jackson Harper, All rights reserved
  9. // (C) 2003 Andreas Nahr
  10. //
  11. using System;
  12. using System.IO;
  13. using System.Text;
  14. using System.Reflection;
  15. using System.Collections;
  16. using System.Collections.Specialized;
  17. using System.Diagnostics;
  18. namespace System.CodeDom.Compiler {
  19. public abstract class CodeCompiler : CodeGenerator, ICodeCompiler
  20. {
  21. protected CodeCompiler ()
  22. {
  23. }
  24. protected abstract string CompilerName {
  25. get;
  26. }
  27. protected abstract string FileExtension {
  28. get;
  29. }
  30. protected abstract string CmdArgsFromParameters (CompilerParameters options);
  31. protected virtual CompilerResults FromDom (CompilerParameters options, CodeCompileUnit e)
  32. {
  33. return FromDomBatch (options, new CodeCompileUnit[]{e});
  34. }
  35. protected virtual CompilerResults FromDomBatch (CompilerParameters options, CodeCompileUnit[] ea)
  36. {
  37. string[] fileNames = new string[ea.Length];
  38. int i = 0;
  39. if (options == null)
  40. options = new CompilerParameters ();
  41. StringCollection assemblies = options.ReferencedAssemblies;
  42. foreach (CodeCompileUnit e in ea) {
  43. fileNames[i] = Path.ChangeExtension (Path.GetTempFileName(), FileExtension);
  44. FileStream f = new FileStream (fileNames[i], FileMode.OpenOrCreate);
  45. StreamWriter s = new StreamWriter (f);
  46. if (e.ReferencedAssemblies != null) {
  47. foreach (string str in e.ReferencedAssemblies) {
  48. if (!assemblies.Contains (str))
  49. assemblies.Add (str);
  50. }
  51. }
  52. ((ICodeGenerator)this).GenerateCodeFromCompileUnit (e, s, new CodeGeneratorOptions());
  53. s.Close();
  54. f.Close();
  55. i++;
  56. }
  57. return Compile (options, fileNames, false);
  58. }
  59. protected virtual CompilerResults FromFile (CompilerParameters options, string fileName)
  60. {
  61. return FromFileBatch (options, new string[] {fileName});
  62. }
  63. protected virtual CompilerResults FromFileBatch (CompilerParameters options, string[] fileNames)
  64. {
  65. return Compile (options, fileNames, true);
  66. }
  67. protected virtual CompilerResults FromSource (CompilerParameters options, string source)
  68. {
  69. return FromSourceBatch(options, new string[]{source});
  70. }
  71. protected virtual CompilerResults FromSourceBatch (CompilerParameters options, string[] sources)
  72. {
  73. string[] fileNames = new string[sources.Length];
  74. int i = 0;
  75. foreach (string source in sources) {
  76. fileNames[i] = Path.ChangeExtension (Path.GetTempFileName(), FileExtension);
  77. FileStream f = new FileStream (fileNames[i], FileMode.OpenOrCreate);
  78. StreamWriter s = new StreamWriter (f);
  79. s.Write (source);
  80. s.Close ();
  81. f.Close ();
  82. i++;
  83. }
  84. return Compile (options, fileNames, false);
  85. }
  86. private CompilerResults Compile (CompilerParameters options, string[] fileNames, bool keepFiles)
  87. {
  88. if (null == options)
  89. throw new ArgumentNullException ("options");
  90. if (null == fileNames)
  91. throw new ArgumentNullException ("fileNames");
  92. options.TempFiles = new TempFileCollection ();
  93. foreach (string file in fileNames)
  94. {
  95. options.TempFiles.AddFile (file, keepFiles);
  96. }
  97. options.TempFiles.KeepFiles = keepFiles;
  98. CompilerResults results = new CompilerResults (new TempFileCollection());
  99. // FIXME this should probably be done by the System.CodeDom.Compiler.Executor class
  100. Process compiler = new Process();
  101. string compiler_output;
  102. string[] compiler_output_lines;
  103. compiler.StartInfo.FileName = CompilerName;
  104. compiler.StartInfo.Arguments = CmdArgsFromParameters (options);
  105. compiler.StartInfo.CreateNoWindow = true;
  106. compiler.StartInfo.UseShellExecute = false;
  107. compiler.StartInfo.RedirectStandardOutput = true;
  108. try {
  109. compiler.Start();
  110. compiler_output = compiler.StandardOutput.ReadToEnd();
  111. compiler.WaitForExit();
  112. }
  113. finally {
  114. results.NativeCompilerReturnValue = compiler.ExitCode;
  115. compiler.Close();
  116. }
  117. // END FIXME
  118. compiler_output_lines = compiler_output.Split(
  119. System.Environment.NewLine.ToCharArray());
  120. foreach (string error_line in compiler_output_lines)
  121. ProcessCompilerOutputLine (results, error_line);
  122. if (results.Errors.Count == 0)
  123. results.CompiledAssembly = Assembly.LoadFrom (options.OutputAssembly);
  124. else
  125. results.CompiledAssembly = null;
  126. return results;
  127. }
  128. [MonoTODO]
  129. protected virtual string GetResponseFileCmdArgs (CompilerParameters options, string cmdArgs)
  130. {
  131. // FIXME I'm not sure what this function should do...
  132. throw new NotImplementedException ();
  133. }
  134. CompilerResults ICodeCompiler.CompileAssemblyFromDom (CompilerParameters options, CodeCompileUnit e)
  135. {
  136. return FromDom (options, e);
  137. }
  138. CompilerResults ICodeCompiler.CompileAssemblyFromDomBatch (CompilerParameters options, CodeCompileUnit[] ea)
  139. {
  140. return FromDomBatch (options, ea);
  141. }
  142. CompilerResults ICodeCompiler.CompileAssemblyFromFile (CompilerParameters options, string fileName)
  143. {
  144. return FromFile (options, fileName);
  145. }
  146. CompilerResults ICodeCompiler.CompileAssemblyFromFileBatch (CompilerParameters options, string[] fileNames)
  147. {
  148. return FromFileBatch (options, fileNames);
  149. }
  150. CompilerResults ICodeCompiler.CompileAssemblyFromSource (CompilerParameters options, string source)
  151. {
  152. return FromSource (options, source);
  153. }
  154. CompilerResults ICodeCompiler.CompileAssemblyFromSourceBatch (CompilerParameters options, string[] sources)
  155. {
  156. return FromSourceBatch (options, sources);
  157. }
  158. protected static string JoinStringArray (string[] sa, string separator)
  159. {
  160. StringBuilder sb = new StringBuilder ();
  161. foreach (string s in sa)
  162. sb.Append (s + separator);
  163. return sb.ToString ();
  164. }
  165. protected abstract void ProcessCompilerOutputLine (CompilerResults results, string line);
  166. }
  167. }