gluezilla/src:
[mono.git] / mcs / class / System.XML / Mono.Xml.Xsl / ScriptCompilerInfo.cs
1 //
2 // MSXslScriptManager.cs
3 //
4 // Author:
5 //      Atsushi Enomoto (atsushi@ximian.com)
6 //
7 // (C)2003 Novell inc.
8 //
9
10 //
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:
18 // 
19 // The above copyright notice and this permission notice shall be
20 // included in all copies or substantial portions of the Software.
21 // 
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.
29 //
30 using System;
31 using System.CodeDom;
32 using System.CodeDom.Compiler;
33 using System.Diagnostics;
34 using System.Collections;
35 using System.Globalization;
36 using System.IO;
37 using System.Reflection;
38 using System.Security;
39 using System.Security.Policy;
40 using System.Xml;
41 using System.Xml.Schema;
42 using System.Xml.XPath;
43 using System.Xml.Xsl;
44 using Microsoft.CSharp;
45 using Microsoft.VisualBasic;
46
47 namespace Mono.Xml.Xsl
48 {
49         internal abstract class ScriptCompilerInfo
50         {
51                 string compilerCommand;
52                 string defaultCompilerOptions;
53
54                 public virtual string CompilerCommand {
55                         get { return compilerCommand; }
56                         set { compilerCommand = value; }
57                 }
58
59                 public virtual string DefaultCompilerOptions {
60                         get { return defaultCompilerOptions; }
61                         set { defaultCompilerOptions = value; }
62                 }
63
64                 public abstract CodeDomProvider CodeDomProvider { get; }
65
66                 public abstract string Extension { get; }
67
68                 public abstract string SourceTemplate { get; }
69
70                 public abstract string FormatSource (IXmlLineInfo li, string file, string code);
71
72                 public virtual string GetCompilerArguments (string targetFileName)
73                 {
74                         return String.Concat (DefaultCompilerOptions, " ", targetFileName);
75                 }
76
77
78                 public virtual Type GetScriptClass (string code, string classSuffix, XPathNavigator scriptNode, Evidence evidence)
79                 {
80                         PermissionSet ps = SecurityManager.ResolvePolicy (evidence);
81                         if (ps != null)
82                                 ps.Demand ();
83
84                         ICodeCompiler compiler = CodeDomProvider.CreateCompiler ();
85                         CompilerParameters parameters = new CompilerParameters ();
86                         parameters.CompilerOptions = DefaultCompilerOptions;
87
88                         // get source filename
89                         string filename = String.Empty;
90                         try {
91                                 if (scriptNode.BaseURI != String.Empty)
92                                         filename = new Uri (scriptNode.BaseURI).LocalPath;
93                         } catch (FormatException) {
94                         }
95                         if (filename == String.Empty)
96                                 filename = "__baseURI_not_supplied__";
97
98                         // get source location
99                         IXmlLineInfo li = scriptNode as IXmlLineInfo;
100
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);
106
107                         CompilerResults res = compiler.CompileAssemblyFromSource (parameters, source);
108                         foreach (CompilerError err in res.Errors)
109                                 if (!err.IsWarning)
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);
115
116                         if (res.CompiledAssembly == null)
117                                 throw new XsltCompileException ("Cannot compile stylesheet script", null, scriptNode);
118                         return res.CompiledAssembly.GetType ("GeneratedAssembly.Script" + classSuffix);
119                 }
120
121                 private string FormatErrorMessage (CompilerResults res)
122                 {
123                         string s = String.Empty;
124                         foreach (CompilerError e in res.Errors) {
125                                 object [] parameters = new object [] {"\n",
126                                         e.FileName,
127                                         e.Line > 0 ? " line " + e.Line : String.Empty,
128                                         e.IsWarning ? " WARNING: " : " ERROR: ",
129                                         e.ErrorNumber,
130                                         ": ",
131                                         e.ErrorText};
132                                 s += String.Concat (parameters);
133                         }
134                         return s;
135                 }
136         }
137
138         internal class CSharpCompilerInfo : ScriptCompilerInfo
139         {
140                 public CSharpCompilerInfo ()
141                 {
142                         this.CompilerCommand = "mcs";
143 #if MS_NET
144                         this.CompilerCommand = "csc.exe";
145 #endif
146                         this.DefaultCompilerOptions = "/t:library /r:System.dll /r:System.Xml.dll /r:Microsoft.VisualBasic.dll";
147                 }
148
149                 public override CodeDomProvider CodeDomProvider {
150                         get { return new CSharpCodeProvider (); }
151                 }
152
153                 public override string Extension {
154                         get { return ".cs"; }
155                 }
156
157                 public override string SourceTemplate {
158                         get {
159                                 return @"// This file is automatically created by Mono managed XSLT engine.
160 // Created time: {0}
161 using System;
162 using System.Collections;
163 using System.Text;
164 using System.Text.RegularExpressions;
165 using System.Xml;
166 using System.Xml.XPath;
167 using System.Xml.Xsl;
168 using Microsoft.VisualBasic;
169
170 namespace GeneratedAssembly
171 {
172 public class Script{1}
173 {
174         {2}
175 }
176 }";
177                         }
178                 }
179
180                 public override string FormatSource (IXmlLineInfo li, string file, string source)
181                 {
182                         if (li == null)
183                                 return source;
184                         return String.Format (CultureInfo.InvariantCulture, "#line {0} \"{1}\"\n{2}", li.LineNumber, file, source);
185                 }
186         }
187
188         internal class VBCompilerInfo : ScriptCompilerInfo
189         {
190                 public VBCompilerInfo ()
191                 {
192                         this.CompilerCommand = "mbas";
193                         this.DefaultCompilerOptions = "/t:library";
194 #if MS_NET
195                         this.CompilerCommand = "vbc.exe";
196                         this.DefaultCompilerOptions = "/t:library  /r:System.dll /r:System.Xml.dll /r:Microsoft.VisualBasic.dll";
197 #endif
198                 }
199
200                 public override CodeDomProvider CodeDomProvider {
201                         get { return new VBCodeProvider (); }
202                 }
203
204                 public override string Extension {
205                         get { return ".vb"; }
206                 }
207
208                 public override string SourceTemplate {
209                         get {
210                                 return @"' This file is automatically created by Mono managed XSLT engine.
211 ' Created time: {0}
212 imports System
213 imports System.Collections
214 imports System.Text
215 imports System.Text.RegularExpressions
216 imports System.Xml
217 imports System.Xml.XPath
218 imports System.Xml.Xsl
219 imports Microsoft.VisualBasic
220
221 namespace GeneratedAssembly
222 public Class Script{1}
223         {2}
224 end Class
225 end namespace
226 ";
227                         }
228                 }
229
230                 public override string FormatSource (IXmlLineInfo li, string file, string source)
231                 {
232                         if (li == null)
233                                 return source;
234                         return String.Format (CultureInfo.InvariantCulture,
235                                 "#ExternalSource (\"{1}\", {0})\n{2}\n#end ExternalSource",
236                                 li.LineNumber, new FileInfo (file).Name, source);
237                 }
238         }
239
240         internal class JScriptCompilerInfo : ScriptCompilerInfo
241         {
242                 static Type providerType;
243
244                 public JScriptCompilerInfo ()
245                 {
246                         this.CompilerCommand = "mjs";
247 #if MS_NET
248                         this.CompilerCommand = "jsc.exe";
249 #endif
250                         this.DefaultCompilerOptions = "/t:library /r:Microsoft.VisualBasic.dll";
251                 }
252
253                 public override CodeDomProvider CodeDomProvider {
254                         get {
255                                 // no need for locking
256                                 if (providerType == null) {
257                                         Assembly jsasm = Assembly.LoadWithPartialName ("Microsoft.JScript", null);
258                                         if (jsasm != null)
259                                                 providerType = jsasm.GetType ("Microsoft.JScript.JScriptCodeProvider");
260                                 }
261                                 return (CodeDomProvider) Activator.CreateInstance (providerType); 
262                         }
263                 }
264
265                 public override string Extension {
266                         get { return ".js"; }
267                 }
268
269                 public override string SourceTemplate {
270                         get {
271                                 return @"// This file is automatically created by Mono managed XSLT engine.
272 // Created time: {0}
273 import System;
274 import System.Collections;
275 import System.Text;
276 import System.Text.RegularExpressions;
277 import System.Xml;
278 import System.Xml.XPath;
279 import System.Xml.Xsl;
280 import Microsoft.VisualBasic;
281
282 package GeneratedAssembly
283 {
284 class Script{1} {
285         {2}
286 }
287 }
288 ";
289                         }
290                 }
291
292                 public override string FormatSource (IXmlLineInfo li, string file, string source)
293                 {
294 #if true // remove when mjs got @set @position support
295                         return source;
296 #else
297                         if (li == null)
298                                 return source;
299                         return String.Format (CultureInfo.InvariantCulture,
300                                 "@set @position ({0}{1}{2}line={3};column={4})\n{5}",
301                                 file != null ? "file=" : String.Empty,
302                                 file,
303                                 file != null ? "; " : String.Empty,
304                                 li.LineNumber,
305                                 li.LinePosition,
306                                 source);
307 #endif
308                 }
309         }
310 }
311