//
// (C)2003 Novell inc.
//
+
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
using System;
using System.CodeDom;
using System.CodeDom.Compiler;
using System.Xml.Schema;
using System.Xml.XPath;
using System.Xml.Xsl;
+using Microsoft.CSharp;
+using Microsoft.VisualBasic;
namespace Mono.Xml.Xsl
{
set { defaultCompilerOptions = value; }
}
+ public abstract CodeDomProvider CodeDomProvider { get; }
+
public abstract string Extension { get; }
public abstract string SourceTemplate { get; }
return String.Concat (DefaultCompilerOptions, " ", targetFileName);
}
- [MonoTODO ("Should use Assembly.LoadFile() instead of LoadFrom() after its implementation has finished.")]
+
public virtual Type GetScriptClass (string code, string classSuffix, XPathNavigator scriptNode, Evidence evidence)
{
- string tmpPath = Path.GetTempPath ();
- if (!tmpPath.EndsWith (Path.DirectorySeparatorChar.ToString ()))
- tmpPath += Path.DirectorySeparatorChar;
- string tmpbase = tmpPath + Guid.NewGuid ();
- ProcessStartInfo psi = new ProcessStartInfo ();
- psi.UseShellExecute = false;
- psi.RedirectStandardError = true;
- psi.RedirectStandardOutput = true;
- Process proc = new Process ();
- proc.StartInfo = psi;
- StreamWriter sw = null;
+ PermissionSet ps = SecurityManager.ResolvePolicy (evidence);
+ if (ps != null)
+ ps.Demand ();
+
+ ICodeCompiler compiler = CodeDomProvider.CreateCompiler ();
+ CompilerParameters parameters = new CompilerParameters ();
+ parameters.CompilerOptions = DefaultCompilerOptions;
+
+ // get source filename
+ string filename = String.Empty;
try {
- PermissionSet ps = SecurityManager.ResolvePolicy (evidence);
- if (ps != null)
- ps.Demand ();
- sw = File.CreateText (tmpbase + Extension);
- sw.WriteLine (SourceTemplate.Replace ("{0}", DateTime.Now.ToString ()).Replace ("{1}", classSuffix).Replace ("{2}", code));
-
- sw.Close ();
- psi.FileName = CompilerCommand;
- psi.Arguments = String.Concat (GetCompilerArguments (tmpbase + Extension));
- psi.WorkingDirectory = tmpPath;
- proc.Start ();
-// Console.WriteLine (proc.StandardOutput.ReadToEnd ());
-// Console.WriteLine (proc.StandardError.ReadToEnd ());
- proc.WaitForExit (); // FIXME: should we configure timeout?
- Assembly generated = Assembly.LoadFrom (tmpbase + ".dll");
-
- if (generated == null)
- throw new XsltCompileException ("Could not load script assembly", null, scriptNode);
- return generated.GetType ("GeneratedAssembly.Script" + classSuffix);
- } catch (Exception ex) {
- throw new XsltCompileException ("Script compilation error: " + ex.Message, ex, scriptNode);
- } finally {
- try {
- File.Delete (tmpbase + Extension);
- File.Delete (tmpbase + ".dll");
- if (sw != null)
- sw.Close ();
- } catch (Exception) {
- }
+ if (scriptNode.BaseURI != String.Empty)
+ filename = new Uri (scriptNode.BaseURI).LocalPath;
+ } catch (FormatException) {
+ }
+ if (filename == String.Empty)
+ filename = "__baseURI_not_supplied__";
+
+ // get source location
+ IXmlLineInfo li = scriptNode as IXmlLineInfo;
+ string lineInfoLine =
+ li != null && li.LineNumber > 0 ?
+ String.Format (CultureInfo.InvariantCulture, "\n#line {0} \"{1}\"", li.LineNumber, filename) :
+ String.Empty;
+
+ string source = SourceTemplate.Replace ("{0}", DateTime.Now.ToString ()).Replace ("{1}", classSuffix).Replace ("{2}", lineInfoLine + code);
+
+ CompilerResults res = compiler.CompileAssemblyFromSource (parameters, source);
+ if (res.Errors.Count != 0)
+ throw new XsltCompileException ("Stylesheet script compile error: \n" + FormatErrorMessage (res) /*+ "Code :\n" + source*/, null, scriptNode);
+ if (res.CompiledAssembly == null)
+ throw new XsltCompileException ("Cannot compile stylesheet script", null, scriptNode);
+ return res.CompiledAssembly.GetType ("GeneratedAssembly.Script" + classSuffix);
+ }
+
+ private string FormatErrorMessage (CompilerResults res)
+ {
+ string s = String.Empty;
+ foreach (CompilerError e in res.Errors) {
+ object [] parameters = new object [] {"\n",
+ e.FileName,
+ e.Line > 0 ? " line " + e.Line : String.Empty,
+ e.IsWarning ? " WARNING: " : " ERROR: ",
+ e.ErrorNumber,
+ ": ",
+ e.ErrorText};
+ s += String.Concat (parameters);
}
+ return s;
}
}
#if MS_NET
this.CompilerCommand = "csc.exe";
#endif
- this.DefaultCompilerOptions = "/t:library /r:Microsoft.VisualBasic.dll";
+ this.DefaultCompilerOptions = "/t:library /r:System.dll /r:System.Xml.dll /r:Microsoft.VisualBasic.dll";
}
+ public override CodeDomProvider CodeDomProvider {\r
+ get { return new CSharpCodeProvider (); }\r
+ }\r
+
public override string Extension {
get { return ".cs"; }
}
this.DefaultCompilerOptions = "/t:library /r:System.dll /r:System.XML.dll /r:Microsoft.VisualBasic.dll";
}
+ public override CodeDomProvider CodeDomProvider {\r
+ get { return new VBCodeProvider (); }\r
+ }\r
+
public override string Extension {
get { return ".vb"; }
}
internal class JScriptCompilerInfo : ScriptCompilerInfo
{
+ static Type providerType;
+
public JScriptCompilerInfo ()
{
this.CompilerCommand = "mjs";
this.DefaultCompilerOptions = "/t:library /r:Microsoft.VisualBasic.dll";
}
+ public override CodeDomProvider CodeDomProvider {
+ get {
+ // no need for locking
+ if (providerType == null) {
+ Assembly jsasm = Assembly.LoadWithPartialName ("Microsoft.JScript", null);
+ if (jsasm != null)
+ providerType = jsasm.GetType ("Microsoft.JScript.JScriptCodeProvider");
+ }
+ return (CodeDomProvider) Activator.CreateInstance (providerType);
+ }
+ }
+
public override string Extension {
get { return ".js"; }
}
";
}
}
-
-#if !MS_NET
- public override Type GetScriptClass (string code, string classSuffix, XPathNavigator scriptNode, Evidence evidence)
- {
- PermissionSet ps = SecurityManager.ResolvePolicy (evidence);
- if (ps != null)
- ps.Demand ();
- Assembly jsasm = Assembly.LoadWithPartialName ("Microsoft.JScript.dll", evidence);
- Type providerType = jsasm.GetType ("Microsoft.JScript.JScriptCodeProvider");
- CodeDomProvider provider = (CodeDomProvider) Activator.CreateInstance (providerType);
-
- ICodeCompiler compiler = provider.CreateCompiler ();
- CompilerParameters parameters = new CompilerParameters ();
- parameters.CompilerOptions = DefaultCompilerOptions;
- CompilerResults res = compiler.CompileAssemblyFromSource (parameters, SourceTemplate.Replace ("{0}", DateTime.Now.ToString ()).Replace ("{1}", classSuffix).Replace ("{2}", code));
- if (res.CompiledAssembly == null)
- throw new XsltCompileException ("Cannot compile stylesheet script", null, scriptNode);
- return res.CompiledAssembly.GetType ("GeneratedAssembly.Script" + classSuffix);
- }
-#endif
}
}