/symbols/mdb/Mono.CompilerServices.SymbolWriter/MonoSymbolWriter.cs
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// 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. 32// 33 34using System; 35using System.Runtime.CompilerServices; 36using System.Collections.Generic; 37using System.IO; 38 39namespace Mono.CompilerServices.SymbolWriter 40{ 41 public class MonoSymbolWriter 42 { 43 List<SourceMethodBuilder> methods; 44 List<SourceFileEntry> sources; 45 List<CompileUnitEntry> comp_units; 46 protected readonly MonoSymbolFile file; 47 string filename; 48 49 private SourceMethodBuilder current_method; 50 Stack<SourceMethodBuilder> current_method_stack = new Stack<SourceMethodBuilder> (); 51 52 public MonoSymbolWriter (string filename) 53 { 54 this.methods = new List<SourceMethodBuilder> (); 55 this.sources = new List<SourceFileEntry> (); 56 this.comp_units = new List<CompileUnitEntry> (); 57 this.file = new MonoSymbolFile (); 58 59 this.filename = filename + ".mdb"; 60 } 61 62 public MonoSymbolFile SymbolFile { 63 get { return file; } 64 } 65 66 public void CloseNamespace () 67 { } 68 69 public void DefineLocalVariable (int index, string name) 70 { 71 if (current_method == null) 72 return; 73 74 current_method.AddLocal (index, name); 75 } 76 77 public void DefineCapturedLocal (int scope_id, string name, string captured_name) 78 { 79 file.DefineCapturedVariable (scope_id, name, captured_name, 80 CapturedVariable.CapturedKind.Local); 81 } 82 83 public void DefineCapturedParameter (int scope_id, string name, string captured_name) 84 { 85 file.DefineCapturedVariable (scope_id, name, captured_name, 86 CapturedVariable.CapturedKind.Parameter); 87 } 88 89 public void DefineCapturedThis (int scope_id, string captured_name) 90 { 91 file.DefineCapturedVariable (scope_id, "this", captured_name, 92 CapturedVariable.CapturedKind.This); 93 } 94 95 public void DefineCapturedScope (int scope_id, int id, string captured_name) 96 { 97 file.DefineCapturedScope (scope_id, id, captured_name); 98 } 99 100 public void DefineScopeVariable (int scope, int index) 101 { 102 if (current_method == null) 103 return; 104 105 current_method.AddScopeVariable (scope, index); 106 } 107 108 public void MarkSequencePoint (int offset, SourceFileEntry file, int line, int column, 109 bool is_hidden) 110 { 111 if (current_method == null) 112 return; 113 114 current_method.MarkSequencePoint (offset, file, line, column, is_hidden); 115 } 116 117 public SourceMethodBuilder OpenMethod (ICompileUnit file, int ns_id, IMethodDef method) 118 { 119 SourceMethodBuilder builder = new SourceMethodBuilder (file, ns_id, method); 120 current_method_stack.Push (current_method); 121 current_method = builder; 122 methods.Add (current_method); 123 return builder; 124 } 125 126 public void CloseMethod () 127 { 128 current_method = (SourceMethodBuilder) current_method_stack.Pop (); 129 } 130 131 public SourceFileEntry DefineDocument (string url) 132 { 133 SourceFileEntry entry = new SourceFileEntry (file, url); 134 sources.Add (entry); 135 return entry; 136 } 137 138 public SourceFileEntry DefineDocument (string url, byte[] guid, byte[] checksum) 139 { 140 SourceFileEntry entry = new SourceFileEntry (file, url, guid, checksum); 141 sources.Add (entry); 142 return entry; 143 } 144 145 public CompileUnitEntry DefineCompilationUnit (SourceFileEntry source) 146 { 147 CompileUnitEntry entry = new CompileUnitEntry (file, source); 148 comp_units.Add (entry); 149 return entry; 150 } 151 152 public int DefineNamespace (string name, CompileUnitEntry unit, 153 string[] using_clauses, int parent) 154 { 155 if ((unit == null) || (using_clauses == null)) 156 throw new NullReferenceException (); 157 158 return unit.DefineNamespace (name, using_clauses, parent); 159 } 160 161 public int OpenScope (int start_offset) 162 { 163 if (current_method == null) 164 return 0; 165 166 current_method.StartBlock (CodeBlockEntry.Type.Lexical, start_offset); 167 return 0; 168 } 169 170 public void CloseScope (int end_offset) 171 { 172 if (current_method == null) 173 return; 174 175 current_method.EndBlock (end_offset); 176 } 177 178 public void OpenCompilerGeneratedBlock (int start_offset) 179 { 180 if (current_method == null) 181 return; 182 183 current_method.StartBlock (CodeBlockEntry.Type.CompilerGenerated, 184 start_offset); 185 } 186 187 public void CloseCompilerGeneratedBlock (int end_offset) 188 { 189 if (current_method == null) 190 return; 191 192 current_method.EndBlock (end_offset); 193 } 194 195 public void StartIteratorBody (int start_offset) 196 { 197 current_method.StartBlock (CodeBlockEntry.Type.IteratorBody, 198 start_offset); 199 } 200 201 public void EndIteratorBody (int end_offset) 202 { 203 current_method.EndBlock (end_offset); 204 } 205 206 public void StartIteratorDispatcher (int start_offset) 207 { 208 current_method.StartBlock (CodeBlockEntry.Type.IteratorDispatcher, 209 start_offset); 210 } 211 212 public void EndIteratorDispatcher (int end_offset) 213 { 214 current_method.EndBlock (end_offset); 215 } 216 217 public void DefineAnonymousScope (int id) 218 { 219 file.DefineAnonymousScope (id); 220 } 221 222 public void WriteSymbolFile (Guid guid) 223 { 224 foreach (SourceMethodBuilder method in methods) 225 method.DefineMethod (file); 226 227 try { 228 // We mmap the file, so unlink the previous version since it may be in use 229 File.Delete (filename); 230 } catch { 231 // We can safely ignore 232 } 233 using (FileStream fs = new FileStream (filename, FileMode.Create, FileAccess.Write)) { 234 file.CreateSymbolFile (guid, fs); 235 } 236 } 237 } 238}