*** empty log message ***
[mono.git] / mcs / class / Mono.CSharp.Debugger / MonoSymbolWriter.cs
1 //
2 // System.Diagnostics.SymbolStore/MonoSymbolWriter.cs
3 //
4 // Author:
5 //   Martin Baulig (martin@gnome.org)
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
11 //
12
13 using System;
14 using System.Reflection;
15 using System.Reflection.Emit;
16 using System.Diagnostics.SymbolStore;
17 using System.Collections;
18 using System.IO;
19         
20 namespace Mono.CSharp.Debugger
21 {
22
23         public class MonoSymbolWriter : IMonoSymbolWriter
24         {
25                 protected string output_filename = null;
26                 protected Hashtable methods = null;
27                 protected Hashtable sources = null;
28
29                 protected class SourceFile : ISourceFile
30                 {
31                         private ISourceMethod[] _methods;
32                         private string _file_name;
33
34                         public SourceFile (string filename)
35                         {
36                                 this._file_name = filename;
37
38                                 this._methods = new ISourceMethod [0];
39                         }
40
41                         // interface ISourceFile
42
43                         public string FileName {
44                                 get {
45                                         return _file_name;
46                                 }
47                         }
48
49                         public ISourceMethod[] Methods {
50                                 get {
51                                         return _methods;
52                                 }
53                         }
54
55                         public void AddMethod (ISourceMethod method)
56                         {
57                                 int i = _methods.Length;
58                                 ISourceMethod[] new_m = new ISourceMethod [i + 1];
59                                 Array.Copy (_methods, new_m, i);
60                                 new_m [i] = method;
61                                 _methods = new_m;
62                         }
63                 }
64
65                 protected class SourceLine : ISourceLine
66                 {
67                         public SourceLine (int offset, int line)
68                         {
69                                 this._offset = offset;
70                                 this._line = line;
71                         }
72
73                         private readonly int _offset;
74                         private readonly int _line;
75
76                         // interface ISourceLine
77
78                         public int Offset {
79                                 get {
80                                         return _offset;
81                                 }
82                         }
83
84                         public int Line {
85                                 get {
86                                         return _line;
87                                 }
88                         }
89                 }
90
91                 protected class LocalVariable : ILocalVariable
92                 {
93                         public LocalVariable (string name, int index)
94                         {
95                                 this._name = name;
96                                 this._index = index;
97                         }
98
99                         private readonly string _name;
100                         private readonly int _index;
101
102                         // interface ILocalVariable
103
104                         public string Name {
105                                 get {
106                                         return _name;
107                                 }
108                         }
109
110                         public int Index {
111                                 get {
112                                         return _index;
113                                 }
114                         }
115                 }
116
117                 protected class SourceMethod : ISourceMethod
118                 {
119                         private ISourceLine[] _lines;
120                         private ILocalVariable[] _locals;
121
122                         private readonly MethodInfo _method_info;
123                         private readonly SourceFile _source_file;
124
125                         public SourceMethod (MethodInfo method_info, SourceFile source_file) {
126                                 this._method_info = method_info;
127                                 this._source_file = source_file;
128
129                                 this._lines = new ISourceLine [0];
130                                 this._locals = new ILocalVariable [0];
131                         }
132
133                         public void SetSourceRange (int startLine, int startColumn,
134                                                     int endLine, int endColumn)
135                         {
136                                 AddLine (new SourceLine (0, startLine));
137                         }
138
139                         // interface ISourceMethod
140
141                         public ISourceLine[] Lines {
142                                 get {
143                                         return _lines;
144                                 }
145                         }
146
147                         public ILocalVariable[] Locals {
148                                 get {
149                                         return _locals;
150                                 }
151                         }
152
153                         public void AddLine (ISourceLine line)
154                         {
155                                 int i = _lines.Length;
156                                 ISourceLine[] new_m = new ISourceLine [i + 1];
157                                 Array.Copy (_lines, new_m, i);
158                                 new_m [i] = line;
159                                 _lines = new_m;
160                         }
161
162                         public void AddLocal (ILocalVariable local)
163                         {
164                                 int i = _locals.Length;
165                                 ILocalVariable[] new_m = new ILocalVariable [i + 1];
166                                 Array.Copy (_locals, new_m, i);
167                                 new_m [i] = local;
168                                 _locals = new_m;
169                         }
170
171                         public MethodInfo MethodInfo {
172                                 get {
173                                         return _method_info;
174                                 }
175                         }
176
177                         public ISourceFile SourceFile {
178                                 get {
179                                         return _source_file;
180                                 }
181                         }
182                 }
183
184                 protected SourceMethod current_method = null;
185
186                 //
187                 // Interface IMonoSymbolWriter
188                 //
189
190                 public MonoSymbolWriter ()
191                 {
192                         methods = new Hashtable ();
193                         sources = new Hashtable ();
194                 }
195
196                 public void Close () {
197                         CreateDwarfFile (output_filename);
198                 }
199
200                 public void CloseNamespace () {
201                 }
202
203                 public void CloseScope (int endOffset) {
204                 }
205
206                 // Create and return a new IMonoSymbolDocumentWriter.
207                 public ISymbolDocumentWriter DefineDocument (string url,
208                                                              Guid language,
209                                                              Guid languageVendor,
210                                                              Guid documentType)
211                 {
212                         return new MonoSymbolDocumentWriter (url);
213                 }
214
215                 public void DefineField (
216                         SymbolToken parent,
217                         string name,
218                         FieldAttributes attributes,
219                         byte[] signature,
220                         SymAddressKind addrKind,
221                         int addr1,
222                         int addr2,
223                         int addr3)
224                 {
225                 }
226
227                 public void DefineGlobalVariable (
228                         string name,
229                         FieldAttributes attributes,
230                         byte[] signature,
231                         SymAddressKind addrKind,
232                         int addr1,
233                         int addr2,
234                         int addr3)
235                 {
236                 }
237
238                 public void DefineLocalVariable (string name,
239                                                  FieldAttributes attributes,
240                                                  byte[] signature,
241                                                  SymAddressKind addrKind,
242                                                  int addr1,
243                                                  int addr2,
244                                                  int addr3,
245                                                  int startOffset,
246                                                  int endOffset)
247                 {
248                         LocalVariable local_info = new LocalVariable (name, addr1);
249
250                         if (current_method != null)
251                                 current_method.AddLocal (local_info);
252                 }
253
254                 public void DefineParameter (
255                         string name,
256                         ParameterAttributes attributes,
257                         int sequence,
258                         SymAddressKind addrKind,
259                         int addr1,
260                         int addr2,
261                         int addr3)
262                 {
263                 }
264
265                 public void DefineSequencePoints (ISymbolDocumentWriter document,
266                                                   int[] offsets,
267                                                   int[] lines,
268                                                   int[] columns,
269                                                   int[] endLines,
270                                                   int[] endColumns)
271                 {
272                         SourceLine source_line = new SourceLine (offsets [0], lines [0]);
273
274                         if (current_method != null)
275                                 current_method.AddLine (source_line);
276                 }
277
278                 public void Initialize (IntPtr emitter, string filename, bool fFullBuild)
279                 {
280                         throw new NotSupportedException ("Please use the 'Initialize (string filename)' "
281                                                          + "constructor and read the documentation in "
282                                                          + "Mono.CSharp.Debugger/IMonoSymbolWriter.cs");
283                 }
284
285                 // This is documented in IMonoSymbolWriter.cs
286                 public void Initialize (string filename)
287                 {
288                         this.output_filename = filename;
289                 }
290
291                 public void OpenMethod (SymbolToken method)
292                 {
293                         // do nothing
294                 }
295
296                 // This is documented in IMonoSymbolWriter.cs
297                 public void OpenMethod (SymbolToken symbol_token, MethodInfo method_info,
298                                         string source_file)
299                 {
300                         int token = symbol_token.GetToken ();
301                         SourceFile source_info;
302
303                         if (methods.ContainsKey (token))
304                                 methods.Remove (token);
305
306                         if (sources.ContainsKey (source_file))
307                                 source_info = (SourceFile) sources [source_file];
308                         else {
309                                 source_info = new SourceFile (source_file);
310                                 sources.Add (source_file, source_info);
311                         }
312
313                         current_method = new SourceMethod (method_info, source_info);
314
315                         source_info.AddMethod (current_method);
316
317                         methods.Add (token, current_method);
318
319                         OpenMethod (symbol_token);
320                 }
321
322                 public void SetMethodSourceRange (ISymbolDocumentWriter startDoc,
323                                                   int startLine, int startColumn,
324                                                   ISymbolDocumentWriter endDoc,
325                                                   int endLine, int endColumn)
326                 {
327                         if ((startDoc == null) || (endDoc == null))
328                                 throw new NullReferenceException ();
329
330                         if (!(startDoc is MonoSymbolDocumentWriter) || !(endDoc is MonoSymbolDocumentWriter))
331                                 throw new NotSupportedException ("both startDoc and endDoc must be of type "
332                                                                  + "MonoSymbolDocumentWriter");
333
334                         if (!startDoc.Equals (endDoc))
335                                 throw new NotSupportedException ("startDoc and endDoc must be the same");
336
337                         if (current_method != null)
338                                 current_method.SetSourceRange (startLine, startColumn,
339                                                                endLine, endColumn);
340
341                         Console.WriteLine ("SOURCE RANGE");
342                 }
343
344                 public void CloseMethod () {
345                         current_method = null;
346                 }
347
348                 public void OpenNamespace (string name)
349                 {
350                 }
351
352                 public int OpenScope (int startOffset)
353                 {
354                         throw new NotImplementedException ();
355                 }
356
357                 public void SetScopeRange (int scopeID, int startOffset, int endOffset)
358                 {
359                 }
360
361                 public void SetSymAttribute (SymbolToken parent, string name, byte[] data)
362                 {
363                 }
364
365                 public void SetUnderlyingWriter (IntPtr underlyingWriter)
366                 {
367                 }
368
369                 public void SetUserEntryPoint (SymbolToken entryMethod)
370                 {
371                 }
372
373                 public void UsingNamespace (string fullName)
374                 {
375                 }
376
377                 //
378                 // MonoSymbolWriter implementation
379                 //
380                 protected void WriteMethod (DwarfFileWriter.DieCompileUnit parent_die, ISourceMethod method)
381                 {
382                         Console.WriteLine ("WRITING METHOD: " + method.MethodInfo.Name);
383
384                         DwarfFileWriter.DieSubProgram die;
385
386                         die = new DwarfFileWriter.DieSubProgram (parent_die, method);
387                 }
388
389                 protected void WriteSource (DwarfFileWriter writer, ISourceFile source)
390                 {
391                         Console.WriteLine ("WRITING SOURCE: " + source.FileName);
392
393                         DwarfFileWriter.CompileUnit compile_unit = new DwarfFileWriter.CompileUnit (
394                                 writer, source.FileName);
395
396                         DwarfFileWriter.DieCompileUnit die = new DwarfFileWriter.DieCompileUnit (compile_unit);
397
398                         foreach (ISourceMethod method in source.Methods)
399                                 WriteMethod (die, method);
400                 }
401
402                 protected void CreateDwarfFile (string filename)
403                 {
404                         Console.WriteLine ("WRITING DWARF FILE: " + filename);
405
406                         DwarfFileWriter writer = new DwarfFileWriter (filename);
407
408                         foreach (ISourceFile source in sources.Values)
409                                 WriteSource (writer, source);
410
411                         writer.Close ();
412
413                         Console.WriteLine ("DONE WRITING DWARF FILE");
414
415                 }
416         }
417 }