Beispiel #1
0
 public static SerializableRenameOptionSet Dehydrate(RenameOptionSet optionSet)
 => new SerializableRenameOptionSet
 {
     RenameOverloads  = optionSet.RenameOverloads,
     RenameInStrings  = optionSet.RenameInStrings,
     RenameInComments = optionSet.RenameInComments,
     RenameFile       = optionSet.RenameFile,
 };
        private static async Task <RenameLocations> FindLocationsInCurrentProcessAsync(
            ISymbol symbol, Solution solution, RenameOptionSet optionSet, CancellationToken cancellationToken)
        {
            Contract.ThrowIfNull(symbol);
            using (Logger.LogBlock(FunctionId.Rename_AllRenameLocations, cancellationToken))
            {
                symbol = await ReferenceProcessing.FindDefinitionSymbolAsync(symbol, solution, cancellationToken).ConfigureAwait(false);

                // First, find the direct references just to the symbol being renamed.
                var originalSymbolResult = await AddLocationsReferenceSymbolsAsync(symbol, solution, cancellationToken).ConfigureAwait(false);

                // Next, find references to overloads, if the user has asked to rename those as well.
                var overloadsResult = await GetOverloadsAsync(symbol, solution, optionSet, cancellationToken).ConfigureAwait(false);

                // Finally, include strings/comments if that's what the user wants.
                var(strings, comments) = await ReferenceProcessing.GetRenamableLocationsInStringsAndCommentsAsync(
                    symbol,
                    solution,
                    originalSymbolResult.Locations,
                    optionSet.RenameInStrings,
                    optionSet.RenameInComments,
                    cancellationToken).ConfigureAwait(false);

                var mergedLocations = ImmutableHashSet.CreateBuilder <RenameLocation>();

                using var _1 = ArrayBuilder <ISymbol> .GetInstance(out var mergedReferencedSymbols);

                using var _2 = ArrayBuilder <ReferenceLocation> .GetInstance(out var mergedImplicitLocations);

                var renameMethodGroupReferences = optionSet.RenameOverloads || !GetOverloadedSymbols(symbol).Any();
                foreach (var result in overloadsResult.Concat(originalSymbolResult))
                {
                    mergedLocations.AddRange(renameMethodGroupReferences
                        ? result.Locations
                        : result.Locations.Where(x => x.CandidateReason != CandidateReason.MemberGroup));

                    mergedImplicitLocations.AddRange(result.ImplicitLocations);
                    mergedReferencedSymbols.AddRange(result.ReferencedSymbols);
                }

                // Add string and comment locations to the merged hashset
                // after adding in reference symbols. This allows any references
                // in comments to be resolved as proper references rather than
                // comment resolutions. See https://github.com/dotnet/roslyn/issues/54294
                mergedLocations.AddRange(strings.NullToEmpty());
                mergedLocations.AddRange(comments.NullToEmpty());

                return(new RenameLocations(
                           symbol, solution, optionSet,
                           new SearchResult(
                               mergedLocations.ToImmutable(),
                               mergedImplicitLocations.ToImmutable(),
                               mergedReferencedSymbols.ToImmutable())));
            }
        }
Beispiel #3
0
 private RenameLocations(
     ISymbol symbol,
     Solution solution,
     RenameOptionSet options,
     SearchResult result)
 {
     Solution = solution;
     Symbol = symbol;
     Options = options;
     _result = result;
 }
Beispiel #4
0
 internal static RenameLocations Create(
     ImmutableHashSet<RenameLocation> locations,
     ISymbol symbol,
     Solution solution,
     ImmutableArray<ISymbol> referencedSymbols,
     ImmutableArray<ReferenceLocation> implicitLocations,
     RenameOptionSet options)
 {
     return new RenameLocations(
         symbol, solution, options,
         new SearchResult(locations, implicitLocations, referencedSymbols));
 }
 internal static RenameLocations Create(
     ImmutableHashSet <RenameLocation> locations,
     ISymbol symbol,
     Solution solution,
     ImmutableArray <ISymbol> referencedSymbols,
     ImmutableArray <ReferenceLocation> implicitLocations,
     RenameOptionSet options)
 {
     return(new RenameLocations(
                symbol, solution, options, originalSymbolResult: null,
                new SearchResult(locations, implicitLocations, referencedSymbols),
                overloadsResult: default, stringsResult: default, commentsResult: default));
Beispiel #6
0
        private static async Task<ImmutableArray<SearchResult>> GetOverloadsAsync(
            ISymbol symbol, Solution solution, RenameOptionSet options, CancellationToken cancellationToken)
        {
            using var _ = ArrayBuilder<SearchResult>.GetInstance(out var overloadsResult);

            if (options.RenameOverloads)
            {
                foreach (var overloadedSymbol in GetOverloadedSymbols(symbol))
                    overloadsResult.Add(await AddLocationsReferenceSymbolsAsync(overloadedSymbol, solution, cancellationToken).ConfigureAwait(false));
            }

            return overloadsResult.ToImmutable();
        }
Beispiel #7
0
        internal static async Task <ConflictResolution> RenameSymbolAsync(
            Solution solution,
            ISymbol symbol,
            string newName,
            RenameOptionSet optionSet,
            ImmutableHashSet <ISymbol>?nonConflictSymbols,
            CancellationToken cancellationToken)
        {
            Contract.ThrowIfNull(solution);
            Contract.ThrowIfNull(symbol);
            Contract.ThrowIfTrue(string.IsNullOrEmpty(newName));

            cancellationToken.ThrowIfCancellationRequested();

            using (Logger.LogBlock(FunctionId.Renamer_RenameSymbolAsync, cancellationToken))
            {
                if (SerializableSymbolAndProjectId.TryCreate(symbol, solution, cancellationToken, out var serializedSymbol))
                {
                    var client = await RemoteHostClient.TryGetClientAsync(solution.Workspace, cancellationToken).ConfigureAwait(false);

                    if (client != null)
                    {
                        var options = SerializableRenameOptionSet.Dehydrate(optionSet);
                        var nonConflictSymbolIds = nonConflictSymbols?.SelectAsArray(s => SerializableSymbolAndProjectId.Dehydrate(solution, s, cancellationToken)) ?? default;

                        var result = await client.TryInvokeAsync <IRemoteRenamerService, SerializableConflictResolution?>(
                            solution,
                            (service, solutionInfo, cancellationToken) => service.RenameSymbolAsync(
                                solutionInfo,
                                serializedSymbol,
                                newName,
                                options,
                                nonConflictSymbolIds,
                                cancellationToken),
                            callbackTarget : null,
                            cancellationToken).ConfigureAwait(false);

                        if (result.HasValue && result.Value != null)
                        {
                            return(await result.Value.RehydrateAsync(solution, cancellationToken).ConfigureAwait(false));
                        }

                        // TODO: do not fall back to in-proc if client is available (https://github.com/dotnet/roslyn/issues/47557)
                    }
                }
            }

            return(await RenameSymbolInCurrentProcessAsync(
                       solution, symbol, newName, optionSet,
                       nonConflictSymbols, cancellationToken).ConfigureAwait(false));
        }
Beispiel #8
0
        internal static async Task <ConflictResolution> RenameSymbolAsync(
            Solution solution,
            ISymbol symbol,
            string newName,
            RenameOptionSet optionSet,
            ImmutableHashSet <ISymbol> nonConflictSymbols,
            CancellationToken cancellationToken)
        {
            Contract.ThrowIfNull(solution);
            Contract.ThrowIfNull(symbol);
            Contract.ThrowIfTrue(string.IsNullOrEmpty(newName));

            cancellationToken.ThrowIfCancellationRequested();

            using (Logger.LogBlock(FunctionId.Renamer_RenameSymbolAsync, cancellationToken))
            {
                var project = solution.GetOriginatingProject(symbol);
                if (project != null)
                {
                    var client = await RemoteHostClient.TryGetClientAsync(solution.Workspace, cancellationToken).ConfigureAwait(false);

                    if (client != null)
                    {
                        var result = await client.TryRunRemoteAsync <SerializableConflictResolution>(
                            WellKnownServiceHubServices.CodeAnalysisService,
                            nameof(IRemoteRenamer.RenameSymbolAsync),
                            solution,
                            new object[]
                        {
                            SerializableSymbolAndProjectId.Create(symbol, project, cancellationToken),
                            newName,
                            SerializableRenameOptionSet.Dehydrate(optionSet),
                            nonConflictSymbols?.Select(s => SerializableSymbolAndProjectId.Dehydrate(solution, s, cancellationToken)).ToArray(),
                        },
                            callbackTarget : null,
                            cancellationToken).ConfigureAwait(false);

                        if (result.HasValue)
                        {
                            return(await result.Value.RehydrateAsync(solution, cancellationToken).ConfigureAwait(false));
                        }
                    }
                }
            }

            return(await RenameSymbolInCurrentProcessAsync(
                       solution, symbol, newName, optionSet,
                       nonConflictSymbols, cancellationToken).ConfigureAwait(false));
        }
Beispiel #9
0
        private static RenameLocations Create(
            ISymbol symbol,
            Solution solution,
            RenameOptionSet options,
            SearchResult originalSymbolResult,
            ImmutableArray <SearchResult> overloadsResult,
            ImmutableArray <RenameLocation> stringsResult,
            ImmutableArray <RenameLocation> commentsResult)
        {
            var mergedLocations = ImmutableHashSet.CreateBuilder <RenameLocation>();

            using var _1 = ArrayBuilder <ISymbol> .GetInstance(out var mergedReferencedSymbols);

            using var _2 = ArrayBuilder <ReferenceLocation> .GetInstance(out var mergedImplicitLocations);

            if (options.RenameInStrings)
            {
                mergedLocations.AddRange(stringsResult);
            }

            if (options.RenameInComments)
            {
                mergedLocations.AddRange(commentsResult);
            }

            var renameMethodGroupReferences = options.RenameOverloads || !GetOverloadedSymbols(symbol).Any();
            var overloadsToMerge            = options.RenameOverloads
                ? overloadsResult.NullToEmpty()
                : ImmutableArray <SearchResult> .Empty;

            foreach (var result in overloadsToMerge.Concat(originalSymbolResult))
            {
                mergedLocations.AddRange(renameMethodGroupReferences
                    ? result.Locations
                    : result.Locations.Where(x => x.CandidateReason != CandidateReason.MemberGroup));

                mergedImplicitLocations.AddRange(result.ImplicitLocations);
                mergedReferencedSymbols.AddRange(result.ReferencedSymbols);
            }

            return(new RenameLocations(
                       symbol, solution, options,
                       new SearchResult(
                           mergedLocations.ToImmutable(),
                           mergedImplicitLocations.ToImmutable(),
                           mergedReferencedSymbols.ToImmutable())));
        }
Beispiel #10
0
        public static async Task <RenameLocations> FindLocationsAsync(
            ISymbol symbol, Solution solution, RenameOptionSet optionSet, CancellationToken cancellationToken)
        {
            Contract.ThrowIfNull(solution);
            Contract.ThrowIfNull(symbol);

            cancellationToken.ThrowIfCancellationRequested();

            using (Logger.LogBlock(FunctionId.Renamer_FindRenameLocationsAsync, cancellationToken))
            {
                if (SerializableSymbolAndProjectId.TryCreate(symbol, solution, cancellationToken, out var serializedSymbol))
                {
                    var client = await RemoteHostClient.TryGetClientAsync(solution.Workspace, cancellationToken).ConfigureAwait(false);

                    if (client != null)
                    {
                        var result = await client.RunRemoteAsync <SerializableRenameLocations?>(
                            WellKnownServiceHubService.CodeAnalysis,
                            nameof(IRemoteRenamer.FindRenameLocationsAsync),
                            solution,
                            new object[]
                        {
                            serializedSymbol,
                            SerializableRenameOptionSet.Dehydrate(optionSet),
                        },
                            callbackTarget : null,
                            cancellationToken).ConfigureAwait(false);

                        if (result != null)
                        {
                            var rehydrated = await RenameLocations.TryRehydrateAsync(
                                solution, result, cancellationToken).ConfigureAwait(false);

                            if (rehydrated != null)
                            {
                                return(rehydrated);
                            }
                        }
                    }
                }
            }

            // Couldn't effectively search in OOP. Perform the search in-proc.
            return(await FindLocationsInCurrentProcessAsync(
                       symbol, solution, optionSet, cancellationToken).ConfigureAwait(false));
        }
Beispiel #11
0
        private static async Task <ConflictResolution> RenameSymbolInCurrentProcessAsync(
            Solution solution,
            ISymbol symbol,
            string newName,
            RenameOptionSet optionSet,
            ImmutableHashSet <ISymbol>?nonConflictSymbols,
            CancellationToken cancellationToken)
        {
            Contract.ThrowIfNull(solution);
            Contract.ThrowIfNull(symbol);
            Contract.ThrowIfTrue(string.IsNullOrEmpty(newName));

            cancellationToken.ThrowIfCancellationRequested();

            var renameLocations = await FindRenameLocationsAsync(solution, symbol, optionSet, cancellationToken).ConfigureAwait(false);

            return(await renameLocations.ResolveConflictsAsync(newName, nonConflictSymbols, cancellationToken).ConfigureAwait(false));
        }
Beispiel #12
0
        /// <summary>
        /// Find the locations that need to be renamed.
        /// </summary>
        public static async Task <RenameLocations> FindLocationsAsync(
            ISymbol symbol, Solution solution, RenameOptionSet optionSet, CancellationToken cancellationToken)
        {
            Contract.ThrowIfNull(solution);
            Contract.ThrowIfNull(symbol);

            cancellationToken.ThrowIfCancellationRequested();

            using (Logger.LogBlock(FunctionId.Renamer_FindRenameLocationsAsync, cancellationToken))
            {
                if (SerializableSymbolAndProjectId.TryCreate(symbol, solution, cancellationToken, out var serializedSymbol))
                {
                    var client = await RemoteHostClient.TryGetClientAsync(solution.Workspace, cancellationToken).ConfigureAwait(false);

                    if (client != null)
                    {
                        var options = SerializableRenameOptionSet.Dehydrate(optionSet);

                        var result = await client.TryInvokeAsync <IRemoteRenamerService, SerializableRenameLocations?>(
                            solution,
                            (service, solutionInfo, cancellationToken) => service.FindRenameLocationsAsync(solutionInfo, serializedSymbol, options, cancellationToken),
                            callbackTarget : null,
                            cancellationToken).ConfigureAwait(false);

                        if (result.HasValue && result.Value != null)
                        {
                            var rehydrated = await TryRehydrateAsync(
                                solution, result.Value, cancellationToken).ConfigureAwait(false);

                            if (rehydrated != null)
                            {
                                return(rehydrated);
                            }
                        }

                        // TODO: do not fall back to in-proc if client is available (https://github.com/dotnet/roslyn/issues/47557)
                    }
                }
            }

            // Couldn't effectively search in OOP. Perform the search in-proc.
            return(await FindLocationsInCurrentProcessAsync(
                       symbol, solution, optionSet, cancellationToken).ConfigureAwait(false));
        }
 private RenameLocations(
     ISymbol symbol,
     Solution solution,
     RenameOptionSet options,
     SearchResult?originalSymbolResult,
     SearchResult mergedResult,
     ImmutableArray <SearchResult> overloadsResult,
     ImmutableArray <RenameLocation> stringsResult,
     ImmutableArray <RenameLocation> commentsResult)
 {
     Solution = solution;
     Symbol   = symbol;
     Options  = options;
     _originalSymbolResult = originalSymbolResult;
     _mergedResult         = mergedResult;
     _overloadsResult      = overloadsResult;
     _stringsResult        = stringsResult;
     _commentsResult       = commentsResult;
 }
Beispiel #14
0
        private static async Task <ConflictResolution> RenameSymbolInCurrentProcessAsync(
            Solution solution,
            ISymbol symbol,
            string newName,
            RenameOptionSet optionSet,
            ImmutableHashSet <ISymbol> nonConflictSymbols,
            CancellationToken cancellationToken)
        {
            Contract.ThrowIfNull(solution);
            Contract.ThrowIfNull(symbol);
            Contract.ThrowIfNull(solution.GetOriginatingProjectId(symbol), WorkspacesResources.Symbols_project_could_not_be_found_in_the_provided_solution);
            Contract.ThrowIfTrue(string.IsNullOrEmpty(newName));

            cancellationToken.ThrowIfCancellationRequested();

            var renameLocations = await FindRenameLocationsAsync(solution, symbol, optionSet, cancellationToken).ConfigureAwait(false);

            return(await renameLocations.ResolveConflictsAsync(newName, nonConflictSymbols, cancellationToken).ConfigureAwait(false));
        }
Beispiel #15
0
        public static async Task <Solution> RenameSymbolAsync(
            Solution solution,
            ISymbol symbol,
            string newName,
            OptionSet optionSet,
            CancellationToken cancellationToken = default
            )
        {
            if (solution == null)
            {
                throw new ArgumentNullException(nameof(solution));
            }

            if (symbol == null)
            {
                throw new ArgumentNullException(nameof(symbol));
            }

            if (string.IsNullOrEmpty(newName))
            {
                throw new ArgumentException(nameof(newName));
            }

            var resolution = await RenameSymbolAsync(
                solution,
                symbol,
                newName,
                RenameOptionSet.From(solution, optionSet),
                nonConflictSymbols : null,
                cancellationToken
                )
                             .ConfigureAwait(false);

            // This is a public entry-point.  So if rename failed to resolve conflicts, we report that back to caller as
            // an exception.
            if (resolution.ErrorMessage != null)
            {
                throw new ArgumentException(resolution.ErrorMessage);
            }

            return(resolution.NewSolution);
        }
Beispiel #16
0
 public RenameRewriterParameters(
     RenameAnnotation renamedSymbolDeclarationAnnotation,
     Document document,
     SemanticModel semanticModel,
     SyntaxNode syntaxRoot,
     string replacementText,
     string originalText,
     ICollection <string> possibleNameConflicts,
     Dictionary <TextSpan, RenameLocation> renameLocations,
     ImmutableDictionary <TextSpan, ImmutableSortedSet <TextSpan>?> stringAndCommentTextSpans,
     ISet <TextSpan> conflictLocationSpans,
     Solution originalSolution,
     ISymbol renameSymbol,
     bool replacementTextValid,
     RenamedSpansTracker renameSpansTracker,
     RenameOptionSet optionSet,
     AnnotationTable <RenameAnnotation> renameAnnotations,
     CancellationToken cancellationToken
     )
 {
     this.RenamedSymbolDeclarationAnnotation = renamedSymbolDeclarationAnnotation;
     this.Document                  = document;
     this.SemanticModel             = semanticModel;
     this.SyntaxRoot                = syntaxRoot;
     this.OriginalSyntaxTree        = semanticModel.SyntaxTree;
     this.ReplacementText           = replacementText;
     this.OriginalText              = originalText;
     this.PossibleNameConflicts     = possibleNameConflicts;
     this.RenameLocations           = renameLocations;
     this.StringAndCommentTextSpans = stringAndCommentTextSpans;
     this.ConflictLocationSpans     = conflictLocationSpans;
     this.OriginalSolution          = originalSolution;
     this.RenameSymbol              = renameSymbol;
     this.ReplacementTextValid      = replacementTextValid;
     this.CancellationToken         = cancellationToken;
     this.RenameSpansTracker        = renameSpansTracker;
     this.OptionSet                 = optionSet;
     this.RenameAnnotations         = renameAnnotations;
 }
Beispiel #17
0
        public static async Task <Solution> RenameSymbolAsync(
            Solution solution, ISymbol symbol, string newName, OptionSet optionSet, CancellationToken cancellationToken = default)
        {
            if (solution == null)
            {
                throw new ArgumentNullException(nameof(solution));
            }

            if (symbol == null)
            {
                throw new ArgumentNullException(nameof(symbol));
            }

            if (solution.GetOriginatingProjectId(symbol) == null)
            {
                throw new ArgumentException(WorkspacesResources.Symbols_project_could_not_be_found_in_the_provided_solution, nameof(symbol));
            }

            if (string.IsNullOrEmpty(newName))
            {
                throw new ArgumentException(nameof(newName));
            }

            var resolution = await RenameSymbolAsync(
                solution, symbol, newName,
                RenameOptionSet.From(solution, optionSet),
                nonConflictSymbols : null, cancellationToken).ConfigureAwait(false);

            // This is a public entrypoint.  So if rename failed to resolve conflicts, we report that back to caller as
            // an exception.
            if (resolution.ErrorMessage != null)
            {
                throw new ArgumentException(resolution.ErrorMessage);
            }

            return(resolution.NewSolution);
        }
Beispiel #18
0
 public static SerializableRenameOptionSet Dehydrate(RenameOptionSet optionSet) =>
Beispiel #19
0
 internal static Task <RenameLocations> FindRenameLocationsAsync(Solution solution, ISymbol symbol, RenameOptionSet optionSet, CancellationToken cancellationToken)
 => RenameLocations.FindLocationsAsync(symbol, solution, optionSet, cancellationToken);
Beispiel #20
0
 internal static Task <RenameLocations> FindRenameLocationsAsync(
     Solution solution, ISymbol symbol, OptionSet optionSet, CancellationToken cancellationToken)
 {
     return(RenameLocations.FindLocationsAsync(
                symbol, solution, RenameOptionSet.From(solution, optionSet), cancellationToken));
 }
Beispiel #21
0
 public static SerializableRenameOptionSet Dehydrate(RenameOptionSet optionSet)
 => new(renameOverloads : optionSet.RenameOverloads,