Merge pull request #1325 from madrang/CryptoToolsCtorCheck
[mono.git] / mcs / class / System / Microsoft.VisualBasic / VBCodeCompiler.cs
index ca92148b7ea9c80fa92df34337511a6142e02fb5..bdb08db595adb849f3cea1b849b7b8a12fb9917a 100644 (file)
@@ -1,15 +1,15 @@
-//\r
-// Microsoft VisualBasic VBCodeCompiler Class implementation\r
-//\r
-// Authors:\r
-//     Jochen Wezel (jwezel@compumaster.de)\r
-//     Gonzalo Paniagua Javier (gonzalo@ximian.com)\r
-//\r
-// (c) 2003 Jochen Wezel (http://www.compumaster.de)\r
-// (c) 2003 Ximian, Inc. (http://www.ximian.com)\r
-//\r
-// Modifications:\r
-// 2003-11-28 JW: create reference to Microsoft.VisualBasic if not explicitly done\r
+//
+// Microsoft VisualBasic VBCodeCompiler Class implementation
+//
+// Authors:
+//     Jochen Wezel (jwezel@compumaster.de)
+//     Gonzalo Paniagua Javier (gonzalo@ximian.com)
+//
+// (c) 2003 Jochen Wezel (http://www.compumaster.de)
+// (c) 2003 Ximian, Inc. (http://www.ximian.com)
+//
+// Modifications:
+// 2003-11-28 JW: create reference to Microsoft.VisualBasic if not explicitly done
 
 //
 // Permission is hereby granted, free of charge, to any person obtaining
 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 //
-\r
-namespace Microsoft.VisualBasic\r
-{\r
-       using System;\r
-       using System.CodeDom;\r
-       using System.CodeDom.Compiler;\r
-       using System.IO;\r
-       using System.Text;\r
-       using System.Reflection;\r
-       using System.Collections;\r
-       using System.Collections.Specialized;\r
-       using System.Diagnostics;\r
-       using System.Text.RegularExpressions;\r
-\r
-       internal class VBCodeCompiler: VBCodeGenerator, ICodeCompiler\r
-       {\r
-               static string windowsMonoPath;\r
-               static string windowsMbasPath;\r
-               static VBCodeCompiler ()\r
-               {\r
-                       if (Path.DirectorySeparatorChar == '\\') {\r
-                               // FIXME: right now we use "fixed" version 1.0\r
-                               // mcs at any time.\r
-                               PropertyInfo gac = typeof (Environment).GetProperty ("GacPath", BindingFlags.Static|BindingFlags.NonPublic);\r
-                               MethodInfo get_gac = gac.GetGetMethod (true);\r
-                               string p = Path.GetDirectoryName (\r
-                                       (string) get_gac.Invoke (null, null));\r
-                               windowsMonoPath = Path.Combine (\r
-                                       Path.GetDirectoryName (\r
-                                               Path.GetDirectoryName (p)),\r
-                                       "bin\\mono.bat");\r
-                               if (!File.Exists (windowsMonoPath))\r
-                                       windowsMonoPath = Path.Combine (\r
-                                               Path.GetDirectoryName (\r
-                                                       Path.GetDirectoryName (p)),\r
-                                               "bin\\mono.exe");\r
-                               windowsMbasPath =\r
-                                       Path.Combine (p, "1.0\\mbas.exe");\r
-                       }\r
-               }\r
-\r
-               //\r
-               // Constructors\r
-               //\r
-               public VBCodeCompiler()\r
-               {\r
-               }\r
-\r
-               //\r
-               // Methods\r
-               //\r
-               [MonoTODO]\r
-               public CompilerResults CompileAssemblyFromDom (CompilerParameters options,CodeCompileUnit e)\r
-               {\r
-                       return CompileAssemblyFromDomBatch (options, new CodeCompileUnit []{e});\r
-               }\r
-\r
-               public CompilerResults CompileAssemblyFromDomBatch (CompilerParameters options,\r
-                                                                   CodeCompileUnit [] ea)\r
-               {\r
-                       string [] fileNames = new string [ea.Length];\r
-                       int i = 0;\r
-                       if (options == null)\r
-                       options = new CompilerParameters ();\r
-\r
-                       StringCollection assemblies = options.ReferencedAssemblies;\r
-\r
-                       foreach (CodeCompileUnit e in ea) {\r
-                               fileNames [i] = GetTempFileNameWithExtension (options.TempFiles, "vb");\r
-                               FileStream f = new FileStream (fileNames [i], FileMode.OpenOrCreate);\r
-                               StreamWriter s = new StreamWriter (f);\r
-                               if (e.ReferencedAssemblies != null) {\r
-                                       foreach (string str in e.ReferencedAssemblies) {\r
-                                               if (!assemblies.Contains (str))\r
-                                                       assemblies.Add (str);\r
-                                       }\r
-                               }\r
-\r
-                               ((ICodeGenerator)this).GenerateCodeFromCompileUnit (e, s, new CodeGeneratorOptions());\r
-                               s.Close();\r
-                               f.Close();\r
-                               i++;\r
-                       }\r
-                       return CompileAssemblyFromFileBatch (options, fileNames);\r
-               }\r
-\r
-               public CompilerResults CompileAssemblyFromFile (CompilerParameters options, string fileName)\r
-               {\r
-                       return CompileAssemblyFromFileBatch (options, new string []{fileName});\r
-               }\r
-\r
-               public CompilerResults CompileAssemblyFromFileBatch (CompilerParameters options,\r
-                                                                    string [] fileNames)\r
-               {\r
-                       if (null == options)\r
-                               throw new ArgumentNullException ("options");\r
-\r
-                       if (null == fileNames)\r
-                               throw new ArgumentNullException ("fileNames");\r
-\r
-                       CompilerResults results = new CompilerResults (options.TempFiles);\r
-                       Process mbas = new Process ();\r
-\r
-                       string mbas_output;\r
-                       string [] mbas_output_lines;\r
-                       // FIXME: these lines had better be platform independent.\r
-                       if (Path.DirectorySeparatorChar == '\\') {\r
-                               mbas.StartInfo.FileName = windowsMonoPath;\r
-                               mbas.StartInfo.Arguments = windowsMbasPath + ' ' + BuildArgs (options, fileNames);\r
-                       }\r
-                       else {\r
-                               mbas.StartInfo.FileName = "mbas";\r
-                               mbas.StartInfo.Arguments = BuildArgs (options,fileNames);\r
-                       }\r
-                       mbas.StartInfo.CreateNoWindow = true;\r
-                       mbas.StartInfo.UseShellExecute = false;\r
-                       mbas.StartInfo.RedirectStandardOutput = true;\r
-                       try {\r
-                               mbas.Start();\r
-                               mbas_output = mbas.StandardOutput.ReadToEnd ();\r
-                               mbas.WaitForExit();\r
-                       } finally {\r
-                               results.NativeCompilerReturnValue = mbas.ExitCode;\r
-                               mbas.Close ();\r
-                       }\r
-\r
-                       mbas_output_lines = mbas_output.Split(Environment.NewLine.ToCharArray());\r
-                       bool loadIt=true;\r
-                       foreach (string error_line in mbas_output_lines) {\r
-                               CompilerError error = CreateErrorFromString (error_line);\r
-                               if (null != error) {\r
-                                       results.Errors.Add (error);\r
-                                       if (!error.IsWarning)\r
-                                               loadIt = false;\r
-                               }\r
-                       }\r
-\r
-                       if (loadIt)\r
-                               results.CompiledAssembly=Assembly.LoadFrom(options.OutputAssembly);\r
-                       else\r
-                               results.CompiledAssembly=null;\r
-\r
-                       return results;\r
-               }\r
-\r
-               public CompilerResults CompileAssemblyFromSource (CompilerParameters options,\r
-                                                                 string source)\r
-               {\r
-                       return CompileAssemblyFromSourceBatch (options, new string [] {source});\r
-               }\r
-\r
-               public CompilerResults CompileAssemblyFromSourceBatch (CompilerParameters options,\r
-                                                                       string [] sources)\r
-               {\r
-                       string [] fileNames = new string [sources.Length];\r
-                       int i = 0;\r
-                       foreach (string source in sources) {\r
-                               fileNames [i] = GetTempFileNameWithExtension (options.TempFiles, "vb");\r
-                               FileStream f = new FileStream (fileNames [i], FileMode.OpenOrCreate);\r
-                               StreamWriter s = new StreamWriter (f);\r
-                               s.Write (source);\r
-                               s.Close ();\r
-                               f.Close ();\r
-                               i++;\r
-                       }\r
-                       return CompileAssemblyFromFileBatch(options,fileNames);\r
-               }\r
-\r
-               static string BuildArgs (CompilerParameters options, string [] fileNames)\r
-               {\r
+
+using System;
+using System.CodeDom;
+using System.CodeDom.Compiler;
+using System.ComponentModel;
+using System.IO;
+using System.Text;
+using System.Reflection;
+using System.Collections;
+using System.Collections.Specialized;
+using System.Diagnostics;
+using System.Text.RegularExpressions;
+
+namespace Microsoft.VisualBasic
+{
+       internal class VBCodeCompiler : VBCodeGenerator, ICodeCompiler
+       {
+               static string windowsMonoPath;
+               static string windowsvbncPath;
+               static string unixVbncCommand;
+
+               static VBCodeCompiler ()
+               {
+                       if (Path.DirectorySeparatorChar == '\\') {
+                               PropertyInfo gac = typeof (Environment).GetProperty ("GacPath", BindingFlags.Static | BindingFlags.NonPublic);
+                               MethodInfo get_gac = gac.GetGetMethod (true);
+                               string p = Path.GetDirectoryName (
+                                       (string) get_gac.Invoke (null, null));
+                               windowsMonoPath = Path.Combine (
+                                       Path.GetDirectoryName (
+                                               Path.GetDirectoryName (p)),
+                                       "bin\\mono.bat");
+                               if (!File.Exists (windowsMonoPath))
+                                       windowsMonoPath = Path.Combine (
+                                               Path.GetDirectoryName (
+                                                       Path.GetDirectoryName (p)),
+                                               "bin\\mono.exe");
+                               windowsvbncPath =
+                                       Path.Combine (p, "2.0\\vbnc.exe");
+                       } else {
+                               var mscorlibPath = new Uri (typeof (object).Assembly.CodeBase).LocalPath;
+                               var unixMcsPath = Path.GetFullPath (Path.Combine (mscorlibPath, "..", "..", "..", "..", "bin", "vbnc"));
+                               if (File.Exists (unixMcsPath))
+                                       unixVbncCommand = unixMcsPath;
+                               else
+                                       unixVbncCommand = "vbnc";
+                       }
+               }
+
+               public CompilerResults CompileAssemblyFromDom (CompilerParameters options, CodeCompileUnit e)
+               {
+                       return CompileAssemblyFromDomBatch (options, new CodeCompileUnit[] { e });
+               }
+
+               public CompilerResults CompileAssemblyFromDomBatch (CompilerParameters options, CodeCompileUnit[] ea)
+               {
+                       if (options == null) {
+                               throw new ArgumentNullException ("options");
+                       }
+
+                       try {
+                               return CompileFromDomBatch (options, ea);
+                       } finally {
+                               options.TempFiles.Delete ();
+                       }
+               }
+
+               public CompilerResults CompileAssemblyFromFile (CompilerParameters options, string fileName)
+               {
+                       return CompileAssemblyFromFileBatch (options, new string[] { fileName });
+               }
+
+               public CompilerResults CompileAssemblyFromFileBatch (CompilerParameters options, string[] fileNames)
+               {
+                       if (options == null) {
+                               throw new ArgumentNullException ("options");
+                       }
+
+                       try {
+                               return CompileFromFileBatch (options, fileNames);
+                       } finally {
+                               options.TempFiles.Delete ();
+                       }
+               }
+
+               public CompilerResults CompileAssemblyFromSource (CompilerParameters options, string source)
+               {
+                       return CompileAssemblyFromSourceBatch (options, new string[] { source });
+               }
+
+               public CompilerResults CompileAssemblyFromSourceBatch (CompilerParameters options, string[] sources)
+               {
+                       if (options == null) {
+                               throw new ArgumentNullException ("options");
+                       }
+
+                       try {
+                               return CompileFromSourceBatch (options, sources);
+                       } finally {
+                               options.TempFiles.Delete ();
+                       }
+               }
+
+               static string BuildArgs (CompilerParameters options, string[] fileNames)
+               {
                        StringBuilder args = new StringBuilder ();
-                       args.AppendFormat ("/quiet ");\r
-                       if (options.GenerateExecutable)\r
-                               args.AppendFormat("/target:exe ");\r
-                       else\r
-                               args.AppendFormat("/target:library ");\r
-\r
-                       /* Disabled. It causes problems now. -- Gonzalo\r
-                       if (options.IncludeDebugInformation)\r
-                               args.AppendFormat("/debug ");\r
-                       */\r
-\r
-                       if (options.TreatWarningsAsErrors)\r
-                               args.AppendFormat ("/warnaserror ");\r
-\r
-                       if (options.WarningLevel != -1)\r
-                               args.AppendFormat ("/wlevel:{0} ", options.WarningLevel);\r
-\r
-                       if (options.OutputAssembly == null) {\r
-                               string ext = (options.GenerateExecutable ? "exe" : "dll");\r
-                               options.OutputAssembly = GetTempFileNameWithExtension (options.TempFiles, ext);\r
-                       }\r
-\r
-                       args.AppendFormat ("/out:\"{0}\" ", options.OutputAssembly);\r
-\r
-                       bool Reference2MSVBFound;\r
-                       Reference2MSVBFound = false;\r
-                       if (null != options.ReferencedAssemblies) \r
-                       {\r
-                               foreach (string import in options.ReferencedAssemblies)\r
-                               {\r
-                                       if (string.Compare (import, "Microsoft.VisualBasic", true, System.Globalization.CultureInfo.InvariantCulture) == 0)\r
-                                               Reference2MSVBFound = true;\r
-                                       args.AppendFormat ("/r:\"{0}\" ", import);\r
-                               }\r
-                       }\r
-                       // add standard import to Microsoft.VisualBasic if missing\r
-                       if (Reference2MSVBFound == false)\r
-                               args.AppendFormat ("/r:\"{0}\" ", "Microsoft.VisualBasic");\r
-\r
-                       args.AppendFormat(" -- "); // makes mbas not try to process filenames as options\r
-\r
-                       foreach (string source in fileNames)\r
-                               args.AppendFormat("\"{0}\" ",source);\r
-\r
-                       return args.ToString();\r
-               }\r
-\r
-               static CompilerError CreateErrorFromString (string error_string)\r
-               {\r
-                       // When IncludeDebugInformation is true, prevents the debug symbols stats from braeking this.\r
-                       if (error_string.StartsWith ("WROTE SYMFILE") || error_string.StartsWith ("OffsetTable"))\r
-                               return null;\r
-\r
-                       CompilerError error = new CompilerError ();\r
-                       Regex reg = new Regex (@"^(\s*(?<file>.*)\((?<line>\d*)(,(?<column>\d*))?\)\s+)*" +\r
-                                               @"(?<level>error|warning)\s*(?<number>.*):\s(?<message>.*)",\r
-                                               RegexOptions.Compiled | RegexOptions.ExplicitCapture);\r
-\r
-                       Match match = reg.Match (error_string);\r
-                       if (!match.Success)\r
-                               return null;\r
-\r
-                       if (String.Empty != match.Result("${file}"))\r
-                               error.FileName = match.Result ("${file}");\r
-\r
-                       if (String.Empty != match.Result ("${line}"))\r
-                               error.Line = Int32.Parse (match.Result ("${line}"));\r
-\r
-                       if (String.Empty != match.Result( "${column}"))\r
-                               error.Column = Int32.Parse (match.Result ("${column}"));\r
-\r
-                       if (match.Result ("${level}") =="warning")\r
-                               error.IsWarning = true;\r
-\r
-                       error.ErrorNumber = match.Result ("${number}");\r
-                       error.ErrorText = match.Result ("${message}");\r
-                       return error;\r
-               }\r
-\r
-               static string GetTempFileNameWithExtension (TempFileCollection temp_files, string extension)\r
-               {\r
-                       return temp_files.AddExtension (extension);\r
-               }\r
-       }\r
-}\r
-\r
+                       args.Append ("/quiet ");
+                       if (options.GenerateExecutable)
+                               args.Append ("/target:exe ");
+                       else
+                               args.Append ("/target:library ");
+
+                       /* Disabled. It causes problems now. -- Gonzalo
+                       if (options.IncludeDebugInformation)
+                               args.AppendFormat("/debug ");
+                       */
+
+                       if (options.TreatWarningsAsErrors)
+                               args.Append ("/warnaserror ");
+
+                       /* Disabled. vbnc does not support warninglevels.
+                       if (options.WarningLevel != -1)
+                               args.AppendFormat ("/wlevel:{0} ", options.WarningLevel);
+                       */
+
+                       if (options.OutputAssembly == null || options.OutputAssembly.Length == 0) {
+                               string ext = (options.GenerateExecutable ? "exe" : "dll");
+                               options.OutputAssembly = GetTempFileNameWithExtension (options.TempFiles, ext, !options.GenerateInMemory);
+                       }
+
+                       args.AppendFormat ("/out:\"{0}\" ", options.OutputAssembly);
+
+                       bool Reference2MSVBFound;
+                       Reference2MSVBFound = false;
+                       if (null != options.ReferencedAssemblies) {
+                               foreach (string import in options.ReferencedAssemblies) {
+                                       if (string.Compare (import, "Microsoft.VisualBasic", true, System.Globalization.CultureInfo.InvariantCulture) == 0)
+                                               Reference2MSVBFound = true;
+                                       args.AppendFormat ("/r:\"{0}\" ", import);
+                               }
+                       }
+                       
+                       // add standard import to Microsoft.VisualBasic if missing
+                       if (!Reference2MSVBFound)
+                               args.Append ("/r:\"Microsoft.VisualBasic.dll\" ");
+
+                       if (options.CompilerOptions != null) {
+                               args.Append (options.CompilerOptions);
+                               args.Append (" ");
+                       }
+                       /* Disabled, vbnc does not support this.
+                       args.Append (" -- "); // makes vbnc not try to process filenames as options
+                       */
+                       foreach (string source in fileNames)
+                               args.AppendFormat (" \"{0}\" ", source);
+
+                       return args.ToString ();
+               }
+
+               static CompilerError CreateErrorFromString (string error_string)
+               {
+                       CompilerError error = new CompilerError ();
+                       Regex reg = new Regex (@"^(\s*(?<file>.*)?\((?<line>\d*)(,(?<column>\d*))?\)\s+)?:\s*" +
+                                               @"(?<level>Error|Warning)?\s*(?<number>.*):\s(?<message>.*)",
+                                               RegexOptions.Compiled | RegexOptions.ExplicitCapture);
+
+                       Match match = reg.Match (error_string);
+                       if (!match.Success) {
+                               return null;
+                       }
+
+                       if (String.Empty != match.Result ("${file}"))
+                               error.FileName = match.Result ("${file}").Trim ();
+
+                       if (String.Empty != match.Result ("${line}"))
+                               error.Line = Int32.Parse (match.Result ("${line}"));
+
+                       if (String.Empty != match.Result ("${column}"))
+                               error.Column = Int32.Parse (match.Result ("${column}"));
+
+                       if (match.Result ("${level}").Trim () == "Warning")
+                               error.IsWarning = true;
+
+                       error.ErrorNumber = match.Result ("${number}");
+                       error.ErrorText = match.Result ("${message}");
+                       
+                       return error;
+               }
+
+               private static string GetTempFileNameWithExtension (TempFileCollection temp_files, string extension, bool keepFile)
+               {
+                       return temp_files.AddExtension (extension, keepFile);
+               }
+
+               private static string GetTempFileNameWithExtension (TempFileCollection temp_files, string extension)
+               {
+                       return temp_files.AddExtension (extension);
+               }
+
+               private CompilerResults CompileFromFileBatch (CompilerParameters options, string[] fileNames)
+               {
+                       
+                       if (options == null) {
+                               throw new ArgumentNullException ("options");
+                       }
+
+                       if (fileNames == null) {
+                               throw new ArgumentNullException ("fileNames");
+                       }
+
+                       CompilerResults results = new CompilerResults (options.TempFiles);
+                       Process vbnc = new Process ();
+
+                       string vbnc_output = "";
+                       string[] vbnc_output_lines;
+                       // FIXME: these lines had better be platform independent.
+                       if (Path.DirectorySeparatorChar == '\\') {
+                               vbnc.StartInfo.FileName = windowsMonoPath;
+                               vbnc.StartInfo.Arguments = windowsvbncPath + ' ' + BuildArgs (options, fileNames);
+                       } else {
+                               vbnc.StartInfo.FileName = "vbnc";
+                               vbnc.StartInfo.Arguments = BuildArgs (options, fileNames);
+                       }
+                       //Console.WriteLine (vbnc.StartInfo.Arguments);
+                       vbnc.StartInfo.CreateNoWindow = true;
+                       vbnc.StartInfo.UseShellExecute = false;
+                       vbnc.StartInfo.RedirectStandardOutput = true;
+                       try {
+                               vbnc.Start ();
+                       } catch (Exception e) {
+                               Win32Exception exc = e as Win32Exception;
+                               if (exc != null) {
+                                       throw new SystemException (String.Format ("Error running {0}: {1}", vbnc.StartInfo.FileName,
+                                                                                       Win32Exception.W32ErrorMessage (exc.NativeErrorCode)));
+                               }
+                               throw;
+                       }
+
+                       try {
+                               vbnc_output = vbnc.StandardOutput.ReadToEnd ();
+                               vbnc.WaitForExit ();
+                       } finally {
+                               results.NativeCompilerReturnValue = vbnc.ExitCode;
+                               vbnc.Close ();
+                       }
+
+                       bool loadIt = true;
+                       if (results.NativeCompilerReturnValue == 1) {
+                               loadIt = false;
+                               vbnc_output_lines = vbnc_output.Split (Environment.NewLine.ToCharArray ());
+                               foreach (string error_line in vbnc_output_lines) {
+                                       CompilerError error = CreateErrorFromString (error_line);
+                                       if (null != error) {
+                                               results.Errors.Add (error);
+                                       }
+                               }
+                       }
+                       
+                       if ((loadIt == false && !results.Errors.HasErrors) // Failed, but no errors? Probably couldn't parse the compiler output correctly. 
+                           || (results.NativeCompilerReturnValue != 0 && results.NativeCompilerReturnValue != 1)) // Neither success (0), nor failure (1), so it crashed. 
+                       {
+                               // Show the entire output as one big error message.
+                               loadIt = false;
+                               CompilerError error = new CompilerError (string.Empty, 0, 0, "VBNC_CRASH", vbnc_output);
+                               results.Errors.Add (error);
+                       };
+
+                       if (loadIt) {
+                               if (options.GenerateInMemory) {
+                                       using (FileStream fs = File.OpenRead (options.OutputAssembly)) {
+                                               byte[] buffer = new byte[fs.Length];
+                                               fs.Read (buffer, 0, buffer.Length);
+                                               results.CompiledAssembly = Assembly.Load (buffer, null);
+                                               fs.Close ();
+                                       }
+                               } else {
+                                       results.CompiledAssembly = Assembly.LoadFrom (options.OutputAssembly);
+                                       results.PathToAssembly = options.OutputAssembly;
+                               }
+                       } else {
+                               results.CompiledAssembly = null;
+                       }
+
+                       return results;
+               }
+
+               private CompilerResults CompileFromDomBatch (CompilerParameters options, CodeCompileUnit[] ea)
+               {
+                       if (options == null) {
+                               throw new ArgumentNullException ("options");
+                       }
+
+                       if (ea == null) {
+                               throw new ArgumentNullException ("ea");
+                       }
+
+                       string[] fileNames = new string[ea.Length];
+                       StringCollection assemblies = options.ReferencedAssemblies;
+
+                       for (int i = 0; i < ea.Length; i++) {
+                               CodeCompileUnit compileUnit = ea[i];
+                               fileNames[i] = GetTempFileNameWithExtension (options.TempFiles, i + ".vb");
+                               FileStream f = new FileStream (fileNames[i], FileMode.OpenOrCreate);
+                               StreamWriter s = new StreamWriter (f);
+                               if (compileUnit.ReferencedAssemblies != null) {
+                                       foreach (string str in compileUnit.ReferencedAssemblies) {
+                                               if (!assemblies.Contains (str))
+                                                       assemblies.Add (str);
+                                       }
+                               }
+
+                               ((ICodeGenerator) this).GenerateCodeFromCompileUnit (compileUnit, s, new CodeGeneratorOptions ());
+                               s.Close ();
+                               f.Close ();
+                       }
+                       return CompileAssemblyFromFileBatch (options, fileNames);
+               }
+
+               private CompilerResults CompileFromSourceBatch (CompilerParameters options, string[] sources)
+               {
+                       if (options == null) {
+                               throw new ArgumentNullException ("options");
+                       }
+
+                       if (sources == null) {
+                               throw new ArgumentNullException ("sources");
+                       }
+
+                       string[] fileNames = new string[sources.Length];
+
+                       for (int i = 0; i < sources.Length; i++) {
+                               fileNames[i] = GetTempFileNameWithExtension (options.TempFiles, i + ".vb");
+                               FileStream f = new FileStream (fileNames[i], FileMode.OpenOrCreate);
+                               using (StreamWriter s = new StreamWriter (f)) {
+                                       s.Write (sources[i]);
+                                       s.Close ();
+                               }
+                               f.Close ();
+                       }
+                       return CompileFromFileBatch (options, fileNames);
+               }
+       }
+}
+