⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ast.cs

📁 charp compiler
💻 CS
📖 第 1 页 / 共 5 页
字号:
    // Return symbol if found.
    // Return null if not found.
    public SymEntry LookupSymbol(string stText)
    {
        SymEntry sym = null;

        if (IsAliasType)
        {
            // For an alias, if the string name matches, then we already have the symbol
            // to return. No search needed.
            if (stText == m_stAlias)
            {   
                if (m_eNamespace is NamespaceExp)
                {
                    return ((NamespaceExp) m_eNamespace).Symbol;                
                }
                
                else if (m_eNamespace is TypeExp)
                {
                    return ((TypeExp) m_eNamespace).Symbol;
                }
                
                Debug.Assert(false);
            }
        } 
        else 
        {
            // Lookup in associated namespace            
            Scope scope = ((NamespaceExp) m_eNamespace).Symbol.ChildScope;
            sym = scope.LookupSymbolInThisScopeOnly(stText);

            // We specifically do not look in nested namespaces
            // See section 9.3.2 of the C# spec for details
            if (sym is NamespaceEntry)
                sym = null;
        }

        return sym;
    }

    public void Resolve(ISemanticResolver s, Scope scopeNamespace)
    {
        // Have to see what our namespace / class resolves to.
        //m_eNamespace.ResolveExpAsRight(s);
        Exp.ResolveExpAsRight(ref m_eNamespace, s);
        if (IsAliasType)
        {
            // Alias could be to either a class or namespace
            //Debug.Assert(m_eNamespace.SymbolMode != ObjExp.Mode.cExpEntry);
            Debug.Assert(m_eNamespace is TypeExp || m_eNamespace is NamespaceExp);
        } 
        else 
        {
            // Directives can only give us namespaces
            //Debug.Assert(m_eNamespace.SymbolMode == ObjExp.Mode.cNamespaceEntry);
            Debug.Assert(m_eNamespace is NamespaceExp);
        }
    }
#endregion
    
#region Checks
    public override void Dump(XmlWriter o)
    {
        o.WriteStartElement("Using");
        if (m_stAlias != null)
            o.WriteAttributeString("alias", m_stAlias);
        m_eNamespace.Dump(o);
        o.WriteEndElement();
    }

// Debugging check
    public override void DebugCheck(ISemanticResolver s)
    {
    }
#endregion
}

//-----------------------------------------------------------------------------
// Declare a user namespace
// Note that a single namespace can be declared across multiple NamespaceDecls.
// Each source file is considered to be in the Global Namespace.
// Each namespace block can have its own set of using directives. (So even
// if 2 blocks refer to the same namespace, they can have different using
// directives)
//-----------------------------------------------------------------------------
public class NamespaceDecl : Node, SymbolEngine.ILookupController
{
#region Construction
    // Any of the array parameters may be null
    public NamespaceDecl(
        Identifier idName, // must be non-null
        UsingDirective [] arUsingDirectives,
        NamespaceDecl[] arNestedNamespaces,
        ClassDecl[] arClasses,
        TypeDeclBase[] arTypes
    )
    {
        m_idName = idName;
    
        m_arUsingDirectives = (arUsingDirectives == null) ? new UsingDirective [0] : arUsingDirectives;
        m_arNestedNamespaces = (arNestedNamespaces == null) ? new NamespaceDecl[0] : arNestedNamespaces; 
        //m_arClasses = (arClasses == null) ? new ClassDecl[0] : arClasses;
        Debug.Assert(arClasses == null);
        
        m_arTypes = (arTypes == null) ? new TypeDeclBase[0] : arTypes;
    }
    
#endregion    

#region Other Functions    
    // Recursively Create a flat list of classes in a program
    public void ReportClasses(ArrayList alClasses)
    {   
        // At each stop, we make sure all of our prerequisite types are added
        // before us. So it doesn't matter what order we add in here.        
        foreach(TypeDeclBase e in m_arTypes)
            e.ReportClass(alClasses);
            
        // Recursively add all classes from nested namespaces
        foreach(NamespaceDecl n in NestedNamespaces)
            n.ReportClasses(alClasses);
    }
#endregion
    
#region Properties & Data    
    Identifier m_idName;
    UsingDirective [] m_arUsingDirectives;
    NamespaceDecl[] m_arNestedNamespaces;
    //ClassDecl[] m_arClasses;
    //EnumDecl[] m_arEnums;
    
    // @todo -merge this with classes
    TypeDeclBase [] m_arTypes;
    
    UserNamespaceEntry m_symbol;
    
    public string Name
    {
        get { return m_idName.Text; }
    }
 
    public NamespaceDecl[] NestedNamespaces
    {
        get { return  m_arNestedNamespaces; }
    }
        
 
    Scope m_context;
    
#endregion        
    
#region Resolution    
    #region Impl ILookupController
    
    // @dogfood - make these explicit interface methods
    // Return null if not found.
    public SymEntry SmartLookup(string stIdentifier, Scope scope)
    {
        // Do a normal lookup of things defined directly in this namespace.
        SymEntry sym = scope.LookupSymbolInThisScopeOnly(stIdentifier);
        if (sym != null)         
            return sym;        
        
        // Look in the using directives associated with this namespace node.
        sym = LookupSymbolInUsingDirectives(stIdentifier);
        return sym;
    }   
        
    // Get a node responsible for this scope.
    // For imported types, this will be null
    public AST.Node OwnerNode { 
        get { return this; }
    }
    
    // Get a symbol responsible for this scope. 
    // This may be null. (If this is null, then OwnerNode should not be null).
    public SymEntry OwnerSymbol { 
        get { return this.m_symbol; }
    }
    
    public void DumpScope(Scope scope)
    {
        if (this.m_arUsingDirectives.Length > 0)
        {
            Console.Write("[has using...]");
        }
        return;
    }
    
    #endregion

    #if true
    // Check the using directives in this namespace block. 
    // Give precedence to an alias over a directive.
    // Return null if not found. 
    // Throw error if ambigious (ie, a symbol can be found refered from multiple
    // using directives)
    // If we haven't resolved all of our own using directives yet, then return null
    // (this is to prevent using directives from affecting each other)
    public SymEntry LookupSymbolInUsingDirectives(string stName)
    {
        if (!m_fResolvedUsing)
            return null;

        // @todo - resolve ambiguity
        SymEntry sym = null;
        foreach(UsingDirective u in this.m_arUsingDirectives)
        {
            sym = u.LookupSymbol(stName);
            if (sym != null)
                return sym;
        }

        return null;
    }
    #endif

    // Flag to note if our using decls have been resolved yet
    bool m_fResolvedUsing = false;

    // Before we can process the classes, we need to add all the namespaces
    public void ResolveNamespace(
        string stParentNamespace, 
        ISemanticResolver s,
        Scope scopeParent)
    {
        Debug.Assert(m_symbol == null);
        
        // We can have one namespaces spread across multiple blocks (NamespaceDecl).
        // All blocks share the same scope (something defined in any block is visible
        // to all blocks), but each block can have its own lexical parent & set
        // of using clause. 
#if true
        m_symbol = (UserNamespaceEntry) scopeParent.LookupSymbolInThisScopeOnly(Name);
        if (m_symbol == null)
        {
            // Create new namespace
            string stFullName;
            if (stParentNamespace == "")
                stFullName = this.Name;
            else 
                stFullName = stParentNamespace + "." + this.Name;

            m_symbol = new UserNamespaceEntry(this, stFullName);
            scopeParent.AddSymbol(m_symbol);                        
        }
        
        // The symbol has the scope with all the data. But each namespace decl creates
        // a proxy scope that links to the symbol's data (Because all blocks share that)
        // but has a tie to its own set of using clauses & lexical parent.
        m_context = m_symbol.ChildScope.CreateSharedScope(this, scopeParent);
        
        foreach(NamespaceDecl n in NestedNamespaces)
            n.ResolveNamespace(m_symbol.FullName, s, m_context);
#else        
        
        // Since we can have multiple disjoint namespace decls refer
        // to the same namespace, we have to check and see if this
        // symbol is already created.        
        m_symbol = (UserNamespaceEntry) s.GetCurrentScope().LookupSymbolInThisScopeOnly(Name);
        if (m_symbol == null) 
        {
            string stFullName;
            if (stParentNamespace == "")
                stFullName = this.Name;
            else 
                stFullName = stParentNamespace + "." + this.Name;

            m_symbol = new UserNamespaceEntry(this, stFullName);        
            s.GetCurrentScope().AddSymbol(m_symbol);
        }
        
        
        EnterNamespace(s);
        
        foreach(NamespaceDecl n in NestedNamespaces)
            n.ResolveNamespace(m_symbol.FullName, s, scopeParent);
            
        
        ExitNamespace(s);
#endif        
    }
/*    
    void EnterNamespace(ISemanticResolver s)
    {
        m_symbol.SetCurrentNode(this);
        s.PushScope(m_symbol.ChildScope);
    }
    
    void ExitNamespace(ISemanticResolver s)
    {
        m_symbol.SetCurrentNode(null);
        s.PopScope(m_symbol.ChildScope);
    }
*/    

    // Resolve the using declarations
    public void ResolveUsingDecls(ISemanticResolver s)
    {
        // All using declarations are resolved at global scope,
        // so don't enter / exit namespaces here
        //EnterNamespace(s);

        
        // Resolve all the using clauses in this namespace block
        Scope prev = s.SetCurrentContext(this.m_context);
        
        foreach(UsingDirective u in this.m_arUsingDirectives)
            u.Resolve(s, m_context);
            
        s.RestoreContext(prev);            
            
        // Recursively add all classes from nested namespaces
        foreach(NamespaceDecl n in NestedNamespaces)
            n.ResolveUsingDecls(s);

        //ExitNamespace(s);

        m_fResolvedUsing = true;
    }
    
    public void ResolveTypesAsBlueStub(
        ISemanticResolver s)
    {
        //EnterNamespace(s);
        
        // add all classes in this namespace
        {            
            foreach(TypeDeclBase e in m_arTypes)
                e.ResolveTypesAsBlueStub(s, this.m_symbol.FullName, m_context);
        }
            
        // Recursively add all classes from nested namespaces
        foreach(NamespaceDecl n in NestedNamespaces)
            n.ResolveTypesAsBlueStub(s);
            
        //ExitNamespace(s);
    }
    
    public void ResolveTypesAsCLR(
        ISemanticResolver s,
        ICLRtypeProvider provider
    )
    {
        // We shouldn't have to update the scope stack since
        // we should only be looking at resolved symbols

        Scope prev = s.SetCurrentContext(m_context);
        
        // add all classes in this namespace
        {   
            foreach(TypeDeclBase e in m_arTypes)
                e.ResolveTypesAsCLR(s, provider);
        }
        
        s.RestoreContext(prev);
            
        // Recursively add all classes from nested namespaces
        foreach(NamespaceDecl n in NestedNamespaces)
            n.ResolveTypesAsCLR(s, provider);
    }
	
    public void ResolveMemberDecls(
        ISemanticResolver s,
        ICLRtypeProvider provider
    )
    {
        // Do for all types in this namespace
        foreach(TypeDeclBase e in m_arTypes)
                e.ResolveMemberDecls(s, provider);
        
            
        // Recursively do all classes from nested namespaces
        foreach(NamespaceDecl n in NestedNamespaces)
            n.ResolveMemberDecls(s, provider);
        
    }

    // Resolve the bodies of methods
    public void ResolveBodies(ISemanticResolver s)
    {   
        foreach(TypeDeclBase e in m_arTypes)
            e.ResolveBodies(s);
        
            
        // Recursively add all classes from nested namespaces
        foreach(NamespaceDecl n in NestedNamespaces)
            n.ResolveBodies(s);
        
    }
#endregion    
    
#region Checks    
    // Dump the AST node contents to an xml file
    public override void Dump(XmlWriter o)
    {
        o.WriteStartElement("Namespace");        
        o.WriteAttributeString("name", Name);
        
        o.WriteStartElement("UsingDirectives");
        foreach(UsingDirective n in m_arUsingDirectives)
            n.Dump(o);
        o.WriteEndElement();
        
        o.WriteStartElement("NestedNamespaces");
        foreach(NamespaceDecl n in m_arNestedNamespaces)
            n.Dump(o);
        o.WriteEndElement();
               
        /*                
        o.WriteStartElement("Classes");
        foreach(ClassDecl n in m_arClasses)
            n.Dump(o);
        o.WriteEndElement();
        */

        o.WriteStartElement("Types");
        foreach(TypeDeclBase e in m_arTypes)
            e.Dump(o);
        o.WriteEndElement();

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -