diff options
author | Lluis Sanchez <llsan@microsoft.com> | 2019-06-07 17:24:45 +0300 |
---|---|---|
committer | Lluis Sanchez <llsan@microsoft.com> | 2019-06-07 17:24:45 +0300 |
commit | adc0c4e33b695c315488262c3c09112e87800111 (patch) | |
tree | e4c93ea740a9d3b691e14fd04878c98adc4c34de /main/src/addins/MonoDevelop.Debugger | |
parent | 526ae087002e5e8aba0c5430fea9142942f85635 (diff) | |
parent | b19a7bf2d6a71057f0820de1c12b9a5faa7d9b53 (diff) |
Merge remote-tracking branch 'origin/master' into release-8.2monodevelop-8.2.0.707
Diffstat (limited to 'main/src/addins/MonoDevelop.Debugger')
7 files changed, 159 insertions, 70 deletions
diff --git a/main/src/addins/MonoDevelop.Debugger/MonoDevelop.Debugger.VSTextView/BreakpointManager.cs b/main/src/addins/MonoDevelop.Debugger/MonoDevelop.Debugger.VSTextView/BreakpointManager.cs index f3f690e450..93058fe629 100644 --- a/main/src/addins/MonoDevelop.Debugger/MonoDevelop.Debugger.VSTextView/BreakpointManager.cs +++ b/main/src/addins/MonoDevelop.Debugger/MonoDevelop.Debugger.VSTextView/BreakpointManager.cs @@ -37,15 +37,17 @@ namespace MonoDevelop.Debugger void TextBuffer_Changed (object sender, TextContentChangedEventArgs e) { foreach (var breakpoint in breakpoints.Values) { - var newSpan = breakpoint.TrackingSpan.GetSpan (e.After); - if (newSpan.IsEmpty) { + var span = breakpoint.TrackingSpan.GetSpan (e.After); + + if (span.IsEmpty || string.IsNullOrWhiteSpace (span.GetText ())) { DebuggingService.Breakpoints.Remove (breakpoint.Breakpoint); continue; } - var newLineNumber = e.After.GetLineFromPosition (newSpan.Start).LineNumber + 1; - if (breakpoint.Breakpoint.Line != newLineNumber) { + + var newLineNumber = e.After.GetLineFromPosition (span.Start).LineNumber + 1; + + if (breakpoint.Breakpoint.Line != newLineNumber) DebuggingService.Breakpoints.UpdateBreakpointLine (breakpoint.Breakpoint, newLineNumber); - } } } @@ -58,38 +60,47 @@ namespace MonoDevelop.Debugger private Dictionary<Breakpoint, ManagerBreakpoint> breakpoints = new Dictionary<Breakpoint, ManagerBreakpoint> (); - private void OnBreakpointsChanged (object sender, EventArgs eventArgs) + private async void OnBreakpointsChanged (object sender, EventArgs eventArgs) { - var snapshot = textBuffer.CurrentSnapshot; var newBreakpoints = new Dictionary<Breakpoint, ManagerBreakpoint> (); - bool needsUpdate = false; + var snapshot = textBuffer.CurrentSnapshot; + var needsUpdate = false; + foreach (var breakpoint in DebuggingService.Breakpoints.GetBreakpointsAtFile (textDocument.FilePath)) { if (breakpoint.Line > snapshot.LineCount) continue; + if (eventArgs is BreakpointEventArgs breakpointEventArgs && breakpointEventArgs.Breakpoint == breakpoint) needsUpdate = true; - var newSpan = snapshot.GetLineFromLineNumber (breakpoint.Line - 1).Extent; + + var line = snapshot.GetLineFromLineNumber (breakpoint.Line - 1); + var position = line.Start.Position + breakpoint.Column; + var span = await DebuggingService.GetBreakpointSpanAsync (textDocument, position); + if (breakpoints.TryGetValue (breakpoint, out var existingBreakpoint)) { newBreakpoints.Add (breakpoint, existingBreakpoint); - if (existingBreakpoint.Span != newSpan.Span) { - // Update if anything was modifed + if (existingBreakpoint.Span != span) { + // Update if anything was modified + existingBreakpoint.Span = span; needsUpdate = true; - existingBreakpoint.Span = newSpan.Span; } } else { // Update if anything was added - needsUpdate = true; - newBreakpoints.Add (breakpoint, new ManagerBreakpoint () { + newBreakpoints.Add (breakpoint, new ManagerBreakpoint { Breakpoint = breakpoint, - TrackingSpan = snapshot.CreateTrackingSpan (newSpan, SpanTrackingMode.EdgeExclusive), - Span = newSpan.Span + TrackingSpan = snapshot.CreateTrackingSpan (span, SpanTrackingMode.EdgeExclusive), + Span = span }); + needsUpdate = true; } } + // Update if anything was removed if (needsUpdate || breakpoints.Keys.Except (newBreakpoints.Keys).Any ()) needsUpdate = true; + breakpoints = newBreakpoints; + if (needsUpdate) BreakpointsChanged?.Invoke (this, new SnapshotSpanEventArgs (new SnapshotSpan (snapshot, 0, snapshot.Length))); } diff --git a/main/src/addins/MonoDevelop.Debugger/MonoDevelop.Debugger.csproj b/main/src/addins/MonoDevelop.Debugger/MonoDevelop.Debugger.csproj index 12b7e203fb..bdecc781e7 100644 --- a/main/src/addins/MonoDevelop.Debugger/MonoDevelop.Debugger.csproj +++ b/main/src/addins/MonoDevelop.Debugger/MonoDevelop.Debugger.csproj @@ -174,6 +174,8 @@ <Compile Include="MonoDevelop.Debugger.VSTextView\QuickInfo\IDebugInfoProvider.cs" /> <Compile Include="MonoDevelop.Debugger.VSTextView\BreakpointManagerService.cs" /> <Compile Include="MonoDevelop.Debugger.VSTextView\BreakpointManager.cs" /> + <Compile Include="MonoDevelop.Debugger\IBreakpointSpanResolver.cs" /> + <Compile Include="MonoDevelop.Debugger\DefaultBreakpointSpanResolver.cs" /> </ItemGroup> <ItemGroup Condition="$(OS) != 'Windows_NT'"> <Compile Include="MonoDevelop.Debugger.VSTextView\ExceptionCaught\ExceptionCaughtProvider.cs" /> diff --git a/main/src/addins/MonoDevelop.Debugger/MonoDevelop.Debugger/DebuggingService.cs b/main/src/addins/MonoDevelop.Debugger/MonoDevelop.Debugger/DebuggingService.cs index 950385ee18..9e19487fc4 100644 --- a/main/src/addins/MonoDevelop.Debugger/MonoDevelop.Debugger/DebuggingService.cs +++ b/main/src/addins/MonoDevelop.Debugger/MonoDevelop.Debugger/DebuggingService.cs @@ -1331,11 +1331,19 @@ namespace MonoDevelop.Debugger static void OnLineCountChanged (object ob, LineCountEventArgs a) { lock (breakpoints) { - foreach (Breakpoint bp in breakpoints.GetBreakpoints ()) { + foreach (var bp in breakpoints.GetBreakpoints ()) { if (bp.FileName == a.TextFile.Name) { if (bp.Line > a.LineNumber) { + var startIndex = a.TextFile.GetPositionFromLineColumn (bp.Line, bp.Column); + var endIndex = a.TextFile.GetPositionFromLineColumn (bp.Line + 1, 0) - 1; + + if (endIndex < startIndex) + endIndex = startIndex; + + var text = a.TextFile.GetText (startIndex, endIndex); + // If the line that has the breakpoint is deleted, delete the breakpoint, otherwise update the line #. - if (bp.Line + a.LineCount >= a.LineNumber) + if (bp.Line + a.LineCount >= a.LineNumber && !string.IsNullOrWhiteSpace (text)) breakpoints.UpdateBreakpointLine (bp, bp.Line + a.LineCount); else breakpoints.Remove (bp); @@ -1482,6 +1490,19 @@ namespace MonoDevelop.Debugger return result; return frame.GetExpressionCompletionData (exp); } + + public static Task<Span> GetBreakpointSpanAsync (ITextDocument document, int position, CancellationToken cancellationToken = default (CancellationToken)) + { + var doc = IdeApp.Workbench.GetDocument (document.FilePath); + IBreakpointSpanResolver resolver = null; + + if (doc != null) + resolver = doc.GetContent<IBreakpointSpanResolver> (); + + resolver = resolver ?? new DefaultBreakpointSpanResolver (); + + return resolver.GetBreakpointSpanAsync (document.TextBuffer, position, cancellationToken); + } } class FeatureCheckerHandlerFactory : IExecutionHandler diff --git a/main/src/addins/MonoDevelop.Debugger/MonoDevelop.Debugger/DefaultBreakpointSpanResolver.cs b/main/src/addins/MonoDevelop.Debugger/MonoDevelop.Debugger/DefaultBreakpointSpanResolver.cs new file mode 100644 index 0000000000..19c245fafb --- /dev/null +++ b/main/src/addins/MonoDevelop.Debugger/MonoDevelop.Debugger/DefaultBreakpointSpanResolver.cs @@ -0,0 +1,47 @@ +// +// DefaultBreakpointSpanResolver.cs +// +// Author: +// Jeffrey Stedfast <jestedfa@microsoft.com> +// +// Copyright (c) 2019 Microsoft Corp. +// +// 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.Threading; +using System.Threading.Tasks; + +using Microsoft.VisualStudio.Text; + +namespace MonoDevelop.Debugger +{ + public class DefaultBreakpointSpanResolver : IBreakpointSpanResolver + { + public Task<Span> GetBreakpointSpanAsync (ITextBuffer buffer, int position, CancellationToken cancellationToken) + { + try { + var line = buffer.CurrentSnapshot.GetLineFromPosition (position); + + return Task.FromResult (Span.FromBounds (line.Start.Position, line.End.Position)); + } catch { + return Task.FromResult (default (Span)); + } + } + } +} diff --git a/main/src/addins/MonoDevelop.Debugger/MonoDevelop.Debugger/IBreakpointSpanResolver.cs b/main/src/addins/MonoDevelop.Debugger/MonoDevelop.Debugger/IBreakpointSpanResolver.cs new file mode 100644 index 0000000000..25f337ac54 --- /dev/null +++ b/main/src/addins/MonoDevelop.Debugger/MonoDevelop.Debugger/IBreakpointSpanResolver.cs @@ -0,0 +1,48 @@ +// +// IBreakpointSpanResolver.cs +// +// Author: +// Jeffrey Stedfast <jestedfa@microsoft.com> +// +// Copyright (c) 2019 Microsoft Corp. +// +// 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.Threading; +using System.Threading.Tasks; + +using Microsoft.VisualStudio.Text; + +namespace MonoDevelop.Debugger +{ + /// <summary> + /// An interface for resolving the span of a breakpoint. + /// </summary> + public interface IBreakpointSpanResolver + { + /// <summary> + /// Resolve the span of a breakpoint. + /// </summary> + /// <param name="buffer">The text buffer.</param> + /// <param name="position">The cursor position.</param> + /// <param name="cancellationToken">The cancellation token.</param> + /// <returns>The span of the breakpoint.</returns> + Task<Span> GetBreakpointSpanAsync (ITextBuffer buffer, int position, CancellationToken cancellationToken); + } +} diff --git a/main/src/addins/MonoDevelop.Debugger/MonoDevelop.Debugger/ObjectValueTreeView.cs b/main/src/addins/MonoDevelop.Debugger/MonoDevelop.Debugger/ObjectValueTreeView.cs index a7f5cb353d..afceba6802 100644 --- a/main/src/addins/MonoDevelop.Debugger/MonoDevelop.Debugger/ObjectValueTreeView.cs +++ b/main/src/addins/MonoDevelop.Debugger/MonoDevelop.Debugger/ObjectValueTreeView.cs @@ -947,15 +947,15 @@ namespace MonoDevelop.Debugger } int numberOfChildren = store.IterNChildren (iter); - Task.Factory.StartNew<ObjectValue[]> (delegate (object arg) { + Task.Run (() => { try { - return ((ObjectValue)arg).GetRangeOfChildren (numberOfChildren - 1, 20); + return value.GetRangeOfChildren (numberOfChildren - 1, 20); } catch (Exception ex) { // Note: this should only happen if someone breaks ObjectValue.GetAllChildren() LoggingService.LogError ("Failed to get ObjectValue children.", ex); return new ObjectValue[0]; } - }, value, cancellationTokenSource.Token).ContinueWith (t => { + }, cancellationTokenSource.Token).ContinueWith (t => { TreeIter it; if (disposed) return; @@ -975,7 +975,7 @@ namespace MonoDevelop.Debugger if (compact) RecalculateWidth (); enumerableLoading.Remove (value); - }, cancellationTokenSource.Token, TaskContinuationOptions.NotOnCanceled, Xwt.Application.UITaskScheduler); + }, cancellationTokenSource.Token, TaskContinuationOptions.NotOnCanceled, Runtime.MainTaskScheduler).Ignore (); } void RefreshRow (TreeIter iter, ObjectValue val) diff --git a/main/src/addins/MonoDevelop.Debugger/MonoDevelop.Debugger/SourceCodeLookup.cs b/main/src/addins/MonoDevelop.Debugger/MonoDevelop.Debugger/SourceCodeLookup.cs index bd69d29c79..91cc41a8e8 100644 --- a/main/src/addins/MonoDevelop.Debugger/MonoDevelop.Debugger/SourceCodeLookup.cs +++ b/main/src/addins/MonoDevelop.Debugger/MonoDevelop.Debugger/SourceCodeLookup.cs @@ -23,15 +23,17 @@ // 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 MonoDevelop.Core; -using System.Collections.Generic; using System.IO; -using System.Security.Cryptography; using System.Linq; +using System.Collections.Generic; + +using Mono.Debugging.Client; + using MonoDevelop.Ide; +using MonoDevelop.Core; using MonoDevelop.Projects; -using Mono.Debugging.Client; namespace MonoDevelop.Debugger { @@ -120,50 +122,9 @@ namespace MonoDevelop.Debugger return FilePath.Null; } - public static bool CheckFileHash (FilePath file, byte[] hash) + public static bool CheckFileHash (FilePath path, byte[] checksum) { - if (hash == null) - return false; - if (File.Exists (file)) { - using (var fs = File.OpenRead (file)) { - // Roslyn SHA1 checksum always starts with 20 - if (hash.Length > 0 && hash [0] == 20) - using (var sha1 = SHA1.Create ()) { - if (sha1.ComputeHash (fs).Take (15).SequenceEqual (hash.Skip (1))) { - return true; - } - } - if (hash.Length > 0 && hash [0] == 32) - using (var sha1 = SHA256.Create ()) { - if (sha1.ComputeHash (fs).Take (15).SequenceEqual (hash.Skip (1))) { - return true; - } - } - if (hash.Length == 20) { - using (var sha1 = SHA1.Create ()) { - fs.Position = 0; - if (sha1.ComputeHash (fs).SequenceEqual (hash)) { - return true; - } - } - } - if (hash.Length == 32) { - using (var sha256 = SHA256.Create ()) { - fs.Position = 0; - if (sha256.ComputeHash (fs).SequenceEqual (hash)) { - return true; - } - } - } - fs.Position = 0; - using (var md5 = MD5.Create ()) { - if (md5.ComputeHash (fs).SequenceEqual (hash)) { - return true; - } - } - } - } - return false; + return SourceLocation.CheckFileHash (path, checksum); } /// <summary> @@ -223,4 +184,3 @@ namespace MonoDevelop.Debugger } } } - |