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

📄 semanticchecker.cs

📁 charp compiler
💻 CS
📖 第 1 页 / 共 3 页
字号:
        int i       = s.IndexOf('.');            
        
        // Search past namespaces
        while(i != -1) 
        {                
            string stNamespace = s.Substring(iStart, i - iStart);
            SymEntry sym = LookupSymbol(scope, stNamespace, false);
                                               
            if (sym == null) 
            {            
                ImportedNamespaceEntry nsImported = new ImportedNamespaceEntry(
                    stNamespace, 
                    s.Substring(0, i)
                    );
                    
                scope.AddSymbol(nsImported);
                    
                scope = nsImported.ChildScope;
            } 
            else 
            {
                // If the symbol already exists, must be a namespace                    
                if (sym is NamespaceEntry) 
                {
                    scope = ((NamespaceEntry) sym).ChildScope;
                } 
                else 
                {
                    ThrowError(SymbolError.IllegalAssembly(tImport.Assembly, "Illegal type: " + s));
                }
            }
            iStart = i + 1;
            i = s.IndexOf('.', iStart);
        }
                   
        // If we're not a nested type, then we can return the scope now
        if (tImport.DeclaringType == null)                   
        {
            Debug.Assert(s.Substring(iStart) == tImport.Name);
            return scope;
        }
        
        // Containing class should have already been added.
        Debug.Assert(TryLookupCLRType(tImport.DeclaringType) != null);
                        
        // Else we have to traverse the class scopes to find out containing scope.        
        // n.n. c1+c2
        i = s.IndexOf('+', iStart);   
        while (i != -1)
        {
            string stClass = s.Substring(iStart, i - iStart);
            
            TypeEntry tBlue = (TypeEntry) LookupSymbol(scope, stClass, true);
            scope = tBlue.MemberScope;
            Debug.Assert(scope != null);
        
            iStart = i + 1;
            i = s.IndexOf('+', iStart);        
        }
        
        Debug.Assert(s.Substring(iStart) == tImport.Name);
        
        return scope;
    }

    // Test to tell if a given type is generic. 
    static bool IsGenericType(System.Type t)
    {
        // Since Blue must compile on v1.1 CLR, the methods on Type to explicitly ask if it's generic are not available.
        // So we use this hack: Generic types in C# have a backtick (`) before the type parameter.

        return t.FullName.IndexOf('`') > 0;
    }

//-----------------------------------------------------------------------------
// Helper to import the specific type and return a TypeEntry. 
// This will recursively import all base types.
// Returns null if we can't import the type.
//-----------------------------------------------------------------------------         
    protected TypeEntry AddImportedType(System.Type tImport)
    {     
        #if true   
        // Don't import non-public classes
        // be wary of nesting
        //if (tImport.IsClass || tImport.IsValueType)
        {
            if (tImport.DeclaringType == null)
            {
                // Not nested
                if (!tImport.IsPublic)
                    return null;
            } else {
                // If Nested, check topmost containing class.
                System.Type t = tImport;
                while (t.DeclaringType != null)
                {
                    t = t.DeclaringType;
                }
                if (!t.IsPublic)
                    return null;            
            }
        }
        #endif
                    
        // If we've already imported this, then nothing to do.   
        {
            TypeEntry t = TryLookupCLRType(tImport);
            if (t != null)
                return t;
        }
        
        // Blue doesn't handle Generics (from V2.0 CLR), so just ignore them when imported.
        if (IsGenericType(tImport))
        {
            Console.WriteLine("Skipping Generic type:" + tImport.FullName);
            return null;
        }

        #if false
        // Debugging facility. Userbreakpoint when we import a specific class.
        if (tImport.Name == "IDictionaryEnumerator")
            System.Diagnostics.Debugger.Break();
        #endif
        
        // Stub immediately to avoid infinite cycles.        
        TypeEntry tBlue = TypeEntry.CreateImportStub(tImport);
        m_hashClrType.Add(tImport, tBlue);
                
        // If we're a nested type, make sure our containing type is imported.                        
        if (tImport.DeclaringType != null)
        {
            AddImportedType(tImport.DeclaringType);
        }
                      
        
        Scope scope = this.CreateImportedContext(tImport);
                             
        
        string stClass = tImport.Name;     
        
        // Already check for multiple imports       
        //if (LookupSymbol(scope, stClass, false) == null)
        {           
            
            // Add Base class
            TypeEntry tSuper = null;            
            if (tImport.BaseType != null)
            {                
                tSuper = AddImportedType(tImport.BaseType);
            }
                
            // Add interfaces, removing all interfaces that we can't access
            System.Type [] tCLRInterfaces = tImport.GetInterfaces();
            ArrayList al = new ArrayList(tCLRInterfaces.Length);            
            
            foreach(System.Type tInterface in tCLRInterfaces)
            {                
                TypeEntry t = AddImportedType(tInterface);
                if (t != null)
                    al.Add(t);
            }
            TypeEntry [] tBlueInterfaces = (TypeEntry[]) al.ToArray(typeof(TypeEntry));
            
            TypeEntry tParent = (tImport.DeclaringType == null) ? 
                null :
                this.ResolveCLRTypeToBlueType(tImport.DeclaringType);
                       
            // @todo - do we have to check if we've been imported again?
            
            // We create the symbol, but don't add the scope until we need to.
            // (else that would be a lot of scopes to add that we'd never use)
            // Note that this must be done on the same reference that we added at the top
            // because by now, the other types have links to that original reference.
            tBlue.FinishImportStub(tSuper, tBlueInterfaces, tParent);
            scope.AddSymbol(tBlue);
                
            
#if true   
            // If we have any nested classes, add them.
            // This will require us to create the class scope.            
            System.Type [] tNestedTypes = tImport.GetNestedTypes(BindingFlags.Public | BindingFlags.NonPublic);
            if (tNestedTypes.Length > 0)
            {
                tBlue.EnsureScopeCreated();
                foreach(System.Type tNested in tNestedTypes)
                {                
                    AddImportedType(tNested);
                }
            }
#endif            
            return tBlue;
        } 
        /*
        else 
        {            
            ThrowError(SymbolError.IllegalAssembly(tImport.Assembly, 
                "Class '" + tImport.FullName + "' defined multiple times"));
            return null;
        }
        */
    
    } // end function

//-----------------------------------------------------------------------------
// Populate the symbol table with just the TypeEntry for all classes exposed
// through the given assembly. (Implicitly, this will add ImportedNamespaceEntries)
// The actual TypeEntry scopes will be populated on first access
//-----------------------------------------------------------------------------
    protected void ImportAssembly(Assembly a)
    {        
        // LoadFrom used for exact filename
        // Load will look in the gac, etc        
        Log.WriteLine(Log.LF.Verbose, "Importing assembly:" + a.ToString());
        
        Type [] typeList = a.GetTypes();
        
        foreach(Type t in typeList)
        {   
            if (t.IsNotPublic)
                continue;
            AddImportedType(t);        
        }
    
    } // end ImportAssembly
               
    protected Assembly GetMscorlib()
    {
        return Assembly.Load("mscorlib.dll");
    }
#endregion               
           
    Scope m_scopeGlobal;

#region Mapping between CLR & Blue types        
//-----------------------------------------------------------------------------        
// Resolve a CLR type to a Blue Type
// How to handle array types?
//-----------------------------------------------------------------------------
    public TypeEntry ResolveCLRTypeToBlueType(System.Type t)
    {
        Debug.Assert(t != null);
        Debug.Assert(!IsGenericType(t), "Can't resolve CLR generic type:" + t.FullName);
        if (t.IsArray)
        {        
            ArrayTypeEntry a = new ArrayTypeEntry(t, this);
            return a;
        }
        if (t.IsByRef)
        {
            System.Type clrElem = t.GetElementType();
            TypeEntry blueElem = ResolveCLRTypeToBlueType(clrElem);
            return new RefTypeEntry(blueElem, this);
        }
        
        TypeEntry type = (TypeEntry) m_hashClrType[t];
        Debug.Assert(type != null, "type '" + t.ToString() + "' is unresolve in blue");
        
        if (type == null)
        {
            Console.WriteLine("Dump: [");
            IDictionaryEnumerator e = m_hashClrType.GetEnumerator();
            while(e.MoveNext())
            {                
                Console.WriteLine("{0}\t\t{1}", e.Key, e.Value);
            }
            Console.WriteLine("] End Dump");
        }
        return type;
    }
    
    // Return the Blue type for the clr interface 
    // May return null if we haven't added it yet.
    protected TypeEntry TryLookupCLRType(System.Type t)
    {
        //Debug.Assert(t.IsInterface);
        
        TypeEntry type = (TypeEntry) m_hashClrType[t];
        return type;
    }

    public void AddClrResolvedType(TypeEntry sym)
    {
        Debug.Assert(sym != null);
        Debug.Assert(sym.CLRType != null);

        // Make sure the blue & CLR types actually match.
        Debug.Assert(sym.FullName == sym.CLRType.FullName);

        ///////
        System.Type tEnum = sym.CLRType;
        /*
        int iEnum1 = tEnum.GetHashCode();
        int iEnum2 = ((object) tEnum).GetHashCode();
        
        int iInt1 = typeof(int).GetHashCode();
        int iInt2 = ((object) typeof(int)).GetHashCode();
        
        bool fFlag1 = Object.Equals(tEnum, typeof(int));
        bool fFlag2 = Object.Equals(typeof(int), tEnum);
        
        bool f3 = (tEnum == typeof(int));
        bool f4 = (typeof(int) == tEnum);
        */
        //////////
        try
        {
            m_hashClrType.Add(sym.CLRType, sym);
        }
        catch (System.Exception e)
        {
            object o = m_hashClrType[sym.CLRType];
            Debug.Assert(false, "Exception:"+ e.Message);
            
        }
    }

    //-----------------------------------------------------------------------------
    // ...
    // Another bug in the frameworks (10/29/01). System.Type has bad implementions
    // of GetHashCode() and Equals() that make them unsuitable for use with
    // a Hashtable. In particular, a TypeBuilder on an enum is viewed the same
    // as the it's underlying type.
    // So we have to have our own comparer that actually works.
    //-----------------------------------------------------------------------------
    
    class TypeHashProvider : IComparer, IHashCodeProvider
    {   
        public virtual int GetHashCode(object obj)
        {
            return obj.ToString().GetHashCode();
        }

        // return 0 if (a==b), else 1
        public virtual int  Compare(object objA, object objB)
        {
            Debug.Assert(objA is Type);
            Debug.Assert(objB is Type);

#if false        
        int iActual = CompareFast(objA, objB);

#if DEBUG
        // Our comparison should be functionally equivalent to comparing

⌨️ 快捷键说明

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