2005-03-03 Atsushi Enomoto <atsushi@ximian.com>
[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 virtual string GetCompilerArguments (string targetFileName)
71                 {
72                         return String.Concat (DefaultCompilerOptions, " ", targetFileName);
73                 }
74
75
76                 public virtual Type GetScriptClass (string code, string classSuffix, XPathNavigator scriptNode, Evidence evidence)
77                 {
78                         PermissionSet ps = SecurityManager.ResolvePolicy (evidence);
79                         if (ps != null)
80                                 ps.Demand ();
81
82                         ICodeCompiler compiler = CodeDomProvider.CreateCompiler ();
83                         CompilerParameters parameters = new CompilerParameters ();
84                         parameters.CompilerOptions = DefaultCompilerOptions;
85
86                         // get source filename
87                         string filename = String.Empty;
88                         try {
89                                 if (scriptNode.BaseURI != String.Empty)
90                                         filename = new Uri (scriptNode.BaseURI).LocalPath;
91                         } catch (FormatException) {
92                         }
93                         if (filename == String.Empty)
94                                 filename = "__baseURI_not_supplied__";
95
96                         // get source location
97                         IXmlLineInfo li = scriptNode as IXmlLineInfo;
98                         string lineInfoLine = 
99                                 li != null && li.LineNumber > 0 ?
100                                 String.Format (CultureInfo.InvariantCulture, "\n#line {0} \"{1}\"", li.LineNumber, filename) :
101                                 String.Empty;
102
103                         string source = SourceTemplate.Replace ("{0}", DateTime.Now.ToString ()).Replace ("{1}", classSuffix).Replace ("{2}", lineInfoLine + code);
104
105                         CompilerResults res = compiler.CompileAssemblyFromSource (parameters, source);
106                         if (res.Errors.Count != 0)
107 //                              throw new XsltCompileException ("Stylesheet script compile error: \n" + FormatErrorMessage (res) /*+ "Code :\n" + source*/, null, scriptNode);
108                                 // Actually it should be XsltCompileException,
109                                 // but to match with silly MS implementation...
110                                 throw new XsltException ("Stylesheet script compile error: \n" + FormatErrorMessage (res) /*+ "Code :\n" + source*/, null, scriptNode);
111                         if (res.CompiledAssembly == null)
112                                 throw new XsltCompileException ("Cannot compile stylesheet script", null, scriptNode);
113                         return res.CompiledAssembly.GetType ("GeneratedAssembly.Script" + classSuffix);
114                 }
115
116                 private string FormatErrorMessage (CompilerResults res)
117                 {
118                         string s = String.Empty;
119                         foreach (CompilerError e in res.Errors) {
120                                 object [] parameters = new object [] {"\n",
121                                         e.FileName,
122                                         e.Line > 0 ? " line " + e.Line : String.Empty,
123                                         e.IsWarning ? " WARNING: " : " ERROR: ",
124                                         e.ErrorNumber,
125                                         ": ",
126                                         e.ErrorText};
127                                 s += String.Concat (parameters);
128                         }
129                         return s;
130                 }
131         }
132
133         internal class CSharpCompilerInfo : ScriptCompilerInfo
134         {
135                 public CSharpCompilerInfo ()
136                 {
137                         this.CompilerCommand = "mcs";
138 #if MS_NET
139                         this.CompilerCommand = "csc.exe";
140 #endif
141                         this.DefaultCompilerOptions = "/t:library /r:System.dll /r:System.Xml.dll /r:Microsoft.VisualBasic.dll";
142                 }
143
144                 public override CodeDomProvider CodeDomProvider {\r
145                         get { return new CSharpCodeProvider (); }\r
146                 }\r
147
148                 public override string Extension {
149                         get { return ".cs"; }
150                 }
151
152                 public override string SourceTemplate {
153                         get {
154                                 return @"// This file is automatically created by Mono managed XSLT engine.
155 // Created time: {0}
156 using System;
157 using System.Collections;
158 using System.Text;
159 using System.Text.RegularExpressions;
160 using System.Xml;
161 using System.Xml.XPath;
162 using System.Xml.Xsl;
163 using Microsoft.VisualBasic;
164
165 namespace GeneratedAssembly
166 {
167 public class Script{1}
168 {
169         {2}
170 }
171 }";
172                         }
173                 }
174         }
175
176         internal class VBCompilerInfo : ScriptCompilerInfo
177         {
178                 public VBCompilerInfo ()
179                 {
180                         this.CompilerCommand = "mbas";
181 #if MS_NET
182                         this.CompilerCommand = "vbc.exe";
183 #endif
184                         this.DefaultCompilerOptions = "/t:library  /r:System.dll /r:System.XML.dll /r:Microsoft.VisualBasic.dll";
185                 }
186
187                 public override CodeDomProvider CodeDomProvider {\r
188                         get { return new VBCodeProvider (); }\r
189                 }\r
190
191                 public override string Extension {
192                         get { return ".vb"; }
193                 }
194
195                 public override string SourceTemplate {
196                         get {
197                                 return @"' This file is automatically created by Mono managed XSLT engine.
198 ' Created time: {0}
199 imports System
200 imports System.Collections
201 imports System.Text
202 imports System.Text.RegularExpressions
203 imports System.Xml
204 imports System.Xml.XPath
205 imports System.Xml.Xsl
206 imports Microsoft.VisualBasic
207
208 namespace GeneratedAssembly
209 public Class Script{1}
210         {2}
211 end Class
212 end namespace
213 ";
214                         }
215                 }
216         }
217
218         internal class JScriptCompilerInfo : ScriptCompilerInfo
219         {
220                 static Type providerType;
221
222                 public JScriptCompilerInfo ()
223                 {
224                         this.CompilerCommand = "mjs";
225 #if MS_NET
226                         this.CompilerCommand = "jsc.exe";
227 #endif
228                         this.DefaultCompilerOptions = "/t:library /r:Microsoft.VisualBasic.dll";
229                 }
230
231                 public override CodeDomProvider CodeDomProvider {
232                         get {
233                                 // no need for locking
234                                 if (providerType == null) {
235                                         Assembly jsasm = Assembly.LoadWithPartialName ("Microsoft.JScript", null);
236                                         if (jsasm != null)
237                                                 providerType = jsasm.GetType ("Microsoft.JScript.JScriptCodeProvider");
238                                 }
239                                 return (CodeDomProvider) Activator.CreateInstance (providerType); 
240                         }
241                 }
242
243                 public override string Extension {
244                         get { return ".js"; }
245                 }
246
247                 public override string SourceTemplate {
248                         get {
249                                 return @"// This file is automatically created by Mono managed XSLT engine.
250 // Created time: {0}
251 import System;
252 import System.Collections;
253 import System.Text;
254 import System.Text.RegularExpressions;
255 import System.Xml;
256 import System.Xml.XPath;
257 import System.Xml.Xsl;
258 import Microsoft.VisualBasic;
259
260 package GeneratedAssembly
261 {
262 class Script{1} {
263         {2}
264 }
265 }
266 ";
267                         }
268                 }
269         }
270 }
271