2 // MSXslScriptManager.cs
5 // Atsushi Enomoto (atsushi@ximian.com)
11 // Permission is hereby granted, free of charge, to any person obtaining
12 // a copy of this software and associated documentation files (the
13 // "Software"), to deal in the Software without restriction, including
14 // without limitation the rights to use, copy, modify, merge, publish,
15 // distribute, sublicense, and/or sell copies of the Software, and to
16 // permit persons to whom the Software is furnished to do so, subject to
17 // the following conditions:
19 // The above copyright notice and this permission notice shall be
20 // included in all copies or substantial portions of the Software.
22 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
23 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
24 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
25 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
26 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
27 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
28 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
32 using System.CodeDom.Compiler;
33 using System.Diagnostics;
34 using System.Collections;
35 using System.Globalization;
37 using System.Reflection;
38 using System.Security;
39 using System.Security.Policy;
41 using System.Xml.Schema;
42 using System.Xml.XPath;
44 using Microsoft.CSharp;
45 using Microsoft.VisualBasic;
47 namespace Mono.Xml.Xsl
49 internal abstract class ScriptCompilerInfo
51 string compilerCommand;
52 string defaultCompilerOptions;
54 public virtual string CompilerCommand {
55 get { return compilerCommand; }
56 set { compilerCommand = value; }
59 public virtual string DefaultCompilerOptions {
60 get { return defaultCompilerOptions; }
61 set { defaultCompilerOptions = value; }
64 public abstract CodeDomProvider CodeDomProvider { get; }
66 public abstract string Extension { get; }
68 public abstract string SourceTemplate { get; }
70 public abstract string FormatSource (IXmlLineInfo li, string file, string code);
72 public virtual string GetCompilerArguments (string targetFileName)
74 return String.Concat (DefaultCompilerOptions, " ", targetFileName);
78 public virtual Type GetScriptClass (string code, string classSuffix, XPathNavigator scriptNode, Evidence evidence)
80 PermissionSet ps = SecurityManager.ResolvePolicy (evidence);
84 ICodeCompiler compiler = CodeDomProvider.CreateCompiler ();
85 CompilerParameters parameters = new CompilerParameters ();
86 parameters.CompilerOptions = DefaultCompilerOptions;
88 // get source filename
89 string filename = String.Empty;
91 if (scriptNode.BaseURI != String.Empty)
92 filename = new Uri (scriptNode.BaseURI).LocalPath;
93 } catch (FormatException) {
95 if (filename == String.Empty)
96 filename = "__baseURI_not_supplied__";
98 // get source location
99 IXmlLineInfo li = scriptNode as IXmlLineInfo;
101 string source = SourceTemplate.Replace ("{0}",
102 DateTime.Now.ToString (CultureInfo.InvariantCulture))
103 .Replace ("{1}", classSuffix)
104 .Replace ("{2}", code);
105 source = FormatSource (li, filename, source);
107 CompilerResults res = compiler.CompileAssemblyFromSource (parameters, source);
108 foreach (CompilerError err in res.Errors)
110 // Actually it should be
111 // XsltCompileException, but to match
112 // with silly MS implementation...
113 // throw new XsltCompileException ("Stylesheet script compile error: \n" + FormatErrorMessage (res) /*+ "Code :\n" + source*/, null, scriptNode);
114 throw new XsltException ("Stylesheet script compile error: \n" + FormatErrorMessage (res) /*+ "Code :\n" + source*/, null, scriptNode);
116 if (res.CompiledAssembly == null)
117 throw new XsltCompileException ("Cannot compile stylesheet script", null, scriptNode);
118 return res.CompiledAssembly.GetType ("GeneratedAssembly.Script" + classSuffix);
121 private string FormatErrorMessage (CompilerResults res)
123 string s = String.Empty;
124 foreach (CompilerError e in res.Errors) {
125 object [] parameters = new object [] {"\n",
127 e.Line > 0 ? " line " + e.Line : String.Empty,
128 e.IsWarning ? " WARNING: " : " ERROR: ",
132 s += String.Concat (parameters);
138 internal class CSharpCompilerInfo : ScriptCompilerInfo
140 public CSharpCompilerInfo ()
142 this.CompilerCommand = "mcs";
144 this.CompilerCommand = "csc.exe";
146 this.DefaultCompilerOptions = "/t:library /r:System.dll /r:System.Xml.dll /r:Microsoft.VisualBasic.dll";
149 public override CodeDomProvider CodeDomProvider {
150 get { return new CSharpCodeProvider (); }
153 public override string Extension {
154 get { return ".cs"; }
157 public override string SourceTemplate {
159 return @"// This file is automatically created by Mono managed XSLT engine.
162 using System.Collections;
164 using System.Text.RegularExpressions;
166 using System.Xml.XPath;
167 using System.Xml.Xsl;
168 using Microsoft.VisualBasic;
170 namespace GeneratedAssembly
172 public class Script{1}
180 public override string FormatSource (IXmlLineInfo li, string file, string source)
184 return String.Format (CultureInfo.InvariantCulture, "#line {0} \"{1}\"\n{2}", li.LineNumber, file, source);
188 internal class VBCompilerInfo : ScriptCompilerInfo
190 public VBCompilerInfo ()
192 this.CompilerCommand = "mbas";
193 this.DefaultCompilerOptions = "/t:library";
195 this.CompilerCommand = "vbc.exe";
196 this.DefaultCompilerOptions = "/t:library /r:System.dll /r:System.Xml.dll /r:Microsoft.VisualBasic.dll";
200 public override CodeDomProvider CodeDomProvider {
201 get { return new VBCodeProvider (); }
204 public override string Extension {
205 get { return ".vb"; }
208 public override string SourceTemplate {
210 return @"' This file is automatically created by Mono managed XSLT engine.
213 imports System.Collections
215 imports System.Text.RegularExpressions
217 imports System.Xml.XPath
218 imports System.Xml.Xsl
219 imports Microsoft.VisualBasic
221 namespace GeneratedAssembly
222 public Class Script{1}
230 public override string FormatSource (IXmlLineInfo li, string file, string source)
234 return String.Format (CultureInfo.InvariantCulture,
235 "#ExternalSource (\"{1}\", {0})\n{2}\n#end ExternalSource",
236 li.LineNumber, new FileInfo (file).Name, source);
240 internal class JScriptCompilerInfo : ScriptCompilerInfo
242 static Type providerType;
244 public JScriptCompilerInfo ()
246 this.CompilerCommand = "mjs";
248 this.CompilerCommand = "jsc.exe";
250 this.DefaultCompilerOptions = "/t:library /r:Microsoft.VisualBasic.dll";
253 public override CodeDomProvider CodeDomProvider {
255 // no need for locking
256 if (providerType == null) {
257 Assembly jsasm = Assembly.LoadWithPartialName ("Microsoft.JScript", null);
259 providerType = jsasm.GetType ("Microsoft.JScript.JScriptCodeProvider");
261 return (CodeDomProvider) Activator.CreateInstance (providerType);
265 public override string Extension {
266 get { return ".js"; }
269 public override string SourceTemplate {
271 return @"// This file is automatically created by Mono managed XSLT engine.
274 import System.Collections;
276 import System.Text.RegularExpressions;
278 import System.Xml.XPath;
279 import System.Xml.Xsl;
280 import Microsoft.VisualBasic;
282 package GeneratedAssembly
292 public override string FormatSource (IXmlLineInfo li, string file, string source)
294 #if true // remove when mjs got @set @position support
299 return String.Format (CultureInfo.InvariantCulture,
300 "@set @position ({0}{1}{2}line={3};column={4})\n{5}",
301 file != null ? "file=" : String.Empty,
303 file != null ? "; " : String.Empty,