예제 #1
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));
        }
        internal static async Task FindReferencesAsync(
            SymbolAndProjectId symbolAndProjectId,
            Solution solution,
            IStreamingFindReferencesProgress progress,
            IImmutableSet <Document> documents,
            FindReferencesSearchOptions options,
            CancellationToken cancellationToken)
        {
            using (Logger.LogBlock(FunctionId.FindReference, cancellationToken))
            {
                // If ProjectId is null then this is a call through our old public API.  We don't have
                // the necessary data to effectively run the call out of proc.
                if (symbolAndProjectId.ProjectId != null)
                {
                    var client = await RemoteHostClient.TryGetClientAsync(solution.Workspace, cancellationToken).ConfigureAwait(false);

                    if (client != null)
                    {
                        // Create a callback that we can pass to the server process to hear about the
                        // results as it finds them.  When we hear about results we'll forward them to
                        // the 'progress' parameter which will then update the UI.
                        var serverCallback = new FindReferencesServerCallback(solution, progress, cancellationToken);

                        var success = await client.TryRunRemoteAsync(
                            WellKnownServiceHubServices.CodeAnalysisService,
                            nameof(IRemoteSymbolFinder.FindReferencesAsync),
                            solution,
                            new object[]
                        {
                            SerializableSymbolAndProjectId.Dehydrate(symbolAndProjectId),
                            documents?.Select(d => d.Id).ToArray(),
                            SerializableFindReferencesSearchOptions.Dehydrate(options),
                        },
                            serverCallback,
                            cancellationToken).ConfigureAwait(false);

                        if (success)
                        {
                            return;
                        }
                    }
                }

                // Couldn't effectively search in OOP. Perform the search in-proc.
                await FindReferencesInCurrentProcessAsync(
                    symbolAndProjectId, solution, progress,
                    documents, options, cancellationToken).ConfigureAwait(false);
            }
        }
        internal static async Task FindReferencesAsync(
            ISymbol symbol,
            Solution solution,
            IStreamingFindReferencesProgress progress,
            IImmutableSet <Document> documents,
            FindReferencesSearchOptions options,
            CancellationToken cancellationToken)
        {
            Contract.ThrowIfNull(solution.GetOriginatingProjectId(symbol), WorkspacesResources.Symbols_project_could_not_be_found_in_the_provided_solution);

            using (Logger.LogBlock(FunctionId.FindReference, cancellationToken))
            {
                var client = await RemoteHostClient.TryGetClientAsync(solution.Workspace, cancellationToken).ConfigureAwait(false);

                if (client != null)
                {
                    // Create a callback that we can pass to the server process to hear about the
                    // results as it finds them.  When we hear about results we'll forward them to
                    // the 'progress' parameter which will then update the UI.
                    var serverCallback = new FindReferencesServerCallback(solution, progress, cancellationToken);

                    var success = await client.TryRunRemoteAsync(
                        WellKnownServiceHubServices.CodeAnalysisService,
                        nameof(IRemoteSymbolFinder.FindReferencesAsync),
                        solution,
                        new object[]
                    {
                        SerializableSymbolAndProjectId.Dehydrate(solution, symbol, cancellationToken),
                        documents?.Select(d => d.Id).ToArray(),
                        SerializableFindReferencesSearchOptions.Dehydrate(options),
                    },
                        serverCallback,
                        cancellationToken).ConfigureAwait(false);

                    if (success)
                    {
                        return;
                    }
                }

                // Couldn't effectively search in OOP. Perform the search in-proc.
                await FindReferencesInCurrentProcessAsync(
                    symbol, solution, progress,
                    documents, options, cancellationToken).ConfigureAwait(false);
            }
        }
예제 #4
0
        internal static async Task <ConflictResolution> ResolveConflictsAsync(
            RenameLocations renameLocationSet,
            string replacementText,
            ImmutableHashSet <ISymbol> nonConflictSymbols,
            CancellationToken cancellationToken)
        {
            cancellationToken.ThrowIfCancellationRequested();

            using (Logger.LogBlock(FunctionId.Renamer_FindRenameLocationsAsync, cancellationToken))
            {
                var solution = renameLocationSet.Solution;
                var client   = await RemoteHostClient.TryGetClientAsync(solution.Workspace, cancellationToken).ConfigureAwait(false);

                if (client != null)
                {
                    var result = await client.TryRunRemoteAsync <SerializableConflictResolution>(
                        WellKnownServiceHubServices.CodeAnalysisService,
                        nameof(IRemoteRenamer.ResolveConflictsAsync),
                        solution,
                        new object[]
                    {
                        renameLocationSet.Dehydrate(solution, cancellationToken),
                        replacementText,
                        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 ResolveConflictsInCurrentProcessAsync(
                       renameLocationSet, replacementText, nonConflictSymbols, cancellationToken).ConfigureAwait(false));
        }
예제 #5
0
        public static async Task <ImmutableArray <INamedTypeSymbol>?> TryFindAndCacheRemoteTypesAsync(
            INamedTypeSymbol type,
            Solution solution,
            IImmutableSet <Project> projects,
            bool transitive,
            FunctionId functionId,
            string remoteFunctionName,
            CancellationToken cancellationToken)
        {
            using (Logger.LogBlock(functionId, cancellationToken))
            {
                var client = await RemoteHostClient.TryGetClientAsync(solution.Workspace, cancellationToken).ConfigureAwait(false);

                if (client != null)
                {
                    var result = await client.TryRunRemoteAsync <ImmutableArray <SerializableSymbolAndProjectId> >(
                        WellKnownServiceHubServices.CodeAnalysisService,
                        remoteFunctionName,
                        solution,
                        new object[]
                    {
                        SerializableSymbolAndProjectId.Dehydrate(solution, type, cancellationToken),
                        projects?.Select(p => p.Id).ToArray(),
                        transitive,
                    },
                        null,
                        cancellationToken).ConfigureAwait(false);

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

            return(null);
        }
예제 #6
0
 public static SerializableSearchResult Dehydrate(Solution solution, RenameLocations.SearchResult result, CancellationToken cancellationToken)
 => result == null ? null : new SerializableSearchResult
 {
     Locations         = result.Locations?.Select(loc => SerializableRenameLocation.Dehydrate(loc)).ToArray(),
     ImplicitLocations = result.ImplicitLocations.IsDefault ? null : result.ImplicitLocations.Select(loc => SerializableReferenceLocation.Dehydrate(loc, cancellationToken)).ToArray(),
     ReferencedSymbols = result.ReferencedSymbols.IsDefault ? null : result.ReferencedSymbols.Select(s => SerializableSymbolAndProjectId.Dehydrate(solution, s, cancellationToken)).ToArray(),
 };
예제 #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));
        }
예제 #8
0
        internal static async Task <ConflictResolution> ResolveConflictsAsync(
            RenameLocations renameLocationSet,
            string replacementText,
            ImmutableHashSet <ISymbol>?nonConflictSymbols,
            CancellationToken cancellationToken)
        {
            cancellationToken.ThrowIfCancellationRequested();

            using (Logger.LogBlock(FunctionId.Renamer_FindRenameLocationsAsync, cancellationToken))
            {
                var solution = renameLocationSet.Solution;
                var client   = await RemoteHostClient.TryGetClientAsync(solution.Workspace, cancellationToken).ConfigureAwait(false);

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

                    var result = await client.TryInvokeAsync <IRemoteRenamerService, SerializableConflictResolution?>(
                        solution,
                        (service, solutionInfo, cancellationToken) => service.ResolveConflictsAsync(solutionInfo, serializableLocationSet, replacementText, 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 ResolveConflictsInCurrentProcessAsync(
                       renameLocationSet, replacementText, nonConflictSymbols, cancellationToken).ConfigureAwait(false));
        }
예제 #9
0
        /// <summary>
        /// Find the locations that need to be renamed.  Can cross process boundaries efficiently to do this.
        /// </summary>
        public static async Task <LightweightRenameLocations> FindRenameLocationsAsync(
            ISymbol symbol, Solution solution, SymbolRenameOptions options, CodeCleanupOptionsProvider fallbackOptions, 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.TryInvokeAsync <IRemoteRenamerService, SerializableRenameLocations?>(
                            solution,
                            (service, solutionInfo, callbackId, cancellationToken) => service.FindRenameLocationsAsync(solutionInfo, callbackId, serializedSymbol, options, cancellationToken),
                            callbackTarget : new RemoteOptionsProvider <CodeCleanupOptions>(solution.Workspace.Services, fallbackOptions),
                            cancellationToken).ConfigureAwait(false);

                        if (result.HasValue && result.Value != null)
                        {
                            var rehydrated = await TryRehydrateAsync(
                                solution, symbol, fallbackOptions, 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.
            var renameLocations = await HeavyweightRenameLocations.FindLocationsInCurrentProcessAsync(
                symbol, solution, options, fallbackOptions, cancellationToken).ConfigureAwait(false);

            return(new LightweightRenameLocations(
                       symbol, solution, options, fallbackOptions, renameLocations.Locations,
                       renameLocations.ImplicitLocations.IsDefault ? null : renameLocations.ImplicitLocations.Select(loc => SerializableReferenceLocation.Dehydrate(loc, cancellationToken)).ToArray(),
                       renameLocations.ReferencedSymbols.IsDefault ? null : renameLocations.ReferencedSymbols.Select(sym => SerializableSymbolAndProjectId.Dehydrate(solution, sym, cancellationToken)).ToArray()));
        }
예제 #10
0
 public SerializableRenameLocations Dehydrate(Solution solution, CancellationToken cancellationToken)
 => new SerializableRenameLocations(
     SerializableSymbolAndProjectId.Dehydrate(solution, Symbol, cancellationToken),
     SerializableRenameOptionSet.Dehydrate(Options),
     SerializableSearchResult.Dehydrate(solution, _result, cancellationToken));