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

📄 typesymbol.cs

📁 charp compiler
💻 CS
📖 第 1 页 / 共 5 页
字号:
//-----------------------------------------------------------------------------
// Symbols for types
//
// @todo - Note, currently these have a terrible object model. TypeEntry
// should have a lot of virtual functions on it that the derived types
// just override. (Similar to the Type AST nodes). Need to fix this.
//-----------------------------------------------------------------------------

using System;
using System.Diagnostics;
using System.Xml;

using Blue.Public;
using Log = Blue.Log;
using Modifiers = AST.Modifiers;


namespace SymbolEngine
{
#region Classes for Type Symbols
    //-----------------------------------------------------------------------------
    // Helper for TypeEntry. Keep overload info for resolving members
    //-----------------------------------------------------------------------------
    public class OverloadedErrorInfo
    {
        protected MethodExpEntry m_symbol;
        protected MethodExpEntry m_symbolVarArg;
        protected int m_count = 0;
        protected bool m_fNoHeader;
        
        // Keep a lazy string record of the overloads for error information.
        // We don't initialize this until we actually get some ambiguity.        
        protected System.Text.StringBuilder m_sbOverloads;

#if DEBUG            
        public static bool m_fLog = false;           
#endif        
                
        public void SetNoHeader()
        {
#if DEBUG        
            if (m_fLog)
                Console.WriteLine("Set no header");        
#endif        
        
            m_fNoHeader = true;
        }
        
        public bool NoHeader
        {
            get { return m_fNoHeader; }
        }
                
        // Return # of matches, giving precedence to non-vararg
        public int MatchCount
        {
            get 
            { 
                return (m_count == 0) ? 
                    ((m_symbolVarArg == null) ? 0 : 1) :
                    m_count; 
            }
        }
        
        public string GetOverloadList()
        {
            return m_sbOverloads.ToString();
        }
        
        public void AddMatch(MethodExpEntry symbol)
        {
#if DEBUG        
            if (m_fLog)
            {
                Console.WriteLine("Adding match:{0}", //TypeEntry.GetDecoratedParams(symbol),
                    symbol.PrettyDecoratedName);        
            }
#endif      
            // If we're ambiguous, then start tracking it for error info          
            // Don't create the string builder until we hit our first ambiguous overload
            if (m_count == 1)
            {                
                m_sbOverloads = new System.Text.StringBuilder();
                
                // Add the first entry
                // @dogfood - should be able to match 0 non-varargs
                //m_sbOverloads.AppendFormat("\t(1):");
                m_sbOverloads.Append("\t(1):");
                m_sbOverloads.Append(m_symbol.PrettyDecoratedName);
                m_sbOverloads.Append('\n');
            }
                        
            m_count++;            
            m_symbol = symbol;
            
            if (m_count > 1)
            {
                // Keep appending the overload entries
                m_sbOverloads.AppendFormat("\t({0}):", m_count);
                m_sbOverloads.Append(symbol.PrettyDecoratedName);
                m_sbOverloads.Append('\n');
            }
        }

        public void AddVarargMatch(MethodExpEntry symbol)
        {
#if DEBUG        
            if (m_fLog)
                Console.WriteLine("Adding vararg match:{0}", TypeEntry.GetDecoratedParams(symbol));        
#endif                
            m_symbolVarArg = symbol;
        }

        public bool IsVarArgMatch
        {
            get 
            {
                return (m_symbol == null) && (m_symbolVarArg != null);
            }
        }

        // Return the symbol, giving precedence to the non-vararg version
        public MethodExpEntry Symbol
        {            
            get { return (m_symbol == null) ? m_symbolVarArg : m_symbol; }
        }
    }

#if false    
    // @todo - this may be a much better hierarchy than what we currently have.

#region TypeEntry base class
    //-----------------------------------------------------------------------------
    // Abstract base class to represent Blue's notion of a type.
    // It's rather silly that we have to maintain an entire symbol table when
    // these are so closely related to System.Type, but alas. TypeBuilders are 
    // not System.Type. 
    //-----------------------------------------------------------------------------
    public abstract class TypeEntry : SymEntry
    {
    
#region Properties
        // Get the System.Type associated with this type entry.
        System.Type CLRType
        {
            get;
        }
#endregion
    }
    
    // A nonreference type
    public abstract class NonRefTypeEntry : TypeEntry
    {
    
    }
    
    // Referenece to any NonRefType
    // Flyweights
    public class RefTypeEntry : TypeEntry
    {
    
    }
    
    // Array of non-ref types
    // These are flyweights. 
    public class ArrayTypeEntry : NonRefTypeEntry
    {
    
    }
    
    // Simple type. These are unique for each type and have a 1:1 match
    // with the a System.Type.
    public class SimpleTypeEntry : NonRefTypeEntry
    {
    
    }
    
    // Enum.
    public class EnumTypeEntry : SimpleTypeEntry
    {
    
    }
    
    // Imported type already has it's CLRType set.
    public class ImportedTypeEntry : NonRefTypeEntry
    {
        
    }
#endregion
#endif


    //-----------------------------------------------------------------------------
    // Represent a type
    // Under the CLR, All types are objects and can have members on them
    // (even primitives like int)
    //-----------------------------------------------------------------------------
    public class TypeEntry : SymEntry, ILookupController
    {
        public enum Genre
        {
            cClass,
            cStruct,
            cInterface,
            
            cReference, // A reference isn't a Class/Struct/Interface
        }
        
        public static Genre GenreFromClrType(System.Type t)
        {
            if (t.IsInterface)
                return Genre.cInterface;
            else if (t.IsValueType)
                return Genre.cStruct;
                
                // ...
                // This is another bug in the CLR Frameworks. MSDN clearly says that
                // typeof(System.Enum).IsClass is supposed to be true 
                // (even though Enum derives from ValueType).
                // But it's not, so we have to special case that.
                // In V2,the docs  will probably be changed to reflect the behavior
                // (because we can't exactly change the behavior at this point). So
                // in that sense, this will be converted from a 'bug' into a 'feature'.
            else if (t.IsClass || (t == typeof(System.Enum)))
                return Genre.cClass;            
            
            
            Debug.Assert(false, "expected Interface,Class, or Struct");  
            return Genre.cClass;
        }
    
#region Construction

#region User Types
        // We need 2-phase initilization
        // 1 - Add stubs
        // 2 - add rest of data (super class, base interfaces)
        
        // Creating from a classdecl
        public TypeEntry(
            string stFullName,            
            AST.ClassDecl nodeDecl,             
            Genre genre,
            Scope scopeParent
            )
        {            
            m_strName = (nodeDecl ==null) ? "<empty>" : nodeDecl.Name;
            m_stFullName = stFullName;
            m_decl = nodeDecl;
            
            m_genre = genre;
            if (genre == Genre.cReference)
            {
            
            } 
            else 
            {
                this.m_mods = nodeDecl.Mods;
            }
            
            // Create a scope now so that we can add stubs for nested types into it.
            // We'll have to set the super-scope later
            // ******** need this for nested types ....
            if (genre != Genre.cReference)
            {
                //m_scope = new Scope((m_genre.ToString()) + "_" + m_strName, nodeDecl, scopeParent);
                m_scope = new Scope((m_genre.ToString()) + "_" + m_strName, this, scopeParent);
            }            
        }

        protected bool m_fIsInit = false;

        public void InitLinks(
            TypeEntry tSuper, 
            TypeEntry [] interfaces  // can be null
            )
        {
            Debug.Assert(m_fIsInit == false);
            Debug.Assert(m_super == null);
            
            m_interfaces = (interfaces == null) ? m_emptyinterfaces : interfaces;
            m_super = tSuper;
            
            // Set containing class, based off lexical scope
            AST.ClassDecl nodeParent = m_scope.LexicalParent.Node as AST.ClassDecl;
            if (nodeParent != null)
            {
                m_containingClass = nodeParent.Symbol;
                Debug.Assert(m_containingClass != null);
            }
        }

        // Sets super scope
        public void FinishInit()
        {            
            Debug.Assert(m_fIsInit == false);
            
            // Relies on super classes being inited already            
            if (m_super != null)
            {
                Debug.Assert(m_super.m_fIsInit);
            }
            foreach(TypeEntry t in m_interfaces)
            {
                Debug.Assert(t.m_fIsInit);
            }
                        
            // Set scopes   
            Debug.Assert(IsInterface || (m_super.MemberScope != null));
            //Scope sSuper = (m_super == null) ? null : m_super.MemberScope;
            
            //m_scope.SetSuperScope(sSuper);

            m_fIsInit = true;
        }
#endregion        
        
#region Imported Types
        // Return a stub used for importing
        static public TypeEntry CreateImportStub(System.Type clrType)
        {
            return new TypeEntry(clrType);
        }
        
        public void FinishImportStub(
            TypeEntry tSuper,
            TypeEntry [] interfaces, // can be null,
            TypeEntry tParent
        )
        {
            m_interfaces        = (interfaces == null) ? m_emptyinterfaces : interfaces;
            m_super             = tSuper;
            m_containingClass   = tParent;
            m_fIsInit           = true;
        }
        
        // Stub entry
        private TypeEntry(System.Type clrType)
        {

⌨️ 快捷键说明

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