/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
- //
- // MdbReader.cs
- //
- // Author:
- // Jb Evain (jbevain@gmail.com)
- //
- // Copyright (c) 2008 - 2011 Jb Evain
- //
- // Permission is hereby granted, free of charge, to any person obtaining
- // a copy of this software and associated documentation files (the
- // "Software"), to deal in the Software without restriction, including
- // without limitation the rights to use, copy, modify, merge, publish,
- // distribute, sublicense, and/or sell copies of the Software, and to
- // permit persons to whom the Software is furnished to do so, subject to
- // the following conditions:
- //
- // The above copyright notice and this permission notice shall be
- // included in all copies or substantial portions of the Software.
- //
- // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
- // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
- // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
- // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- //
- using System;
- using System.Collections.Generic;
- using System.IO;
- using Mono.Cecil.Cil;
- using Mono.Collections.Generic;
- using Mono.CompilerServices.SymbolWriter;
- namespace Mono.Cecil.Mdb {
- public class MdbReaderProvider : ISymbolReaderProvider {
- public ISymbolReader GetSymbolReader (ModuleDefinition module, string fileName)
- {
- return new MdbReader (module, MonoSymbolFile.ReadSymbolFile (module, fileName));
- }
- public ISymbolReader GetSymbolReader (ModuleDefinition module, Stream symbolStream)
- {
- throw new NotImplementedException ();
- }
- }
- public class MdbReader : ISymbolReader {
- readonly ModuleDefinition module;
- readonly MonoSymbolFile symbol_file;
- readonly Dictionary<string, Document> documents;
- public MdbReader (ModuleDefinition module, MonoSymbolFile symFile)
- {
- this.module = module;
- this.symbol_file = symFile;
- this.documents = new Dictionary<string, Document> ();
- }
- public bool ProcessDebugHeader (ImageDebugDirectory directory, byte [] header)
- {
- return symbol_file.Guid == module.Mvid;
- }
- public void Read (MethodBody body, InstructionMapper mapper)
- {
- var method_token = body.Method.MetadataToken;
- var entry = symbol_file.GetMethodByToken (method_token.ToInt32 ());
- if (entry == null)
- return;
- var scopes = ReadScopes (entry, body, mapper);
- ReadLineNumbers (entry, mapper);
- ReadLocalVariables (entry, body, scopes);
- }
- static void ReadLocalVariables (MethodEntry entry, MethodBody body, Scope [] scopes)
- {
- var locals = entry.GetLocals ();
- foreach (var local in locals) {
- if (local.Index < 0 || local.Index >= body.Variables.Count) // Mono 2.6 emits wrong local infos for iterators
- continue;
-
- var variable = body.Variables [local.Index];
- variable.Name = local.Name;
- var index = local.BlockIndex;
- if (index < 0 || index >= scopes.Length)
- continue;
- var scope = scopes [index];
- if (scope == null)
- continue;
- scope.Variables.Add (variable);
- }
- }
- void ReadLineNumbers (MethodEntry entry, InstructionMapper mapper)
- {
- Document document = null;
- var table = entry.GetLineNumberTable ();
- foreach (var line in table.LineNumbers) {
- var instruction = mapper (line.Offset);
- if (instruction == null)
- continue;
- if (document == null)
- document = GetDocument (entry.CompileUnit.SourceFile);
- instruction.SequencePoint = new SequencePoint (document) {
- StartLine = line.Row,
- EndLine = line.Row,
- };
- }
- }
- Document GetDocument (SourceFileEntry file)
- {
- var file_name = file.FileName;
- Document document;
- if (documents.TryGetValue (file_name, out document))
- return document;
- document = new Document (file_name);
- documents.Add (file_name, document);
- return document;
- }
- static Scope [] ReadScopes (MethodEntry entry, MethodBody body, InstructionMapper mapper)
- {
- var blocks = entry.GetCodeBlocks ();
- var scopes = new Scope [blocks.Length];
- foreach (var block in blocks) {
- if (block.BlockType != CodeBlockEntry.Type.Lexical)
- continue;
- var scope = new Scope ();
- scope.Start = mapper (block.StartOffset);
- scope.End = mapper (block.EndOffset);
- scopes [block.Index] = scope;
- if (body.Scope == null)
- body.Scope = scope;
- if (!AddScope (body.Scope, scope))
- body.Scope = scope;
- }
- return scopes;
- }
- static bool AddScope (Scope provider, Scope scope)
- {
- foreach (var sub_scope in provider.Scopes) {
- if (AddScope (sub_scope, scope))
- return true;
- if (scope.Start.Offset >= sub_scope.Start.Offset && scope.End.Offset <= sub_scope.End.Offset) {
- sub_scope.Scopes.Add (scope);
- return true;
- }
- }
- return false;
- }
- public void Read (MethodSymbols symbols)
- {
- var entry = symbol_file.GetMethodByToken (symbols.MethodToken.ToInt32 ());
- if (entry == null)
- return;
- ReadLineNumbers (entry, symbols);
- ReadLocalVariables (entry, symbols);
- }
- void ReadLineNumbers (MethodEntry entry, MethodSymbols symbols)
- {
- var table = entry.GetLineNumberTable ();
- var lines = table.LineNumbers;
- var instructions = symbols.instructions = new Collection<InstructionSymbol> (lines.Length);
- for (int i = 0; i < lines.Length; i++) {
- var line = lines [i];
- instructions.Add (new InstructionSymbol (line.Offset, new SequencePoint (GetDocument (entry.CompileUnit.SourceFile)) {
- StartLine = line.Row,
- EndLine = line.Row,
- }));
- }
- }
- static void ReadLocalVariables (MethodEntry entry, MethodSymbols symbols)
- {
- foreach (var local in entry.GetLocals ()) {
- if (local.Index < 0 || local.Index >= symbols.Variables.Count) // Mono 2.6 emits wrong local infos for iterators
- continue;
- var variable = symbols.Variables [local.Index];
- variable.Name = local.Name;
- }
- }
- public void Dispose ()
- {
- symbol_file.Dispose ();
- }
- }
- }