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 CreateStaticFields ();
65 CreateConstructor (null, null);
68 protected virtual void CreateStaticFields ()
70 CodeMemberField fld = new CodeMemberField (typeof (bool), "__intialized");
71 fld.Attributes = MemberAttributes.Private | MemberAttributes.Static;
72 fld.InitExpression = new CodePrimitiveExpression (false);
73 mainClass.Members.Add (fld);
76 protected virtual void CreateConstructor (CodeStatementCollection localVars, CodeStatementCollection trueStmt)
78 CodeConstructor ctor = new CodeConstructor ();
79 ctor.Attributes = MemberAttributes.Public;
80 mainClass.Members.Add (ctor);
82 if (localVars != null)
83 ctor.Statements.AddRange (localVars);
85 CodeTypeReferenceExpression r = new CodeTypeReferenceExpression (mainNS.Name + "." + mainClass.Name);
86 CodeFieldReferenceExpression intialized = new CodeFieldReferenceExpression (r, "__intialized");
88 CodeBinaryOperatorExpression bin = new CodeBinaryOperatorExpression (intialized,
89 CodeBinaryOperatorType.ValueEquality,
90 new CodePrimitiveExpression (false));
92 CodeAssignStatement assign = new CodeAssignStatement (intialized,
93 new CodePrimitiveExpression (true));
95 CodeConditionStatement cond = new CodeConditionStatement (bin, assign);
97 cond.TrueStatements.AddRange (trueStmt);
99 ctor.Statements.Add (cond);
104 if (parser.Scripts == null || parser.Scripts.Count == 0)
107 foreach (object o in parser.Scripts) {
109 mainClass.Members.Add (new CodeSnippetTypeMember ((string) o));
113 protected virtual void CreateMethods ()
117 protected virtual void AddInterfaces ()
119 if (parser.Interfaces == null)
122 foreach (object o in parser.Interfaces) {
124 mainClass.BaseTypes.Add (new CodeTypeReference ((string) o));
128 protected virtual void ProcessObjectTag (ObjectTagBuilder tag)
132 void CheckCompilerErrors (CompilerResults results)
134 if (results.NativeCompilerReturnValue == 0)
137 StringWriter writer = new StringWriter();
138 provider.CreateGenerator().GenerateCodeFromCompileUnit (unit, writer, null);
139 throw new CompilationException (parser.InputFile, results.Errors, writer.ToString ());
142 public virtual Type GetCompiledType ()
145 CompilationCacheItem item = CachingCompiler.GetCached (parser.InputFile);
147 Assembly a = item.Result.CompiledAssembly;
149 return a.GetType (mainClassExpr.Type.BaseType, true);
152 string lang = parser.Language;
153 CompilationConfiguration config;
155 config = CompilationConfiguration.GetInstance (parser.Context);
156 provider = config.GetProvider (lang);
157 if (provider == null)
158 throw new HttpException ("Configuration error. Language not supported: " +
161 compiler = provider.CreateCompiler ();
164 compilerParameters.IncludeDebugInformation = parser.Debug;
165 compilerParameters.CompilerOptions = config.GetCompilerOptions (lang) + " " +
166 parser.CompilerOptions;
168 compilerParameters.WarningLevel = config.GetWarningLevel (lang);
169 CompilerResults results = CachingCompiler.Compile (this);
170 CheckCompilerErrors (results);
171 if (results.CompiledAssembly == null)
172 throw new CompilationException (parser.InputFile, results.Errors,
173 "No assembly returned after compilation!?");
175 return results.CompiledAssembly.GetType (mainClassExpr.Type.BaseType, true);
178 internal CompilerParameters CompilerParameters {
179 get { return compilerParameters; }
182 internal CodeCompileUnit Unit {
186 internal virtual ICodeCompiler Compiler {
187 get { return compiler; }
190 internal TemplateParser Parser {
191 get { return parser; }