GenericParameter.cs: override Module properly
[mcs.git] / class / Mono.CompilerServices.SymbolWriter / MonoSymbolWriter.cs
blobae36bc6d727c5523c32b81f86ec1d003e17fd9e6
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 class MonoSymbolWriter
43 ArrayList methods = null;
44 ArrayList sources = null;
45 ArrayList comp_units = null;
46 protected readonly MonoSymbolFile file;
47 string filename = null;
49 private SourceMethodBuilder current_method = null;
50 private Stack current_method_stack;
52 public MonoSymbolWriter (string filename)
54 this.methods = new ArrayList ();
55 this.sources = new ArrayList ();
56 this.comp_units = new ArrayList ();
57 this.current_method_stack = new Stack ();
58 this.file = new MonoSymbolFile ();
60 this.filename = filename + ".mdb";
63 public MonoSymbolFile SymbolFile {
64 get { return file; }
67 public void CloseNamespace ()
68 { }
70 public void DefineLocalVariable (int index, string name)
72 if (current_method == null)
73 return;
75 current_method.AddLocal (index, name);
78 public void DefineCapturedLocal (int scope_id, string name, string captured_name)
80 file.DefineCapturedVariable (scope_id, name, captured_name,
81 CapturedVariable.CapturedKind.Local);
84 public void DefineCapturedParameter (int scope_id, string name, string captured_name)
86 file.DefineCapturedVariable (scope_id, name, captured_name,
87 CapturedVariable.CapturedKind.Parameter);
90 public void DefineCapturedThis (int scope_id, string captured_name)
92 file.DefineCapturedVariable (scope_id, "this", captured_name,
93 CapturedVariable.CapturedKind.This);
96 public void DefineCapturedScope (int scope_id, int id, string captured_name)
98 file.DefineCapturedScope (scope_id, id, captured_name);
101 public void DefineScopeVariable (int scope, int index)
103 if (current_method == null)
104 return;
106 current_method.AddScopeVariable (scope, index);
109 public void MarkSequencePoint (int offset, SourceFileEntry file, int line, int column,
110 bool is_hidden)
112 if (current_method == null)
113 return;
115 current_method.MarkSequencePoint (offset, file, line, column, is_hidden);
118 public SourceMethodBuilder OpenMethod (ICompileUnit file, int ns_id, IMethodDef method)
120 SourceMethodBuilder builder = new SourceMethodBuilder (file, ns_id, method);
121 current_method_stack.Push (current_method);
122 current_method = builder;
123 methods.Add (current_method);
124 return builder;
127 public void CloseMethod ()
129 current_method = (SourceMethodBuilder) current_method_stack.Pop ();
132 public SourceFileEntry DefineDocument (string url)
134 SourceFileEntry entry = new SourceFileEntry (file, url);
135 sources.Add (entry);
136 return entry;
139 public SourceFileEntry DefineDocument (string url, byte[] guid, byte[] checksum)
141 SourceFileEntry entry = new SourceFileEntry (file, url, guid, checksum);
142 sources.Add (entry);
143 return entry;
146 public CompileUnitEntry DefineCompilationUnit (SourceFileEntry source)
148 CompileUnitEntry entry = new CompileUnitEntry (file, source);
149 comp_units.Add (entry);
150 return entry;
153 public int DefineNamespace (string name, CompileUnitEntry unit,
154 string[] using_clauses, int parent)
156 if ((unit == null) || (using_clauses == null))
157 throw new NullReferenceException ();
159 return unit.DefineNamespace (name, using_clauses, parent);
162 public int OpenScope (int start_offset)
164 if (current_method == null)
165 return 0;
167 current_method.StartBlock (CodeBlockEntry.Type.Lexical, start_offset);
168 return 0;
171 public void CloseScope (int end_offset)
173 if (current_method == null)
174 return;
176 current_method.EndBlock (end_offset);
179 public void OpenCompilerGeneratedBlock (int start_offset)
181 if (current_method == null)
182 return;
184 current_method.StartBlock (CodeBlockEntry.Type.CompilerGenerated,
185 start_offset);
188 public void CloseCompilerGeneratedBlock (int end_offset)
190 if (current_method == null)
191 return;
193 current_method.EndBlock (end_offset);
196 public void StartIteratorBody (int start_offset)
198 current_method.StartBlock (CodeBlockEntry.Type.IteratorBody,
199 start_offset);
202 public void EndIteratorBody (int end_offset)
204 current_method.EndBlock (end_offset);
207 public void StartIteratorDispatcher (int start_offset)
209 current_method.StartBlock (CodeBlockEntry.Type.IteratorDispatcher,
210 start_offset);
213 public void EndIteratorDispatcher (int end_offset)
215 current_method.EndBlock (end_offset);
218 public void DefineAnonymousScope (int id)
220 file.DefineAnonymousScope (id);
223 public void WriteSymbolFile (Guid guid)
225 foreach (SourceMethodBuilder method in methods)
226 method.DefineMethod (file);
228 try {
229 // We mmap the file, so unlink the previous version since it may be in use
230 File.Delete (filename);
231 } catch {
232 // We can safely ignore
234 using (FileStream fs = new FileStream (filename, FileMode.Create, FileAccess.Write)) {
235 file.CreateSymbolFile (guid, fs);
240 public class SourceMethodBuilder
242 ArrayList _locals;
243 ArrayList _blocks;
244 ArrayList _scope_vars;
245 Stack _block_stack;
246 string _real_name;
247 IMethodDef _method;
248 ICompileUnit _comp_unit;
249 // MethodEntry.Flags _method_flags;
250 int _ns_id;
252 public SourceMethodBuilder (ICompileUnit comp_unit, int ns_id, IMethodDef method)
254 this._comp_unit = comp_unit;
255 this._method = method;
256 this._ns_id = ns_id;
258 method_lines = new LineNumberEntry [32];
261 private LineNumberEntry [] method_lines;
262 private int method_lines_pos = 0;
264 public void MarkSequencePoint (int offset, SourceFileEntry file, int line, int column,
265 bool is_hidden)
267 if (method_lines_pos == method_lines.Length) {
268 LineNumberEntry [] tmp = method_lines;
269 method_lines = new LineNumberEntry [method_lines.Length * 2];
270 Array.Copy (tmp, method_lines, method_lines_pos);
273 int file_idx = file != null ? file.Index : 0;
274 method_lines [method_lines_pos++] = new LineNumberEntry (
275 file_idx, line, offset, is_hidden);
278 public void StartBlock (CodeBlockEntry.Type type, int start_offset)
280 if (_block_stack == null)
281 _block_stack = new Stack ();
282 if (_blocks == null)
283 _blocks = new ArrayList ();
285 int parent = CurrentBlock != null ? CurrentBlock.Index : -1;
287 CodeBlockEntry block = new CodeBlockEntry (
288 _blocks.Count + 1, parent, type, start_offset);
290 _block_stack.Push (block);
291 _blocks.Add (block);
294 public void EndBlock (int end_offset)
296 CodeBlockEntry block = (CodeBlockEntry) _block_stack.Pop ();
297 block.Close (end_offset);
300 public CodeBlockEntry[] Blocks {
301 get {
302 if (_blocks == null)
303 return new CodeBlockEntry [0];
305 CodeBlockEntry[] retval = new CodeBlockEntry [_blocks.Count];
306 _blocks.CopyTo (retval, 0);
307 return retval;
311 public CodeBlockEntry CurrentBlock {
312 get {
313 if ((_block_stack != null) && (_block_stack.Count > 0))
314 return (CodeBlockEntry) _block_stack.Peek ();
315 else
316 return null;
320 public LocalVariableEntry[] Locals {
321 get {
322 if (_locals == null)
323 return new LocalVariableEntry [0];
324 else {
325 LocalVariableEntry[] retval =
326 new LocalVariableEntry [_locals.Count];
327 _locals.CopyTo (retval, 0);
328 return retval;
333 public void AddLocal (int index, string name)
335 if (_locals == null)
336 _locals = new ArrayList ();
337 int block_idx = CurrentBlock != null ? CurrentBlock.Index : 0;
338 _locals.Add (new LocalVariableEntry (index, name, block_idx));
341 public ScopeVariable[] ScopeVariables {
342 get {
343 if (_scope_vars == null)
344 return new ScopeVariable [0];
346 ScopeVariable[] retval = new ScopeVariable [_scope_vars.Count];
347 _scope_vars.CopyTo (retval);
348 return retval;
352 public void AddScopeVariable (int scope, int index)
354 if (_scope_vars == null)
355 _scope_vars = new ArrayList ();
356 _scope_vars.Add (
357 new ScopeVariable (scope, index));
360 public string RealMethodName {
361 get { return _real_name; }
364 public void SetRealMethodName (string name)
366 _real_name = name;
369 public ICompileUnit SourceFile {
370 get { return _comp_unit; }
373 public IMethodDef Method {
374 get { return _method; }
377 public void DefineMethod (MonoSymbolFile file)
379 LineNumberEntry[] lines = new LineNumberEntry [method_lines_pos];
380 Array.Copy (method_lines, lines, method_lines_pos);
382 MethodEntry entry = new MethodEntry (
383 file, _comp_unit.Entry, _method.Token, ScopeVariables,
384 Locals, lines, Blocks, RealMethodName, 0, //_method_flags,
385 _ns_id);
387 file.AddMethod (entry);