Skip to content

Commit

Permalink
Merge pull request #24910 from isc30/23030-DisableLiteralCtrlClickNav…
Browse files Browse the repository at this point in the history
…igation

[#23030] Disable literal Ctrl+Click navigation
  • Loading branch information
sharwell authored May 2, 2018
2 parents ba9ee62 + 8529918 commit 3adcd5e
Show file tree
Hide file tree
Showing 11 changed files with 292 additions and 76 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@

namespace Microsoft.CodeAnalysis.Editor.GoToDefinition
{
// GoToDefinition
internal abstract class AbstractGoToDefinitionService : IGoToDefinitionService
{
private readonly IEnumerable<Lazy<IStreamingFindUsagesPresenter>> _streamingPresenters;
Expand All @@ -27,7 +28,7 @@ public async Task<IEnumerable<INavigableItem>> FindDefinitionsAsync(
Document document, int position, CancellationToken cancellationToken)
{
var symbolService = document.GetLanguageService<IGoToDefinitionSymbolService>();
var (symbol, span) = await symbolService.GetSymbolAndBoundSpanAsync(document, position, cancellationToken).ConfigureAwait(false);
var (symbol, span) = await symbolService.GetSymbolAndBoundSpanAsync(document, position, includeType: true, cancellationToken).ConfigureAwait(false);

// Try to compute source definitions from symbol.
var items = symbol != null
Expand All @@ -43,7 +44,7 @@ public bool TryGoToDefinition(Document document, int position, CancellationToken
{
// Try to compute the referenced symbol and attempt to go to definition for the symbol.
var symbolService = document.GetLanguageService<IGoToDefinitionSymbolService>();
var (symbol, _) = symbolService.GetSymbolAndBoundSpanAsync(document, position, cancellationToken).WaitAndGetResult(cancellationToken);
var (symbol, _) = symbolService.GetSymbolAndBoundSpanAsync(document, position, includeType: true, cancellationToken).WaitAndGetResult(cancellationToken);
if (symbol is null)
{
return false;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
using System.Threading;
using System.Threading.Tasks;
using Microsoft.CodeAnalysis.FindSymbols;
using Microsoft.CodeAnalysis.Shared.Extensions;
using Microsoft.CodeAnalysis.Text;

namespace Microsoft.CodeAnalysis.Editor.GoToDefinition
Expand All @@ -12,23 +13,33 @@ internal abstract class AbstractGoToDefinitionSymbolService : IGoToDefinitionSym
{
protected abstract ISymbol FindRelatedExplicitlyDeclaredSymbol(ISymbol symbol, Compilation compilation);

public async Task<(ISymbol, TextSpan)> GetSymbolAndBoundSpanAsync(Document document, int position, CancellationToken cancellationToken)
public async Task<(ISymbol, TextSpan)> GetSymbolAndBoundSpanAsync(Document document, int position, bool includeType, CancellationToken cancellationToken)
{
var workspace = document.Project.Solution.Workspace;

var semanticModel = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false);
var semanticInfo = await SymbolFinder.GetSemanticInfoAtPositionAsync(semanticModel, position, workspace, cancellationToken).ConfigureAwait(false);
var symbol = GetSymbol(semanticInfo, includeType);

// prefer references to declarations. It's more likely that the user is attempting to
// go to a definition at some other location, rather than the definition they're on.
if (symbol is null)
{
return (null, semanticInfo.Span);
}

return (FindRelatedExplicitlyDeclaredSymbol(symbol, semanticModel.Compilation), semanticInfo.Span);
}

private ISymbol GetSymbol(TokenSemanticInfo semanticInfo, bool includeType)
{
// Prefer references to declarations. It's more likely that the user is attempting to
// go to a definition at some other location, rather than the definition they're on.
// This can happen when a token is at a location that is both a reference and a definition.
// For example, on an anonymous type member declaration.
var symbol = semanticInfo.AliasSymbol ??
semanticInfo.ReferencedSymbols.FirstOrDefault() ??
semanticInfo.DeclaredSymbol ??
semanticInfo.Type;

return (FindRelatedExplicitlyDeclaredSymbol(symbol, semanticModel.Compilation), semanticInfo.Span);
return semanticInfo.AliasSymbol
?? semanticInfo.ReferencedSymbols.FirstOrDefault()
?? semanticInfo.DeclaredSymbol
?? (includeType ? semanticInfo.Type : null);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,20 @@

namespace Microsoft.CodeAnalysis.Editor.GoToDefinition
{
// Ctrl+Click (GoToSymbol)
internal abstract class AbstractGoToSymbolService : ForegroundThreadAffinitizedObject, IGoToSymbolService
{
public async Task GetSymbolsAsync(GoToSymbolContext context)
{
var document = context.Document;
var position = context.Position;
var cancellationToken = context.CancellationToken;

var service = document.GetLanguageService<IGoToDefinitionSymbolService>();
var (symbol, span) = await service.GetSymbolAndBoundSpanAsync(document, position, cancellationToken).ConfigureAwait(false);

// [includeType: false]
// Enable Ctrl+Click on tokens with aliased, referenced or declared symbol.
// If the token has none of those but does have a type (mostly literals), we're not interested
var (symbol, span) = await service.GetSymbolAndBoundSpanAsync(document, position, includeType: false, cancellationToken).ConfigureAwait(false);

if (symbol == null)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,6 @@ namespace Microsoft.CodeAnalysis.Editor.GoToDefinition
{
internal interface IGoToDefinitionSymbolService : ILanguageService
{
Task<(ISymbol, TextSpan)> GetSymbolAndBoundSpanAsync(Document document, int position, CancellationToken cancellationToken);
Task<(ISymbol, TextSpan)> GetSymbolAndBoundSpanAsync(Document document, int position, bool includeType, CancellationToken cancellationToken);
}
}
Loading

0 comments on commit 3adcd5e

Please sign in to comment.