/Plugins/Ycm/Plugin/third_party/ycmd/third_party/OmniSharpServer/cecil/symbols/mdb/Mono.Cecil.Mdb/MdbReader.cs

https://bitbucket.org/WscriChy/vim-configuration · C# · 222 lines · 150 code · 45 blank · 27 comment · 27 complexity · 491bb6b54134b03372eff5d5bdc72495 MD5 · raw file

  1. //
  2. // MdbReader.cs
  3. //
  4. // Author:
  5. // Jb Evain (jbevain@gmail.com)
  6. //
  7. // Copyright (c) 2008 - 2011 Jb Evain
  8. //
  9. // Permission is hereby granted, free of charge, to any person obtaining
  10. // a copy of this software and associated documentation files (the
  11. // "Software"), to deal in the Software without restriction, including
  12. // without limitation the rights to use, copy, modify, merge, publish,
  13. // distribute, sublicense, and/or sell copies of the Software, and to
  14. // permit persons to whom the Software is furnished to do so, subject to
  15. // the following conditions:
  16. //
  17. // The above copyright notice and this permission notice shall be
  18. // included in all copies or substantial portions of the Software.
  19. //
  20. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  21. // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  22. // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  23. // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
  24. // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
  25. // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
  26. // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  27. //
  28. using System;
  29. using System.Collections.Generic;
  30. using System.IO;
  31. using Mono.Cecil.Cil;
  32. using Mono.Collections.Generic;
  33. using Mono.CompilerServices.SymbolWriter;
  34. namespace Mono.Cecil.Mdb {
  35. public class MdbReaderProvider : ISymbolReaderProvider {
  36. public ISymbolReader GetSymbolReader (ModuleDefinition module, string fileName)
  37. {
  38. return new MdbReader (module, MonoSymbolFile.ReadSymbolFile (module, fileName));
  39. }
  40. public ISymbolReader GetSymbolReader (ModuleDefinition module, Stream symbolStream)
  41. {
  42. throw new NotImplementedException ();
  43. }
  44. }
  45. public class MdbReader : ISymbolReader {
  46. readonly ModuleDefinition module;
  47. readonly MonoSymbolFile symbol_file;
  48. readonly Dictionary<string, Document> documents;
  49. public MdbReader (ModuleDefinition module, MonoSymbolFile symFile)
  50. {
  51. this.module = module;
  52. this.symbol_file = symFile;
  53. this.documents = new Dictionary<string, Document> ();
  54. }
  55. public bool ProcessDebugHeader (ImageDebugDirectory directory, byte [] header)
  56. {
  57. return symbol_file.Guid == module.Mvid;
  58. }
  59. public void Read (MethodBody body, InstructionMapper mapper)
  60. {
  61. var method_token = body.Method.MetadataToken;
  62. var entry = symbol_file.GetMethodByToken (method_token.ToInt32 ());
  63. if (entry == null)
  64. return;
  65. var scopes = ReadScopes (entry, body, mapper);
  66. ReadLineNumbers (entry, mapper);
  67. ReadLocalVariables (entry, body, scopes);
  68. }
  69. static void ReadLocalVariables (MethodEntry entry, MethodBody body, Scope [] scopes)
  70. {
  71. var locals = entry.GetLocals ();
  72. foreach (var local in locals) {
  73. if (local.Index < 0 || local.Index >= body.Variables.Count) // Mono 2.6 emits wrong local infos for iterators
  74. continue;
  75. var variable = body.Variables [local.Index];
  76. variable.Name = local.Name;
  77. var index = local.BlockIndex;
  78. if (index < 0 || index >= scopes.Length)
  79. continue;
  80. var scope = scopes [index];
  81. if (scope == null)
  82. continue;
  83. scope.Variables.Add (variable);
  84. }
  85. }
  86. void ReadLineNumbers (MethodEntry entry, InstructionMapper mapper)
  87. {
  88. Document document = null;
  89. var table = entry.GetLineNumberTable ();
  90. foreach (var line in table.LineNumbers) {
  91. var instruction = mapper (line.Offset);
  92. if (instruction == null)
  93. continue;
  94. if (document == null)
  95. document = GetDocument (entry.CompileUnit.SourceFile);
  96. instruction.SequencePoint = new SequencePoint (document) {
  97. StartLine = line.Row,
  98. EndLine = line.Row,
  99. };
  100. }
  101. }
  102. Document GetDocument (SourceFileEntry file)
  103. {
  104. var file_name = file.FileName;
  105. Document document;
  106. if (documents.TryGetValue (file_name, out document))
  107. return document;
  108. document = new Document (file_name);
  109. documents.Add (file_name, document);
  110. return document;
  111. }
  112. static Scope [] ReadScopes (MethodEntry entry, MethodBody body, InstructionMapper mapper)
  113. {
  114. var blocks = entry.GetCodeBlocks ();
  115. var scopes = new Scope [blocks.Length];
  116. foreach (var block in blocks) {
  117. if (block.BlockType != CodeBlockEntry.Type.Lexical)
  118. continue;
  119. var scope = new Scope ();
  120. scope.Start = mapper (block.StartOffset);
  121. scope.End = mapper (block.EndOffset);
  122. scopes [block.Index] = scope;
  123. if (body.Scope == null)
  124. body.Scope = scope;
  125. if (!AddScope (body.Scope, scope))
  126. body.Scope = scope;
  127. }
  128. return scopes;
  129. }
  130. static bool AddScope (Scope provider, Scope scope)
  131. {
  132. foreach (var sub_scope in provider.Scopes) {
  133. if (AddScope (sub_scope, scope))
  134. return true;
  135. if (scope.Start.Offset >= sub_scope.Start.Offset && scope.End.Offset <= sub_scope.End.Offset) {
  136. sub_scope.Scopes.Add (scope);
  137. return true;
  138. }
  139. }
  140. return false;
  141. }
  142. public void Read (MethodSymbols symbols)
  143. {
  144. var entry = symbol_file.GetMethodByToken (symbols.MethodToken.ToInt32 ());
  145. if (entry == null)
  146. return;
  147. ReadLineNumbers (entry, symbols);
  148. ReadLocalVariables (entry, symbols);
  149. }
  150. void ReadLineNumbers (MethodEntry entry, MethodSymbols symbols)
  151. {
  152. var table = entry.GetLineNumberTable ();
  153. var lines = table.LineNumbers;
  154. var instructions = symbols.instructions = new Collection<InstructionSymbol> (lines.Length);
  155. for (int i = 0; i < lines.Length; i++) {
  156. var line = lines [i];
  157. instructions.Add (new InstructionSymbol (line.Offset, new SequencePoint (GetDocument (entry.CompileUnit.SourceFile)) {
  158. StartLine = line.Row,
  159. EndLine = line.Row,
  160. }));
  161. }
  162. }
  163. static void ReadLocalVariables (MethodEntry entry, MethodSymbols symbols)
  164. {
  165. foreach (var local in entry.GetLocals ()) {
  166. if (local.Index < 0 || local.Index >= symbols.Variables.Count) // Mono 2.6 emits wrong local infos for iterators
  167. continue;
  168. var variable = symbols.Variables [local.Index];
  169. variable.Name = local.Name;
  170. }
  171. }
  172. public void Dispose ()
  173. {
  174. symbol_file.Dispose ();
  175. }
  176. }
  177. }