* roottypes.cs: Rename from tree.cs.
[mono.git] / mcs / mbas / location.cs
1 //\r
2 // location.cs: Keeps track of the location of source code entity\r
3 //\r
4 // Author:\r
5 //   Miguel de Icaza\r
6 //\r
7 // (C) 2001 Ximian, Inc.\r
8 //\r
9 \r
10 using System;\r
11 using System.IO;\r
12 using System.Collections;\r
13 using System.Diagnostics.SymbolStore;\r
14 \r
15 namespace Mono.MonoBASIC {\r
16 \r
17         /// <summary>\r
18         ///   Keeps track of the location in the program\r
19         /// </summary>\r
20         ///\r
21         /// <remarks>\r
22         ///   This uses a compact representation and a couple of auxiliary\r
23         ///   structures to keep track of tokens to (line, col, file) mappings.\r
24         ///\r
25         public struct Location {\r
26                 const int NUM_ROW_BITS = 16;\r
27                 const int NUM_COL_BITS =  8;\r
28                 const int NUM_FILE_BITS = (32-NUM_ROW_BITS-NUM_COL_BITS);\r
29                 \r
30                 const int NUM_FILE_SHIFTS = 0;\r
31                 const int NUM_ROW_SHIFTS = NUM_FILE_BITS;\r
32                 const int NUM_COL_SHIFTS =  NUM_ROW_BITS+NUM_FILE_BITS;\r
33 \r
34                 const int FILE_MASK = (1<<NUM_FILE_BITS)-1;\r
35                 const int ROW_MASK = ((1<<NUM_ROW_BITS)-1)<<NUM_FILE_BITS;\r
36                 const int COL_MASK = ((1<<NUM_COL_BITS)-1)<<(NUM_ROW_BITS+NUM_FILE_BITS);\r
37                 \r
38                 public int token; // ordered triplet: (Row, Col, File Index)\r
39 \r
40                 static ArrayList source_list;\r
41                 static Hashtable source_files;\r
42                 static int source_count;\r
43                 static int current_source;\r
44                 static Hashtable sym_docs;\r
45 \r
46                 public readonly static Location Null;\r
47                 \r
48                 static Location ()\r
49                 {\r
50                         source_files = new Hashtable ();\r
51                         source_list = new ArrayList ();\r
52                         current_source = 0;\r
53                         sym_docs = new Hashtable ();\r
54                         Null.token = 0;\r
55                 }\r
56 \r
57                 static public void SetCurrentSource(string name)\r
58                 {\r
59                         int index;\r
60                         \r
61                         if (!source_files.Contains (name)) {\r
62                                 index = ++source_count;\r
63                                 source_files.Add (name, index);\r
64                                 source_list.Add (name);\r
65                         }\r
66                         else {\r
67                                 index = (int)source_files[name];\r
68                         }\r
69 \r
70                         current_source = index;\r
71                 }\r
72                 \r
73                 public Location (int row, int col)\r
74                 {\r
75                         if (row < 0 || col <  0)\r
76                                 token = 0;\r
77                         else {\r
78                                 if (col > 255)\r
79                                         col = 255;\r
80                                 token = (current_source<<NUM_FILE_SHIFTS) + (row<<NUM_ROW_SHIFTS) + (col<<NUM_COL_SHIFTS);\r
81                         }\r
82                 }\r
83 \r
84                 public override string ToString ()\r
85                 {\r
86                         return Name + ": (" + Row + ")";\r
87                 }\r
88                 \r
89                 static public bool IsNull (Location l)\r
90                 {\r
91                         return l.token == 0;\r
92                 }\r
93 \r
94                 public string Name {\r
95                         get {\r
96                                 if(token == 0)\r
97                                         return "Internal";\r
98 \r
99                                 int index = (token & FILE_MASK)>>NUM_FILE_SHIFTS;\r
100                                 string file = (string) source_list [index - 1];\r
101                                 return file;\r
102                         }\r
103                 }\r
104 \r
105                 public int Row {\r
106                         get {\r
107                                 if (token == 0)\r
108                                         return 1;\r
109 \r
110                                 return (token & ROW_MASK)>>NUM_ROW_SHIFTS;\r
111                         }\r
112                 }\r
113 \r
114                 public int Col {\r
115                         get {\r
116                                 if (token == 0)\r
117                                         return 1;\r
118                                 \r
119                                 return (token & COL_MASK)>>NUM_COL_SHIFTS;\r
120                         }\r
121                 }\r
122 \r
123                 // The ISymbolDocumentWriter interface is used by the symbol writer to\r
124                 // describe a single source file - for each source file there's exactly\r
125                 // one corresponding ISymbolDocumentWriter instance.\r
126                 //\r
127                 // This class has an internal hash table mapping source document names\r
128                 // to such ISymbolDocumentWriter instances - so there's exactly one\r
129                 // instance per document.\r
130                 //\r
131                 // This property returns the ISymbolDocumentWriter instance which belongs\r
132                 // to the location's source file.\r
133                 //\r
134                 // If we don't have a symbol writer, this property is always null.\r
135                 public ISymbolDocumentWriter SymbolDocument {\r
136                         get {\r
137                                 ISymbolWriter sw = CodeGen.SymbolWriter;\r
138                                 ISymbolDocumentWriter doc;\r
139 \r
140                                 if (token < 0)\r
141                                         return null;\r
142 \r
143                                 // If we don't have a symbol writer, return null.\r
144                                 if (sw == null)\r
145                                         return null;\r
146 \r
147                                 string path = Path.GetFullPath (Name);\r
148 \r
149                                 if (sym_docs.Contains (path))\r
150                                         // If we already created an ISymbolDocumentWriter\r
151                                         // instance for this document, return it.\r
152                                         doc = (ISymbolDocumentWriter) sym_docs [path];\r
153                                 else {\r
154                                         // Create a new ISymbolDocumentWriter instance and\r
155                                         // store it in the hash table.\r
156                                         doc = sw.DefineDocument (path, SymLanguageType.Basic,\r
157                                                                  SymLanguageVendor.Microsoft,\r
158                                                                  SymDocumentType.Text);\r
159 \r
160                                         sym_docs.Add (path, doc);\r
161                                 }\r
162 \r
163                                 return doc;\r
164                         }\r
165                 }\r
166         }\r
167 }\r