Browse Source

Remove all code related to debugging of decompiled code

pull/32/merge
David Srbecký 13 years ago
parent
commit
3c1353849f
  1. 15
      src/AddIns/Debugger/Debugger.AddIn/Pads/BreakPointsPad.cs
  2. 117
      src/AddIns/Debugger/Debugger.AddIn/Service/WindowsDebugger.cs
  3. 17
      src/AddIns/Debugger/Debugger.AddIn/TreeModel/ValueNode.cs
  4. 43
      src/AddIns/Debugger/Debugger.Core/Breakpoint.cs
  5. 2
      src/AddIns/Debugger/Debugger.Core/Debugger.Core.csproj
  6. 5
      src/AddIns/Debugger/Debugger.Core/LocalVariable.cs
  7. 4
      src/AddIns/Debugger/Debugger.Core/Module.cs
  8. 7
      src/AddIns/Debugger/Debugger.Core/NDebugger.cs
  9. 11
      src/AddIns/Debugger/Debugger.Core/Options.cs
  10. 37
      src/AddIns/Debugger/Debugger.Core/PdbSymbolSource.cs
  11. 5
      src/AddIns/Debugger/Debugger.Core/Process.cs
  12. 12
      src/AddIns/Debugger/Debugger.Core/StackFrame.cs
  13. 9
      src/AddIns/Debugger/Debugger.Tests/DebuggerTestsBase.cs
  14. 204
      src/AddIns/DisplayBindings/ILSpyAddIn/DebuggerDecompilerService.cs
  15. 9
      src/AddIns/DisplayBindings/ILSpyAddIn/DebuggerTextOutput.cs
  16. 7
      src/AddIns/DisplayBindings/ILSpyAddIn/ILSpyAddIn.csproj
  17. 41
      src/AddIns/DisplayBindings/ILSpyAddIn/NavigateToDecompiledEntityService.cs
  18. 84
      src/AddIns/DisplayBindings/ILSpyAddIn/ViewContent/CodeView.cs
  19. 180
      src/AddIns/DisplayBindings/ILSpyAddIn/ViewContent/DecompiledViewContent.cs
  20. 1
      src/Main/Base/Project/ICSharpCode.SharpDevelop.csproj
  21. 51
      src/Main/Base/Project/Src/Services/Debugger/DebuggerService.cs
  22. 73
      src/Main/Base/Project/Src/Services/Debugger/DecompiledBreakpointBookmark.cs

15
src/AddIns/Debugger/Debugger.AddIn/Pads/BreakPointsPad.cs

@ -28,20 +28,5 @@ namespace ICSharpCode.SharpDevelop.Gui.Pads @@ -28,20 +28,5 @@ namespace ICSharpCode.SharpDevelop.Gui.Pads
{
return mark.IsVisibleInBookmarkPad && mark is BreakpointBookmark;
}
/*
protected override void OnItemActivated(SDBookmark bookmark)
{
if (bookmark is DecompiledBreakpointBookmark) {
// get information from breakpoint and navigate to the decompiled type
string assemblyFile, typeName;
if (DecompiledBreakpointBookmark.GetAssemblyAndType(bookmark.FileName, out assemblyFile, out typeName)) {
NavigationService.NavigateTo(assemblyFile, typeName, string.Empty, bookmark.LineNumber, false);
}
throw new NotImplementedException();
} else {
base.OnItemActivated(bookmark);
}
}*/
}
}

117
src/AddIns/Debugger/Debugger.AddIn/Service/WindowsDebugger.cs

@ -2,34 +2,25 @@ @@ -2,34 +2,25 @@
// This code is distributed under the BSD license (for details please see \src\AddIns\Debugger\Debugger.AddIn\license.txt)
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Security.Cryptography;
using System.Text;
using System.Windows.Forms;
using Debugger;
using Debugger.AddIn;
using Debugger.AddIn.Tooltips;
using Debugger.AddIn.TreeModel;
using Debugger.Interop.CorPublish;
using Debugger.MetaData;
using ICSharpCode.Core;
using ICSharpCode.Core.WinForms;
using ICSharpCode.NRefactory;
using ICSharpCode.NRefactory.CSharp;
using ICSharpCode.NRefactory.Semantics;
using ICSharpCode.SharpDevelop.Editor.Bookmarks;
using ICSharpCode.SharpDevelop.Debugging;
using ICSharpCode.SharpDevelop.Editor;
using ICSharpCode.SharpDevelop.Gui;
using ICSharpCode.SharpDevelop.Gui.OptionPanels;
using ICSharpCode.SharpDevelop.Project;
using Mono.Cecil;
using Process = Debugger.Process;
using StackFrame = Debugger.StackFrame;
using TreeNode = Debugger.AddIn.TreeModel.TreeNode;
@ -87,7 +78,7 @@ namespace ICSharpCode.SharpDevelop.Services @@ -87,7 +78,7 @@ namespace ICSharpCode.SharpDevelop.Services
ICorPublish corPublish;
internal IDebuggerDecompilerService debuggerDecompilerService;
List<ISymbolSource> symbolSources = new List<ISymbolSource>();
/// <inheritdoc/>
public bool BreakAtBeginning { get; set; }
@ -357,8 +348,8 @@ namespace ICSharpCode.SharpDevelop.Services @@ -357,8 +348,8 @@ namespace ICSharpCode.SharpDevelop.Services
public void InitializeService()
{
// get decompiler service
debuggerDecompilerService = SD.GetService<IDebuggerDecompilerService>();
symbolSources.Add(new PdbSymbolSource());
symbolSources.AddRange(AddInTree.BuildItems<ISymbolSource>("/SharpDevelop/Services/DebuggerService/SymbolSource", null, false));
// init NDebugger
CurrentDebugger = new NDebugger();
@ -407,44 +398,7 @@ namespace ICSharpCode.SharpDevelop.Services @@ -407,44 +398,7 @@ namespace ICSharpCode.SharpDevelop.Services
void AddBreakpoint(BreakpointBookmark bookmark)
{
Breakpoint breakpoint = null;
#warning decompiler
/*if (bookmark is DecompiledBreakpointBookmark) {
try {
if (debuggerDecompilerService == null) {
LoggingService.Warn("No IDebuggerDecompilerService found!");
return;
}
var dbb = (DecompiledBreakpointBookmark)bookmark;
MemberReference memberReference = null;
string assemblyFile, typeName;
if (DecompiledBreakpointBookmark.GetAssemblyAndType(dbb.FileName, out assemblyFile, out typeName)) {
memberReference = dbb.GetMemberReference(debuggerDecompilerService.GetAssemblyResolver(assemblyFile));
}
int token = memberReference.MetadataToken.ToInt32();
if (!debuggerDecompilerService.CheckMappings(token))
debuggerDecompilerService.DecompileOnDemand(memberReference as TypeDefinition);
int[] ilRanges;
int methodToken;
// if (debuggerDecompilerService.GetILAndTokenByLineNumber(token, dbb.LineNumber, out ilRanges, out methodToken)) {
// CurrentDebugger.AddILBreakpoint(memberReference.FullName, dbb.LineNumber, memberReference.MetadataToken.ToInt32(), methodToken, ilRanges[0], dbb.IsEnabled);
// }
} catch (System.Exception ex) {
LoggingService.Error("Error on DecompiledBreakpointBookmark: " + ex.Message);
}
} else {*/
breakpoint = CurrentDebugger.AddBreakpoint(bookmark.FileName, bookmark.LineNumber, 0, bookmark.IsEnabled);
//}
if (breakpoint == null) {
LoggingService.Warn(string.Format("unable to create breakpoint: {0}", bookmark.ToString()));
return;
}
Breakpoint breakpoint = CurrentDebugger.AddBreakpoint(bookmark.FileName, bookmark.LineNumber, 0, bookmark.IsEnabled);
bookmark.InternalBreakpointObject = breakpoint;
bookmark.IsHealthy = (CurrentProcess == null) || breakpoint.IsSet;
bookmark.IsEnabledChanged += delegate { breakpoint.IsEnabled = bookmark.IsEnabled; };
@ -512,6 +466,10 @@ namespace ICSharpCode.SharpDevelop.Services @@ -512,6 +466,10 @@ namespace ICSharpCode.SharpDevelop.Services
CurrentThread = e.Thread;
CurrentStackFrame = CurrentThread != null ? CurrentThread.MostRecentUserStackFrame : null;
// Select the symbol source
var symbolSource = symbolSources.FirstOrDefault(s => CurrentStackFrame == null || s.HasSymbols(CurrentStackFrame.MethodInfo));
CurrentProcess.SymbolSource = symbolSource ?? symbolSources.First();
// We can have several events happening at the same time
bool breakProcess = e.Break;
@ -642,74 +600,15 @@ namespace ICSharpCode.SharpDevelop.Services @@ -642,74 +600,15 @@ namespace ICSharpCode.SharpDevelop.Services
SD.Workbench.MainWindow.Activate();
// if (debuggedProcess.IsSelectedFrameForced()) {
if (CurrentStackFrame.HasSymbols) {
SequencePoint nextStatement = CurrentStackFrame.NextStatement;
if (nextStatement != null) {
DebuggerService.RemoveCurrentLineMarker();
DebuggerService.JumpToCurrentLine(nextStatement.Filename, nextStatement.StartLine, nextStatement.StartColumn, nextStatement.EndLine, nextStatement.EndColumn);
}
} else {
#warning JumpToDecompiledCode(CurrentStackFrame);
}
// } else {
// var frame = debuggedProcess.SelectedThread.MostRecentStackFrame;
// // other pause reasons
// if (frame != null && frame.HasSymbols) {
// JumpToSourceCode();
// } else {
// // use most recent stack frame because we don't have the symbols
// JumpToDecompiledCode(debuggedProcess.SelectedThread.MostRecentStackFrame);
// }
// }
}
/*
void JumpToDecompiledCode(Debugger.StackFrame frame)
{
if (frame == null) {
LoggingService.Error("No stack frame!");
return;
}
if (debuggerDecompilerService == null) {
LoggingService.Warn("No IDebuggerDecompilerService found!");
return;
}
// check for options - if these options are enabled, debugging decompiled code should not continue
if (!CurrentProcess.Options.DecompileCodeWithoutSymbols) {
LoggingService.Info("Decompiled code debugging is disabled!");
return;
}
DebuggerService.RemoveCurrentLineMarker();
// get external data
int typeToken = frame.MethodInfo.DeclaringType.MetadataToken;
int methodToken = frame.MethodInfo.MetadataToken;
int ilOffset = frame.IP;
int[] ilRanges = null;
int line = -1;
bool isMatch = false;
var debugType = (DebugType)frame.MethodInfo.DeclaringType;
debuggerDecompilerService.DebugStepInformation = Tuple.Create(methodToken, ilOffset);
if (debuggerDecompilerService.GetILAndLineNumber(typeToken, methodToken, ilOffset, out ilRanges, out line, out isMatch)) {
// update marker & navigate to line
NavigationService.NavigateTo(debugType.DebugModule.FullPath,
debugType.FullNameWithoutGenericArguments,
IDStringProvider.GetIDString(frame.MethodInfo),
line);
} else
{
// no line => do decompilation
NavigationService.NavigateTo(debugType.DebugModule.FullPath,
debugType.FullNameWithoutGenericArguments,
IDStringProvider.GetIDString(frame.MethodInfo));
}
}
*/
StopAttachedProcessDialogResult ShowStopAttachedProcessDialog()
{
string caption = StringParser.Parse("${res:XML.MainMenu.DebugMenu.Stop}");

17
src/AddIns/Debugger/Debugger.AddIn/TreeModel/ValueNode.cs

@ -255,23 +255,6 @@ namespace Debugger.AddIn.TreeModel @@ -255,23 +255,6 @@ namespace Debugger.AddIn.TreeModel
}
} else {
WindowsDebugger debugger = (WindowsDebugger)DebuggerService.CurrentDebugger;
#warning decompiler
/*
if (debugger.debuggerDecompilerService != null) {
int typeToken = stackFrame.MethodInfo.DeclaringType.MetadataToken;
int methodToken = stackFrame.MethodInfo.MetadataToken;
foreach (var localVar in debugger.debuggerDecompilerService.GetLocalVariables(typeToken, methodToken)) {
int index = ((int[])debugger.debuggerDecompilerService.GetLocalVariableIndex(typeToken, methodToken, localVar))[0];
yield return new ValueNode("Icons.16x16.Local", localVar, () => {
var newStackFrame = GetCurrentStackFrame();
if (newStackFrame.MethodInfo != stackFrame.MethodInfo)
throw new GetValueException("Expected stack frame: " + stackFrame.MethodInfo.ToString());
return newStackFrame.GetLocalVariableValue((uint)index);
});
}
}
*/
}
}

43
src/AddIns/Debugger/Debugger.Core/Breakpoint.cs

@ -69,7 +69,7 @@ namespace Debugger @@ -69,7 +69,7 @@ namespace Debugger
public virtual bool SetBreakpoint(Module module)
{
var seq = PDBSymbolSource.GetSequencePoint(module, this.FileName, this.Line, this.Column);
var seq = module.SymbolSource.GetSequencePoint(module, this.FileName, this.Line, this.Column);
if (seq != null) {
ICorDebugFunction corFuction = module.CorModule.GetFunctionFromToken(seq.MethodDefToken);
ICorDebugFunctionBreakpoint corBreakpoint = corFuction.GetILCode().CreateBreakpoint((uint)seq.ILOffset);
@ -80,45 +80,4 @@ namespace Debugger @@ -80,45 +80,4 @@ namespace Debugger
return false;
}
}
/*
public class ILBreakpoint : Breakpoint
{
public ILBreakpoint(string typeName, int line, int metadataToken, int memberToken, int offset, bool enabled)
: base(null, line, 0, enabled)
{
this.TypeName = typeName;
this.MetadataToken = metadataToken;
this.MemberMetadataToken = memberToken;
this.ILOffset = offset;
this.IsEnabled = enabled;
}
public int MetadataToken { get; private set; }
public int MemberMetadataToken { get; private set; }
public int ILOffset { get; private set; }
public override bool SetBreakpoint(Module module)
{
var currentModuleTypes = module.GetNamesOfDefinedTypes();
// set the breakpoint only if the module contains the type
if (!currentModuleTypes.Contains(this.TypeName))
return false;
SourcecodeSegment segment = SourcecodeSegment.CreateForIL(module, this.Line, MemberMetadataToken, ILOffset);
if (segment == null)
return false;
try {
ICorDebugFunctionBreakpoint corBreakpoint = segment.CorFunction.GetILCode().CreateBreakpoint((uint)segment.ILStart);
corBreakpoint.Activate(this.IsEnabled ? 1 : 0);
corBreakpoints.Add(corBreakpoint);
return true;
} catch {
return false;
}
}
}
*/
}

2
src/AddIns/Debugger/Debugger.Core/Debugger.Core.csproj

@ -88,7 +88,7 @@ @@ -88,7 +88,7 @@
<Compile Include="NDebugger.cs" />
<Compile Include="Options.cs" />
<Compile Include="Process.cs" />
<Compile Include="PDBSymbolSource.cs" />
<Compile Include="PdbSymbolSource.cs" />
<Compile Include="StackFrame.cs" />
<Compile Include="Stepper.cs" />
<Compile Include="Thread.cs" />

5
src/AddIns/Debugger/Debugger.Core/LocalVariable.cs

@ -51,12 +51,13 @@ namespace Debugger.MetaData @@ -51,12 +51,13 @@ namespace Debugger.MetaData
public static List<LocalVariable> GetLocalVariables(IMethod method)
{
if (!PDBSymbolSource.HasSymbols(method))
var module = method.ParentAssembly.GetModule();
if (!module.SymbolSource.HasSymbols(method))
return null;
List<LocalVariable> localVariables = new List<LocalVariable>();
foreach (ILLocalVariable ilvar in PDBSymbolSource.GetLocalVariables(method)) {
foreach (ILLocalVariable ilvar in module.SymbolSource.GetLocalVariables(method)) {
int index = ilvar.Index;
// NB: Display class does not have the compiler-generated flag
if (ilvar.IsCompilerGenerated || ilvar.Name.StartsWith("CS$")) {

4
src/AddIns/Debugger/Debugger.Core/Module.cs

@ -46,6 +46,10 @@ namespace Debugger @@ -46,6 +46,10 @@ namespace Debugger
get { return process; }
}
public ISymbolSource SymbolSource {
get { return this.Process.SymbolSource; }
}
NDebugger Debugger {
get { return this.AppDomain.Process.Debugger; }
}

7
src/AddIns/Debugger/Debugger.Core/NDebugger.cs

@ -170,13 +170,6 @@ namespace Debugger @@ -170,13 +170,6 @@ namespace Debugger
return breakpoint;
}
// public ILBreakpoint AddILBreakpoint(string typeName, int line, int metadataToken, int memberToken, int offset, bool enabled)
// {
// ILBreakpoint breakpoint = new ILBreakpoint(typeName, line, metadataToken, memberToken, offset, enabled);
// AddBreakpoint(breakpoint);
// return breakpoint;
// }
void AddBreakpoint(Breakpoint breakpoint)
{
this.breakpoints.Add(breakpoint);

11
src/AddIns/Debugger/Debugger.Core/Options.cs

@ -6,17 +6,6 @@ namespace Debugger @@ -6,17 +6,6 @@ namespace Debugger
{
public class Options
{
public Options()
{
EnableJustMyCode = true;
StepOverNoSymbols = true;
StepOverDebuggerAttributes = true;
StepOverAllProperties = false;
StepOverFieldAccessProperties = true;
SymbolsSearchPaths = new string[0];
PauseOnHandledExceptions = false;
}
public virtual bool EnableJustMyCode { get; set; }
public virtual bool StepOverNoSymbols { get; set; }
public virtual bool StepOverDebuggerAttributes { get; set; }

37
src/AddIns/Debugger/Debugger.Core/PdbSymbolSource.cs

@ -56,7 +56,25 @@ namespace Debugger @@ -56,7 +56,25 @@ namespace Debugger
public ILRange[] ILRanges { get; set; }
}
public class PDBSymbolSource
public interface ISymbolSource
{
/// <summary> Find sequence point by IL offset </summary>
SequencePoint GetSequencePoint(IMethod method, int iloffset);
/// <summary> Find sequence point by source code location </summary>
SequencePoint GetSequencePoint(Module module, string filename, int line, int column);
/// <summary> Determine whether the method is debugable </summary>
bool HasSymbols(IMethod method);
/// <summary> Get IL ranges that should be always stepped over by the debugger </summary>
IEnumerable<ILRange> GetIgnoredILRanges(IMethod method);
/// <summary> Get local variable metadata </summary>
IEnumerable<ILLocalVariable> GetLocalVariables(IMethod method);
}
public class PdbSymbolSource : ISymbolSource
{
/// <summary>
/// Get absolute source code path for the specified document.
@ -118,7 +136,7 @@ namespace Debugger @@ -118,7 +136,7 @@ namespace Debugger
}
}
public static SequencePoint GetSequencePoint(IMethod method, int iloffset)
public SequencePoint GetSequencePoint(IMethod method, int iloffset)
{
var symMethod = method.GetSymMethod();
if (symMethod == null)
@ -149,14 +167,11 @@ namespace Debugger @@ -149,14 +167,11 @@ namespace Debugger
return sequencePoint;
}
public static SequencePoint GetSequencePoint(Module module, string filename, int line, int column)
public SequencePoint GetSequencePoint(Module module, string filename, int line, int column)
{
// Do not use ISymUnmanagedReader.GetDocument! It is broken if two files have the same name
// Do not use ISymUnmanagedMethod.GetOffset! It sometimes returns negative offset
if (filename == null || !Path.IsPathRooted(filename))
throw new DebuggerException("Invalid filename. Absolute path is required.");
ISymUnmanagedReader symReader = module.SymReader;
if (symReader == null)
return null; // No symbols
@ -181,9 +196,7 @@ namespace Debugger @@ -181,9 +196,7 @@ namespace Debugger
int codesize = (int)corFunction.GetILCode().GetSize();
var seqPoints = symMethod.GetSequencePoints(codesize).Where(s => s.StartLine != 0xFEEFEE);
SequencePoint seqPoint = null;
if (column == 0) {
seqPoint = seqPoints.FirstOrDefault(s => s.StartLine <= line && line <= s.EndLine);
} else {
if (column != 0) {
seqPoint = seqPoints.FirstOrDefault(s => (s.StartLine < line || (s.StartLine == line && s.StartColumn <= column)) &&
(line < s.EndLine || (line == s.EndLine && column <= s.EndColumn)));
}
@ -191,12 +204,12 @@ namespace Debugger @@ -191,12 +204,12 @@ namespace Debugger
return seqPoint;
}
public static bool HasSymbols(IMethod method)
public bool HasSymbols(IMethod method)
{
return method.GetSymMethod() != null;
}
public static IEnumerable<ILRange> GetIgnoredILRanges(IMethod method)
public IEnumerable<ILRange> GetIgnoredILRanges(IMethod method)
{
var symMethod = method.GetSymMethod();
if (symMethod == null)
@ -206,7 +219,7 @@ namespace Debugger @@ -206,7 +219,7 @@ namespace Debugger
return symMethod.GetSequencePoints(codeSize).Where(p => p.StartLine == 0xFEEFEE).SelectMany(p => p.ILRanges).ToList();
}
public static IEnumerable<ILLocalVariable> GetLocalVariables(IMethod method)
public IEnumerable<ILLocalVariable> GetLocalVariables(IMethod method)
{
var symMethod = method.GetSymMethod();
if (symMethod == null)

5
src/AddIns/Debugger/Debugger.Core/Process.cs

@ -107,6 +107,8 @@ namespace Debugger @@ -107,6 +107,8 @@ namespace Debugger
public string Filename { get; private set; }
public ISymbolSource SymbolSource { get; set; }
public static DebugModeFlag DebugMode { get; set; }
internal Process(NDebugger debugger, ICorDebugProcess corProcess, string filename, string workingDirectory)
@ -115,6 +117,7 @@ namespace Debugger @@ -115,6 +117,7 @@ namespace Debugger
this.corProcess = corProcess;
this.workingDirectory = workingDirectory;
this.Filename = System.IO.Path.GetFullPath(filename); // normalize path
this.SymbolSource = new PdbSymbolSource();
this.callbackInterface = new ManagedCallback(this);
}
@ -452,7 +455,7 @@ namespace Debugger @@ -452,7 +455,7 @@ namespace Debugger
public void RunTo(string fileName, int line, int column)
{
foreach(Module module in this.Modules) {
SequencePoint seq = PDBSymbolSource.GetSequencePoint(module, fileName, line, column);
SequencePoint seq = this.SymbolSource.GetSequencePoint(module, fileName, line, column);
if (seq != null) {
ICorDebugFunction corFunction = module.CorModule.GetFunctionFromToken(seq.MethodDefToken);
ICorDebugFunctionBreakpoint corBreakpoint = corFunction.GetILCode().CreateBreakpoint((uint)seq.ILOffset);

12
src/AddIns/Debugger/Debugger.Core/StackFrame.cs

@ -46,7 +46,7 @@ namespace Debugger @@ -46,7 +46,7 @@ namespace Debugger
/// <summary> True if the stack frame has symbols defined. </summary>
public bool HasSymbols {
get {
return PDBSymbolSource.HasSymbols(this.MethodInfo);
return this.Module.SymbolSource.HasSymbols(this.MethodInfo);
}
}
@ -154,10 +154,10 @@ namespace Debugger @@ -154,10 +154,10 @@ namespace Debugger
void AsyncStep(bool stepIn)
{
List<ILRange> stepRanges = new List<ILRange>();
var seq = PDBSymbolSource.GetSequencePoint(this.MethodInfo, this.IP);
var seq = this.Module.SymbolSource.GetSequencePoint(this.MethodInfo, this.IP);
if (seq != null) {
stepRanges.AddRange(seq.ILRanges);
stepRanges.AddRange(PDBSymbolSource.GetIgnoredILRanges(this.MethodInfo));
stepRanges.AddRange(this.Module.SymbolSource.GetIgnoredILRanges(this.MethodInfo));
}
// Remove overlapping and connected ranges
@ -195,7 +195,7 @@ namespace Debugger @@ -195,7 +195,7 @@ namespace Debugger
/// </summary>
public SequencePoint NextStatement {
get {
return PDBSymbolSource.GetSequencePoint(this.MethodInfo, this.IP);
return this.Module.SymbolSource.GetSequencePoint(this.MethodInfo, this.IP);
}
}
@ -203,7 +203,7 @@ namespace Debugger @@ -203,7 +203,7 @@ namespace Debugger
{
this.Process.AssertPaused();
var seq = PDBSymbolSource.GetSequencePoint(this.Module, filename, line, column);
var seq = this.Module.SymbolSource.GetSequencePoint(this.Module, filename, line, column);
if (seq != null && seq.MethodDefToken == this.MethodInfo.GetMetadataToken()) {
try {
if (dryRun) {
@ -347,7 +347,7 @@ namespace Debugger @@ -347,7 +347,7 @@ namespace Debugger
Options opt = this.Process.Options;
if (opt.StepOverNoSymbols) {
if (!PDBSymbolSource.HasSymbols(this.MethodInfo)) return true;
if (!this.Module.SymbolSource.HasSymbols(this.MethodInfo)) return true;
}
if (opt.StepOverDebuggerAttributes) {
string[] debuggerAttributes = {

9
src/AddIns/Debugger/Debugger.Tests/DebuggerTestsBase.cs

@ -200,6 +200,15 @@ namespace Debugger.Tests @@ -200,6 +200,15 @@ namespace Debugger.Tests
testNode.SetAttribute("name", testName);
shapshotID = 0;
debugger.Options = new Options();
debugger.Options.EnableJustMyCode = true;
debugger.Options.StepOverNoSymbols = true;
debugger.Options.StepOverDebuggerAttributes = true;
debugger.Options.StepOverAllProperties = false;
debugger.Options.StepOverFieldAccessProperties = true;
debugger.Options.SymbolsSearchPaths = new string[0];
debugger.Options.PauseOnHandledExceptions = false;
log = "";
lastLogMessage = null;
process = debugger.Start(exeFilename, Path.GetDirectoryName(exeFilename), testName, false);

204
src/AddIns/DisplayBindings/ILSpyAddIn/DebuggerDecompilerService.cs

@ -1,204 +0,0 @@ @@ -1,204 +0,0 @@
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.IO;
using ICSharpCode.Decompiler;
using ICSharpCode.Decompiler.Ast;
using ICSharpCode.Decompiler.ILAst;
using ICSharpCode.ILSpyAddIn.LaunchILSpy;
using ICSharpCode.SharpDevelop.Debugging;
using ICSharpCode.SharpDevelop.Project;
using Mono.Cecil;
namespace ICSharpCode.ILSpyAddIn
{
/*
// Dummy class to avoid the build errors after updating the ICSharpCode.Decompiler version.
// TODO: get rid of this & fix debugging decompiled files
public class DecompileInformation {
public dynamic LocalVariables;
public dynamic CodeMappings;
}
/// <summary>
/// Stores the decompilation information.
/// </summary>
public class DebuggerDecompilerService : IDebuggerDecompilerService
{
ILSpyAssemblyResolver resolver;
static DebuggerDecompilerService()
{
DebugInformation = new ConcurrentDictionary<int, DecompileInformation>();
ProjectService.SolutionClosed += delegate {
DebugInformation.Clear();
GC.Collect();
};
}
internal static IDebuggerDecompilerService Instance { get; private set; }
/// <summary>
/// Gets or sets the external debug information.
/// <summary>This constains the code mappings and local variables.</summary>
/// </summary>
internal static ConcurrentDictionary<int, DecompileInformation> DebugInformation { get; private set; }
public DebuggerDecompilerService()
{
Instance = this;
}
public Tuple<int, int> DebugStepInformation { get; set; }
public bool CheckMappings(int typeToken)
{
DecompileInformation data = null;
DebugInformation.TryGetValue(typeToken, out data);
DecompileInformation information = data as DecompileInformation;
if (information == null)
return false;
if (information.CodeMappings == null)
return false;
return true;
}
public void DecompileOnDemand(TypeDefinition type)
{
if (type == null)
return;
if (CheckMappings(type.MetadataToken.ToInt32()))
return;
try {
DecompilerContext context = new DecompilerContext(type.Module);
AstBuilder astBuilder = new AstBuilder(context);
astBuilder.AddType(type);
DebuggerTextOutput output = new DebuggerTextOutput(new PlainTextOutput());
astBuilder.GenerateCode(output);
// int token = type.MetadataToken.ToInt32();
// var info = new DecompileInformation {
// CodeMappings = astBuilder.CodeMappings,
// LocalVariables = astBuilder.LocalVariables,
// DecompiledMemberReferences = astBuilder.DecompiledMemberReferences
// };
//
// // save the data
// DebugInformation.AddOrUpdate(token, info, (k, v) => info);
} catch {
return;
}
}
public bool GetILAndTokenByLineNumber(int typeToken, int lineNumber, out int[] ilRanges, out int memberToken)
{
ilRanges = null;
memberToken = -1;
if (!CheckMappings(typeToken))
return false;
var data = (DecompileInformation)DebugInformation[typeToken];
var mappings = data.CodeMappings;
foreach (var key in mappings.Keys) {
var list = mappings[key];
var instruction = list.GetInstructionByLineNumber(lineNumber, out memberToken);
if (instruction == null)
continue;
ilRanges = new int[] { instruction.ILInstructionOffset.From, instruction.ILInstructionOffset.To };
memberToken = instruction.MemberMapping.MetadataToken;
return true;
}
return false;
}
public bool GetILAndLineNumber(int typeToken, int memberToken, int ilOffset, out int[] ilRange, out int line, out bool isMatch)
{
ilRange = null;
line = -1;
isMatch = false;
if (!CheckMappings(typeToken))
return false;
var data = (DecompileInformation)DebugInformation[typeToken];
var mappings = data.CodeMappings;
if (!mappings.ContainsKey(memberToken))
return false;
var map = mappings[memberToken].GetInstructionByTokenAndOffset(memberToken, ilOffset, out isMatch);
if (map != null) {
ilRange = map.ToArray(isMatch);
line = map.SourceCodeLine;
return true;
}
return false;
}
public IEnumerable<string> GetLocalVariables(int typeToken, int memberToken)
{
if (DebugInformation == null || !DebugInformation.ContainsKey(typeToken))
yield break;
var externalData = DebugInformation[typeToken];
IEnumerable<ILVariable> list;
if (externalData.LocalVariables.TryGetValue(memberToken, out list)) {
foreach (var local in list) {
if (local.IsParameter)
continue;
if (string.IsNullOrEmpty(local.Name))
continue;
yield return local.Name;
}
}
}
public object GetLocalVariableIndex(int typeToken, int memberToken, string name)
{
if (DebugInformation == null || !DebugInformation.ContainsKey(typeToken))
return null;
var externalData = DebugInformation[typeToken];
IEnumerable<ILVariable> list;
if (externalData.LocalVariables.TryGetValue(memberToken, out list)) {
foreach (var local in list) {
if (local.IsParameter)
continue;
if (local.Name == name)
return new[] { local.OriginalVariable.Index };
}
}
return null;
}
public IAssemblyResolver GetAssemblyResolver(string assemblyFile)
{
if (string.IsNullOrEmpty(assemblyFile))
throw new ArgumentException("assemblyFile is null or empty");
string folderPath = Path.GetDirectoryName(assemblyFile);
if (resolver == null)
return (resolver = new ILSpyAssemblyResolver(folderPath));
if (string.Compare(folderPath, resolver.FolderPath, StringComparison.OrdinalIgnoreCase) != 0)
return (resolver = new ILSpyAssemblyResolver(folderPath));
return resolver;
}
}
*/
}

9
src/AddIns/DisplayBindings/ILSpyAddIn/DebuggerTextOutput.cs

@ -13,7 +13,7 @@ namespace ICSharpCode.ILSpyAddIn @@ -13,7 +13,7 @@ namespace ICSharpCode.ILSpyAddIn
{
readonly ITextOutput output;
public readonly List<MemberMapping> DebuggerMemberMappings = new List<MemberMapping>();
public readonly Dictionary<string, MethodDebugSymbols> DebugSymbols = new Dictionary<string, MethodDebugSymbols>();
public readonly Dictionary<string, ICSharpCode.NRefactory.TextLocation> MemberLocations = new Dictionary<string, ICSharpCode.NRefactory.TextLocation>();
public DebuggerTextOutput(ITextOutput output)
@ -63,10 +63,11 @@ namespace ICSharpCode.ILSpyAddIn @@ -63,10 +63,11 @@ namespace ICSharpCode.ILSpyAddIn
output.WriteReference(text, reference, isLocal);
}
public void AddDebuggerMemberMapping(MemberMapping memberMapping)
public void AddDebugSymbols(MethodDebugSymbols methodDebugSymbols)
{
DebuggerMemberMappings.Add(memberMapping);
output.AddDebuggerMemberMapping(memberMapping);
var id = XmlDocKeyProvider.GetKey(methodDebugSymbols.CecilMethod);
this.DebugSymbols.Add(id, methodDebugSymbols);
output.AddDebugSymbols(methodDebugSymbols);
}
public void MarkFoldStart(string collapsedText, bool defaultCollapsed)

7
src/AddIns/DisplayBindings/ILSpyAddIn/ILSpyAddIn.csproj

@ -52,6 +52,7 @@ @@ -52,6 +52,7 @@
<RequiredTargetFramework>3.5</RequiredTargetFramework>
</Reference>
<Reference Include="System.Drawing" />
<Reference Include="System.Linq" />
<Reference Include="System.Windows.Forms" />
<Reference Include="System.Xaml">
<RequiredTargetFramework>4.0</RequiredTargetFramework>
@ -64,7 +65,6 @@ @@ -64,7 +65,6 @@
<Compile Include="..\..\..\Main\GlobalAssemblyInfo.cs">
<Link>Properties\GlobalAssemblyInfo.cs</Link>
</Compile>
<Compile Include="DebuggerDecompilerService.cs" />
<Compile Include="DebuggerTextOutput.cs" />
<Compile Include="LaunchILSpy\ILSpyAssemblyResolver.cs" />
<Compile Include="NavigateToDecompiledEntityService.cs" />
@ -75,7 +75,6 @@ @@ -75,7 +75,6 @@
<DependentUpon>SetILSpyPathDialog.cs</DependentUpon>
</Compile>
<Compile Include="LaunchILSpy\OpenInILSpyCommand.cs" />
<Compile Include="ViewContent\CodeView.cs" />
<Compile Include="ViewContent\DecompiledViewContent.cs" />
<EmbeddedResource Include="LaunchILSpy\SetILSpyPathDialog.resx">
<DependentUpon>SetILSpyPathDialog.cs</DependentUpon>
@ -119,6 +118,10 @@ @@ -119,6 +118,10 @@
<Name>ICSharpCode.Core</Name>
<Private>False</Private>
</ProjectReference>
<ProjectReference Include="..\..\Debugger\Debugger.Core\Debugger.Core.csproj">
<Project>{1D18D788-F7EE-4585-A23B-34DC8EC63CB8}</Project>
<Name>Debugger.Core</Name>
</ProjectReference>
<ProjectReference Include="..\AvalonEdit.AddIn\AvalonEdit.AddIn.csproj">
<Project>{0162E499-42D0-409B-AA25-EED21F75336B}</Project>
<Name>AvalonEdit.AddIn</Name>

41
src/AddIns/DisplayBindings/ILSpyAddIn/NavigateToDecompiledEntityService.cs

@ -8,7 +8,6 @@ using ICSharpCode.Core; @@ -8,7 +8,6 @@ using ICSharpCode.Core;
using ICSharpCode.NRefactory.Documentation;
using ICSharpCode.NRefactory.TypeSystem;
using ICSharpCode.SharpDevelop;
using ICSharpCode.SharpDevelop.Gui;
namespace ICSharpCode.ILSpyAddIn
{
@ -54,45 +53,5 @@ namespace ICSharpCode.ILSpyAddIn @@ -54,45 +53,5 @@ namespace ICSharpCode.ILSpyAddIn
}
SD.Workbench.ShowView(new DecompiledViewContent(assemblyFile, typeName, entityIdString));
}
/*
public bool NavigateToMember(FileName assemblyFile, string typeName, string entityTag, int lineNumber, bool updateMarker)
{
if (string.IsNullOrEmpty(assemblyFile))
throw new ArgumentException("assemblyFile is null or empty");
if (string.IsNullOrEmpty(typeName))
throw new ArgumentException("typeName is null or empty");
// jump to line number if the decompiled view content exists - no need for a new decompilation
foreach (var viewContent in WorkbenchSingleton.Workbench.ViewContentCollection.OfType<DecompiledViewContent>()) {
if (string.Equals(viewContent.AssemblyFile, assemblyFile, StringComparison.OrdinalIgnoreCase) && typeName == viewContent.FullTypeName) {
if (updateMarker) {
viewContent.UpdateDebuggingUI();
}
if (lineNumber > 0)
viewContent.JumpToLineNumber(lineNumber);
else
viewContent.JumpToEntity(entityTag);
viewContent.WorkbenchWindow.SelectWindow();
return true;
}
}
// create a new decompiled view
var decompiledView = new DecompiledViewContent(assemblyFile, typeName, entityTag);
decompiledView.DecompilationFinished += delegate {
if (updateMarker) {
decompiledView.UpdateDebuggingUI();
}
if (lineNumber > 0)
decompiledView.JumpToLineNumber(lineNumber);
else
decompiledView.JumpToEntity(entityTag);
};
WorkbenchSingleton.Workbench.ShowView(decompiledView);
return true;
}
*/
}
}

84
src/AddIns/DisplayBindings/ILSpyAddIn/ViewContent/CodeView.cs

@ -1,84 +0,0 @@ @@ -1,84 +0,0 @@
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
// This code is distributed under MIT X11 license (for details please see \doc\license.txt)
using System;
using System.ComponentModel.Design;
using System.Windows.Controls;
using ICSharpCode.AvalonEdit.AddIn;
using ICSharpCode.AvalonEdit.Document;
using ICSharpCode.AvalonEdit.Highlighting;
using ICSharpCode.AvalonEdit.Search;
using ICSharpCode.SharpDevelop;
using ICSharpCode.SharpDevelop.Editor;
using ICSharpCode.SharpDevelop.Editor.Bookmarks;
using ICSharpCode.SharpDevelop.Gui;
namespace ICSharpCode.ILSpyAddIn.ViewContent
{
/// <summary>
/// Equivalent to AE.AddIn CodeEditor, but without editing capabilities.
/// </summary>
class CodeView : Grid, IDisposable, IPositionable
{
readonly SharpDevelopTextEditor textEditor;
readonly IconBarManager iconBarManager;
readonly IconBarMargin iconMargin;
readonly TextMarkerService textMarkerService;
readonly AvalonEditTextEditorAdapter adapter;
public CodeView()
{
textEditor = new SharpDevelopTextEditor();
textEditor.IsReadOnly = true;
this.Children.Add(textEditor);
adapter = new AvalonEditTextEditorAdapter(textEditor);
textEditor.SyntaxHighlighting = HighlightingManager.Instance.GetDefinition("C#");
// add margin
this.iconMargin = new IconBarMargin(iconBarManager = new IconBarManager());
textEditor.TextArea.LeftMargins.Insert(0, iconMargin);
textEditor.TextArea.TextView.VisualLinesChanged += delegate { iconMargin.InvalidateVisual(); };
// add marker service
this.textMarkerService = new TextMarkerService(textEditor.Document);
textEditor.TextArea.TextView.BackgroundRenderers.Add(textMarkerService);
textEditor.TextArea.TextView.LineTransformers.Add(textMarkerService);
var documentServiceContainer = textEditor.Document.GetRequiredService<ServiceContainer>();
documentServiceContainer.AddService(typeof(ITextMarkerService), textMarkerService);
documentServiceContainer.AddService(typeof(IBookmarkMargin), iconBarManager);
textEditor.TextArea.DefaultInputHandler.NestedInputHandlers.Add(new SearchInputHandler(textEditor.TextArea));
}
public TextDocument Document {
get { return textEditor.Document; }
}
public IconBarManager IconBarManager {
get { return iconBarManager; }
}
public void Dispose()
{
}
public int Line {
get {
return textEditor.TextArea.Caret.Line;
}
}
public int Column {
get {
return textEditor.TextArea.Caret.Column;
}
}
public void JumpTo(int line, int column)
{
adapter.JumpTo(line, column);
}
}
}

180
src/AddIns/DisplayBindings/ILSpyAddIn/ViewContent/DecompiledViewContent.cs

@ -3,14 +3,19 @@ @@ -3,14 +3,19 @@
using System;
using System.Collections.Generic;
using System.ComponentModel.Design;
using System.IO;
using System.Linq;
using System.Threading;
using ICSharpCode.AvalonEdit.AddIn;
using ICSharpCode.AvalonEdit.Highlighting;
using ICSharpCode.Core;
using ICSharpCode.Decompiler;
using ICSharpCode.Decompiler.Ast;
using ICSharpCode.NRefactory.Documentation;
using ICSharpCode.SharpDevelop.Gui;
using ICSharpCode.ILSpyAddIn.LaunchILSpy;
using ICSharpCode.ILSpyAddIn.ViewContent;
using ICSharpCode.NRefactory;
using ICSharpCode.NRefactory.TypeSystem;
using ICSharpCode.SharpDevelop;
@ -24,11 +29,15 @@ namespace ICSharpCode.ILSpyAddIn @@ -24,11 +29,15 @@ namespace ICSharpCode.ILSpyAddIn
/// <summary>
/// Hosts a decompiled type.
/// </summary>
class DecompiledViewContent : AbstractViewContentWithoutFile
class DecompiledViewContent : AbstractViewContentWithoutFile, IPositionable
{
readonly FileName assemblyFile;
readonly string fullTypeName;
readonly FileName virtualFileName;
public FileName VirtualFileName { get; private set; }
public override FileName PrimaryFileName {
get { return this.VirtualFileName; }
}
/// <summary>
/// Entity to jump to once decompilation has finished.
@ -37,16 +46,19 @@ namespace ICSharpCode.ILSpyAddIn @@ -37,16 +46,19 @@ namespace ICSharpCode.ILSpyAddIn
bool decompilationFinished;
readonly CodeView codeView;
readonly CodeEditor codeEditor = new CodeEditor();
readonly CancellationTokenSource cancellation = new CancellationTokenSource();
Dictionary<string, TextLocation> memberLocations;
public Dictionary<string, MethodDebugSymbols> DebugSymbols { get; private set; }
#region Constructor
public DecompiledViewContent(FileName assemblyFile, string fullTypeName, string entityTag)
{
this.virtualFileName = FileName.Create("ilspy://" + assemblyFile + "/" + fullTypeName);
this.codeView = new CodeView();
this.VirtualFileName = FileName.Create("ilspy://" + assemblyFile + "/" + fullTypeName + ".cs");
this.Services = codeEditor.PrimaryTextEditor.GetRequiredService<IServiceContainer>();
this.Services.AddService(typeof(IPositionable), this);
this.assemblyFile = assemblyFile;
this.fullTypeName = fullTypeName;
@ -55,15 +67,68 @@ namespace ICSharpCode.ILSpyAddIn @@ -55,15 +67,68 @@ namespace ICSharpCode.ILSpyAddIn
string shortTypeName = fullTypeName.Substring(fullTypeName.LastIndexOf('.') + 1);
this.TitleName = "[" + ReflectionHelper.SplitTypeParameterCountFromReflectionName(shortTypeName) + "]";
Thread thread = new Thread(DecompilationThread);
thread.Name = "Decompiler (" + shortTypeName + ")";
thread.Start();
DecompilationThread();
// Thread thread = new Thread(DecompilationThread);
// thread.Name = "Decompiler (" + shortTypeName + ")";
// thread.Start();
// thread.Join();
SD.BookmarkManager.BookmarkRemoved += BookmarkManager_Removed;
SD.BookmarkManager.BookmarkAdded += BookmarkManager_Added;
this.codeEditor.FileName = this.VirtualFileName;
this.codeEditor.ActiveTextEditor.IsReadOnly = true;
this.codeEditor.ActiveTextEditor.SyntaxHighlighting = HighlightingManager.Instance.GetDefinition("C#");
}
#endregion
public static DecompiledViewContent Get(FileName virtualFileName)
{
var viewContents = SD.Workbench.ViewContentCollection.OfType<DecompiledViewContent>();
return viewContents.FirstOrDefault(c => c.VirtualFileName == virtualFileName);
}
public static DecompiledViewContent Get(IEntity entity)
{
if (entity == null)
throw new ArgumentNullException("entity");
// Get the underlying entity for generic instance members
if (entity is IMember)
entity = ((IMember)entity).MemberDefinition;
ITypeDefinition declaringType = (entity as ITypeDefinition) ?? entity.DeclaringTypeDefinition;
if (declaringType == null)
return null;
// get the top-level type
while (declaringType.DeclaringTypeDefinition != null)
declaringType = declaringType.DeclaringTypeDefinition;
FileName assemblyLocation = declaringType.ParentAssembly.GetRuntimeAssemblyLocation();
if (assemblyLocation != null && File.Exists(assemblyLocation)) {
return Get(assemblyLocation, declaringType.ReflectionName);
}
return null;
}
public static DecompiledViewContent Get(FileName assemblyFile, string typeName)
{
if (assemblyFile == null)
throw new ArgumentNullException("assemblyFile");
if (string.IsNullOrEmpty(typeName))
throw new ArgumentException("typeName is null or empty");
foreach (var viewContent in SD.Workbench.ViewContentCollection.OfType<DecompiledViewContent>()) {
if (viewContent.AssemblyFile == assemblyFile && typeName == viewContent.FullTypeName) {
return viewContent;
}
}
var newViewContent = new DecompiledViewContent(assemblyFile, typeName, null);
SD.Workbench.ShowView(newViewContent);
return newViewContent;
}
#region Properties
public FileName AssemblyFile {
get { return assemblyFile; }
@ -77,7 +142,7 @@ namespace ICSharpCode.ILSpyAddIn @@ -77,7 +142,7 @@ namespace ICSharpCode.ILSpyAddIn
}
public override object Control {
get { return codeView; }
get { return codeEditor; }
}
public override bool IsReadOnly {
@ -90,7 +155,7 @@ namespace ICSharpCode.ILSpyAddIn @@ -90,7 +155,7 @@ namespace ICSharpCode.ILSpyAddIn
public override void Dispose()
{
cancellation.Cancel();
codeView.Dispose();
codeEditor.Dispose();
SD.BookmarkManager.BookmarkAdded -= BookmarkManager_Added;
SD.BookmarkManager.BookmarkRemoved -= BookmarkManager_Removed;
// DecompileInformation data;
@ -121,8 +186,8 @@ namespace ICSharpCode.ILSpyAddIn @@ -121,8 +186,8 @@ namespace ICSharpCode.ILSpyAddIn
return;
}
TextLocation location;
if (memberLocations != null && memberLocations.TryGetValue(entityIdString, out location))
codeView.JumpTo(location.Line, location.Column);
if (entityIdString != null && memberLocations != null && memberLocations.TryGetValue(entityIdString, out location))
this.JumpTo(location.Line, location.Column);
}
#endregion
@ -132,9 +197,10 @@ namespace ICSharpCode.ILSpyAddIn @@ -132,9 +197,10 @@ namespace ICSharpCode.ILSpyAddIn
try {
StringWriter writer = new StringWriter();
RunDecompiler(assemblyFile, fullTypeName, new DebuggerTextOutput(new PlainTextOutput(writer)), cancellation.Token);
if (!cancellation.IsCancellationRequested) {
SD.MainThread.InvokeAsyncAndForget(() => OnDecompilationFinished(writer));
}
// if (!cancellation.IsCancellationRequested) {
// SD.MainThread.InvokeAsyncAndForget(() => OnDecompilationFinished(writer));
// }
OnDecompilationFinished(writer);
} catch (OperationCanceledException) {
// ignore cancellation
} catch (Exception ex) {
@ -171,14 +237,15 @@ namespace ICSharpCode.ILSpyAddIn @@ -171,14 +237,15 @@ namespace ICSharpCode.ILSpyAddIn
// save decompilation data
memberLocations = textOutput.MemberLocations;
this.DebugSymbols = textOutput.DebugSymbols;
}
void OnDecompilationFinished(StringWriter output)
{
if (cancellation.IsCancellationRequested)
return;
codeView.Document.Text = output.ToString();
codeView.Document.UndoStack.ClearAll();
codeEditor.Document.Text = output.ToString();
codeEditor.Document.UndoStack.ClearAll();
this.decompilationFinished = true;
JumpToEntity(this.jumpToEntityIdStringWhenDecompilationFinished);
@ -205,65 +272,15 @@ namespace ICSharpCode.ILSpyAddIn @@ -205,65 +272,15 @@ namespace ICSharpCode.ILSpyAddIn
codeView.IconBarManager.Bookmarks.Add(bookmark);
}
}
public void UpdateDebuggingUI()
{
if (!DebuggerService.IsDebuggerStarted)
return;
if (decompiledType == null || decompiledType.MetadataToken == null)
return;
int typeToken = decompiledType.MetadataToken.ToInt32();
if (!DebuggerDecompilerService.DebugInformation.ContainsKey(typeToken))
return;
var decompilerService = DebuggerDecompilerService.Instance;
if (decompilerService == null || decompilerService.DebugStepInformation == null)
return;
// get debugging information
DecompileInformation debugInformation = (DecompileInformation)DebuggerDecompilerService.DebugInformation[typeToken];
int methodToken = decompilerService.DebugStepInformation.Item1;
int ilOffset = decompilerService.DebugStepInformation.Item2;
int line;
MemberReference member;
if (debugInformation.CodeMappings == null || !debugInformation.CodeMappings.ContainsKey(methodToken))
return;
debugInformation.CodeMappings[methodToken].GetInstructionByTokenAndOffset(methodToken, ilOffset, out member, out line);
// if the codemappings are not built
if (line <= 0) {
DebuggerService.CurrentDebugger.StepOver();
return;
}
// jump to line - scoll and unfold
this.UpdateCurrentLineBookmark(line);
this.JumpToLineNumber(line);
}
void UpdateCurrentLineBookmark(int lineNumber)
{
if (lineNumber <= 0)
return;
CurrentLineBookmark.SetPosition(uri, codeView.Document, lineNumber, 0, lineNumber, 0);
var currentLineBookmark = BookmarkManager.Bookmarks.OfType<CurrentLineBookmark>().FirstOrDefault();
if (currentLineBookmark != null) {
// update bookmark & marker
codeView.IconBarManager.Bookmarks.Add(currentLineBookmark);
currentLineBookmark.Document = this.codeView.TextEditor.Document;
}
}*/
*/
#endregion
#region Bookmarks
void BookmarkManager_Removed(object sender, BookmarkEventArgs e)
{
var mark = e.Bookmark;
if (mark != null && codeView.IconBarManager.Bookmarks.Contains(mark)) {
codeView.IconBarManager.Bookmarks.Remove(mark);
if (mark != null && codeEditor.IconBarManager.Bookmarks.Contains(mark)) {
codeEditor.IconBarManager.Bookmarks.Remove(mark);
mark.Document = null;
}
}
@ -271,10 +288,25 @@ namespace ICSharpCode.ILSpyAddIn @@ -271,10 +288,25 @@ namespace ICSharpCode.ILSpyAddIn
void BookmarkManager_Added(object sender, BookmarkEventArgs e)
{
var mark = e.Bookmark;
if (mark != null && mark is BreakpointBookmark && mark.FileName == virtualFileName) {
codeView.IconBarManager.Bookmarks.Add(mark);
mark.Document = this.codeView.Document;
if (mark != null && mark.FileName == VirtualFileName) {
codeEditor.IconBarManager.Bookmarks.Add(mark);
mark.Document = this.codeEditor.Document;
}
}
#endregion
#region IPositionable
public int Line {
get { return codeEditor.ActiveTextEditorAdapter.Caret.Line; }
}
public int Column {
get { return codeEditor.ActiveTextEditorAdapter.Caret.Column; }
}
public void JumpTo(int line, int column)
{
codeEditor.ActiveTextEditor.JumpTo(line, column);
}
#endregion

1
src/Main/Base/Project/ICSharpCode.SharpDevelop.csproj

@ -515,7 +515,6 @@ @@ -515,7 +515,6 @@
<Compile Include="Src\Services\ClassBrowserIcons\ImageSourceImage.cs" />
<Compile Include="Src\Services\Debugger\BreakpointBookmark.cs" />
<Compile Include="Src\Services\Debugger\BreakpointBookmarkEventArgs.cs" />
<Compile Include="Src\Services\Debugger\DecompiledBreakpointBookmark.cs" />
<Compile Include="Workbench\File\IFileService.cs" />
<Compile Include="Workbench\File\OpenedFile.cs" />
<Compile Include="Src\Services\LanguageBinding\AggregatedLanguageBinding.cs" />

51
src/Main/Base/Project/Src/Services/Debugger/DebuggerService.cs

@ -231,55 +231,4 @@ namespace ICSharpCode.SharpDevelop.Debugging @@ -231,55 +231,4 @@ namespace ICSharpCode.SharpDevelop.Debugging
DebuggerService.CurrentDebugger.HandleToolTipRequest(e);
}
}
/// <summary>
/// Interface for common debugger-decompiler mapping operations.
/// </summary>
[SDService]
public interface IDebuggerDecompilerService
{
/*
/// <summary>
/// Gets or sets the current method token and IL offset. Used for step in/out.
/// </summary>
Tuple<int, int> DebugStepInformation { get; set; }
/// <summary>
/// Checks the code mappings.
/// </summary>
bool CheckMappings(int typeToken);
/// <summary>
/// Decompiles on demand a type.
/// </summary>
void DecompileOnDemand(TypeDefinition type);
/// <summary>
/// Gets the IL from and IL to.
/// </summary>
bool GetILAndTokenByLineNumber(int typeToken, int lineNumber, out int[] ilRanges, out int memberToken);
/// <summary>
/// Gets the ILRange and source code line number.
/// </summary>
bool GetILAndLineNumber(int typeToken, int memberToken, int ilOffset, out int[] ilRange, out int line, out bool isMatch);
/// <summary>
/// Gets the local variables of a type and a member.
/// </summary>
IEnumerable<string> GetLocalVariables(int typeToken, int memberToken);
/// <summary>
/// Gets the local variable index.
/// </summary>
object GetLocalVariableIndex(int typeToken, int memberToken, string name);
/// <summary>
/// Gets an implementation of an assembly resolver.
/// </summary>
/// <param name="assemblyFile">Assembly file path.</param>
/// <returns>An <see cref="IAssemblyResolver"/>.</returns>
IAssemblyResolver GetAssemblyResolver(string assemblyFile);
*/
}
}

73
src/Main/Base/Project/Src/Services/Debugger/DecompiledBreakpointBookmark.cs

@ -1,73 +0,0 @@ @@ -1,73 +0,0 @@
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
using System;
using ICSharpCode.Core;
using ICSharpCode.NRefactory;
using ICSharpCode.SharpDevelop.Debugging;
namespace ICSharpCode.SharpDevelop.Editor.Bookmarks
{
/*
public class DecompiledBreakpointBookmark : BreakpointBookmark
{
public const string SEPARATOR = ","; // don't use '.'
MemberReference memberReference;
string assemblyFile;
public DecompiledBreakpointBookmark(FileName fileName, TextLocation location)
: base(fileName, location)
{
}
public MemberReference MemberReference {
get { return memberReference; }
}
public MemberReference GetMemberReference(IAssemblyResolver resolver)
{
if (resolver == null)
throw new ArgumentNullException("resolver");
if (memberReference != null)
return memberReference;
// reload from filename
ReaderParameters readerParameters = new ReaderParameters();
// Use new assembly resolver instance so that the AssemblyDefinitions can be garbage-collected
// once the code is decompiled.
readerParameters.AssemblyResolver = resolver;
string typeName;
if (GetAssemblyAndType(FileName.ToString(), out assemblyFile, out typeName)) {
ModuleDefinition module = ModuleDefinition.ReadModule(assemblyFile, readerParameters);
TypeDefinition typeDefinition = module.GetType(typeName);
if (typeDefinition == null)
throw new InvalidOperationException("Could not find type");
memberReference = typeDefinition;
}
return memberReference;
}
/// <summary>
/// Gets the assembly file and the type from the file name.
/// </summary>
/// <returns><c>true</c>, if the operation succeded; <c>false</c>, otherwise.</returns>
public static bool GetAssemblyAndType(string fileName, out string assemblyFile, out string typeName)
{
if (string.IsNullOrEmpty(fileName) || !fileName.Contains(",")) {
assemblyFile = null;
typeName = null;
return false;
}
int index = fileName.IndexOf(SEPARATOR);
assemblyFile = fileName.Substring(0, index);
typeName = fileName.Substring(index + 1, fileName.Length - index - 4);
return true;
}
}
*/
}
Loading…
Cancel
Save