rendered paste bodyIndex: IgnoreFileBuildProvider.cs
===================================================================
--- IgnoreFileBuildProvider.cs (revision 67781)
+++ IgnoreFileBuildProvider.cs (working copy)
@@ -31,7 +31,7 @@
#if NET_2_0
namespace System.Web.Compilation {
-
+ [BuildProviderAppliesTo (BuildProviderAppliesTo.All)]
class IgnoreFileBuildProvider : BuildProvider
{
public override void GenerateCode (AssemblyBuilder assemblyBuilder)
Index: WebServiceBuildProvider.cs
===================================================================
--- WebServiceBuildProvider.cs (revision 67781)
+++ WebServiceBuildProvider.cs (working copy)
@@ -39,7 +39,7 @@
using System.Web.UI;
namespace System.Web.Compilation {
-
+ [BuildProviderAppliesTo (BuildProviderAppliesTo.Web)]
sealed class WebServiceBuildProvider : BuildProvider {
WebServiceCompiler wscompiler;
CompilerType compiler_type;
Index: PageBuildProvider.cs
===================================================================
--- PageBuildProvider.cs (revision 67781)
+++ PageBuildProvider.cs (working copy)
@@ -40,6 +40,7 @@
namespace System.Web.Compilation {
+ [BuildProviderAppliesTo (BuildProviderAppliesTo.Web)]
sealed class PageBuildProvider : BuildProvider {
PageCompiler pcompiler;
CompilerType compiler_type;
Index: UserControlBuildProvider.cs
===================================================================
--- UserControlBuildProvider.cs (revision 67781)
+++ UserControlBuildProvider.cs (working copy)
@@ -39,7 +39,7 @@
using System.Web.UI;
namespace System.Web.Compilation {
-
+ [BuildProviderAppliesTo (BuildProviderAppliesTo.Web)]
sealed class UserControlBuildProvider : BuildProvider {
UserControlCompiler uccompiler;
CompilerType compiler_type;
Index: AssemblyBuilder.cs
===================================================================
--- AssemblyBuilder.cs (revision 67781)
+++ AssemblyBuilder.cs (working copy)
@@ -49,27 +49,35 @@
CodeDomProvider provider;
List <CodeCompileUnit> units;
List <string> source_files;
+ List <string> referenced_assemblies;
Dictionary <string, string> 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 <CodeCompileUnit> ();
- units.Add (new CodeCompileUnit ());
temp_files = new TempFileCollection ();
+ referenced_assemblies = new List <string> ();
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; }
}
@@ -101,14 +109,10 @@
{
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")]
public void AddCodeCompileUnit (BuildProvider buildProvider, CodeCompileUnit compileUnit)
{
if (buildProvider == null)
@@ -120,18 +124,30 @@
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,7 +156,7 @@
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;
@@ -156,19 +172,59 @@
{
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);
+
+ // 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 <string> 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 <string, string> resources = ResourceFiles;
+ foreach (KeyValuePair <string, string> de in resources)
+ options.EmbeddedResources.Add (de.Value);
+ foreach (string refasm in referenced_assemblies)
+ options.ReferencedAssemblies.Add (refasm);
+
+ results = provider.CompileAssemblyFromFile (options, files.ToArray ());
+
// FIXME: generate the code and display it
if (results.NativeCompilerReturnValue != 0)
throw new CompilationException (virtualPath, results.Errors, "");
@@ -184,7 +240,8 @@
results.CompiledAssembly = Assembly.LoadFrom (options.OutputAssembly);
}
- results.TempFiles.Delete ();
+ if (!KeepFiles)
+ results.TempFiles.Delete ();
return results;
}
}
Index: WebHandlerBuildProvider.cs
===================================================================
--- WebHandlerBuildProvider.cs (revision 67781)
+++ WebHandlerBuildProvider.cs (working copy)
@@ -39,7 +39,7 @@
using System.Web.UI;
namespace System.Web.Compilation {
-
+ [BuildProviderAppliesTo (BuildProviderAppliesTo.Web)]
sealed class WebHandlerBuildProvider : BuildProvider {
WebServiceCompiler wscompiler;
CompilerType compiler_type;
Index: AppCodeCompiler.cs
===================================================================
--- AppCodeCompiler.cs (revision 67781)
+++ AppCodeCompiler.cs (working copy)
@@ -130,30 +130,102 @@
}
CodeDomProvider provider = null;
- // First the files in the language we are aware of
- if (compilerInfo != null) {
+ if (compilerInfo == null) {
+ CompilationSection config = WebConfigurationManager.GetSection ("system.web/compilation") as CompilationSe
ction;
+ if (config == null || !CodeDomProvider.IsDefinedLanguage (config.DefaultLanguage))
+ throw new HttpException ("Failed to retrieve default source language");
+ compilerInfo = CodeDomProvider.GetCompilerInfo (config.DefaultLanguage);
+ if (compilerInfo == null || !compilerInfo.IsCodeDomProviderTypeValid)
+ throw new HttpException ("Internal error while initializing application");
provider = compilerInfo.CreateProvider ();
if (provider == null)
- throw new HttpException ("Unable to create a compiler for App_Code contents");
+ throw new HttpException ("A code provider error occurred while initializing application.");
+ }
+
- CompilerParameters parameters = compilerInfo.CreateDefaultCompilerParameters ();
- int num = rnd.Next () + 1;
+ //
+ //TODO: do not compile the known files below, add them to the AssemblyBuilder instead (using SourceFiles) and
+ //then process the unknown files with BuildProviders. After all the source files are added, use
+ //AssemblyBuilder.BuildAssembly to generate the actual assembly.
+ provider = compilerInfo.CreateProvider ();
+ if (provider == null)
+ throw new HttpException ("A code provider error occurred while initializing application.");
+
+ AssemblyBuilder abuilder = new AssemblyBuilder (provider);
+ foreach (string file in knownfiles)
+ abuilder.AddCodeFile (file);
+
+ BuildProvider bprovider;
+ CompilationSection compilationSection = WebConfigurationManager.GetSection ("system.web/compilation") as CompilationSection;
+ if (compilationSection != null) {
+ BuildProviderCollection buildProviders = compilationSection.BuildProviders;
- string assemblyName = Path.Combine (
- AppDomain.CurrentDomain.SetupInformation.DynamicBase,
- String.Format ("{0}.{1}.dll", name, num.ToString ("x")));
- parameters.OutputAssembly = assemblyName;
- CompilerResults results = provider.CompileAssemblyFromFile (parameters, knownfiles.ToArray ());
- if (results.Errors.Count == 0) {
- BuildManager.CodeAssemblies.Add (results.PathToAssembly);
- BuildManager.TopLevelAssemblies.Add (results.CompiledAssembly);
- } else {
- if (HttpContext.Current.IsCustomErrorEnabled)
- throw new HttpException ("An error occurred while initializing application.");
- throw new CompilationException (null, results.Errors, null);
+ foreach (string file in unknownfiles) {
+ bprovider = GetBuildProviderFor (file, buildProviders);
+ if (bprovider == null)
+ continue;
+ bprovider.GenerateCode (abuilder);
}
}
+
+ int num = rnd.Next () + 1;
+ string assemblyName = Path.Combine (
+ AppDomain.CurrentDomain.SetupInformation.DynamicBase,
+ String.Format ("{0}.{1}.dll", name, num.ToString ("x")));
+ CompilerParameters parameters = compilerInfo.CreateDefaultCompilerParameters ();
+ parameters.OutputAssembly = assemblyName;
+ CompilerResults results = abuilder.BuildAssembly (parameters);
+ if (results.Errors.Count == 0) {
+ BuildManager.CodeAssemblies.Add (results.PathToAssembly);
+ BuildManager.TopLevelAssemblies.Add (results.CompiledAssembly);
+ } else {
+ if (HttpContext.Current.IsCustomErrorEnabled)
+ throw new HttpException ("An error occurred while initializing application.");
+ throw new CompilationException (null, results.Errors, null);
+ }
}
+
+ private BuildProvider GetBuildProviderFor (string file, BuildProviderCollection buildProviders)
+ {
+ if (file == null || file.Length == 0 || buildProviders == null || buildProviders.Count == 0)
+ return null;
+
+ foreach (BuildProvider bp in buildProviders)
+ if (IsCorrectBuilderType (bp))
+ return bp;
+
+ return null;
+ }
+
+ private bool IsCorrectBuilderType (BuildProvider bp)
+ {
+ if (bp == null)
+ return false;
+ Type type;
+ object[] attrs;
+
+ type = bp.GetType ();
+ attrs = type.GetCustomAttributes (true);
+ if (attrs == null)
+ return false;
+
+ BuildProviderAppliesToAttribute bpAppliesTo;
+ bool attributeFound = false;
+ foreach (object attr in attrs) {
+ bpAppliesTo = attr as BuildProviderAppliesToAttribute;
+ if (bpAppliesTo == null)
+ continue;
+ attributeFound = true;
+ if ((bpAppliesTo.AppliesTo & BuildProviderAppliesTo.All) == BuildProviderAppliesTo.All ||
+ (bpAppliesTo.AppliesTo & BuildProviderAppliesTo.Code) == BuildProviderAppliesTo.Code)
+ return true;
+ }
+
+ if (attributeFound)
+ return false;
+ return true;
+ }
+
}
internal class AppCodeCompiler