public SymEntry EnsureSymbolType(SymEntry sym, System.Type tExpected, FileRange location) { if (sym == null) return null; /* Type tSym = sym.GetType(); if (tSym == tExpected) return sym; if (tSym.IsSubclassOf(tExpected)) return sym; */ bool fMatch = SymbolEngine.TypeEntry.IsAssignable(sym.GetType(), tExpected); if (fMatch) return sym; ThrowError(SymbolError.BadSymbolType(sym, tExpected, location)); /* this.ThrowError(Code.cBadSymbolType, location, "Symbol '" + sym.Name + "' must be of type '" + tExpected.ToString() + "', not '" + sym.GetType().ToString() + "'"); */ return sym; }
// We only need Lookup() during the resolve phase (because that's the only time // we need to convert text into symbols) // After that, we can just use the symbols directly // Lookup an entry in a specific scope // If it doesn't exist, then return null if !fMustExist and throw if fMustExist public SymEntry LookupSymbol(Scope scope, Identifier id, bool fMustExist) { SymEntry s = scope.LookupSymbol(id.Text); if (fMustExist && s == null) { ThrowError(SymbolError.UndefinedSymbol(id)); } return s; }
public virtual void EnsureAssignable( System.Type tFrom, System.Type tTo, FileRange location ) { bool fOk = TypeEntry.IsAssignable(tFrom, tTo); if (!fOk) { ThrowError(SymbolError.TypeMismatch(tFrom, tTo, location)); } }
// Lookup a symbol in the current context. // The context includes the lexical scope stack, super scopes, // and using directives // If it doesn't exist, then return null if !fMustExist and throw exception if fMustExist public virtual SymEntry LookupSymbolWithContext(Identifier id, bool fMustExist) { string strName = id.Text; // Search through stack of lexical scopes SymEntry sym = null; Scope t = m_CurrentContext; while(t != null) { sym = LookupSymbol(t, id, false); // <-- smart lookup, go through ILookupController if (sym != null) return sym; t = t.m_LexicalParent; } // Don't need this any more with ILookupControllers #if false // Check using directives if not found in the current scope stack // Do this by traversing the scope stack and looking for UserNamespaceEntry // (we can never be in an imported namespace, so that's ok) t = m_CurrentContext; while (t != null) { AST.NamespaceDecl node = t.Node as AST.NamespaceDecl; if (node != null) { sym = node.LookupSymbolInUsingDirectives(this, id); if (sym != null) return sym; } t = t.m_LexicalParent; } #endif // Symbol not found if (fMustExist) { //ThrowError_UndefinedSymbol(id); ThrowError(SymbolError.UndefinedSymbol(id)); } return null; }
// Get rid of this function public SymEntry LookupSymbol(Scope scope, string st, bool fMustExist) { SymEntry s = scope.LookupSymbol(st); bool f= false; if (f) { System.Xml.XmlWriter o = new System.Xml.XmlTextWriter(new System.IO.StreamWriter("dump.xml")); scope.Dump(o, true); o.Close(); } if (fMustExist && s == null) { FileRange range = new FileRange(); range.Filename = "<not specified>"; Identifier id = new Identifier(st, range); //ThrowError_UndefinedSymbol(id); ThrowError(SymbolError.UndefinedSymbol(id)); } return s; }
internal static int ERResolve(SymbolError.Code e) { return ((int) e) + 3000; }
internal ErrorException(SymbolError.Code e, FileRange location, string stMessage) : this(ERResolve(e), location, stMessage) { }
// @dogfood - if a parameter is of type 'code', then that gets confused with // the ErrorException get_Code Property from our base class. // For now, use a fully-qualified name. But we should fix this. //internal SymbolErrorException(Code c, FileRange location, string s) : internal SymbolErrorException(SymbolError.Code c, FileRange location, string s) : base (c, location, s) { // All Symbol errors will come through this body. }
static public void ThrowError(SymbolError.SymbolErrorException e) { Blue.Driver.StdErrorLog.ThrowError(e); }
// Shortcut helper functions. static public void PrintError(SymbolError.SymbolErrorException e) { Blue.Driver.StdErrorLog.PrintError(e); }
//----------------------------------------------------------------------------- // Create the scopes for an imported types //----------------------------------------------------------------------------- Scope CreateImportedContext(System.Type tImport) { // Traverse namespaces to find scope Scope scope = m_scopeGlobal; string s = tImport.ToString(); // In a type's string name, the '.' separates namespaces, // the '+' separates for nested classes. // Valid form: // i.i.i+i+i+i int iStart = 0; 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; }