X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mcs%2Fclass%2FSystem.Web%2FSystem.Web.Compilation%2FAssemblyBuilder.cs;h=fda3ffdeb015480997bcb93a37b569b87d9ffc99;hb=de3974edad92ee569938f465b9167a841f0da297;hp=f84376b767f42b6e6a836cbf175fd9dd1092a67a;hpb=948dbf8d4581ac17f5420cc4f7dc375e3c502576;p=mono.git diff --git a/mcs/class/System.Web/System.Web.Compilation/AssemblyBuilder.cs b/mcs/class/System.Web/System.Web.Compilation/AssemblyBuilder.cs index f84376b767f..fda3ffdeb01 100644 --- a/mcs/class/System.Web/System.Web.Compilation/AssemblyBuilder.cs +++ b/mcs/class/System.Web/System.Web.Compilation/AssemblyBuilder.cs @@ -49,27 +49,33 @@ namespace System.Web.Compilation { CodeDomProvider provider; List units; List source_files; + List referenced_assemblies; Dictionary resource_files; TempFileCollection temp_files; - string virtual_path; //TODO: there should be a Compile () method here which is where all the compilation exceptions are thrown from. + + internal AssemblyBuilder (CodeDomProvider provider) + : this (null, provider) + {} internal AssemblyBuilder (string virtualPath, CodeDomProvider provider) { this.provider = provider; - this.virtual_path = virtualPath; units = new List (); - units.Add (new CodeCompileUnit ()); temp_files = new TempFileCollection (); + referenced_assemblies = new List (); CompilationSection section; - section = (CompilationSection) WebConfigurationManager.GetSection ("system.web/compilation", virtualPath); + if (virtualPath != null) + section = (CompilationSection) WebConfigurationManager.GetSection ("system.web/compilation", virtualPath); + else + section = (CompilationSection) WebConfigurationManager.GetSection ("system.web/compilation"); string tempdir = section.TempDirectory; if (tempdir == null || tempdir == "") tempdir = AppDomain.CurrentDomain.SetupInformation.DynamicBase; temp_files = new TempFileCollection (tempdir, KeepFiles); } - + internal TempFileCollection TempFiles { get { return temp_files; } } @@ -102,13 +108,16 @@ namespace System.Web.Compilation { if (a == null) throw new ArgumentNullException ("a"); - StringCollection coll = units [units.Count - 1].ReferencedAssemblies; - string location = a.Location; - if (coll.IndexOf (location) == -1) - coll.Add (location); + referenced_assemblies.Add (a.Location); } - [MonoTODO ("Do something with the buildProvider argument")] + internal void AddCodeCompileUnit (CodeCompileUnit compileUnit) + { + if (compileUnit == null) + throw new ArgumentNullException ("compileUnit"); + units.Add (compileUnit); + } + public void AddCodeCompileUnit (BuildProvider buildProvider, CodeCompileUnit compileUnit) { if (buildProvider == null) @@ -120,18 +129,30 @@ namespace System.Web.Compilation { units.Add (compileUnit); } - [MonoTODO ("Anything to do with the buildProvider argument?")] public TextWriter CreateCodeFile (BuildProvider buildProvider) { if (buildProvider == null) throw new ArgumentNullException ("buildProvider"); - string filename = temp_files.AddExtension ("temp", true); + // Generate a file name with the correct source language extension + string filename = GetTempFilePhysicalPath (provider.FileExtension); SourceFiles.Add (filename); return new StreamWriter (File.OpenWrite (filename), WebEncoding.FileEncoding); } - [MonoTODO ("Anything to do with the buildProvider argument?")] + internal void AddCodeFile (string path) + { + if (path == null || path.Length == 0) + return; + string extension = Path.GetExtension (path); + if (extension == null || extension.Length == 0) + return; // maybe better to throw an exception here? + extension = extension.Substring (1); + string filename = GetTempFilePhysicalPath (extension); + File.Copy (path, filename, true); + SourceFiles.Add (filename); + } + public Stream CreateEmbeddedResource (BuildProvider buildProvider, string name) { if (buildProvider == null) @@ -140,13 +161,13 @@ namespace System.Web.Compilation { if (name == null || name == "") throw new ArgumentNullException ("name"); - string filename = temp_files.AddExtension ("resource", true); + string filename = GetTempFilePhysicalPath ("resource"); Stream stream = File.OpenWrite (filename); ResourceFiles [name] = filename; return stream; } - [MonoTODO] + [MonoTODO ("Not implemented, does nothing")] public void GenerateTypeFactory (string typeName) { // Do nothing by now. @@ -156,23 +177,69 @@ namespace System.Web.Compilation { { if (extension == null) throw new ArgumentNullException ("extension"); - - return temp_files.AddExtension (extension, true); + + return temp_files.AddExtension (String.Format ("_{0}.{1}", temp_files.Count, extension), true); } public CodeDomProvider CodeDomProvider { get { return provider; } } + internal CompilerResults BuildAssembly (CompilerParameters options) + { + return BuildAssembly (null, options); + } + internal CompilerResults BuildAssembly (string virtualPath, CompilerParameters options) { + if (options == null) + throw new ArgumentNullException ("options"); + CompilerResults results; CodeCompileUnit [] units = GetUnitsAsArray (); - results = provider.CompileAssemblyFromDom (options, units); - // FIXME: generate the code and display it - if (results.NativeCompilerReturnValue != 0) - throw new CompilationException (virtualPath, results.Errors, ""); + // Since we may have some source files and some code + // units, we generate code from all of them and then + // compile the assembly from the set of temporary source + // files. This also facilates possible debugging for the + // end user, since they get the code beforehand. + List files = SourceFiles; + string filename; + StreamWriter sw = null; + foreach (CodeCompileUnit unit in units) { + filename = GetTempFilePhysicalPath (provider.FileExtension); + try { + sw = new StreamWriter (File.OpenWrite (filename), WebEncoding.FileEncoding); + provider.GenerateCodeFromCompileUnit (unit, sw, null); + files.Add (filename); + } catch { + throw; + } finally { + if (sw != null) { + sw.Flush (); + sw.Close (); + } + } + } + Dictionary resources = ResourceFiles; + foreach (KeyValuePair de in resources) + options.EmbeddedResources.Add (de.Value); + foreach (string refasm in referenced_assemblies) + options.ReferencedAssemblies.Add (refasm); + + results = provider.CompileAssemblyFromFile (options, files.ToArray ()); + + if (results.NativeCompilerReturnValue != 0) { + string fileText = null; + try { + using (StreamReader sr = File.OpenText (results.Errors [0].FileName)) { + fileText = sr.ReadToEnd (); + } + } catch (Exception) {} + + throw new CompilationException (virtualPath, results.Errors, fileText); + } + Assembly assembly = results.CompiledAssembly; if (assembly == null) { if (!File.Exists (options.OutputAssembly)) { @@ -181,10 +248,16 @@ namespace System.Web.Compilation { "No assembly returned after compilation!?"); } - results.CompiledAssembly = Assembly.LoadFrom (options.OutputAssembly); + try { + results.CompiledAssembly = Assembly.LoadFrom (options.OutputAssembly); + } catch (Exception ex) { + results.TempFiles.Delete (); + throw new HttpException ("Unable to load compiled assembly", ex); + } } - results.TempFiles.Delete (); + if (!KeepFiles) + results.TempFiles.Delete (); return results; } }