Example #1
0
        internal static AP.ChangeInfo[] GetChanges(PythonTextBufferInfo buffer, ITextVersion curVersion)
        {
            var changes = new List <AP.ChangeInfo>();

            if (curVersion.Changes != null)
            {
                foreach (var change in curVersion.Changes)
                {
                    var oldPos = buffer.LocationTracker.GetSourceLocation(change.OldPosition, curVersion.VersionNumber);
                    var oldEnd = buffer.LocationTracker.GetSourceLocation(change.OldEnd, curVersion.VersionNumber);
                    changes.Add(new AP.ChangeInfo {
                        startLine   = oldPos.Line,
                        startColumn = oldPos.Column,
                        endLine     = oldEnd.Line,
                        endColumn   = oldEnd.Column,
                        newText     = change.NewText,
#if DEBUG
                        _startIndex = change.OldPosition,
                        _endIndex   = change.OldEnd
#endif
                    });
                }
            }

#if DEBUG
            Debug.WriteLine("Getting changes for version {0}", curVersion.VersionNumber);
            foreach (var c in changes)
            {
                Debug.WriteLine($" - ({c.startLine}, {c.startColumn})-({c.endLine}, {c.endColumn}): \"{c.newText}\"");
            }
#endif
            return(changes.ToArray());
        }
Example #2
0
 public Span GetSpan(ITextVersion version)
 {
     return(Span.FromBounds(
                _start.GetPosition(version),
                _end.GetPosition(version)
                ));
 }
Example #3
0
 public TextSnapshot(ITextBuffer textBuffer, ITextVersion version, StringRebuilder content)
     : base(version)
 {
     System.Diagnostics.Debug.Assert(version.Length == content.Length);
     this.textBuffer = textBuffer;
     this.content    = content;
 }
Example #4
0
        protected override int TrackPosition(ITextVersion targetVersion)
        {
            // Compute the new position on the requested snapshot.
            //
            // This method can be called simultaneously from multiple threads, and must be fast.
            //
            // We are relying on the atomicity of pointer copies (this.cachedPosition might change after we've
            // fetched it but we will always get a self-consistent VersionPosition). This ensures we
            // have proper behavior when called from multiple threads--multiple threads may all track and update the
            // cached value if called at inconvenient times, but they will return consistent results.
            // ForwardFidelity points do not support tracking backward, so consistency is not guaranteed in that case.

            VersionPosition cached = this.cachedPosition;
            int             targetPosition;

            if (targetVersion == cached.Version)
            {
                targetPosition = cached.Position;
            }
            else if (targetVersion.VersionNumber > cached.Version.VersionNumber)
            {
                // Roll the cached version forward to the requested version.
                targetPosition = Tracking.TrackPositionForwardInTime(this.trackingMode, cached.Position, cached.Version, targetVersion);

                // Cache new cached version.
                this.cachedPosition = new VersionPosition(targetVersion, targetPosition);
            }
            else
            {
                // Roll backwards from the cached version.
                targetPosition = Tracking.TrackPositionBackwardInTime(this.trackingMode, cached.Position, cached.Version, targetVersion);
            }
            return(targetPosition);
        }
Example #5
0
        //Check to see if, when translating position to snapshot, the character after position was deleted.
        private static bool CharacterDeleted(SnapshotPoint position, ITextSnapshot snapshot)
        {
            int currentPosition = position.Position;

            ITextVersion version = position.Snapshot.Version;

            while (version.VersionNumber != snapshot.Version.VersionNumber)
            {
                foreach (ITextChange change in version.Changes)
                {
                    if (change.NewPosition > currentPosition)
                    {
                        break;
                    }
                    else
                    {
                        if (change.NewPosition + change.OldLength > currentPosition)
                        {
                            //Line break (or the first character of it) was deleted.
                            return(true);
                        }
                        else
                        {
                            //Change occurs entirely before currentPosition so adjust.
                            currentPosition += change.Delta;
                        }
                    }
                }

                version = version.Next;
            }

            return(false);
        }
Example #6
0
        internal void DocumentClosed(ITextSnapshot savedSnapshot)
        {
            Assumes.NotNull(_originalVersion);

            if ((savedSnapshot != null) && (savedSnapshot.Version.VersionNumber > _originalVersion.VersionNumber))
            {
                // The document was saved and we want to line/column indices in the saved snapshot (& not the current snapshot)
                var savedSpan = new SnapshotSpan(savedSnapshot, Tracking.TrackSpanForwardInTime(_trackingMode, _originalSpan, _originalVersion, savedSnapshot.Version));

                PersistentSpan.SnapshotPointToLineIndex(savedSpan.Start, out _startLine, out _startIndex);
                PersistentSpan.SnapshotPointToLineIndex(savedSpan.End, out _endLine, out _endIndex);
            }
            else
            {
                // The document was never saved (or was saved before we created) so continue to use the old line/column indices.
                // Since those are set when either the span is created (against an open document) or when the document is reopened,
                // they don't need to be changed.
            }

            //We set this to false when the document is closed because we have an accurate line/index and that is more stable
            //than a simple offset.
            _useLineIndex    = true;
            _originalSpan    = default(Span);
            _originalVersion = null;
            _span            = null;
        }
        public async Task <ImmutableArray <NavigationBarItem> > GetItemsAsync(
            Document document, ITextVersion textVersion, CancellationToken cancellationToken)
        {
            var items = await _service.GetItemsAsync(document, cancellationToken).ConfigureAwait(false);

            return(ConvertItems(items, textVersion));
        }
Example #8
0
        internal HighFidelityTrackingPoint(ITextVersion version, int position, PointTrackingMode trackingMode, TrackingFidelityMode fidelity)
            : base(version, position, trackingMode)
        {
            if (fidelity != TrackingFidelityMode.UndoRedo && fidelity != TrackingFidelityMode.Backward)
            {
                throw new ArgumentOutOfRangeException(nameof(fidelity));
            }
            List <VersionNumberPosition> initialHistory = null;

            if (fidelity == TrackingFidelityMode.UndoRedo && version.VersionNumber > 0)
            {
                // The system may perform undo operations that reach prior to the initial version; if any of
                // those transitions are noninvertible, then redoing back to the initial version will give the
                // wrong answer. Thus we save the state of the point for the initial version, unless the
                // initial version happens to be version zero (in which case we could not undo past it).

                initialHistory = new List <VersionNumberPosition>();

                if (version.VersionNumber != version.ReiteratedVersionNumber)
                {
                    Debug.Assert(version.ReiteratedVersionNumber < version.VersionNumber);
                    // If the current version and reiterated version differ, also remember the position
                    // using the reiterated version number, since when undoing back to this point it
                    // will be the key that is used.
                    initialHistory.Add(new VersionNumberPosition(version.ReiteratedVersionNumber, position));
                }

                initialHistory.Add(new VersionNumberPosition(version.VersionNumber, position));
            }
            this.cachedPosition = new VersionPositionHistory(version, position, initialHistory);
            this.fidelity       = fidelity;
        }
Example #9
0
        private static AP.ChangeInfo[] GetChanges(ITextVersion curVersion)
        {
            Debug.WriteLine("Changes for version {0}", curVersion.VersionNumber);
            var changes = new List <AP.ChangeInfo>();

            if (curVersion.Changes != null)
            {
                AP.ChangeInfo prev = null;
                foreach (var change in curVersion.Changes)
                {
                    Debug.WriteLine("Changes for version {0} {1} {2}", change.OldPosition, change.OldLength, change.NewText);

                    if (prev != null && !string.IsNullOrEmpty(prev.newText) &&
                        change.OldLength == 0 && prev.length == 0 && prev.start + prev.newText.Length == change.OldPosition)
                    {
                        // we can merge the two changes together
                        prev.newText += change.NewText;
                        continue;
                    }

                    prev = new AP.ChangeInfo()
                    {
                        start   = change.OldPosition,
                        length  = change.OldLength,
                        newText = change.NewText
                    };
                    changes.Add(prev);
                }
            }
            return(changes.ToArray());
        }
        private int ExecOnAll(
            ref Guid pguidCmdGroup,
            uint nCmdID,
            uint nCmdexecopt,
            IntPtr pvaIn,
            IntPtr pvaOut)
        {
            var result             = 0;
            var pguidCmdGroupLocal = pguidCmdGroup;

            this.SelectionSwapExec(
                (tempSelections, targetSelections) =>
            {
                // Begin the edit.
                this.dte.UndoContext.Open("Multi-point edit");

                foreach (var selection in tempSelections)
                {
                    selection.SetSelection(this.textView);
                    this.expectedEditVersion = this.textView.TextSnapshot.Version;
                    result = this.nextTarget.Exec(ref pguidCmdGroupLocal, nCmdID, nCmdexecopt, pvaIn, pvaOut);

                    // Add the selection into the list again - we do this so that we have
                    // clean selection details in the list and can handle any merging
                    targetSelections.InsertExpectEnd(Utils.GetCurrentSelections(this.textView));
                }

                // End the edit
                this.dte.UndoContext.Close();
            });

            pguidCmdGroup = pguidCmdGroupLocal;
            return(result);
        }
Example #11
0
 public BufferInfo(ITextBuffer buffer, int id)
 {
     Buffer            = buffer;
     Id                = id;
     _analysisVersion  = buffer.CurrentSnapshot.Version;
     LastParsedVersion = _analysisVersion.VersionNumber - 1;
 }
Example #12
0
 private static IEnumerable <ITextVersion> GetVersions(ITextVersion from, ITextVersion to)
 {
     for (var v = from; v != null && v != to; v = v.Next)
     {
         yield return(v);
     }
 }
Example #13
0
 public Span GetSpan(ITextVersion version)
 {
     return Span.FromBounds(
         _start.GetPosition(version),
         _end.GetPosition(version)
     );
 }
        /// <summary>
        /// Constructs a TextBufferChangeUndoPrimitive.
        /// </summary>
        /// <param name="undoHistory">
        /// The ITextUndoHistory this change will be added to.
        /// </param>
        /// <param name="textVersion">
        /// The <see cref="ITextVersion" /> representing this change.
        /// This is actually the version associated with the snapshot prior to the change.
        /// </param>
        /// <exception cref="ArgumentNullException"><paramref name="undoHistory"/> is null.</exception>
        /// <exception cref="ArgumentNullException"><paramref name="textVersion"/> is null.</exception>
        public TextBufferChangeUndoPrimitive(ITextUndoHistory undoHistory, ITextVersion textVersion)
        {
            // Verify input parameters
            if (undoHistory == null)
            {
                throw new ArgumentNullException("undoHistory");
            }

            if (textVersion == null)
            {
                throw new ArgumentNullException("textVersion");
            }

            _textChanges   = textVersion.Changes;
            _beforeVersion = textVersion.ReiteratedVersionNumber;
            _afterVersion  = textVersion.Next.VersionNumber;
            Debug.Assert(textVersion.Next.VersionNumber == textVersion.Next.ReiteratedVersionNumber,
                         "Creating a TextBufferChangeUndoPrimitive for a change that has previously been undone?  This is probably wrong.");

            _undoHistory        = undoHistory;
            TextBuffer          = textVersion.TextBuffer;
            AttachedToNewBuffer = false;

            _canUndo = true;

#if DEBUG
            // for debug sanity checks
            _bufferLengthAfterChange = textVersion.Next.Length;
#endif
        }
Example #15
0
 public ElisionSnapshot(ElisionBuffer elisionBuffer,
                        ITextSnapshot sourceSnapshot,
                        ITextVersion version,
                        ElisionMap content,
                        bool fillInMappingMode)
     : base(version)
 {
     this.elisionBuffer  = elisionBuffer;
     this.sourceSnapshot = sourceSnapshot;
     // The SourceSnapshots property is used heavily, so cache a handy copy.
     this.sourceSnapshots = new ReadOnlyCollection <ITextSnapshot>(new FrugalList <ITextSnapshot>()
     {
         sourceSnapshot
     });
     this.totalLength       = content.Length;
     this.content           = content;
     this.totalLineCount    = content.LineCount;
     this.fillInMappingMode = fillInMappingMode;
     Debug.Assert(this.totalLength == version.Length,
                  string.Format(System.Globalization.CultureInfo.CurrentCulture,
                                "Elision Snapshot Inconsistency. Content: {0}, Previous + delta: {1}", this.totalLength, version.Length));
     if (this.totalLength != version.Length)
     {
         throw new InvalidOperationException(Strings.InvalidLengthCalculation);
     }
 }
Example #16
0
 public MultilineCommentToken(IClassificationType type, ITrackingSpan span, ITextVersion version)
     : base(TokenType.MultilineComment)
 {
     classificationType = type;
     trackingSpan       = span;
     textVersion        = version;
 }
 public MouseLeftDownInfo(VirtualSnapshotSpan span, Point point, int clicks, ITextVersion version)
 {
     Span    = span;
     Point   = point;
     Clicks  = clicks;
     Version = version;
 }
Example #18
0
 private void Initialize(TextBuffer buffer, ITextVersion bufferVersion, Int32 position, TrackingMode trackingMode)
 {
     _version      = bufferVersion;
     _textBuffer   = buffer;
     _position     = position;
     _trackingMode = trackingMode;
 }
Example #19
0
        public async Task <bool> TryNavigateToItemAsync(
            Document document, NavigationBarItem item, ITextView view, ITextVersion textVersion, CancellationToken cancellationToken)
        {
            // The logic here was ported from FSharp's implementation. The main reason was to avoid shimming INotificationService.
            var navigationSpan = item.TryGetNavigationSpan(textVersion);

            if (navigationSpan != null)
            {
                var span              = navigationSpan.Value;
                var workspace         = document.Project.Solution.Workspace;
                var navigationService = workspace.Services.GetRequiredService <IFSharpDocumentNavigationService>();

                await _threadingContext.JoinableTaskFactory.SwitchToMainThreadAsync(cancellationToken);

                if (navigationService.CanNavigateToPosition(workspace, document.Id, span.Start, virtualSpace: 0, cancellationToken))
                {
                    navigationService.TryNavigateToPosition(workspace, document.Id, span.Start, virtualSpace: 0, options: null, cancellationToken);
                }
                else
                {
                    var notificationService = workspace.Services.GetRequiredService <INotificationService>();
                    notificationService.SendNotification(EditorFeaturesResources.The_definition_of_the_object_is_hidden, severity: NotificationSeverity.Error);
                }
            }

            return(true);
        }
Example #20
0
        public Model(ITextVersion textVersion, QuickInfoItem item, bool trackMouse)
        {
            Contract.ThrowIfNull(item);

            this.TextVersion = textVersion;
            this.Item        = item;
            this.TrackMouse  = trackMouse;
        }
Example #21
0
        public TextVersionMock CreateNextVersion(TextChangeMock change)
        {
            _change = change;
            var nextVersion = new TextVersionMock(TextBuffer, VersionNumber + 1, Length + _change.Delta);

            Next = nextVersion;
            return(nextVersion);
        }
        private void UpdateVersion(ITextSnapshot snapshot)
        {
            ITextVersion v = snapshot.Version;

            VersionText      = "V " + v.VersionNumber.ToString();
            ReiteratedText   = "R " + v.ReiteratedVersionNumber.ToString();
            this.prevVersion = v;
        }
Example #23
0
        public TextVersionMock CreateNextVersion(TextChangeMock change)
        {
            _change = change;
            TextVersionMock nextVersion = new TextVersionMock(TextBuffer, VersionNumber + 1, Length + _change.Delta);

            Next = nextVersion;

            return nextVersion;
        }
		/// <summary>
		/// Initializes a new instance of the <see cref="ClassificationSpan"/> class.
		/// </summary>
		/// <exception cref="ArgumentNullException"><para><paramref name="classification"/> is <see langword="null"/>.</para></exception>
		public ClassificationSpan(TextBuffer buffer, ITextVersion version, Int32 start, Int32 length, String classification)
			: base(buffer, version, start, length)
		{
			if (classification == null)
			{
				throw new ArgumentNullException("classification");
			}

			_classification = classification;
		}
Example #25
0
        public void CheckCompilationVersion()
        {
            ITextVersion textVersion = this.TextBuffer?.CurrentSnapshot?.Version;

            if (this.backgroundVersion == null || this.backgroundVersion != textVersion)
            {
                Interlocked.Exchange(ref this.backgroundVersion, textVersion);
                this.Compile();
            }
        }
Example #26
0
 public void Dispose()
 {
     if (this.SpanSet != null)
     {
         this.SpanSet.Delete(this);
         this.SpanSet     = null;
         _originalVersion = null;
         _span            = null;
     }
 }
Example #27
0
        /// <summary>
        /// Initializes a new instance of the <see cref="ClassificationSpan"/> class.
        /// </summary>
        /// <exception cref="ArgumentNullException"><para><paramref name="classification"/> is <see langword="null"/>.</para></exception>
        public ClassificationSpan(TextBuffer buffer, ITextVersion version, Int32 start, Int32 length, String classification)
            : base(buffer, version, start, length)
        {
            if (classification == null)
            {
                throw new ArgumentNullException("classification");
            }

            _classification = classification;
        }
Example #28
0
        public TextSpan?TryGetNavigationSpan(ITextVersion textVersion)
        {
            if (this.NavigationSpan == null)
            {
                return(null);
            }

            return(this.TextVersion !.CreateTrackingSpan(this.NavigationSpan.Value.ToSpan(), SpanTrackingMode.EdgeExclusive)
                   .GetSpan(textVersion).ToTextSpan());
        }
 public VersionSpanHistory(ITextVersion version,
                           Span span,
                           List <VersionNumberPosition> noninvertibleStartHistory,
                           List <VersionNumberPosition> noninvertibleEndHistory)
 {
     this.version = version;
     this.span    = span;
     this.noninvertibleStartHistory = noninvertibleStartHistory;
     this.noninvertibleEndHistory   = noninvertibleEndHistory;
 }
        protected async Task NavigateToSymbolItemAsync(
            Document document, NavigationBarItem item, SymbolItem symbolItem, ITextVersion textVersion, CancellationToken cancellationToken)
        {
            var workspace = document.Project.Solution.Workspace;

            var(documentId, position, virtualSpace) = await GetNavigationLocationAsync(
                document, item, symbolItem, textVersion, cancellationToken).ConfigureAwait(false);

            await NavigateToPositionAsync(workspace, documentId, position, virtualSpace, cancellationToken).ConfigureAwait(false);
        }
Example #31
0
        protected override int TrackPosition(ITextVersion targetVersion)
        {
            // Compute the new position on the requested snapshot.
            // This object caches the most recently requested version and the position in that version.
            //
            // We are relying on the atomicity of pointer copies (this.cachedPosition might change after we've
            // fetched it below but we will always get a self-consistent VersionPosition). This ensures we
            // have proper behavior when called from multiple threads (multiple threads may all track and update the
            // cached value if called at inconvenient times, but they will return consistent results).
            //
            // In most cases, one can track backwards from the cached version to a previously computed
            // version and get the same result, but this is not always the case: in particular, when the
            // position lies in a deleted region, simulating reinsertion of that region will not cause
            // the previous value of the position to be recovered. Such transitions are called noninvertible.
            // This class explicitly tracks the positions of the point for versions for which the subsequent
            // transition is noninvertible; this allows the value to be computed properly when tracking backwards
            // or in undo/redo situations.

            VersionPositionHistory cached = this.cachedPosition;    // must fetch just once

            if (targetVersion == cached.Version)
            {
                // easy!
                return(cached.Position);
            }

            List <VersionNumberPosition> noninvertibleHistory = cached.NoninvertibleHistory;
            int targetPosition;

            if (targetVersion.VersionNumber > cached.Version.VersionNumber)
            {
                // Roll the cached version forward to the requested version.
                targetPosition = TrackPositionForwardInTime
                                     (this.trackingMode,
                                     this.fidelity,
                                     ref noninvertibleHistory,
                                     cached.Position,
                                     cached.Version,
                                     targetVersion);

                // Cache new position
                this.cachedPosition = new VersionPositionHistory(targetVersion, targetPosition, noninvertibleHistory);
            }
            else
            {
                // roll backwards from the cached version
                targetPosition = TrackPositionBackwardInTime
                                     (this.trackingMode,
                                     this.fidelity == TrackingFidelityMode.Backward ? noninvertibleHistory : null,
                                     cached.Position,
                                     cached.Version,
                                     targetVersion);
            }
            return(targetPosition);
        }
Example #32
0
        private SnapshotPoint GetPoint(ITextVersion version) {
            if (version.TextBuffer != _snapshot.TextBuffer) {
                Debug.Fail("Mismatched buffers");
                throw new ArgumentException("Mismatched text buffers");
            }
            
            var newPos = _position;
            var current = _snapshot.Version;
            var target = version;
            var toSnapshot = ((MockTextVersion)target)._snapshot;
            if (current.VersionNumber > target.VersionNumber) {
                // Apply the changes in reverse
                var changesStack = new Stack<INormalizedTextChangeCollection>();

                for (var v = target; v.VersionNumber < current.VersionNumber; v = v.Next) {
                    changesStack.Push(v.Changes);
                }


                while (changesStack.Count > 0) {
                    foreach (var change in changesStack.Pop()) {
                        if (change.Delta > 0 && change.NewPosition <= newPos && change.NewPosition - change.Delta > newPos) {
                            // point was deleted
                            newPos = change.NewPosition;
                        } else if (change.NewPosition == newPos) {
                            if (_mode == PointTrackingMode.Positive) {
                                newPos -= change.Delta;
                            }
                        } else if (change.NewPosition < newPos) {
                            newPos -= change.Delta;
                        }
                    }
                }
            } else if (current.VersionNumber < target.VersionNumber) {
                // Apply the changes normally
                for (var v = current; v.VersionNumber < target.VersionNumber; v = v.Next) {
                    foreach (var change in v.Changes) {
                        if (change.Delta < 0 && change.OldPosition <= newPos && change.OldPosition - change.Delta > newPos) {
                            // point was deleted
                            newPos = change.OldPosition;
                        } else if (change.OldPosition == newPos) {
                            if (_mode == PointTrackingMode.Positive) {
                                newPos += change.Delta;
                            }
                        } else if(change.OldPosition < newPos) {
                            newPos += change.Delta;
                        }
                    }
                }
            }

            Debug.Assert(newPos >= 0, string.Format("new point '{0}' should be zero or greater", newPos));
            Debug.Assert(newPos <= toSnapshot.Length, string.Format("new point '{0}' should be {1} or less", newPos, toSnapshot.Length));
            return new SnapshotPoint(toSnapshot, newPos);
        }
Example #33
0
        // Returns spans corresponding to the changes that occurred between startVersion and endVersion
        public static bool GetChangedExtent(this ITextVersion oldVersion, ITextVersion newVersion, out Span?oldSpan, out Span?newSpan)
        {
            oldSpan = null;
            newSpan = null;

            if (oldVersion.VersionNumber > newVersion.VersionNumber)
            {
                // They've asked for information about an earlier snapshot, not supported
                Debug.Assert(false);
                return(false);
            }

            int newEnd   = Int32.MinValue;
            int position = Int32.MaxValue;
            int deltaLen = 0;

            while (oldVersion != newVersion)
            {
                INormalizedTextChangeCollection changes = oldVersion.Changes;
                if (changes.Count > 0)
                {
                    ITextChange firstChange    = changes[0];
                    ITextChange lastChange     = changes[changes.Count - 1];
                    int         changeDeltaLen = lastChange.NewEnd - lastChange.OldEnd;

                    deltaLen += changeDeltaLen;

                    position = Math.Min(position, firstChange.NewPosition);

                    if (newEnd < lastChange.OldEnd)
                    {
                        newEnd = lastChange.NewEnd;
                    }
                    else
                    {
                        newEnd += changeDeltaLen;
                    }
                }

                oldVersion = oldVersion.Next;
            }

            if (newEnd < position)
            {
                // There weren't any changes between the versions, return a null TextChangeExtent
                return(false);
            }

            int oldEnd = newEnd - deltaLen;

            oldSpan = Span.FromBounds(position, oldEnd);
            newSpan = Span.FromBounds(position, newEnd);

            return(true);
        }
Example #34
0
		public TrackingPoint(ITextVersion textVersion, int position, PointTrackingMode trackingMode, TrackingFidelityMode trackingFidelity) {
			if (textVersion == null)
				throw new ArgumentNullException(nameof(textVersion));
			if ((uint)position > (uint)textVersion.Length)
				throw new ArgumentOutOfRangeException(nameof(position));
			TextBuffer = textVersion.TextBuffer;
			TrackingMode = trackingMode;
			TrackingFidelity = trackingFidelity;
			this.textVersion = textVersion;
			this.position = position;
		}
Example #35
0
 public Model(
     ITextVersion textVersion,
     QuickInfoItem item,
     IQuickInfoProvider provider,
     bool trackMouse)
 {
     this.TextVersion = textVersion;
     this.Item        = item;
     this.Provider    = provider;
     this.TrackMouse  = trackMouse;
 }
Example #36
0
		public TrackingSpan(ITextVersion textVersion, Span span, SpanTrackingMode trackingMode, TrackingFidelityMode trackingFidelity) {
			if (textVersion == null)
				throw new ArgumentNullException(nameof(textVersion));
			if ((uint)span.End > (uint)textVersion.Length)
				throw new ArgumentOutOfRangeException(nameof(span));
			TextBuffer = textVersion.TextBuffer;
			TrackingFidelity = trackingFidelity;
			TrackingMode = trackingMode;
			this.textVersion = textVersion;
			this.span = span;
		}
        private SnapshotPoint GetPoint(ITextVersion version) {
            var current = _snapshot.Version;
            var target = version;
            if (current.VersionNumber == target.VersionNumber) {
                return new SnapshotPoint(_snapshot, _position);
            } else if (current.VersionNumber > target.VersionNumber) {
                // Apply the changes in reverse
                var changesStack = new Stack<INormalizedTextChangeCollection>();

                for (var v = target; v.VersionNumber < current.VersionNumber; v = v.Next) {
                    changesStack.Push(v.Changes);
                }

                var newPos = _position;

                while (changesStack.Count > 0) {
                    foreach (var change in changesStack.Pop()) {
                        if (change.Delta > 0 && change.NewPosition <= newPos && change.NewPosition - change.Delta > newPos) {
                            // point was deleted
                            newPos = change.NewPosition;
                        } else if (change.NewPosition == newPos) {
                            if (_mode == PointTrackingMode.Positive) {
                                newPos -= change.Delta;
                            }
                        } else if (change.NewPosition < newPos) {
                            newPos -= change.Delta;
                        }
                    }
                }

                return new SnapshotPoint(((MockTextVersion)target)._snapshot, newPos);
            } else {
                // Apply the changes normally
                var newPos = _position;
                for (var v = current; v.VersionNumber < target.VersionNumber; v = v.Next) {
                    foreach (var change in v.Changes) {
                        if (change.Delta < 0 && change.OldPosition <= newPos && change.OldPosition - change.Delta > newPos) {
                            // point was deleted
                            newPos = change.OldPosition;
                        } else if (change.OldPosition == newPos) {
                            if (_mode == PointTrackingMode.Positive) {
                                newPos += change.Delta;
                            }
                        } else if(change.OldPosition < newPos) {
                            newPos += change.Delta;
                        }
                    }
                }

                return new SnapshotPoint(((MockTextVersion)target)._snapshot, newPos);
            }
        }
Example #38
0
        public Model(
            ITextVersion textVersion,
            QuickInfoItem item,
            IQuickInfoProvider provider,
            bool trackMouse)
        {
            Contract.ThrowIfNull(item);

            this.TextVersion = textVersion;
            this.Item = item;
            this.Provider = provider;
            this.TrackMouse = trackMouse;
        }
Example #39
0
		public TextSnapshot(ITextSource textSource, IContentType contentType, TextBuffer textBuffer, ITextVersion textVersion) {
			if (textSource == null)
				throw new ArgumentNullException(nameof(textSource));
			if (contentType == null)
				throw new ArgumentNullException(nameof(contentType));
			if (textBuffer == null)
				throw new ArgumentNullException(nameof(textBuffer));
			if (textVersion == null)
				throw new ArgumentNullException(nameof(textVersion));
			this.textSource = textSource;
			ContentType = contentType;
			TextBuffer = textBuffer;
			Version = textVersion;
		}
Example #40
0
        /// <summary>
        /// Creates a new location tracker which can track spans and positions through time.
        /// 
        /// The tracker will translate positions from the specified version to the current
        /// snapshot in VS.  Requests can be made to track either forwards or backwards.
        /// </summary>
        public LocationTracker(ITextVersion lastAnalysisVersion, ITextBuffer buffer, int fromVersion) {
            // We always hold onto the last version that we've successfully analyzed, as that's
            // the last event the out of proc analyzer will send us.  Once we've received
            // that event all future information should come from at least that version.  This
            // prevents us from holding onto every version in the world.
            Debug.Assert(fromVersion >= lastAnalysisVersion.VersionNumber);

            while (lastAnalysisVersion.VersionNumber != fromVersion) {
                lastAnalysisVersion = lastAnalysisVersion.Next;
            }

            _fromVersion = lastAnalysisVersion;
            _buffer = buffer;
        }
 /// <summary>
 /// May return <code>null</code> if span is outside range of document.
 /// </summary>
 private ITrackingSpan CreateTrackingSpan(ITextVersion version, int position, int length) {
   // Check range of span is ok (we don't know what happen to the files
   // on disk, so we have to be safe)
   if ((0 <= position) && (position + length <= version.Length)) {
     // See http://blogs.msdn.com/b/noahric/archive/2009/06/06/editor-perf-markers-vs-tracking-spans.aspx
     // Never grows the tracking span.
     const SpanTrackingMode mode = SpanTrackingMode.EdgeExclusive;
     var span = version.CreateTrackingSpan(
       new Span(position, length),
       mode,
       TrackingFidelityMode.Forward);
     return span;
   } else {
     return null;
   }
 }
Example #42
0
		public int GetPosition(ITextVersion version) {
			if (version == null)
				throw new ArgumentNullException(nameof(version));
			if (version == textVersion)
				return position;
			if (version.TextBuffer != textVersion.TextBuffer)
				throw new ArgumentException();

			// Rewrite the values since it's common to just move in one direction. This can lose
			// information: if we move forward and then backward, we might get another position.
			position = version.VersionNumber > textVersion.VersionNumber ?
				Tracking.TrackPositionForwardInTime(TrackingMode, position, textVersion, version) :
				Tracking.TrackPositionBackwardInTime(TrackingMode, position, textVersion, version);
			textVersion = version;
			return position;
		}
Example #43
0
        public Span GetSpan(ITextVersion version) {
            var start = _start.GetPosition(version);
            var end = _end.GetPosition(version);

            if (start > end) {
                // start has positive tracking, end has negative, everything has been deleted
                // and our spans have become inverted.
                return new Span(
                    start,
                    0
                );
            }
            return Span.FromBounds(
                _start.GetPosition(version),
                _end.GetPosition(version)
            );
        }
Example #44
0
        public Span GetSpan(ITextVersion version) {
            var current = _snapshot.Version;
            var target = version;
            if (current.VersionNumber == target.VersionNumber) {
                return new Span(_start, _length);
            } else if (current.VersionNumber > target.VersionNumber) {
                // Apply the changes in reverse
                var changesStack = new Stack<INormalizedTextChangeCollection>();

                for (var v = target; v.VersionNumber < current.VersionNumber; v = v.Next) {
                    changesStack.Push(v.Changes);
                }

                var newStart = _start;
                var newLength = _length;

                while (changesStack.Count > 0) {
                    foreach (var change in changesStack.Pop()) {
                        if (change.NewPosition <= newStart) {
                            newStart -= change.Delta;
                        } else if (change.NewPosition <= newStart + newLength) {
                            newLength -= change.Delta;
                        }
                    }
                }

                return new Span(newStart, newLength);
            } else {
                // Apply the changes normally
                var newStart = _start;
                var newLength = _length;

                for (var v = current; v.VersionNumber < target.VersionNumber; v = v.Next) {
                    foreach (var change in v.Changes) {
                        if (change.OldPosition < newStart) {
                            newStart += change.Delta;
                        } else if (change.OldPosition < newStart + newLength) {
                            newLength += change.Delta;
                        }
                    }
                }

                return new Span(newStart, newLength);
            }
        }
		/// <summary>
		/// Initializes a new instance of the <see cref="VersionedTextSpan"/> class.
		/// </summary>
		/// <exception cref="ArgumentNullException">
		/// <para><paramref name="buffer"/> is <see langword="null"/>.</para>
		/// -or-
		/// <para><paramref name="span"/> is <see langword="null"/>.</para>
		/// -or-
		/// <para><paramref name="version"/> is <see langword="null"/>.</para>
		/// </exception>
		public VersionedTextSpan(TextBuffer buffer, ITextVersion version, Span span)
		{
			if (buffer == null)
			{
				throw new ArgumentNullException("buffer");
			}

			if (version == null)
			{
				throw new ArgumentNullException("version");
			}

			if (span == null)
			{
				throw new ArgumentNullException("span");
			}

			this.Construct(buffer, buffer.Version, span.Start, span.Length, SpanTrackingMode.EdgeExclusive);
		}
Example #46
0
        /// <summary>
        /// Creates a new location tracker which can track spans and positions through time.
        /// 
        /// The tracker will translate positions from the specified version to the current
        /// snapshot in VS.  Requests can be made to track either forwards or backwards.
        /// </summary>
        public LocationTracker(ITextVersion lastAnalysisVersion, ITextBuffer buffer, int fromVersion) {
            // We always hold onto the last version that we've successfully analyzed, as that's
            // the last event the out of proc analyzer will send us.  Once we've received
            // that event all future information should come from at least that version.  This
            // prevents us from holding onto every version in the world.

            if (fromVersion >= lastAnalysisVersion.VersionNumber) {
                while (lastAnalysisVersion.Next != null && lastAnalysisVersion.VersionNumber != fromVersion) {
                    lastAnalysisVersion = lastAnalysisVersion.Next;
                }
            } else {
                // Warn the developer, but we should be able to continue with
                // the ITextVersion that was provided.
                Debug.Fail("fromVersion {0} was less than lastAnalysisVersion {1}".FormatInvariant(fromVersion, lastAnalysisVersion.VersionNumber));
            }

            _fromVersion = lastAnalysisVersion;
            _buffer = buffer;
        }
			public bool TryAdvanceVersion(ITextVersion newVersion) {
				var v = Version;
				while (v != newVersion) {
					var changes = v.Changes;
					if (changes == null)
						break;
					if (changes.Count == 1 && changes[0].OldPosition == 0 && changes[0].OldLength == v.Length)
						return false;
					v = v.Next;
				}
				Version = newVersion;
				return true;
			}
 public Span GetSpan(ITextVersion version)
 {
     throw new NotImplementedException();
 }
 private static IEnumerable<IEnumerable<TextChangeRange>> GetMultipleVersionTextChanges(ITextVersion oldVersion, ITextVersion newVersion, bool forward)
 {
     for (var version = oldVersion; version != newVersion; version = version.Next)
     {
         yield return version.Changes.Select(forward ? s_forwardTextChangeRange : s_backwardTextChangeRange);
     }
 }
		/// <summary>
		/// </summary>
		/// <exception cref="ArgumentNullException">
		/// <para>
		///		<paramref name="targetVersion"/> is <see langword="null"/>.
		/// </para>
		/// -or-
		/// <para>
		///		The specified <paramref name="version"/> does not belong to the specified <paramref name="buffer"/>.
		/// </para>
		/// </exception>
		public Span Span(ITextVersion targetVersion)
		{
			if (targetVersion == null)
			{
				throw new ArgumentNullException("targetVersion");
			}

			if (!_buffer.VersionBelongsToBuffer(targetVersion))
			{
				throw new ArgumentException("The specified TextVersion does not belong to the specified TextBuffer");
			}

			ITextVersion next = _version;
			Int32 num = TextBuffer.CompareVersions(next, targetVersion);
			Int32 position = _start;
			Int32 num3 = _start + _length;
			if (num < 0)
			{
				while (next != targetVersion)
				{
					if (_trackingMode == SpanTrackingMode.EdgeExclusive)
					{
						position = TextSpan.UpdatePositiveTrackingPoint(next.Change, position);
						num3 = TextSpan.UpdateNegativeTrackingPoint(next.Change, num3);
					}
					else
					{
						position = TextSpan.UpdateNegativeTrackingPoint(next.Change, position);
						num3 = TextSpan.UpdatePositiveTrackingPoint(next.Change, num3);
					}
					next = next.Next;
				}
			}
			else if (num > 0)
			{
				Stack<TextChange> stack = new Stack<TextChange>(1);
				for (ITextVersion version2 = targetVersion; version2 != next; version2 = version2.Next)
				{
					stack.Push(version2.Change);
				}
				while (stack.Count > 0)
				{
					TextChange change = stack.Pop();
					if (_trackingMode == SpanTrackingMode.EdgeExclusive)
					{
						if (change.Position <= position)
						{
							position -= change.Delta;
						}
						if (change.Position < num3)
						{
							num3 -= change.Delta;
						}
					}
					else
					{
						if (change.Position < position)
						{
							position -= change.Delta;
						}
						if (change.Position <= num3)
						{
							num3 -= change.Delta;
						}
					}
				}
			}
			if (num3 < position)
			{
				num3 = position;
			}
			return new Span(position, num3 - position);
		}
		/// <summary>
		/// Initializes a new instance of the <see cref="VersionedTextSpan"/> class.
		/// </summary>
		/// <exception cref="ArgumentNullException">
		/// <para><paramref name="buffer"/> is <see langword="null"/>.</para>
		/// -or-
		/// <para><paramref name="version"/> is <see langword="null"/>.</para>
		/// </exception>
		public VersionedTextSpan(TextBuffer buffer, ITextVersion version, Int32 start, Int32 length)
		{
			if (buffer == null)
			{
				throw new ArgumentNullException("buffer");
			}

			if (version == null)
			{
				throw new ArgumentNullException("version");
			}

			this.Construct(buffer, version, start, length, SpanTrackingMode.EdgeExclusive);
		}
 public int GetPosition(ITextVersion version)
 {
     return _position;
 }
            private TextChangeRange GetChangeRanges(ITextVersion oldVersion, ITextVersion newVersion, bool forward)
            {
                TextChangeRange? range = null;
                var iterator = GetMultipleVersionTextChanges(oldVersion, newVersion, forward);
                foreach (var changes in forward ? iterator : iterator.Reverse())
                {
                    range = range.Accumulate(changes);
                }

                Contract.Requires(range.HasValue);
                return range.Value;
            }
 public Span GetSpan(ITextVersion version)
 {
     return _span;
 }
Example #55
0
        // Returns spans corresponding to the changes that occurred between startVersion and endVersion
        public static bool GetChangedExtent(this ITextVersion oldVersion, ITextVersion newVersion, out Span? oldSpan, out Span? newSpan) {
            oldSpan = null;
            newSpan = null;

            if (oldVersion.VersionNumber > newVersion.VersionNumber) {
                // They've asked for information about an earlier snapshot, not supported
                Debug.Assert(false);
                return false;
            }

            int newEnd = Int32.MinValue;
            int position = Int32.MaxValue;
            int deltaLen = 0;
            while (oldVersion != newVersion) {
                INormalizedTextChangeCollection changes = oldVersion.Changes;
                if (changes.Count > 0) {
                    ITextChange firstChange = changes[0];
                    ITextChange lastChange = changes[changes.Count - 1];
                    int changeDeltaLen = lastChange.NewEnd - lastChange.OldEnd;

                    deltaLen += changeDeltaLen;

                    position = Math.Min(position, firstChange.NewPosition);

                    if (newEnd < lastChange.OldEnd) {
                        newEnd = lastChange.NewEnd;
                    } else {
                        newEnd += changeDeltaLen;
                    }
                }

                oldVersion = oldVersion.Next;
            }

            if (newEnd < position) {
                // There weren't any changes between the versions, return a null TextChangeExtent
                return false;
            }

            int oldEnd = newEnd - deltaLen;
            oldSpan = Span.FromBounds(position, oldEnd);
            newSpan = Span.FromBounds(position, newEnd);

            return true;
        }
			public MouseLeftDownInfo(VirtualSnapshotSpan span, Point point, int clicks, ITextVersion version) {
				Span = span;
				Point = point;
				Clicks = clicks;
				Version = version;
			}
		/// <summary>
		/// Initializes a new instance of the <see cref="VersionedTextSpan"/> class.
		/// </summary>
		/// <exception cref="ArgumentNullException">
		/// <para><paramref name="buffer"/> is <see langword="null"/>.</para>
		/// -or-
		/// <para><paramref name="version"/> is <see langword="null"/>.</para>
		/// </exception>
		/// <exception cref="ArgumentException">
		/// <para>The specified <paramref name="version"/> does not belong to the specified <paramref name="buffer"/>.</para>
		/// </exception>
		public VersionedTextSpan(TextBuffer buffer, ITextVersion version, Int32 start, Int32 length, SpanTrackingMode trackingMode)
		{
			if (buffer == null)
			{
				throw new ArgumentNullException("buffer");
			}
			if (version == null)
			{
				throw new ArgumentNullException("version");
			}
			if (!buffer.VersionBelongsToBuffer(version))
			{
				throw new ArgumentException("The specified TextVersion does not belong to the specified TextBuffer.");
			}
			this.Construct(buffer, version, start, length, trackingMode);
		}
Example #58
0
 public Span GetSpan(ITextVersion version)
 {
     return new Span(_start, _length);
 }
Example #59
0
 Span ITrackingSpan.GetSpan(ITextVersion version)
 {
     throw new System.NotImplementedException();
 }
		private void Construct(TextBuffer buffer, ITextVersion version, Int32 start, Int32 length, SpanTrackingMode trackingMode)
		{
			Int32 lengthOfVersion = buffer.GetLengthOfVersion(version);
			if ((start < 0) || (start > lengthOfVersion))
			{
				throw new ArgumentOutOfRangeException("start");
			}
			if ((length < 0) || ((start + length) > lengthOfVersion))
			{
				throw new ArgumentOutOfRangeException("length");
			}
			_buffer = buffer;
			_version = version;
			_start = start;
			_length = length;
			_trackingMode = trackingMode;
		}