New test.
[mono.git] / mcs / class / System.Web / System.Web.UI / TemplateParser.cs
1 //
2 // System.Web.UI.TemplateParser
3 //
4 // Authors:
5 //      Duncan Mak (duncan@ximian.com)
6 //      Gonzalo Paniagua Javier (gonzalo@ximian.com)
7 //
8 // (C) 2002,2003 Ximian, Inc. (http://www.ximian.com)
9 // Copyright (C) 2005 Novell, Inc (http://www.novell.com)
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
31 using System.CodeDom.Compiler;
32 using System.Collections;
33 using System.Globalization;
34 using System.IO;
35 using System.Reflection;
36 using System.Security.Permissions;
37 using System.Web.Compilation;
38 using System.Web.Configuration;
39 using System.Web.Util;
40
41 namespace System.Web.UI {
42
43         // CAS
44         [AspNetHostingPermission (SecurityAction.LinkDemand, Level = AspNetHostingPermissionLevel.Minimal)]
45         [AspNetHostingPermission (SecurityAction.InheritanceDemand, Level = AspNetHostingPermissionLevel.Minimal)]
46         public abstract class TemplateParser : BaseParser
47         {
48                 string inputFile;
49                 string text;
50                 string privateBinPath;
51                 Hashtable mainAttributes;
52                 ArrayList dependencies;
53                 ArrayList assemblies;
54                 Hashtable anames;
55                 ArrayList imports;
56                 ArrayList interfaces;
57                 ArrayList scripts;
58                 Type baseType;
59                 string className;
60                 RootBuilder rootBuilder;
61                 bool debug;
62                 string compilerOptions;
63                 string language;
64                 bool strictOn = false;
65                 bool explicitOn = false;
66                 bool output_cache;
67                 int oc_duration;
68                 string oc_header, oc_custom, oc_param, oc_controls;
69                 bool oc_shared;
70                 OutputCacheLocation oc_location;
71                 CultureInfo invariantCulture = CultureInfo.InvariantCulture;
72 #if NET_2_0
73                 string src;
74                 string partialClassName;
75 #endif
76                 Assembly srcAssembly;
77                 int appAssemblyIndex = -1;
78
79                 internal TemplateParser ()
80                 {
81                         imports = new ArrayList ();
82 #if NET_2_0
83                         AddNamespaces (imports);
84 #else
85                         imports.Add ("System");
86                         imports.Add ("System.Collections");
87                         imports.Add ("System.Collections.Specialized");
88                         imports.Add ("System.Configuration");
89                         imports.Add ("System.Text");
90                         imports.Add ("System.Text.RegularExpressions");
91                         imports.Add ("System.Web");
92                         imports.Add ("System.Web.Caching");
93                         imports.Add ("System.Web.Security");
94                         imports.Add ("System.Web.SessionState");
95                         imports.Add ("System.Web.UI");
96                         imports.Add ("System.Web.UI.WebControls");
97                         imports.Add ("System.Web.UI.HtmlControls");
98 #endif
99
100                         assemblies = new ArrayList ();
101 #if NET_2_0
102                         bool addAssembliesInBin = false;
103                         foreach (AssemblyInfo info in CompilationConfig.Assemblies) {
104                                 if (info.Assembly == "*")
105                                         addAssembliesInBin = true;
106                                 else
107                                         AddAssemblyByName (info.Assembly);
108                         }
109                         if (addAssembliesInBin)
110                                 AddAssembliesInBin ();
111
112                         foreach (NamespaceInfo info in PagesConfig.Namespaces) {
113                                 imports.Add (info.Namespace);
114                         }
115 #else
116                         foreach (string a in CompilationConfig.Assemblies)
117                                 AddAssemblyByName (a);
118                         if (CompilationConfig.AssembliesInBin)
119                                 AddAssembliesInBin ();
120 #endif
121
122                         language = CompilationConfig.DefaultLanguage;
123                 }
124                 
125                 internal void AddApplicationAssembly ()
126                 {
127                         string location = Context.ApplicationInstance.AssemblyLocation;
128                         if (location != typeof (TemplateParser).Assembly.Location) {
129                                 appAssemblyIndex = assemblies.Add (location);
130                         }
131                 }
132
133                 protected abstract Type CompileIntoType ();
134
135 #if NET_2_0
136                 void AddNamespaces (ArrayList imports)
137                 {
138                         if (BuildManager.HaveResources)
139                                 imports.Add ("System.Resources");
140                         
141                         PagesSection pages = WebConfigurationManager.GetSection ("system.web/pages") as PagesSection;
142                         if (pages == null)
143                                 return;
144
145                         NamespaceCollection namespaces = pages.Namespaces;
146                         if (namespaces == null || namespaces.Count == 0)
147                                 return;
148
149                         foreach (NamespaceInfo nsi in namespaces)
150                                 imports.Add (nsi.Namespace);
151                 }
152                 
153                 internal void RegisterConfigControls ()
154                 {
155                         PagesSection pages = WebConfigurationManager.GetSection ("system.web/pages") as PagesSection;
156                         if (pages == null)
157                                 return;
158
159                         TagPrefixCollection controls = pages.Controls;
160                         if (controls == null || controls.Count == 0)
161                                 return;
162
163                         foreach (TagPrefixInfo tpi in controls) {
164                                 if (!String.IsNullOrEmpty (tpi.TagName))
165                                         RegisterCustomControl (tpi.TagPrefix, tpi.TagName, tpi.Source);
166                                 else if (!String.IsNullOrEmpty (tpi.Namespace))
167                                         RegisterNamespace (tpi.TagPrefix, tpi.Namespace, tpi.Assembly);
168                         }
169                 }
170 #endif
171                 
172                 internal void RegisterCustomControl (string tagPrefix, string tagName, string src)
173                 {
174                         string realpath = MapPath (src);
175                         if (String.Compare (realpath, inputFile, false, invariantCulture) == 0)
176                                 return;
177                         
178                         if (!File.Exists (realpath))
179                                 throw new ParseException (Location, "Could not find file \"" + realpath + "\".");
180                         string vpath = UrlUtils.Combine (BaseVirtualDir, src);
181                         Type type = null;
182                         AddDependency (realpath);
183                         try {
184                                 ArrayList other_deps = new ArrayList ();
185                                 type = UserControlParser.GetCompiledType (vpath, realpath, other_deps, Context);
186                                 foreach (string s in other_deps) {
187                                         AddDependency (s);
188                                 }
189                         } catch (ParseException pe) {
190                                 if (this is UserControlParser)
191                                         throw new ParseException (Location, pe.Message, pe);
192                                 throw;
193                         }
194
195                         AddAssembly (type.Assembly, true);
196                         RootBuilder.Foundry.RegisterFoundry (tagPrefix, tagName, type);
197                 }
198
199                 internal void RegisterNamespace (string tagPrefix, string ns, string assembly)
200                 {
201                         AddImport (ns);
202                         Assembly ass = AddAssemblyByName (assembly);
203                         AddDependency (ass.Location);
204                         RootBuilder.Foundry.RegisterFoundry (tagPrefix, ass, ns);
205                 }
206                 
207                 internal virtual void HandleOptions (object obj)
208                 {
209                 }
210
211                 internal static string GetOneKey (Hashtable tbl)
212                 {
213                         foreach (object key in tbl.Keys)
214                                 return key.ToString ();
215
216                         return null;
217                 }
218                 
219                 internal virtual void AddDirective (string directive, Hashtable atts)
220                 {
221                         if (String.Compare (directive, DefaultDirectiveName, true) == 0) {
222                                 if (mainAttributes != null)
223                                         ThrowParseException ("Only 1 " + DefaultDirectiveName + " is allowed");
224
225                                 mainAttributes = atts;
226                                 ProcessMainAttributes (mainAttributes);
227                                 return;
228                         }
229
230                         int cmp = String.Compare ("Assembly", directive, true);
231                         if (cmp == 0) {
232                                 string name = GetString (atts, "Name", null);
233                                 string src = GetString (atts, "Src", null);
234
235                                 if (atts.Count > 0)
236                                         ThrowParseException ("Attribute " + GetOneKey (atts) + " unknown.");
237
238                                 if (name == null && src == null)
239                                         ThrowParseException ("You gotta specify Src or Name");
240                                         
241                                 if (name != null && src != null)
242                                         ThrowParseException ("Src and Name cannot be used together");
243
244                                 if (name != null) {
245                                         AddAssemblyByName (name);
246                                 } else {
247                                         GetAssemblyFromSource (src);
248                                 }
249
250                                 return;
251                         }
252
253                         cmp = String.Compare ("Import", directive, true);
254                         if (cmp == 0) {
255                                 string namesp = GetString (atts, "Namespace", null);
256                                 if (atts.Count > 0)
257                                         ThrowParseException ("Attribute " + GetOneKey (atts) + " unknown.");
258                                 
259                                 if (namesp != null && namesp != "")
260                                         AddImport (namesp);
261                                 return;
262                         }
263
264                         cmp = String.Compare ("Implements", directive, true);
265                         if (cmp == 0) {
266                                 string ifacename = GetString (atts, "Interface", "");
267
268                                 if (atts.Count > 0)
269                                         ThrowParseException ("Attribute " + GetOneKey (atts) + " unknown.");
270                                 
271                                 Type iface = LoadType (ifacename);
272                                 if (iface == null)
273                                         ThrowParseException ("Cannot find type " + ifacename);
274
275                                 if (!iface.IsInterface)
276                                         ThrowParseException (iface + " is not an interface");
277
278                                 AddInterface (iface.FullName);
279                                 return;
280                         }
281
282                         cmp = String.Compare ("OutputCache", directive, true);
283                         if (cmp == 0) {
284                                 output_cache = true;
285                                 
286                                 if (atts ["Duration"] == null)
287                                         ThrowParseException ("The directive is missing a 'duration' attribute.");
288                                 if (atts ["VaryByParam"] == null)
289                                         ThrowParseException ("This directive is missing a 'VaryByParam' " +
290                                                         "attribute, which should be set to \"none\", \"*\", " +
291                                                         "or a list of name/value pairs.");
292
293                                 foreach (DictionaryEntry entry in atts) {
294                                         string key = (string) entry.Key;
295                                         switch (key.ToLower ()) {
296                                         case "duration":
297                                                 oc_duration = Int32.Parse ((string) entry.Value);
298                                                 if (oc_duration < 1)
299                                                         ThrowParseException ("The 'duration' attribute must be set " +
300                                                                         "to a positive integer value");
301                                                 break;
302                                         case "varybyparam":
303                                                 oc_param = (string) entry.Value;
304                                                 if (String.Compare (oc_param, "none") == 0)
305                                                         oc_param = null;
306                                                 break;
307                                         case "varybyheader":
308                                                 oc_header = (string) entry.Value;
309                                                 break;
310                                         case "varybycustom":
311                                                 oc_custom = (string) entry.Value;
312                                                 break;
313                                         case "location":
314                                                 if (!(this is PageParser))
315                                                         goto default;
316
317                                                 try {
318                                                         oc_location = (OutputCacheLocation) Enum.Parse (
319                                                                 typeof (OutputCacheLocation), (string) entry.Value, true);
320                                                 } catch {
321                                                         ThrowParseException ("The 'location' attribute is case sensitive and " +
322                                                                         "must be one of the following values: Any, Client, " +
323                                                                         "Downstream, Server, None, ServerAndClient.");
324                                                 }
325                                                 break;
326                                         case "varybycontrol":
327                                                 if (this is PageParser)
328                                                         goto default;
329
330                                                 oc_controls = (string) entry.Value;
331                                                 break;
332                                         case "shared":
333                                                 if (this is PageParser)
334                                                         goto default;
335
336                                                 try {
337                                                         oc_shared = Boolean.Parse ((string) entry.Value);
338                                                 } catch {
339                                                         ThrowParseException ("The 'shared' attribute is case sensitive" +
340                                                                         " and must be set to 'true' or 'false'.");
341                                                 }
342                                                 break;
343                                         default:
344                                                 ThrowParseException ("The '" + key + "' attribute is not " +
345                                                                 "supported by the 'Outputcache' directive.");
346                                                 break;
347                                         }
348                                         
349                                 }
350                                 
351                                 return;
352                         }
353
354                         ThrowParseException ("Unknown directive: " + directive);
355                 }
356
357                 internal Type LoadType (string typeName)
358                 {
359                         // First try loaded assemblies, then try assemblies in Bin directory.
360                         Type type = null;
361                         bool seenBin = false;
362                         Assembly [] assemblies = AppDomain.CurrentDomain.GetAssemblies ();
363                         foreach (Assembly ass in assemblies) {
364                                 type = ass.GetType (typeName);
365                                 if (type == null)
366                                         continue;
367
368                                 if (Path.GetDirectoryName (ass.Location) != PrivateBinPath) {
369                                         AddAssembly (ass, true);
370                                 } else {
371                                         seenBin = true;
372                                 }
373
374                                 AddDependency (ass.Location);
375                                 return type;
376                         }
377
378                         if (seenBin)
379                                 return null;
380
381                         // Load from bin
382                         if (!Directory.Exists (PrivateBinPath))
383                                 return null;
384
385                         string [] binDlls = Directory.GetFiles (PrivateBinPath, "*.dll");
386                         foreach (string s in binDlls) {
387                                 Assembly binA = Assembly.LoadFrom (s);
388                                 type = binA.GetType (typeName);
389                                 if (type == null)
390                                         continue;
391
392                                 AddDependency (binA.Location);
393                                 return type;
394                         }
395
396                         return null;
397                 }
398
399                 void AddAssembliesInBin ()
400                 {
401                         if (!Directory.Exists (PrivateBinPath))
402                                 return;
403
404                         string [] binDlls = Directory.GetFiles (PrivateBinPath, "*.dll");
405                         foreach (string s in binDlls) {
406                                 assemblies.Add (s);
407                         }
408                 }
409
410                 internal virtual void AddInterface (string iface)
411                 {
412                         if (interfaces == null)
413                                 interfaces = new ArrayList ();
414
415                         if (!interfaces.Contains (iface))
416                                 interfaces.Add (iface);
417                 }
418                 
419                 internal virtual void AddImport (string namesp)
420                 {
421                         if (imports == null)
422                                 imports = new ArrayList ();
423
424                         if (!imports.Contains (namesp))
425                                 imports.Add (namesp);
426                 }
427
428                 internal virtual void AddSourceDependency (string filename)
429                 {
430                         if (dependencies != null && dependencies.Contains (filename)) {
431                                 ThrowParseException ("Circular file references are not allowed. File: " + filename);
432                         }
433
434                         AddDependency (filename);
435                 }
436
437                 internal virtual void AddDependency (string filename)
438                 {
439                         if (filename == "")
440                                 return;
441
442                         if (dependencies == null)
443                                 dependencies = new ArrayList ();
444
445                         if (!dependencies.Contains (filename))
446                                 dependencies.Add (filename);
447                 }
448                 
449                 internal virtual void AddAssembly (Assembly assembly, bool fullPath)
450                 {
451                         if (assembly.Location == "")
452                                 return;
453
454                         if (anames == null)
455                                 anames = new Hashtable ();
456
457                         string name = assembly.GetName ().Name;
458                         string loc = assembly.Location;
459                         if (fullPath) {
460                                 if (!assemblies.Contains (loc)) {
461                                         assemblies.Add (loc);
462                                 }
463
464                                 anames [name] = loc;
465                                 anames [loc] = assembly;
466                         } else {
467                                 if (!assemblies.Contains (name)) {
468                                         assemblies.Add (name);
469                                 }
470
471                                 anames [name] = assembly;
472                         }
473                 }
474
475                 internal virtual Assembly AddAssemblyByFileName (string filename)
476                 {
477                         Assembly assembly = null;
478                         Exception error = null;
479
480                         try {
481                                 assembly = Assembly.LoadFrom (filename);
482                         } catch (Exception e) { error = e; }
483
484                         if (assembly == null)
485                                 ThrowParseException ("Assembly " + filename + " not found", error);
486
487                         AddAssembly (assembly, true);
488                         return assembly;
489                 }
490
491                 internal virtual Assembly AddAssemblyByName (string name)
492                 {
493                         if (anames == null)
494                                 anames = new Hashtable ();
495
496                         if (anames.Contains (name)) {
497                                 object o = anames [name];
498                                 if (o is string)
499                                         o = anames [o];
500
501                                 return (Assembly) o;
502                         }
503
504                         Assembly assembly = null;
505                         Exception error = null;
506                         if (name.IndexOf (',') != -1) {
507                                 try {
508                                         assembly = Assembly.Load (name);
509                                 } catch (Exception e) { error = e; }
510                         }
511
512                         if (assembly == null) {
513                                 try {
514                                         assembly = Assembly.LoadWithPartialName (name);
515                                 } catch (Exception e) { error = e; }
516                         }
517                         
518                         if (assembly == null)
519                                 ThrowParseException ("Assembly " + name + " not found", error);
520
521                         AddAssembly (assembly, true);
522                         return assembly;
523                 }
524
525                 internal virtual void ProcessMainAttributes (Hashtable atts)
526                 {
527                         atts.Remove ("Description"); // ignored
528 #if NET_1_1
529                         atts.Remove ("CodeBehind");  // ignored
530 #endif
531                         atts.Remove ("AspCompat"); // ignored
532
533                         debug = GetBool (atts, "Debug", true);
534                         compilerOptions = GetString (atts, "CompilerOptions", "");
535                         language = GetString (atts, "Language", CompilationConfig.DefaultLanguage);
536                         strictOn = GetBool (atts, "Strict", CompilationConfig.Strict);
537                         explicitOn = GetBool (atts, "Explicit", CompilationConfig.Explicit);
538
539                         string inherits = GetString (atts, "Inherits", null);
540 #if NET_2_0
541                         // In ASP 2, the source file is actually integrated with
542                         // the generated file via the use of partial classes. This
543                         // means that the code file has to be confirmed, but not
544                         // used at this point.
545                         src = GetString (atts, "CodeFile", null);
546
547                         if (src != null && inherits != null) {
548                                 // Make sure the source exists
549                                 src = UrlUtils.Combine (BaseVirtualDir, src);
550                                 string realPath = MapPath (src, false);
551                                 if (!File.Exists (realPath))
552                                         ThrowParseException ("File " + src + " not found");
553
554                                 // Verify that the inherits is a valid identify not a
555                                 // fully-qualified name.
556                                 if (!CodeGenerator.IsValidLanguageIndependentIdentifier (inherits))
557                                         ThrowParseException (String.Format ("'{0}' is not valid for 'inherits'", inherits));
558
559                                 // We are going to create a partial class that shares
560                                 // the same name as the inherits tag, so reset the
561                                 // name. The base type is changed because it is the
562                                 // code file's responsibilty to extend the classes
563                                 // needed.
564                                 partialClassName = inherits;
565
566                                 // Add the code file as an option to the
567                                 // compiler. This lets both files be compiled at once.
568                                 compilerOptions += " \"" + realPath + "\"";
569                         } else if (inherits != null) {
570                                 // We just set the inherits directly because this is a
571                                 // Single-Page model.
572                                 SetBaseType (inherits);
573                         }
574 #else
575                         string src = GetString (atts, "Src", null);
576
577                         if (src != null)
578                                 srcAssembly = GetAssemblyFromSource (src);
579
580                         if (inherits != null)
581                                 SetBaseType (inherits);
582
583                         className = GetString (atts, "ClassName", null);
584                         if (className != null && !CodeGenerator.IsValidLanguageIndependentIdentifier (className))
585                                 ThrowParseException (String.Format ("'{0}' is not valid for 'className'", className));
586 #endif
587
588                         if (atts.Count > 0)
589                                 ThrowParseException ("Unknown attribute: " + GetOneKey (atts));
590                 }
591
592                 internal void SetBaseType (string type)
593                 {
594                         if (type == DefaultBaseTypeName)
595                                 return;
596
597                         Type parent = null;
598                         if (srcAssembly != null)
599                                 parent = srcAssembly.GetType (type);
600
601                         if (parent == null)
602                                 parent = LoadType (type);
603
604                         if (parent == null)
605                                 ThrowParseException ("Cannot find type " + type);
606
607                         if (!DefaultBaseType.IsAssignableFrom (parent))
608                                 ThrowParseException ("The parent type does not derive from " + DefaultBaseType);
609
610                         baseType = parent;
611                 }
612
613                 Assembly GetAssemblyFromSource (string vpath)
614                 {
615                         vpath = UrlUtils.Combine (BaseVirtualDir, vpath);
616                         string realPath = MapPath (vpath, false);
617                         if (!File.Exists (realPath))
618                                 ThrowParseException ("File " + vpath + " not found");
619
620                         AddSourceDependency (realPath);
621
622                         CompilerResults result = CachingCompiler.Compile (language, realPath, realPath, assemblies);
623                         if (result.NativeCompilerReturnValue != 0) {
624                                 StreamReader reader = new StreamReader (realPath);
625                                 throw new CompilationException (realPath, result.Errors, reader.ReadToEnd ());
626                         }
627
628                         AddAssembly (result.CompiledAssembly, true);
629                         return result.CompiledAssembly;
630                 }
631                 
632                 internal abstract Type DefaultBaseType { get; }
633                 internal abstract string DefaultBaseTypeName { get; }
634                 internal abstract string DefaultDirectiveName { get; }
635
636                 internal string InputFile
637                 {
638                         get { return inputFile; }
639                         set { inputFile = value; }
640                 }
641
642 #if NET_2_0
643                 internal bool IsPartial
644                 {
645                         get { return src != null; }
646                 }
647
648                 internal string PartialClassName
649                 {
650                         get { return partialClassName; }
651                 }
652 #endif
653
654                 internal string Text
655                 {
656                         get { return text; }
657                         set { text = value; }
658                 }
659
660                 internal Type BaseType
661                 {
662                         get {
663                                 if (baseType == null)
664                                         baseType = DefaultBaseType;
665
666                                 return baseType;
667                         }
668                 }
669                 
670                 internal string ClassName {
671                         get {
672                                 if (className != null)
673                                         return className;
674
675                                 className = Path.GetFileName (inputFile).Replace ('.', '_');
676                                 className = className.Replace ('-', '_'); 
677                                 className = className.Replace (' ', '_');
678
679                                 if (Char.IsDigit(className[0])) {
680                                         className = "_" + className;
681                                 }
682
683                                 return className;
684                         }
685                 }
686
687                 internal string PrivateBinPath {
688                         get {
689                                 if (privateBinPath != null)
690                                         return privateBinPath;
691
692                                 AppDomainSetup setup = AppDomain.CurrentDomain.SetupInformation;
693                                 privateBinPath = Path.Combine (setup.ApplicationBase, setup.PrivateBinPath);
694
695                                 return privateBinPath;
696                         }
697                 }
698
699                 internal ArrayList Scripts {
700                         get {
701                                 if (scripts == null)
702                                         scripts = new ArrayList ();
703
704                                 return scripts;
705                         }
706                 }
707
708                 internal ArrayList Imports {
709                         get { return imports; }
710                 }
711
712                 internal ArrayList Assemblies {
713                         get {
714                                 if (appAssemblyIndex != -1) {
715                                         object o = assemblies [appAssemblyIndex];
716                                         assemblies.RemoveAt (appAssemblyIndex);
717                                         assemblies.Add (o);
718                                         appAssemblyIndex = -1;
719                                 }
720
721                                 return assemblies;
722                         }
723                 }
724
725                 internal ArrayList Interfaces {
726                         get { return interfaces; }
727                 }
728
729                 internal RootBuilder RootBuilder {
730                         get { return rootBuilder; }
731                         set { rootBuilder = value; }
732                 }
733
734                 internal ArrayList Dependencies {
735                         get { return dependencies; }
736                         set { dependencies = value; }
737                 }
738
739                 internal string CompilerOptions {
740                         get { return compilerOptions; }
741                 }
742
743                 internal string Language {
744                         get { return language; }
745                 }
746
747                 internal bool StrictOn {
748                         get { return strictOn; }
749                 }
750
751                 internal bool ExplicitOn {
752                         get { return explicitOn; }
753                 }
754                 
755                 internal bool Debug {
756                         get { return debug; }
757                 }
758
759                 internal bool OutputCache {
760                         get { return output_cache; }
761                 }
762
763                 internal int OutputCacheDuration {
764                         get { return oc_duration; }
765                 }
766
767                 internal string OutputCacheVaryByHeader {
768                         get { return oc_header; }
769                 }
770
771                 internal string OutputCacheVaryByCustom {
772                         get { return oc_custom; }
773                 }
774
775                 internal string OutputCacheVaryByControls {
776                         get { return oc_controls; }
777                 }
778                 
779                 internal bool OutputCacheShared {
780                         get { return oc_shared; }
781                 }
782                 
783                 internal OutputCacheLocation OutputCacheLocation {
784                         get { return oc_location; }
785                 }
786
787                 internal string OutputCacheVaryByParam {
788                         get { return oc_param; }
789                 }
790
791 #if NET_2_0
792                 internal PagesSection PagesConfig {
793                         get {
794                                 return WebConfigurationManager.GetSection ("system.web/pages") as PagesSection;
795                         }
796                 }
797 #else
798                 internal PagesConfiguration PagesConfig {
799                         get { return PagesConfiguration.GetInstance (Context); }
800                 }
801 #endif
802         }
803 }
804