internal static void LogSession(Workspace workspace, LinkedFileDiffMergingSessionInfo sessionInfo)
        {
            if (sessionInfo.LinkedFileGroups.Count > 1)
            {
                LogNewSessionWithLinkedFiles();
                LogNumberOfLinkedFileGroupsProcessed(sessionInfo.LinkedFileGroups.Count);

                foreach (var groupInfo in sessionInfo.LinkedFileGroups)
                {
                    LogNumberOfIdenticalDiffs(groupInfo.IdenticalDiffs);
                    LogNumberOfIsolatedDiffs(groupInfo.IsolatedDiffs);
                    LogNumberOfOverlappingDistinctDiffs(groupInfo.OverlappingDistinctDiffs);
                    LogNumberOfOverlappingDistinctDiffsWithSameSpan(groupInfo.OverlappingDistinctDiffsWithSameSpan);
                    LogNumberOfOverlappingDistinctDiffsWithSameSpanAndSubstringRelation(groupInfo.OverlappingDistinctDiffsWithSameSpanAndSubstringRelation);
                    LogNumberOfInsertedMergeConflictComments(groupInfo.InsertedMergeConflictComments);
                    LogNumberOfInsertedMergeConflictCommentsAtAdjustedLocation(groupInfo.InsertedMergeConflictCommentsAtAdjustedLocation);

                    if (groupInfo.InsertedMergeConflictComments > 0 ||
                        groupInfo.InsertedMergeConflictCommentsAtAdjustedLocation > 0)
                    {
                        Logger.Log(FunctionId.Workspace_Solution_LinkedFileDiffMergingSession_LinkedFileGroup, SessionLogMessage.Create(groupInfo));
                    }
                }
            }
        }
        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);
        }
            private async Task<LinkedFileMergeResult> MergeLinkedDocumentGroupAsync(
                IEnumerable<DocumentId> linkedDocumentGroup,
                LinkedFileDiffMergingSessionInfo sessionInfo,
                CancellationToken cancellationToken)
            {
                var groupSessionInfo = new LinkedFileGroupSessionInfo();

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

                var appliedChanges = await newSolution.GetDocument(linkedDocumentGroup.First()).GetTextChangesAsync(oldSolution.GetDocument(linkedDocumentGroup.First())).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,
                        cancellationToken).ConfigureAwait(false);
                }

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

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

                IEnumerable<TextChange> allChanges;
                if (unmergedChanges.Any())
                {
                    var mergeConflictCommentAdder = originalDocument.GetLanguageService<ILinkedFileMergeConflictCommentAdditionService>();
                    var commentChanges = mergeConflictCommentAdder.CreateCommentsForUnmergedChanges(originalSourceText, unmergedChanges);

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

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

                return new LinkedFileMergeResult(originalSourceText.WithChanges(allChanges), hasMergeConflicts: unmergedChanges.Any());
            }
Esempio n. 4
0
        internal async Task <LinkedFileMergeSessionResult> MergeDiffsAsync(IMergeConflictHandler mergeConflictHandler, CancellationToken cancellationToken)
        {
            var 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));
        }
        private void LogLinkedFileDiffMergingSessionInfo(LinkedFileDiffMergingSessionInfo sessionInfo)
        {
            // don't report telemetry
            if (!_logSessionInfo)
            {
                return;
            }

            var sessionId = SessionLogMessage.GetNextId();

            Logger.Log(FunctionId.Workspace_Solution_LinkedFileDiffMergingSession, SessionLogMessage.Create(sessionId, sessionInfo));

            foreach (var groupInfo in sessionInfo.LinkedFileGroups)
            {
                Logger.Log(FunctionId.Workspace_Solution_LinkedFileDiffMergingSession_LinkedFileGroup, SessionLogMessage.Create(sessionId, groupInfo));
            }
        }
        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. 7
0
            internal async Task <Solution> MergeDiffsAsync(CancellationToken cancellationToken)
            {
                LinkedFileDiffMergingSessionInfo sessionInfo = new LinkedFileDiffMergingSessionInfo();

                var linkedDocumentGroupsWithChanges = solutionChanges
                                                      .GetProjectChanges()
                                                      .SelectMany(p => p.GetChangedDocuments())
                                                      .GroupBy(d => oldSolution.GetDocument(d).FilePath, StringComparer.InvariantCultureIgnoreCase);

                var updatedSolution = newSolution;

                foreach (var linkedDocumentGroup in linkedDocumentGroupsWithChanges)
                {
                    var allLinkedDocuments = newSolution.GetDocumentIdsWithFilePath(newSolution.GetDocumentState(linkedDocumentGroup.First()).FilePath);
                    if (allLinkedDocuments.Length == 1)
                    {
                        continue;
                    }

                    SourceText mergedText;
                    if (linkedDocumentGroup.Count() > 1)
                    {
                        mergedText = (await MergeLinkedDocumentGroupAsync(linkedDocumentGroup, sessionInfo, cancellationToken).ConfigureAwait(false)).MergedSourceText;
                    }
                    else
                    {
                        mergedText = await newSolution.GetDocument(linkedDocumentGroup.Single()).GetTextAsync(cancellationToken).ConfigureAwait(false);
                    }

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

                LogLinkedFileDiffMergingSessionInfo(sessionInfo);

                return(updatedSolution);
            }
            internal async Task<Solution> MergeDiffsAsync(CancellationToken cancellationToken)
            {
                LinkedFileDiffMergingSessionInfo sessionInfo = new LinkedFileDiffMergingSessionInfo();

                var linkedDocumentGroupsWithChanges = solutionChanges
                    .GetProjectChanges()
                    .SelectMany(p => p.GetChangedDocuments())
                    .GroupBy(d => oldSolution.GetDocument(d).FilePath, StringComparer.InvariantCultureIgnoreCase);

                var updatedSolution = newSolution;
                foreach (var linkedDocumentGroup in linkedDocumentGroupsWithChanges)
                {
                    var allLinkedDocuments = newSolution.GetDocumentIdsWithFilePath(newSolution.GetDocumentState(linkedDocumentGroup.First()).FilePath);
                    if (allLinkedDocuments.Length == 1)
                    {
                        continue;
                    }

                    SourceText mergedText;
                    if (linkedDocumentGroup.Count() > 1)
                    {
                        mergedText = (await MergeLinkedDocumentGroupAsync(linkedDocumentGroup, sessionInfo, cancellationToken).ConfigureAwait(false)).MergedSourceText;
                    }
                    else
                    {
                        mergedText = await newSolution.GetDocument(linkedDocumentGroup.Single()).GetTextAsync(cancellationToken).ConfigureAwait(false);
                    }

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

                LogLinkedFileDiffMergingSessionInfo(sessionInfo);

                return updatedSolution;
            }
                public static KeyValueLogMessage Create(int sessionId, LinkedFileDiffMergingSessionInfo sessionInfo)
                {
                    return KeyValueLogMessage.Create(m =>
                    {
                        m[SessionId] = sessionId.ToString();

                        m[HasLinkedFile] = (sessionInfo.LinkedFileGroups.Count > 0).ToString();
                    });
                }
            private void LogLinkedFileDiffMergingSessionInfo(LinkedFileDiffMergingSessionInfo sessionInfo)
            {
                var sessionId = SessionLogMessasge.GetNextId();

                Logger.Log(FunctionId.Workspace_Solution_LinkedFileDiffMergingSession, SessionLogMessasge.Create(sessionId, sessionInfo));

                foreach (var groupInfo in sessionInfo.LinkedFileGroups)
                {
                    Logger.Log(FunctionId.Workspace_Solution_LinkedFileDiffMergingSession_LinkedFileGroup, SessionLogMessasge.Create(sessionId, groupInfo));
                }
            }
        private void LogLinkedFileDiffMergingSessionInfo(LinkedFileDiffMergingSessionInfo sessionInfo)
        {
            if (!_logSessionInfo)
            {
                return;
            }

            LinkedFileDiffMergingLogger.LogSession(this._newSolution.Workspace, sessionInfo);
        }
        private void LogLinkedFileDiffMergingSessionInfo(LinkedFileDiffMergingSessionInfo sessionInfo)
        {
            // don't report telemetry
            if (!_logSessionInfo)
            {
                return;
            }

            var sessionId = SessionLogMessage.GetNextId();

            Logger.Log(FunctionId.Workspace_Solution_LinkedFileDiffMergingSession, SessionLogMessage.Create(sessionId, sessionInfo));

            foreach (var groupInfo in sessionInfo.LinkedFileGroups)
            {
                Logger.Log(FunctionId.Workspace_Solution_LinkedFileDiffMergingSession_LinkedFileGroup, SessionLogMessage.Create(sessionId, groupInfo));
            }
        }
Esempio n. 13
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
                       ));
        }
 void ITelemetryService.LogLinkedFileDiffMergingSession(LinkedFileDiffMergingSessionInfo session)
 {
 }