Clean up semantics of invoking ResolveMemberAccess.
[mono.git] / mcs / mbas / location.cs
index 308778f6cb23a1849d2044b17568a0a2ce592607..c930229c789c4749dff2b53b68e18e342c1aa327 100644 (file)
-//
-// location.cs: Keeps track of the location of source code entity
-//
-// Author:
-//   Miguel de Icaza
-//
-// (C) 2001 Ximian, Inc.
-//
-
-using System;
-using System.IO;
-using System.Collections;
-using System.Diagnostics.SymbolStore;
-
-namespace Mono.MonoBASIC {
-
-       /// <summary>
-       ///   Keeps track of the location in the program
-       /// </summary>
-       ///
-       /// <remarks>
-       ///   This uses a compact representation and a couple of auxiliary
-       ///   structures to keep track of tokens to (file,line) mappings.
-       ///
-       ///   We could probably also keep track of columns by storing those
-       ///   in 8 bits (and say, map anything after char 255 to be `255+').
-       /// </remarks>
-       public struct Location {
-               public int token; 
-
-               static Hashtable map;
-               static Hashtable sym_docs;
-               static ArrayList list;
-               static int global_count;
-               static int module_base;
-
-               public readonly static Location Null;
-               
-               static Location ()
-               {
-                       map = new Hashtable ();
-                       list = new ArrayList ();
-                       sym_docs = new Hashtable ();
-                       global_count = 0;
-                       module_base = 0;
-                       Null.token = -1;
-               }
-
-               static public void Push (string name)
-               {
-                       map.Remove (global_count);
-                       map.Add (global_count, name);
-                       list.Add (global_count);
-                       module_base = global_count;
-               }
-               
-               public Location (int row, int col)
-               {
-                       if (row < 0 || col <  0)
-                               token = -1;
-                       else {
-                               if (col > 255)
-                                       col = 255;
-                               token = module_base + (row << 8) + col;
-                               if (global_count < token)
-                                       global_count = token;
-                       }
-               }
-
-               public override string ToString ()
-               {
-                       return Name + ": (" + Row + ")";
-               }
-               
-               /// <summary>
-               ///   Whether the Location is Null
-               /// </summary>
-               static public bool IsNull (Location l)
-               {
-                       return l.token == -1;
-               }
-
-               public string Name {
-                       get {
-                               int best = 0;
-                               
-                               if (token < 0)
-                                       return "Internal";
-
-                               foreach (int b in list){
-                                       if (token > b)
-                                               best = b;
-                               }
-                               return (string) map [best];
-                       }
-               }
-
-               public int Row {
-                       get {
-                               int best = 0;
-                               
-                               if (token < 0)
-                                       return 1;
-                               
-                               foreach (int b in list){
-                                       if (token > b)
-                                               best = b;
-                               }
-                               return (token - best) >> 8;
-                       }
-               }
-
-               public int Col {
-                       get {
-                               int best = 0;
-                               
-                               if (token < 0)
-                                       return 1;
-                               
-                               foreach (int b in list){
-                                       if (token > b)
-                                               best = b;
-                               }
-                               return (token - best) & 0xFF;
-                       }
-               }
-
-               // The ISymbolDocumentWriter interface is used by the symbol writer to
-               // describe a single source file - for each source file there's exactly
-               // one corresponding ISymbolDocumentWriter instance.
-               //
-               // This class has an internal hash table mapping source document names
-               // to such ISymbolDocumentWriter instances - so there's exactly one
-               // instance per document.
-               //
-               // This property returns the ISymbolDocumentWriter instance which belongs
-               // to the location's source file.
-               //
-               // If we don't have a symbol writer, this property is always null.
-               public ISymbolDocumentWriter SymbolDocument {
-                       get {
-                               ISymbolWriter sw = CodeGen.SymbolWriter;
-                               ISymbolDocumentWriter doc;
-
-                               if (token < 0)
-                                       return null;
-
-                               // If we don't have a symbol writer, return null.
-                               if (sw == null)
-                                       return null;
-
-                               string path = Path.GetFullPath (Name);
-
-                               if (sym_docs.Contains (path))
-                                       // If we already created an ISymbolDocumentWriter
-                                       // instance for this document, return it.
-                                       doc = (ISymbolDocumentWriter) sym_docs [path];
-                               else {
-                                       // Create a new ISymbolDocumentWriter instance and
-                                       // store it in the hash table.
-                                       doc = sw.DefineDocument (path, SymLanguageType.Basic,
-                                                                SymLanguageVendor.Microsoft,
-                                                                SymDocumentType.Text);
-
-                                       sym_docs.Add (path, doc);
-                               }
-
-                               return doc;
-                       }
-               }
-       }
-}
+//\r
+// location.cs: Keeps track of the location of source code entity\r
+//\r
+// Author:\r
+//   Miguel de Icaza\r
+//\r
+// (C) 2001 Ximian, Inc.\r
+//\r
+\r
+using System;\r
+using System.IO;\r
+using System.Collections;\r
+using System.Diagnostics.SymbolStore;\r
+\r
+namespace Mono.MonoBASIC {\r
+\r
+       /// <summary>\r
+       ///   Keeps track of the location in the program\r
+       /// </summary>\r
+       ///\r
+       /// <remarks>\r
+       ///   This uses a compact representation and a couple of auxiliary\r
+       ///   structures to keep track of tokens to (line, col, file) mappings.\r
+       ///\r
+       public struct Location {\r
+               const int NUM_ROW_BITS = 16;\r
+               const int NUM_COL_BITS =  8;\r
+               const int NUM_FILE_BITS = (32-NUM_ROW_BITS-NUM_COL_BITS);\r
+               \r
+               const int NUM_FILE_SHIFTS = 0;\r
+               const int NUM_ROW_SHIFTS = NUM_FILE_BITS;\r
+               const int NUM_COL_SHIFTS =  NUM_ROW_BITS+NUM_FILE_BITS;\r
+\r
+               const int FILE_MASK = (1<<NUM_FILE_BITS)-1;\r
+               const int ROW_MASK = ((1<<NUM_ROW_BITS)-1)<<NUM_FILE_BITS;\r
+               const int COL_MASK = ((1<<NUM_COL_BITS)-1)<<(NUM_ROW_BITS+NUM_FILE_BITS);\r
+               \r
+               public int token; // ordered triplet: (Row, Col, File Index)\r
+\r
+               static ArrayList source_list;\r
+               static Hashtable source_files;\r
+               static int source_count;\r
+               static int current_source;\r
+               static Hashtable sym_docs;\r
+\r
+               public readonly static Location Null;\r
+               \r
+               static Location ()\r
+               {\r
+                       source_files = new Hashtable ();\r
+                       source_list = new ArrayList ();\r
+                       current_source = 0;\r
+                       sym_docs = new Hashtable ();\r
+                       Null.token = 0;\r
+               }\r
+\r
+               static public void SetCurrentSource(string name)\r
+               {\r
+                       int index;\r
+                       \r
+                       if (!source_files.Contains (name)) {\r
+                               index = ++source_count;\r
+                               source_files.Add (name, index);\r
+                               source_list.Add (name);\r
+                       }\r
+                       else {\r
+                               index = (int)source_files[name];\r
+                       }\r
+\r
+                       current_source = index;\r
+               }\r
+               \r
+               public Location (int row, int col)\r
+               {\r
+                       if (row < 0 || col <  0)\r
+                               token = 0;\r
+                       else {\r
+                               if (col > 255)\r
+                                       col = 255;\r
+                               token = (current_source<<NUM_FILE_SHIFTS) + (row<<NUM_ROW_SHIFTS) + (col<<NUM_COL_SHIFTS);\r
+                       }\r
+               }\r
+\r
+               public override string ToString ()\r
+               {\r
+                       return Name + ": (" + Row + ")";\r
+               }\r
+               \r
+               static public bool IsNull (Location l)\r
+               {\r
+                       return l.token == 0;\r
+               }\r
+\r
+               public string Name {\r
+                       get {\r
+                               if(token == 0)\r
+                                       return "Internal";\r
+\r
+                               int index = (token & FILE_MASK)>>NUM_FILE_SHIFTS;\r
+                               string file = (string) source_list [index - 1];\r
+                               return file;\r
+                       }\r
+               }\r
+\r
+               public int Row {\r
+                       get {\r
+                               if (token == 0)\r
+                                       return 1;\r
+\r
+                               return (token & ROW_MASK)>>NUM_ROW_SHIFTS;\r
+                       }\r
+               }\r
+\r
+               public int Col {\r
+                       get {\r
+                               if (token == 0)\r
+                                       return 1;\r
+                               \r
+                               return (token & COL_MASK)>>NUM_COL_SHIFTS;\r
+                       }\r
+               }\r
+\r
+               // The ISymbolDocumentWriter interface is used by the symbol writer to\r
+               // describe a single source file - for each source file there's exactly\r
+               // one corresponding ISymbolDocumentWriter instance.\r
+               //\r
+               // This class has an internal hash table mapping source document names\r
+               // to such ISymbolDocumentWriter instances - so there's exactly one\r
+               // instance per document.\r
+               //\r
+               // This property returns the ISymbolDocumentWriter instance which belongs\r
+               // to the location's source file.\r
+               //\r
+               // If we don't have a symbol writer, this property is always null.\r
+               public ISymbolDocumentWriter SymbolDocument {\r
+                       get {\r
+                               ISymbolWriter sw = CodeGen.SymbolWriter;\r
+                               ISymbolDocumentWriter doc;\r
+\r
+                               if (token < 0)\r
+                                       return null;\r
+\r
+                               // If we don't have a symbol writer, return null.\r
+                               if (sw == null)\r
+                                       return null;\r
+\r
+                               string path = Path.GetFullPath (Name);\r
+\r
+                               if (sym_docs.Contains (path))\r
+                                       // If we already created an ISymbolDocumentWriter\r
+                                       // instance for this document, return it.\r
+                                       doc = (ISymbolDocumentWriter) sym_docs [path];\r
+                               else {\r
+                                       // Create a new ISymbolDocumentWriter instance and\r
+                                       // store it in the hash table.\r
+                                       doc = sw.DefineDocument (path, SymLanguageType.Basic,\r
+                                                                SymLanguageVendor.Microsoft,\r
+                                                                SymDocumentType.Text);\r
+\r
+                                       sym_docs.Add (path, doc);\r
+                               }\r
+\r
+                               return doc;\r
+                       }\r
+               }\r
+       }\r
+}\r