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

📄 ast.cs

📁 charp compiler
💻 CS
📖 第 1 页 / 共 5 页
字号:
                if (t.IsEnum)
                {
                    // If we imported the enum, it will import as a TypeEntry, but then we still
                    // don't have to add it.
                    EnumDecl e = ((EnumTypeEntry) f.Symbol.FieldType).Node;
                    if (e != null)
                    {
                        e.ReportClass(alClasses);                        
                    }                
                } 
                else if (t.IsValueType)
                {
                    if (f.Symbol.FieldType.Node != null)
                    {
                        f.Symbol.FieldType.Node.ReportClass(alClasses);
                    }
                }
            }
        }
        #endif

        // Now, add this class
        alClasses.Add(this);
                
        // Now that the outer type is added, make sure all nested classes
        // get added.        
        foreach(TypeDeclBase t in this.m_alNestedTypes)
        {
            t.ReportClass(alClasses);
        }
        
    }
    
    // Get the CLR type that this node represents. Useful for codegen.
    public override System.Type CLRType
    {
        get {
            return this.Symbol.CLRType;
        }
    }
#endregion    

#region Resolve Types as Blue Stub
    // Semantic checking
    // Stubs can be resolved in any order.
    public override void ResolveTypesAsBlueStub(
        ISemanticResolver s,
        string stNamespace,
        Scope scopeParent
        )
    {
        // Get our name. Nested classes are separated with a '+'
        // Namespaces are separated with a '.'
        string stFullName = (stNamespace == "") ? 
            (m_strName) :
            (stNamespace + "." + m_strName);

        // Are we a nested class? 
        if (scopeParent.Node is ClassDecl)
        {
            Debug.Assert(stNamespace != "");
            stFullName = stNamespace + "+" + m_strName;
        }                    

        // Create a stub sym entry to add to current scope
        m_symbol = new TypeEntry(stFullName, this, m_genre, scopeParent);
        scopeParent.AddSymbol(m_symbol);
        
        // Stub on nested types
        //s.PushScope(m_symbol.MemberScope);
        
        // Our context is the same as the scope on our symbol
        Scope context = m_symbol.MemberScope;
        Debug.Assert(context != null);
        
        s.SetCurrentClass(m_symbol);
                    
        foreach(TypeDeclBase t in this.m_alNestedTypes)
        {   
            t.ResolveTypesAsBlueStub(s, stFullName, context);
        }
        
        s.SetCurrentClass(null);
        //s.PopScope(m_symbol.MemberScope);
    }
#endregion

#region Resolve Type as CLR

    // Called after we've resolved as a blue type
    // Pair this type with a CLR type obtained via the Provider
    // Recursively call on all inherited types (base class & interfaces)
    public override void ResolveTypesAsCLR(
        ISemanticResolver s,
        ICLRtypeProvider provider
        )
    {
        // Since this can be called recursively, bail if we're already resolved.
        if (this.Symbol.IsInit)
            return;
        
        
        // S is already set to the context that we're evaluating in.
        Scope prev = s.SetCurrentContext(this.Symbol.MemberScope.LexicalParent);
        
        FixBaseTypes(s, provider); // this is recursive        
        CreateCLRType(s, provider);
        
        s.RestoreContext(prev);
    }

    // Now that all the types have been stubbed and established their context,
    // we can recursively run through and resolve all of our base types.
    void FixBaseTypes(
        ISemanticResolver s,  
        ICLRtypeProvider provider
    )
    {
        TypeEntry tSuper = null;
        
        BeginCheckCycle(s);
        
        ArrayList alInterfaces = new ArrayList();
        
        // Decide who our super class is and which interfaces we're inheriting
        foreach(TypeSig sig in this.m_arSuper)
        {
            sig.ResolveType(s);
            
            TypeEntry t = sig.BlueType;
            
            // Make sure this base type is resolved. Do this recursively
            ClassDecl c = t.Node;
            if (c != null)
            {
                c.ResolveTypesAsCLR(s, provider);
            }
            
            if (t.IsClass)
            {
                Debug.Assert(this.IsClass, "Only a class can have a super-class");
                
                if (tSuper != null)
                {
                    ThrowError(SymbolError.OnlySingleInheritence(this));                
                }
                tSuper = t;
            } else {
                // Both structs & interfaces can only derive from interfaces (not classes)
                if (!t.IsInterface)
                    ThrowError(SymbolError.MustDeriveFromInterface(this, t));
                alInterfaces.Add(t);
            }
        }
        
        TypeEntry [] tInterfaces = new TypeEntry[alInterfaces.Count];
        for(int i = 0; i < alInterfaces.Count; i++)
            tInterfaces[i] = (TypeEntry) alInterfaces[i];
        
        // If no super class is specified, then we use as follows:
        // 'Interface' has no super class,
        // 'Class'     has 'System.Object'
        // 'Struct'    has 'System.ValueType'        
        if (!IsInterface && (tSuper == null))
        {
            if (IsClass)
                tSuper = s.ResolveCLRTypeToBlueType(typeof(object));
            if (IsStruct)
                tSuper = s.ResolveCLRTypeToBlueType(typeof(System.ValueType));                
        }
        
        
        Debug.Assert(IsInterface ^ (tSuper != null));

        // Just to sanity check, make sure the symbol stub is still there
        #if DEBUG               
        TypeEntry sym = (TypeEntry) s.GetCurrentContext().LookupSymbolInThisScopeOnly(m_strName);        
        Debug.Assert(sym == m_symbol);
        #endif

        m_symbol.InitLinks(tSuper, tInterfaces);
                
        // Make sure all of our base types are resolved        
        foreach(TypeEntry t in this.Symbol.BaseInterfaces)
        {               
            t.EnsureResolved(s);
        }
            
        if (Symbol.Super != null)                   
            Symbol.Super.EnsureResolved(s);
                
        // Final call. Set super scope
        m_symbol.FinishInit();
        
        
        EndCheckCycle();
    }
    
    // Flag to help check for cyclical dependencies
    bool m_fIsResolving;
    
    protected void BeginCheckCycle(
        ISemanticResolver s
    )
    {
        // This may get called mutliple times (since we call it recursively,
        // and we may have multiple derived classes). But it shouldn't 
        // get called from itself (which would imply circular reference)
        if (m_fIsResolving)
        {
            ThrowError(SymbolError.CircularReference(this.Symbol));
            /*
            s.ThrowError(SemanticChecker.Code.cCircularReference,
                this.Location, "Type '" + this.Symbol.FullName + "' is in a circular reference");
            */                
        }
        m_fIsResolving = true;
    }
    
    protected void EndCheckCycle()
    {
        m_fIsResolving = false;
    }
    
        
    // Requires that all of our base types have been resolved.
    void CreateCLRType(
        ISemanticResolver s,
        ICLRtypeProvider provider)
    {
    // Should have already resolved as a blue type
        Debug.Assert(this.Symbol != null);

        BeginCheckCycle(s);

        // Now that all of our dependent classes have their clr type set,
        // we can go ahead and set ours.
        // Note that a derived class may have already set ours, so we have
        // to check
        if (Symbol.CLRType == null)
        {
            // Get the clr type and then update the symbol engine
            this.Symbol.SetCLRType(provider);
            s.AddClrResolvedType(this.Symbol);
        }
        Debug.Assert(this.Symbol.CLRType != null);

        // Nested classes
        foreach(TypeDeclBase t in this.m_alNestedTypes)
        {
            t.ResolveTypesAsCLR(s, provider);        
        }

        EndCheckCycle();
    }

#endregion // resolution

#region Resolve Members
    
    // Make sure that all of our base types are resolved.
    void FixBaseMemberDecls(ISemanticResolver s, ICLRtypeProvider provider)
    {   
        if (this.IsClass)
        {
            if (this.Symbol.Super.Node != null)
                this.Symbol.Super.Node.ResolveMemberDecls(s, provider);
        }
                
        foreach(TypeEntry t in this.Symbol.BaseInterfaces)
        {
            if (t.Node != null)
                t.Node.ResolveMemberDecls(s, provider);
        }
    }

    // Resolve all the fields in this type. Only class/struct should call
    // this. 
    void FixFields(ISemanticResolver s, ICLRtypeProvider provider)
    {
        Debug.Assert(!IsInterface);
        
        int cInstance = 0;
        int cStatic = 0;

        foreach(FieldDecl f in m_alFields)
        {
            f.ResolveMember(m_symbol, s, provider);
            //f.Symbol.SetInfo(provider);

            if (f.InitialExp != null)
                if (f.Mods.IsStatic) 
                    cStatic++; 
                else 
                    cInstance++;
        }


        Statement [] stmtStatic = new Statement[cStatic];
        Statement [] stmtInstance = new Statement[cInstance];

        cStatic = 0;
        cInstance = 0;
        // Fields can have assignments. Make 2 helper functions to do
        // assignment for static & instance fields
        foreach(FieldDecl f in m_alFields)
        {
            if (f.InitialExp != null)
            {           
                Statement stmt = new ExpStatement(new AssignStmtExp(
                    new SimpleObjExp(new Identifier(f.Name, f.Location)), f.InitialExp));

                if (f.Mods.IsStatic)
                {
                    stmtStatic[cStatic] = stmt;
                    cStatic++;
                } 
                else 
                {
                    if (IsStruct)
                    {
                        //ThrowError_NoFieldInitForStructs(s, f);
                        ThrowError(SymbolError.NoFieldInitForStructs(f));
                    }
                    
                    stmtInstance[cInstance] = stmt;
                    cInstance ++;
                }
            } // end has initializer expression
        }

        Debug.Assert(cStatic == stmtStatic.Length);
        Debug.Assert(cInstance == stmtInstance.Length);

        // Create methods to initialize the static & instance fields.
        // Then the ctors can call these methods
        if (cStatic != 0)
        {
            Modifiers mods = new Modifiers();
            mods.SetStatic();
            mods.SetPrivate();
            
            m_nodeStaticInit = new MethodDecl(
                new Identifier(".StaticInit", this.Location), 
                new ResolvedTypeSig(typeof(void), s),                    
                new ParamVarDecl[0],
                new BlockStatement(null, stmtStatic),                     
                mods
                );

            //AddMethodToList(m_nodeStaticInit);
        } 
        if (cInstance != 0)
        {   
            Modifiers mods = new Modifiers();
            mods.SetPrivate();
            
            m_nodeInstanceInit = new MethodDecl(
                new Identifier(".InstanceInit", this.Location),                     
                new ResolvedTypeSig(typeof(void), s),
                new ParamVarDecl[0],
                new BlockStatement(null, stmtInstance),                     
                mods
                );
            AddMethodToList(m_nodeInstanceInit);
        }        
    } // end fields
    
    // Debug only, make sure that we don't add methods after we start resolving them.
    #if DEBUG
    bool m_fLockMethodList;
    #endif
    
    void FixMethods(
        ISemanticResolver s,
        ICLRtypeProvider provider
    )
    {        
        #if DEBUG
        Debug.Assert(!m_fLockMethodList);
        m_fLockMethodList = true;
        #endif
        
        // Resolve all methods, do some inheritence checks too:
        // - if a class has any abstract members, it must be abstract        
        bool fHasAbstractMember = false;
        foreach(MethodDecl m in m_alMethods)
        {
            // set provider=null since we have to tweak members based off inheritence checks
            m.ResolveMember(m_symbol, s, null);            
            if (m.Mods.IsAbstract)
                fHasAbstractMember = true;
        }
        
        Debug.Assert(!fHasAbstractMember || !this.IsStruct, "Only classes / interfaces can have abstract members");
        
        // If we have any abstract members, then the class must be abstract
        if (fHasAbstractMember && !this.Mods.IsAbstract)            
            PrintError(SymbolError.ClassMustBeAbstract(this));
                        
        
        // Do some checks that will modify how we create the CLR type.
        if (!IsInterface)
        {            
            // Make sure that we implement all methods from all the interfaces
            // that we inherit from
            foreach(TypeEntry t in this.Symbol.BaseInterfaces)
                EnsureMethodsImplemented(s, t);
        }
                
        foreach(MethodDecl m in m_alMethods)
        {            
            m.Symbol.SetInfo(provider);
            // If a method is 'override', an exact match must exist in a super clas that:
            //      a) is marked 'override' also
            //      b) is marked 'virtual'
            if (m.Mods.IsOverride)
   

⌨️ 快捷键说明

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