(DISTFILES): Comment out a few missing files.
[mono-project.git] / mcs / class / Mono.CSharp.Debugger / MonoSymbolWriter.cs
blob10fc8ce88af4dc540bc18f96b2e457de9dbe26b5
1 //
2 // Mono.CSharp.Debugger/MonoSymbolWriter.cs
3 //
4 // Author:
5 // Martin Baulig (martin@ximian.com)
6 //
7 // This is the default implementation of the System.Diagnostics.SymbolStore.ISymbolWriter
8 // interface.
9 //
10 // (C) 2002 Ximian, Inc. http://www.ximian.com
14 // Permission is hereby granted, free of charge, to any person obtaining
15 // a copy of this software and associated documentation files (the
16 // "Software"), to deal in the Software without restriction, including
17 // without limitation the rights to use, copy, modify, merge, publish,
18 // distribute, sublicense, and/or sell copies of the Software, and to
19 // permit persons to whom the Software is furnished to do so, subject to
20 // the following conditions:
21 //
22 // The above copyright notice and this permission notice shall be
23 // included in all copies or substantial portions of the Software.
24 //
25 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
26 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
27 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
28 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
29 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
30 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
31 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
34 using System;
35 using System.Runtime.CompilerServices;
36 using System.Collections;
37 using System.IO;
39 namespace Mono.CompilerServices.SymbolWriter
41 public interface ISourceFile
43 SourceFileEntry Entry {
44 get;
48 public interface ISourceMethod
50 string Name {
51 get;
54 int NamespaceID {
55 get;
58 int Token {
59 get;
63 public class MonoSymbolWriter
65 protected ArrayList locals = null;
66 protected ArrayList methods = null;
67 protected ArrayList sources = null;
68 protected readonly MonoSymbolFile file;
69 private string filename = null;
71 LineNumberEntry [] current_method_lines;
72 int current_method_lines_pos = 0;
74 internal ISourceFile[] Sources {
75 get {
76 ISourceFile[] retval = new ISourceFile [sources.Count];
77 sources.CopyTo (retval, 0);
78 return retval;
82 private SourceMethod current_method = null;
85 // Interface IMonoSymbolWriter
88 public MonoSymbolWriter (string filename)
90 this.methods = new ArrayList ();
91 this.sources = new ArrayList ();
92 this.locals = new ArrayList ();
93 this.file = new MonoSymbolFile ();
95 this.filename = filename + ".mdb";
97 this.current_method_lines = new LineNumberEntry [50];
100 public void CloseNamespace ()
103 public void DefineLocalVariable (string name, byte[] signature)
105 if (current_method == null)
106 return;
108 current_method.AddLocal (name, signature);
111 public void MarkSequencePoint (int offset, int line, int column)
113 if (current_method == null)
114 return;
116 if (current_method_lines_pos == current_method_lines.Length) {
117 LineNumberEntry [] tmp = current_method_lines;
118 current_method_lines = new LineNumberEntry [current_method_lines.Length * 2];
119 Array.Copy (tmp, current_method_lines, current_method_lines_pos);
122 current_method_lines [current_method_lines_pos++] = new LineNumberEntry (line, offset);
125 public void OpenMethod (ISourceFile file, ISourceMethod method,
126 int startRow, int startColumn,
127 int endRow, int endColumn)
129 SourceMethod source = new SourceMethod (
130 file, method, startRow, startColumn, endRow, endColumn);
132 current_method = source;
133 methods.Add (current_method);
136 public void CloseMethod ()
138 current_method.SetLineNumbers (
139 current_method_lines, current_method_lines_pos);
140 current_method_lines_pos = 0;
142 current_method = null;
145 public SourceFileEntry DefineDocument (string url)
147 SourceFileEntry entry = new SourceFileEntry (file, url);
148 sources.Add (entry);
149 return entry;
152 public int DefineNamespace (string name, SourceFileEntry source,
153 string[] using_clauses, int parent)
155 if ((source == null) || (using_clauses == null))
156 throw new NullReferenceException ();
158 return source.DefineNamespace (name, using_clauses, parent);
161 public int OpenScope (int startOffset)
163 if (current_method == null)
164 return 0;
166 current_method.StartBlock (startOffset);
167 return 0;
170 public void CloseScope (int endOffset)
172 if (current_method == null)
173 return;
175 current_method.EndBlock (endOffset);
178 protected byte[] CreateOutput (Guid guid)
180 foreach (SourceMethod method in methods) {
181 method.SourceFile.Entry.DefineMethod (
182 method.Method.Name, method.Method.Token,
183 method.Locals, method.Lines, method.Blocks,
184 method.Start.Row, method.End.Row,
185 method.Method.NamespaceID);
188 return file.CreateSymbolFile (guid);
191 public void WriteSymbolFile (Guid guid)
193 using (FileStream stream = new FileStream (
194 filename, FileMode.Create, FileAccess.Write)) {
195 byte[] data = CreateOutput (guid);
196 stream.Write (data, 0, data.Length);
200 protected class SourceMethod
202 LineNumberEntry [] lines;
203 private ArrayList _locals;
204 private ArrayList _blocks;
205 private Stack _block_stack;
206 private int next_block_id = 0;
207 private ISourceMethod _method;
208 private ISourceFile _file;
209 private LineNumberEntry _start, _end;
211 private LexicalBlockEntry _implicit_block;
213 public SourceMethod (ISourceFile file, ISourceMethod method,
214 int startLine, int startColumn,
215 int endLine, int endColumn)
217 this._file = file;
218 this._method = method;
220 this._start = new LineNumberEntry (startLine, 0);
221 this._end = new LineNumberEntry (endLine, 0);
223 this._implicit_block = new LexicalBlockEntry (0, 0);
226 public void StartBlock (int startOffset)
228 LexicalBlockEntry block = new LexicalBlockEntry (
229 ++next_block_id, startOffset);
230 if (_block_stack == null)
231 _block_stack = new Stack ();
232 _block_stack.Push (block);
233 if (_blocks == null)
234 _blocks = new ArrayList ();
235 _blocks.Add (block);
238 public void EndBlock (int endOffset)
240 LexicalBlockEntry block =
241 (LexicalBlockEntry) _block_stack.Pop ();
243 block.Close (endOffset);
246 public LexicalBlockEntry[] Blocks {
247 get {
248 if (_blocks == null)
249 return new LexicalBlockEntry [0];
250 else {
251 LexicalBlockEntry[] retval =
252 new LexicalBlockEntry [_blocks.Count];
253 _blocks.CopyTo (retval, 0);
254 return retval;
259 public LexicalBlockEntry CurrentBlock {
260 get {
261 if ((_block_stack != null) && (_block_stack.Count > 0))
262 return (LexicalBlockEntry) _block_stack.Peek ();
263 else
264 return _implicit_block;
268 public LineNumberEntry[] Lines {
269 get {
270 return lines;
274 public LocalVariableEntry[] Locals {
275 get {
276 if (_locals == null)
277 return new LocalVariableEntry [0];
278 else {
279 LocalVariableEntry[] retval =
280 new LocalVariableEntry [_locals.Count];
281 _locals.CopyTo (retval, 0);
282 return retval;
287 public void AddLocal (string name, byte[] signature)
289 if (_locals == null)
290 _locals = new ArrayList ();
291 _locals.Add (new LocalVariableEntry (
292 name, signature, CurrentBlock.Index));
295 public ISourceFile SourceFile {
296 get { return _file; }
299 public ISourceMethod Method {
300 get { return _method; }
303 public LineNumberEntry Start {
304 get { return _start; }
307 public LineNumberEntry End {
308 get { return _end; }
312 // Passes on the lines from the MonoSymbolWriter. This method is
313 // free to mutate the lns array, and it does.
315 internal void SetLineNumbers (LineNumberEntry [] lns, int count)
317 int pos = 0;
319 int last_offset = -1;
320 int last_row = -1;
321 for (int i = 0; i < count; i++) {
322 LineNumberEntry line = lns [i];
324 if (line.Offset > last_offset) {
325 if (last_row >= 0)
326 lns [pos++] = new LineNumberEntry (
327 last_row, last_offset);
329 last_row = line.Row;
330 last_offset = line.Offset;
331 } else if (line.Row > last_row) {
332 last_row = line.Row;
336 lines = new LineNumberEntry [count + ((last_row >= 0) ? 1 : 0)];
337 Array.Copy (lns, lines, pos);
338 if (last_row >= 0)
339 lines [pos] = new LineNumberEntry (
340 last_row, last_offset);