Exemple #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));
        }
        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);
        }