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 // The attempt to use an already pre-compiled
85 // class assumes the caller has computed the
86 // classSuffix as a hash of the code
87 // string. MSXslScriptManager.cs does that.
88 // The mechanism how exactly such pre-compiled
89 // classes should be produced are not
91 string scriptname = "Script" + classSuffix;
92 string typename = "GeneratedAssembly." + scriptname;
94 Type retval = Type.GetType (typename);
101 Type retval = Assembly.LoadFrom (scriptname + ".dll").GetType (typename);
107 // OK, we have to actually compile the script.
108 ICodeCompiler compiler = CodeDomProvider.CreateCompiler ();
109 CompilerParameters parameters = new CompilerParameters ();
110 parameters.CompilerOptions = DefaultCompilerOptions;
112 // get source filename
113 string filename = String.Empty;
115 if (scriptNode.BaseURI != String.Empty)
116 filename = new Uri (scriptNode.BaseURI).LocalPath;
117 } catch (FormatException) {
119 if (filename == String.Empty)
120 filename = "__baseURI_not_supplied__";
122 // get source location
123 IXmlLineInfo li = scriptNode as IXmlLineInfo;
125 string source = SourceTemplate.Replace ("{0}",
126 DateTime.Now.ToString (CultureInfo.InvariantCulture))
127 .Replace ("{1}", classSuffix)
128 .Replace ("{2}", code);
129 source = FormatSource (li, filename, source);
131 CompilerResults res = compiler.CompileAssemblyFromSource (parameters, source);
132 foreach (CompilerError err in res.Errors)
134 // Actually it should be
135 // XsltCompileException, but to match
136 // with silly MS implementation...
137 // throw new XsltCompileException ("Stylesheet script compile error: \n" + FormatErrorMessage (res) /*+ "Code :\n" + source*/, null, scriptNode);
138 throw new XsltException ("Stylesheet script compile error: \n" + FormatErrorMessage (res) /*+ "Code :\n" + source*/, null, scriptNode);
140 if (res.CompiledAssembly == null)
141 throw new XsltCompileException ("Cannot compile stylesheet script", null, scriptNode);
142 return res.CompiledAssembly.GetType (typename);
145 private string FormatErrorMessage (CompilerResults res)
147 string s = String.Empty;
148 foreach (CompilerError e in res.Errors) {
149 object [] parameters = new object [] {"\n",
151 e.Line > 0 ? " line " + e.Line : String.Empty,
152 e.IsWarning ? " WARNING: " : " ERROR: ",
156 s += String.Concat (parameters);
162 internal class CSharpCompilerInfo : ScriptCompilerInfo
164 public CSharpCompilerInfo ()
166 this.CompilerCommand = "mcs";
168 this.CompilerCommand = "csc.exe";
170 this.DefaultCompilerOptions = "/t:library /r:System.dll /r:System.Xml.dll";
173 public override CodeDomProvider CodeDomProvider {
174 get { return new CSharpCodeProvider (); }
177 public override string Extension {
178 get { return ".cs"; }
181 public override string SourceTemplate {
183 return @"// This file is automatically created by Mono managed XSLT engine.
186 using System.Collections;
188 using System.Text.RegularExpressions;
190 using System.Xml.XPath;
191 using System.Xml.Xsl;
192 using Microsoft.VisualBasic;
194 namespace GeneratedAssembly
196 public class Script{1}
204 public override string FormatSource (IXmlLineInfo li, string file, string source)
208 return String.Format (CultureInfo.InvariantCulture, "#line {0} \"{1}\"\n{2}", li.LineNumber, file, source);
212 internal class VBCompilerInfo : ScriptCompilerInfo
214 public VBCompilerInfo ()
216 this.CompilerCommand = "mbas";
217 this.DefaultCompilerOptions = "/t:library";
219 this.CompilerCommand = "vbc.exe";
220 this.DefaultCompilerOptions = "/t:library /r:System.dll /r:System.Xml.dll /r:Microsoft.VisualBasic.dll";
224 public override CodeDomProvider CodeDomProvider {
225 get { return new VBCodeProvider (); }
228 public override string Extension {
229 get { return ".vb"; }
232 public override string SourceTemplate {
234 return @"' This file is automatically created by Mono managed XSLT engine.
237 imports System.Collections
239 imports System.Text.RegularExpressions
241 imports System.Xml.XPath
242 imports System.Xml.Xsl
243 imports Microsoft.VisualBasic
245 namespace GeneratedAssembly
246 public Class Script{1}
254 public override string FormatSource (IXmlLineInfo li, string file, string source)
258 return String.Format (CultureInfo.InvariantCulture,
259 "#ExternalSource (\"{1}\", {0})\n{2}\n#end ExternalSource",
260 li.LineNumber, new FileInfo (file).Name, source);
264 internal class JScriptCompilerInfo : ScriptCompilerInfo
266 static Type providerType;
268 public JScriptCompilerInfo ()
270 this.CompilerCommand = "mjs";
272 this.CompilerCommand = "jsc.exe";
274 this.DefaultCompilerOptions = "/t:library";
277 public override CodeDomProvider CodeDomProvider {
279 // no need for locking
280 if (providerType == null) {
281 Assembly jsasm = Assembly.LoadWithPartialName ("Microsoft.JScript", null);
283 providerType = jsasm.GetType ("Microsoft.JScript.JScriptCodeProvider");
285 return (CodeDomProvider) Activator.CreateInstance (providerType);
289 public override string Extension {
290 get { return ".js"; }
293 public override string SourceTemplate {
295 return @"// This file is automatically created by Mono managed XSLT engine.
298 import System.Collections;
300 import System.Text.RegularExpressions;
302 import System.Xml.XPath;
303 import System.Xml.Xsl;
304 import Microsoft.VisualBasic;
306 package GeneratedAssembly
316 public override string FormatSource (IXmlLineInfo li, string file, string source)
318 #if true // remove when mjs got @set @position support
323 return String.Format (CultureInfo.InvariantCulture,
324 "@set @position ({0}{1}{2}line={3};column={4})\n{5}",
325 file != null ? "file=" : String.Empty,
327 file != null ? "; " : String.Empty,