Welcome to mirror list, hosted at ThFree Co, Russian Federation.

location.cs « mbas « mcs - github.com/mono/mono.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: 1b32f32de6e26126fb4dd22566d7569d7fdd3584 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
//
// location.cs: Keeps track of the location of source code entity
//
// Author:
//   Miguel de Icaza
//
// (C) 2001 Ximian, Inc.
//

using System;
using System.Collections;
using System.Diagnostics.SymbolStore;

namespace Mono.CSharp {
	/// <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)
		{
			if (row < 0)
				token = -1;
			else {
				token = module_base + row;
				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;
			}
		}

		// 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;

				if (sym_docs.Contains (Name))
					// If we already created an ISymbolDocumentWriter
					// instance for this document, return it.
					doc = (ISymbolDocumentWriter) sym_docs [Name];
				else {
					// Create a new ISymbolDocumentWriter instance and
					// store it in the hash table.
					doc = sw.DefineDocument (Name, SymLanguageType.CSharp,
								 SymLanguageVendor.Microsoft,
								 SymDocumentType.Text);

					sym_docs.Add (Name, doc);
				}

				return doc;
			}
		}
	}
}