diff options
author | Kirill Osenkov <github@osenkov.com> | 2018-08-15 21:13:16 +0300 |
---|---|---|
committer | Kirill Osenkov <github@osenkov.com> | 2018-08-15 21:13:16 +0300 |
commit | b407d9744a34fd4647cf3e99068a28d728fd65a2 (patch) | |
tree | e6d6cef915f32dec4f2d16b1868045143deb589f /src/Text/Impl/ClassificationAggregator | |
parent | cf974b266fb428d846e2e16a25a4eeb8f635c26f (diff) |
Updating to VS-Platform 15.8.519 (29d85337c7d2af248a692fd65ac37b444551e4cf).
Diffstat (limited to 'src/Text/Impl/ClassificationAggregator')
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 } } |