BaseCompiler.cs 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179
  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. void BuildTree ()
  63. {
  64. Init ();
  65. CreateMethods ();
  66. }
  67. protected virtual void CreateStaticFields ()
  68. {
  69. CodeMemberField fld = new CodeMemberField (typeof (bool), "__intialized");
  70. fld.Attributes = MemberAttributes.Private | MemberAttributes.Static;
  71. fld.InitExpression = new CodePrimitiveExpression (false);
  72. mainClass.Members.Add (fld);
  73. }
  74. protected virtual void CreateConstructor (CodeStatementCollection localVars, CodeStatementCollection trueStmt)
  75. {
  76. CodeConstructor ctor = new CodeConstructor ();
  77. ctor.Attributes = MemberAttributes.Public;
  78. mainClass.Members.Add (ctor);
  79. if (localVars != null)
  80. ctor.Statements.AddRange (localVars);
  81. CodeTypeReferenceExpression r = new CodeTypeReferenceExpression (mainNS.Name + "." + mainClass.Name);
  82. CodeFieldReferenceExpression intialized = new CodeFieldReferenceExpression (r, "__intialized");
  83. CodeBinaryOperatorExpression bin = new CodeBinaryOperatorExpression (intialized,
  84. CodeBinaryOperatorType.ValueEquality,
  85. new CodePrimitiveExpression (false));
  86. CodeAssignStatement assign = new CodeAssignStatement (intialized,
  87. new CodePrimitiveExpression (true));
  88. CodeConditionStatement cond = new CodeConditionStatement (bin, assign);
  89. if (trueStmt != null)
  90. cond.TrueStatements.AddRange (trueStmt);
  91. ctor.Statements.Add (cond);
  92. }
  93. void AddScripts ()
  94. {
  95. if (parser.Scripts == null || parser.Scripts.Count == 0)
  96. return;
  97. foreach (object o in parser.Scripts) {
  98. if (o is string)
  99. mainClass.Members.Add (new CodeSnippetTypeMember ((string) o));
  100. }
  101. }
  102. protected virtual void CreateMethods ()
  103. {
  104. }
  105. protected virtual void AddInterfaces ()
  106. {
  107. if (parser.Interfaces == null)
  108. return;
  109. foreach (object o in parser.Interfaces) {
  110. if (o is string)
  111. mainClass.BaseTypes.Add (new CodeTypeReference ((string) o));
  112. }
  113. }
  114. protected virtual void ProcessObjectTag (ObjectTagBuilder tag)
  115. {
  116. }
  117. void CheckCompilerErrors (CompilerResults results)
  118. {
  119. if (results.NativeCompilerReturnValue == 0)
  120. return;
  121. StringWriter writer = new StringWriter();
  122. provider.CreateGenerator().GenerateCodeFromCompileUnit (unit, writer, null);
  123. throw new CompilationException (parser.InputFile, results.Errors, writer.ToString ());
  124. }
  125. public virtual Type GetCompiledType ()
  126. {
  127. //TODO: get the compiler and default options from system.web/compileroptions
  128. provider = new CSharpCodeProvider ();
  129. compiler = provider.CreateCompiler ();
  130. BuildTree ();
  131. CompilerResults results = CachingCompiler.Compile (this);
  132. CheckCompilerErrors (results);
  133. return results.CompiledAssembly.GetType (mainClassExpr.Type.BaseType, true);
  134. }
  135. internal CompilerParameters CompilerParameters {
  136. get { return compilerParameters; }
  137. }
  138. internal CodeCompileUnit Unit {
  139. get { return unit; }
  140. }
  141. internal ICodeCompiler Compiler {
  142. get { return compiler; }
  143. }
  144. internal TemplateParser Parser {
  145. get { return parser; }
  146. }
  147. }
  148. }