BaseCompiler.cs 4.9 KB

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