2 // System.Web.Compilation.BaseCompiler
5 // Gonzalo Paniagua Javier (gonzalo@ximian.com)
7 // (C) 2002,2003 Ximian, Inc (http://www.ximian.com)
12 using System.CodeDom.Compiler;
13 using System.Collections;
14 using System.Reflection;
17 using System.Web.Configuration;
20 namespace System.Web.Compilation
22 abstract class BaseCompiler
24 TemplateParser parser;
25 CodeDomProvider provider;
26 ICodeCompiler compiler;
29 CompilerParameters compilerParameters;
30 protected CodeTypeDeclaration mainClass;
31 protected CodeTypeReferenceExpression mainClassExpr;
32 protected static CodeThisReferenceExpression thisRef = new CodeThisReferenceExpression ();
34 protected BaseCompiler (TemplateParser parser)
36 compilerParameters = new CompilerParameters ();
42 unit = new CodeCompileUnit ();
43 mainNS = new CodeNamespace ("ASP");
44 unit.Namespaces.Add (mainNS);
45 mainClass = new CodeTypeDeclaration (parser.ClassName);
46 mainClass.TypeAttributes = TypeAttributes.Public;
47 mainNS.Types.Add (mainClass);
48 mainClass.BaseTypes.Add (new CodeTypeReference (parser.BaseType.FullName));
49 mainClassExpr = new CodeTypeReferenceExpression ("ASP." + parser.ClassName);
50 foreach (object o in parser.Imports) {
52 mainNS.Imports.Add (new CodeNamespaceImport ((string) o));
55 if (parser.Assemblies != null) {
56 foreach (object o in parser.Assemblies) {
58 unit.ReferencedAssemblies.Add ((string) o);
63 AddClassAttributes ();
64 CreateStaticFields ();
66 CreateConstructor (null, null);
69 protected virtual void CreateStaticFields ()
71 CodeMemberField fld = new CodeMemberField (typeof (bool), "__intialized");
72 fld.Attributes = MemberAttributes.Private | MemberAttributes.Static;
73 fld.InitExpression = new CodePrimitiveExpression (false);
74 mainClass.Members.Add (fld);
77 protected virtual void CreateConstructor (CodeStatementCollection localVars, CodeStatementCollection trueStmt)
79 CodeConstructor ctor = new CodeConstructor ();
80 ctor.Attributes = MemberAttributes.Public;
81 mainClass.Members.Add (ctor);
83 if (localVars != null)
84 ctor.Statements.AddRange (localVars);
86 CodeTypeReferenceExpression r = new CodeTypeReferenceExpression (mainNS.Name + "." + mainClass.Name);
87 CodeFieldReferenceExpression intialized = new CodeFieldReferenceExpression (r, "__intialized");
89 CodeBinaryOperatorExpression bin = new CodeBinaryOperatorExpression (intialized,
90 CodeBinaryOperatorType.ValueEquality,
91 new CodePrimitiveExpression (false));
93 CodeAssignStatement assign = new CodeAssignStatement (intialized,
94 new CodePrimitiveExpression (true));
96 CodeConditionStatement cond = new CodeConditionStatement (bin, assign);
98 cond.TrueStatements.AddRange (trueStmt);
100 ctor.Statements.Add (cond);
105 if (parser.Scripts == null || parser.Scripts.Count == 0)
108 foreach (object o in parser.Scripts) {
110 mainClass.Members.Add (new CodeSnippetTypeMember ((string) o));
114 protected virtual void CreateMethods ()
118 protected virtual void AddInterfaces ()
120 if (parser.Interfaces == null)
123 foreach (object o in parser.Interfaces) {
125 mainClass.BaseTypes.Add (new CodeTypeReference ((string) o));
129 protected virtual void AddClassAttributes ()
133 protected virtual void ProcessObjectTag (ObjectTagBuilder tag)
137 void CheckCompilerErrors (CompilerResults results)
139 if (results.NativeCompilerReturnValue == 0)
142 StringWriter writer = new StringWriter();
143 provider.CreateGenerator().GenerateCodeFromCompileUnit (unit, writer, null);
144 throw new CompilationException (parser.InputFile, results.Errors, writer.ToString ());
147 public virtual Type GetCompiledType ()
150 CompilationCacheItem item = CachingCompiler.GetCached (parser.InputFile);
152 Assembly a = item.Result.CompiledAssembly;
154 return a.GetType (mainClassExpr.Type.BaseType, true);
157 string lang = parser.Language;
158 CompilationConfiguration config;
160 config = CompilationConfiguration.GetInstance (parser.Context);
161 provider = config.GetProvider (lang);
162 if (provider == null)
163 throw new HttpException ("Configuration error. Language not supported: " +
166 compiler = provider.CreateCompiler ();
169 compilerParameters.IncludeDebugInformation = parser.Debug;
170 compilerParameters.CompilerOptions = config.GetCompilerOptions (lang) + " " +
171 parser.CompilerOptions;
173 compilerParameters.WarningLevel = config.GetWarningLevel (lang);
174 CompilerResults results = CachingCompiler.Compile (this);
175 CheckCompilerErrors (results);
176 if (results.CompiledAssembly == null)
177 throw new CompilationException (parser.InputFile, results.Errors,
178 "No assembly returned after compilation!?");
180 return results.CompiledAssembly.GetType (mainClassExpr.Type.BaseType, true);
183 internal CompilerParameters CompilerParameters {
184 get { return compilerParameters; }
187 internal CodeCompileUnit Unit {
191 internal virtual ICodeCompiler Compiler {
192 get { return compiler; }
195 internal TemplateParser Parser {
196 get { return parser; }