提交 eee853f3 编写于 作者: C CyrusNajmabadi

Initial implementation of streaming find refs in the FindRefsService.

上级 1867b5e1
......@@ -20,4 +20,17 @@ internal class CSharpFindReferencesService : AbstractFindReferencesService
{
}
}
}
[ExportLanguageService(typeof(IStreamingFindReferencesService), LanguageNames.CSharp), Shared]
internal class CSharpStreamingFindReferencesService : AbstractFindReferencesService
{
[ImportingConstructor]
public CSharpStreamingFindReferencesService(
[ImportMany] IEnumerable<IReferencedSymbolsPresenter> referencedSymbolsPresenters,
[ImportMany] IEnumerable<INavigableItemsPresenter> navigableItemsPresenters,
[ImportMany] IEnumerable<IFindReferencesResultProvider> externalReferencesProviders)
: base(referencedSymbolsPresenters, navigableItemsPresenters, externalReferencesProviders)
{
}
}
}
\ No newline at end of file
......@@ -267,6 +267,7 @@
<Compile Include="Implementation\Diagnostics\DiagnosticsSuggestionTaggerProvider.cs" />
<Compile Include="Implementation\Diagnostics\SuggestionAdornmentManagerProvider.cs" />
<Compile Include="Implementation\Diagnostics\SuggestionTag.cs" />
<Compile Include="Implementation\FindReferences\AbstractFindReferencesService.ProgressAdapter.cs" />
<Compile Include="Implementation\FindReferences\FindReferencesContext.cs" />
<Compile Include="Implementation\FindReferences\IFindReferencesNavigableItemResultProvider.cs" />
<Compile Include="Implementation\GoToDefinition\INavigableDefinitionProvider.cs" />
......@@ -808,4 +809,4 @@
<ImportGroup Label="Targets">
<Import Project="..\..\..\build\Targets\VSL.Imports.targets" />
</ImportGroup>
</Project>
</Project>
\ No newline at end of file
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.CodeAnalysis.Editor.Navigation;
using Microsoft.CodeAnalysis.FindSymbols;
using Microsoft.CodeAnalysis.Shared.Utilities;
namespace Microsoft.CodeAnalysis.Editor.Implementation.FindReferences
{
internal abstract partial class AbstractFindReferencesService
{
/// <summary>
/// Forwards IFindReferencesProgress calls to a FindRefrencesContext instance.
/// </summary>
private class ProgressAdapter : IFindReferencesProgress
{
private readonly Solution _solution;
private readonly FindReferencesContext _context;
private readonly ConcurrentDictionary<ISymbol, INavigableItem> _symbolToNavigableItem =
new ConcurrentDictionary<ISymbol, INavigableItem>(SymbolEquivalenceComparer.Instance);
private readonly Func<ISymbol, INavigableItem> _navigableItemFactory;
public ProgressAdapter(Solution solution, FindReferencesContext context)
{
_solution = solution;
_context = context;
_navigableItemFactory = s => NavigableItemFactory.GetItemFromSymbolLocation(
solution, s, s.Locations.First());
}
public void OnStarted() => _context.OnStarted();
public void OnCompleted() => _context.OnCompleted();
public void ReportProgress(int current, int maximum) => _context.ReportProgress(current, maximum);
public void OnFindInDocumentStarted(Document document) => _context.OnFindInDocumentStarted(document);
public void OnFindInDocumentCompleted(Document document) => _context.OnFindInDocumentCompleted(document);
private INavigableItem GetNavigableItem(ISymbol symbol)
{
return _symbolToNavigableItem.GetOrAdd(symbol, _navigableItemFactory);
}
public void OnDefinitionFound(ISymbol symbol)
{
_context.OnDefinitionFound(GetNavigableItem(symbol));
}
public void OnReferenceFound(ISymbol symbol, ReferenceLocation location)
{
_context.OnReferenceFound(
GetNavigableItem(symbol),
NavigableItemFactory.GetItemFromSymbolLocation(_solution, symbol, location.Location));
}
}
}
}
\ No newline at end of file
......@@ -14,8 +14,8 @@
namespace Microsoft.CodeAnalysis.Editor.Implementation.FindReferences
{
internal abstract class AbstractFindReferencesService :
IFindReferencesService
internal abstract partial class AbstractFindReferencesService :
IFindReferencesService, IStreamingFindReferencesService
{
private readonly IEnumerable<IReferencedSymbolsPresenter> _referenceSymbolPresenters;
private readonly IEnumerable<INavigableItemsPresenter> _navigableItemPresenters;
......@@ -34,6 +34,8 @@ internal abstract class AbstractFindReferencesService :
private async Task<Tuple<ISymbol, Solution>> GetRelevantSymbolAndSolutionAtPositionAsync(
Document document, int position, CancellationToken cancellationToken)
{
cancellationToken.ThrowIfCancellationRequested();
var symbol = await SymbolFinder.FindSymbolAtPositionAsync(document, position, cancellationToken: cancellationToken).ConfigureAwait(false);
if (symbol != null)
{
......@@ -118,7 +120,7 @@ public bool TryFindReferences(Document document, int position, IWaitContext wait
// First see if we have any external navigable item references.
// If so, we display the results as navigable items.
var succeeded = TryFindAndDisplayNavigableItemsReferencesAsync(document, position, waitContext).WaitAndGetResult(cancellationToken);
var succeeded = TryFindAndDisplayNavigableItemsReferencesAsync(document, position, waitContext).WaitAndGetResult(cancellationToken);
if (succeeded)
{
return true;
......@@ -184,5 +186,25 @@ private bool TryDisplayReferences(Tuple<IEnumerable<ReferencedSymbol>, Solution>
return false;
}
public async Task FindReferencesAsync(
Document document, int position, FindReferencesContext context)
{
var cancellationToken = context.CancellationToken;
cancellationToken.ThrowIfCancellationRequested();
var symbolAndSolution = await GetRelevantSymbolAndSolutionAtPositionAsync(
document, position, cancellationToken).ConfigureAwait(false);
var symbol = symbolAndSolution.Item1;
var solution = symbolAndSolution.Item2;
var result = await SymbolFinder.FindReferencesAsync(
symbol,
solution,
progress: new ProgressAdapter(solution, context),
documents: null,
cancellationToken: cancellationToken).ConfigureAwait(false);
}
}
}
}
\ No newline at end of file
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.CodeAnalysis.Editor.Commands;
using Microsoft.CodeAnalysis.Editor.Host;
using Microsoft.CodeAnalysis.Editor.Implementation.FindReferences;
using Microsoft.CodeAnalysis.Editor.Navigation;
using Microsoft.CodeAnalysis.Editor.UnitTests.Utilities;
using Microsoft.CodeAnalysis.Editor.UnitTests.Workspaces;
using Microsoft.CodeAnalysis.FindSymbols;
using Microsoft.VisualStudio.Language.Intellisense;
using Microsoft.CodeAnalysis.Shared.TestHooks;
using Microsoft.VisualStudio.Text;
using Moq;
using Roslyn.Test.Utilities;
using Roslyn.Utilities;
using Xunit;
......@@ -29,7 +29,9 @@ public async Task TestFindReferencesSynchronousCall()
var handler = new FindReferencesCommandHandler(
TestWaitIndicator.Default,
SpecializedCollections.SingletonEnumerable(findReferencesPresenter));
SpecializedCollections.SingletonEnumerable(findReferencesPresenter),
SpecializedCollections.EmptyEnumerable<IAsyncFindReferencesPresenter>(),
workspace.ExportProvider.GetExports<IAsynchronousOperationListener, FeatureMetadata>());
var textView = workspace.Documents[0].GetTextView();
textView.Caret.MoveTo(new SnapshotPoint(textView.TextSnapshot, 7));
......
......@@ -17,4 +17,16 @@ Namespace Microsoft.CodeAnalysis.Editor.VisualBasic.FindReferences
MyBase.New(referencedSymbolsPresenters, navigableItemsPresenters, externalReferencesProviders)
End Sub
End Class
End Namespace
<ExportLanguageService(GetType(IStreamingFindReferencesService), LanguageNames.VisualBasic), [Shared]>
Friend Class VisualBasicStreamingFindReferencesService
Inherits AbstractFindReferencesService
<ImportingConstructor>
Protected Sub New(<ImportMany> referencedSymbolsPresenters As IEnumerable(Of IReferencedSymbolsPresenter),
<ImportMany> navigableItemsPresenters As IEnumerable(Of INavigableItemsPresenter),
<ImportMany> externalReferencesProviders As IEnumerable(Of IFindReferencesResultProvider))
MyBase.New(referencedSymbolsPresenters, navigableItemsPresenters, externalReferencesProviders)
End Sub
End Class
End Namespace
\ No newline at end of file
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册