CachingCompiler.cs 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188
  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.CodeDom;
  11. using System.CodeDom.Compiler;
  12. using System.Collections;
  13. using System.Collections.Specialized;
  14. using System.IO;
  15. using System.Web.UI;
  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. CompilerResults result;
  22. ArrayList dependencies;
  23. DateTime reference;
  24. public CompilationCacheItem (CompilerResults result, ArrayList dependencies)
  25. {
  26. this.result = result;
  27. this.dependencies = dependencies;
  28. this.reference = DateTime.Now;
  29. }
  30. public CompilationCacheItem (CompilerResults result, string file)
  31. {
  32. this.result = result;
  33. this.dependencies = new ArrayList (1);
  34. dependencies.Add (file);
  35. this.reference = DateTime.Now;
  36. }
  37. public bool CheckDependencies (string key)
  38. {
  39. if (dependencies == null)
  40. return true; // Forever young
  41. foreach (string s in dependencies) {
  42. if (!File.Exists (s) || File.GetLastWriteTime (s) > reference)
  43. return false;
  44. }
  45. return true;
  46. }
  47. public CompilerResults Result {
  48. get { return result; }
  49. }
  50. }
  51. internal class CompilationCache
  52. {
  53. static Hashtable cache;
  54. static CompilationCache instance = new CompilationCache ();
  55. private CompilationCache ()
  56. {
  57. }
  58. static CompilationCache ()
  59. {
  60. cache = new Hashtable ();
  61. }
  62. public static CompilationCache GetInstance ()
  63. {
  64. return instance;
  65. }
  66. public bool CheckDependencies (CompilationCacheItem item, string key)
  67. {
  68. bool result = item.CheckDependencies (key);
  69. if (result == false)
  70. cache.Remove (key);
  71. return result;
  72. }
  73. public CompilationCacheItem this [string key] {
  74. get { return cache [key] as CompilationCacheItem; }
  75. set { cache [key] = value; }
  76. }
  77. }
  78. internal class CachingCompiler
  79. {
  80. static CompilationCache cache = CompilationCache.GetInstance ();
  81. private CachingCompiler () {}
  82. public static CompilationCacheItem GetCached (string key)
  83. {
  84. if (key == null)
  85. throw new ArgumentNullException ("key");
  86. CompilationCacheItem item = cache [key];
  87. if (item != null && cache.CheckDependencies (item, key))
  88. return item;
  89. return null;
  90. }
  91. static object compilationLock = new object ();
  92. public static CompilerResults Compile (BaseCompiler compiler)
  93. {
  94. string key = compiler.Parser.InputFile;
  95. CompilationCacheItem item = GetCached (key);
  96. if (item != null)
  97. return item.Result;
  98. CompilerResults results = null;
  99. lock (compilationLock) {
  100. item = GetCached (key);
  101. if (item != null)
  102. return item.Result;
  103. results = compiler.Compiler.CompileAssemblyFromDom (compiler.CompilerParameters, compiler.Unit);
  104. cache [key] = new CompilationCacheItem (results, compiler.Parser.Dependencies);
  105. }
  106. return results;
  107. }
  108. public static CompilerResults Compile (string key, string file, WebServiceCompiler compiler)
  109. {
  110. CompilationCacheItem item = GetCached (key);
  111. if (item != null)
  112. return item.Result;
  113. CompilerResults results = null;
  114. lock (compilationLock) {
  115. item = GetCached (key);
  116. if (item != null)
  117. return item.Result;
  118. SimpleWebHandlerParser parser = compiler.Parser;
  119. CompilerParameters options = GetOptions (parser.Assemblies);
  120. options.IncludeDebugInformation = parser.Debug;
  121. results = compiler.Compiler.CompileAssemblyFromFile (options, file);
  122. cache [key] = new CompilationCacheItem (results, parser.Dependencies);
  123. }
  124. return results;
  125. }
  126. static CompilerParameters GetOptions (ICollection assemblies)
  127. {
  128. CompilerParameters options = new CompilerParameters ();
  129. if (assemblies != null) {
  130. StringCollection coll = options.ReferencedAssemblies;
  131. foreach (string str in assemblies)
  132. coll.Add (str);
  133. }
  134. return options;
  135. }
  136. public static CompilerResults Compile (string key, string file, ArrayList assemblies)
  137. {
  138. CompilationCacheItem item = GetCached (key);
  139. if (item != null)
  140. return item.Result;
  141. CompilerResults results = null;
  142. lock (compilationLock) {
  143. item = GetCached (file);
  144. if (item != null)
  145. return item.Result;
  146. CompilerParameters options = GetOptions (assemblies);
  147. //TODO: support for other languages
  148. results = CSCompiler.Compiler.CompileAssemblyFromFile (options, file);
  149. cache [key] = new CompilationCacheItem (results, file);
  150. }
  151. return results;
  152. }
  153. }
  154. }