private void UpdateDirtySpans(TextContentChangedEventArgs e)
        {
            _currentSnapshot = e.After;

            var newDirtySpans = _dirtySpans.CloneAndTrackTo(e.After, SpanTrackingMode.EdgeInclusive);

            newDirtySpans = e.Changes
                            .Aggregate(newDirtySpans, (current, change) => NormalizedSnapshotSpanCollection.Union(
                                           current, new NormalizedSnapshotSpanCollection(e.After, change.NewSpan)));

            _dirtySpans = newDirtySpans;
        }
Exemple #2
0
        private void UpdateDirtySpans(TextContentChangedEventArgs e)
        {
            currentSnapshot = e.After;

            var newDirtySpans = dirtySpans.CloneAndTrackTo(e.After, SpanTrackingMode.EdgeInclusive);

            foreach (var change in e.Changes)
            {
                newDirtySpans = NormalizedSnapshotSpanCollection.Union(newDirtySpans, new NormalizedSnapshotSpanCollection(e.After, change.NewSpan));
            }

            dirtySpans = newDirtySpans;
        }
        internal void EnqueueChanges(
            ITextSnapshot snapshot,
            NormalizedSnapshotSpanCollection changedSpans)
        {
            AssertIsForeground();

            var version      = snapshot.Version.VersionNumber;
            var currentSpans = _snapshotVersionToSpansMap.GetOrAdd(version, s_addFunction);
            var allSpans     = NormalizedSnapshotSpanCollection.Union(currentSpans, changedSpans);

            _snapshotVersionToSpansMap[version] = allSpans;

            EnqueueNotificationRequest(_throttleDelay);
        }
            internal void EnqueueChanges(NormalizedSnapshotSpanCollection changedSpans)
            {
                AssertIsForeground();
                if (changedSpans.Count == 0)
                {
                    return;
                }

                var snapshot = changedSpans.First().Snapshot;

                var version      = snapshot.Version.VersionNumber;
                var currentSpans = _snapshotVersionToSpansMap.GetOrAdd(version, s_addFunction);
                var allSpans     = NormalizedSnapshotSpanCollection.Union(currentSpans, changedSpans);

                _snapshotVersionToSpansMap[version] = allSpans;

                EnqueueNotificationRequest(TaggerDelay.NearImmediate);
            }
Exemple #5
0
        private void OnBufferChange(object sender, TextContentChangedEventArgs e)
        {
            _currentSnapshot = e.After;

            // Translate all of the old dirty spans to the new snapshot.
            NormalizedSnapshotSpanCollection newDirtySpans = _dirtySpans.CloneAndTrackTo(e.After, SpanTrackingMode.EdgeInclusive);

            // Dirty all the spans that changed.
            foreach (var change in e.Changes)
            {
                newDirtySpans = NormalizedSnapshotSpanCollection.Union(newDirtySpans, new NormalizedSnapshotSpanCollection(e.After, change.NewSpan));
            }

            // Translate all the security errors to the new snapshot (and remove anything that is a dirty
            // region since we will need to check that again).
            var oldSecurityErrors = this.Factory.CurrentSnapshot;
            var newSecurityErrors = new DevSkimErrorsSnapshot(this.FilePath, oldSecurityErrors.VersionNumber + 1);

            // Copy all of the old errors to the new errors unless the error was affected by the text change
            foreach (var error in oldSecurityErrors.Errors)
            {
                Debug.Assert(error.NextIndex == -1);

                var newError = DevSkimError.CloneAndTranslateTo(error, e.After);

                if (newError != null)
                {
                    Debug.Assert(newError.Span.Length == error.Span.Length);

                    error.NextIndex = newSecurityErrors.Errors.Count;
                    newSecurityErrors.Errors.Add(newError);
                }
            }

            this.UpdateSecurityErrors(newSecurityErrors);

            _dirtySpans = newDirtySpans;

            // Start processing the dirty spans (which no-ops if we're already doing it).
            if (_dirtySpans.Count != 0)
            {
                this.KickUpdate();
            }
        }
Exemple #6
0
 static NormalizedSnapshotSpanCollection SymmetricDifference(NormalizedSnapshotSpanCollection first, NormalizedSnapshotSpanCollection second)
 {
     return(NormalizedSnapshotSpanCollection.Union(
                NormalizedSnapshotSpanCollection.Difference(first, second),
                NormalizedSnapshotSpanCollection.Difference(second, first)));
 }
Exemple #7
0
        internal IEnumerable <ICollapsible> InternalGetAllRegions(NormalizedSnapshotSpanCollection spans, bool exposedRegionsOnly, CancellationToken?cancel = null)
        {
            EnsureValid(spans);

            // No collapsibles if disabled
            if (!isEnabled || spans.Count == 0)
            {
                return(new List <Collapsible>());
            }

            ITextSnapshot snapshot = spans[0].Snapshot;

            IList <Collapsed> currentCollapsed = GetCollapsedRegionsInternal(spans, exposedRegionsOnly);

            IEnumerable <ICollapsible> newCollapsibles;

            if (!exposedRegionsOnly || currentCollapsed.Count == 0)
            {
                newCollapsibles = CollapsiblesFromTags(this.InternalGetTags(spans, cancel)).Keys;
            }
            else
            {
                NormalizedSnapshotSpanCollection collapsedRegions = new NormalizedSnapshotSpanCollection(currentCollapsed.Select(c => c.Extent.GetSpan(snapshot)));
                NormalizedSnapshotSpanCollection exposed          = NormalizedSnapshotSpanCollection.Difference(spans, collapsedRegions);

                // Ensure there is an empty region on each end
                SnapshotSpan first = spans[0];
                SnapshotSpan last  = spans[spans.Count - 1];
                NormalizedSnapshotSpanCollection ends = new NormalizedSnapshotSpanCollection(new SnapshotSpan[] { new SnapshotSpan(first.Start, 0), new SnapshotSpan(last.End, 0) });
                exposed = NormalizedSnapshotSpanCollection.Union(exposed, ends);

                newCollapsibles = CollapsiblesFromTags(this.InternalGetTags(exposed, cancel)).Keys.Where(c => IsRegionExposed(c, snapshot));
            }

            IEnumerable <ICollapsed> removed;

            var merged = MergeRegions(currentCollapsed, newCollapsibles, out removed);

            // NOTE: IF we have misbehaved taggers, it is possible that we'll see invalid
            // changes here in removed regions that are currently collapsed.  We can deal
            // with this by expanding as needed, but it will cause an event to be sent out, which will
            // likely be unexpected and cause bugs in our clients.

            // There are a few ways we can deal with this:

            // #1: Expand/collapse regions and event
            foreach (var removedRegion in removed)
            {
                Debug.Fail("Removing a region here means a tagger has misbehaved.");
                if (removedRegion.IsCollapsed)
                {
                    Expand(removedRegion);
                }
            }

            // Other options:
            // #2: Return the new regions without doing anything special
            // #3: Return the current collapsed + uncollapsed added regions

            return(merged);
        }