Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/microsoft/vs-editor-api.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKirill Osenkov <github@osenkov.com>2018-08-15 21:13:16 +0300
committerKirill Osenkov <github@osenkov.com>2018-08-15 21:13:16 +0300
commitb407d9744a34fd4647cf3e99068a28d728fd65a2 (patch)
treee6d6cef915f32dec4f2d16b1868045143deb589f /src/Text/Impl/ClassificationAggregator
parentcf974b266fb428d846e2e16a25a4eeb8f635c26f (diff)
Updating to VS-Platform 15.8.519 (29d85337c7d2af248a692fd65ac37b444551e4cf).
Diffstat (limited to 'src/Text/Impl/ClassificationAggregator')
-rw-r--r--src/Text/Impl/ClassificationAggregator/ClassifierAggregator.cs14
-rw-r--r--src/Text/Impl/ClassificationAggregator/ClassifierTagger.cs2
-rw-r--r--src/Text/Impl/ClassificationAggregator/ProjectionWorkaround.cs91
3 files changed, 45 insertions, 62 deletions
diff --git a/src/Text/Impl/ClassificationAggregator/ClassifierAggregator.cs b/src/Text/Impl/ClassificationAggregator/ClassifierAggregator.cs
index b10eee8..95b3bdf 100644
--- a/src/Text/Impl/ClassificationAggregator/ClassifierAggregator.cs
+++ b/src/Text/Impl/ClassificationAggregator/ClassifierAggregator.cs
@@ -37,15 +37,15 @@ namespace Microsoft.VisualStudio.Text.Classification.Implementation
// Validate.
if (textBuffer == null)
{
- throw new ArgumentNullException("textBuffer");
+ throw new ArgumentNullException(nameof(textBuffer));
}
if (bufferTagAggregatorFactory == null)
{
- throw new ArgumentNullException("bufferTagAggregatorFactory");
+ throw new ArgumentNullException(nameof(bufferTagAggregatorFactory));
}
if (classificationTypeRegistry == null)
{
- throw new ArgumentNullException("classificationTypeRegistry");
+ throw new ArgumentNullException(nameof(classificationTypeRegistry));
}
_textBuffer = textBuffer;
@@ -63,15 +63,15 @@ namespace Microsoft.VisualStudio.Text.Classification.Implementation
// Validate.
if (textView == null)
{
- throw new ArgumentNullException("textView");
+ throw new ArgumentNullException(nameof(textView));
}
if (viewTagAggregatorFactory == null)
{
- throw new ArgumentNullException("viewTagAggregatorFactory");
+ throw new ArgumentNullException(nameof(viewTagAggregatorFactory));
}
if (classificationTypeRegistry == null)
{
- throw new ArgumentNullException("classificationTypeRegistry");
+ throw new ArgumentNullException(nameof(classificationTypeRegistry));
}
_textBuffer = textView.TextBuffer;
@@ -336,7 +336,7 @@ namespace Microsoft.VisualStudio.Text.Classification.Implementation
return results;
}
- private int Compare(PointData a, PointData b)
+ private static int Compare(PointData a, PointData b)
{
if (a.Position == b.Position)
return (b.IsStart.CompareTo(a.IsStart)); // startpoints go before end points when positions are tied
diff --git a/src/Text/Impl/ClassificationAggregator/ClassifierTagger.cs b/src/Text/Impl/ClassificationAggregator/ClassifierTagger.cs
index 653e768..4871c38 100644
--- a/src/Text/Impl/ClassificationAggregator/ClassifierTagger.cs
+++ b/src/Text/Impl/ClassificationAggregator/ClassifierTagger.cs
@@ -70,7 +70,9 @@ namespace Microsoft.VisualStudio.Text.Classification.Implementation
#region IDisposable members
+#pragma warning disable CA1063 // Implement IDisposable Correctly
public void Dispose()
+#pragma warning restore CA1063 // Implement IDisposable Correctly
{
foreach(var classifier in Classifiers)
{
diff --git a/src/Text/Impl/ClassificationAggregator/ProjectionWorkaround.cs b/src/Text/Impl/ClassificationAggregator/ProjectionWorkaround.cs
index 35a5835..b2a65a3 100644
--- a/src/Text/Impl/ClassificationAggregator/ProjectionWorkaround.cs
+++ b/src/Text/Impl/ClassificationAggregator/ProjectionWorkaround.cs
@@ -9,12 +9,9 @@ namespace Microsoft.VisualStudio.Text.Classification.Implementation
{
using System;
using System.Collections.Generic;
- using System.Collections.ObjectModel;
using System.ComponentModel.Composition;
- using Microsoft.VisualStudio.Text.Differencing;
using Microsoft.VisualStudio.Text.Projection;
using Microsoft.VisualStudio.Text.Tagging;
- using Microsoft.VisualStudio.Text.Utilities;
using Microsoft.VisualStudio.Utilities;
[Export(typeof(ITaggerProvider))]
@@ -22,16 +19,13 @@ namespace Microsoft.VisualStudio.Text.Classification.Implementation
[TagType(typeof(ClassificationTag))]
internal class ProjectionWorkaroundProvider : ITaggerProvider
{
- [Import]
- internal IDifferenceService diffService { get; set; }
-
public ITagger<T> CreateTagger<T>(ITextBuffer buffer) where T : ITag
{
IProjectionBuffer projectionBuffer = buffer as IProjectionBuffer;
if (projectionBuffer == null)
return null;
- return new ProjectionWorkaroundTagger(projectionBuffer, diffService) as ITagger<T>;
+ return new ProjectionWorkaroundTagger(projectionBuffer) as ITagger<T>;
}
}
@@ -45,82 +39,69 @@ namespace Microsoft.VisualStudio.Text.Classification.Implementation
internal class ProjectionWorkaroundTagger : ITagger<ClassificationTag>
{
IProjectionBuffer ProjectionBuffer { get; set; }
- IDifferenceService diffService;
- internal ProjectionWorkaroundTagger(IProjectionBuffer projectionBuffer, IDifferenceService diffService)
+ internal ProjectionWorkaroundTagger(IProjectionBuffer projectionBuffer)
{
this.ProjectionBuffer = projectionBuffer;
- this.diffService = diffService;
this.ProjectionBuffer.SourceBuffersChanged += SourceSpansChanged;
}
#region ITagger<ClassificationTag> members
public IEnumerable<ITagSpan<ClassificationTag>> GetTags(NormalizedSnapshotSpanCollection spans)
{
- yield break;
+ return Array.Empty<ITagSpan<ClassificationTag>>();
}
public event EventHandler<SnapshotSpanEventArgs> TagsChanged;
-
#endregion
#region Source span differencing + change event
private void SourceSpansChanged(object sender, ProjectionSourceSpansChangedEventArgs e)
{
- if (e.Changes.Count == 0)
+ var handler = TagsChanged;
+ if ((handler != null) && (e.Changes.Count == 0))
{
// If there weren't text changes, but there were span changes, then
// send out a classification changed event over the spans that changed.
- ProjectionSpanDifference difference = ProjectionSpanDiffer.DiffSourceSpans(this.diffService, e.Before, e.After);
- int pos = 0;
- int start = int.MaxValue;
- int end = int.MinValue;
- foreach (var diff in difference.DifferenceCollection)
- {
- pos += GetMatchSize(difference.DeletedSpans, diff.Before);
- start = Math.Min(start, pos);
-
- // Now, for every span added in the new snapshot that replaced
- // the deleted spans, add it to our span to raise changed events
- // over.
- for (int i = diff.Right.Start; i < diff.Right.End; i++)
- {
- pos += difference.InsertedSpans[i].Length;
- }
-
- end = Math.Max(end, pos);
- }
+ //
+ // We're raising a single event here so all we need is the start of the first changed span
+ // to the end of the last changed span (or, as we calculate it, the end of the first identical
+ // spans to the start of the last identical spans).
+ //
+ // Note that we are being generous in the span we raise. For example if I change the projection buffer
+ // from projecting (V0:[0,10)) and (V0:[10,15)) to projecting (V0:[0,5)) and (V0:[5,15)) we'll raise a snapshot changed
+ // event over the entire buffer even though neither the projected text nor the content type of its buffer
+ // changed. This case shouldn't happen very often and the cost of (falsely) raising a classification changed
+ // event is pretty small so this is a net perf win compared to doing a more expensive diff to get the actual
+ // changed span.
+ var leftSpans = e.Before.GetSourceSpans();
+ var rightSpans = e.After.GetSourceSpans();
+ var spansToCompare = Math.Min(leftSpans.Count, rightSpans.Count);
- if (start != int.MaxValue && end != int.MinValue)
+ int start = 0;
+ int identicalSpansAtStart = 0;
+ while ((identicalSpansAtStart < spansToCompare) && (leftSpans[identicalSpansAtStart] == rightSpans[identicalSpansAtStart]))
{
- RaiseTagsChangedEvent(new SnapshotSpan(e.After, Span.FromBounds(start, end)));
+ start += rightSpans[identicalSpansAtStart].Length;
+ ++identicalSpansAtStart;
}
- }
- }
- private static int GetMatchSize(ReadOnlyCollection<SnapshotSpan> spans, Match match)
- {
- int size = 0;
- if (match != null)
- {
- Span extent = match.Left;
- for (int s = extent.Start; s < extent.End; ++s)
+ if ((identicalSpansAtStart < leftSpans.Count) || (identicalSpansAtStart < rightSpans.Count))
{
- size += spans[s].Length;
- }
- }
- return size;
- }
+ // There are at least some span differences between leftSpans and rightSpans so we don't need to worry about running over.
+ spansToCompare -= identicalSpansAtStart; //No need to compare spans in the starting identical block.
+ int end = e.After.Length;
+ int identicalSpansAtEndPlus1 = 1;
+ while ((identicalSpansAtEndPlus1 <= spansToCompare) && (leftSpans[leftSpans.Count - identicalSpansAtEndPlus1] == rightSpans[rightSpans.Count - identicalSpansAtEndPlus1]))
+ {
+ end -= rightSpans[rightSpans.Count - identicalSpansAtEndPlus1].Length;
+ ++identicalSpansAtEndPlus1;
+ }
- private void RaiseTagsChangedEvent(SnapshotSpan span)
- {
- var handler = TagsChanged;
- if (handler != null)
- {
- handler(this, new SnapshotSpanEventArgs(span));
+ handler(this, new SnapshotSpanEventArgs(new SnapshotSpan(e.After, Span.FromBounds(start, end))));
+ }
}
}
-
#endregion
}
}