public Task FindImplementationsAsync(
            PinnedSolutionInfo solutionInfo,
            SerializableSymbolAndProjectId symbolAndProjectIdArg,
            CancellationToken cancellationToken)
        {
            return(RunServiceAsync(async() =>
            {
                using (UserOperationBooster.Boost())
                {
                    var solution = await GetSolutionAsync(solutionInfo, cancellationToken).ConfigureAwait(false);
                    var project = solution.GetProject(symbolAndProjectIdArg.ProjectId);

                    var symbol = await symbolAndProjectIdArg.TryRehydrateAsync(
                        solution, cancellationToken).ConfigureAwait(false);
                    if (symbol == null)
                    {
                        return;
                    }

                    var context = new RemoteFindUsageContext(solution, EndPoint, cancellationToken);
                    await AbstractFindUsagesService.FindImplementationsAsync(
                        symbol, project, context).ConfigureAwait(false);
                }
            }, cancellationToken));
        }
예제 #2
0
        public async Task FindSymbolReferencesAsync(
            ISymbol symbol,
            Project project,
            CancellationToken cancellationToken
            )
        {
            var streamingPresenter = _streamingPresenter.Value;

            // Let the presenter know we're starting a search.  It will give us back
            // the context object that the FAR service will push results into.
            var context = streamingPresenter.StartSearch(
                EditorFeaturesResources.Find_References,
                supportsReferences: true,
                cancellationToken
                );

            try
            {
                await AbstractFindUsagesService
                .FindSymbolReferencesAsync(context, symbol, project)
                .ConfigureAwait(false);
            }
            finally
            {
                await context.OnCompletedAsync().ConfigureAwait(false);
            }
        }
예제 #3
0
        private static async Task FindReferencesAsync(SymbolListItem symbolListItem, Project project, CodeAnalysis.FindUsages.FindUsagesContext context)
        {
            var compilation = await project.GetCompilationAsync(context.CancellationToken).ConfigureAwait(false);

            var symbol = symbolListItem.ResolveSymbol(compilation);

            if (symbol != null)
            {
                await AbstractFindUsagesService.FindSymbolReferencesAsync(context, symbol, project).ConfigureAwait(false);
            }
        }
예제 #4
0
        public async Task FindSymbolReferencesAsync(ISymbol symbol, Project project, CancellationToken cancellationToken)
        {
            var streamingPresenter = _streamingPresenter.Value;

            // Let the presenter know we're starting a search.  It will give us back
            // the context object that the FAR service will push results into.
            var context = streamingPresenter.StartSearch(EditorFeaturesResources.Find_References, supportsReferences: true);

            await AbstractFindUsagesService.FindSymbolReferencesAsync(_threadingContext, context, symbol, project, cancellationToken).ConfigureAwait(false);

            // Note: we don't need to put this in a finally.  The only time we might not hit
            // this is if cancellation or another error gets thrown.  In the former case,
            // that means that a new search has started.  We don't care about telling the
            // context it has completed.  In the latter case something wrong has happened
            // and we don't want to run any more code in this particular context.
            await context.OnCompletedAsync().ConfigureAwait(false);
        }
        public async Task FindSymbolReferencesAsync(ISymbol symbol, Project project, CancellationToken cancellationToken)
        {
            var streamingPresenter = _streamingPresenter.Value;

            // Let the presenter know we're starting a search.  It will give us back
            // the context object that the FAR service will push results into.
            //
            // We're awaiting the work to find the symbols (as opposed to kicking it off in a
            // fire-and-forget streaming fashion).  As such, we do not want to use the cancellation
            // token provided by the presenter.  Instead, we'll let our caller own if this work
            // is cancelable.
            var(context, _) = streamingPresenter.StartSearch(EditorFeaturesResources.Find_References, supportsReferences: true);

            try
            {
                await AbstractFindUsagesService.FindSymbolReferencesAsync(context, symbol, project, cancellationToken).ConfigureAwait(false);
            }
            finally
            {
                await context.OnCompletedAsync(cancellationToken).ConfigureAwait(false);
            }
        }
        private async Task StreamingFindReferencesAsync(
            Document document, int caretPosition, IStreamingFindUsagesPresenter presenter)
        {
            try
            {
                // first, let's see if we even have a comment, otherwise there's no use in starting a search
                var relevantSymbol = await FindUsagesHelpers.GetRelevantSymbolAndProjectAtPositionAsync(document, caretPosition, new CancellationToken()).ConfigureAwait(false);
                var symbol = relevantSymbol?.symbol;
                if (symbol == null)
                    return; // would be useful if we could notify the user why we didn't do anything
                            // maybe using something like an info bar?

                var findUsagesService = document.GetLanguageService<IFindUsagesService>();

                using var token = _asyncListener.BeginAsyncOperation(nameof(StreamingFindReferencesAsync));

                var (context, cancellationToken) = presenter.StartSearch(EditorFeaturesResources.Find_References, supportsReferences: true);

                using (Logger.LogBlock(
                    FunctionId.CommandHandler_FindAllReference,
                    KeyValueLogMessage.Create(LogType.UserAction, m => m["type"] = "streaming"),
                    cancellationToken))
                {
                    var symbolsToLookup = new List<ISymbol>();

                    foreach (var curSymbol in symbol.ContainingType.GetMembers()
                                                    .Where(m => m.Kind == symbol.Kind && m.Name == symbol.Name))
                    {
                        if (!document.Project.TryGetCompilation(out var compilation))
                        {
                            // TODO: should we do anything more here?
                            continue;
                        }

                        foreach (var sym in SymbolFinder.FindSimilarSymbols(curSymbol, compilation, cancellationToken))
                        {
                            // assumption here is, that FindSimilarSymbols returns symbols inside same project
                            var symbolsToAdd = await GatherSymbolsAsync(sym, document.Project.Solution, cancellationToken).ConfigureAwait(false);
                            symbolsToLookup.AddRange(symbolsToAdd);
                        }
                    }

                    foreach (var candidate in symbolsToLookup)
                    {
                        await AbstractFindUsagesService.FindSymbolReferencesAsync(context, candidate, document.Project, cancellationToken).ConfigureAwait(false);
                    }

                    // Note: we don't need to put this in a finally.  The only time we might not hit
                    // this is if cancellation or another error gets thrown.  In the former case,
                    // that means that a new search has started.  We don't care about telling the
                    // context it has completed.  In the latter case something wrong has happened
                    // and we don't want to run any more code in this particular context.
                    await context.OnCompletedAsync(cancellationToken).ConfigureAwait(false);
                }
            }
            catch (OperationCanceledException)
            {
            }
            catch (Exception e) when (FatalError.ReportAndCatch(e))
            {
            }
        }