diff options
author | Mike Krüger <mikkrg@microsoft.com> | 2019-08-08 12:30:20 +0300 |
---|---|---|
committer | monojenkins <jo.shields+jenkins@xamarin.com> | 2019-08-15 18:58:00 +0300 |
commit | b5a82b5fb052736f5674caf80683463cefa88f71 (patch) | |
tree | 31fd3d6e299b6fb4b584fbd32458a39878163eab /main | |
parent | fb1b3652a9f98b6c5ea3bc63a267773338938506 (diff) |
Fixes VSTS Bug 959146: System.NullReferenceException exception in Mono.TextEditor.Utils.TextBreaker.BreakLinesIntoWords()
https://devdiv.visualstudio.com/DevDiv/_workitems/edit/959146
I can't find the cause of it. I checked the parameters of
BreakLinesIntoWords now. The diff must be out of sync with the text
document that should now not happen, it's checked before paint that
the versions match. In any case that implementation is more solid.
Diffstat (limited to 'main')
2 files changed, 48 insertions, 2 deletions
diff --git a/main/src/addins/VersionControl/MonoDevelop.VersionControl/MonoDevelop.VersionControl.Views/EditorCompareWidgetBase.cs b/main/src/addins/VersionControl/MonoDevelop.VersionControl/MonoDevelop.VersionControl.Views/EditorCompareWidgetBase.cs index df71cb3487..1f10044251 100644 --- a/main/src/addins/VersionControl/MonoDevelop.VersionControl/MonoDevelop.VersionControl.Views/EditorCompareWidgetBase.cs +++ b/main/src/addins/VersionControl/MonoDevelop.VersionControl/MonoDevelop.VersionControl.Views/EditorCompareWidgetBase.cs @@ -40,6 +40,7 @@ using MonoDevelop.Projects.Text; using MonoDevelop.Core.Text; using MonoDevelop.Ide.Editor; using Microsoft.VisualStudio.Text; +using MonoDevelop.Ide.TextEditing; namespace MonoDevelop.VersionControl.Views { @@ -68,6 +69,7 @@ namespace MonoDevelop.VersionControl.Views set { leftDiff = value; OnDiffChanged (EventArgs.Empty); + SetDiffEditorVersions (); } } @@ -77,9 +79,32 @@ namespace MonoDevelop.VersionControl.Views set { rightDiff = value; OnDiffChanged (EventArgs.Empty); + SetDiffEditorVersions (); } } - + + ITextSourceVersion [] diffVersions; + + void SetDiffEditorVersions () + { + if (diffVersions == null) // editors.Length never changes + diffVersions = new ITextSourceVersion [editors.Length]; + for (int i = 0; i < editors.Length; i++) { + diffVersions [i] = editors [i].Document.Version; + } + } + + bool IsEditorDiffValid () + { + if (diffVersions == null) + return false; + for (int i = 0; i < editors.Length; i++) { + if (diffVersions [i].CompareAge (editors [i].Document.Version) != 0) + return false; + } + return true; + } + internal abstract MonoTextEditor MainEditor { get; } @@ -147,11 +172,15 @@ namespace MonoDevelop.VersionControl.Views if (editors.Length == 2) { editors[0].Painted += delegate (object sender, PaintEventArgs args) { + if (!IsEditorDiffValid ()) + return; var myEditor = (TextArea)sender; PaintEditorOverlay (myEditor, args, LeftDiff, true); }; editors[1].Painted += delegate (object sender, PaintEventArgs args) { + if (!IsEditorDiffValid ()) + return; var myEditor = (TextArea)sender; PaintEditorOverlay (myEditor, args, LeftDiff, false); }; @@ -160,15 +189,21 @@ namespace MonoDevelop.VersionControl.Views Add (rightDiffScrollBar); } else { editors[0].Painted += delegate (object sender, PaintEventArgs args) { + if (!IsEditorDiffValid ()) + return; var myEditor = (TextArea)sender; PaintEditorOverlay (myEditor, args, LeftDiff, true); }; editors[1].Painted += delegate (object sender, PaintEventArgs args) { + if (!IsEditorDiffValid ()) + return; var myEditor = (TextArea)sender; PaintEditorOverlay (myEditor, args, LeftDiff, false); PaintEditorOverlay (myEditor, args, RightDiff, false); }; editors[2].Painted += delegate (object sender, PaintEventArgs args) { + if (!IsEditorDiffValid ()) + return; var myEditor = (TextArea)sender; PaintEditorOverlay (myEditor, args, RightDiff, true); }; @@ -287,7 +322,9 @@ namespace MonoDevelop.VersionControl.Views static List<ISegment> BreakTextInWords (MonoTextEditor editor, int start, int count) { - return TextBreaker.BreakLinesIntoWords(editor, start, count); + var s = Math.Min (start, editor.LineCount); + var c = Math.Min (count, editor.LineCount - (s - 1)); + return TextBreaker.BreakLinesIntoWords(editor, s, c); } static List<Cairo.Rectangle> CalculateChunkPath (MonoTextEditor editor, List<Hunk> diff, List<ISegment> words, bool useRemove) diff --git a/main/src/core/Mono.TextEditor.Shared/Mono.TextEditor.Utils/TextBreaker.cs b/main/src/core/Mono.TextEditor.Shared/Mono.TextEditor.Utils/TextBreaker.cs index 5be96e1b53..a727db5439 100644 --- a/main/src/core/Mono.TextEditor.Shared/Mono.TextEditor.Utils/TextBreaker.cs +++ b/main/src/core/Mono.TextEditor.Shared/Mono.TextEditor.Utils/TextBreaker.cs @@ -25,6 +25,7 @@ // THE SOFTWARE. using System; using System.Collections.Generic; +using MonoDevelop.Core; using MonoDevelop.Core.Text; namespace Mono.TextEditor.Utils @@ -74,9 +75,17 @@ namespace Mono.TextEditor.Utils /// </param> public static List<ISegment> BreakLinesIntoWords (TextDocument document, int startLine, int lineCount, bool includeDelimiter = true) { + if (document is null) + throw new ArgumentNullException (nameof (document)); + if (startLine < 1) + throw new ArgumentOutOfRangeException (nameof (startLine), "startLine >= 1, was " + startLine); + if (startLine - 1 + lineCount > document.LineCount) + throw new ArgumentOutOfRangeException (nameof (startLine), "startLine + lineCount <= " + (document.LineCount + 1) + ", was " + startLine); var result = new List<ISegment> (); for (int line = startLine; line < startLine + lineCount; line++) { var lineSegment = document.GetLine (line); + if (lineSegment == null) + continue; int offset = lineSegment.Offset; bool wasIdentifierPart = false; int lastWordEnd = 0; |