BaseCodeDomTreeGenerator.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 / BaseCodeDomTreeGenerator.cs / 1503810 / BaseCodeDomTreeGenerator.cs

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

/********************************************** 
 
Class hierarchy:
 
BaseCodeDomTreeGenerator
    BaseTemplateCodeDomTreeGenerator
        TemplateControlCodeDomTreeGenerator
            PageCodeDomTreeGenerator 
            UserControlCodeDomTreeGenerator
        PageThemeCodeDomTreeGenerator 
    ApplicationFileCodeDomTreeGenerator 
***********************************************/
 


namespace System.Web.Compilation {
 
using System.Text;
using System.Runtime.Serialization.Formatters; 
using System.ComponentModel; 
using System;
using System.Collections; 
using System.Collections.Specialized;
using System.Reflection;
using System.IO;
using Microsoft.Win32; 
using System.Security.Cryptography;
using System.Web.Caching; 
using System.Web.Util; 
using System.Web.UI;
using System.Web.SessionState; 
using System.CodeDom;
using System.CodeDom.Compiler;
using Util = System.Web.UI.Util;
using System.Web.Hosting; 
using System.Web.Profile;
using System.Web.Configuration; 
using System.Globalization; 

 
internal abstract class BaseCodeDomTreeGenerator {

    protected CodeDomProvider _codeDomProvider;
    protected CodeCompileUnit _codeCompileUnit; 
    private CodeNamespace _sourceDataNamespace;
    protected CodeTypeDeclaration _sourceDataClass; 
    protected CodeTypeDeclaration _intermediateClass; 
    private CompilerParameters _compilParams;
    protected StringResourceBuilder _stringResourceBuilder; 
    protected bool _usingVJSCompiler;
    private static IDictionary _generatedColumnOffsetDictionary;

    private VirtualPath _virtualPath; 

    // The constructors 
    protected CodeConstructor _ctor; 

    protected CodeTypeReferenceExpression _classTypeExpr; 

    internal const string defaultNamespace = "ASP";

    // Used for things that we don't want the user to see 
    internal const string internalAspNamespace = "__ASP";
 
    private const string initializedFieldName = "__initialized"; 

    private const string _dummyVariable = "__dummyVar"; 
    private const int _defaultColumnOffset = 4;

    private TemplateParser _parser;
    TemplateParser Parser { get { return _parser; } } 

    // We generate different code for the designer 
    protected bool _designerMode; 
    internal void SetDesignerMode() { _designerMode = true; }
 
    private IDictionary _linePragmasTable;
    internal IDictionary LinePragmasTable { get { return _linePragmasTable; } }

    // Used to generate indexed into the LinePragmasTable 
    private int _pragmaIdGenerator=1;
 
    private static bool _urlLinePragmas; 

    static BaseCodeDomTreeGenerator() { 
        CompilationSection config = MTConfigUtil.GetCompilationAppConfig();

        _urlLinePragmas = config.UrlLinePragmas;
    } 

#if DBG 
    private bool _addedDebugComment; 
#endif
 
#if DBG
    protected void AppendDebugComment(CodeStatementCollection statements) {
        if (!_addedDebugComment) {
            _addedDebugComment = true; 
            StringBuilder debugComment = new StringBuilder();
 
            debugComment.Append("\r\n"); 
            debugComment.Append("** DEBUG INFORMATION **");
            debugComment.Append("\r\n"); 

            statements.Add(new CodeCommentStatement(debugComment.ToString()));
        }
    } 
#endif
 
    internal /*public*/ CodeCompileUnit GetCodeDomTree(CodeDomProvider codeDomProvider, 
        StringResourceBuilder stringResourceBuilder, VirtualPath virtualPath) {
 
        Debug.Assert(_codeDomProvider == null && _stringResourceBuilder == null);

        _codeDomProvider = codeDomProvider;
        _stringResourceBuilder = stringResourceBuilder; 
        _virtualPath = virtualPath;
 
        // Build the data tree that needs to be compiled 
        if (!BuildSourceDataTree())
            return null; 

        // Tell the root builder that the CodeCompileUnit is now fully complete
        if (Parser.RootBuilder != null) {
            Parser.RootBuilder.OnCodeGenerationComplete(); 
        }
 
        return _codeCompileUnit; 
    }
 
    protected /*public*/ CompilerParameters CompilParams { get { return _compilParams; } }

    internal string GetInstantiatableFullTypeName() {
 
        // In updatable mode, we never build the final type, so return null
        if (PrecompilingForUpdatableDeployment) 
            return null; 

        return Util.MakeFullTypeName(_sourceDataNamespace.Name, _sourceDataClass.Name); 
    }

    internal string GetIntermediateFullTypeName() {
 
        return Util.MakeFullTypeName(Parser.BaseTypeNamespace, _intermediateClass.Name);
    } 
 
    /*
     * Set some fields that are needed for code generation 
     */
    protected BaseCodeDomTreeGenerator(TemplateParser parser) {
        _parser = parser;
 
        Debug.Assert(Parser.BaseType != null);
    } 
 
    protected void ApplyEditorBrowsableCustomAttribute(CodeTypeMember member) {
        Debug.Assert(_designerMode, "This method should only be used in design mode."); 

        // Generate EditorBrowsableAttribute to hide the generated methods from the tool
        // [EditorBrowsable(EditorBrowsableState.Never)]
        CodeAttributeDeclaration editorBrowsableAttribute = new CodeAttributeDeclaration(); 
        editorBrowsableAttribute.Name = typeof(EditorBrowsableAttribute).FullName;
        editorBrowsableAttribute.Arguments.Add(new CodeAttributeArgument(new CodeFieldReferenceExpression(new CodeTypeReferenceExpression(typeof(EditorBrowsableState)), "Never"))); 
        member.CustomAttributes.Add(editorBrowsableAttribute); 
    }
 

    /// 
    ///     Create a name for the generated class
    ///  
    protected virtual string GetGeneratedClassName() {
        string className; 
 
        // If the user specified the class name, just use that
        if (Parser.GeneratedClassName != null) 
            return Parser.GeneratedClassName;

        // Use the input file name to generate the class name
 
        className = _virtualPath.FileName;
 
        // Prepend the class name with the directory path within the app (DevDiv 42063) 
        string appRelVirtualDir = _virtualPath.Parent.AppRelativeVirtualPathStringOrNull;
        if (appRelVirtualDir != null) { 
            Debug.Assert(UrlPath.IsAppRelativePath(appRelVirtualDir));
            className = appRelVirtualDir.Substring(2) + className;
        }
 
        // Change invalid chars to underscores
        className = Util.MakeValidTypeNameFromString(className); 
 
        // Make it lower case to make it more predictable (VSWhidbey 503369)
        className = className.ToLowerInvariant(); 

        // If it's the same as the base type name, prepend it with an underscore to prevent
        // a compile error.
        string baseTypeName = Parser.BaseTypeName != null ? Parser.BaseTypeName : Parser.BaseType.Name; 
        if (StringUtil.EqualsIgnoreCase(className, baseTypeName)) {
            className = "_" + className; 
        } 

        return className; 
    }

    internal static bool IsAspNetNamespace(string ns) {
        return (ns == defaultNamespace); 
    }
 
    private bool PrecompilingForUpdatableDeployment { 
        get {
            // For global.asax, this never applies 
            if (IsGlobalAsaxGenerator)
                return false;

            return BuildManager.PrecompilingForUpdatableDeployment; 
        }
    } 
 
    private bool BuildSourceDataTree() {
 
        _compilParams = Parser.CompilParams;

        _codeCompileUnit = new CodeCompileUnit();
        _codeCompileUnit.UserData["AllowLateBound"] = !Parser.FStrict; 
        _codeCompileUnit.UserData["RequireVariableDeclaration"] = Parser.FExplicit;
 
        // Set a flag indicating if we're using the VJS compiler.  See comment in BuildExtractMethod for more information. 
        _usingVJSCompiler = (_codeDomProvider.FileExtension == ".jsl");
 
        _sourceDataNamespace = new CodeNamespace(Parser.GeneratedNamespace);

        string generatedClassName = GetGeneratedClassName();
 
        if (Parser.BaseTypeName != null) {
 
            Debug.Assert(Parser.CodeFileVirtualPath != null); 

            // This is the case where the page has a CodeFile attribute 

            CodeNamespace intermediateNamespace = new CodeNamespace(Parser.BaseTypeNamespace);
            _codeCompileUnit.Namespaces.Add(intermediateNamespace);
            _intermediateClass = new CodeTypeDeclaration(Parser.BaseTypeName); 

            // Specify the base class in the UserData in case the CodeDom provider needs 
            // to reflect on it when generating code from the CodeCompileUnit (VSWhidbey 475294) 
            // In design mode, use the default base type (e.g. Page or UserControl) to avoid
            // ending up with a type that can't be serialized to the Venus domain (VSWhidbey 545535) 
            if (_designerMode)
                _intermediateClass.UserData["BaseClassDefinition"] = Parser.DefaultBaseType;
            else
                _intermediateClass.UserData["BaseClassDefinition"] = Parser.BaseType; 

            intermediateNamespace.Types.Add(_intermediateClass); 
 
            // Generate a partial class
            _intermediateClass.IsPartial = true; 

            // Unless we're precompiling for updatable deployment, create the derived class
            if (!PrecompilingForUpdatableDeployment) {
 
                _sourceDataClass = new CodeTypeDeclaration(generatedClassName);
                // VSWhidbey 411701. Always use global type reference for the baseType 
                // when codefile is present. 
                _sourceDataClass.BaseTypes.Add(CodeDomUtility.BuildGlobalCodeTypeReference(
                    Util.MakeFullTypeName(Parser.BaseTypeNamespace, Parser.BaseTypeName))); 

                _sourceDataNamespace.Types.Add(_sourceDataClass);
            }
        } 
        else {
 
            // The page is not using code besides 

            _intermediateClass = new CodeTypeDeclaration(generatedClassName); 
            _intermediateClass.BaseTypes.Add(CodeDomUtility.BuildGlobalCodeTypeReference(Parser.BaseType));
            _sourceDataNamespace.Types.Add(_intermediateClass);

            // There is only one class, so make both fields point to the same thing 
            _sourceDataClass = _intermediateClass;
        } 
 
        // Add the derived class namespace after the base partial class so C# parser
        // can still parse the code correctly in case the derived class contains error. 
        // VSWhidbey 397646
        _codeCompileUnit.Namespaces.Add(_sourceDataNamespace);

        // We don't generate any code during updatable precompilation of a single (inline) page, 
        // except for global.asax
        if (PrecompilingForUpdatableDeployment && Parser.CodeFileVirtualPath == null) 
            return false; 

        // Add metadata attributes to the class 
        GenerateClassAttributes();

        // In VB, always import Microsoft.VisualBasic (VSWhidbey 256475)
        if (_codeDomProvider is Microsoft.VisualBasic.VBCodeProvider) 
            _sourceDataNamespace.Imports.Add(new CodeNamespaceImport("Microsoft.VisualBasic"));
 
        // Add all the namespaces 
        if (Parser.NamespaceEntries != null) {
            foreach (NamespaceEntry entry in Parser.NamespaceEntries.Values) { 
                // Create a line pragma if available
                CodeLinePragma linePragma;
                if (entry.VirtualPath != null) {
                    linePragma = CreateCodeLinePragma(entry.VirtualPath, entry.Line); 
                }
                else { 
                    linePragma = null; 
                }
 
                CodeNamespaceImport nsi = new CodeNamespaceImport(entry.Namespace);
                nsi.LinePragma = linePragma;

                _sourceDataNamespace.Imports.Add(nsi); 
            }
        } 
 
        if (_sourceDataClass != null) {
            // We need to generate a global reference to avoid ambiguities (VSWhidbey 284936) 
            string fullClassName = Util.MakeFullTypeName(_sourceDataNamespace.Name, _sourceDataClass.Name);
            CodeTypeReference classTypeRef = CodeDomUtility.BuildGlobalCodeTypeReference(fullClassName);

            // Since this is needed in several places, store it in a member variable 
            _classTypeExpr = new CodeTypeReferenceExpression(classTypeRef);
        } 
 
        // Add the implemented interfaces
        GenerateInterfaces(); 

        // Build various properties, fields, methods
        BuildMiscClassMembers();
 
        // Build the default constructors
        if (!_designerMode && _sourceDataClass != null) { 
            _ctor = new CodeConstructor(); 
            AddDebuggerNonUserCodeAttribute(_ctor);
            _sourceDataClass.Members.Add(_ctor); 
            BuildDefaultConstructor();
        }

        return true; 
    }
 
    /* 
     * Add metadata attributes to the class
     */ 
    protected virtual void GenerateClassAttributes() {
        // If this is a debuggable page, generate a
        // CompilerGlobalScopeAttribute attribute (ASURT 33027)
        if (CompilParams.IncludeDebugInformation && _sourceDataClass != null) { 
            CodeAttributeDeclaration attribDecl = new CodeAttributeDeclaration(
                "System.Runtime.CompilerServices.CompilerGlobalScopeAttribute"); 
            _sourceDataClass.CustomAttributes.Add(attribDecl); 
        }
    } 

    /*
     * Generate the list of implemented interfaces
     */ 
    protected virtual void GenerateInterfaces() {
        if (Parser.ImplementedInterfaces != null) { 
            foreach (Type t in Parser.ImplementedInterfaces) { 
                _intermediateClass.BaseTypes.Add(new CodeTypeReference(t));
            } 
        }
    }

    /* 
     * Build first-time intialization statements
     */ 
    protected virtual void BuildInitStatements(CodeStatementCollection trueStatements, CodeStatementCollection topLevelStatements) { 
    }
 

    /*
     * Build the default constructor
     */ 
    protected virtual void BuildDefaultConstructor() {
 
        _ctor.Attributes &= ~MemberAttributes.AccessMask; 
        _ctor.Attributes |= MemberAttributes.Public;
 
        // private static bool __initialized;
        CodeMemberField initializedField = new CodeMemberField(typeof(bool), initializedFieldName);
        initializedField.Attributes |= MemberAttributes.Static;
        _sourceDataClass.Members.Add(initializedField); 

 
        // if (__intialized == false) 
        CodeConditionStatement initializedCondition = new CodeConditionStatement();
        initializedCondition.Condition = new CodeBinaryOperatorExpression( 
                                                new CodeFieldReferenceExpression(
                                                    _classTypeExpr,
                                                    initializedFieldName),
                                                CodeBinaryOperatorType.ValueEquality, 
                                                new CodePrimitiveExpression(false));
 
        this.BuildInitStatements(initializedCondition.TrueStatements, _ctor.Statements); 

        initializedCondition.TrueStatements.Add(new CodeAssignStatement( 
                                                    new CodeFieldReferenceExpression(
                                                        _classTypeExpr,
                                                        initializedFieldName),
                                                    new CodePrimitiveExpression(true))); 

        // i.e. __intialized = true; 
        _ctor.Statements.Add(initializedCondition); 
    }
 
    /*
     * Build various properties, fields, methods
     */
    protected virtual void BuildMiscClassMembers() { 

        // Build the Profile property 
        if (NeedProfileProperty) 
            BuildProfileProperty();
 
        // Skip the rest if we're only generating the intermediate class
        if (_sourceDataClass == null)
            return;
 
        // Build the injected properties from the global.asax  tags
        BuildApplicationObjectProperties(); 
        BuildSessionObjectProperties(); 

        // Build the injected properties for objects scoped to the page 
        BuildPageObjectProperties();

        // Add all the 
                        
                    
                    

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