2 // System.Diagnostics.SymbolStore/MonoSymbolWriter.cs
5 // Martin Baulig (martin@gnome.org)
7 // This is the default implementation of the System.Diagnostics.SymbolStore.ISymbolWriter
10 // (C) 2002 Ximian, Inc. http://www.ximian.com
14 using System.Reflection;
15 using System.Reflection.Emit;
16 using System.Diagnostics.SymbolStore;
17 using System.Collections;
20 namespace Mono.CSharp.Debugger
23 public class MonoSymbolWriter : IMonoSymbolWriter
25 protected string output_filename = null;
26 protected Hashtable methods = null;
27 protected Hashtable sources = null;
29 protected class SourceFile : ISourceFile
31 private ArrayList _methods = new ArrayList ();
32 private string _file_name;
34 public SourceFile (string filename)
36 this._file_name = filename;
39 // interface ISourceFile
41 public string FileName {
47 public ISourceMethod[] Methods {
49 ISourceMethod[] retval = new ISourceMethod [_methods.Count];
50 _methods.CopyTo (retval);
55 public void AddMethod (ISourceMethod method)
57 _methods.Add (method);
61 protected class SourceLine : ISourceLine
63 public SourceLine (int offset, int line)
65 this._offset = offset;
69 private readonly int _offset;
70 private readonly int _line;
72 // interface ISourceLine
87 protected class LocalVariable : ILocalVariable
89 public LocalVariable (string name, int index)
95 private readonly string _name;
96 private readonly int _index;
98 // interface ILocalVariable
113 protected class SourceMethod : ISourceMethod
115 private ArrayList _lines = new ArrayList ();
116 private ArrayList _locals = new ArrayList ();
118 private readonly MethodInfo _method_info;
119 private readonly SourceFile _source_file;
120 private readonly int _token;
122 public SourceMethod (int token, MethodInfo method_info, SourceFile source_file) {
123 this._method_info = method_info;
124 this._source_file = source_file;
128 public void SetSourceRange (int startLine, int startColumn,
129 int endLine, int endColumn)
131 AddLine (new SourceLine (0, startLine));
134 // interface ISourceMethod
136 public ISourceLine[] Lines {
138 ISourceLine[] retval = new ISourceLine [_lines.Count];
139 _lines.CopyTo (retval);
144 public ILocalVariable[] Locals {
146 ILocalVariable[] retval = new ILocalVariable [_locals.Count];
147 _locals.CopyTo (retval);
152 public void AddLine (ISourceLine line)
157 public void AddLocal (ILocalVariable local)
162 public MethodInfo MethodInfo {
168 public ISourceFile SourceFile {
174 public int FirstLine {
176 if (_lines.Count > 0)
177 return ((ISourceLine) _lines [0]).Line;
183 public int LastLine {
185 if (_lines.Count > 0)
186 return ((ISourceLine) _lines [_lines.Count - 1]).Line;
192 public int CodeSize {
205 protected SourceMethod current_method = null;
208 // Interface IMonoSymbolWriter
211 public MonoSymbolWriter ()
213 methods = new Hashtable ();
214 sources = new Hashtable ();
217 public void Close () {
218 CreateDwarfFile (output_filename);
221 public void CloseNamespace () {
224 public void CloseScope (int endOffset) {
227 // Create and return a new IMonoSymbolDocumentWriter.
228 public ISymbolDocumentWriter DefineDocument (string url,
233 return new MonoSymbolDocumentWriter (url);
236 public void DefineField (
239 FieldAttributes attributes,
241 SymAddressKind addrKind,
248 public void DefineGlobalVariable (
250 FieldAttributes attributes,
252 SymAddressKind addrKind,
259 public void DefineLocalVariable (string name,
260 FieldAttributes attributes,
262 SymAddressKind addrKind,
269 LocalVariable local_info = new LocalVariable (name, addr1);
271 if (current_method != null)
272 current_method.AddLocal (local_info);
275 public void DefineParameter (
277 ParameterAttributes attributes,
279 SymAddressKind addrKind,
286 public void DefineSequencePoints (ISymbolDocumentWriter document,
293 SourceLine source_line = new SourceLine (offsets [0], lines [0]);
295 if (current_method != null)
296 current_method.AddLine (source_line);
299 public void Initialize (IntPtr emitter, string filename, bool fFullBuild)
301 throw new NotSupportedException ("Please use the 'Initialize (string filename)' "
302 + "constructor and read the documentation in "
303 + "Mono.CSharp.Debugger/IMonoSymbolWriter.cs");
306 // This is documented in IMonoSymbolWriter.cs
307 public void Initialize (string filename)
309 this.output_filename = filename;
312 public void OpenMethod (SymbolToken method)
317 // This is documented in IMonoSymbolWriter.cs
318 public void OpenMethod (SymbolToken symbol_token, MethodInfo method_info,
321 int token = symbol_token.GetToken ();
322 SourceFile source_info;
324 if (methods.ContainsKey (token))
325 methods.Remove (token);
327 if (sources.ContainsKey (source_file))
328 source_info = (SourceFile) sources [source_file];
330 source_info = new SourceFile (source_file);
331 sources.Add (source_file, source_info);
334 current_method = new SourceMethod (token, method_info, source_info);
336 source_info.AddMethod (current_method);
338 methods.Add (token, current_method);
340 OpenMethod (symbol_token);
343 public void SetMethodSourceRange (ISymbolDocumentWriter startDoc,
344 int startLine, int startColumn,
345 ISymbolDocumentWriter endDoc,
346 int endLine, int endColumn)
348 if ((startDoc == null) || (endDoc == null))
349 throw new NullReferenceException ();
351 if (!(startDoc is MonoSymbolDocumentWriter) || !(endDoc is MonoSymbolDocumentWriter))
352 throw new NotSupportedException ("both startDoc and endDoc must be of type "
353 + "MonoSymbolDocumentWriter");
355 if (!startDoc.Equals (endDoc))
356 throw new NotSupportedException ("startDoc and endDoc must be the same");
358 if (current_method != null)
359 current_method.SetSourceRange (startLine, startColumn,
362 Console.WriteLine ("SOURCE RANGE");
365 public void CloseMethod () {
366 current_method = null;
369 public void OpenNamespace (string name)
373 public int OpenScope (int startOffset)
375 throw new NotImplementedException ();
378 public void SetScopeRange (int scopeID, int startOffset, int endOffset)
382 public void SetSymAttribute (SymbolToken parent, string name, byte[] data)
386 public void SetUnderlyingWriter (IntPtr underlyingWriter)
390 public void SetUserEntryPoint (SymbolToken entryMethod)
394 public void UsingNamespace (string fullName)
399 // MonoSymbolWriter implementation
401 protected void WriteMethod (DwarfFileWriter.DieCompileUnit parent_die, ISourceMethod method)
403 Console.WriteLine ("WRITING METHOD: " + method.MethodInfo.Name);
405 DwarfFileWriter.DieSubProgram die;
407 die = new DwarfFileWriter.DieSubProgram (parent_die, method);
410 protected void WriteSource (DwarfFileWriter writer, ISourceFile source)
412 Console.WriteLine ("WRITING SOURCE: " + writer + " " + source.FileName);
414 DwarfFileWriter.CompileUnit compile_unit = new DwarfFileWriter.CompileUnit (
415 writer, source.FileName);
417 DwarfFileWriter.DieCompileUnit die = new DwarfFileWriter.DieCompileUnit (compile_unit);
419 foreach (ISourceMethod method in source.Methods)
420 WriteMethod (die, method);
423 protected void CreateDwarfFile (string filename)
425 Console.WriteLine ("WRITING DWARF FILE: " + filename);
427 DwarfFileWriter writer = new DwarfFileWriter (filename);
429 foreach (ISourceFile source in sources.Values)
430 WriteSource (writer, source);
434 Console.WriteLine ("DONE WRITING DWARF FILE");