private void ProcessBuildProviders() { CompilerType compilerType = null; BuildProvider firstLanguageBuildProvider = null; // First, delete all the existing satellite assemblies of the assembly // we're about to build (VSWhidbey 87022) (only if it has a fixed name) if (OutputAssemblyName != null) { Debug.Assert(!CbmGenerateOnlyMode); StandardDiskBuildResultCache.RemoveSatelliteAssemblies(OutputAssemblyName); } // List of BuildProvider's that don't ask for a specific language ArrayList languageFreeBuildProviders = null; foreach (BuildProvider buildProvider in _buildProviders) { // If it's an InternalBuildProvider, give it the assembly references early on buildProvider.SetReferencedAssemblies(_referencedAssemblies); // Instruct the internal build providers to continue processing for more parse errors. if (!BuildManager.ThrowOnFirstParseError) { InternalBuildProvider provider = buildProvider as InternalBuildProvider; if (provider != null) { provider.ThrowOnFirstParseError = false; } } // Get the language and culture CompilerType ctwp = BuildProvider.GetCompilerTypeFromBuildProvider(buildProvider); // Only look for a culture if we're supposed to (basically, in the resources directories) string cultureName = null; if (_supportLocalization) { cultureName = buildProvider.GetCultureName(); } // Is it asking for a specific language? if (ctwp != null) { // If it specifies a language, it can't also have a culture if (cultureName != null) { throw new HttpException(SR.GetString(SR.Both_culture_and_language, BuildProvider.GetDisplayName(buildProvider))); } // Do we already know the language we'll be using if (compilerType != null) { // If it's different from the current one, fail if (!ctwp.Equals(compilerType)) { throw new HttpException(SR.GetString(SR.Inconsistent_language, BuildProvider.GetDisplayName(buildProvider), BuildProvider.GetDisplayName(firstLanguageBuildProvider))); } } else { // Keep track of the build provider of error handling purpose firstLanguageBuildProvider = buildProvider; // Keep track of the language compilerType = ctwp; _assemblyBuilder = compilerType.CreateAssemblyBuilder( CompConfig, _referencedAssemblies, _generatedFilesDir, OutputAssemblyName); } } else { if (cultureName != null) { // Ignore the culture files in generate-only mode if (CbmGenerateOnlyMode) { continue; } if (_satelliteAssemblyBuilders == null) { _satelliteAssemblyBuilders = new Hashtable( StringComparer.OrdinalIgnoreCase); } // Check if we already have an assembly builder for this culture AssemblyBuilder satelliteAssemblyBuilder = (AssemblyBuilder)_satelliteAssemblyBuilders[cultureName]; // If not, create one and store it in the hashtable if (satelliteAssemblyBuilder == null) { satelliteAssemblyBuilder = CompilerType.GetDefaultAssemblyBuilder( CompConfig, _referencedAssemblies, _configPath, OutputAssemblyName); satelliteAssemblyBuilder.CultureName = cultureName; _satelliteAssemblyBuilders[cultureName] = satelliteAssemblyBuilder; } satelliteAssemblyBuilder.AddBuildProvider(buildProvider); continue; } if (_assemblyBuilder == null) { // If this provider doesn't need a specific language, and we don't know // the language yet, just keep track of it if (languageFreeBuildProviders == null) { languageFreeBuildProviders = new ArrayList(); } languageFreeBuildProviders.Add(buildProvider); continue; } } _assemblyBuilder.AddBuildProvider(buildProvider); } // If we didn't get an AssemblyBuilder, use a default if (_assemblyBuilder == null && languageFreeBuildProviders != null) { _assemblyBuilder = CompilerType.GetDefaultAssemblyBuilder( CompConfig, _referencedAssemblies, _configPath, _generatedFilesDir, OutputAssemblyName); } // Add all the language free providers (if any) to the AssemblyBuilder if (_assemblyBuilder != null && languageFreeBuildProviders != null) { foreach (BuildProvider languageFreeBuildProvider in languageFreeBuildProviders) { _assemblyBuilder.AddBuildProvider(languageFreeBuildProvider); } } }
private bool CompileNonDependentBuildProviders(ICollection buildProviders) { // Key: CompilerType, Value: AssemblyBuilder IDictionary assemblyBuilders = new Hashtable(); // List of InternalBuildProvider's that don't ask for a specific language ArrayList languageFreeBuildProviders = null; // AssemblyBuilder used for providers that don't need a specific language AssemblyBuilder defaultAssemblyBuilder = null; bool hasParserErrors = false; foreach (BuildProvider buildProvider in buildProviders) { if (IsBuildProviderSkipable(buildProvider)) { continue; } // Instruct the internal build providers to continue processing for more parse errors. if (!BuildManager.ThrowOnFirstParseError) { InternalBuildProvider provider = buildProvider as InternalBuildProvider; if (provider != null) { provider.ThrowOnFirstParseError = false; } } CompilerType compilerType = null; // Get the language try { compilerType = BuildProvider.GetCompilerTypeFromBuildProvider( buildProvider); } catch (HttpParseException ex) { // Ignore the error if we are in that mode. if (_ignoreProvidersWithErrors) { continue; } hasParserErrors = true; // Remember the first parse exception if (_firstException == null) { _firstException = ex; } if (_parserErrors == null) { _parserErrors = new ParserErrorCollection(); } _parserErrors.AddRange(ex.ParserErrors); continue; } catch { // Ignore the error if we are in that mode. if (_ignoreProvidersWithErrors) { continue; } throw; } AssemblyBuilder assemblyBuilder = defaultAssemblyBuilder; ICollection typeNames = buildProvider.GetGeneratedTypeNames(); // Is it asking for a specific language? if (compilerType == null) { // If this provider doesn't need a specific language, and we haven't yet created // a default builder that is capable of building this, just keep track of it if (defaultAssemblyBuilder == null || defaultAssemblyBuilder.IsBatchFull || defaultAssemblyBuilder.ContainsTypeNames(typeNames)) { if (languageFreeBuildProviders == null) { languageFreeBuildProviders = new ArrayList(); } languageFreeBuildProviders.Add(buildProvider); continue; } } else { // Check if we already have an assembly builder of the right type assemblyBuilder = (AssemblyBuilder)assemblyBuilders[compilerType]; } // Starts a new assemblyBuilder if the old one already contains another buildprovider // that uses the same type name if (assemblyBuilder == null || assemblyBuilder.IsBatchFull || assemblyBuilder.ContainsTypeNames(typeNames)) { // If the assemblyBuilder is full, compile it. if (assemblyBuilder != null) { CompileAssemblyBuilder(assemblyBuilder); } AssemblyBuilder newBuilder = compilerType.CreateAssemblyBuilder( _compConfig, _referencedAssemblies); assemblyBuilders[compilerType] = newBuilder; // Remember it as the default if we don't already have one, // or if the default is already full, switch the default to the new one. if (defaultAssemblyBuilder == null || defaultAssemblyBuilder == assemblyBuilder) { defaultAssemblyBuilder = newBuilder; } assemblyBuilder = newBuilder; } assemblyBuilder.AddTypeNames(typeNames); assemblyBuilder.AddBuildProvider(buildProvider); } // Don't try to compile providers, otherwise compile exceptions will be bubbled up, // and we lose the parse errors. if (hasParserErrors) { return(false); } // Handle all the left over language free providers if (languageFreeBuildProviders != null) { // Indicates whether the default assembly builder is not a language specific builder. bool newDefaultAssemblyBuilder = (defaultAssemblyBuilder == null); // Add language independent providers to the default assembly builder. foreach (BuildProvider languageFreeBuildProvider in languageFreeBuildProviders) { ICollection typeNames = languageFreeBuildProvider.GetGeneratedTypeNames(); // If we don't have a default language assembly builder, get one or // starts a new assemblyBuilder if the old one already contains another buildprovider // that uses the same type name if (defaultAssemblyBuilder == null || defaultAssemblyBuilder.IsBatchFull || defaultAssemblyBuilder.ContainsTypeNames(typeNames)) { // If the default assemblyBuilder is full, compile it. if (defaultAssemblyBuilder != null) { CompileAssemblyBuilder(defaultAssemblyBuilder); } defaultAssemblyBuilder = CompilerType.GetDefaultAssemblyBuilder( _compConfig, _referencedAssemblies, _vdir.VirtualPathObject /*configPath*/, null /*outputAssemblyName*/); // the default assembly builder needs to be compiled separately. newDefaultAssemblyBuilder = true; } defaultAssemblyBuilder.AddTypeNames(typeNames); defaultAssemblyBuilder.AddBuildProvider(languageFreeBuildProvider); } // Only compile the default assembly builder if it's not part of language specific // assembly builder (which will be compiled separately) if (newDefaultAssemblyBuilder) { // Compile the default assembly builder. CompileAssemblyBuilder(defaultAssemblyBuilder); } } CompileAssemblyBuilderParallel(assemblyBuilders.Values); return(true); }