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

📄 typeast.cs

📁 charp compiler
💻 CS
📖 第 1 页 / 共 2 页
字号:
//-----------------------------------------------------------------------------    
// AST nodes for types
//-----------------------------------------------------------------------------    

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

using SymbolEngine;
using Blue.Public;
using CodeGen = Blue.CodeGen;

namespace AST
{

#region Base class
//-----------------------------------------------------------------------------    
// Base TypeSig
// An AST wrapper for a TypeEntry symbol
// Represent any kind of Type (array, simple, reference, etc)
//-----------------------------------------------------------------------------    

/// <summary>
/// Abstract base class for ast nodes representing types.
/// </summary>
/// <remarks>
/// <para>The following nodes derive from TypeSig:<list type="bullet">
/// <item><see cref="ResolvedTypeSig"/>- a node not associated with source that directly wraps a symbol. </item>
/// <item><see cref="SimpleTypeSig"/> - a node representing a non-decorated type from source.</item>
/// <item><see cref="ArrayTypeSig"/> - a node representing an array type</item>
/// <item><see cref="RefTypeSig"/> - a node representing a reference to a type.</item>
/// </list></para>
/// <para>A TypeSig represents the usage of a type in the AST. A <see cref="ClassDecl"/> represents
/// the definition of a type in the AST. A <see cref="SymbolEngine.TypeEntry"/> is the symbol
/// representing the type.</para>
/// </remarks>
public abstract class TypeSig : Node
{
#region Virtuals - Symbols
    // From a Type, we want to be able to get the BLUE & CLR symbols
    public abstract TypeEntry BlueType
    {
        get;
    }
    
    public virtual Type CLRType
    {
        get {
            return BlueType.CLRType;
        }
    }
#endregion

#region Virtual - Getting Derived States    
    // Given a generic type, we need to be able to find out what it really is and
    // safely get it to a more derived state.
    // Derived classes can override with a more direct implementation.
    public virtual bool IsArray
    {
        get { 
            return (CLRType.IsArray); 
        }
    }
    
    // Assume that if this isn't overriden, we're not an array.
    public virtual ArrayTypeSig AsArraySig
    {
        get {            
            // We would like this, but the debugger will evaluate it in a watch window and die.
            // So we'll just let the null-ref exception warn us.
            Debug.Assert(false); // Not implemented
            return null;
        }
    }
#endregion        
    
#region Resolution    
    // Resolution
    public abstract void ResolveType(ISemanticResolver s);
#endregion    
    
#region Checks
    public override void Dump(XmlWriter o)
    {
        o.WriteStartElement(this.GetType().ToString());
        
        TypeEntry t = BlueType;
        o.WriteAttributeString("BlueType", t.ToString());
        
        System.Type t2 = CLRType;
        o.WriteAttributeString("CLRType", t2.ToString());
                
        o.WriteEndElement();
    }
    
    public override void DebugCheck(ISemanticResolver s)
    {        
        BlueType.DebugCheck(s);        
    }
    
    
    public override void ToSource(System.CodeDom.Compiler.IndentedTextWriter sb)    
    {
        sb.Write("<T>{0}", ToString());
    }
    
    public override string ToString()
    {
        if (BlueType == null)
            return "Unresolved";
        else if (CLRType == null)
            return this.BlueType.ToString();
        else                
            return this.CLRType.ToString();
    }
#endregion       
}

#endregion Base Class

//-----------------------------------------------------------------------------    
// Class to represent a flyweight around a CLR-type.
// @todo - If we expect this to handle ref types, then we just have to make it not
// derive from NonRefTypeSig.
//-----------------------------------------------------------------------------    
public class ResolvedTypeSig : NonRefTypeSig
{
#region Construction        
    // Expose constructor that takes an already resolved type
    // Very useful when we build/modify parts of the AST during resolution
    public ResolvedTypeSig(TypeEntry t)
    {
        Debug.Assert(!t.IsRef, "Don't expect ref types");
        Debug.Assert(t != null);
        m_type = t;
    }
    
    public ResolvedTypeSig(System.Type t, ISemanticResolver s)
    {
        Debug.Assert(!t.IsByRef, "Don't expect ref types");
        Debug.Assert(t != null);
        Debug.Assert(s != null);
        m_type = s.ResolveCLRTypeToBlueType(t);
    }
#endregion
    
    // Since we already have a symbol, we don't have anything to do
    // (symbols are resolved);
    public override void ResolveType(ISemanticResolver s)
    {   
    }

    public override ArrayTypeSig AsArraySig
    {
        get { 
            Debug.Assert(m_type.IsArray);
            Debug.Assert(false, "@todo - implement this");
            return null;
        }        
    }
    
#region Properties & Data
    // Get the resolved type
    protected TypeEntry m_type;
    public override TypeEntry BlueType
    {
        get { return m_type; }
    }
    
    public override Type CLRType
    {
        get { return m_type.CLRType; }
    }
#endregion
}


//-----------------------------------------------------------------------------    
// Common base class for types that are not references (includes Simple & Array)
//-----------------------------------------------------------------------------    
public abstract class NonRefTypeSig : TypeSig
{
    
}

//-----------------------------------------------------------------------------    
// Simple type. May be class, interface, struct, enum.
// Get this from the parse tree.
//-----------------------------------------------------------------------------    
public class SimpleTypeSig : NonRefTypeSig
{
#region Construction
    public SimpleTypeSig(Exp e)
    {
        if (e != null)
            m_filerange = e.Location;
            
        m_oeValue = e;           
    }
#endregion    
    
#region Properties & Data   
    // SimpleType is never an array 
    public override bool IsArray
    {
        get { return false; }
    }
                   
    // This object is completely hidden    
    protected Exp m_oeValue;
    
    // Get the resolved type
    TypeEntry m_type;
    public override TypeEntry BlueType
    {
        get { return m_type; }
    }
#endregion
    
    // Semantic resolution
    public override void ResolveType(ISemanticResolver s)
    {
        if (m_type != null)
            return;
            
        Exp.ResolveExpAsRight(ref m_oeValue, s);
                
        Debug.Assert(m_oeValue is TypeExp);                
        m_type = ((TypeExp) m_oeValue).Symbol;
    }
    
#region Checks    
/*
    public override string ToString()
    {
        if (m_type != null)
            return "TypeSig:" + m_type.ToString();
        else
            return "TypeSig:<unresolved>";        
    }
*/    
    // Dump as XML
    public override void Dump(XmlWriter o)
    {
        o.WriteStartElement("TypeSig");
                
        if (m_oeValue != null)
            m_oeValue.Dump(o);
                    
        o.WriteEndElement();
    }
    
    public override void DebugCheck(ISemanticResolver s)
    {        
        Debug.Assert(m_type != null);
        TypeEntry t = BlueType;
        
        if (t.IsRef)
            return;
        
        System.Type clrType = t.CLRType;
        
        // Make sure that our CLR type matches our TypeEntry
        if (clrType != null)
        {
            // @todo - Enums aren't entered into the hash.
            if (!(t is EnumTypeEntry))
            {
                TypeEntry t2 = s.ResolveCLRTypeToBlueType(clrType);
                Debug.Assert(t == t2);
            }
        }
        if (clrType == null)
        {   
            // Even now, the only way we can have no clr type is if we
            // are a user declared class
            Debug.Assert(t.Node != null);            
        }
                
    } // DebugCheck   
#endregion     
}

//-----------------------------------------------------------------------------    
// Array
//-----------------------------------------------------------------------------    
public class ArrayTypeSig : NonRefTypeSig
{
#region Construction
    // ArrayType of base T and given rank
    public ArrayTypeSig(NonRefTypeSig tElem, int dimension)
    {
        Debug.Assert(tElem != null);
        
        m_filerange = tElem.Location;
        m_cDimension = dimension;
        m_sigBase = tElem;
    }
    
    // Create an array node given an existing CLR array type
    public ArrayTypeSig(System.Type tArray, ISemanticResolver s)    
    {
        Debug.Assert(tArray != null);
        
        m_filerange = null;
        m_cDimension = tArray.GetArrayRank();        
        Debug.Assert(m_cDimension == 1, "@todo - only 1d arrays currently implemented");
        
        m_ArrayTypeRec = s.ResolveCLRTypeToBlueType(tArray).AsArrayType;
        m_sigBase = null; // left as null.
    }
    /*
    public ArrayTypeSig(ResolvedTypeSig tElem, int dimension)
    {
        Debug.Assert(tElem != null);

⌨️ 快捷键说明

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