BaseCompiler.cs 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195
  1. //
  2. // System.Web.Compilation.BaseCompiler
  3. //
  4. // Authors:
  5. // Gonzalo Paniagua Javier ([email protected])
  6. //
  7. // (C) 2002,2003 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.Reflection;
  14. using System.Text;
  15. using System.Web.UI;
  16. using System.Web.Configuration;
  17. using System.IO;
  18. namespace System.Web.Compilation
  19. {
  20. abstract class BaseCompiler
  21. {
  22. TemplateParser parser;
  23. CodeDomProvider provider;
  24. ICodeCompiler compiler;
  25. CodeCompileUnit unit;
  26. CodeNamespace mainNS;
  27. CompilerParameters compilerParameters;
  28. protected CodeTypeDeclaration mainClass;
  29. protected CodeTypeReferenceExpression mainClassExpr;
  30. protected static CodeThisReferenceExpression thisRef = new CodeThisReferenceExpression ();
  31. protected BaseCompiler (TemplateParser parser)
  32. {
  33. compilerParameters = new CompilerParameters ();
  34. this.parser = parser;
  35. }
  36. void Init ()
  37. {
  38. unit = new CodeCompileUnit ();
  39. mainNS = new CodeNamespace ("ASP");
  40. unit.Namespaces.Add (mainNS);
  41. mainClass = new CodeTypeDeclaration (parser.ClassName);
  42. mainClass.TypeAttributes = TypeAttributes.Public;
  43. mainNS.Types.Add (mainClass);
  44. mainClass.BaseTypes.Add (new CodeTypeReference (parser.BaseType.FullName));
  45. mainClassExpr = new CodeTypeReferenceExpression ("ASP." + parser.ClassName);
  46. foreach (object o in parser.Imports) {
  47. if (o is string)
  48. mainNS.Imports.Add (new CodeNamespaceImport ((string) o));
  49. }
  50. if (parser.Assemblies != null) {
  51. foreach (object o in parser.Assemblies) {
  52. if (o is string)
  53. unit.ReferencedAssemblies.Add ((string) o);
  54. }
  55. }
  56. AddInterfaces ();
  57. CreateStaticFields ();
  58. AddScripts ();
  59. CreateConstructor (null, null);
  60. }
  61. protected virtual void CreateStaticFields ()
  62. {
  63. CodeMemberField fld = new CodeMemberField (typeof (bool), "__intialized");
  64. fld.Attributes = MemberAttributes.Private | MemberAttributes.Static;
  65. fld.InitExpression = new CodePrimitiveExpression (false);
  66. mainClass.Members.Add (fld);
  67. }
  68. protected virtual void CreateConstructor (CodeStatementCollection localVars, CodeStatementCollection trueStmt)
  69. {
  70. CodeConstructor ctor = new CodeConstructor ();
  71. ctor.Attributes = MemberAttributes.Public;
  72. mainClass.Members.Add (ctor);
  73. if (localVars != null)
  74. ctor.Statements.AddRange (localVars);
  75. CodeTypeReferenceExpression r = new CodeTypeReferenceExpression (mainNS.Name + "." + mainClass.Name);
  76. CodeFieldReferenceExpression intialized = new CodeFieldReferenceExpression (r, "__intialized");
  77. CodeBinaryOperatorExpression bin = new CodeBinaryOperatorExpression (intialized,
  78. CodeBinaryOperatorType.ValueEquality,
  79. new CodePrimitiveExpression (false));
  80. CodeAssignStatement assign = new CodeAssignStatement (intialized,
  81. new CodePrimitiveExpression (true));
  82. CodeConditionStatement cond = new CodeConditionStatement (bin, assign);
  83. if (trueStmt != null)
  84. cond.TrueStatements.AddRange (trueStmt);
  85. ctor.Statements.Add (cond);
  86. }
  87. void AddScripts ()
  88. {
  89. if (parser.Scripts == null || parser.Scripts.Count == 0)
  90. return;
  91. foreach (object o in parser.Scripts) {
  92. if (o is string)
  93. mainClass.Members.Add (new CodeSnippetTypeMember ((string) o));
  94. }
  95. }
  96. protected virtual void CreateMethods ()
  97. {
  98. }
  99. protected virtual void AddInterfaces ()
  100. {
  101. if (parser.Interfaces == null)
  102. return;
  103. foreach (object o in parser.Interfaces) {
  104. if (o is string)
  105. mainClass.BaseTypes.Add (new CodeTypeReference ((string) o));
  106. }
  107. }
  108. protected virtual void ProcessObjectTag (ObjectTagBuilder tag)
  109. {
  110. }
  111. void CheckCompilerErrors (CompilerResults results)
  112. {
  113. if (results.NativeCompilerReturnValue == 0)
  114. return;
  115. StringWriter writer = new StringWriter();
  116. provider.CreateGenerator().GenerateCodeFromCompileUnit (unit, writer, null);
  117. throw new CompilationException (parser.InputFile, results.Errors, writer.ToString ());
  118. }
  119. public virtual Type GetCompiledType ()
  120. {
  121. Init ();
  122. CompilationCacheItem item = CachingCompiler.GetCached (parser.InputFile);
  123. if (item != null) {
  124. Assembly a = item.Result.CompiledAssembly;
  125. if (a != null)
  126. return a.GetType (mainClassExpr.Type.BaseType, true);
  127. }
  128. string lang = parser.Language;
  129. CompilationConfiguration config;
  130. config = CompilationConfiguration.GetInstance (parser.Context);
  131. provider = config.GetProvider (lang);
  132. if (provider == null)
  133. throw new HttpException ("Configuration error. Language not supported: " +
  134. lang, 500);
  135. compiler = provider.CreateCompiler ();
  136. CreateMethods ();
  137. compilerParameters.IncludeDebugInformation = parser.Debug;
  138. compilerParameters.CompilerOptions = config.GetCompilerOptions (lang) + " " +
  139. parser.CompilerOptions;
  140. compilerParameters.WarningLevel = config.GetWarningLevel (lang);
  141. CompilerResults results = CachingCompiler.Compile (this);
  142. CheckCompilerErrors (results);
  143. if (results.CompiledAssembly == null)
  144. throw new CompilationException (parser.InputFile, results.Errors,
  145. "No assembly returned after compilation!?");
  146. return results.CompiledAssembly.GetType (mainClassExpr.Type.BaseType, true);
  147. }
  148. internal CompilerParameters CompilerParameters {
  149. get { return compilerParameters; }
  150. }
  151. internal CodeCompileUnit Unit {
  152. get { return unit; }
  153. }
  154. internal virtual ICodeCompiler Compiler {
  155. get { return compiler; }
  156. }
  157. internal TemplateParser Parser {
  158. get { return parser; }
  159. }
  160. }
  161. }