diff --git a/src/AddIns/Debugger/Debugger.AddIn/Debugger.AddIn.csproj b/src/AddIns/Debugger/Debugger.AddIn/Debugger.AddIn.csproj index a04ab189bc..fff7b5da32 100644 --- a/src/AddIns/Debugger/Debugger.AddIn/Debugger.AddIn.csproj +++ b/src/AddIns/Debugger/Debugger.AddIn/Debugger.AddIn.csproj @@ -353,10 +353,6 @@ <Name>ICSharpCode.AvalonEdit</Name> <Private>False</Private> </ProjectReference> - <ProjectReference Include="..\..\..\Libraries\ICSharpCode.Decompiler\ICSharpCode.Decompiler.csproj"> - <Project>{984CC812-9470-4A13-AFF9-CC44068D666C}</Project> - <Name>ICSharpCode.Decompiler</Name> - </ProjectReference> <ProjectReference Include="..\..\..\Libraries\Mono.Cecil\Mono.Cecil.csproj"> <Project>{D68133BD-1E63-496E-9EDE-4FBDBF77B486}</Project> <Name>Mono.Cecil</Name> diff --git a/src/AddIns/Debugger/Debugger.AddIn/Pads/LocalVarPad.cs b/src/AddIns/Debugger/Debugger.AddIn/Pads/LocalVarPad.cs index 0e340f622c..3c6cdf9444 100644 --- a/src/AddIns/Debugger/Debugger.AddIn/Pads/LocalVarPad.cs +++ b/src/AddIns/Debugger/Debugger.AddIn/Pads/LocalVarPad.cs @@ -57,10 +57,11 @@ namespace ICSharpCode.SharpDevelop.Gui.Pads public override void RefreshPad() { - if (debuggedProcess == null || debuggedProcess.IsRunning || debuggedProcess.SelectedStackFrame == null) { + if (debuggedProcess == null || debuggedProcess.IsRunning) { localVarList.WatchItems.Clear(); return; } + localVarList.WatchItems.Clear(); using(new PrintTimes("Local Variables refresh")) { try { diff --git a/src/AddIns/Debugger/Debugger.AddIn/Pads/WatchPad.cs b/src/AddIns/Debugger/Debugger.AddIn/Pads/WatchPad.cs index 29511f6189..439053f00c 100644 --- a/src/AddIns/Debugger/Debugger.AddIn/Pads/WatchPad.cs +++ b/src/AddIns/Debugger/Debugger.AddIn/Pads/WatchPad.cs @@ -162,7 +162,7 @@ namespace ICSharpCode.SharpDevelop.Gui.Pads public override void RefreshPad() { - if (debuggedProcess == null || debuggedProcess.IsRunning || debuggedProcess.SelectedStackFrame == null) + if (debuggedProcess == null || debuggedProcess.IsRunning) return; using(new PrintTimes("Watch Pad refresh")) { diff --git a/src/AddIns/Debugger/Debugger.AddIn/Service/WindowsDebugger.cs b/src/AddIns/Debugger/Debugger.AddIn/Service/WindowsDebugger.cs index ce5434a8e5..0b6051eece 100644 --- a/src/AddIns/Debugger/Debugger.AddIn/Service/WindowsDebugger.cs +++ b/src/AddIns/Debugger/Debugger.AddIn/Service/WindowsDebugger.cs @@ -19,8 +19,6 @@ using Debugger.Interop.CorPublish; using Debugger.MetaData; using ICSharpCode.Core; using ICSharpCode.Core.WinForms; -using ICSharpCode.Decompiler; -using ICSharpCode.Decompiler.ILAst; using ICSharpCode.NRefactory; using ICSharpCode.NRefactory.Ast; using ICSharpCode.NRefactory.Visitors; @@ -461,38 +459,24 @@ namespace ICSharpCode.SharpDevelop.Services } // Stepping: - - SourceCodeMapping GetCurrentCodeMapping(out bool isMatch) + Debugger.StackFrame GetStackFrame() { + bool isMatch = false; + int line = -1; + int[] ilRange = null; + var frame = debuggedProcess.SelectedThread.MostRecentStackFrame; int typeToken = frame.MethodInfo.DeclaringType.MetadataToken; int methodToken = frame.MethodInfo.MetadataToken; - DecompileInformation debugInformation = (DecompileInformation)DebuggerService.ExternalDebugInformation[typeToken]; - isMatch = false; - - if (debugInformation == null) - return null; - - // get the mapped instruction from the current line marker or the next one - if (!debugInformation.CodeMappings.ContainsKey(methodToken)) - return null; - var mappings = (List<MemberMapping>)debugInformation.CodeMappings[methodToken]; - return mappings.GetInstructionByTokenAndOffset(methodToken, frame.IP, out isMatch); - } - - Debugger.StackFrame GetStackFrame() - { - bool isMatch; - Debugger.StackFrame frame = debuggedProcess.SelectedThread.MostRecentStackFrame; - var map = GetCurrentCodeMapping(out isMatch); - if (map == null) { - frame = debuggedProcess.SelectedThread.MostRecentStackFrame; + var decompilerService = GetDecompilerService(); + if (!decompilerService.GetILAndLineNumber(typeToken, methodToken, frame.IP, out ilRange, out line, out isMatch)){ + frame.SourceCodeLine = 0; frame.ILRanges = new [] { 0, 1 }; } else { - frame.SourceCodeLine = map.SourceCodeLine; - frame.ILRanges = map.ToArray(isMatch); + frame.SourceCodeLine = line; + frame.ILRanges = ilRange; } return frame; @@ -599,10 +583,8 @@ namespace ICSharpCode.SharpDevelop.Services var stackFrame = !debuggedProcess.IsInExternalCode ? debuggedProcess.SelectedStackFrame : debuggedProcess.SelectedThread.MostRecentStackFrame; try { - object data = GetLocalVariableIndex(stackFrame, variableName); - // evaluate expression - return ExpressionEvaluator.Evaluate(variableName, SupportedLanguage.CSharp, stackFrame, data); + return ExpressionEvaluator.Evaluate(variableName, SupportedLanguage.CSharp, stackFrame); } catch { throw; } @@ -768,39 +750,38 @@ namespace ICSharpCode.SharpDevelop.Services if (bookmark is DecompiledBreakpointBookmark) { var dbb = (DecompiledBreakpointBookmark)bookmark; var memberReference = dbb.MemberReference; - if (!DebuggerService.ExternalDebugInformation.ContainsKey(memberReference.MetadataToken.ToInt32())) - return; + var decompilerService = GetDecompilerService(); + int token = memberReference.MetadataToken.ToInt32(); - // check if the codemappings exists for bookmark line - DecompileInformation data = (DecompileInformation)DebuggerService.ExternalDebugInformation[memberReference.MetadataToken.ToInt32()]; - var storage = data.CodeMappings; - int token = 0; - foreach (var key in storage.Keys) { - var instruction = storage[key].GetInstructionByLineNumber(dbb.LineNumber, out token); - - if (instruction == null) { - continue; - } - - dbb.ILFrom = instruction.ILInstructionOffset.From; - dbb.ILTo = instruction.ILInstructionOffset.To; - + if (!DebuggerService.ExternalDebugInformation.ContainsKey(token)) + decompilerService.DecompileOnDemand(memberReference as TypeDefinition); + + int[] ilRanges; + int methodToken; + if (decompilerService.GetILAndTokenByLineNumber(token, dbb.LineNumber, out ilRanges, out methodToken)) { + dbb.ILFrom = ilRanges[0]; + dbb.ILTo = ilRanges[1]; + // create BP breakpoint = new ILBreakpoint( debugger, dbb.MemberReference.FullName, dbb.LineNumber, memberReference.MetadataToken.ToInt32(), - instruction.MemberMapping.MetadataToken, + methodToken, dbb.ILFrom, dbb.IsEnabled); debugger.Breakpoints.Add(breakpoint); - break; } } else { breakpoint = debugger.Breakpoints.Add(bookmark.FileName, null, bookmark.LineNumber, 0, bookmark.IsEnabled); } + if (breakpoint == null) { + LoggingService.Warn(string.Format("unable to create breakpoint: {0}", bookmark.ToString())); + return; + } + MethodInvoker setBookmarkColor = delegate { if (debugger.Processes.Count == 0) { bookmark.IsHealthy = true; @@ -969,8 +950,8 @@ namespace ICSharpCode.SharpDevelop.Services var currentModuleTypes = e.Module.GetNamesOfDefinedTypes(); foreach (var bookmark in DebuggerService.Breakpoints.OfType<DecompiledBreakpointBookmark>()) { var breakpoint = debugger.Breakpoints.FirstOrDefault( - b => b is ILBreakpoint && b.Line == bookmark.LineNumber && - ((ILBreakpoint)b).MetadataToken == bookmark.MemberReference.MetadataToken.ToInt32()); + b => b is ILBreakpoint && b.Line == bookmark.LineNumber && + ((ILBreakpoint)b).MetadataToken == bookmark.MemberReference.MetadataToken.ToInt32()); if (breakpoint == null) continue; // set the breakpoint only if the module contains the type @@ -1058,39 +1039,37 @@ namespace ICSharpCode.SharpDevelop.Services int typeToken = frame.MethodInfo.DeclaringType.MetadataToken; // get external data - object data = null; - DebuggerService.ExternalDebugInformation.TryGetValue(typeToken, out data); - DecompileInformation externalData = data as DecompileInformation; - int token = frame.MethodInfo.MetadataToken; + int methodToken = frame.MethodInfo.MetadataToken; int ilOffset = frame.IP; - int line; - MemberReference memberReference; - if (externalData != null && externalData.CodeMappings.ContainsKey(token)) { - var mappings = externalData.CodeMappings[token]; - if (mappings.GetInstructionByTokenAndOffset(token, ilOffset, out memberReference, out line)) { - DebuggerService.DebugStepInformation = null; // we do not need to step into/out + var decompilerService = GetDecompilerService(); + int[] ilRanges = null; + int line = -1; + bool isMatch = false; + if (decompilerService.GetILAndLineNumber(typeToken, methodToken, ilOffset, out ilRanges, out line, out isMatch)) { + DebuggerService.DebugStepInformation = null; // we do not need to step into/out - // update marker - var debugType = (DebugType)frame.MethodInfo.DeclaringType; - string fullTypeName = debugType.FullNameWithoutGenericArguments; - string shortTypeName = fullTypeName.Substring(fullTypeName.LastIndexOf('.') + 1); - string title = "[" + shortTypeName + "]"; - foreach (var vc in WorkbenchSingleton.Workbench.ViewContentCollection.OfType<AbstractViewContentWithoutFile>()) { - if (string.Equals(vc.TitleName, title, StringComparison.OrdinalIgnoreCase)) { - CurrentLineBookmark.SetPosition(vc, line, 0, line, 0); - vc.WorkbenchWindow.SelectWindow(); - return; - } + // update marker + var debugType = (DebugType)frame.MethodInfo.DeclaringType; + + foreach (dynamic vc in WorkbenchSingleton.Workbench.ViewContentCollection.OfType<AbstractViewContentWithoutFile>()) { + if (vc == null || vc.MemberReference == null) + continue; + + if (vc.MemberReference.MetadataToken.ToInt32() == debugType.MetadataToken) { + CurrentLineBookmark.SetPosition(vc, line, 0, line, 0); + var wbw = vc.WorkbenchWindow as IWorkbenchWindow; + if (wbw != null) + wbw.SelectWindow(); + return; } - // the decompiled content was closed so we have to recreate it - StepIntoUnknownFrame(frame, token, ilOffset); - } else { - StepIntoUnknownFrame(frame, token, ilOffset); } + // the decompiled content was closed so we have to recreate it + StepIntoUnknownFrame(frame, methodToken, ilOffset); } else { - StepIntoUnknownFrame(frame, token, ilOffset); + StepIntoUnknownFrame(frame, methodToken, ilOffset); } + } } @@ -1102,6 +1081,15 @@ namespace ICSharpCode.SharpDevelop.Services NavigationService.NavigateTo(debugType.DebugModule.FullPath, debugType.FullNameWithoutGenericArguments, string.Empty); } + IDebuggerDecompilerService GetDecompilerService() + { + var items = AddInTree.BuildItems<IDebuggerDecompilerService>("/SharpDevelop/Services/DebuggerDecompilerService", null, false); + if (items.Count == 0) + return null; + + return items[0]; + } + StopAttachedProcessDialogResult ShowStopAttachedProcessDialog() { string caption = StringParser.Parse("${res:XML.MainMenu.DebugMenu.Stop}"); @@ -1119,32 +1107,5 @@ namespace ICSharpCode.SharpDevelop.Services .Where(p => e.Item.Name.IndexOf(p.Name) >= 0) .ForEach(p => e.Item.LoadSymbolsFromDisk(new []{ Path.GetDirectoryName(p.OutputAssemblyFullPath) })); } - - public static object GetLocalVariableIndex(Debugger.StackFrame stackFrame, string variableName) - { - // get the target name - int typeToken = stackFrame.MethodInfo.DeclaringType.MetadataToken; - int methodToken = stackFrame.MethodInfo.MetadataToken; - int index = variableName.IndexOf('.'); - string targetName = variableName; - if (index != -1) { - targetName = variableName.Substring(0, index); - } - - // get local variable index and store it in UserData property - used in evaluator - object data = null; - IEnumerable<ILVariable> list; - if (DebuggerService.ExternalDebugInformation == null || !DebuggerService.ExternalDebugInformation.ContainsKey(typeToken)) - return null; - - DecompileInformation externalData = (DecompileInformation)DebuggerService.ExternalDebugInformation[typeToken]; - if (externalData.LocalVariables.TryGetValue(methodToken, out list)) { - var variable = list.FirstOrDefault(v => v.Name == targetName); - if (variable != null && variable.OriginalVariable != null) { - data = new[] { variable.OriginalVariable.Index }; - } - } - return data; - } } } diff --git a/src/AddIns/Debugger/Debugger.AddIn/TreeModel/ExpressionNode.cs b/src/AddIns/Debugger/Debugger.AddIn/TreeModel/ExpressionNode.cs index 54e7ee1ba7..c15704dbdb 100644 --- a/src/AddIns/Debugger/Debugger.AddIn/TreeModel/ExpressionNode.cs +++ b/src/AddIns/Debugger/Debugger.AddIn/TreeModel/ExpressionNode.cs @@ -14,8 +14,6 @@ using System.Windows.Forms; using Debugger.AddIn.Visualizers; using Debugger.MetaData; using ICSharpCode.Core; -using ICSharpCode.Decompiler; -using ICSharpCode.Decompiler.ILAst; using ICSharpCode.NRefactory.Ast; using ICSharpCode.SharpDevelop; using ICSharpCode.SharpDevelop.Debugging; @@ -159,17 +157,8 @@ namespace Debugger.AddIn.TreeModel Value val; try { var process = WindowsDebugger.DebuggedProcess; - var context = !process.IsInExternalCode ? process.SelectedStackFrame : process.SelectedThread.MostRecentStackFrame; - object data = WindowsDebugger.GetLocalVariableIndex(WindowsDebugger.DebuggedProcess.SelectedThread.MostRecentStackFrame, Name); - if (expression is MemberReferenceExpression) { - var memberExpression = (MemberReferenceExpression)expression; - memberExpression.TargetObject.UserData = data; - } else { - expression.UserData = data; - } - // evaluate expression - val = expression.Evaluate(WindowsDebugger.DebuggedProcess); + val = expression.Evaluate(process); } catch (GetValueException e) { error = e; this.Text = e.Message; diff --git a/src/AddIns/DisplayBindings/ILSpyAddIn/DebuggerDecompilerService.cs b/src/AddIns/DisplayBindings/ILSpyAddIn/DebuggerDecompilerService.cs new file mode 100644 index 0000000000..c1e8789108 --- /dev/null +++ b/src/AddIns/DisplayBindings/ILSpyAddIn/DebuggerDecompilerService.cs @@ -0,0 +1,103 @@ +// 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.Decompiler; +using ICSharpCode.Decompiler.Ast; +using ICSharpCode.SharpDevelop.Debugging; +using Mono.Cecil; + +namespace ICSharpCode.ILSpyAddIn +{ + /// <summary> + /// Description of DebuggerDecompilerService. + /// </summary> + public class DebuggerDecompilerService : IDebuggerDecompilerService + { + private bool CheckMappings(int typeToken) + { + object data = null; + DebuggerService.ExternalDebugInformation.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); + astBuilder.GenerateCode(new PlainTextOutput()); + + int token = type.MetadataToken.ToInt32(); + var info = new DecompileInformation { + CodeMappings = astBuilder.CodeMappings, + LocalVariables = astBuilder.LocalVariables, + DecompiledMemberReferences = astBuilder.DecompiledMemberReferences + }; + + // save the data + DebuggerService.ExternalDebugInformation.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)DebuggerService.ExternalDebugInformation[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 [] { 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)DebuggerService.ExternalDebugInformation[typeToken]; + var mappings = data.CodeMappings; + var map = mappings[memberToken].GetInstructionByTokenAndOffset(memberToken, ilOffset, out isMatch); + if (map != null) { + ilRange = map.ToArray(isMatch); + line = map.SourceCodeLine; + return true; + } + + return false; + } + } +} diff --git a/src/AddIns/DisplayBindings/ILSpyAddIn/ILSpyAddIn.addin b/src/AddIns/DisplayBindings/ILSpyAddIn/ILSpyAddIn.addin index 19a2adb926..7b4da78f64 100644 --- a/src/AddIns/DisplayBindings/ILSpyAddIn/ILSpyAddIn.addin +++ b/src/AddIns/DisplayBindings/ILSpyAddIn/ILSpyAddIn.addin @@ -16,6 +16,10 @@ <Class id="ILSpy" class="ICSharpCode.ILSpyAddIn.NavigateToDecompiledEntityService"/> </Path> + <Path name="/SharpDevelop/Services/DebuggerDecompilerService"> + <Class id="DebuggerDecompilerService" class="ICSharpCode.ILSpyAddIn.DebuggerDecompilerService"/> + </Path> + <!-- Text editor context menu: Launch ILSpy command --> <Path name = "/SharpDevelop/ViewContent/DefaultTextEditor/ClassMemberContextMenu"> diff --git a/src/AddIns/DisplayBindings/ILSpyAddIn/ILSpyAddIn.csproj b/src/AddIns/DisplayBindings/ILSpyAddIn/ILSpyAddIn.csproj index 415cbd3c4f..44512a97fa 100644 --- a/src/AddIns/DisplayBindings/ILSpyAddIn/ILSpyAddIn.csproj +++ b/src/AddIns/DisplayBindings/ILSpyAddIn/ILSpyAddIn.csproj @@ -63,6 +63,7 @@ <Compile Include="..\..\..\Main\GlobalAssemblyInfo.cs"> <Link>Properties\GlobalAssemblyInfo.cs</Link> </Compile> + <Compile Include="DebuggerDecompilerService.cs" /> <Compile Include="NavigateToDecompiledEntityService.cs" /> <Compile Include="Properties\AssemblyInfo.cs" /> <Compile Include="LaunchILSpy\ILSpyController.cs" /> diff --git a/src/AddIns/DisplayBindings/ILSpyAddIn/ViewContent/DecompiledViewContent.cs b/src/AddIns/DisplayBindings/ILSpyAddIn/ViewContent/DecompiledViewContent.cs index 1082b9b6c5..40dde52118 100644 --- a/src/AddIns/DisplayBindings/ILSpyAddIn/ViewContent/DecompiledViewContent.cs +++ b/src/AddIns/DisplayBindings/ILSpyAddIn/ViewContent/DecompiledViewContent.cs @@ -168,22 +168,17 @@ namespace ICSharpCode.ILSpyAddIn .PreOrder((AstNode)astBuilder.CompilationUnit, n => n.Children) .Where(n => n is AttributedNode && n.Annotation<Tuple<int, int>>() != null); MemberReference = typeDefinition; + int token = MemberReference.MetadataToken.ToInt32(); - if (!DebuggerService.ExternalDebugInformation.ContainsKey(token)) { - DebuggerService.ExternalDebugInformation.Add(token, new DecompileInformation { - CodeMappings = astBuilder.CodeMappings, - LocalVariables = astBuilder.LocalVariables, - DecompiledMemberReferences = astBuilder.DecompiledMemberReferences, - AstNodes = nodes - }); - } else { - DebuggerService.ExternalDebugInformation[token] = new DecompileInformation { - CodeMappings = astBuilder.CodeMappings, - LocalVariables = astBuilder.LocalVariables, - DecompiledMemberReferences = astBuilder.DecompiledMemberReferences, - AstNodes = nodes - }; - } + var info = new DecompileInformation { + CodeMappings = astBuilder.CodeMappings, + LocalVariables = astBuilder.LocalVariables, + DecompiledMemberReferences = astBuilder.DecompiledMemberReferences, + AstNodes = nodes + }; + + // save the data + DebuggerService.ExternalDebugInformation.AddOrUpdate(token, info, (k, v) => info); } void OnDecompilationFinished(StringWriter output) @@ -222,37 +217,42 @@ namespace ICSharpCode.ILSpyAddIn if (!DebuggerService.IsDebuggerStarted) return; - if (DebuggerService.DebugStepInformation != null) { - // get debugging information - DecompileInformation debugInformation = (DecompileInformation)DebuggerService.ExternalDebugInformation[MemberReference.MetadataToken.ToInt32()]; - int token = DebuggerService.DebugStepInformation.Item1; - int ilOffset = DebuggerService.DebugStepInformation.Item2; - int line; - MemberReference member; - if (debugInformation.CodeMappings == null || !debugInformation.CodeMappings.ContainsKey(token)) - return; - - debugInformation.CodeMappings[token].GetInstructionByTokenAndOffset(token, ilOffset, out member, out line); - - // HACK : if the codemappings are not built - if (line == 0) { - DebuggerService.CurrentDebugger.StepOver(); - return; - } - // update bookmark & marker - codeView.UnfoldAndScroll(line); - CurrentLineBookmark.SetPosition(this, line, 0, line, 0); + if (MemberReference == null || MemberReference.MetadataToken == null) + return; + + int typeToken = MemberReference.MetadataToken.ToInt32(); + if (!DebuggerService.ExternalDebugInformation.ContainsKey(typeToken)) + return; + + // get debugging information + DecompileInformation debugInformation = (DecompileInformation)DebuggerService.ExternalDebugInformation[typeToken]; + int token = DebuggerService.DebugStepInformation.Item1; + int ilOffset = DebuggerService.DebugStepInformation.Item2; + int line; + MemberReference member; + if (debugInformation.CodeMappings == null || !debugInformation.CodeMappings.ContainsKey(token)) + return; + + debugInformation.CodeMappings[token].GetInstructionByTokenAndOffset(token, ilOffset, out member, out line); + + // HACK : if the codemappings are not built + if (line <= 0) { + DebuggerService.CurrentDebugger.StepOver(); + return; } + // update bookmark & marker + codeView.UnfoldAndScroll(line); + CurrentLineBookmark.SetPosition(this, line, 0, line, 0); } public void JumpTo(int lineNumber) - { - if (lineNumber <= 0) - return; - + { if (codeView == null) return; + if (lineNumber <= 0 || lineNumber > codeView.Document.LineCount) + return; + codeView.UnfoldAndScroll(lineNumber); } #endregion diff --git a/src/Main/Base/Project/Src/Services/Debugger/BreakpointBookmark.cs b/src/Main/Base/Project/Src/Services/Debugger/BreakpointBookmark.cs index 1277fe4b7c..3bdbcc5da4 100644 --- a/src/Main/Base/Project/Src/Services/Debugger/BreakpointBookmark.cs +++ b/src/Main/Base/Project/Src/Services/Debugger/BreakpointBookmark.cs @@ -114,5 +114,10 @@ namespace ICSharpCode.SharpDevelop.Debugging marker.ForegroundColor = Colors.White; return marker; } + + public override string ToString() + { + return string.Format("{0} @{1}", this.FileName, this.LineNumber); + } } } diff --git a/src/Main/Base/Project/Src/Services/Debugger/CurrentLineBookmark.cs b/src/Main/Base/Project/Src/Services/Debugger/CurrentLineBookmark.cs index 9a80788f46..6235fbdb84 100644 --- a/src/Main/Base/Project/Src/Services/Debugger/CurrentLineBookmark.cs +++ b/src/Main/Base/Project/Src/Services/Debugger/CurrentLineBookmark.cs @@ -22,34 +22,34 @@ namespace ICSharpCode.SharpDevelop.Debugging static int endLine; static int endColumn; - public static void SetPosition(IViewContent viewContent, int makerStartLine, int makerStartColumn, int makerEndLine, int makerEndColumn) + public static void SetPosition(IViewContent viewContent, int markerStartLine, int markerStartColumn, int markerEndLine, int markerEndColumn) { ITextEditorProvider tecp = viewContent as ITextEditorProvider; if (tecp != null) { - SetPosition(tecp.TextEditor.FileName, tecp.TextEditor.Document, makerStartLine, makerStartColumn, makerEndLine, makerEndColumn); + SetPosition(tecp.TextEditor.FileName, tecp.TextEditor.Document, markerStartLine, markerStartColumn, markerEndLine, markerEndColumn); } else { lock (syncObject) { dynamic codeView = viewContent.Control; var document = codeView.TextEditor.Document as IDocument; - SetPosition(null, document, makerStartLine, makerStartColumn, makerEndLine, makerEndColumn); + SetPosition(codeView.Adapter.FileName, document, markerStartLine, markerStartColumn, markerEndLine, markerEndColumn); codeView.IconBarManager.Bookmarks.Add(CurrentLineBookmark.instance); - codeView.UnfoldAndScroll(makerStartLine); + codeView.UnfoldAndScroll(markerStartLine); if (document != null) CurrentLineBookmark.instance.Document = document; } } } - public static void SetPosition(FileName fileName, IDocument document, int makerStartLine, int makerStartColumn, int makerEndLine, int makerEndColumn) + public static void SetPosition(FileName fileName, IDocument document, int markerStartLine, int markerStartColumn, int markerEndLine, int markerEndColumn) { if (document == null) return; Remove(); - startLine = makerStartLine; - startColumn = makerStartColumn; - endLine = makerEndLine; - endColumn = makerEndColumn; + startLine = markerStartLine; + startColumn = markerStartColumn; + endLine = markerEndLine; + endColumn = markerEndColumn; if (startLine < 1 || startLine > document.TotalNumberOfLines) return; diff --git a/src/Main/Base/Project/Src/Services/Debugger/DebuggerService.cs b/src/Main/Base/Project/Src/Services/Debugger/DebuggerService.cs index 15b5e6714e..a63de998ac 100644 --- a/src/Main/Base/Project/Src/Services/Debugger/DebuggerService.cs +++ b/src/Main/Base/Project/Src/Services/Debugger/DebuggerService.cs @@ -2,6 +2,7 @@ // 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 System.Text; @@ -35,7 +36,7 @@ namespace ICSharpCode.SharpDevelop.Debugging BookmarkManager.Added += BookmarkAdded; BookmarkManager.Removed += BookmarkRemoved; - ExternalDebugInformation = new Dictionary<int, object>(); + ExternalDebugInformation = new ConcurrentDictionary<int, object>(); } static void GetDescriptors() @@ -110,7 +111,7 @@ namespace ICSharpCode.SharpDevelop.Debugging /// Gets or sets the external debug information. /// <summary>This constains the code mappings and local variables.</summary> /// </summary> - public static Dictionary<int, object> ExternalDebugInformation { get; set; } + public static ConcurrentDictionary<int, object> ExternalDebugInformation { get; private set; } /// <summary> /// Gets or sets the current token and IL offset. Used for step in/out. @@ -462,4 +463,25 @@ namespace ICSharpCode.SharpDevelop.Debugging DebuggerService.HandleToolTipRequest(e); } } + + /// <summary> + /// Interface for common debugger-decompiler mapping operations. + /// </summary> + public interface IDebuggerDecompilerService + { + /// <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); + } } diff --git a/src/Setup/Files.wxs b/src/Setup/Files.wxs index 0aba4c67a2..5471ba5af9 100644 --- a/src/Setup/Files.wxs +++ b/src/Setup/Files.wxs @@ -1425,8 +1425,6 @@ <File Source="..\..\AddIns\Debugger\Debugger.AddIn.addin" Id="Debugger.AddIn.addin" Name="Debugger.AddIn.addin" /> <File Source="..\..\AddIns\Debugger\Debugger.AddIn.dll" Id="Debugger.AddIn.dll" Name="Debugger.AddIn.dll" /> <File Source="..\..\AddIns\Debugger\Debugger.Core.dll" Id="Debugger.Core.dll" Name="Debugger.Core.dll" /> - <File Source="..\..\AddIns\Debugger\ICSharpCode.NewNRefactory.dll" Id="Debugger.ICSharpCode.NewNRefactory.dll" Name="ICSharpCode.NewNRefactory.dll" /> - <File Source="..\..\AddIns\Debugger\ICSharpCode.Decompiler.dll" Id="Debugger.ICSharpCode.Decompiler.dll" Name="ICSharpCode.Decompiler.dll" /> </Component> </Directory> <Directory Id="MiscAddInsFolder" Name="Misc">