提交 0a220a62 编写于 作者: C Cyrus Najmabadi

temp point

上级 715d5e89
......@@ -2,6 +2,8 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
#nullable enable
using System;
using System.Collections.Immutable;
using System.Linq;
......@@ -12,6 +14,7 @@
using Microsoft.CodeAnalysis.FindUsages;
using Microsoft.CodeAnalysis.LanguageServices;
using Microsoft.CodeAnalysis.Shared.Extensions;
using Microsoft.CodeAnalysis.SymbolMonikers;
using Roslyn.Utilities;
using VS.IntelliNav.Contracts;
......@@ -20,10 +23,14 @@ namespace Microsoft.CodeAnalysis.Editor.FindUsages
internal abstract partial class AbstractFindUsagesService : IFindUsagesService
{
private readonly IThreadingContext _threadingContext;
private readonly ICodeIndexProvider? _codeIndexProvider;
protected AbstractFindUsagesService(IThreadingContext threadingContext)
protected AbstractFindUsagesService(
IThreadingContext threadingContext,
ICodeIndexProvider? codeIndexProvider)
{
_threadingContext = threadingContext;
_codeIndexProvider = codeIndexProvider;
}
public async Task FindImplementationsAsync(
......@@ -111,7 +118,7 @@ protected AbstractFindUsagesService(IThreadingContext threadingContext)
ImmutableArray<DefinitionItem> definitions,
CancellationToken cancellationToken)
{
var factory = solution.Workspace.Services.GetService<IDefinitionsAndReferencesFactory>();
var factory = solution.Workspace.Services.GetRequiredService<IDefinitionsAndReferencesFactory>();
return definitions.Select(d => factory.GetThirdPartyDefinitionItem(solution, d, cancellationToken))
.WhereNotNull()
.ToImmutableArray();
......@@ -127,13 +134,11 @@ protected AbstractFindUsagesService(IThreadingContext threadingContext)
var symbolAndProject = await FindUsagesHelpers.GetRelevantSymbolAndProjectAtPositionAsync(
document, position, cancellationToken).ConfigureAwait(false);
if (symbolAndProject == null)
{
return;
}
await FindSymbolReferencesAsync(
_threadingContext,
context, symbolAndProject?.symbol, symbolAndProject?.project, cancellationToken).ConfigureAwait(false);
_threadingContext, _codeIndexProvider, context,
symbolAndProject.Value.symbol, symbolAndProject.Value.project, cancellationToken).ConfigureAwait(false);
}
/// <summary>
......@@ -141,7 +146,7 @@ protected AbstractFindUsagesService(IThreadingContext threadingContext)
/// and want to push all the references to it into the Streaming-Find-References window.
/// </summary>
public static async Task FindSymbolReferencesAsync(
IThreadingContext threadingContext,
IThreadingContext threadingContext, ICodeIndexProvider? codeIndexProvider,
IFindUsagesContext context, ISymbol symbol, Project project, CancellationToken cancellationToken)
{
await context.SetSearchTitleAsync(string.Format(EditorFeaturesResources._0_references,
......@@ -154,14 +159,53 @@ protected AbstractFindUsagesService(IThreadingContext threadingContext)
// engine will push results into the 'progress' instance passed into it.
// We'll take those results, massage them, and forward them along to the
// FindReferencesContext instance we were given.
await SymbolFinder.FindReferencesAsync(
var normalFindReferencesTask = SymbolFinder.FindReferencesAsync(
SymbolAndProjectId.Create(symbol, project.Id),
project.Solution,
progressAdapter,
documents: null,
options: options,
cancellationToken: cancellationToken).ConfigureAwait(false);
ICodeIndexProvider
options,
cancellationToken);
// Kick off work to search the online code index system in parallel
var codeIndexReferencesTask = FindCodeIndexReferencesAsync(
codeIndexProvider,
symbol,
project.Solution,
progressAdapter,
options,
cancellationToken);
await Task.WhenAll(normalFindReferencesTask, codeIndexReferencesTask).ConfigureAwait(false);
}
private async Task FindCodeIndexReferencesAsync(
ICodeIndexProvider? codeIndexProvider,
ISymbol symbol, Solution solution,
FindReferencesProgressAdapter progressAdapter,
FindReferencesSearchOptions options,
CancellationToken cancellationToken)
{
if (codeIndexProvider == null)
return;
var moniker = SymbolMoniker.TryCreate(symbol);
if (moniker == null)
return;
var monikers = SpecializedCollections.SingletonEnumerable(moniker);
var currentPage = 0;
while (true)
{
var results = await codeIndexProvider.FindReferencesByMonikerAsync(
monikers, includeDecleration: true, pageIndex: currentPage, cancellationToken: cancellationToken).ConfigureAwait(false);
if (results == null || results.Count == 0)
break;
currentPage++;
await ProcessCodeIndexResultsAsync(
codeIndexProvider, results, cancellationToken).ConfigureAwait(false);
}
}
private async Task<bool> TryFindLiteralReferencesAsync(
......@@ -170,8 +214,8 @@ protected AbstractFindUsagesService(IThreadingContext threadingContext)
var cancellationToken = context.CancellationToken;
cancellationToken.ThrowIfCancellationRequested();
var syntaxTree = await document.GetSyntaxTreeAsync(cancellationToken).ConfigureAwait(false);
var syntaxFacts = document.GetLanguageService<ISyntaxFactsService>();
var syntaxTree = await document.GetRequiredSyntaxTreeAsync(cancellationToken).ConfigureAwait(false);
var syntaxFacts = document.GetRequiredLanguageService<ISyntaxFactsService>();
// Currently we only support FAR for numbers, strings and characters. We don't
// bother with true/false/null as those are likely to have way too many results
......@@ -192,20 +236,19 @@ protected AbstractFindUsagesService(IThreadingContext threadingContext)
// for numeric values, and a decimal won't fit within that.
var tokenValue = token.Value;
if (tokenValue == null || tokenValue is decimal)
{
return false;
}
var semanticModel = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false);
if (token.Parent is null)
return false;
var semanticModel = await document.GetRequiredSemanticModelAsync(cancellationToken).ConfigureAwait(false);
var symbol = semanticModel.GetSymbolInfo(token.Parent).Symbol ?? semanticModel.GetDeclaredSymbol(token.Parent);
// Numeric labels are available in VB. In that case we want the normal FAR engine to
// do the searching. For these literals we want to find symbolic results and not
// numeric matches.
if (symbol is ILabelSymbol)
{
return false;
}
// Use the literal to make the title. Trim literal if it's too long.
var title = syntaxFacts.ConvertToSingleLine(token.Parent).ToString();
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册