diff options
author | Gonzalo Paniagua Javier <gonzalo.mono@gmail.com> | 2002-11-26 05:52:25 +0300 |
---|---|---|
committer | Gonzalo Paniagua Javier <gonzalo.mono@gmail.com> | 2002-11-26 05:52:25 +0300 |
commit | be2bff830e7e81a846f4e98b4b9788d2f7e3c7ab (patch) | |
tree | 2027822986a58a5701d7aebf6a5eff1f0b8ae976 | |
parent | 1fce2977b3fe34dd4171623ec2ff5e6ad5403a84 (diff) |
2002-11-26 Gonzalo Paniagua Javier <gonzalo@ximian.com>
* list: added/removed files.
* System.Web.Compilation/AspGenerator.cs: reworked user control
compilation. Provide the options as a Hashtable for use in compilation.
Create the user controls in the private bin path of the domain.
* System.Web.Compilation/BaseCompiler.cs: base class for the various
compiler types.
* System.Web.Compilation/CachingCompiler.cs: actually executes mcs and
do some poor caching (it will use Cache when finished).
* System.Web.Compilation/CompilationException.cs: this exception has
enough information to generate a nice error page.
* System.Web.Compilation/CompilationResult.cs: used in caching.
* System.Web.Compilation/PageCompiler.cs: now derives from BaseCompiler
* System.Web.Compilation/TemplateFactory.cs: no longer needed.
* System.Web.Compilation/UserControlCompiler.cs: new class used when
compiling user controls.
* System.Web.Compilation/WebServiceCompiler.cs: derives from
BaseCompiler.
* System.Web.Mail/SmtpMail.cs: i don't wanna see that warning :-).
* System.Web.UI/TemplateParser.cs: fixed BaseType.
* System.Web.UI/UserControlParser.cs: helper class to compile user
controls.
svn path=/trunk/mcs/; revision=9191
17 files changed, 698 insertions, 420 deletions
diff --git a/mcs/class/System.Web/ChangeLog b/mcs/class/System.Web/ChangeLog index 67b90d91491..015e43ba022 100644 --- a/mcs/class/System.Web/ChangeLog +++ b/mcs/class/System.Web/ChangeLog @@ -1,3 +1,7 @@ +2002-11-26 Gonzalo Paniagua Javier <gonzalo@ximian.com> + + * list: added/removed files. + 2002-11-20 Gonzalo Paniagua Javier <gonzalo@ximian.com> * makefile.gnu: s/MONO_PATH_PREFIX/MONO_PATH/ diff --git a/mcs/class/System.Web/System.Web.Compilation/AspGenerator.cs b/mcs/class/System.Web/System.Web.Compilation/AspGenerator.cs index ea8459c9ce4..b8bc9e000c3 100644 --- a/mcs/class/System.Web/System.Web.Compilation/AspGenerator.cs +++ b/mcs/class/System.Web/System.Web.Compilation/AspGenerator.cs @@ -271,7 +271,6 @@ class AspGenerator { private object [] parts; private ArrayListWrapper elements; - private StringBuilder buildOptions; private StringBuilder prolog; private StringBuilder declarations; private StringBuilder script; @@ -292,12 +291,14 @@ class AspGenerator private string fullPath; private static string enableSessionStateLiteral = ", System.Web.SessionState.IRequiresSessionState"; + Hashtable options; + string privateBinPath; + enum UserControlResult { OK = 0, FileNotFound = 1, - XspFailed = 2, - CompilationFailed = 3 + CompilationFailed = 2 } public AspGenerator (string pathToFile, ArrayList elements) @@ -310,6 +311,7 @@ class AspGenerator this.className = filename.Replace ('.', '_'); // Overridden by @ Page classname this.className = className.Replace ('-', '_'); this.className = className.Replace (' ', '_'); + Options ["ClassName"] = this.className; this.fullPath = Path.GetFullPath (pathToFile); /* if (IsUserControl) { @@ -322,6 +324,14 @@ class AspGenerator // //*/ this.has_form_tag = false; + AppDomainSetup setup = AppDomain.CurrentDomain.SetupInformation; + privateBinPath = setup.PrivateBinPath; + if (privateBinPath == null || privateBinPath.Length == 0) + privateBinPath = "bin"; + + if (!Path.IsPathRooted (privateBinPath)) + privateBinPath = Path.Combine (setup.ApplicationBase, privateBinPath); + Init (); } @@ -350,6 +360,15 @@ class AspGenerator } } + public Hashtable Options { + get { + if (options == null) + options = new Hashtable (); + + return options; + } + } + public void AddInterface (string iface) { if (interfaces == "") { @@ -381,20 +400,18 @@ class AspGenerator constructor = new StringBuilder (); init_funcs = new StringBuilder (); epilog = new StringBuilder (); - buildOptions = new StringBuilder (); current_function = new StringBuilder (); functions = new Stack (); functions.Push (current_function); - parts = new Object [7]; - parts [0] = buildOptions; - parts [1] = prolog; - parts [2] = declarations; - parts [3] = script; - parts [4] = constructor; - parts [5] = init_funcs; - parts [6] = epilog; + parts = new Object [6]; + parts [0] = prolog; + parts [1] = declarations; + parts [2] = script; + parts [3] = constructor; + parts [4] = init_funcs; + parts [5] = epilog; prolog.Append ("namespace ASP {\n" + "\tusing System;\n" + @@ -459,6 +476,7 @@ class AspGenerator { if (att ["ClassName"] != null){ this.className = (string) att ["ClassName"]; + Options ["ClassName"] = className; } if (att ["EnableSessionState"] != null){ @@ -482,14 +500,23 @@ class AspGenerator } */ - if (att ["CompilerOptions"] != null){ - string compilerOptions = (string) att ["CompilerOptions"]; - buildOptions.AppendFormat ("//<compileroptions options=\"{0}\"/>\n", compilerOptions); - } + if (att ["CompilerOptions"] != null) + Options ["CompilerOptions"] = (string) att ["CompilerOptions"]; //FIXME: add support for more attributes. } + void AddReference (string dll) + { + string references = Options ["References"] as string; + if (references == null) + references = dll; + else + references = references + " " + dll; + + Options ["References"] = references; + } + private void RegisterDirective (TagAttributes att) { string tag_prefix = (string) (att ["tagprefix"] == null ? "" : att ["tagprefix"]); @@ -503,9 +530,9 @@ class AspGenerator throw new ApplicationException ("Invalid attributes for @ Register: " + att.ToString ()); prolog.AppendFormat ("\tusing {0};\n", name_space); - string dll = "output" + Path.DirectorySeparatorChar + assembly_name + ".dll"; + string dll = privateBinPath + Path.DirectorySeparatorChar + assembly_name + ".dll"; Foundry.RegisterFoundry (tag_prefix, dll, name_space); - buildOptions.AppendFormat ("//<reference dll=\"{0}\"/>\n", dll); + AddReference (dll); return; } @@ -532,13 +559,10 @@ class AspGenerator prolog.AppendFormat ("\tusing {0};\n", "ASP"); string dll = "output" + Path.DirectorySeparatorChar + data.assemblyName + ".dll"; Foundry.RegisterFoundry (tag_prefix, data.assemblyName, "ASP", data.className); - buildOptions.AppendFormat ("//<reference dll=\"{0}\"/>\n", data.assemblyName); + AddReference (data.assemblyName); break; case UserControlResult.FileNotFound: throw new ApplicationException ("File '" + src + "' not found."); - case UserControlResult.XspFailed: - //TODO - throw new NotImplementedException (); case UserControlResult.CompilationFailed: //TODO: should say where the generated .cs file is for the server to //show the source and the compiler error @@ -1474,8 +1498,6 @@ class AspGenerator private void End () { - buildOptions.AppendFormat ("//<class name=\"{0}\"/>\n", className); - buildOptions.Append ("\n"); classDecl = "\tpublic class " + className + " : " + parent + interfaces + " {\n"; prolog.Append ("\n" + classDecl); declarations.Append ("\t\tprivate static bool __intialized = false;\n\n"); @@ -1583,110 +1605,20 @@ class AspGenerator return data; } - string noExt = Path.GetFileNameWithoutExtension (src); - string csName = "output" + dirSeparator + "xsp_ctrl_" + noExt + ".cs"; - if (!Directory.Exists ("output")) - Directory.CreateDirectory ("output"); - - if (Xsp (src, csName) == false) { - data.result = UserControlResult.XspFailed; + string csName = Path.GetTempFileName () + ".cs"; + string dll = Path.ChangeExtension (csName, ".dll"); + UserControlCompiler compiler = new UserControlCompiler (new UserControlParser (src), csName); + Type t = compiler.GetCompiledType (); + if (t == null) { + data.result = UserControlResult.CompilationFailed; return data; } - StreamReader fileReader = new StreamReader (File.Open (csName, FileMode.Open)); - data.className = src.Replace ('.', '_'); - - StringBuilder compilerOptions = new StringBuilder ("/r:System.Web.dll /r:System.Drawing.dll "); - compilerOptions.Append ("/target:library "); - - string line; - while ((line = fileReader.ReadLine ()) != null && line != "") { - if (line.StartsWith ("//<class ")) { - data.className = GetAttributeValue (line, "name"); - } else if (line.StartsWith ("//<reference ")) { - string dllName = GetAttributeValue (line, "dll"); - compilerOptions.AppendFormat ("/r:{0} ", dllName); - } else if (line.StartsWith ("//<compileroptions ")) { - string options = GetAttributeValue (line, "options"); - compilerOptions.Append (" " + options + " "); - } else { - Console.Error.WriteLine ("Ignoring build option: {0}", line); - } - } - fileReader.Close (); - - string dll = Path.ChangeExtension (csName, ".dll"); + data.className = t.FullName; data.assemblyName = dll; - if (Compile (csName, dll, compilerOptions) == false) { - data.result = UserControlResult.CompilationFailed; - } return data; } - - private static string GetAttributeValue (string line, string att) - { - string att_start = att + "=\""; - int begin = line.IndexOf (att_start); - int end = line.Substring (begin + att_start.Length).IndexOf ('"'); - if (begin == -1 || end == -1) - throw new ApplicationException ("Error in compilation option:\n" + line); - - return line.Substring (begin + att_start.Length, end); - } - - private static bool Xsp (string fileName, string csFileName) - { -#if MONO - return RunProcess ("mono", - "xsp.exe --control " + fileName, - csFileName, - "output" + dirSeparator + "xsp_ctrl_" + Path.GetFileName (fileName) + - ".sh"); -#else - return RunProcess ("xsp", - "--control " + fileName, - csFileName, - "output" + dirSeparator + "xsp_ctrl_" + fileName + ".bat"); -#endif - } - - private static bool Compile (string csName, string dllName, StringBuilder compilerOptions) - { - compilerOptions.AppendFormat ("/out:{0} ", dllName); - compilerOptions.Append (csName + " "); - - string cmdline = compilerOptions.ToString (); - string noext = Path.GetFileNameWithoutExtension (csName); - string output_file = "output" + dirSeparator + "output_from_compilation_" + noext + ".txt"; - string bat_file = "output" + dirSeparator + "last_compilation_" + noext + ".bat"; - return RunProcess ("mcs", cmdline, output_file, bat_file); - } - - private static bool RunProcess (string exe, string arguments, string output_file, string script_file) - { - Process proc = new Process (); - - proc.StartInfo.FileName = exe; - proc.StartInfo.Arguments = arguments; - proc.StartInfo.UseShellExecute = false; - proc.StartInfo.RedirectStandardOutput = true; - proc.Start (); - string poutput = proc.StandardOutput.ReadToEnd(); - proc.WaitForExit (); - int result = proc.ExitCode; - proc.Close (); - - StreamWriter cmd_output = new StreamWriter (File.Create (output_file)); - cmd_output.Write (poutput); - cmd_output.Close (); - StreamWriter bat_output = new StreamWriter (File.Create (script_file)); - bat_output.Write (exe + " " + arguments); - bat_output.Close (); - - return (result == 0); - } - } } diff --git a/mcs/class/System.Web/System.Web.Compilation/BaseCompiler.cs b/mcs/class/System.Web/System.Web.Compilation/BaseCompiler.cs new file mode 100644 index 00000000000..9828f6bcf0e --- /dev/null +++ b/mcs/class/System.Web/System.Web.Compilation/BaseCompiler.cs @@ -0,0 +1,74 @@ +// +// System.Web.Compilation.BaseCompiler +// +// Authors: +// Gonzalo Paniagua Javier (gonzalo@ximian.com) +// +// (C) 2002 Ximian, Inc (http://www.ximian.com) +// + +using System; +using System.IO; + +namespace System.Web.Compilation +{ + abstract class BaseCompiler + { + static Random rnd = new Random ((int) DateTime.Now.Ticks); + string randomName; + + protected BaseCompiler () + { + } + + public virtual Type GetCompiledType () + { + return null; + } + + public virtual string Key { + get { + return null; + } + } + + public virtual string SourceFile { + get { + return null; + } + } + + public virtual string [] Dependencies { + get { + return null; + } + } + + public virtual string CompilerOptions { + get { + return "/r:System.Web.dll /r:System.Data.dll /r:System.Drawing.dll"; + } + } + + static string GetRandomFileName () + { + string output; + + do { + output = "tmp" + rnd.Next () + ".dll"; + } while (File.Exists (output)); + + return output; + } + + public virtual string TargetFile { + get { + if (randomName == null) + randomName = GetRandomFileName (); + + return randomName; + } + } + } +} + diff --git a/mcs/class/System.Web/System.Web.Compilation/CachingCompiler.cs b/mcs/class/System.Web/System.Web.Compilation/CachingCompiler.cs new file mode 100644 index 00000000000..8ce495067f4 --- /dev/null +++ b/mcs/class/System.Web/System.Web.Compilation/CachingCompiler.cs @@ -0,0 +1,156 @@ +// +// System.Web.Compilation.CachingCompiler +// +// Authors: +// Gonzalo Paniagua Javier (gonzalo@ximian.com) +// +// (C) 2002 Ximian, Inc (http://www.ximian.com) +// +using System; +using System.Collections; +using System.Diagnostics; +using System.IO; +using System.Text; +using System.Web.UI; +using System.Web.Util; + +namespace System.Web.Compilation +{ + //TODO: caching should be done using System.Web.Caching, but that namespace still need some work. + internal class CompilationCacheItem + { + CompilationResult result; + DateTime time; + + public CompilationCacheItem (CompilationResult result, DateTime time) + { + this.result = result; + this.time = time; + } + + public bool CheckDependencies (string [] newDependencies, DateTime time) + { + // FIXME + return true; + } + + public CompilationResult Result + { + get { return result; } + } + } + + internal class CompilationCache + { + static Hashtable cache; + static CompilationCache instance = new CompilationCache (); + + private CompilationCache () + { + } + + static CompilationCache () + { + cache = new Hashtable (); + } + + public static CompilationCache GetInstance () + { + return instance; + } + + public CompilationCacheItem this [string key] + { + get { + return cache [key] as CompilationCacheItem; + } + + set { + cache [key] = value; + } + } + } + + internal class CachingCompiler + { + static CompilationCache cache = CompilationCache.GetInstance (); + string key; + BaseCompiler compiler; + + public CachingCompiler (BaseCompiler compiler) + { + this.compiler = compiler; + this.key = compiler.Key; + } + + public static CompilationCacheItem GetCached (string key) + { + if (key == null) + throw new ArgumentNullException ("key"); + + CompilationCacheItem item = cache [key]; + return item; + } + + static object compilationLock = new object (); + public bool Compile (CompilationResult result) + { + if (compiler.SourceFile == null) + throw new ArgumentException ("No source to compile!"); + + result.Reset (); + CompilationCacheItem item; + + item = GetCached (key); + if (item != null) { + if (item.CheckDependencies (compiler.Dependencies, DateTime.Now) == true) { + result = item.Result; + return true; + } + } + + lock (compilationLock) { + item = GetCached (key); + if (item != null) { + if (item.CheckDependencies (compiler.Dependencies, DateTime.Now) == true) { + result = item.Result; + return true; + } + } + + RealCompile (result); + cache [key] = new CompilationCacheItem (result, DateTime.Now); + } + + return (result.ExitCode == 0); + } + + void RealCompile (CompilationResult result) + { + StringBuilder options = new StringBuilder ("/target:library "); + if (compiler.CompilerOptions != null) + options.Append (compiler.CompilerOptions + ' '); + + options.AppendFormat ("/out:{0} ", compiler.TargetFile); + options.Append (compiler.SourceFile); + + Process proc = new Process (); + proc.StartInfo.FileName = "mcs"; + proc.StartInfo.Arguments = options.ToString (); + proc.StartInfo.UseShellExecute = false; + proc.StartInfo.RedirectStandardOutput = true; + + WebTrace.WriteLine ("{0} {1}", proc.StartInfo.FileName, options.ToString ()); + proc.Start (); + string poutput = proc.StandardOutput.ReadToEnd(); + proc.WaitForExit (); + result.ExitCode = proc.ExitCode; + proc.Close (); + proc = null; + + result.CompilerOutput = poutput; + result.OutputFile = compiler.TargetFile; + } + } +} + diff --git a/mcs/class/System.Web/System.Web.Compilation/ChangeLog b/mcs/class/System.Web/System.Web.Compilation/ChangeLog index 090a236d165..5cc7e298a5b 100644 --- a/mcs/class/System.Web/System.Web.Compilation/ChangeLog +++ b/mcs/class/System.Web/System.Web.Compilation/ChangeLog @@ -1,3 +1,25 @@ +2002-11-26 Gonzalo Paniagua Javier <gonzalo@ximian.com> + + * AspGenerator.cs: reworked user control + compilation. Provide the options as a Hashtable for use in compilation. + Create the user controls in the private bin path of the domain. + + * BaseCompiler.cs: base class for the various compiler types. + + * CachingCompiler.cs: actually executes mcs and do some poor caching + (it will use Cache when finished). + + * CompilationException.cs: this exception has enough information to + generate a nice error page. + * CompilationResult.cs: used in caching. + + * PageCompiler.cs: now derives from BaseCompiler + + * TemplateFactory.cs: no longer needed. + + * UserControlCompiler.cs: new class used when compiling user controls. + * WebServiceCompiler.cs: derives from BaseCompiler. + 2002-11-13 Gonzalo Paniagua Javier <gonzalo@ximian.com> * AspElements.cs: added ServerComment class. diff --git a/mcs/class/System.Web/System.Web.Compilation/CompilationException.cs b/mcs/class/System.Web/System.Web.Compilation/CompilationException.cs new file mode 100644 index 00000000000..43c88ab98d3 --- /dev/null +++ b/mcs/class/System.Web/System.Web.Compilation/CompilationException.cs @@ -0,0 +1,34 @@ +// +// System.Web.Compilation.CompilationException +// +// Authors: +// Gonzalo Paniagua Javier (gonzalo@ximian.com) +// +// (C) 2002 Ximian, Inc (http://www.ximian.com) +// + +using System; + +namespace System.Web.Compilation +{ + internal class CompilationException : Exception + { + CompilationResult result; + + public CompilationException (CompilationResult result) + { + this.result = result; + } + + public CompilationException (string msg, CompilationResult result) + { + this.result = result; + } + + public CompilationException (CompilationCacheItem item) + { + this.result = item.Result; + } + } +} + diff --git a/mcs/class/System.Web/System.Web.Compilation/CompilationResult.cs b/mcs/class/System.Web/System.Web.Compilation/CompilationResult.cs new file mode 100644 index 00000000000..f9770cd8e74 --- /dev/null +++ b/mcs/class/System.Web/System.Web.Compilation/CompilationResult.cs @@ -0,0 +1,55 @@ +// +// System.Web.Compilation.CompilationResult +// +// Authors: +// Gonzalo Paniagua Javier (gonzalo@ximian.com) +// +// (C) 2002 Ximian, Inc (http://www.ximian.com) +// +using System; + +namespace System.Web.Compilation +{ + internal class CompilationResult + { + int exitCode; + string output; + string outputFile; + object data; + + public CompilationResult () + { + } + + public void Reset () + { + exitCode = 0; + output = null; + } + + public int ExitCode + { + get { return exitCode; } + set { exitCode = exitCode; } + } + + public string CompilerOutput + { + get { return output; } + set { output = value; } + } + + public string OutputFile + { + get { return outputFile; } + set { outputFile = value; } + } + + public object Data + { + get { return data; } + set { data = value; } + } + } +} + diff --git a/mcs/class/System.Web/System.Web.Compilation/PageCompiler.cs b/mcs/class/System.Web/System.Web.Compilation/PageCompiler.cs index 9fd81fefc02..c066441968f 100644 --- a/mcs/class/System.Web/System.Web.Compilation/PageCompiler.cs +++ b/mcs/class/System.Web/System.Web.Compilation/PageCompiler.cs @@ -7,33 +7,96 @@ // (C) 2002 Ximian, Inc (http://www.ximian.com) // using System; +using System.Collections; using System.IO; +using System.Reflection; +using System.Text; using System.Web.UI; using System.Web.Util; namespace System.Web.Compilation { - class PageCompiler + class PageCompiler : BaseCompiler { - private PageParser pageParser; + PageParser pageParser; + string sourceFile; + Hashtable options; - internal PageCompiler (PageParser pageParser) + private PageCompiler (PageParser pageParser) { this.pageParser = pageParser; } + public override Type GetCompiledType () + { + string inputFile = pageParser.InputFile; + sourceFile = GenerateSourceFile (); + + CachingCompiler compiler = new CachingCompiler (this); + CompilationResult result = new CompilationResult (); + if (compiler.Compile (result) == false) + throw new CompilationException (result); + + Assembly assembly = Assembly.LoadFrom (result.OutputFile); + Type [] types = assembly.GetTypes (); + if (types.Length != 1) + throw new CompilationException ("More than 1 Type in a page?", result); + + result.Data = types [0]; + return types [0]; + } + + public override string Key { + get { + return pageParser.InputFile; + } + } + + public override string SourceFile { + get { + return sourceFile; + } + } + + public override string CompilerOptions { + get { + if (options == null) + return base.CompilerOptions; + + StringBuilder sb = new StringBuilder (base.CompilerOptions); + string compilerOptions = options ["CompilerOptions"] as string; + if (compilerOptions != null) { + sb.Append (' '); + sb.Append (compilerOptions); + } + + string references = options ["References"] as string; + if (references == null) + return sb.ToString (); + + string [] split = references.Split (' '); + foreach (string s in split) + sb.AppendFormat (" /r:{0}", s); + + return sb.ToString (); + } + } + public static Type CompilePageType (PageParser pageParser) { - Type t = TemplateFactory.GetTypeFromSource (pageParser.InputFile, null); - if (t != null) - return t; + CompilationCacheItem item = CachingCompiler.GetCached (pageParser.InputFile); + if (item != null && item.Result != null) { + if (item.Result != null) + return item.Result.Data as Type; - string sourceFile = GenerateSourceFile (pageParser); - WebTrace.WriteLine ("Compiling {0} ({1})", sourceFile, pageParser.InputFile); - return TemplateFactory.GetTypeFromSource (pageParser.InputFile, sourceFile); + throw new CompilationException (item.Result); + } + + PageCompiler pc = new PageCompiler (pageParser); + return pc.GetCompiledType (); } - private static string GenerateSourceFile (PageParser pageParser) + string GenerateSourceFile () { string inputFile = pageParser.InputFile; @@ -41,9 +104,10 @@ namespace System.Web.Compilation AspParser parser = new AspParser (inputFile, input); parser.Parse (); AspGenerator generator = new AspGenerator (inputFile, parser.Elements); - generator.BaseType = "System.Web.UI.Page"; + generator.BaseType = pageParser.BaseType.ToString (); generator.ProcessElements (); pageParser.Text = generator.GetCode ().ReadToEnd (); + options = generator.Options; //FIXME: should get Tmp dir for this application string csName = Path.GetTempFileName () + ".cs"; @@ -55,3 +119,4 @@ namespace System.Web.Compilation } } } + diff --git a/mcs/class/System.Web/System.Web.Compilation/TemplateFactory.cs b/mcs/class/System.Web/System.Web.Compilation/TemplateFactory.cs deleted file mode 100644 index 50d10b0c58f..00000000000 --- a/mcs/class/System.Web/System.Web.Compilation/TemplateFactory.cs +++ /dev/null @@ -1,272 +0,0 @@ -//
-// System.Web.Compilation.TemplateFactory
-//
-// Authors:
-// Gonzalo Paniagua Javier (gonzalo@ximian.com)
-//
-// (C) 2002 Ximian, Inc (http://www.ximian.com)
-//
-using System;
-using System.Collections;
-using System.Diagnostics;
-using System.IO;
-using System.Reflection;
-using System.Text;
-using System.Web.UI;
-using System.Web.Util;
-
-//TODO: should use private bin to store dlls (when AppDomain and Assembly.Load know about it?)
-namespace System.Web.Compilation
-{
- class CompiledTypeData
- {
- string csFile;
- string aspxFile;
- Type type;
- DateTime since;
- //TODO: ArrayList fileDependencies;
-
- public CompiledTypeData (string aspxFile, string csFile, Type type, DateTime since)
- {
- this.aspxFile = aspxFile;
- this.csFile = csFile;
- this.type = type;
- this.since = since;
-
- }
-
- public bool IsNewer (DateTime dt)
- {
- return (dt > since);
- }
-
- public Type Type
- {
- get { return type; }
- set { type = value; }
- }
-
- public DateTime Since
- {
- get { return since; }
- set { since = value; }
- }
- }
-
- class TemplateFactory
- {
- internal class PageBuilder
- {
- private StringBuilder cscOptions;
- private string csFileName;
- private string className;
- public static char dirSeparator = Path.DirectorySeparatorChar;
- private static Hashtable cachedData = new Hashtable ();
- private static Random rnd_file = new Random ();
-
- private PageBuilder ()
- {
- }
-
- internal PageBuilder (string fileName)
- {
- csFileName = fileName;
-
- cscOptions = new StringBuilder ();
- cscOptions.Append ("/target:library ");
- AddReference ("System.Data");
- AddReference ("System.Web");
- AddReference ("System.Drawing");
- }
-
- internal Type Build ()
- {
- string dll;
-
- StreamReader st_file = new StreamReader (File.OpenRead (csFileName));
-
- StringReader file_content = new StringReader (st_file.ReadToEnd ());
- st_file.Close ();
- if (GetBuildOptions (file_content) == false)
- return null;
-
- dll = rnd_file.Next () + Path.GetFileName (csFileName).Replace (".cs", ".dll");
- if (Compile (csFileName, dll) == true){
- Assembly assembly = Assembly.LoadFrom (dll);
- Type type = assembly.GetType ("ASP." + className);
- return type;
- }
-
- return null;
- }
-
- private static bool RunProcess (string exe, string arguments, string output_file, string script_file)
- {
- Console.WriteLine ("{0} {1}", exe, arguments);
- Console.WriteLine ("Output goes to {0}", output_file);
- Console.WriteLine ("Script file is {0}", script_file);
- Process proc = new Process ();
-
- proc.StartInfo.FileName = exe;
- proc.StartInfo.Arguments = arguments;
- proc.StartInfo.UseShellExecute = false;
- proc.StartInfo.RedirectStandardOutput = true;
- proc.Start ();
- string poutput = proc.StandardOutput.ReadToEnd();
- proc.WaitForExit ();
- int result = proc.ExitCode;
- proc.Close ();
-
- StreamWriter cmd_output = new StreamWriter (File.Create (output_file));
- cmd_output.Write (poutput);
- cmd_output.Close ();
- StreamWriter bat_output = new StreamWriter (File.Create (script_file));
- bat_output.Write (exe + " " + arguments);
- bat_output.Close ();
-
- return (result == 0);
- }
-
- private bool GetBuildOptions (StringReader genCode)
- {
- string line;
- string dll;
-
- while ((line = genCode.ReadLine ()) != String.Empty) {
- if (line.StartsWith ("//<class ")){
- className = GetAttributeValue (line, "name");
- } else if (line.StartsWith ("//<compileandreference ")) {
- string src = GetAttributeValue (line, "src");
- dll = src.Replace (".cs", ".dll"); //FIXME
- //File.Delete (dll);
- if (Compile (src, dll) == false){
- Console.WriteLine ("Error compiling {0}. See the output file.", src);
- return false;
- }
- AddReference (dll.Replace (".dll", ""));
- } else if (line.StartsWith ("//<reference ")) {
- dll = GetAttributeValue (line, "dll");
- AddReference (dll);
- } else if (line.StartsWith ("//<compileroptions ")) {
- string options = GetAttributeValue (line, "options");
- cscOptions.Append (" " + options + " ");
- } else {
- Console.WriteLine ("This is the build option line i get:\n" + line);
- return false;
- }
- }
-
- return true;
- }
-
- private void AddReference (string reference)
- {
- string arg = String.Format ("/r:{0}.dll ", reference);
- cscOptions.Append (arg);
- }
-
- private string GetAttributeValue (string line, string att)
- {
- string att_start = att + "=\"";
- int begin = line.IndexOf (att_start);
- int end = line.Substring (begin + att_start.Length).IndexOf ('"');
- if (begin == -1 || end == -1)
- throw new ApplicationException ("Error in reference option:\n" + line);
-
- return line.Substring (begin + att_start.Length, end);
- }
-
- private bool Compile (string csName, string dllName)
- {
- cscOptions.AppendFormat ("/out:{0} ", dllName);
- cscOptions.Append (csName);
-
- string cmdline = cscOptions.ToString ();
- string noext = csName.Replace (".cs", "");
- string output_file = noext + "_compilation_output.txt";
- string bat_file = noext + "_compile_command.bat";
- return RunProcess ("mcs", cmdline, output_file, bat_file);
- }
- }
-
-
- static object compiling = new object ();
- static Hashtable compiledTypes = new Hashtable ();
-
- internal static string CompilationOutputFileName (string fileName)
- {
- string name = "xsp_" + Path.GetFileName (fileName).Replace (".aspx", ".txt");
- return "output" + PageBuilder.dirSeparator + "output_from_compilation_" + name;
- }
-
- internal static string GeneratedXspFileName (string fileName)
- {
- string name = Path.GetFileName (fileName).Replace (".aspx", ".cs");
- return "output" + PageBuilder.dirSeparator + "xsp_" + name;
- }
-
- private TemplateFactory ()
- {
- }
-
- static Type AlreadyGotIt (string aspxFile, ref DateTime filedt)
- {
- WebTrace.PushContext ("TemplateFactory.AlreadyGotIt");
- WebTrace.WriteLine ("Start: {0}", aspxFile);
- if (!compiledTypes.Contains (aspxFile)) {
- WebTrace.WriteLine ("File {0} not already compiled", filedt);
- WebTrace.PopContext ();
- return null;
- }
-
- CompiledTypeData data = (CompiledTypeData) compiledTypes [aspxFile];
- try {
- filedt = File.GetLastWriteTime (aspxFile);
- } catch {
- WebTrace.WriteLine ("Error getting date for {0}", aspxFile);
- WebTrace.PopContext ();
- return null;
- }
-
- if (data.IsNewer (filedt)) {
- compiledTypes.Remove (aspxFile);
- WebTrace.WriteLine ("aspx modified: {0}", filedt);
- WebTrace.PopContext ();
- return null;
- }
-
- WebTrace.WriteLine ("End: {0}", data.Type);
- WebTrace.PopContext ();
- return data.Type;
- }
-
- internal static Type GetTypeFromSource (string aspxFile, string csFile)
- {
- DateTime filedt = DateTime.Now;
- Type type = AlreadyGotIt (aspxFile, ref filedt) as Type;
- if (type != null)
- return type;
-
- if (csFile == null || !File.Exists (csFile))
- return null; //FIXME: throw an exception if the file does not exists
-
- PageBuilder builder = new PageBuilder (csFile);
- lock (compiling) {
- type = AlreadyGotIt (aspxFile, ref filedt) as Type;
- if (type != null)
- return type;
-
- type = builder.Build ();
- }
-
- if (type == null)
- return null;
-
- CompiledTypeData data = new CompiledTypeData (aspxFile, csFile, type, filedt);
- compiledTypes.Add (aspxFile, data);
-
- return type;
- }
- }
-}
-
diff --git a/mcs/class/System.Web/System.Web.Compilation/UserControlCompiler.cs b/mcs/class/System.Web/System.Web.Compilation/UserControlCompiler.cs new file mode 100644 index 00000000000..9c953dd5409 --- /dev/null +++ b/mcs/class/System.Web/System.Web.Compilation/UserControlCompiler.cs @@ -0,0 +1,105 @@ +// +// System.Web.Compilation.UserControlCompiler +// +// Authors: +// Gonzalo Paniagua Javier (gonzalo@ximian.com) +// +// (C) 2002 Ximian, Inc (http://www.ximian.com) +// +using System; +using System.IO; +using System.Reflection; +using System.Web.UI; +using System.Web.Util; + +namespace System.Web.Compilation +{ + class UserControlCompiler : BaseCompiler + { + UserControlParser userControlParser; + string sourceFile; + string targetFile; + + internal UserControlCompiler (UserControlParser userControlParser, string targetFile) + { + this.userControlParser = userControlParser; + this.targetFile = targetFile; + } + + public override Type GetCompiledType () + { + string inputFile = userControlParser.InputFile; + sourceFile = GenerateSourceFile (userControlParser); + + CachingCompiler compiler = new CachingCompiler (this); + CompilationResult result = new CompilationResult (); + if (compiler.Compile (result) == false) + throw new CompilationException (result); + + Assembly assembly = Assembly.LoadFrom (result.OutputFile); + Type [] types = assembly.GetTypes (); + if (types.Length != 1) + throw new CompilationException ("More than 1 Type in a user control?", result); + + result.Data = types [0]; + return types [0]; + } + + public override string Key { + get { + return userControlParser.InputFile; + } + } + + public override string SourceFile { + get { + return sourceFile; + } + } + + public override string TargetFile { + get { + if (targetFile == null) + targetFile = Path.ChangeExtension (sourceFile, ".dll"); + + return targetFile; + } + } + + public static Type CompileUserControlType (UserControlParser userControlParser) + { + CompilationCacheItem item = CachingCompiler.GetCached (userControlParser.InputFile); + if (item != null && item.Result != null) { + if (item.Result != null) + return item.Result.Data as Type; + + throw new CompilationException (item.Result); + } + + UserControlCompiler pc = new UserControlCompiler (userControlParser, null); + return pc.GetCompiledType (); + } + + static string GenerateSourceFile (UserControlParser userControlParser) + { + string inputFile = userControlParser.InputFile; + + Stream input = File.OpenRead (inputFile); + AspParser parser = new AspParser (inputFile, input); + parser.Parse (); + AspGenerator generator = new AspGenerator (inputFile, parser.Elements); + generator.BaseType = userControlParser.BaseType.ToString (); + generator.ProcessElements (); + userControlParser.Text = generator.GetCode ().ReadToEnd (); + + //FIXME: should get Tmp dir for this application + string csName = Path.GetTempFileName () + ".cs"; + WebTrace.WriteLine ("Writing {0}", csName); + StreamWriter output = new StreamWriter (File.OpenWrite (csName)); + output.Write (userControlParser.Text); + output.Close (); + return csName; + } + } +} + diff --git a/mcs/class/System.Web/System.Web.Compilation/WebServiceCompiler.cs b/mcs/class/System.Web/System.Web.Compilation/WebServiceCompiler.cs index 2cf293c5685..50e9962fb2f 100644 --- a/mcs/class/System.Web/System.Web.Compilation/WebServiceCompiler.cs +++ b/mcs/class/System.Web/System.Web.Compilation/WebServiceCompiler.cs @@ -8,30 +8,36 @@ // using System; using System.IO; +using System.Reflection; using System.Web.UI; namespace System.Web.Compilation { - class WebServiceCompiler + class WebServiceCompiler : BaseCompiler { - private WebServiceCompiler () + SimpleWebHandlerParser wService; + string sourceFile; + + private WebServiceCompiler (SimpleWebHandlerParser wService) { + this.wService = wService; } public static Type CompileIntoType (SimpleWebHandlerParser wService) { - string sourceFile = GenerateSourceFile (wService); - Type type = TemplateFactory.GetTypeFromSource (wService.PhysicalPath, sourceFile); - if (type.FullName != wService.ClassName) - throw new ApplicationException (String.Format ( - "Class={0}, but the class compiled is {1}", - wService.ClassName, - type.FullName)); - - return type; + CompilationCacheItem item = CachingCompiler.GetCached (wService.PhysicalPath); + if (item != null && item.Result != null) { + if (item.Result != null) + return item.Result.Data as Type; + + throw new CompilationException (item.Result); + } + + WebServiceCompiler wsc = new WebServiceCompiler (wService); + return wsc.GetCompiledType (); } - private static string GenerateSourceFile (SimpleWebHandlerParser wService) + static string GenerateSourceFile (SimpleWebHandlerParser wService) { //FIXME: should get Tmp dir for this application string csName = Path.GetTempFileName (); @@ -40,6 +46,40 @@ namespace System.Web.Compilation output.Close (); return csName; } + + public override Type GetCompiledType () + { + sourceFile = GenerateSourceFile (wService); + + CachingCompiler compiler = new CachingCompiler (this); + CompilationResult result = new CompilationResult (); + if (compiler.Compile (result) == false) + throw new CompilationException (result); + + Assembly assembly = Assembly.LoadFrom (result.OutputFile); + Type [] types = assembly.GetTypes (); + Type type = types [0]; + if (type.FullName != wService.ClassName) + throw new ApplicationException (String.Format ( + "Class={0}, but the class compiled is {1}", + wService.ClassName, + type.FullName)); + + result.Data = type; + return type; + } + + public override string Key { + get { + return wService.PhysicalPath; + } + } + + public override string SourceFile { + get { + return sourceFile; + } + } } } diff --git a/mcs/class/System.Web/System.Web.Mail/ChangeLog b/mcs/class/System.Web/System.Web.Mail/ChangeLog index 22aa7695cac..b2e226261e1 100644 --- a/mcs/class/System.Web/System.Web.Mail/ChangeLog +++ b/mcs/class/System.Web/System.Web.Mail/ChangeLog @@ -1,3 +1,7 @@ +2002-11-26 Gonzalo Paniagua Javier <gonzalo@ximian.com> + + * SmtpMail.cs: i don't wanna see that warning :-). + 2002-04-26 Lawrence Pit <loz@cable.a2000.nl> * MailAttachment.cs: Implemented diff --git a/mcs/class/System.Web/System.Web.Mail/SmtpMail.cs b/mcs/class/System.Web/System.Web.Mail/SmtpMail.cs index 9884191f171..3fb1d2d8135 100644 --- a/mcs/class/System.Web/System.Web.Mail/SmtpMail.cs +++ b/mcs/class/System.Web/System.Web.Mail/SmtpMail.cs @@ -42,6 +42,7 @@ namespace System.Web.Mail throw new NotImplementedException("Mono.Mail component is work in progress");
+ /*
try {
// TODO: possibly cache ctor info object..
Type stype = Type.GetType ("Mono.Mail.Smtp.SmtpSender");
@@ -58,6 +59,7 @@ namespace System.Web.Mail } catch (Exception) {
throw new Exception ("Unable to call Mono.Mail.Smtp.SmtpSender");
}
+ */
}
public static void Send (string from, string to, string subject, string messageText)
diff --git a/mcs/class/System.Web/System.Web.UI/ChangeLog b/mcs/class/System.Web/System.Web.UI/ChangeLog index 9f9ccce876f..4fc221a013d 100644 --- a/mcs/class/System.Web/System.Web.UI/ChangeLog +++ b/mcs/class/System.Web/System.Web.UI/ChangeLog @@ -1,3 +1,8 @@ +2002-11-26 Gonzalo Paniagua Javier <gonzalo@ximian.com> + + * TemplateParser.cs: fixed BaseType. + * UserControlParser.cs: helper class to compile user controls. + 2002-11-20 Gonzalo Paniagua Javier <gonzalo@ximian.com> * LosFormatter.cs: added DateTime to special types. diff --git a/mcs/class/System.Web/System.Web.UI/TemplateParser.cs b/mcs/class/System.Web/System.Web.UI/TemplateParser.cs index 816fc4f201e..5a60882a1a6 100755 --- a/mcs/class/System.Web/System.Web.UI/TemplateParser.cs +++ b/mcs/class/System.Web/System.Web.UI/TemplateParser.cs @@ -16,7 +16,6 @@ namespace System.Web.UI { private string inputFile; private string text; - private Type baseType; protected abstract Type CompileIntoType (); @@ -38,8 +37,7 @@ namespace System.Web.UI internal Type BaseType { - get { return baseType; } - set { baseType = value; } + get { return DefaultBaseType; } } } } diff --git a/mcs/class/System.Web/System.Web.UI/UserControlParser.cs b/mcs/class/System.Web/System.Web.UI/UserControlParser.cs new file mode 100644 index 00000000000..b454da5c11e --- /dev/null +++ b/mcs/class/System.Web/System.Web.UI/UserControlParser.cs @@ -0,0 +1,49 @@ +// +// System.Web.UI.UserControlParser +// +// Authors: +// Gonzalo Paniagua Javier (gonzalo@ximian.com) +// +// (C) 2002 Ximian, Inc (http://www.ximian.com) +// +using System; +using System.Web; +using System.Web.Compilation; + +namespace System.Web.UI +{ + public sealed class UserControlParser : TemplateControlParser + { + internal UserControlParser (string inputFile) + { + InputFile = inputFile; + } + + public static Type GetCompiledType (string virtualPath, string inputFile, HttpContext context) + { + UserControlParser ucp = new UserControlParser (inputFile); + Type t = ucp.CompileIntoType (); + return t; + } + + protected override Type CompileIntoType () + { + return UserControlCompiler.CompileUserControlType (this); + } + + protected override Type DefaultBaseType + { + get { + return typeof (Control); + } + } + + protected override string DefaultDirectiveName + { + get { + return "control"; + } + } + } +} + diff --git a/mcs/class/System.Web/list b/mcs/class/System.Web/list index 00e9dd1524e..b79df061abe 100755 --- a/mcs/class/System.Web/list +++ b/mcs/class/System.Web/list @@ -131,6 +131,7 @@ System.Web.UI/SimpleHandlerFactory.cs System.Web.UI/TagPrefixAttribute.cs System.Web.UI/TemplateContainerAttribute.cs System.Web.UI/TemplateControlParser.cs +System.Web.UI/UserControlParser.cs System.Web.UI/ValidatorCollection.cs System.Web.UI/ValidationPropertyAttribute.cs System.Web.UI/AttributeCollection.cs @@ -353,7 +354,11 @@ System.Web.Compilation/AspElements.cs System.Web.Compilation/AspGenerator.cs System.Web.Compilation/AspParser.cs System.Web.Compilation/AspTokenizer.cs +System.Web.Compilation/BaseCompiler.cs +System.Web.Compilation/CachingCompiler.cs +System.Web.Compilation/CompilationResult.cs +System.Web.Compilation/CompilationException.cs System.Web.Compilation/PageCompiler.cs -System.Web.Compilation/TemplateFactory.cs +System.Web.Compilation/UserControlCompiler.cs System.Web.Compilation/WebServiceCompiler.cs System.Web.Handlers/TraceHandler.cs |