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