diff options
author | Lluis Sanchez <llsan@microsoft.com> | 2018-03-20 17:05:03 +0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-03-20 17:05:03 +0300 |
commit | f71cc8bbd668d465ddb698a85f0d940b15c0e05a (patch) | |
tree | 39635d49e764e38d61ac2c46ee7bf5eb81f10d09 | |
parent | ac80317172c17015ae47f72f7650b2275bda5d37 (diff) | |
parent | 3157317602c44d38ea9185a03fa70540f95de381 (diff) |
Merge pull request #4193 from mono/d15-6-fix584103
[15.6] Extreme drop in editor performance after update to version
6 files changed, 142 insertions, 17 deletions
diff --git a/main/src/addins/MonoDevelop.Refactoring/MonoDevelop.CodeIssues/CodeDiagnosticRunner.cs b/main/src/addins/MonoDevelop.Refactoring/MonoDevelop.CodeIssues/CodeDiagnosticRunner.cs index 4b7c3f5e1f..0c2ee09a70 100644 --- a/main/src/addins/MonoDevelop.Refactoring/MonoDevelop.CodeIssues/CodeDiagnosticRunner.cs +++ b/main/src/addins/MonoDevelop.Refactoring/MonoDevelop.CodeIssues/CodeDiagnosticRunner.cs @@ -196,7 +196,7 @@ namespace MonoDevelop.CodeIssues if (DataHasTag (data, WellKnownDiagnosticTags.EditAndContinue)) continue; - if (!diagnosticTable [data.Id].IsEnabled) + if (!diagnosticTable.TryGetValue (data.Id, out var desc) || !desc.IsEnabled) continue; var diagnostic = await data.ToDiagnosticAsync (analysisDocument, cancellationToken); diff --git a/main/src/addins/MonoDevelop.SourceEditor2/MonoDevelop.SourceEditor/SourceEditorView.cs b/main/src/addins/MonoDevelop.SourceEditor2/MonoDevelop.SourceEditor/SourceEditorView.cs index 41b20e712f..5747aadd81 100644 --- a/main/src/addins/MonoDevelop.SourceEditor2/MonoDevelop.SourceEditor/SourceEditorView.cs +++ b/main/src/addins/MonoDevelop.SourceEditor2/MonoDevelop.SourceEditor/SourceEditorView.cs @@ -264,6 +264,9 @@ namespace MonoDevelop.SourceEditor Document_MimeTypeChanged(this, EventArgs.Empty);
widget.TextEditor.Document.MimeTypeChanged += Document_MimeTypeChanged; + if (loadedInCtor) { + Document.DiffTracker.SetBaseDocument (Document.CreateDocumentSnapshot ()); + } }
@@ -916,7 +919,7 @@ namespace MonoDevelop.SourceEditor string text = null;
if (loadEncoding == null) {
- text = MonoDevelop.Core.Text.TextFileUtility.ReadAllText(fileName, out loadEncoding);
+ text = TextFileUtility.ReadAllText(fileName, out loadEncoding);
} else {
text = MonoDevelop.Core.Text.TextFileUtility.ReadAllText(fileName, loadEncoding);
}
@@ -929,8 +932,8 @@ namespace MonoDevelop.SourceEditor document.DiffTracker.Reset();
} else {
document.Text = text;
- document.DiffTracker.SetBaseDocument(Document.CreateDocumentSnapshot());
}
+ document.DiffTracker.SetBaseDocument (Document.CreateDocumentSnapshot ()); didLoadCleanly = true; } diff --git a/main/src/core/Mono.TextEditor.Shared/Mono.TextEditor.Utils/CompressingTreeList.cs b/main/src/core/Mono.TextEditor.Shared/Mono.TextEditor.Utils/CompressingTreeList.cs index 068763df76..94ba1a7c36 100644 --- a/main/src/core/Mono.TextEditor.Shared/Mono.TextEditor.Utils/CompressingTreeList.cs +++ b/main/src/core/Mono.TextEditor.Shared/Mono.TextEditor.Utils/CompressingTreeList.cs @@ -37,7 +37,7 @@ namespace Mono.TextEditor.Utils internal class CompressingNode : IRedBlackTreeNode { - internal readonly T value; + internal T value; internal int count, totalCount; public CompressingNode (T value, int count) diff --git a/main/src/core/Mono.TextEditor.Shared/Mono.TextEditor/Document/DiffTracker.cs b/main/src/core/Mono.TextEditor.Shared/Mono.TextEditor/Document/DiffTracker.cs index d35ced6951..2246c19076 100644 --- a/main/src/core/Mono.TextEditor.Shared/Mono.TextEditor/Document/DiffTracker.cs +++ b/main/src/core/Mono.TextEditor.Shared/Mono.TextEditor/Document/DiffTracker.cs @@ -33,9 +33,13 @@ namespace Mono.TextEditor { class LineChangeInfo { + internal readonly static LineChangeInfo Unchanged = new LineChangeInfo (TextDocument.LineState.Unchanged); + internal readonly static LineChangeInfo Dirty = new LineChangeInfo (TextDocument.LineState.Dirty); + internal readonly static LineChangeInfo Changed = new LineChangeInfo (TextDocument.LineState.Changed); + public Mono.TextEditor.TextDocument.LineState state; - public LineChangeInfo (Mono.TextEditor.TextDocument.LineState state) + LineChangeInfo (Mono.TextEditor.TextDocument.LineState state) { this.state = state; } @@ -70,7 +74,9 @@ namespace Mono.TextEditor if (lineStates == null) return; for(int i = e.TextChanges.Count - 1; i >= 0; i--) {
- var change = e.TextChanges[i];
+ var change = e.TextChanges[i]; + if (change.RemovalLength == 0) + continue;
var startLine = trackDocument.GetLineByOffset (change.Offset); var endRemoveLine = trackDocument.GetLineByOffset (change.Offset + change.RemovalLength); if (startLine == null || endRemoveLine == null) @@ -91,17 +97,20 @@ namespace Mono.TextEditor var startLine = trackDocument.GetLineByOffset (change.NewOffset); var endLine = trackDocument.GetLineByOffset (change.NewOffset + change.InsertionLength); var lineNumber = startLine.LineNumber; - var oldState = lineNumber < lineStates.Count ? lineStates [lineNumber] : null; - if (oldState != null && oldState.state == TextDocument.LineState.Dirty) - continue; var insertedLines = endLine.LineNumber - lineNumber; + if (insertedLines == 0) { + var oldState = lineNumber < lineStates.Count ? lineStates [lineNumber] : null; + if (oldState != null && oldState.state == TextDocument.LineState.Dirty) + continue; + lineStates[lineNumber] = LineChangeInfo.Dirty; + if (trackDocument != null) + trackDocument.CommitMultipleLineUpdate (lineNumber, lineNumber + insertedLines); + continue; + } try { - lineStates [lineNumber] = new LineChangeInfo (Mono.TextEditor.TextDocument.LineState.Dirty); + lineStates.InsertRange (lineNumber, insertedLines , LineChangeInfo.Dirty); if (trackDocument != null) - trackDocument.CommitLineUpdate (lineNumber); - while (insertedLines-- > 0) { - lineStates.Insert (lineNumber, new LineChangeInfo (Mono.TextEditor.TextDocument.LineState.Dirty)); - } + trackDocument.CommitMultipleLineUpdate (lineNumber, lineNumber + insertedLines); } catch (Exception ex) { Console.WriteLine ("error while DiffTracker.TrackDocument_TextChanged:" + ex); } @@ -113,11 +122,11 @@ namespace Mono.TextEditor if (lineStates != null) { foreach (var node in lineStates.tree) { if (node.value.state == Mono.TextEditor.TextDocument.LineState.Dirty) - node.value.state = Mono.TextEditor.TextDocument.LineState.Changed; + node.value = LineChangeInfo.Changed; } } else { lineStates = new CompressingTreeList<LineChangeInfo>((x, y) => x.Equals(y)); - lineStates.InsertRange(0, document.LineCount + 1, new LineChangeInfo (Mono.TextEditor.TextDocument.LineState.Unchanged)); + lineStates.InsertRange (0, document.LineCount + 1, LineChangeInfo.Unchanged); trackDocument.TextChanging += TrackDocument_TextChanging; trackDocument.TextChanged += TrackDocument_TextChanged; } @@ -126,7 +135,7 @@ namespace Mono.TextEditor public void Reset () { lineStates = new CompressingTreeList<LineChangeInfo>((x, y) => x.Equals(y)); - lineStates.InsertRange(0, trackDocument.LineCount + 1, new LineChangeInfo (Mono.TextEditor.TextDocument.LineState.Unchanged)); + lineStates.InsertRange(0, trackDocument.LineCount + 1, LineChangeInfo.Unchanged); } } } diff --git a/main/src/core/MonoDevelop.TextEditor.Tests/Mono.TextEditor.Tests/DiffTrackerTests.cs b/main/src/core/MonoDevelop.TextEditor.Tests/Mono.TextEditor.Tests/DiffTrackerTests.cs new file mode 100644 index 0000000000..4cc2648f66 --- /dev/null +++ b/main/src/core/MonoDevelop.TextEditor.Tests/Mono.TextEditor.Tests/DiffTrackerTests.cs @@ -0,0 +1,112 @@ +// +// DiffTrackerTests.cs +// +// Author: +// Mike Krüger <mikkrg@microsoft.com> +// +// Copyright (c) 2018 Microsoft Corporation. All rights reserved. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +using System; +using System.Collections.Generic; +using NUnit.Framework; +using System.Linq; +using Mono.TextEditor.Utils; +using System.Text; + +namespace Mono.TextEditor.Tests +{ + [TestFixture] + public class DiffTrackerTests + { + static TextDocument GetDocument () + { + TextDocument doc = new TextDocument (); + StringBuilder sb = new StringBuilder (); + for (int i = 0; i < 10; i++) + sb.AppendLine ("1234567890"); + doc.Text = sb.ToString (); + doc.DiffTracker.SetBaseDocument (doc.CreateDocumentSnapshot ()); + + return doc; + } + + [Test] + public void TestInsertChanged () + { + var doc = GetDocument (); + Assert.AreEqual (TextDocument.LineState.Unchanged, doc.DiffTracker.GetLineState (doc.GetLine (5))); + doc.InsertText (doc.GetLine (5).Offset, "Hello"); + Assert.AreEqual (TextDocument.LineState.Dirty, doc.DiffTracker.GetLineState (doc.GetLine (5))); + } + + [Test] + public void TestRemoveChanged () + { + var doc = GetDocument (); + Assert.AreEqual (TextDocument.LineState.Unchanged, doc.DiffTracker.GetLineState (doc.GetLine (5))); + doc.RemoveText (doc.GetLine (5).Offset, 1); + Assert.AreEqual (TextDocument.LineState.Dirty, doc.DiffTracker.GetLineState (doc.GetLine (5))); + } + + [Test] + public void TestInsertLine () + { + var doc = GetDocument (); + Assert.AreEqual (TextDocument.LineState.Unchanged, doc.DiffTracker.GetLineState (doc.GetLine (5))); + doc.InsertText (doc.GetLine (5).Offset, "Hello\n"); + Assert.AreEqual (TextDocument.LineState.Dirty, doc.DiffTracker.GetLineState (doc.GetLine (5))); + } + + [Test] + public void TestRemoveLine () + { + var doc = GetDocument (); + Assert.AreEqual (TextDocument.LineState.Unchanged, doc.DiffTracker.GetLineState (doc.GetLine (5))); + doc.RemoveText (doc.GetLine (5).Offset, doc.GetLine (5).LengthIncludingDelimiter); + Assert.AreEqual (TextDocument.LineState.Dirty, doc.DiffTracker.GetLineState (doc.GetLine (5))); + } + + [Test] + public void TestLowerLineChangeOnInsert () + { + var doc = GetDocument (); + Assert.AreEqual (TextDocument.LineState.Unchanged, doc.DiffTracker.GetLineState (doc.GetLine (5))); + doc.InsertText (doc.GetLine (7).Offset, "Hello\n"); + doc.InsertText (doc.GetLine (5).Offset, "Hello\n"); + Assert.AreEqual (TextDocument.LineState.Dirty, doc.DiffTracker.GetLineState (doc.GetLine (5))); + Assert.AreEqual (TextDocument.LineState.Unchanged, doc.DiffTracker.GetLineState (doc.GetLine (7))); + Assert.AreEqual (TextDocument.LineState.Dirty, doc.DiffTracker.GetLineState (doc.GetLine (8))); + } + + + [Test] + public void TestLowerLineChangeOnRemove () + { + var doc = GetDocument (); + Assert.AreEqual (TextDocument.LineState.Unchanged, doc.DiffTracker.GetLineState (doc.GetLine (5))); + doc.InsertText (doc.GetLine (7).Offset, "Hello\n"); + doc.RemoveText (doc.GetLine (5).Offset, doc.GetLine (5).LengthIncludingDelimiter); + Assert.AreEqual (TextDocument.LineState.Dirty, doc.DiffTracker.GetLineState (doc.GetLine (5))); + Assert.AreEqual (TextDocument.LineState.Unchanged, doc.DiffTracker.GetLineState (doc.GetLine (7))); + Assert.AreEqual (TextDocument.LineState.Dirty, doc.DiffTracker.GetLineState (doc.GetLine (6))); + } + + } +} diff --git a/main/src/core/MonoDevelop.TextEditor.Tests/MonoDevelop.TextEditor.Tests.csproj b/main/src/core/MonoDevelop.TextEditor.Tests/MonoDevelop.TextEditor.Tests.csproj index ed0861d6bf..2e81e3c00d 100644 --- a/main/src/core/MonoDevelop.TextEditor.Tests/MonoDevelop.TextEditor.Tests.csproj +++ b/main/src/core/MonoDevelop.TextEditor.Tests/MonoDevelop.TextEditor.Tests.csproj @@ -80,6 +80,7 @@ <Compile Include="Mono.TextEditor.Tests\SemanticRuleTests.cs" /> <Compile Include="Mono.TextEditor.Tests\TextEditorDataTests.cs" /> <Compile Include="MonoDevelop.TextEditor.Extension\NavigationExtensionTests.cs" /> + <Compile Include="Mono.TextEditor.Tests\DiffTrackerTests.cs" /> </ItemGroup> <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" /> <ItemGroup> |