Пример #1
0
        private static async Task <T> FindAsync <T>(Solution solution, DocumentId documentId, SyntaxNode syntaxNode,
                                                    Func <CodeLensFindReferencesProgress, Task <T> > onResults, Func <CodeLensFindReferencesProgress, Task <T> > onCapped,
                                                    int searchCap, CancellationToken cancellationToken) where T : class
        {
            var document = solution.GetDocument(documentId);

            if (document == null)
            {
                return(null);
            }

            var cacheService = solution.Services.CacheService;
            var caches       = solution.GetProjectDependencyGraph().GetProjectsThatTransitivelyDependOnThisProject(document.Project.Id).Select(pid => cacheService?.EnableCaching(pid)).ToList();

            try
            {
                var semanticModel = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false);

                cancellationToken.ThrowIfCancellationRequested();

                var symbol = semanticModel.GetDeclaredSymbol(syntaxNode, cancellationToken);
                if (symbol == null)
                {
                    return(null);
                }

                using (var progress = new CodeLensFindReferencesProgress(symbol, syntaxNode, searchCap, cancellationToken))
                {
                    try
                    {
                        await SymbolFinder.FindReferencesAsync(symbol, solution, progress, null,
                                                               progress.CancellationToken).ConfigureAwait(false);

                        return(await onResults(progress).ConfigureAwait(false));
                    }
                    catch (OperationCanceledException)
                    {
                        if (onCapped != null && progress.SearchCapReached)
                        {
                            // search was cancelled, and it was cancelled by us because a cap was reached.
                            return(await onCapped(progress).ConfigureAwait(false));
                        }

                        // search was cancelled, but not because of cap.
                        // this always throws.
                        throw;
                    }
                }
            }
            finally
            {
                caches.WhereNotNull().Do(c => c.Dispose());
            }
        }
Пример #2
0
        private async Task <T> FindAsync <T>(Solution solution, DocumentId documentId, SyntaxNode syntaxNode,
                                             Func <CodeLensFindReferencesProgress, Task <T> > onResults, Func <CodeLensFindReferencesProgress, Task <T> > onCapped,
                                             int searchCap, CancellationToken cancellationToken) where T : class
        {
            var document = solution.GetDocument(documentId);

            if (document == null)
            {
                return(null);
            }

            var semanticModel = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false);

            if (semanticModel == null)
            {
                return(null);
            }

            cancellationToken.ThrowIfCancellationRequested();

            var symbol = semanticModel.GetDeclaredSymbol(syntaxNode, cancellationToken);

            if (symbol == null)
            {
                return(null);
            }

            using (var progress = new CodeLensFindReferencesProgress(symbol, syntaxNode, searchCap, cancellationToken))
            {
                try
                {
                    await SymbolFinder.FindReferencesAsync(symbol, solution, progress, null,
                                                           progress.CancellationToken).ConfigureAwait(false);

                    return(await onResults(progress).ConfigureAwait(false));
                }
                catch (OperationCanceledException)
                {
                    if (onCapped != null && progress.SearchCapReached)
                    {
                        // search was cancelled, and it was cancelled by us because a cap was reached.
                        return(await onCapped(progress).ConfigureAwait(false));
                    }

                    // search was cancelled, but not because of cap.
                    // this always throws.
                    throw;
                }
            }
        }
Пример #3
0
        public async Task<ReferenceCount?> GetReferenceCountAsync(Solution solution, DocumentId documentId, SyntaxNode syntaxNode, int maxSearchResults, CancellationToken cancellationToken)
        {
            var document = solution.GetDocument(documentId);
            if (document == null)
            {
                return null;
            }

            var semanticModel = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false);
            if (semanticModel == null)
            {
                return null;
            }

            cancellationToken.ThrowIfCancellationRequested();

            var symbol = semanticModel.GetDeclaredSymbol(syntaxNode, cancellationToken);
            if (symbol == null)
            {
                return null;
            }

            using (var progress = new CodeLensFindReferencesProgress(symbol, syntaxNode, maxSearchResults, cancellationToken))
            {
                try
                {
                    await SymbolFinder.FindReferencesAsync(symbol, solution, progress, null,
                        progress.CancellationToken).ConfigureAwait(false);

                    return new ReferenceCount(
                        progress.SearchCap > 0
                            ? Math.Min(progress.ReferencesCount, progress.SearchCap)
                            : progress.ReferencesCount, progress.SearchCapReached);
                }
                catch (OperationCanceledException)
                {
                    if (progress.SearchCapReached)
                    {
                        // search was cancelled, and it was cancelled by us because a cap was reached.
                        return new ReferenceCount(progress.SearchCap, isCapped: true);
                    }

                    // search was cancelled, but not because of cap.
                    // this always throws.
                    throw;
                }
            }
        }
Пример #4
0
        public async Task<IEnumerable<ReferenceLocationDescriptor>> FindReferenceLocationsAsync(Solution solution, DocumentId documentId, SyntaxNode syntaxNode, CancellationToken cancellationToken)
        {
            var document = solution.GetDocument(documentId);
            if (document == null)
            {
                return null;
            }

            var semanticModel = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false);
            if (semanticModel == null)
            {
                return null;
            }

            cancellationToken.ThrowIfCancellationRequested();

            var symbol = semanticModel.GetDeclaredSymbol(syntaxNode, cancellationToken);
            if (symbol == null)
            {
                return null;
            }

            using (var progress = new CodeLensFindReferencesProgress(symbol, syntaxNode, searchCap: 0, cancellationToken: cancellationToken))
            {
                await SymbolFinder.FindReferencesAsync(symbol, solution, progress, null,
                    progress.CancellationToken).ConfigureAwait(false);

                var referenceTasks = progress.Locations
                    .Where(location => location.Kind != LocationKind.MetadataFile && location.Kind != LocationKind.None)
                    .Distinct(LocationComparer.Instance)
                    .Select(
                        location =>
                            GetDescriptorOfEnclosingSymbolAsync(solution, location, cancellationToken))
                    .ToArray();

                await Task.WhenAll(referenceTasks).ConfigureAwait(false);

                return referenceTasks.Select(task => task.Result);
            }
        }