Esempio n. 1
0
        private async Task <LinkedFileMergeResult> MergeLinkedDocumentGroupAsync(
            IEnumerable <DocumentId> allLinkedDocuments,
            IEnumerable <DocumentId> linkedDocumentGroup,
            LinkedFileDiffMergingSessionInfo sessionInfo,
            IMergeConflictHandler mergeConflictHandler,
            CancellationToken cancellationToken)
        {
            var groupSessionInfo = new LinkedFileGroupSessionInfo();

            // Automatically merge non-conflicting diffs while collecting the conflicting diffs

            var textDifferencingService = _oldSolution.Workspace.Services.GetService <IDocumentTextDifferencingService>() ?? new DefaultDocumentTextDifferencingService();
            var appliedChanges          = await textDifferencingService.GetTextChangesAsync(_oldSolution.GetDocument(linkedDocumentGroup.First()), _newSolution.GetDocument(linkedDocumentGroup.First()), cancellationToken).ConfigureAwait(false);

            var unmergedChanges = new List <UnmergedDocumentChanges>();

            foreach (var documentId in linkedDocumentGroup.Skip(1))
            {
                appliedChanges = await AddDocumentMergeChangesAsync(
                    _oldSolution.GetDocument(documentId),
                    _newSolution.GetDocument(documentId),
                    appliedChanges.ToList(),
                    unmergedChanges,
                    groupSessionInfo,
                    textDifferencingService,
                    cancellationToken).ConfigureAwait(false);
            }

            var originalDocument   = _oldSolution.GetDocument(linkedDocumentGroup.First());
            var originalSourceText = await originalDocument.GetTextAsync(cancellationToken).ConfigureAwait(false);

            // Add comments in source explaining diffs that could not be merged

            IEnumerable <TextChange> allChanges;
            IList <TextSpan>         mergeConflictResolutionSpan = new List <TextSpan>();

            if (unmergedChanges.Any())
            {
                mergeConflictHandler ??= _oldSolution.GetDocument(linkedDocumentGroup.First()).GetLanguageService <ILinkedFileMergeConflictCommentAdditionService>();
                var mergeConflictTextEdits = mergeConflictHandler.CreateEdits(originalSourceText, unmergedChanges);

                allChanges = MergeChangesWithMergeFailComments(appliedChanges, mergeConflictTextEdits, mergeConflictResolutionSpan, groupSessionInfo);
            }
            else
            {
                allChanges = appliedChanges;
            }

            groupSessionInfo.LinkedDocuments      = _newSolution.GetDocumentIdsWithFilePath(originalDocument.FilePath).Length;
            groupSessionInfo.DocumentsWithChanges = linkedDocumentGroup.Count();
            sessionInfo.LogLinkedFileResult(groupSessionInfo);

            return(new LinkedFileMergeResult(allLinkedDocuments, originalSourceText.WithChanges(allChanges), mergeConflictResolutionSpan));
        }
Esempio n. 2
0
        internal async Task <Solution> WithMergedLinkedFileChangesAsync(
            Solution oldSolution,
            SolutionChanges?solutionChanges            = null,
            IMergeConflictHandler mergeConflictHandler = null,
            CancellationToken cancellationToken        = default(CancellationToken))
        {
            // we only log sessioninfo for actual changes committed to workspace which should exclude ones from preview
            var session = new LinkedFileDiffMergingSession(oldSolution, this, solutionChanges ?? this.GetChanges(oldSolution), logSessionInfo: solutionChanges != null);

            return((await session.MergeDiffsAsync(mergeConflictHandler, cancellationToken).ConfigureAwait(false)).MergedSolution);
        }
        private async Task<LinkedFileMergeResult> MergeLinkedDocumentGroupAsync(
            IEnumerable<DocumentId> allLinkedDocuments,
            IEnumerable<DocumentId> linkedDocumentGroup,
            LinkedFileDiffMergingSessionInfo sessionInfo,
            IMergeConflictHandler mergeConflictHandler,
            CancellationToken cancellationToken)
        {
            var groupSessionInfo = new LinkedFileGroupSessionInfo();

            // Automatically merge non-conflicting diffs while collecting the conflicting diffs

            var textDifferencingService = _oldSolution.Workspace.Services.GetService<IDocumentTextDifferencingService>() ?? new DefaultDocumentTextDifferencingService();
            var appliedChanges = await textDifferencingService.GetTextChangesAsync(_oldSolution.GetDocument(linkedDocumentGroup.First()), _newSolution.GetDocument(linkedDocumentGroup.First()), cancellationToken).ConfigureAwait(false);
            var unmergedChanges = new List<UnmergedDocumentChanges>();

            foreach (var documentId in linkedDocumentGroup.Skip(1))
            {
                appliedChanges = await AddDocumentMergeChangesAsync(
                    _oldSolution.GetDocument(documentId),
                    _newSolution.GetDocument(documentId),
                    appliedChanges.ToList(),
                    unmergedChanges,
                    groupSessionInfo,
                    textDifferencingService,
                    cancellationToken).ConfigureAwait(false);
            }

            var originalDocument = _oldSolution.GetDocument(linkedDocumentGroup.First());
            var originalSourceText = await originalDocument.GetTextAsync(cancellationToken).ConfigureAwait(false);

            // Add comments in source explaining diffs that could not be merged

            IEnumerable<TextChange> allChanges;
            IList<TextSpan> mergeConflictResolutionSpan = new List<TextSpan>();

            if (unmergedChanges.Any())
            {
                mergeConflictHandler = mergeConflictHandler ?? _oldSolution.GetDocument(linkedDocumentGroup.First()).GetLanguageService<ILinkedFileMergeConflictCommentAdditionService>();
                var mergeConflictTextEdits = mergeConflictHandler.CreateEdits(originalSourceText, unmergedChanges);

                allChanges = MergeChangesWithMergeFailComments(appliedChanges, mergeConflictTextEdits, mergeConflictResolutionSpan, groupSessionInfo);
            }
            else
            {
                allChanges = appliedChanges;
            }

            groupSessionInfo.LinkedDocuments = _newSolution.GetDocumentIdsWithFilePath(originalDocument.FilePath).Length;
            groupSessionInfo.DocumentsWithChanges = linkedDocumentGroup.Count();
            sessionInfo.LogLinkedFileResult(groupSessionInfo);

            return new LinkedFileMergeResult(allLinkedDocuments, originalSourceText.WithChanges(allChanges), mergeConflictResolutionSpan);
        }
        internal async Task <LinkedFileMergeSessionResult> MergeDiffsAsync(IMergeConflictHandler mergeConflictHandler, CancellationToken cancellationToken)
        {
            LinkedFileDiffMergingSessionInfo sessionInfo = new LinkedFileDiffMergingSessionInfo();

            var linkedDocumentGroupsWithChanges = _solutionChanges
                                                  .GetProjectChanges()
                                                  .SelectMany(p => p.GetChangedDocuments())
                                                  .GroupBy(d => _oldSolution.GetDocument(d).FilePath, StringComparer.OrdinalIgnoreCase);

            var linkedFileMergeResults = new List <LinkedFileMergeResult>();

            var updatedSolution = _newSolution;

            foreach (var linkedDocumentsWithChanges in linkedDocumentGroupsWithChanges)
            {
                var documentInNewSolution = _newSolution.GetDocument(linkedDocumentsWithChanges.First());

                // Ensure the first document in the group is the first in the list of
                var allLinkedDocuments = documentInNewSolution.GetLinkedDocumentIds().Add(documentInNewSolution.Id);
                if (allLinkedDocuments.Length == 1)
                {
                    continue;
                }

                SourceText mergedText;
                if (linkedDocumentsWithChanges.Count() > 1)
                {
                    var mergeGroupResult = await MergeLinkedDocumentGroupAsync(allLinkedDocuments, linkedDocumentsWithChanges, sessionInfo, mergeConflictHandler, cancellationToken).ConfigureAwait(false);

                    linkedFileMergeResults.Add(mergeGroupResult);
                    mergedText = mergeGroupResult.MergedSourceText;
                }
                else
                {
                    mergedText = await _newSolution.GetDocument(linkedDocumentsWithChanges.Single()).GetTextAsync(cancellationToken).ConfigureAwait(false);
                }

                foreach (var documentId in allLinkedDocuments)
                {
                    updatedSolution = updatedSolution.WithDocumentText(documentId, mergedText);
                }
            }

            LogLinkedFileDiffMergingSessionInfo(sessionInfo);

            return(new LinkedFileMergeSessionResult(updatedSolution, linkedFileMergeResults));
        }
        internal async Task<LinkedFileMergeSessionResult> MergeDiffsAsync(IMergeConflictHandler mergeConflictHandler, CancellationToken cancellationToken)
        {
            LinkedFileDiffMergingSessionInfo sessionInfo = new LinkedFileDiffMergingSessionInfo();

            var linkedDocumentGroupsWithChanges = _solutionChanges
                .GetProjectChanges()
                .SelectMany(p => p.GetChangedDocuments())
                .GroupBy(d => _oldSolution.GetDocument(d).FilePath, StringComparer.OrdinalIgnoreCase);

            var linkedFileMergeResults = new List<LinkedFileMergeResult>();

            var updatedSolution = _newSolution;
            foreach (var linkedDocumentsWithChanges in linkedDocumentGroupsWithChanges)
            {
                var documentInNewSolution = _newSolution.GetDocument(linkedDocumentsWithChanges.First());

                // Ensure the first document in the group is the first in the list of 
                var allLinkedDocuments = documentInNewSolution.GetLinkedDocumentIds().Add(documentInNewSolution.Id);
                if (allLinkedDocuments.Length == 1)
                {
                    continue;
                }

                SourceText mergedText;
                if (linkedDocumentsWithChanges.Count() > 1)
                {
                    var mergeGroupResult = await MergeLinkedDocumentGroupAsync(allLinkedDocuments, linkedDocumentsWithChanges, sessionInfo, mergeConflictHandler, cancellationToken).ConfigureAwait(false);
                    linkedFileMergeResults.Add(mergeGroupResult);
                    mergedText = mergeGroupResult.MergedSourceText;
                }
                else
                {
                    mergedText = await _newSolution.GetDocument(linkedDocumentsWithChanges.Single()).GetTextAsync(cancellationToken).ConfigureAwait(false);
                }

                foreach (var documentId in allLinkedDocuments)
                {
                    updatedSolution = updatedSolution.WithDocumentText(documentId, mergedText);
                }
            }

            LogLinkedFileDiffMergingSessionInfo(sessionInfo);

            return new LinkedFileMergeSessionResult(updatedSolution, linkedFileMergeResults);
        }
Esempio n. 6
0
        internal async Task<Solution> WithMergedLinkedFileChangesAsync(
            Solution oldSolution,
            SolutionChanges? solutionChanges = null,
            IMergeConflictHandler mergeConflictHandler = null,
            CancellationToken cancellationToken = default(CancellationToken))
        {
            // we only log sessioninfo for actual changes committed to workspace which should exclude ones from preview
            var session = new LinkedFileDiffMergingSession(oldSolution, this, solutionChanges ?? this.GetChanges(oldSolution), logSessionInfo: solutionChanges != null);

            return (await session.MergeDiffsAsync(mergeConflictHandler, cancellationToken).ConfigureAwait(false)).MergedSolution;
        }