public IHierarchicalDifferenceCollection GetDifferences(IContentType contentType, string left, string right)
        {
            Initialize();

            ITextDifferencingService          diffService = this.diffSelectorService.GetTextDifferencingService(contentType);
            StringDifferenceOptions           diffOptions = new StringDifferenceOptions(StringDifferenceTypes.Line, 0, true);
            IHierarchicalDifferenceCollection differences = diffService.DiffStrings(left, right, diffOptions);

            return(differences);
        }
Example #2
0
        private NormalizedSpanCollection GetChangedSpans(IHierarchicalDifferenceCollection diffResult)
        {
            var lineSpans = new List <Span>();

            foreach (var difference in diffResult)
            {
                var mappedSpan = diffResult.RightDecomposition.GetSpanInOriginal(difference.Right);
                lineSpans.Add(mappedSpan);
            }

            return(new NormalizedSpanCollection(lineSpans));
        }
        private NormalizedSpanCollection GetOriginalSpans(IHierarchicalDifferenceCollection diffResult, CancellationToken cancellationToken)
        {
            cancellationToken.ThrowIfCancellationRequested();
            var lineSpans = new List <Span>();

            foreach (var difference in diffResult)
            {
                cancellationToken.ThrowIfCancellationRequested();
                var mappedSpan = diffResult.LeftDecomposition.GetSpanInOriginal(difference.Left);
                lineSpans.Add(mappedSpan);
            }

            return(new NormalizedSpanCollection(lineSpans));
        }
        private static IList <TextChange> GetChangesFromDifferenceCollection(ref int delta,
                                                                             TextChange originalChange,
                                                                             ChangeString oldText,
                                                                             ChangeString newText,
                                                                             IHierarchicalDifferenceCollection diffCollection,
                                                                             int leftOffset  = 0,
                                                                             int rightOffset = 0)
        {
            List <TextChange> changes = new List <TextChange>();

            for (int i = 0; i < diffCollection.Differences.Count; i++)
            {
                Difference currentDiff = diffCollection.Differences[i];

                Span leftDiffSpan  = Translate(diffCollection.LeftDecomposition.GetSpanInOriginal(currentDiff.Left), leftOffset);
                Span rightDiffSpan = Translate(diffCollection.RightDecomposition.GetSpanInOriginal(currentDiff.Right), rightOffset);

                // TODO: Since this evaluates differences lazily, we should add something here to *not* compute the next
                // level of differences if we think it would be too expensive.
                IHierarchicalDifferenceCollection nextLevelDiffs = diffCollection.GetContainedDifferences(i);

                if (nextLevelDiffs != null)
                {
                    changes.AddRange(GetChangesFromDifferenceCollection(ref delta, originalChange, oldText, newText, nextLevelDiffs, leftDiffSpan.Start, rightDiffSpan.Start));
                }
                else
                {
                    TextChange minimalChange = new TextChange(originalChange.OldPosition + leftDiffSpan.Start,
                                                              oldText.Substring(leftDiffSpan),
                                                              newText.Substring(rightDiffSpan),
                                                              ComputeBoundaryConditions(originalChange, oldText, leftDiffSpan));

                    minimalChange.NewPosition = originalChange.NewPosition + rightDiffSpan.Start;
                    if (minimalChange.OldLength > 0 && minimalChange.NewLength > 0)
                    {
                        minimalChange.IsOpaque = true;
                    }

                    delta += minimalChange.Delta;
                    changes.Add(minimalChange);
                }
            }

            return(changes);
        }
        // return type Task<object> is required by ISuggestedAction.GetPreviewAsync
        public Task <object> CreateChangePreviewAsync(
            SarifErrorListItem errorListItem,
            ITextBuffer buffer,
            Action <ITextBuffer,
                    ITextSnapshot> applyEdit,
            string description = null,
            FrameworkElement additionalContent = null)
        {
            ITextBuffer bufferClone = this.CloneBuffer(buffer);

            applyEdit(bufferClone, buffer.CurrentSnapshot);

            IHierarchicalDifferenceCollection diffResult    = this.ComputeDifferences(buffer, bufferClone);
            NormalizedSpanCollection          originalSpans = this.GetOriginalSpans(diffResult);
            NormalizedSpanCollection          changedSpans  = this.GetChangedSpans(diffResult);

            List <LineSpan> originalLineSpans = this.CreateLineSpans(buffer.CurrentSnapshot, originalSpans);
            List <LineSpan> changedLineSpans  = this.CreateLineSpans(bufferClone.CurrentSnapshot, changedSpans);

            if (!originalLineSpans.Any())
            {
                originalLineSpans = changedLineSpans;
            }

            if (!(originalLineSpans.Any() && changedLineSpans.Any()))
            {
                return(Task.FromResult <object>(null));
            }

            const string Separator = "\u2026"; // Horizontal ellipsis.

            IProjectionBuffer originalProjectionBuffer = this.projectionBufferFactoryService.CreateProjectionBufferWithoutIndentation(
                this.editorOptionsFactoryService.GlobalOptions,
                buffer.CurrentSnapshot,
                Separator,
                originalLineSpans.ToArray());

            IProjectionBuffer newProjectionBuffer = this.projectionBufferFactoryService.CreateProjectionBufferWithoutIndentation(
                this.editorOptionsFactoryService.GlobalOptions,
                bufferClone.CurrentSnapshot,
                Separator,
                changedLineSpans.ToArray());

            return(this.CreateNewDifferenceViewerAsync(errorListItem, originalProjectionBuffer, newProjectionBuffer, description, additionalContent));
        }
 private void UpdateLatestComparedToLocalVersionDifferences()
 {
     // Recalculate differences between server version and local version.
     // This can be done now, because it is independent of the user's editing
     // session.
     if (this.latestVersion != null && this.latestVersionContent != null)
     {
         if (this.latestVersion.Id.Equals(this.localVersion))
         {
             // If user's local workspace is now at the latest, there are no differences.
             this.latestComparedToLocalDifferences = null;
         }
         else
         {
             // Otherwise, calculate the differences.
             this.latestComparedToLocalDifferences = FileComparerService.Instance.GetDifferences(this.TextBuffer.ContentType, this.localVersionContent, this.latestVersionContent);
         }
     }
 }
Example #7
0
        private ChangeList GetChangeList(
            IHierarchicalDifferenceCollection diff,
            DocumentId id,
            SourceText oldText,
            SourceText newText
            )
        {
            var spanChanges = new List <SpanChange>();

            foreach (var difference in diff)
            {
                var leftSpan  = diff.LeftDecomposition.GetSpanInOriginal(difference.Left);
                var rightSpan = diff.RightDecomposition.GetSpanInOriginal(difference.Right);

                var leftText  = oldText.GetSubText(leftSpan.ToTextSpan()).ToString();
                var rightText = newText.GetSubText(rightSpan.ToTextSpan()).ToString();

                var trackingSpan = _buffer.CurrentSnapshot.CreateTrackingSpan(
                    leftSpan,
                    SpanTrackingMode.EdgeInclusive
                    );

                var isDeletion  = difference.DifferenceType == DifferenceType.Remove;
                var displayText = isDeletion ? GetDisplayText(leftText) : GetDisplayText(rightText);

                var spanChange = new SpanChange(
                    trackingSpan,
                    _buffer,
                    id,
                    displayText,
                    leftText,
                    rightText,
                    isDeletion,
                    this,
                    engine
                    );

                spanChanges.Add(spanChange);
            }

            return(new ChangeList(spanChanges.ToArray()));
        }
Example #8
0
        private static bool ContainsBetterDiff(TextDocument left, TextDocument right, IHierarchicalDifferenceCollection diffResult, CancellationToken cancellationToken)
        {
            var textDiffCount = diffResult.Differences.Count;

            var leftDocument  = left as Document;
            var rightDocument = right as Document;

            if (leftDocument == null || rightDocument == null)
            {
                return(false);
            }

            var syntaxDiffCount = rightDocument.GetTextChangesAsync(leftDocument, cancellationToken).WaitAndGetResult(cancellationToken).Count();

            return(syntaxDiffCount > textDiffCount);
        }
Example #9
0
        private NormalizedSpanCollection GetChangedSpans(IHierarchicalDifferenceCollection diffResult, CancellationToken cancellationToken)
        {
            cancellationToken.ThrowIfCancellationRequested();
            var lineSpans = new List<Span>();

            foreach (var difference in diffResult)
            {
                cancellationToken.ThrowIfCancellationRequested();
                var mappedSpan = diffResult.RightDecomposition.GetSpanInOriginal(difference.Right);
                lineSpans.Add(mappedSpan);
            }

            return new NormalizedSpanCollection(lineSpans);
        }
Example #10
0
        private ChangeList GetChangeList(IHierarchicalDifferenceCollection diff, DocumentId id, SourceText oldText, SourceText newText)
        {
            var spanChanges = new List<SpanChange>();
            foreach (var difference in diff)
            {
                var leftSpan = diff.LeftDecomposition.GetSpanInOriginal(difference.Left);
                var rightSpan = diff.RightDecomposition.GetSpanInOriginal(difference.Right);

                var leftText = oldText.GetSubText(leftSpan.ToTextSpan()).ToString();
                var rightText = newText.GetSubText(rightSpan.ToTextSpan()).ToString();

                var trackingSpan = _buffer.CurrentSnapshot.CreateTrackingSpan(leftSpan, SpanTrackingMode.EdgeInclusive);

                var isDeletion = difference.DifferenceType == DifferenceType.Remove;
                var displayText = isDeletion ? GetDisplayText(leftText) : GetDisplayText(rightText);

                var spanChange = new SpanChange(trackingSpan, _buffer, id, displayText, leftText, rightText, isDeletion, this, engine);

                spanChanges.Add(spanChange);
            }

            return new ChangeList(spanChanges.ToArray());
        }
Example #11
0
        private static bool ContainsBetterDiff(TextDocument left, TextDocument right, IHierarchicalDifferenceCollection diffResult, CancellationToken cancellationToken)
        {
            var textDiffCount = diffResult.Differences.Count;

            var leftDocument = left as Document;
            var rightDocument = right as Document;
            if (leftDocument == null || rightDocument == null)
            {
                return false;
            }

            var syntaxDiffCount = rightDocument.GetTextChangesAsync(leftDocument, cancellationToken).WaitAndGetResult(cancellationToken).Count();
            return syntaxDiffCount > textDiffCount;
        }
        private void UpdateEditBufferComparedToLocalVersionDifferences()
        {
            string editBufferContents = this.TextBuffer.CurrentSnapshot.GetText().ToString();

            this.editBufferComparedToLocalDifferences = FileComparerService.Instance.GetDifferences(this.TextBuffer.ContentType, this.localVersionContent, editBufferContents);
        }