2010-03-12 Jb Evain <jbevain@novell.com>
[mono.git] / mcs / class / System.Web / System.Web.Compilation / PageCompiler.cs
1 //
2 // System.Web.Compilation.PageCompiler
3 //
4 // Authors:
5 //      Gonzalo Paniagua Javier (gonzalo@ximian.com)
6 //
7 // (C) 2002,2003 Ximian, Inc (http://www.ximian.com)
8 //
9
10 //
11 // Permission is hereby granted, free of charge, to any person obtaining
12 // a copy of this software and associated documentation files (the
13 // "Software"), to deal in the Software without restriction, including
14 // without limitation the rights to use, copy, modify, merge, publish,
15 // distribute, sublicense, and/or sell copies of the Software, and to
16 // permit persons to whom the Software is furnished to do so, subject to
17 // the following conditions:
18 // 
19 // The above copyright notice and this permission notice shall be
20 // included in all copies or substantial portions of the Software.
21 // 
22 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
23 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
24 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
25 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
26 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
27 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
28 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
29 //
30 using System;
31 using System.CodeDom;
32 using System.Collections;
33 using System.Collections.Generic;
34 using System.IO;
35 using System.Reflection;
36 using System.Text;
37 using System.Web.Configuration;
38 using System.Web.UI;
39 using System.Web.SessionState;
40 using System.Web.Util;
41 using System.Web.Profile;
42
43 namespace System.Web.Compilation
44 {
45         class PageCompiler : TemplateControlCompiler
46         {
47                 PageParser pageParser;
48                 static CodeTypeReference intRef = new CodeTypeReference (typeof (int));
49
50                 public PageCompiler (PageParser pageParser)
51                         : base (pageParser)
52                 {
53                         this.pageParser = pageParser;
54                 }
55
56                 protected override void CreateStaticFields ()
57                 {
58                         base.CreateStaticFields ();
59                         
60                         CodeMemberField fld = new CodeMemberField (typeof (object), "__fileDependencies");
61                         fld.Attributes = MemberAttributes.Private | MemberAttributes.Static;
62                         fld.InitExpression = new CodePrimitiveExpression (null);
63                         mainClass.Members.Add (fld);
64
65                         if (pageParser.OutputCache) {
66                                 fld = new CodeMemberField (typeof (OutputCacheParameters), "__outputCacheSettings");
67                                 fld.Attributes = MemberAttributes.Private | MemberAttributes.Static;
68                                 fld.InitExpression = new CodePrimitiveExpression (null);
69                                 mainClass.Members.Add (fld);
70                         }
71                 }
72                 
73                 protected override void CreateConstructor (CodeStatementCollection localVars,
74                                                            CodeStatementCollection trueStmt)
75                 {
76                         if (!String.IsNullOrEmpty (pageParser.MasterPageFile))
77                                 // This is here just to trigger master page build, so that its type
78                                 // is available when compiling the page itself.
79                                 BuildManager.GetCompiledType (pageParser.MasterPageFile);
80
81                         if (pageParser.ClientTarget != null) {
82                                 CodeExpression prop;
83                                 prop = new CodePropertyReferenceExpression (thisRef, "ClientTarget");
84                                 CodeExpression ct = new CodePrimitiveExpression (pageParser.ClientTarget);
85                                 if (localVars == null)
86                                         localVars = new CodeStatementCollection ();
87                                 localVars.Add (new CodeAssignStatement (prop, ct));
88                         }
89
90                         ArrayList deps = pageParser.Dependencies;
91                         int depsCount = deps != null ? deps.Count : 0;
92                         
93                         if (depsCount > 0) {
94                                 if (localVars == null)
95                                         localVars = new CodeStatementCollection ();
96                                 if (trueStmt == null)
97                                         trueStmt = new CodeStatementCollection ();
98
99                                 CodeAssignStatement assign;
100                                 localVars.Add (
101                                         new CodeVariableDeclarationStatement (
102                                                 typeof (string[]),
103                                                 "dependencies")
104                                 );
105
106                                 CodeVariableReferenceExpression dependencies = new CodeVariableReferenceExpression ("dependencies");
107                                 trueStmt.Add (
108                                         new CodeAssignStatement (dependencies, new CodeArrayCreateExpression (typeof (string), depsCount))
109                                 );
110                                 
111                                 CodeArrayIndexerExpression arrayIndex;
112                                 object o;
113                                 
114                                 for (int i = 0; i < depsCount; i++) {
115                                         o = deps [i];
116                                         arrayIndex = new CodeArrayIndexerExpression (dependencies, new CodeExpression[] {new CodePrimitiveExpression (i)});
117                                         assign = new CodeAssignStatement (arrayIndex, new CodePrimitiveExpression (o));
118                                         trueStmt.Add (assign);
119                                 }
120                                 
121                                 CodeMethodInvokeExpression getDepsCall = new CodeMethodInvokeExpression (
122                                         thisRef,
123                                         "GetWrappedFileDependencies",
124                                         new CodeExpression[] {dependencies}
125                                 );
126                                 assign = new CodeAssignStatement (GetMainClassFieldReferenceExpression ("__fileDependencies"), getDepsCall);
127
128                                 trueStmt.Add (assign);
129                         }
130
131                         base.CreateConstructor (localVars, trueStmt);
132                 }
133                 
134                 protected override void AddInterfaces () 
135                 {
136                         base.AddInterfaces ();
137                         CodeTypeReference cref;
138                         
139                         if (pageParser.EnableSessionState) {
140                                 cref = new CodeTypeReference (typeof (IRequiresSessionState));
141                                 if (partialClass != null)
142                                         partialClass.BaseTypes.Add (cref);
143                                 else
144                                         mainClass.BaseTypes.Add (cref);
145                         }
146                         
147                         if (pageParser.ReadOnlySessionState) {
148                                 cref = new CodeTypeReference (typeof (IReadOnlySessionState));
149                                 if (partialClass != null)
150                                         partialClass.BaseTypes.Add (cref);                                      
151                                 else
152                                         mainClass.BaseTypes.Add (cref);
153                         }
154
155                         if (pageParser.Async)
156                                 mainClass.BaseTypes.Add (new CodeTypeReference (typeof (System.Web.IHttpAsyncHandler)));
157                         
158                         mainClass.BaseTypes.Add (new CodeTypeReference (typeof (System.Web.IHttpHandler)));
159                 }
160
161                 void CreateGetTypeHashCode () 
162                 {
163                         CodeMemberMethod method = new CodeMemberMethod ();
164                         method.ReturnType = intRef;
165                         method.Name = "GetTypeHashCode";
166                         method.Attributes = MemberAttributes.Public | MemberAttributes.Override;
167                         Random rnd = new Random (pageParser.InputFile.GetHashCode ());
168                         method.Statements.Add (new CodeMethodReturnStatement (new CodePrimitiveExpression (rnd.Next ())));
169                         mainClass.Members.Add (method);
170                 }
171
172                 static CodeExpression GetExpressionForValueAndType (object value, Type valueType)
173                 {
174                         // Put short circuit types here
175                         if (valueType == typeof (TimeSpan)) {
176                                 CodeMethodReferenceExpression mref = new CodeMethodReferenceExpression (
177                                         new CodeTypeReferenceExpression (typeof (TimeSpan)),
178                                         "Parse");
179
180                                 return new CodeMethodInvokeExpression (
181                                         mref,
182                                         new CodeExpression[] { new CodePrimitiveExpression (((TimeSpan) value).ToString ()) }
183                                 );
184                         }
185
186                         throw new HttpException (String.Format ("Unable to create assign expression for type '{0}'.", valueType));
187                 }
188                 
189                 static CodeAssignStatement CreatePropertyAssign (CodeExpression expr, string name, object value)
190                 {
191                         CodeExpression rhs;
192                         if (value == null || value is string)
193                                 rhs = new CodePrimitiveExpression (value);
194                         else {
195                                 Type vt = value.GetType ();
196
197                                 if (vt.IsPrimitive)
198                                         rhs = new CodePrimitiveExpression (value);
199                                 else
200                                         rhs = GetExpressionForValueAndType (value, vt);
201                         }
202                         
203                         return new CodeAssignStatement (new CodePropertyReferenceExpression (expr, name), rhs);
204                 }
205
206                 static CodeAssignStatement CreatePropertyAssign (string name, object value)
207                 {
208                         return CreatePropertyAssign (thisRef, name, value);
209                 }
210
211                 void AddStatementsFromDirective (CodeMemberMethod method)
212                 {
213                         string responseEncoding = pageParser.ResponseEncoding;
214                         if (responseEncoding != null)
215                                 method.Statements.Add (CreatePropertyAssign ("ResponseEncoding", responseEncoding));
216                         
217                         int codepage = pageParser.CodePage;
218                         if (codepage != -1)
219                                 method.Statements.Add (CreatePropertyAssign ("CodePage", codepage));
220
221                         string contentType = pageParser.ContentType;
222                         if (contentType != null)
223                                 method.Statements.Add (CreatePropertyAssign ("ContentType", contentType));
224                         
225                         int lcid = pageParser.LCID;
226                         if (lcid != -1)
227                                 method.Statements.Add (CreatePropertyAssign ("LCID", lcid));
228
229                         string culture = pageParser.Culture;
230                         if (culture != null)
231                                 method.Statements.Add (CreatePropertyAssign ("Culture", culture));
232
233                         culture = pageParser.UICulture;
234                         if (culture != null)
235                                 method.Statements.Add (CreatePropertyAssign ("UICulture", culture));
236
237                         string errorPage = pageParser.ErrorPage;
238                         if (errorPage != null)
239                                 method.Statements.Add (CreatePropertyAssign ("ErrorPage", errorPage));
240
241                         if (pageParser.HaveTrace) {
242                                 CodeAssignStatement stmt = new CodeAssignStatement ();
243                                 stmt.Left = new CodePropertyReferenceExpression (thisRef, "TraceEnabled");
244                                 stmt.Right = new CodePrimitiveExpression (pageParser.Trace);
245                                 method.Statements.Add (stmt);
246                         }
247
248                         if (pageParser.TraceMode != TraceMode.Default) {
249                                 CodeAssignStatement stmt = new CodeAssignStatement ();
250                                 CodeTypeReferenceExpression tm = new CodeTypeReferenceExpression ("System.Web.TraceMode");
251                                 stmt.Left = new CodePropertyReferenceExpression (thisRef, "TraceModeValue");
252                                 stmt.Right = new CodeFieldReferenceExpression (tm, pageParser.TraceMode.ToString ());
253                                 method.Statements.Add (stmt);
254                         }
255
256                         if (pageParser.NotBuffer) {
257                                 CodeAssignStatement stmt = new CodeAssignStatement ();
258                                 stmt.Left = new CodePropertyReferenceExpression (thisRef, "Buffer");
259                                 stmt.Right = new CodePrimitiveExpression (false);
260                                 method.Statements.Add (stmt);
261                         }
262
263                         if (!pageParser.EnableEventValidation) {
264                                 CodeAssignStatement stmt = new CodeAssignStatement ();
265                                 CodePropertyReferenceExpression prop;
266                                 prop = new CodePropertyReferenceExpression (thisRef, "EnableEventValidation");
267                                 stmt.Left = prop;
268                                 stmt.Right = new CodePrimitiveExpression (pageParser.EnableEventValidation);
269                                 method.Statements.Add (stmt);
270                         }
271
272                         if (pageParser.MaintainScrollPositionOnPostBack) {
273                                 CodeAssignStatement stmt = new CodeAssignStatement ();
274                                 CodePropertyReferenceExpression prop;
275                                 prop = new CodePropertyReferenceExpression (thisRef, "MaintainScrollPositionOnPostBack");
276                                 stmt.Left = prop;
277                                 stmt.Right = new CodePrimitiveExpression (pageParser.MaintainScrollPositionOnPostBack);
278                                 method.Statements.Add (stmt);
279                         }
280                 }
281
282                 protected override void AddStatementsToConstructor (CodeConstructor ctor)
283                 {
284                         base.AddStatementsToConstructor (ctor);
285                         if (pageParser.OutputCache)
286                                 OutputCacheParamsBlock (ctor);
287                 }
288                 
289                 protected override void AddStatementsToInitMethod (CodeMemberMethod method)
290                 {
291                         AddStatementsFromDirective (method);
292                         ILocation directiveLocation = pageParser.DirectiveLocation;
293
294                         CodeArgumentReferenceExpression ctrlVar = new CodeArgumentReferenceExpression("__ctrl");
295                         if (pageParser.Title != null)
296                                 method.Statements.Add (AddLinePragma (CreatePropertyAssign (ctrlVar, "Title", pageParser.Title), directiveLocation));
297
298                         if (pageParser.MasterPageFile != null)
299                                 method.Statements.Add (AddLinePragma (CreatePropertyAssign (ctrlVar, "MasterPageFile", pageParser.MasterPageFile), directiveLocation));
300
301                         if (pageParser.Theme != null)
302                                 method.Statements.Add (AddLinePragma (CreatePropertyAssign (ctrlVar, "Theme", pageParser.Theme), directiveLocation));
303
304                         if (pageParser.StyleSheetTheme != null)
305                                 method.Statements.Add (AddLinePragma (CreatePropertyAssign (ctrlVar, "StyleSheetTheme", pageParser.StyleSheetTheme), directiveLocation));
306
307                         if (pageParser.Async != false)
308                                 method.Statements.Add (AddLinePragma (CreatePropertyAssign (ctrlVar, "AsyncMode", pageParser.Async), directiveLocation));
309
310                         if (pageParser.AsyncTimeout != -1)
311                                 method.Statements.Add (AddLinePragma (CreatePropertyAssign (ctrlVar, "AsyncTimeout",
312                                                                                             TimeSpan.FromSeconds (pageParser.AsyncTimeout)), directiveLocation));
313
314                         CodeMethodInvokeExpression expr = new CodeMethodInvokeExpression (thisRef, "InitializeCulture");
315                         method.Statements.Add (AddLinePragma (new CodeExpressionStatement (expr), directiveLocation));
316                 }
317
318                 protected override void PrependStatementsToFrameworkInitialize (CodeMemberMethod method)
319                 {
320                         base.PrependStatementsToFrameworkInitialize (method);
321                         if (pageParser.StyleSheetTheme != null)
322                                 method.Statements.Add (CreatePropertyAssign ("StyleSheetTheme", pageParser.StyleSheetTheme));
323                 }
324                 
325                 protected override void AppendStatementsToFrameworkInitialize (CodeMemberMethod method)
326                 {
327                         base.AppendStatementsToFrameworkInitialize (method);
328
329                         ArrayList deps = pageParser.Dependencies;
330                         int depsCount = deps != null ? deps.Count : 0;
331
332                         if (depsCount > 0) {
333                                 CodeFieldReferenceExpression fileDependencies = GetMainClassFieldReferenceExpression ("__fileDependencies");
334
335                                 method.Statements.Add (
336                                         new CodeMethodInvokeExpression (
337                                                 thisRef,
338                                                 "AddWrappedFileDependencies",
339                                                 new CodeExpression[] {fileDependencies})
340                                 );
341
342                         }
343
344                         if (pageParser.OutputCache) {
345                                 CodeMethodReferenceExpression init = new CodeMethodReferenceExpression (thisRef, "InitOutputCache");
346                                 CodeMethodInvokeExpression invoke = new CodeMethodInvokeExpression (init, GetMainClassFieldReferenceExpression ("__outputCacheSettings"));
347                                 method.Statements.Add (invoke);
348                         }
349
350                         if (pageParser.ValidateRequest) {
351                                 CodeMethodInvokeExpression expr = new CodeMethodInvokeExpression ();
352                                 CodePropertyReferenceExpression prop;
353                                 prop = new CodePropertyReferenceExpression (thisRef, "Request");
354                                 expr.Method = new CodeMethodReferenceExpression (prop, "ValidateInput");
355                                 method.Statements.Add (expr);
356                         }
357                 }
358
359                 CodeAssignStatement AssignOutputCacheParameter (CodeVariableReferenceExpression variable, string propName, object value)
360                 {
361                         var ret = new CodeAssignStatement ();
362
363                         ret.Left = new CodeFieldReferenceExpression (variable, propName);
364
365                         if (value is OutputCacheLocation)
366                                 ret.Right = new CodeFieldReferenceExpression (
367                                         new CodeTypeReferenceExpression (new CodeTypeReference (typeof (OutputCacheLocation), CodeTypeReferenceOptions.GlobalReference)),
368                                         value.ToString ()
369                                 );
370                         else
371                                 ret.Right = new CodePrimitiveExpression (value);
372                         return ret;
373                 }
374                 
375                 void OutputCacheParamsBlock (CodeMemberMethod method)
376                 {
377                         var statements = new List <CodeStatement> ();
378                         var localSettingsDecl = new CodeVariableDeclarationStatement (typeof (OutputCacheParameters), "outputCacheSettings");
379                         var localSettings = new CodeVariableReferenceExpression ("outputCacheSettings");
380                         
381                         statements.Add (localSettingsDecl);
382                         statements.Add (
383                                 new CodeAssignStatement (
384                                         localSettings,
385                                         new CodeObjectCreateExpression (typeof (OutputCacheParameters), new CodeExpression[] {})
386                                 )
387                         );
388                         
389                         TemplateParser.OutputCacheParsedParams parsed = pageParser.OutputCacheParsedParameters;
390                         if ((parsed & TemplateParser.OutputCacheParsedParams.CacheProfile) != 0)
391                                 statements.Add (AssignOutputCacheParameter (localSettings, "CacheProfile", pageParser.OutputCacheCacheProfile));
392                         statements.Add (AssignOutputCacheParameter (localSettings, "Duration", pageParser.OutputCacheDuration));
393                         if ((parsed & TemplateParser.OutputCacheParsedParams.Location) != 0)
394                                 statements.Add (AssignOutputCacheParameter (localSettings, "Location", pageParser.OutputCacheLocation));
395                         if ((parsed & TemplateParser.OutputCacheParsedParams.NoStore) != 0)
396                                 statements.Add (AssignOutputCacheParameter (localSettings, "NoStore", pageParser.OutputCacheNoStore));
397                         if ((parsed & TemplateParser.OutputCacheParsedParams.SqlDependency) != 0)
398                                 statements.Add (AssignOutputCacheParameter (localSettings, "SqlDependency", pageParser.OutputCacheSqlDependency));
399                         if ((parsed & TemplateParser.OutputCacheParsedParams.VaryByContentEncodings) != 0)
400                                 statements.Add (AssignOutputCacheParameter (localSettings, "VaryByContentEncoding", pageParser.OutputCacheVaryByContentEncodings));
401                         if ((parsed & TemplateParser.OutputCacheParsedParams.VaryByControl) != 0)
402                                 statements.Add (AssignOutputCacheParameter (localSettings, "VaryByControl", pageParser.OutputCacheVaryByControls));
403                         if ((parsed & TemplateParser.OutputCacheParsedParams.VaryByCustom) != 0)
404                                 statements.Add (AssignOutputCacheParameter (localSettings, "VaryByCustom", pageParser.OutputCacheVaryByCustom));
405                         if ((parsed & TemplateParser.OutputCacheParsedParams.VaryByHeader) != 0)
406                                 statements.Add (AssignOutputCacheParameter (localSettings, "VaryByHeader", pageParser.OutputCacheVaryByHeader));
407                         statements.Add (AssignOutputCacheParameter (localSettings, "VaryByParam", pageParser.OutputCacheVaryByParam));
408
409                         CodeFieldReferenceExpression outputCacheSettings = GetMainClassFieldReferenceExpression ("__outputCacheSettings");
410                         statements.Add (new CodeAssignStatement (outputCacheSettings, localSettings));
411                         
412                         var cond = new CodeConditionStatement (
413                                 new CodeBinaryOperatorExpression (
414                                         outputCacheSettings,
415                                         CodeBinaryOperatorType.IdentityEquality,
416                                         new CodePrimitiveExpression (null)
417                                 ),
418                                 statements.ToArray ()
419                         );
420
421                         method.Statements.Add (cond);
422                 }
423
424                 void CreateStronglyTypedProperty (Type type, string name)
425                 {
426                         if (type == null)
427                                 return;
428                         
429                         CodeMemberProperty mprop = new CodeMemberProperty ();
430                         mprop.Name = name;
431                         mprop.Type = new CodeTypeReference (type);
432                         mprop.Attributes = MemberAttributes.Public | MemberAttributes.New;
433                         CodeExpression prop = new CodePropertyReferenceExpression (new CodeBaseReferenceExpression (), name);
434                         prop = new CodeCastExpression (type, prop);
435                         mprop.GetStatements.Add (new CodeMethodReturnStatement (prop));
436                         if (partialClass != null)
437                                 partialClass.Members.Add (mprop);
438                         else
439                                 mainClass.Members.Add (mprop);
440
441                         AddReferencedAssembly (type.Assembly);
442                 }
443                 
444                 protected internal override void CreateMethods ()
445                 {
446                         base.CreateMethods ();
447
448                         CreateProfileProperty ();
449                         CreateStronglyTypedProperty (pageParser.MasterType, "Master");
450                         CreateStronglyTypedProperty (pageParser.PreviousPageType, "PreviousPage");
451                         CreateGetTypeHashCode ();
452
453                         if (pageParser.Async)
454                                 CreateAsyncMethods ();
455                 }
456
457                 void CreateAsyncMethods ()
458                 {
459                         CodeMemberMethod method = new CodeMemberMethod ();
460                         CodeParameterDeclarationExpression arg;
461                         CodeMethodInvokeExpression invoke;
462
463                         // public virtual System.IAsyncResult BeginProcessRequest(System.Web.HttpContext context, System.AsyncCallback cb, object data);
464                         method.ReturnType = new CodeTypeReference (typeof (IAsyncResult));
465                         method.Name = "BeginProcessRequest";
466                         method.Attributes = MemberAttributes.Public;
467                         
468                         arg = new CodeParameterDeclarationExpression ();
469                         arg.Type = new CodeTypeReference (typeof (HttpContext));
470                         arg.Name = "context";
471                         method.Parameters.Add (arg);
472
473                         arg = new CodeParameterDeclarationExpression ();
474                         arg.Type = new CodeTypeReference (typeof (AsyncCallback));
475                         arg.Name = "cb";
476                         method.Parameters.Add (arg);
477
478                         arg = new CodeParameterDeclarationExpression ();
479                         arg.Type = new CodeTypeReference (typeof (object));
480                         arg.Name = "data";
481                         method.Parameters.Add (arg);
482
483                         invoke = new CodeMethodInvokeExpression (thisRef, "AsyncPageBeginProcessRequest");
484                         invoke.Parameters.Add (new CodeArgumentReferenceExpression ("context"));
485                         invoke.Parameters.Add (new CodeArgumentReferenceExpression ("cb"));
486                         invoke.Parameters.Add (new CodeArgumentReferenceExpression ("data"));
487
488                         method.Statements.Add (new CodeMethodReturnStatement (invoke));
489                         mainClass.Members.Add (method);
490
491                         // public virtual void EndProcessRequest(System.IAsyncResult ar);
492                         method = new CodeMemberMethod ();
493                         method.ReturnType = new CodeTypeReference (typeof (void));
494                         method.Name = "EndProcessRequest";
495                         method.Attributes = MemberAttributes.Public;
496
497                         arg = new CodeParameterDeclarationExpression ();
498                         arg.Type = new CodeTypeReference (typeof (IAsyncResult));
499                         arg.Name = "ar";
500                         method.Parameters.Add (arg);
501
502                         invoke = new CodeMethodInvokeExpression (thisRef, "AsyncPageEndProcessRequest");
503                         invoke.Parameters.Add (new CodeArgumentReferenceExpression ("ar"));
504
505                         method.Statements.Add (invoke);
506                         mainClass.Members.Add (method);
507
508                         // public override void ProcessRequest(System.Web.HttpContext context);
509                         method = new CodeMemberMethod ();
510                         method.ReturnType = new CodeTypeReference (typeof (void));
511                         method.Name = "ProcessRequest";
512                         method.Attributes = MemberAttributes.Public | MemberAttributes.Override;
513
514                         arg = new CodeParameterDeclarationExpression ();
515                         arg.Type = new CodeTypeReference (typeof (HttpContext));
516                         arg.Name = "context";
517                         method.Parameters.Add (arg);
518                         
519                         invoke = new CodeMethodInvokeExpression (new CodeBaseReferenceExpression (), "ProcessRequest");
520                         invoke.Parameters.Add (new CodeArgumentReferenceExpression ("context"));
521
522                         method.Statements.Add (invoke);
523                         mainClass.Members.Add (method);
524                 }
525                 
526                 public static Type CompilePageType (PageParser pageParser)
527                 {
528                         PageCompiler compiler = new PageCompiler (pageParser);
529                         return compiler.GetCompiledType ();
530                 }
531         }
532 }