BuildProvider.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ 4.0 / 4.0 / untmp / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / fx / src / xsp / System / Web / Compilation / BuildProvider.cs / 1599796 / BuildProvider.cs

                            //------------------------------------------------------------------------------ 
// 
//     Copyright (c) Microsoft Corporation.  All rights reserved.
// 
//----------------------------------------------------------------------------- 

 
 
/*********************************
 
Class hierarchy

BuildProvider
    ProfileBuildProvider 
    BaseResourcesBuildProvider
        ResXBuildProvider 
        ResourcesBuildProvider 
    XsdBuildProvider
    WsdlBuildProvider 
    InternalBuildProvider
        SourceFileBuildProvider
        SimpleHandlerBuildProvider
            WebServiceBuildProvider 
            WebHandlerBuildProvider
            ImageGeneratorBuildProvider 
        BaseTemplateBuildProvider 
            ApplicationBuildProvider
            TemplateControlBuildProvider 
                PageBuildProvider
                UserControlBuildProvider
                    MasterPageBuildProvider
            PageThemeBuildProvider 
                GlobalPageThemeBuildProvider
 
**********************************/ 

 
namespace System.Web.Compilation {

using System;
using System.Security.Permissions; 
using System.IO;
using System.Collections; 
using System.Collections.Generic; 
using System.Collections.Specialized;
using System.CodeDom; 
using System.CodeDom.Compiler;
using System.Web.Util;
using System.Web.UI;
using System.Web.Hosting; 

// Flags returned from BuildProvider.GetResultFlags 
[Flags] 
public enum BuildProviderResultFlags {
    Default = 0, 
    ShutdownAppDomainOnChange = 1,
}

 
/// 
///     
///       Base class for build providers that want to participate in a compilation. 
///       It should be used by build providers that process files based on a virtual path.
///     
/// 
public abstract class BuildProvider {

    private static Dictionary s_dynamicallyRegisteredProviders = new Dictionary(); 

    // 
    // Public interface 
    //
 

    /// 
    ///     Returns the CompilerType for the language that this build provider
    ///     needs to use, or null of it can use any language. 
    /// 
    public virtual CompilerType CodeCompilerType { get { return null; } } 
 

    ///  
    ///     Asks this build provider to generate any code that it needs, using the various
    ///     methods on the passed in BuildProvider.
    /// 
    public virtual void GenerateCode(AssemblyBuilder assemblyBuilder) {} 

 
    ///  
    ///     Returns the class generated by this buildprovider
    ///  
    public virtual Type GetGeneratedType(CompilerResults results) {
        return null;
    }
 

    ///  
    ///     Returns a string that the provider wants to have persisted with the compiled assembly. 
    /// 
    public virtual string GetCustomString(CompilerResults results) { 
        return null;
    }

 
    /// 
    ///     Returns some flags that drives the behavior of the persisted result. 
    ///  
    public virtual BuildProviderResultFlags GetResultFlags(CompilerResults results) {
        return BuildProviderResultFlags.Default; 
    }

    /// 
    ///     Give the BuildProvider a chance to look at the compile errors, and possibly tweak them 
    /// 
    public virtual void ProcessCompileErrors(CompilerResults results) { 
    } 

    ///  
    ///     Returns the list of files (virtual paths) that this provider depends on.
    ///     Those files need to be built before this BuildProvider.  The resulting assemblies
    ///     are added as references when compiling this BuildProvider.
    ///     This does not include things like server side includes, which don't directly 
    ///     produce a BuildResult.
    ///     This is used to implement batching by separating BuildProviders 
    ///  
    internal virtual ICollection GetBuildResultVirtualPathDependencies() { return null; }
 
    public virtual ICollection VirtualPathDependencies {
        get {
            // By default, return the virtual path as its only dependency
            return new SingleObjectCollection(VirtualPath); 
        }
    } 
 

    ///  
    ///     Returns the virtual path that this build provider handles
    /// 
    protected internal string VirtualPath {
        get { return System.Web.VirtualPath.GetVirtualPathString(_virtualPath); } 
    }
 
 
    /// 
    ///     Returns the virtual path object that this build provider handles 
    /// 
    internal VirtualPath VirtualPathObject {
        get { return _virtualPath; }
    } 

 
    ///  
    ///     Opens a stream for the virtual file handled by this provider
    ///  
    protected Stream OpenStream() {
        return OpenStream(VirtualPath);
    }
 

    ///  
    ///     Opens a stream for a virtual file 
    /// 
    protected Stream OpenStream(string virtualPath) { 
        return VirtualPathProvider.OpenFile(virtualPath);
    }

    internal /*protected*/ Stream OpenStream(VirtualPath virtualPath) { 
        return virtualPath.OpenFile();
    } 
 

    ///  
    ///     Opens a reader for the virtual file handled by this provider
    /// 
    protected TextReader OpenReader() {
        return OpenReader(VirtualPathObject); 
    }
 
 
    /// 
    ///     Opens a reader for a virtual file 
    /// 
    protected TextReader OpenReader(string virtualPath) {
        return OpenReader(System.Web.VirtualPath.Create(virtualPath));
    } 

    internal /*protected*/ TextReader OpenReader(VirtualPath virtualPath) { 
        Stream stream = OpenStream(virtualPath); 
        return Util.ReaderFromStream(stream, virtualPath);
    } 

    public static void RegisterBuildProvider(string extension, Type providerType) {
        if (String.IsNullOrEmpty(extension)) {
            throw ExceptionUtil.ParameterNullOrEmpty("extension"); 
        }
        if (providerType == null) { 
            throw new ArgumentNullException("providerType"); 
        }
        if (!typeof(BuildProvider).IsAssignableFrom(providerType)) { 
            //
            throw ExceptionUtil.ParameterInvalid("providerType");
        }
        BuildManager.ThrowIfPreAppStartNotRunning(); 

        // Last call wins. If a user wants to use a different provider they can always provide an 
        // override in the app's config. 
        s_dynamicallyRegisteredProviders[extension] = new CompilationBuildProviderInfo(providerType);
    } 

    internal static BuildProviderInfo GetBuildProviderInfo(System.Web.Configuration.CompilationSection config, string extension) {
        Debug.Assert(extension != null);
        var entry = config.BuildProviders[extension]; 
        if (entry != null) {
            return entry.BuildProviderInfo; 
        } 

        BuildProviderInfo info = null; 
        s_dynamicallyRegisteredProviders.TryGetValue(extension, out info);
        return info;
    }
 

    ///  
    ///     Returns a collection of assemblies that the build provider will be compiled with. 
    /// 
    protected ICollection ReferencedAssemblies { 
        get { return _referencedAssemblies; }
    }

 
    /// 
    ///     Returns the default CompilerType to be used for a specific language 
    ///  
    protected CompilerType GetDefaultCompilerTypeForLanguage(string language) {
        return CompilationUtil.GetCompilerInfoFromLanguage(VirtualPathObject, language); 
    }


    ///  
    ///     Returns the default CompilerType to be used for the default language
    ///  
    protected CompilerType GetDefaultCompilerType() { 
        return CompilationUtil.GetDefaultLanguageCompilerInfo(null /*compConfig*/, VirtualPathObject);
    } 


    //
    // Internal code 
    //
 
    #pragma warning disable 0649 
    internal SimpleBitVector32 flags;
    #pragma warning restore 0649 

    // const masks into the BitVector32
    internal const int isDependedOn                 = 0x00000001;
    internal const int noBuildResult                = 0x00000002; 
    internal const int ignoreParseErrors            = 0x00000004;
    internal const int ignoreControlProperties      = 0x00000008; 
    internal const int dontThrowOnFirstParseError   = 0x00000010; 
    internal const int contributedCode              = 0x00000020;
 
    private VirtualPath _virtualPath;

    private ICollection _referencedAssemblies;
 
    private BuildProviderSet _buildProviderDependencies;
    internal BuildProviderSet BuildProviderDependencies { 
        get { 
            return _buildProviderDependencies;
        } 
    }

    // Is any other BuildProvider depending on this BuildProvider
    internal bool IsDependedOn { get { return flags[isDependedOn]; } } 

    internal void SetNoBuildResult() { 
        flags[noBuildResult] = true; 
    }
 
    // Remember that this BuildProvider has contributed to the compilation
    internal void SetContributedCode() {
        flags[contributedCode] = true;
    } 

    internal void SetVirtualPath(VirtualPath virtualPath) { 
        _virtualPath = virtualPath; 
    }
 
    internal void SetReferencedAssemblies(ICollection referencedAssemblies) {
        _referencedAssemblies = referencedAssemblies;
    }
 
    internal void AddBuildProviderDependency(BuildProvider dependentBuildProvider) {
        if (_buildProviderDependencies == null) 
            _buildProviderDependencies = new BuildProviderSet(); 

        _buildProviderDependencies.Add(dependentBuildProvider); 

        dependentBuildProvider.flags[isDependedOn] = true;
    }
 
    /*
     * Return the culture name for this provider (e.g. "fr" or "fr-fr"). 
     * If no culture applies, return null. 
     */
    internal string GetCultureName() { 
        return Util.GetCultureName(VirtualPath);
    }

    internal BuildResult GetBuildResult(CompilerResults results) { 

        BuildResult result = CreateBuildResult(results); 
        if (result == null) 
            return null;
 
        result.VirtualPath = VirtualPathObject;
        SetBuildResultDependencies(result);

        return result; 
    }
 
    internal virtual BuildResult CreateBuildResult(CompilerResults results) { 

        // If the build provider is not supposed to have a build result, just return 
        if (flags[noBuildResult])
            return null;

        // Access the CompiledAssembly property to make sure the assembly gets loaded 
        // Otherwise, the user code in GetGeneratedType() will fail to load it in medium trust since
        // they don't have access to the codegen folder 
        if (!BuildManagerHost.InClientBuildManager && results != null) { 
            // The ClientBuildManager runs in full trust, so we skip this statement
            // to avoid unnecessary loading of the assembly. 
            var assembly = results.CompiledAssembly;
        }

        // Ask the build provider if it wants to persist a Type 
        Type type = GetGeneratedType(results);
 
        BuildResult result; 

        if (type != null) { 
            // Create a BuildResult for it
            BuildResultCompiledType resultCompiledType = CreateBuildResult(type);

            if (!resultCompiledType.IsDelayLoadType) { 
                // If the returned type doesn't come from the generated assembly, set a flag
                if (results == null || type.Assembly != results.CompiledAssembly) 
                    resultCompiledType.UsesExistingAssembly = true; 
            }
 
            result = resultCompiledType;
        }
        else {
            // Ask the build provider if it instead wants to persist a custom string 
            string customString = GetCustomString(results);
 
            // If it does, persist it 
            if (customString != null) {
                // Only preserve an assembly if the BuildProvider has actually contributed code 
                // to the compilation.
                result = new BuildResultCustomString(
                    flags[contributedCode] ? results.CompiledAssembly : null,
                    customString); 
            }
            else { 
                // Nothing was built: nothing to persist 
                if (results == null)
                    return null; 

                // Otherwise, just persist the assembly, if any
                result = new BuildResultCompiledAssembly(results.CompiledAssembly);
            } 
        }
 
        // Ask the provider it it wants to set some flags on the result 
        int resultFlags = (int) GetResultFlags(results);
        if (resultFlags != 0) { 
            // Make sure only the lower bits are set
            Debug.Assert((resultFlags & 0xFFFF0000) == 0);
            resultFlags &= 0x0000FFFF;
 
            result.Flags |= resultFlags;
        } 
 
        return result;
    } 

    internal virtual BuildResultCompiledType CreateBuildResult(Type t) {
        return new BuildResultCompiledType(t);
    } 

    internal void SetBuildResultDependencies(BuildResult result) { 
 
        result.AddVirtualPathDependencies(VirtualPathDependencies);
    } 


    //
    // Helper methods 
    //
 
    internal static CompilerType GetCompilerTypeFromBuildProvider( 
        BuildProvider buildProvider) {
 
        HttpContext context = null;
        if (EtwTrace.IsTraceEnabled(EtwTraceLevel.Verbose, EtwTraceFlags.Infrastructure) && (context = HttpContext.Current) != null)
            EtwTrace.Trace(EtwTraceType.ETW_TYPE_PARSE_ENTER, context.WorkerRequest);
 
        try {
            CompilerType compilerType = buildProvider.CodeCompilerType; 
            if (compilerType != null) { 
                CompilationUtil.CheckCompilerOptionsAllowed(compilerType.CompilerParameters.CompilerOptions,
                    false /*config*/, null, 0); 
            }
            return compilerType;
        }
        finally { 
            if (EtwTrace.IsTraceEnabled(EtwTraceLevel.Verbose, EtwTraceFlags.Infrastructure) && context != null)
                EtwTrace.Trace(EtwTraceType.ETW_TYPE_PARSE_LEAVE, context.WorkerRequest); 
        } 
    }
 
    //
    // Return a 'friendly' string that identifies the build provider
    //
    internal static string GetDisplayName(BuildProvider buildProvider) { 

        // If it has a VirtualPath, use it 
        if (buildProvider.VirtualPath != null) { 
            return buildProvider.VirtualPath;
        } 

        // Otherwise, the best we can do is the type name
        return buildProvider.GetType().Name;
    } 

    internal virtual ICollection GetGeneratedTypeNames() { 
        return null; 
    }
 
    #region Methods from InternalBuildProvider

    // Protected internal methods: IgnoreParseErrors and GetCodeCompileUnit
 
    // When this is set, we ignore parse errors and keep on processing the page as
    // well as possible.  This is used for the Venus CBM scenario 
    internal virtual bool IgnoreParseErrors { 
        get { return flags[ignoreParseErrors]; }
        set { flags[ignoreParseErrors] = value; } 
    }

    // This is used in CBM to instruct the control builders to skip control properties
    internal bool IgnoreControlProperties { 
        get { return flags[ignoreControlProperties]; }
        set { flags[ignoreControlProperties] = value; } 
    } 

    // Indicates whether the parser should continue processing for more errors. 
    // This is used in both CBM and aspnet_compiler tool.
    internal bool ThrowOnFirstParseError {
        get { return !flags[dontThrowOnFirstParseError]; }
        set { flags[dontThrowOnFirstParseError] = !value; } 
    }
 
    // This is used in the CBM scenario only 
    internal virtual IAssemblyDependencyParser AssemblyDependencyParser {
        get { return null; } 
    }

    // This is used in the CBM scenario only
    ///  
    /// Returns the CodeCompileUnit and sets the associated dictionary containing the line pragmas.
    ///  
    protected internal virtual CodeCompileUnit GetCodeCompileUnit(out IDictionary linePragmasTable) { 

        // Default implementation with code at line 1 

        string sourceString = Util.StringFromVirtualPath(VirtualPathObject);
        CodeSnippetCompileUnit snippetCompileUnit = new CodeSnippetCompileUnit(sourceString);
 
        LinePragmaCodeInfo codeInfo = new LinePragmaCodeInfo(1 /* startLine */, 1 /* startColumn */, 1 /* startGeneratedColumn */, -1 /* codeLength */, false /* isCodeNuggest */);
        linePragmasTable = new Hashtable(); 
        linePragmasTable[1] = codeInfo; 

        return snippetCompileUnit; 
    }

    internal virtual ICollection GetCompileWithDependencies() { return null; }
 
    #endregion Methods from InternalBuildProvider
 
    private class CompilationBuildProviderInfo : BuildProviderInfo { 

        private readonly Type _type; 

        public CompilationBuildProviderInfo(Type type) {
            Debug.Assert(type != null);
            _type = type; 
        }
 
        internal override Type Type { 
            get {
                return _type; 
            }
        }
    }
} 

// The InternalBuildProvider class is still retained to internally distinguish between 
// buildProviders that actually implement the required methods and those that don't, and 
// also to minimize code change where possible.
internal abstract class InternalBuildProvider: BuildProvider { 

}

internal abstract class BuildProviderInfo { 
    // AppliesTo value from the BuildProviderAppliesToAttribute
    private BuildProviderAppliesTo _appliesTo; 
 
    internal abstract Type Type { get; }
 
    internal BuildProviderAppliesTo AppliesTo {
        get {
            if (_appliesTo != 0)
                return _appliesTo; 

            // Check whether the control builder's class exposes an AppliesTo attribute 
            object[] attrs = Type.GetCustomAttributes( 
                typeof(BuildProviderAppliesToAttribute), /*inherit*/ true);
 
            if ((attrs != null) && (attrs.Length > 0)) {
                Debug.Assert(attrs[0] is BuildProviderAppliesToAttribute);
                _appliesTo = ((BuildProviderAppliesToAttribute)attrs[0]).AppliesTo;
            } 
            else {
                // Default to applying to All 
                _appliesTo = BuildProviderAppliesTo.All; 
            }
 
            return _appliesTo;
        }
    }
} 

} 

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
                        

Link Menu

Network programming in C#, Network Programming in VB.NET, Network Programming in .NET
This book is available now!
Buy at Amazon US or
Buy at Amazon UK