CachingCompiler.cs 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158
  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 bool CheckDependencies (string key)
  31. {
  32. if (dependencies == null)
  33. return true; // Forever young
  34. foreach (string s in dependencies) {
  35. if (!File.Exists (s) || File.GetLastWriteTime (s) > reference)
  36. return false;
  37. }
  38. return true;
  39. }
  40. public CompilerResults Result {
  41. get { return result; }
  42. }
  43. }
  44. internal class CompilationCache
  45. {
  46. static Hashtable cache;
  47. static CompilationCache instance = new CompilationCache ();
  48. private CompilationCache ()
  49. {
  50. }
  51. static CompilationCache ()
  52. {
  53. cache = new Hashtable ();
  54. }
  55. public static CompilationCache GetInstance ()
  56. {
  57. return instance;
  58. }
  59. public bool CheckDependencies (CompilationCacheItem item, string key)
  60. {
  61. bool result = item.CheckDependencies (key);
  62. if (result == false)
  63. cache.Remove (key);
  64. return result;
  65. }
  66. public CompilationCacheItem this [string key] {
  67. get { return cache [key] as CompilationCacheItem; }
  68. set { cache [key] = value; }
  69. }
  70. }
  71. internal class CachingCompiler
  72. {
  73. static CompilationCache cache = CompilationCache.GetInstance ();
  74. private CachingCompiler () {}
  75. public static CompilationCacheItem GetCached (string key)
  76. {
  77. if (key == null)
  78. throw new ArgumentNullException ("key");
  79. CompilationCacheItem item = cache [key];
  80. if (item != null && cache.CheckDependencies (item, key))
  81. return item;
  82. return null;
  83. }
  84. static object compilationLock = new object ();
  85. public static CompilerResults Compile (BaseCompiler compiler)
  86. {
  87. string key = compiler.Parser.InputFile;
  88. CompilationCacheItem item = GetCached (key);
  89. if (item != null)
  90. return item.Result;
  91. CompilerResults results = null;
  92. lock (compilationLock) {
  93. item = GetCached (key);
  94. if (item != null)
  95. return item.Result;
  96. results = compiler.Compiler.CompileAssemblyFromDom (compiler.CompilerParameters, compiler.Unit);
  97. cache [key] = new CompilationCacheItem (results, compiler.Parser.Dependencies);
  98. }
  99. return results;
  100. }
  101. static CompilerParameters GetOptions (ICollection assemblies)
  102. {
  103. CompilerParameters options = new CompilerParameters ();
  104. if (assemblies != null) {
  105. StringCollection coll = options.ReferencedAssemblies;
  106. foreach (string str in assemblies)
  107. coll.Add (str);
  108. }
  109. return options;
  110. }
  111. public static CompilerResults Compile (string file, ArrayList assemblies)
  112. {
  113. CompilationCacheItem item = GetCached (file);
  114. if (item != null)
  115. return item.Result;
  116. CompilerResults results = null;
  117. lock (compilationLock) {
  118. item = GetCached (file);
  119. if (item != null)
  120. return item.Result;
  121. CompilerParameters options = GetOptions (assemblies);
  122. //TODO: support for other languages
  123. results = CSCompiler.Compiler.CompileAssemblyFromFile (options, file);
  124. cache [file] = new CompilationCacheItem (results, null);
  125. }
  126. return results;
  127. }
  128. }
  129. }