CachingCompiler.cs 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156
  1. //
  2. // System.Web.Compilation.CachingCompiler
  3. //
  4. // Authors:
  5. // Gonzalo Paniagua Javier ([email protected])
  6. //
  7. // (C) 2002 Ximian, Inc (http://www.ximian.com)
  8. //
  9. using System;
  10. using System.Collections;
  11. using System.Diagnostics;
  12. using System.IO;
  13. using System.Text;
  14. using System.Web.UI;
  15. using System.Web.Util;
  16. namespace System.Web.Compilation
  17. {
  18. //TODO: caching should be done using System.Web.Caching, but that namespace still need some work.
  19. internal class CompilationCacheItem
  20. {
  21. CompilationResult result;
  22. DateTime time;
  23. public CompilationCacheItem (CompilationResult result, DateTime time)
  24. {
  25. this.result = result;
  26. this.time = time;
  27. }
  28. public bool CheckDependencies (string [] newDependencies, DateTime time)
  29. {
  30. // FIXME
  31. return true;
  32. }
  33. public CompilationResult Result
  34. {
  35. get { return result; }
  36. }
  37. }
  38. internal class CompilationCache
  39. {
  40. static Hashtable cache;
  41. static CompilationCache instance = new CompilationCache ();
  42. private CompilationCache ()
  43. {
  44. }
  45. static CompilationCache ()
  46. {
  47. cache = new Hashtable ();
  48. }
  49. public static CompilationCache GetInstance ()
  50. {
  51. return instance;
  52. }
  53. public CompilationCacheItem this [string key]
  54. {
  55. get {
  56. return cache [key] as CompilationCacheItem;
  57. }
  58. set {
  59. cache [key] = value;
  60. }
  61. }
  62. }
  63. internal class CachingCompiler
  64. {
  65. static CompilationCache cache = CompilationCache.GetInstance ();
  66. string key;
  67. BaseCompiler compiler;
  68. public CachingCompiler (BaseCompiler compiler)
  69. {
  70. this.compiler = compiler;
  71. this.key = compiler.Key;
  72. }
  73. public static CompilationCacheItem GetCached (string key)
  74. {
  75. if (key == null)
  76. throw new ArgumentNullException ("key");
  77. CompilationCacheItem item = cache [key];
  78. return item;
  79. }
  80. static object compilationLock = new object ();
  81. public bool Compile (CompilationResult result)
  82. {
  83. if (compiler.SourceFile == null)
  84. throw new ArgumentException ("No source to compile!");
  85. result.Reset ();
  86. CompilationCacheItem item;
  87. item = GetCached (key);
  88. if (item != null) {
  89. if (item.CheckDependencies (compiler.Dependencies, DateTime.Now) == true) {
  90. result.CopyFrom (item.Result);
  91. return true;
  92. }
  93. }
  94. lock (compilationLock) {
  95. item = GetCached (key);
  96. if (item != null) {
  97. if (item.CheckDependencies (compiler.Dependencies, DateTime.Now) == true) {
  98. result.CopyFrom (item.Result);
  99. return true;
  100. }
  101. }
  102. RealCompile (result);
  103. cache [key] = new CompilationCacheItem (result, DateTime.Now);
  104. }
  105. return (result.ExitCode == 0);
  106. }
  107. void RealCompile (CompilationResult result)
  108. {
  109. StringBuilder options = new StringBuilder ("/target:library ");
  110. if (compiler.CompilerOptions != null)
  111. options.Append (compiler.CompilerOptions + ' ');
  112. options.AppendFormat ("/out:{0} ", compiler.TargetFile);
  113. options.Append (compiler.SourceFile);
  114. Process proc = new Process ();
  115. proc.StartInfo.FileName = "mcs";
  116. proc.StartInfo.Arguments = options.ToString ();
  117. proc.StartInfo.UseShellExecute = false;
  118. proc.StartInfo.RedirectStandardOutput = true;
  119. WebTrace.WriteLine ("{0} {1}", proc.StartInfo.FileName, options.ToString ());
  120. proc.Start ();
  121. string poutput = proc.StandardOutput.ReadToEnd();
  122. proc.WaitForExit ();
  123. result.ExitCode = proc.ExitCode;
  124. proc.Close ();
  125. proc = null;
  126. result.CompilerOutput = poutput;
  127. result.OutputFile = compiler.TargetFile;
  128. }
  129. }
  130. }