2 // System.Web.UI.TemplateParser
5 // Duncan Mak (duncan@ximian.com)
6 // Gonzalo Paniagua Javier (gonzalo@ximian.com)
7 // Marek Habersack (mhabersack@novell.com)
9 // (C) 2002,2003 Ximian, Inc. (http://www.ximian.com)
10 // Copyright (C) 2005-2008 Novell, Inc (http://www.novell.com)
12 // Permission is hereby granted, free of charge, to any person obtaining
13 // a copy of this software and associated documentation files (the
14 // "Software"), to deal in the Software without restriction, including
15 // without limitation the rights to use, copy, modify, merge, publish,
16 // distribute, sublicense, and/or sell copies of the Software, and to
17 // permit persons to whom the Software is furnished to do so, subject to
18 // the following conditions:
20 // The above copyright notice and this permission notice shall be
21 // included in all copies or substantial portions of the Software.
23 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
24 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
25 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
26 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
27 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
28 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
29 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
32 using System.CodeDom.Compiler;
33 using System.Collections;
34 using System.Collections.Generic;
35 using System.ComponentModel;
36 using System.Globalization;
38 using System.Reflection;
39 using System.Security.Permissions;
41 using System.Threading;
42 using System.Web.Compilation;
43 using System.Web.Configuration;
44 using System.Web.Hosting;
45 using System.Web.Util;
47 namespace System.Web.UI {
48 internal class ServerSideScript
50 public readonly string Script;
51 public readonly ILocation Location;
53 public ServerSideScript (string script, ILocation location)
61 [AspNetHostingPermission (SecurityAction.LinkDemand, Level = AspNetHostingPermissionLevel.Minimal)]
62 [AspNetHostingPermission (SecurityAction.InheritanceDemand, Level = AspNetHostingPermissionLevel.Minimal)]
63 public abstract class TemplateParser : BaseParser
66 internal enum OutputCacheParsedParams
69 CacheProfile = 0x0002,
71 SqlDependency = 0x0008,
72 VaryByCustom = 0x0010,
73 VaryByHeader = 0x0020,
74 VaryByControl = 0x0040,
75 VaryByContentEncodings = 0x0080
80 Hashtable mainAttributes;
81 ArrayList dependencies;
84 string[] binDirAssemblies;
85 Dictionary <string, bool> namespacesCache;
86 Dictionary <string, bool> imports;
87 List <string> interfaces;
88 List <ServerSideScript> scripts;
90 bool baseTypeIsGlobal = true;
92 RootBuilder rootBuilder;
94 string compilerOptions;
96 bool implicitLanguage;
99 bool linePragmasOn = true;
102 string oc_header, oc_custom, oc_param, oc_controls;
103 string oc_content_encodings, oc_cacheprofile, oc_sqldependency;
105 OutputCacheParsedParams oc_parsed_params = 0;
107 OutputCacheLocation oc_location;
109 // Kludge needed to support pre-parsing of the main directive (see
110 // AspNetGenerator.GetRootBuilderType)
111 internal int allowedMainDirectives = 0;
116 string partialClassName;
117 string codeFileBaseClass;
118 string metaResourceKey;
119 Type codeFileBaseClassType;
120 Type pageParserFilterType;
121 PageParserFilter pageParserFilter;
123 List <UnknownAttributeDescriptor> unknownMainAttributes;
124 Stack <string> includeDirs;
125 List <string> registeredTagNames;
126 ILocation directiveLocation;
128 int appAssemblyIndex = -1;
130 internal TemplateParser ()
132 imports = new Dictionary <string, bool> (StringComparer.Ordinal);
133 LoadConfigDefaults ();
134 assemblies = new ArrayList ();
135 CompilationSection compConfig = CompilationConfig;
136 foreach (AssemblyInfo info in compConfig.Assemblies) {
137 if (info.Assembly != "*")
138 AddAssemblyByName (info.Assembly);
141 language = compConfig.DefaultLanguage;
142 implicitLanguage = true;
145 internal virtual void LoadConfigDefaults ()
147 AddNamespaces (imports);
148 debug = CompilationConfig.Debug;
151 internal void AddApplicationAssembly ()
153 if (Context.ApplicationInstance == null)
154 return; // this may happen if we have Global.asax and have
155 // controls registered from Web.Config
156 string location = Context.ApplicationInstance.AssemblyLocation;
157 if (location != typeof (TemplateParser).Assembly.Location) {
158 appAssemblyIndex = assemblies.Add (location);
162 protected abstract Type CompileIntoType ();
164 internal void AddControl (Type type, IDictionary attributes)
166 AspGenerator generator = AspGenerator;
167 if (generator == null)
169 generator.AddControl (type, attributes);
172 void AddNamespaces (Dictionary <string, bool> imports)
174 if (BuildManager.HaveResources)
175 imports.Add ("System.Resources", true);
177 PagesSection pages = PagesConfig;
181 NamespaceCollection namespaces = pages.Namespaces;
182 if (namespaces == null || namespaces.Count == 0)
185 foreach (NamespaceInfo nsi in namespaces) {
186 string ns = nsi.Namespace;
187 if (imports.ContainsKey (ns))
190 imports.Add (ns, true);
194 internal void RegisterCustomControl (string tagPrefix, string tagName, string src)
196 string realpath = null;
197 bool fileExists = false;
198 VirtualFile vf = null;
199 VirtualPathProvider vpp = HostingEnvironment.VirtualPathProvider;
200 VirtualPath vp = new VirtualPath (src, BaseVirtualDir);
201 string vpAbsolute = vp.Absolute;
203 if (vpp.FileExists (vpAbsolute)) {
205 vf = vpp.GetFile (vpAbsolute);
207 realpath = MapPath (vf.VirtualPath);
211 ThrowParseFileNotFound (src);
213 if (String.Compare (realpath, inputFile, false, Helpers.InvariantCulture) == 0)
216 string vpath = vf.VirtualPath;
219 RegisterTagName (tagPrefix + ":" + tagName);
220 RootBuilder.Foundry.RegisterFoundry (tagPrefix, tagName, vpath);
221 AddDependency (vpath);
222 } catch (ParseException pe) {
223 if (this is UserControlParser)
224 throw new ParseException (Location, pe.Message, pe);
229 internal void RegisterNamespace (string tagPrefix, string ns, string assembly)
234 if (assembly != null && assembly.Length > 0)
235 ass = AddAssemblyByName (assembly);
237 RootBuilder.Foundry.RegisterFoundry (tagPrefix, ass, ns);
240 internal virtual void HandleOptions (object obj)
244 internal static string GetOneKey (Hashtable tbl)
246 foreach (object key in tbl.Keys)
247 return key.ToString ();
252 internal virtual void AddDirective (string directive, Hashtable atts)
254 var pageParserFilter = PageParserFilter;
255 if (String.Compare (directive, DefaultDirectiveName, true, Helpers.InvariantCulture) == 0) {
256 bool allowMainDirective = allowedMainDirectives > 0;
258 if (mainAttributes != null && !allowMainDirective)
259 ThrowParseException ("Only 1 " + DefaultDirectiveName + " is allowed");
261 allowedMainDirectives--;
262 if (mainAttributes != null)
265 if (pageParserFilter != null)
266 pageParserFilter.PreprocessDirective (directive.ToLower (Helpers.InvariantCulture), atts);
268 mainAttributes = atts;
269 ProcessMainAttributes (mainAttributes);
271 } else if (pageParserFilter != null)
272 pageParserFilter.PreprocessDirective (directive.ToLower (Helpers.InvariantCulture), atts);
274 int cmp = String.Compare ("Assembly", directive, true, Helpers.InvariantCulture);
276 string name = GetString (atts, "Name", null);
277 string src = GetString (atts, "Src", null);
280 ThrowParseException ("Attribute " + GetOneKey (atts) + " unknown.");
282 if (name == null && src == null)
283 ThrowParseException ("You gotta specify Src or Name");
285 if (name != null && src != null)
286 ThrowParseException ("Src and Name cannot be used together");
289 AddAssemblyByName (name);
291 GetAssemblyFromSource (src);
297 cmp = String.Compare ("Import", directive, true, Helpers.InvariantCulture);
299 string namesp = GetString (atts, "Namespace", null);
301 ThrowParseException ("Attribute " + GetOneKey (atts) + " unknown.");
307 cmp = String.Compare ("Implements", directive, true, Helpers.InvariantCulture);
309 string ifacename = GetString (atts, "Interface", "");
312 ThrowParseException ("Attribute " + GetOneKey (atts) + " unknown.");
314 Type iface = LoadType (ifacename);
316 ThrowParseException ("Cannot find type " + ifacename);
318 if (!iface.IsInterface)
319 ThrowParseException (iface + " is not an interface");
321 AddInterface (iface.FullName);
325 cmp = String.Compare ("OutputCache", directive, true, Helpers.InvariantCulture);
327 HttpResponse response = HttpContext.Current.Response;
328 if (response != null)
329 response.Cache.SetValidUntilExpires (true);
333 if (atts ["Duration"] == null)
334 ThrowParseException ("The directive is missing a 'duration' attribute.");
335 if (atts ["VaryByParam"] == null && atts ["VaryByControl"] == null)
336 ThrowParseException ("This directive is missing 'VaryByParam' " +
337 "or 'VaryByControl' attribute, which should be set to \"none\", \"*\", " +
338 "or a list of name/value pairs.");
340 foreach (DictionaryEntry entry in atts) {
341 string key = (string) entry.Key;
345 switch (key.ToLower (Helpers.InvariantCulture)) {
347 oc_duration = Int32.Parse ((string) entry.Value);
349 ThrowParseException ("The 'duration' attribute must be set " +
350 "to a positive integer value");
353 case "sqldependency":
354 oc_sqldependency = (string) entry.Value;
359 oc_nostore = Boolean.Parse ((string) entry.Value);
360 oc_parsed_params |= OutputCacheParsedParams.NoStore;
362 ThrowParseException ("The 'NoStore' attribute is case sensitive" +
363 " and must be set to 'true' or 'false'.");
368 oc_cacheprofile = (string) entry.Value;
369 oc_parsed_params |= OutputCacheParsedParams.CacheProfile;
372 case "varybycontentencodings":
373 oc_content_encodings = (string) entry.Value;
374 oc_parsed_params |= OutputCacheParsedParams.VaryByContentEncodings;
378 oc_param = (string) entry.Value;
379 if (String.Compare (oc_param, "none", true, Helpers.InvariantCulture) == 0)
383 oc_header = (string) entry.Value;
384 oc_parsed_params |= OutputCacheParsedParams.VaryByHeader;
387 oc_custom = (string) entry.Value;
388 oc_parsed_params |= OutputCacheParsedParams.VaryByCustom;
391 if (!(this is PageParser))
395 oc_location = (OutputCacheLocation) Enum.Parse (
396 typeof (OutputCacheLocation), (string) entry.Value, true);
397 oc_parsed_params |= OutputCacheParsedParams.Location;
399 ThrowParseException ("The 'location' attribute is case sensitive and " +
400 "must be one of the following values: Any, Client, " +
401 "Downstream, Server, None, ServerAndClient.");
404 case "varybycontrol":
405 oc_controls = (string) entry.Value;
406 oc_parsed_params |= OutputCacheParsedParams.VaryByControl;
409 if (this is PageParser)
413 oc_shared = Boolean.Parse ((string) entry.Value);
415 ThrowParseException ("The 'shared' attribute is case sensitive" +
416 " and must be set to 'true' or 'false'.");
420 ThrowParseException ("The '" + key + "' attribute is not " +
421 "supported by the 'Outputcache' directive.");
430 ThrowParseException ("Unknown directive: " + directive);
433 internal Type LoadType (string typeName)
435 Type type = HttpApplication.LoadType (typeName);
438 Assembly asm = type.Assembly;
439 string location = asm.Location;
441 string dirname = Path.GetDirectoryName (location);
442 bool doAddAssembly = true;
443 if (dirname == HttpApplication.BinDirectory)
444 doAddAssembly = false;
447 AddAssembly (asm, true);
452 internal virtual void AddInterface (string iface)
454 if (interfaces == null)
455 interfaces = new List <string> ();
457 if (!interfaces.Contains (iface))
458 interfaces.Add (iface);
461 internal virtual void AddImport (string namesp)
463 if (namesp == null || namesp.Length == 0)
467 imports = new Dictionary <string, bool> (StringComparer.Ordinal);
469 if (imports.ContainsKey (namesp))
472 imports.Add (namesp, true);
473 AddAssemblyForNamespace (namesp);
476 void AddAssemblyForNamespace (string namesp)
478 if (binDirAssemblies == null)
479 binDirAssemblies = HttpApplication.BinDirectoryAssemblies;
480 if (binDirAssemblies.Length == 0)
483 if (namespacesCache == null)
484 namespacesCache = new Dictionary <string, bool> ();
485 else if (namespacesCache.ContainsKey (namesp))
488 foreach (Assembly asm in AppDomain.CurrentDomain.GetAssemblies ())
489 if (FindNamespaceInAssembly (asm, namesp))
492 IList tla = BuildManager.TopLevelAssemblies;
493 if (tla != null && tla.Count > 0) {
494 foreach (Assembly asm in tla) {
495 if (FindNamespaceInAssembly (asm, namesp))
501 foreach (string s in binDirAssemblies) {
502 a = Assembly.LoadFrom (s);
503 if (FindNamespaceInAssembly (a, namesp))
508 bool FindNamespaceInAssembly (Assembly asm, string namesp)
513 asmTypes = asm.GetTypes ();
514 } catch (ReflectionTypeLoadException) {
519 foreach (Type type in asmTypes) {
520 if (String.Compare (type.Namespace, namesp, StringComparison.Ordinal) == 0) {
521 namespacesCache.Add (namesp, true);
522 AddAssembly (asm, true);
530 internal virtual void AddSourceDependency (string filename)
532 if (dependencies != null && dependencies.Contains (filename))
533 ThrowParseException ("Circular file references are not allowed. File: " + filename);
535 AddDependency (filename);
538 internal virtual void AddDependency (string filename)
540 if (filename == null || filename == String.Empty)
543 if (dependencies == null)
544 dependencies = new ArrayList ();
546 if (!dependencies.Contains (filename))
547 dependencies.Add (filename);
550 internal virtual void AddAssembly (Assembly assembly, bool fullPath)
552 if (assembly == null || assembly.Location == String.Empty)
556 anames = new Hashtable ();
558 string name = assembly.GetName ().Name;
559 string loc = assembly.Location;
561 if (!assemblies.Contains (loc)) {
562 assemblies.Add (loc);
566 anames [loc] = assembly;
568 if (!assemblies.Contains (name)) {
569 assemblies.Add (name);
572 anames [name] = assembly;
576 internal virtual Assembly AddAssemblyByFileName (string filename)
578 Assembly assembly = null;
579 Exception error = null;
582 assembly = Assembly.LoadFrom (filename);
583 } catch (Exception e) { error = e; }
585 if (assembly == null)
586 ThrowParseException ("Assembly " + filename + " not found", error);
588 AddAssembly (assembly, true);
592 internal virtual Assembly AddAssemblyByName (string name)
595 anames = new Hashtable ();
597 if (anames.Contains (name)) {
598 object o = anames [name];
605 Assembly assembly = null;
606 Exception error = null;
608 assembly = Assembly.Load (name);
609 } catch (Exception e) { error = e; }
611 if (assembly == null) {
613 assembly = Assembly.LoadWithPartialName (name);
614 } catch (Exception e) { error = e; }
617 if (assembly == null)
618 ThrowParseException ("Assembly " + name + " not found", error);
620 AddAssembly (assembly, true);
624 internal virtual void ProcessMainAttributes (Hashtable atts)
626 directiveLocation = new System.Web.Compilation.Location (Location);
627 CompilationSection compConfig;
629 compConfig = CompilationConfig;
631 atts.Remove ("Description"); // ignored
632 atts.Remove ("CodeBehind"); // ignored
633 atts.Remove ("AspCompat"); // ignored
635 debug = GetBool (atts, "Debug", compConfig.Debug);
636 compilerOptions = GetString (atts, "CompilerOptions", "");
637 language = GetString (atts, "Language", "");
638 if (language.Length != 0)
639 implicitLanguage = false;
641 language = compConfig.DefaultLanguage;
643 strictOn = GetBool (atts, "Strict", compConfig.Strict);
644 explicitOn = GetBool (atts, "Explicit", compConfig.Explicit);
645 if (atts.ContainsKey ("LinePragmas"))
646 linePragmasOn = GetBool (atts, "LinePragmas", true);
648 string inherits = GetString (atts, "Inherits", null);
649 string srcRealPath = null;
651 // In ASP 2, the source file is actually integrated with
652 // the generated file via the use of partial classes. This
653 // means that the code file has to be confirmed, but not
654 // used at this point.
655 src = GetString (atts, "CodeFile", null);
656 codeFileBaseClass = GetString (atts, "CodeFileBaseClass", null);
658 if (src == null && codeFileBaseClass != null)
659 ThrowParseException ("The 'CodeFileBaseClass' attribute cannot be used without a 'CodeFile' attribute");
661 string legacySrc = GetString (atts, "Src", null);
662 if (legacySrc != null) {
663 legacySrc = UrlUtils.Combine (BaseVirtualDir, legacySrc);
664 GetAssemblyFromSource (legacySrc);
668 legacySrc = MapPath (legacySrc, false);
669 srcRealPath = legacySrc;
670 if (!File.Exists (srcRealPath))
671 ThrowParseException ("File " + src + " not found");
675 legacySrc = MapPath (legacySrc, false);
677 AddDependency (legacySrc);
680 if (!srcIsLegacy && src != null && inherits != null) {
681 // Make sure the source exists
682 src = UrlUtils.Combine (BaseVirtualDir, src);
683 srcRealPath = MapPath (src, false);
685 if (!HostingEnvironment.VirtualPathProvider.FileExists (src))
686 ThrowParseException ("File " + src + " not found");
688 // We are going to create a partial class that shares
689 // the same name as the inherits tag, so reset the
690 // name. The base type is changed because it is the
691 // code file's responsibilty to extend the classes
693 partialClassName = inherits;
695 // Add the code file as an option to the
696 // compiler. This lets both files be compiled at once.
697 compilerOptions += " \"" + srcRealPath + "\"";
699 if (codeFileBaseClass != null) {
701 codeFileBaseClassType = LoadType (codeFileBaseClass);
702 } catch (Exception) {
705 if (codeFileBaseClassType == null)
706 ThrowParseException ("Could not load type '{0}'", codeFileBaseClass);
708 } else if (inherits != null) {
709 // We just set the inherits directly because this is a
710 // Single-Page model.
711 SetBaseType (inherits);
715 if (VirtualPathUtility.IsAbsolute (src))
716 src = VirtualPathUtility.ToAppRelative (src);
720 className = GetString (atts, "ClassName", null);
721 if (className != null) {
722 string [] identifiers = className.Split ('.');
723 for (int i = 0; i < identifiers.Length; i++)
724 if (!CodeGenerator.IsValidLanguageIndependentIdentifier (identifiers [i]))
725 ThrowParseException (String.Format ("'{0}' is not a valid "
726 + "value for attribute 'classname'.", className));
729 if (this is TemplateControlParser)
730 metaResourceKey = GetString (atts, "meta:resourcekey", null);
732 if (inherits != null && (this is PageParser || this is UserControlParser) && atts.Count > 0) {
733 if (unknownMainAttributes == null)
734 unknownMainAttributes = new List <UnknownAttributeDescriptor> ();
737 foreach (DictionaryEntry de in atts) {
738 key = de.Key as string;
739 val = de.Value as string;
741 if (String.IsNullOrEmpty (key) || String.IsNullOrEmpty (val))
743 CheckUnknownAttribute (key, val, inherits);
749 ThrowParseException ("Unknown attribute: " + GetOneKey (atts));
752 void RegisterTagName (string tagName)
754 if (registeredTagNames == null)
755 registeredTagNames = new List <string> ();
757 if (registeredTagNames.Contains (tagName))
760 registeredTagNames.Add (tagName);
763 void CheckUnknownAttribute (string name, string val, string inherits)
765 MemberInfo mi = null;
766 bool missing = false;
767 string memberName = name.Trim ().ToLower (Helpers.InvariantCulture);
768 Type parent = codeFileBaseClassType;
774 MemberInfo[] infos = parent.GetMember (memberName,
775 MemberTypes.Field | MemberTypes.Property,
776 BindingFlags.Public | BindingFlags.Instance |
777 BindingFlags.IgnoreCase | BindingFlags.Static);
778 if (infos.Length != 0) {
779 // prefer public properties to public methods (it's what MS.NET does)
780 foreach (MemberInfo tmp in infos) {
781 if (tmp is PropertyInfo) {
790 } catch (Exception) {
794 ThrowParseException (
795 "Error parsing attribute '{0}': Type '{1}' does not have a public property named '{0}'",
796 memberName, inherits);
798 Type memberType = null;
799 if (mi is PropertyInfo) {
800 PropertyInfo pi = mi as PropertyInfo;
803 ThrowParseException (
804 "Error parsing attribute '{0}': The '{0}' property is read-only and cannot be set.",
806 memberType = pi.PropertyType;
807 } else if (mi is FieldInfo) {
808 memberType = ((FieldInfo)mi).FieldType;
810 ThrowParseException ("Could not determine member the kind of '{0}' in base type '{1}",
811 memberName, inherits);
812 TypeConverter converter = TypeDescriptor.GetConverter (memberType);
813 bool convertible = true;
816 if (converter == null || !converter.CanConvertFrom (typeof (string)))
821 value = converter.ConvertFromInvariantString (val);
822 } catch (Exception) {
828 ThrowParseException ("Error parsing attribute '{0}': Cannot create an object of type '{1}' from its string representation '{2}' for the '{3}' property.",
829 memberName, memberType, val, mi.Name);
831 UnknownAttributeDescriptor desc = new UnknownAttributeDescriptor (mi, value);
832 unknownMainAttributes.Add (desc);
835 internal void SetBaseType (string type)
838 if (type == null || type == DefaultBaseTypeName)
839 parent = DefaultBaseType;
843 if (parent == null) {
844 parent = LoadType (type);
847 ThrowParseException ("Cannot find type " + type);
849 if (!DefaultBaseType.IsAssignableFrom (parent))
850 ThrowParseException ("The parent type '" + type + "' does not derive from " + DefaultBaseType);
853 var pageParserFilter = PageParserFilter;
854 if (pageParserFilter != null && !pageParserFilter.AllowBaseType (parent))
855 throw new HttpException ("Base type '" + parent + "' is not allowed.");
860 internal void SetLanguage (string language)
862 this.language = language;
863 implicitLanguage = false;
866 internal void PushIncludeDir (string dir)
868 if (includeDirs == null)
869 includeDirs = new Stack <string> (1);
871 includeDirs.Push (dir);
874 internal string PopIncludeDir ()
876 if (includeDirs == null || includeDirs.Count == 0)
879 return includeDirs.Pop () as string;
882 Assembly GetAssemblyFromSource (string vpath)
884 vpath = UrlUtils.Combine (BaseVirtualDir, vpath);
885 string realPath = MapPath (vpath, false);
886 if (!File.Exists (realPath))
887 ThrowParseException ("File " + vpath + " not found");
889 AddSourceDependency (vpath);
891 CompilerResults result;
893 CompilerParameters parameters;
894 CodeDomProvider provider = BaseCompiler.CreateProvider (HttpContext.Current, language, out parameters, out tmp);
895 if (provider == null)
896 throw new HttpException ("Cannot find provider for language '" + language + "'.");
898 AssemblyBuilder abuilder = new AssemblyBuilder (provider);
899 abuilder.CompilerOptions = parameters;
900 abuilder.AddAssemblyReference (BuildManager.GetReferencedAssemblies () as List <Assembly>);
901 abuilder.AddCodeFile (realPath);
902 result = abuilder.BuildAssembly (new VirtualPath (vpath));
904 if (result.NativeCompilerReturnValue != 0) {
905 using (StreamReader reader = new StreamReader (realPath)) {
906 throw new CompilationException (realPath, result.Errors, reader.ReadToEnd ());
910 AddAssembly (result.CompiledAssembly, true);
911 return result.CompiledAssembly;
914 internal abstract string DefaultBaseTypeName { get; }
915 internal abstract string DefaultDirectiveName { get; }
917 internal bool LinePragmasOn {
918 get { return linePragmasOn; }
921 internal byte[] MD5Checksum {
922 get { return md5checksum; }
923 set { md5checksum = value; }
926 internal PageParserFilter PageParserFilter {
928 if (pageParserFilter != null)
929 return pageParserFilter;
931 Type t = PageParserFilterType;
935 pageParserFilter = Activator.CreateInstance (t) as PageParserFilter;
936 pageParserFilter.Initialize (this);
938 return pageParserFilter;
942 internal Type PageParserFilterType {
944 if (pageParserFilterType == null) {
945 string typeName = PagesConfig.PageParserFilterType;
946 if (String.IsNullOrEmpty (typeName))
949 pageParserFilterType = HttpApplication.LoadType (typeName, true);
952 return pageParserFilterType;
956 internal Type DefaultBaseType {
958 Type type = Type.GetType (DefaultBaseTypeName, true);
964 internal ILocation DirectiveLocation {
965 get { return directiveLocation; }
968 internal string ParserDir {
970 if (includeDirs == null || includeDirs.Count == 0)
973 return includeDirs.Peek () as string;
977 internal string InputFile
979 get { return inputFile; }
980 set { inputFile = value; }
983 internal bool IsPartial {
984 get { return (!srcIsLegacy && src != null); }
987 internal string CodeBehindSource {
996 internal string PartialClassName {
997 get { return partialClassName; }
1000 internal string CodeFileBaseClass {
1001 get { return codeFileBaseClass; }
1004 internal string MetaResourceKey {
1005 get { return metaResourceKey; }
1008 internal Type CodeFileBaseClassType
1010 get { return codeFileBaseClassType; }
1013 internal List <UnknownAttributeDescriptor> UnknownMainAttributes
1015 get { return unknownMainAttributes; }
1018 internal string Text {
1019 get { return text; }
1020 set { text = value; }
1023 internal Type BaseType {
1025 if (baseType == null)
1026 SetBaseType (DefaultBaseTypeName);
1032 internal bool BaseTypeIsGlobal {
1033 get { return baseTypeIsGlobal; }
1034 set { baseTypeIsGlobal = value; }
1037 static long autoClassCounter = 0;
1039 internal string EncodeIdentifier (string value)
1041 if (value == null || value.Length == 0 || CodeGenerator.IsValidLanguageIndependentIdentifier (value))
1044 StringBuilder ret = new StringBuilder ();
1046 char ch = value [0];
1047 switch (Char.GetUnicodeCategory (ch)) {
1048 case UnicodeCategory.LetterNumber:
1049 case UnicodeCategory.LowercaseLetter:
1050 case UnicodeCategory.TitlecaseLetter:
1051 case UnicodeCategory.UppercaseLetter:
1052 case UnicodeCategory.OtherLetter:
1053 case UnicodeCategory.ModifierLetter:
1054 case UnicodeCategory.ConnectorPunctuation:
1058 case UnicodeCategory.DecimalDigitNumber:
1068 for (int i = 1; i < value.Length; i++) {
1070 switch (Char.GetUnicodeCategory (ch)) {
1071 case UnicodeCategory.LetterNumber:
1072 case UnicodeCategory.LowercaseLetter:
1073 case UnicodeCategory.TitlecaseLetter:
1074 case UnicodeCategory.UppercaseLetter:
1075 case UnicodeCategory.OtherLetter:
1076 case UnicodeCategory.ModifierLetter:
1077 case UnicodeCategory.ConnectorPunctuation:
1078 case UnicodeCategory.DecimalDigitNumber:
1079 case UnicodeCategory.NonSpacingMark:
1080 case UnicodeCategory.SpacingCombiningMark:
1081 case UnicodeCategory.Format:
1091 return ret.ToString ();
1094 internal string ClassName {
1096 if (className != null)
1099 string physPath = HttpContext.Current.Request.PhysicalApplicationPath;
1102 if (String.IsNullOrEmpty (inputFile)) {
1104 using (StreamReader sr = Reader as StreamReader) {
1106 FileStream fr = sr.BaseStream as FileStream;
1114 if (String.IsNullOrEmpty (inFile)) {
1115 // generate a unique class name
1117 suffix = Interlocked.Increment (ref autoClassCounter);
1118 className = String.Format ("autoclass_nosource_{0:x}", suffix);
1122 if (StrUtils.StartsWith (inFile, physPath))
1123 className = inputFile.Substring (physPath.Length).ToLower (Helpers.InvariantCulture);
1125 className = Path.GetFileName (inputFile);
1126 className = EncodeIdentifier (className);
1131 internal List <ServerSideScript> Scripts {
1133 if (scripts == null)
1134 scripts = new List <ServerSideScript> ();
1140 internal Dictionary <string, bool> Imports {
1141 get { return imports; }
1144 internal List <string> Interfaces {
1145 get { return interfaces; }
1148 internal ArrayList Assemblies {
1150 if (appAssemblyIndex != -1) {
1151 object o = assemblies [appAssemblyIndex];
1152 assemblies.RemoveAt (appAssemblyIndex);
1154 appAssemblyIndex = -1;
1161 internal RootBuilder RootBuilder {
1163 if (rootBuilder != null)
1165 AspGenerator generator = AspGenerator;
1166 if (generator != null)
1167 rootBuilder = generator.RootBuilder;
1171 set { rootBuilder = value; }
1174 internal ArrayList Dependencies {
1175 get { return dependencies; }
1176 set { dependencies = value; }
1179 internal string CompilerOptions {
1180 get { return compilerOptions; }
1183 internal string Language {
1184 get { return language; }
1187 internal bool ImplicitLanguage {
1188 get { return implicitLanguage; }
1191 internal bool StrictOn {
1192 get { return strictOn; }
1195 internal bool ExplicitOn {
1196 get { return explicitOn; }
1199 internal bool Debug {
1200 get { return debug; }
1203 internal bool OutputCache {
1204 get { return output_cache; }
1207 internal int OutputCacheDuration {
1208 get { return oc_duration; }
1211 internal OutputCacheParsedParams OutputCacheParsedParameters {
1212 get { return oc_parsed_params; }
1215 internal string OutputCacheSqlDependency {
1216 get { return oc_sqldependency; }
1219 internal string OutputCacheCacheProfile {
1220 get { return oc_cacheprofile; }
1223 internal string OutputCacheVaryByContentEncodings {
1224 get { return oc_content_encodings; }
1227 internal bool OutputCacheNoStore {
1228 get { return oc_nostore; }
1231 internal virtual TextReader Reader {
1232 get { return null; }
1236 internal string OutputCacheVaryByHeader {
1237 get { return oc_header; }
1240 internal string OutputCacheVaryByCustom {
1241 get { return oc_custom; }
1244 internal string OutputCacheVaryByControls {
1245 get { return oc_controls; }
1248 internal bool OutputCacheShared {
1249 get { return oc_shared; }
1252 internal OutputCacheLocation OutputCacheLocation {
1253 get { return oc_location; }
1256 internal string OutputCacheVaryByParam {
1257 get { return oc_param; }
1260 internal List <string> RegisteredTagNames {
1261 get { return registeredTagNames; }
1264 internal PagesSection PagesConfig {
1265 get { return GetConfigSection <PagesSection> ("system.web/pages") as PagesSection; }
1268 internal AspGenerator AspGenerator {