/symbols/mdb/Mono.CompilerServices.SymbolWriter/MonoSymbolWriter.cs

http://github.com/jbevain/cecil · C# · 238 lines · 165 code · 40 blank · 33 comment · 18 complexity · 0150251a8787aed9518ae4a0d9b9791a MD5 · raw file

  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
  11. //
  12. //
  13. // Permission is hereby granted, free of charge, to any person obtaining
  14. // a copy of this software and associated documentation files (the
  15. // "Software"), to deal in the Software without restriction, including
  16. // without limitation the rights to use, copy, modify, merge, publish,
  17. // distribute, sublicense, and/or sell copies of the Software, and to
  18. // permit persons to whom the Software is furnished to do so, subject to
  19. // the following conditions:
  20. //
  21. // The above copyright notice and this permission notice shall be
  22. // included in all copies or substantial portions of the Software.
  23. //
  24. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  25. // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  26. // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  27. // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
  28. // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
  29. // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
  30. // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  31. //
  32. using System;
  33. using System.Runtime.CompilerServices;
  34. using System.Collections.Generic;
  35. using System.IO;
  36. namespace Mono.CompilerServices.SymbolWriter
  37. {
  38. public class MonoSymbolWriter
  39. {
  40. List<SourceMethodBuilder> methods;
  41. List<SourceFileEntry> sources;
  42. List<CompileUnitEntry> comp_units;
  43. protected readonly MonoSymbolFile file;
  44. string filename;
  45. private SourceMethodBuilder current_method;
  46. Stack<SourceMethodBuilder> current_method_stack = new Stack<SourceMethodBuilder> ();
  47. public MonoSymbolWriter (string filename)
  48. {
  49. this.methods = new List<SourceMethodBuilder> ();
  50. this.sources = new List<SourceFileEntry> ();
  51. this.comp_units = new List<CompileUnitEntry> ();
  52. this.file = new MonoSymbolFile ();
  53. this.filename = filename + ".mdb";
  54. }
  55. public MonoSymbolFile SymbolFile {
  56. get { return file; }
  57. }
  58. public void CloseNamespace ()
  59. { }
  60. public void DefineLocalVariable (int index, string name)
  61. {
  62. if (current_method == null)
  63. return;
  64. current_method.AddLocal (index, name);
  65. }
  66. public void DefineCapturedLocal (int scope_id, string name, string captured_name)
  67. {
  68. file.DefineCapturedVariable (scope_id, name, captured_name,
  69. CapturedVariable.CapturedKind.Local);
  70. }
  71. public void DefineCapturedParameter (int scope_id, string name, string captured_name)
  72. {
  73. file.DefineCapturedVariable (scope_id, name, captured_name,
  74. CapturedVariable.CapturedKind.Parameter);
  75. }
  76. public void DefineCapturedThis (int scope_id, string captured_name)
  77. {
  78. file.DefineCapturedVariable (scope_id, "this", captured_name,
  79. CapturedVariable.CapturedKind.This);
  80. }
  81. public void DefineCapturedScope (int scope_id, int id, string captured_name)
  82. {
  83. file.DefineCapturedScope (scope_id, id, captured_name);
  84. }
  85. public void DefineScopeVariable (int scope, int index)
  86. {
  87. if (current_method == null)
  88. return;
  89. current_method.AddScopeVariable (scope, index);
  90. }
  91. public void MarkSequencePoint (int offset, SourceFileEntry file, int line, int column,
  92. bool is_hidden)
  93. {
  94. if (current_method == null)
  95. return;
  96. current_method.MarkSequencePoint (offset, file, line, column, is_hidden);
  97. }
  98. public SourceMethodBuilder OpenMethod (ICompileUnit file, int ns_id, IMethodDef method)
  99. {
  100. SourceMethodBuilder builder = new SourceMethodBuilder (file, ns_id, method);
  101. current_method_stack.Push (current_method);
  102. current_method = builder;
  103. methods.Add (current_method);
  104. return builder;
  105. }
  106. public void CloseMethod ()
  107. {
  108. current_method = (SourceMethodBuilder) current_method_stack.Pop ();
  109. }
  110. public SourceFileEntry DefineDocument (string url)
  111. {
  112. SourceFileEntry entry = new SourceFileEntry (file, url);
  113. sources.Add (entry);
  114. return entry;
  115. }
  116. public SourceFileEntry DefineDocument (string url, byte[] guid, byte[] checksum)
  117. {
  118. SourceFileEntry entry = new SourceFileEntry (file, url, guid, checksum);
  119. sources.Add (entry);
  120. return entry;
  121. }
  122. public CompileUnitEntry DefineCompilationUnit (SourceFileEntry source)
  123. {
  124. CompileUnitEntry entry = new CompileUnitEntry (file, source);
  125. comp_units.Add (entry);
  126. return entry;
  127. }
  128. public int DefineNamespace (string name, CompileUnitEntry unit,
  129. string[] using_clauses, int parent)
  130. {
  131. if ((unit == null) || (using_clauses == null))
  132. throw new NullReferenceException ();
  133. return unit.DefineNamespace (name, using_clauses, parent);
  134. }
  135. public int OpenScope (int start_offset)
  136. {
  137. if (current_method == null)
  138. return 0;
  139. current_method.StartBlock (CodeBlockEntry.Type.Lexical, start_offset);
  140. return 0;
  141. }
  142. public void CloseScope (int end_offset)
  143. {
  144. if (current_method == null)
  145. return;
  146. current_method.EndBlock (end_offset);
  147. }
  148. public void OpenCompilerGeneratedBlock (int start_offset)
  149. {
  150. if (current_method == null)
  151. return;
  152. current_method.StartBlock (CodeBlockEntry.Type.CompilerGenerated,
  153. start_offset);
  154. }
  155. public void CloseCompilerGeneratedBlock (int end_offset)
  156. {
  157. if (current_method == null)
  158. return;
  159. current_method.EndBlock (end_offset);
  160. }
  161. public void StartIteratorBody (int start_offset)
  162. {
  163. current_method.StartBlock (CodeBlockEntry.Type.IteratorBody,
  164. start_offset);
  165. }
  166. public void EndIteratorBody (int end_offset)
  167. {
  168. current_method.EndBlock (end_offset);
  169. }
  170. public void StartIteratorDispatcher (int start_offset)
  171. {
  172. current_method.StartBlock (CodeBlockEntry.Type.IteratorDispatcher,
  173. start_offset);
  174. }
  175. public void EndIteratorDispatcher (int end_offset)
  176. {
  177. current_method.EndBlock (end_offset);
  178. }
  179. public void DefineAnonymousScope (int id)
  180. {
  181. file.DefineAnonymousScope (id);
  182. }
  183. public void WriteSymbolFile (Guid guid)
  184. {
  185. foreach (SourceMethodBuilder method in methods)
  186. method.DefineMethod (file);
  187. try {
  188. // We mmap the file, so unlink the previous version since it may be in use
  189. File.Delete (filename);
  190. } catch {
  191. // We can safely ignore
  192. }
  193. using (FileStream fs = new FileStream (filename, FileMode.Create, FileAccess.Write)) {
  194. file.CreateSymbolFile (guid, fs);
  195. }
  196. }
  197. }
  198. }