// The rename process and annotation for the bookkeeping is performed in one-step
            private async Task<Solution> AnnotateAndRename_WorkerAsync(
                Solution originalSolution,
                Solution partiallyRenamedSolution,
                HashSet<DocumentId> documentIdsToRename,
                IEnumerable<RenameLocation> renameLocations,
                RenamedSpansTracker renameSpansTracker,
                bool replacementTextValid)
            {
                try
                {
                    foreach (var documentId in documentIdsToRename.ToList())
                    {
                        _cancellationToken.ThrowIfCancellationRequested();

                        // We try to rewrite all locations that are not candidate locations. If there is only one location 
                        // it must be the correct one (the symbol is ambiguous to something else) and we always try to rewrite it.
                        var document = originalSolution.GetDocument(documentId);
                        var semanticModel = await document.GetSemanticModelAsync(_cancellationToken).ConfigureAwait(false);
                        var originalSyntaxRoot = await semanticModel.SyntaxTree.GetRootAsync(_cancellationToken).ConfigureAwait(false);

                        // Get all rename locations for the current document.
                        var allTextSpansInSingleSourceTree = renameLocations
                            .Where(l => l.DocumentId == documentId && !l.IsRenameInStringOrComment && (renameLocations.Count() == 1 || !l.IsCandidateLocation || l.IsMethodGroupReference))
                            .ToDictionary(l => l.Location.SourceSpan);

                        // All textspan in the document documentId, that requires rename in String or Comment
                        var stringAndCommentTextSpansInSingleSourceTree = renameLocations
                            .Where(l => l.DocumentId == documentId && l.IsRenameInStringOrComment)
                            .GroupBy(l => l.ContainingLocationForStringOrComment)
                            .Select(g => g.Key)
                            .ToSet();

                        var conflictLocationSpans = _conflictLocations
                                                    .Where(t => t.DocumentId == documentId)
                                                    .Select(t => t.ComplexifiedSpan).ToSet();

                        // Annotate all nodes with a RenameLocation annotations to record old locations & old referenced symbols.
                        // Also annotate nodes that should get complexified (nodes for rename locations + conflict locations)
                        var parameters = new RenameRewriterParameters(
                            _renamedSymbolDeclarationAnnotation,
                            document,
                            semanticModel,
                            originalSyntaxRoot,
                            _replacementText,
                            _originalText,
                            _possibleNameConflicts,
                            allTextSpansInSingleSourceTree,
                            stringAndCommentTextSpansInSingleSourceTree,
                            conflictLocationSpans,
                            originalSolution,
                            _renameLocationSet.Symbol,
                            replacementTextValid,
                            renameSpansTracker,
                            _optionSet,
                            _renameAnnotations,
                            _cancellationToken);

                        var renameRewriterLanguageService = document.Project.LanguageServices.GetService<IRenameRewriterLanguageService>();
                        var newRoot = renameRewriterLanguageService.AnnotateAndRename(parameters);

                        if (newRoot == originalSyntaxRoot)
                        {
                            // Update the list for the current phase, some files with strings containing the original or replacement
                            // text may have been filtered out.
                            documentIdsToRename.Remove(documentId);
                        }
                        else
                        {
                            partiallyRenamedSolution = partiallyRenamedSolution.WithDocumentSyntaxRoot(documentId, newRoot, PreservationMode.PreserveIdentity);
                        }
                    }

                    return partiallyRenamedSolution;
                }
                catch (Exception e) when (FatalError.ReportUnlessCanceled(e))
                {
                    throw ExceptionUtilities.Unreachable;
                }
            }
Beispiel #2
0
            // The rename process and annotation for the bookkeeping is performed in one-step
            private async Task <Solution> AnnotateAndRename_WorkerAsync(
                Solution originalSolution,
                Solution partiallyRenamedSolution,
                HashSet <DocumentId> documentIdsToRename,
                ISet <RenameLocation> renameLocations,
                RenamedSpansTracker renameSpansTracker,
                bool replacementTextValid)
            {
                try
                {
                    foreach (var documentId in documentIdsToRename.ToList())
                    {
                        _cancellationToken.ThrowIfCancellationRequested();

                        var document      = originalSolution.GetDocument(documentId);
                        var semanticModel = await document.GetSemanticModelAsync(_cancellationToken).ConfigureAwait(false);

                        var originalSyntaxRoot = await semanticModel.SyntaxTree.GetRootAsync(_cancellationToken).ConfigureAwait(false);

                        // Get all rename locations for the current document.
                        var allTextSpansInSingleSourceTree = renameLocations
                                                             .Where(l => l.DocumentId == documentId && ShouldIncludeLocation(renameLocations, l))
                                                             .ToDictionary(l => l.Location.SourceSpan);

                        // All textspan in the document documentId, that requires rename in String or Comment
                        var stringAndCommentTextSpansInSingleSourceTree = renameLocations
                                                                          .Where(l => l.DocumentId == documentId && l.IsRenameInStringOrComment)
                                                                          .GroupBy(l => l.ContainingLocationForStringOrComment)
                                                                          .Select(g => g.Key)
                                                                          .ToSet();

                        var conflictLocationSpans = _conflictLocations
                                                    .Where(t => t.DocumentId == documentId)
                                                    .Select(t => t.ComplexifiedSpan).ToSet();

                        // Annotate all nodes with a RenameLocation annotations to record old locations & old referenced symbols.
                        // Also annotate nodes that should get complexified (nodes for rename locations + conflict locations)
                        var parameters = new RenameRewriterParameters(
                            _renamedSymbolDeclarationAnnotation,
                            document,
                            semanticModel,
                            originalSyntaxRoot,
                            _replacementText,
                            _originalText,
                            _possibleNameConflicts,
                            allTextSpansInSingleSourceTree,
                            stringAndCommentTextSpansInSingleSourceTree,
                            conflictLocationSpans,
                            originalSolution,
                            _renameLocationSet.Symbol,
                            replacementTextValid,
                            renameSpansTracker,
                            _optionSet,
                            _renameAnnotations,
                            _cancellationToken);

                        var renameRewriterLanguageService = document.GetLanguageService <IRenameRewriterLanguageService>();
                        var newRoot = renameRewriterLanguageService.AnnotateAndRename(parameters);

                        if (newRoot == originalSyntaxRoot)
                        {
                            // Update the list for the current phase, some files with strings containing the original or replacement
                            // text may have been filtered out.
                            documentIdsToRename.Remove(documentId);
                        }
                        else
                        {
                            partiallyRenamedSolution = partiallyRenamedSolution.WithDocumentSyntaxRoot(documentId, newRoot, PreservationMode.PreserveIdentity);
                        }
                    }

                    return(partiallyRenamedSolution);
                }
                catch (Exception e) when(FatalError.ReportUnlessCanceled(e))
                {
                    throw ExceptionUtilities.Unreachable;
                }
            }
            // The rename process and annotation for the bookkeeping is performed in one-step
            private async Task <Solution> AnnotateAndRename_WorkerAsync(
                Solution originalSolution,
                Solution partiallyRenamedSolution,
                HashSet <DocumentId> documentIdsToRename,
                IEnumerable <RenameLocation> renameLocations,
                RenamedSpansTracker renameSpansTracker,
                bool replacementTextValid)
            {
                foreach (var documentId in documentIdsToRename.ToList())
                {
                    cancellationToken.ThrowIfCancellationRequested();

                    // We try to rewrite all locations that are not candidate locations. If there is only one location
                    // it must be the correct one (the symbol is ambiguous to something else) and we always try to rewrite it.
                    var document      = originalSolution.GetDocument(documentId);
                    var semanticModel = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false);

                    var originalSyntaxRoot = await semanticModel.SyntaxTree.GetRootAsync(cancellationToken).ConfigureAwait(false);

                    // Get all rename locations for the current document.
                    var allTextSpansInSingleSourceTree = renameLocations
                                                         .Where(l => l.DocumentId == documentId && !l.IsRenameInStringOrComment && (renameLocations.Count() == 1 || !l.IsCandidateLocation))
                                                         .ToDictionary(l => l.Location.SourceSpan);

                    // All textspan in the document documentId, that requires rename in String or Comment
                    var stringAndCommentTextSpansInSingleSourceTree = renameLocations
                                                                      .Where(l => l.DocumentId == documentId && l.IsRenameInStringOrComment)
                                                                      .GroupBy(l => l.ContainingLocationForStringOrComment)
                                                                      .Select(g => g.Key)
                                                                      .ToSet();

                    var conflictLocationSpans = this.conflictLocations
                                                .Where(t => t.DocumentId == documentId)
                                                .Select(t => t.ComplexifiedSpan).ToSet();

                    // Annotate all nodes with a RenameLocation annotations to record old locations & old referenced symbols.
                    // Also annotate nodes that should get complexified (nodes for rename locations + conflict locations)
                    var parameters = new RenameRewriterParameters(
                        this.renamedSymbolDeclarationAnnotation,
                        document,
                        semanticModel,
                        originalSyntaxRoot,
                        replacementText,
                        originalText,
                        possibleNameConflicts,
                        allTextSpansInSingleSourceTree,
                        stringAndCommentTextSpansInSingleSourceTree,
                        conflictLocationSpans,
                        originalSolution,
                        renameLocationSet.Symbol,
                        replacementTextValid,
                        cancellationToken,
                        renameSpansTracker,
                        optionSet,
                        this.renameAnnotations);

                    var renameRewriterLanguageService = LanguageService.GetService <IRenameRewriterLanguageService>(document);
                    var newRoot = renameRewriterLanguageService.AnnotateAndRename(parameters);

                    if (newRoot == originalSyntaxRoot)
                    {
                        // Update the list for the current phase, some files with strings containing the original or replacement
                        // text may have been filtered out.
                        documentIdsToRename.Remove(documentId);
                    }
                    else
                    {
                        partiallyRenamedSolution = partiallyRenamedSolution.WithDocumentSyntaxRoot(documentId, newRoot, PreservationMode.PreserveIdentity);
                    }
                }

                return(partiallyRenamedSolution);
            }