* System.Web.dll.sources: new files in System.Web.Configuration.
* System.Web.Configuration/CompilationConfiguration.cs:
* System.Web.Configuration/CompilationConfigurationHandler.cs:
* System.Web.Configuration/CompilerCollection.cs:
* System.Web.Configuration/WebCompiler.cs: new files that process and
store system.web/compilation info (compilers + assemblies).
* System.Web.Configuration/HttpHandlersSectionHandler.cs: added option
for an attribute to be empty.
* System.Web.UI/BaseParser.cs: added CompilationConfig property.
* System.Web.UI/TemplateParser.cs:
* System.Web.UI/SimpleWebHandlerParser.cs: added CompilationConfig
property. Don't hardcode assembly names any more, assemblies in bin
are added depending on the configuration. The default language is
also taken from the configuration.
* System.Web.Compilation/BaseCompiler.cs: now gets the CodeCompiler
from configuration files.
In short, this changes make our ASP.NET support any language
that has CodeDom CodeCompiler and CodeGenerator.
VB.NET currently fails because of its buggy handling of options.
svn path=/trunk/mcs/; revision=19035
using System.Reflection;
using System.Text;
using System.Web.UI;
-//temp:
-using Microsoft.CSharp;
+using System.Web.Configuration;
using System.IO;
namespace System.Web.Compilation
return a.GetType (mainClassExpr.Type.BaseType, true);
}
- //TODO: get the compiler and default options from system.web/compileroptions
- provider = new CSharpCodeProvider ();
+ string lang = parser.Language;
+ CompilationConfiguration config;
+
+ config = CompilationConfiguration.GetInstance (parser.Context);
+ provider = config.GetProvider (lang);
+ if (provider == null)
+ throw new HttpException ("Configuration error. Language not supported: " +
+ lang, 500);
+
compiler = provider.CreateCompiler ();
CreateMethods ();
compilerParameters.IncludeDebugInformation = parser.Debug;
CompilerResults results = CachingCompiler.Compile (this);
CheckCompilerErrors (results);
+ if (results.CompiledAssembly == null)
+ throw new CompilationException (parser.InputFile, results.Errors,
+ "No assembly returned after compilation!?");
return results.CompiledAssembly.GetType (mainClassExpr.Type.BaseType, true);
}
+2003-10-14 Gonzalo Paniagua Javier <gonzalo@ximian.com>
+
+ * System.Web.Compilation/BaseCompiler.cs: now gets the CodeCompiler
+ from configuration files.
+
2003-10-13 Gonzalo Paniagua Javier <gonzalo@ximian.com>
* Directive.cs: new attribute for @Page directive in 1.1.
+2003-10-14 Gonzalo Paniagua Javier <gonzalo@ximian.com>
+
+ * CompilationConfiguration.cs:
+ * CompilationConfigurationHandler.cs:
+ * CompilerCollection.cs:
+ * WebCompiler.cs: new files that process and store
+ system.web/compilation info (compilers + assemblies).
+
+ * HttpHandlersSectionHandler.cs: added option for an attribute to be
+ empty.
+
2003-10-10 Gonzalo Paniagua Javier <gonzalo@ximian.com>
* WebControlsSectionHandler.cs: new file to handle <webControls>
--- /dev/null
+//
+// System.Web.Configuration.CompilationConfiguration
+//
+// Authors:
+// Gonzalo Paniagua Javier (gonzalo@ximian.com)
+//
+// (C) 2003 Ximian, Inc (http://www.ximian.com)
+//
+
+using System;
+using System.CodeDom.Compiler;
+using System.Collections;
+using System.Configuration;
+using System.IO;
+using System.Web;
+using System.Xml;
+
+namespace System.Web.Configuration
+{
+ sealed class CompilationConfiguration
+ {
+ bool debug = false;
+ bool batch = false;
+ int batch_timeout;
+ string default_language = "c#";
+ bool _explicit = true;
+ int max_batch_size = 30;
+ int max_batch_file_size = 3000;
+ int num_recompiles_before_app_restart = 15;
+ bool strict = false;
+ string temp_directory;
+ CompilerCollection compilers;
+ ArrayList assemblies;
+ bool assembliesInBin = false;
+
+ /* Only the config. handler should create instances of this. Use GetInstance (context) */
+ public CompilationConfiguration (object p)
+ {
+ CompilationConfiguration parent = p as CompilationConfiguration;
+ if (parent != null)
+ Init (parent);
+
+ if (compilers == null)
+ compilers = new CompilerCollection ();
+
+ if (assemblies == null)
+ assemblies = new ArrayList ();
+
+ if (temp_directory == null)
+ temp_directory = Path.GetTempPath ();
+ }
+
+ static public CompilationConfiguration GetInstance (HttpContext context)
+ {
+ CompilationConfiguration config;
+ config = HttpContext.Context.GetConfig ("system.web/compilation")
+ as CompilationConfiguration;
+
+ if (config == null)
+ throw new HttpException ("Configuration error.", 500);
+
+ return config;
+ }
+
+ public CodeDomProvider GetProvider (string language)
+ {
+ WebCompiler compiler = Compilers [language];
+ if (compiler == null)
+ return null;
+
+ if (compiler.Provider != null)
+ return compiler.Provider;
+
+ Type t = Type.GetType (compiler.Type);
+ compiler.Provider = Activator.CreateInstance (t) as CodeDomProvider;
+ return compiler.Provider;
+ }
+
+ void Init (CompilationConfiguration parent)
+ {
+ debug = parent.debug;
+ batch = parent.batch;
+ batch_timeout = parent.batch_timeout;
+ default_language = parent.default_language;
+ _explicit = parent._explicit;
+ max_batch_size = parent.max_batch_size;
+ max_batch_file_size = parent.max_batch_file_size;
+ num_recompiles_before_app_restart = parent.num_recompiles_before_app_restart;
+ strict = parent.strict;
+ temp_directory = parent.temp_directory;
+ compilers = new CompilerCollection (parent.compilers);
+ ArrayList p = parent.assemblies;
+ ICollection coll = (p == null) ? (ICollection) new object [0] : p;
+ assemblies = new ArrayList (coll);
+ }
+
+ public bool Debug {
+ get { return debug; }
+ set { debug = value; }
+ }
+
+ public bool Batch {
+ get { return batch; }
+ set { batch = value; }
+ }
+
+ public int BatchTimeout {
+ get { return batch_timeout; }
+ set { batch_timeout = value; }
+ }
+
+ public string DefaultLanguage {
+ get { return default_language; }
+ set { default_language = value; }
+ }
+
+ public bool Explicit {
+ get { return _explicit; }
+ set { _explicit = value; }
+ }
+
+ public int MaxBatchSize {
+ get { return max_batch_size; }
+ set { max_batch_size = value; }
+ }
+
+ public int MaxBatchFileSize {
+ get { return max_batch_file_size; }
+ set { max_batch_file_size = value; }
+ }
+
+ public int NumRecompilesBeforeAppRestart {
+ get { return num_recompiles_before_app_restart; }
+ set { num_recompiles_before_app_restart = value; }
+ }
+
+ public bool Strict {
+ get { return strict; }
+ set { strict = value; }
+ }
+
+ public string TempDirectory {
+ get { return temp_directory; }
+ set {
+ if (value == null || value == "")
+ value = Path.GetTempPath ();
+
+ if (!Directory.Exists (value))
+ throw new ArgumentException ("Directory does not exist");
+
+ temp_directory = value;
+ }
+ }
+
+ public CompilerCollection Compilers {
+ get { return compilers; }
+ }
+
+ public ArrayList Assemblies {
+ get { return assemblies; }
+ }
+
+ public bool AssembliesInBin {
+ get { return assembliesInBin; }
+ set { assembliesInBin = value; }
+ }
+ }
+}
+
--- /dev/null
+//
+// System.Web.Configuration.CompilationConfigurationHandler
+//
+// Authors:
+// Gonzalo Paniagua Javier (gonzalo@ximian.com)
+//
+// (C) 2003 Ximian, Inc (http://www.ximian.com)
+//
+
+using System;
+using System.Collections;
+using System.Configuration;
+using System.Xml;
+
+namespace System.Web.Configuration
+{
+ class CompilationConfigurationHandler : IConfigurationSectionHandler
+ {
+ public object Create (object parent, object context, XmlNode section)
+ {
+ CompilationConfiguration config = new CompilationConfiguration (parent);
+
+ config.TempDirectory = AttValue ("tempDirectory", section, true);
+ config.DefaultLanguage = AttValue ("defaultLanguage", section);
+ if (config.DefaultLanguage == null)
+ config.DefaultLanguage = "c#";
+
+ config.Debug = AttBoolValue ("debug", section, false);
+ config.Batch = AttBoolValue ("batch", section, false);
+ config.Explicit = AttBoolValue ("explicit", section, true);
+ config.Strict = AttBoolValue ("strict", section, false);
+ config.BatchTimeout = AttUIntValue ("batchTimeout", section, 0);
+ config.MaxBatchSize = AttUIntValue ("maxBatchSize", section, 0);
+ config.MaxBatchFileSize = AttUIntValue ("maxBatchFileSize", section, 0);
+ config.NumRecompilesBeforeAppRestart =
+ AttUIntValue ("numRecompilesBeforeAppRestart", section, 15);
+
+ if (section.Attributes != null && section.Attributes.Count != 0)
+ ThrowException ("Unrecognized attribute.", section);
+
+ XmlNodeList authNodes = section.ChildNodes;
+ foreach (XmlNode child in authNodes) {
+ XmlNodeType ntype = child.NodeType;
+ if (ntype != XmlNodeType.Element)
+ continue;
+
+ if (child.Name == "compilers") {
+ ReadCompilers (child.ChildNodes, config);
+ continue;
+ }
+
+ if (child.Name == "assemblies") {
+ ReadAssemblies (child.ChildNodes, config);
+ continue;
+ }
+
+ ThrowException ("Unexpected element", child);
+ }
+
+ return config;
+ }
+
+ static void ReadCompilers (XmlNodeList nodes, CompilationConfiguration config)
+ {
+ foreach (XmlNode child in nodes) {
+ XmlNodeType ntype = child.NodeType;
+ if (ntype != XmlNodeType.Element)
+ continue;
+
+ if (child.Name != "compiler")
+ ThrowException ("Unexpected element", child);
+
+ WebCompiler compiler = new WebCompiler ();
+ compiler.Languages = AttValue ("language", child);
+ compiler.Extension = AttValue ("extension", child);
+ compiler.Type = AttValue ("type", child);
+ compiler.CompilerOptions = AttValue ("compilerOptions", child, true, true);
+ compiler.WarningLevel = AttUIntValue ("warningLevel", child, 0);
+ config.Compilers [compiler.Languages] = compiler;
+ }
+ }
+
+ static void ReadAssemblies (XmlNodeList nodes, CompilationConfiguration config)
+ {
+ ArrayList assemblies = config.Assemblies;
+
+ foreach (XmlNode child in nodes) {
+ XmlNodeType ntype = child.NodeType;
+ if (ntype != XmlNodeType.Element)
+ continue;
+
+ if (child.Name == "clear") {
+ assemblies.Clear ();
+ config.AssembliesInBin = false;
+ continue;
+ }
+
+ string aname = AttValue ("assembly", child);
+ if (child.Name == "add") {
+ if (aname == "*") {
+ config.AssembliesInBin = true;
+ continue;
+ }
+
+ aname = aname + ".dll";
+ if (!assemblies.Contains (aname))
+ assemblies.Add (aname);
+
+ continue;
+ }
+
+ if (child.Name == "remove") {
+ if (aname == "*") {
+ config.AssembliesInBin = false;
+ continue;
+ }
+ aname = aname + ".dll";
+ assemblies.Remove (aname);
+ continue;
+ }
+
+ ThrowException ("Unexpected element " + child.Name, child);
+ }
+ }
+
+ static string AttValue (string name, XmlNode node, bool optional)
+ {
+ return AttValue (name, node, optional, false);
+ }
+
+ static string AttValue (string name, XmlNode node, bool optional, bool allowEmpty)
+ {
+ return HandlersUtil.ExtractAttributeValue (name, node, optional, allowEmpty);
+ }
+
+ static bool AttBoolValue (string name, XmlNode node, bool _default)
+ {
+ string v = AttValue (name, node, true);
+ if (v == null)
+ return _default;
+
+ bool result = (v == "true");
+ if (!result && v != "false")
+ ThrowException ("Invalid boolean value in " + name, node);
+
+ return result;
+ }
+
+ static int AttUIntValue (string name, XmlNode node, int _default)
+ {
+ string v = AttValue (name, node, true);
+ if (v == null)
+ return _default;
+
+ int result = 0;
+ try {
+ result = (int) UInt32.Parse (v);
+ } catch {
+ ThrowException ("Invalid number in " + name, node);
+ }
+
+ return result;
+ }
+
+ static string AttValue (string name, XmlNode node)
+ {
+ return HandlersUtil.ExtractAttributeValue (name, node, true);
+ }
+
+ static void ThrowException (string message, XmlNode node)
+ {
+ HandlersUtil.ThrowException (message, node);
+ }
+ }
+}
+
--- /dev/null
+//
+// System.Web.Configuration.CompilerCollection
+//
+// Authors:
+// Gonzalo Paniagua Javier (gonzalo@ximian.com)
+//
+// (C) 2003 Ximian, Inc (http://www.ximian.com)
+//
+
+using System;
+using System.Collections;
+
+namespace System.Web.Configuration
+{
+ sealed class CompilerCollection
+ {
+ Hashtable compilers;
+
+ public CompilerCollection () : this (null) {}
+
+ public CompilerCollection (CompilerCollection parent)
+ {
+ compilers = new Hashtable (CaseInsensitiveHashCodeProvider.Default,
+ CaseInsensitiveComparer.Default);
+
+ if (parent != null && parent.compilers != null) {
+ foreach (DictionaryEntry entry in parent.compilers)
+ compilers [entry.Key] = entry.Value;
+ }
+ }
+
+ public WebCompiler this [string language] {
+ get { return compilers [language] as WebCompiler; }
+ set {
+ compilers [language] = value;
+ string [] langs = language.Split (';');
+ foreach (string s in langs) {
+ string x = s.Trim ();
+ if (x != "")
+ compilers [x] = value;
+ }
+ }
+ }
+ }
+}
+
}
static internal string ExtractAttributeValue (string attKey, XmlNode node, bool optional)
+ {
+ return ExtractAttributeValue (attKey, node, optional, false);
+ }
+
+ static internal string ExtractAttributeValue (string attKey, XmlNode node, bool optional,
+ bool allowEmpty)
{
if (node.Attributes == null) {
if (optional)
}
string value = att.Value;
- if (value == String.Empty) {
+ if (!allowEmpty && value == String.Empty) {
string opt = optional ? "Optional" : "Required";
ThrowException (opt + " attribute is empty: " + attKey, node);
}
--- /dev/null
+//
+// System.Web.Configuration.WebCompiler
+//
+// Authors:
+// Gonzalo Paniagua Javier (gonzalo@ximian.com)
+//
+// (C) 2003 Ximian, Inc (http://www.ximian.com)
+//
+
+using System;
+using System.Collections;
+using System.CodeDom.Compiler;
+
+namespace System.Web.Configuration
+{
+ class WebCompiler
+ {
+ public string Languages;
+ public string Extension;
+ public string Type;
+ public int WarningLevel;
+ public string CompilerOptions;
+ public CodeDomProvider Provider;
+
+ public override string ToString ()
+ {
+ return "Languages: " + Languages + "\n" +
+ "Extension: " + Extension + "\n" +
+ "Type: " + Type + "\n" +
+ "WarningLevel: " + WarningLevel + "\n" +
+ "CompilerOptions: " + CompilerOptions + "\n";
+ }
+ }
+}
+
using System.IO;
using System.Web;
using System.Web.Compilation;
+using System.Web.Configuration;
using System.Web.Util;
namespace System.Web.UI
string baseDir;
string baseVDir;
ILocation location;
+ CompilationConfiguration compilationConfig;
internal string MapPath (string path)
{
set { baseVDir = value; }
}
+
+ internal CompilationConfiguration CompilationConfig {
+ get {
+ if (compilationConfig == null)
+ compilationConfig = CompilationConfiguration.GetInstance (context);
+
+ return compilationConfig;
+ }
+ }
}
}
+2003-10-14 Gonzalo Paniagua Javier <gonzalo@ximian.com>
+
+ * BaseParser.cs: added CompilationConfig property.
+
+ * TemplateParser.cs:
+ * SimpleWebHandlerParser.cs: added CompilationConfig property.
+ Don't hardcode assembly names any more, assemblies in bin are added
+ depending on the configuration. The default language is also taken
+ from the configuration.
+
2003-10-13 Gonzalo Paniagua Javier <gonzalo@ximian.com>
* LosFormatter.cs: fixed bug #49604. Patch by yaronsh@mainsoft.com.
using System.Text;
using System.Web;
using System.Web.Compilation;
+using System.Web.Configuration;
using System.Web.Util;
namespace System.Web.UI
string privateBinPath;
string baseDir;
string baseVDir;
+ CompilationConfiguration compilationConfig;
protected SimpleWebHandlerParser (HttpContext context, string virtualPath, string physicalPath)
{
AddDependency (physicalPath);
assemblies = new ArrayList ();
- assemblies.Add ("System.dll");
- assemblies.Add ("System.Drawing.dll");
- assemblies.Add ("System.Data.dll");
- assemblies.Add ("System.Web.dll");
- assemblies.Add ("System.Web.Services.dll");
- assemblies.Add ("System.Xml.dll");
- AddAssembliesInBin ();
+ assemblies.AddRange (CompilationConfig.Assemblies);
+ if (CompilationConfig.AssembliesInBin)
+ AddAssembliesInBin ();
+
+ language = CompilationConfig.DefaultLanguage;
GetDirectivesAndContent ();
}
}
language = GetAndRemove (attributes, "language");
- if (language != null) {
- if (0 != String.Compare (language, "C#", true))
- throw new ParseException (null, "Only C# language is supported by now.");
- }
+ if (language == null)
+ language = CompilationConfig.DefaultLanguage;
codeBehind = GetAndRemove (attributes, "codebehind");
if (attributes.Count > 0)
return baseVDir;
}
}
+
+ internal CompilationConfiguration CompilationConfig {
+ get {
+ if (compilationConfig == null)
+ compilationConfig = CompilationConfiguration.GetInstance (context);
+
+ return compilationConfig;
+ }
+ }
}
}
imports.Add ("System.Web.UI.HtmlControls");
assemblies = new ArrayList ();
- assemblies.Add ("System.dll");
- assemblies.Add ("System.Drawing.dll");
- assemblies.Add ("System.Data.dll");
- assemblies.Add ("System.Web.dll");
- assemblies.Add ("System.Xml.dll");
- AddAssembliesInBin ();
+ assemblies.AddRange (CompilationConfig.Assemblies);
+ if (CompilationConfig.AssembliesInBin)
+ AddAssembliesInBin ();
+
+ language = CompilationConfig.DefaultLanguage;
}
protected abstract Type CompileIntoType ();
debug = GetBool (atts, "Debug", true);
compilerOptions = GetString (atts, "CompilerOptions", null);
- language = GetString (atts, "Language", "C#");
- if (String.Compare (language, "c#", true) != 0)
- ThrowParseException ("Only C# supported.");
-
+ language = GetString (atts, "Language", CompilationConfig.DefaultLanguage);
string src = GetString (atts, "Src", null);
Assembly srcAssembly = null;
if (src != null)
System.Web.Configuration/AuthConfig.cs
System.Web.Configuration/AuthenticationMode.cs
System.Web.Configuration/ClientTargetSectionHandler.cs
+System.Web.Configuration/CompilationConfiguration.cs
+System.Web.Configuration/CompilationConfigurationHandler.cs
+System.Web.Configuration/CompilerCollection.cs
System.Web.Configuration/FormsAuthPasswordFormat.cs
System.Web.Configuration/FormsProtectionEnum.cs
System.Web.Configuration/GlobalizationConfiguration.cs
System.Web.Configuration/MachineKeyConfig.cs
System.Web.Configuration/AuthorizationConfig.cs
System.Web.Configuration/GlobalizationConfigurationHandler.cs
+System.Web.Configuration/WebCompiler.cs
System.Web.Configuration/WebControlsSectionHandler.cs
System.Web.Handlers/TraceHandler.cs
System.Web.Hosting/AppDomainFactory.cs