private void CacheCompileErrors(AssemblyBuilder assemblyBuilder, CompilerResults results) { System.Web.Compilation.BuildProvider provider = null; foreach (CompilerError error in results.Errors) { if (!error.IsWarning) { System.Web.Compilation.BuildProvider buildProviderFromLinePragma = assemblyBuilder.GetBuildProviderFromLinePragma(error.FileName); if (((buildProviderFromLinePragma != null) && (buildProviderFromLinePragma is BaseTemplateBuildProvider)) && (buildProviderFromLinePragma != provider)) { provider = buildProviderFromLinePragma; CompilerResults results2 = new CompilerResults(null); foreach (string str in results.Output) { results2.Output.Add(str); } results2.PathToAssembly = results.PathToAssembly; results2.NativeCompilerReturnValue = results.NativeCompilerReturnValue; results2.Errors.Add(error); HttpCompileException compileException = new HttpCompileException(results2, assemblyBuilder.GetGeneratedSourceFromBuildProvider(buildProviderFromLinePragma)); BuildResult result = new BuildResultCompileError(buildProviderFromLinePragma.VirtualPathObject, compileException); buildProviderFromLinePragma.SetBuildResultDependencies(result); BuildManager.CacheVPathBuildResult(buildProviderFromLinePragma.VirtualPathObject, result, this._utcStart); } } } }
// Cache the various compile errors found during batching private void CacheCompileErrors(AssemblyBuilder assemblyBuilder, CompilerResults results) { BuildProvider previous = null; // Go through all the compile errors foreach (CompilerError error in results.Errors) { // Skip warnings if (error.IsWarning) continue; // Try to map the error back to a BuildProvider. If we can't, skip the error. BuildProvider buildProvider = assemblyBuilder.GetBuildProviderFromLinePragma(error.FileName); if (buildProvider == null) continue; // Only cache the error for template controls. Otherwise, for file types like // asmx/ashx, it's too likely that two of them define the same class. if (!(buildProvider is BaseTemplateBuildProvider)) continue; // If the error is for the same page as the previous one, ignore it if (buildProvider == previous) continue; previous = buildProvider; // Create a new CompilerResults for this error CompilerResults newResults = new CompilerResults(null /*tempFiles*/); // Copy all the output to the new result. Note that this will include all the // error lines, not just the ones for this BuildProvider. But that's not a big deal, // and we can't easily filter the output here. foreach (string s in results.Output) newResults.Output.Add(s); // Copy various other fields to the new CompilerResults object newResults.PathToAssembly = results.PathToAssembly; newResults.NativeCompilerReturnValue = results.NativeCompilerReturnValue; // Add this error. It will be the only one in the CompilerResults object. newResults.Errors.Add(error); // Create a new HttpCompileException & BuildResultCompileError to wrap this error HttpCompileException e = new HttpCompileException(newResults, assemblyBuilder.GetGeneratedSourceFromBuildProvider(buildProvider)); BuildResult result = new BuildResultCompileError(buildProvider.VirtualPathObject, e); // Add the dependencies to the compile error build provider, so that // we will retry compilation when a dependency changes buildProvider.SetBuildResultDependencies(result); // Cache it BuildManager.CacheVPathBuildResult(buildProvider.VirtualPathObject, result, _utcStart); } }
private BuildResult CompileWebFile(VirtualPath virtualPath) { BuildResult result = null; string cacheKey = null; if (_topLevelFilesCompiledCompleted) { VirtualPath parentPath = virtualPath.Parent; // First, try to batch the directory if enabled if (IsBatchEnabledForDirectory(parentPath)) { BatchCompileWebDirectory(null, parentPath, true /*ignoreErrors*/); // If successful, it would have been cached to memory cacheKey = GetCacheKeyFromVirtualPath(virtualPath); result = _memoryCache.GetBuildResult(cacheKey); if (result == null && DelayLoadType.Enabled) { // We might not have cached the result in the memory cache // if we are trying to delay loading the assembly. result = GetBuildResultFromCache(cacheKey); } if (result != null) { // If what we found in the cache is a CompileError, rethrow the exception if (result is BuildResultCompileError) { throw ((BuildResultCompileError)result).CompileException; } return result; } } } DateTime utcStart = DateTime.UtcNow; // Name the assembly based on the virtual path, in order to get a recognizable name string outputAssemblyName = BuildManager.WebAssemblyNamePrefix + BuildManager.GenerateRandomAssemblyName( GetGeneratedAssemblyBaseName(virtualPath), false /*topLevel*/); BuildProvidersCompiler bpc = new BuildProvidersCompiler(virtualPath /*configPath*/, outputAssemblyName); // Create a BuildProvider based on the virtual path BuildProvider buildProvider = CreateBuildProvider(virtualPath, bpc.CompConfig, bpc.ReferencedAssemblies, true /*failIfUnknown*/); // Set the BuildProvider using a single item collection bpc.SetBuildProviders(new SingleObjectCollection(buildProvider)); // Compile it CompilerResults results; try { results = bpc.PerformBuild(); result = buildProvider.GetBuildResult(results); } catch (HttpCompileException e) { // If we're not supposed to cache the exception, just rethrow it if (e.DontCache) throw; result = new BuildResultCompileError(virtualPath, e); // Add the dependencies to the compile error build provider, so that // we will retry compilation when a dependency changes buildProvider.SetBuildResultDependencies(result); // Remember the virtualpath dependencies, so that we will correctly // invalidate buildresult when depdency changes. e.VirtualPathDependencies = buildProvider.VirtualPathDependencies; // Cache it for next time CacheVPathBuildResultInternal(virtualPath, result, utcStart); // Set the DontCache flag, so that the exception will not be incorrectly // cached again lower down the stack (VSWhidbey 128234) e.DontCache = true; throw; } if (result == null) return null; // Cache it for next time CacheVPathBuildResultInternal(virtualPath, result, utcStart); if (!_precompilingApp && BuildResultCompiledType.UsesDelayLoadType(result)) { // The result uses DelayLoadType, which should not get exposed. // If we are not performing precompilation, then we should // get the actual result from cache and return that instead. if (cacheKey == null) { cacheKey = GetCacheKeyFromVirtualPath(virtualPath); } result = BuildManager.GetBuildResultFromCache(cacheKey); } return result; }
// Cache the various compile errors found during batching private void CacheCompileErrors(AssemblyBuilder assemblyBuilder, CompilerResults results) { BuildProvider previous = null; // Go through all the compile errors foreach (CompilerError error in results.Errors) { // Skip warnings if (error.IsWarning) { continue; } // Try to map the error back to a BuildProvider. If we can't, skip the error. BuildProvider buildProvider = assemblyBuilder.GetBuildProviderFromLinePragma(error.FileName); if (buildProvider == null) { continue; } // Only cache the error for template controls. Otherwise, for file types like // asmx/ashx, it's too likely that two of them define the same class. if (!(buildProvider is BaseTemplateBuildProvider)) { continue; } // If the error is for the same page as the previous one, ignore it if (buildProvider == previous) { continue; } previous = buildProvider; // Create a new CompilerResults for this error CompilerResults newResults = new CompilerResults(null /*tempFiles*/); // Copy all the output to the new result. Note that this will include all the // error lines, not just the ones for this BuildProvider. But that's not a big deal, // and we can't easily filter the output here. foreach (string s in results.Output) { newResults.Output.Add(s); } // Copy various other fields to the new CompilerResults object newResults.PathToAssembly = results.PathToAssembly; newResults.NativeCompilerReturnValue = results.NativeCompilerReturnValue; // Add this error. It will be the only one in the CompilerResults object. newResults.Errors.Add(error); // Create a new HttpCompileException & BuildResultCompileError to wrap this error HttpCompileException e = new HttpCompileException(newResults, assemblyBuilder.GetGeneratedSourceFromBuildProvider(buildProvider)); BuildResult result = new BuildResultCompileError(buildProvider.VirtualPathObject, e); // Add the dependencies to the compile error build provider, so that // we will retry compilation when a dependency changes buildProvider.SetBuildResultDependencies(result); // Cache it BuildManager.CacheVPathBuildResult(buildProvider.VirtualPathObject, result, _utcStart); } }