static void GenerateAssembly (AssemblyBuilder abuilder, BuildProviderGroup group, VirtualPath vp, bool debug) { IDictionary <string, bool> deps; BuildManagerCacheItem bmci; string bvp, vpabsolute = vp.Absolute; StringBuilder sb; string newline; int failedCount = 0; if (debug) { newline = Environment.NewLine; sb = new StringBuilder ("Code generation for certain virtual paths in a batch failed. Those files have been removed from the batch." + newline); sb.Append ("Since you're running in debug mode, here's some more information about the error:" + newline); } else { newline = null; sb = null; } List <BuildProvider> failedBuildProviders = null; StringComparison stringComparison = RuntimeHelpers.StringComparison; foreach (BuildProvider bp in group) { bvp = bp.VirtualPath; if (HasCachedItemNoLock (bvp)) continue; try { bp.GenerateCode (abuilder); } catch (Exception ex) { if (String.Compare (bvp, vpabsolute, stringComparison) == 0) { if (ex is CompilationException || ex is ParseException) throw; throw new HttpException ("Code generation failed.", ex); } if (failedBuildProviders == null) failedBuildProviders = new List <BuildProvider> (); failedBuildProviders.Add (bp); failedCount++; if (sb != null) { if (failedCount > 1) sb.Append (newline); sb.AppendFormat ("Failed file virtual path: {0}; Exception: {1}{2}{1}", bp.VirtualPath, newline, ex); } continue; } deps = bp.ExtractDependencies (); if (deps != null) { foreach (var dep in deps) { bmci = GetCachedItemNoLock (dep.Key); if (bmci == null || bmci.BuiltAssembly == null) continue; abuilder.AddAssemblyReference (bmci.BuiltAssembly); } } } if (sb != null && failedCount > 0) ShowDebugModeMessage (sb.ToString ()); if (failedBuildProviders != null) { foreach (BuildProvider bp in failedBuildProviders) group.Remove (bp); } foreach (Assembly asm in referencedAssemblies) { if (asm == null) continue; abuilder.AddAssemblyReference (asm); } CompilerResults results = abuilder.BuildAssembly (vp); // No results is not an error - it is possible that the assembly builder contained only .asmx and // .ashx files which had no body, just the directive. In such case, no code unit or code file is added // to the assembly builder and, in effect, no assembly is produced but there are STILL types that need // to be added to the cache. Assembly compiledAssembly = results != null ? results.CompiledAssembly : null; try { buildCacheLock.EnterWriteLock (); if (compiledAssembly != null) referencedAssemblies.Add (compiledAssembly); foreach (BuildProvider bp in group) { if (HasCachedItemNoLock (bp.VirtualPath)) continue; StoreInCache (bp, compiledAssembly, results); } } finally { buildCacheLock.ExitWriteLock (); } }
static void RemoveFailedAssemblies (string requestedVirtualPath, CompilationException ex, AssemblyBuilder abuilder, BuildProviderGroup group, CompilerResults results, bool debug) { StringBuilder sb; string newline; if (debug) { newline = Environment.NewLine; sb = new StringBuilder ("Compilation of certain files in a batch failed. Another attempt to compile the batch will be made." + newline); sb.Append ("Since you're running in debug mode, here's some more information about the error:" + newline); } else { newline = null; sb = null; } var failedBuildProviders = new List <BuildProvider> (); BuildProvider bp; HttpContext ctx = HttpContext.Current; HttpRequest req = ctx != null ? ctx.Request : null; bool rethrow = false; foreach (CompilerError error in results.Errors) { if (error.IsWarning) continue; bp = abuilder.GetBuildProviderForPhysicalFilePath (error.FileName); if (bp == null) { bp = FindBuildProviderForPhysicalPath (error.FileName, group, req); if (bp == null) continue; } if (String.Compare (bp.VirtualPath, requestedVirtualPath, StringComparison.Ordinal) == 0) rethrow = true; if (!failedBuildProviders.Contains (bp)) { failedBuildProviders.Add (bp); if (sb != null) sb.AppendFormat ("\t{0}{1}", bp.VirtualPath, newline); } if (sb != null) sb.AppendFormat ("\t\t{0}{1}", error, newline); } foreach (BuildProvider fbp in failedBuildProviders) group.Remove (fbp); if (sb != null) { sb.AppendFormat ("{0}The following exception has been thrown for the file(s) listed above:{0}{1}", newline, ex.ToString ()); ShowDebugModeMessage (sb.ToString ()); sb = null; } if (rethrow) throw new HttpException ("Compilation failed.", ex); }