public async Task FindBasesAsync(Document document, int position, IFindUsagesContext context) { var cancellationToken = context.CancellationToken; var symbolAndProjectOpt = await FindUsagesHelpers.GetRelevantSymbolAndProjectAtPositionAsync( document, position, cancellationToken).ConfigureAwait(false); if (symbolAndProjectOpt == null) { await context.ReportMessageAsync( EditorFeaturesResources.Cannot_navigate_to_the_symbol_under_the_caret).ConfigureAwait(false); return; } var(symbol, project) = symbolAndProjectOpt.Value; var bases = FindBaseHelpers.FindBases( symbol, project, cancellationToken); await context.SetSearchTitleAsync( string.Format(EditorFeaturesResources._0_bases, FindUsagesHelpers.GetDisplayName(symbol))).ConfigureAwait(false); var found = false; // For each potential base, try to find its definition in sources. // If found, add it's definitionItem to the context. // If not found but the symbol is from metadata, create it's definition item from metadata and add to the context. foreach (var baseSymbol in bases) { var sourceDefinition = await SymbolFinder.FindSourceDefinitionAsync( SymbolAndProjectId.Create(baseSymbol, project.Id), project.Solution, cancellationToken).ConfigureAwait(false); if (sourceDefinition.Symbol != null) { var definitionItem = await sourceDefinition.Symbol.ToClassifiedDefinitionItemAsync( project.Solution.GetProject(sourceDefinition.ProjectId), includeHiddenLocations : false, FindReferencesSearchOptions.Default, cancellationToken : cancellationToken) .ConfigureAwait(false); await context.OnDefinitionFoundAsync(definitionItem).ConfigureAwait(false); found = true; } else if (baseSymbol.Locations.Any(l => l.IsInMetadata)) { var definitionItem = baseSymbol.ToNonClassifiedDefinitionItem( project, includeHiddenLocations: true); await context.OnDefinitionFoundAsync(definitionItem).ConfigureAwait(false); found = true; } } if (!found) { await context.ReportMessageAsync(EditorFeaturesResources.The_symbol_has_no_base) .ConfigureAwait(false); } }
private static async Task InspectInterfaceAsync( IFindUsagesContext context, INamedTypeSymbol interfaceSymbol, INamedTypeSymbol namedTypeSymbol, Project project ) { foreach (var interfaceMember in interfaceSymbol.GetMembers()) { if (context.CancellationToken.IsCancellationRequested) { return; } var impl = namedTypeSymbol.FindImplementationForInterfaceMember(interfaceMember); if (impl == null) { continue; } var definitionItem = impl.ToNonClassifiedDefinitionItem(project.Solution, true); #pragma warning disable CA2007 // Consider calling ConfigureAwait on the awaited task await context.OnDefinitionFoundAsync(definitionItem); #pragma warning restore CA2007 // Consider calling ConfigureAwait on the awaited task } }
public async Task FindImplementationsAsync(Document document, int position, IFindUsagesContext context) { var tuple = await FindUsagesHelpers.FindImplementationsAsync( document, position, context.CancellationToken).ConfigureAwait(false); if (tuple == null) { context.ReportMessage(EditorFeaturesResources.Cannot_navigate_to_the_symbol_under_the_caret); return; } var message = tuple.Value.message; if (message != null) { context.ReportMessage(message); return; } context.SetSearchTitle(string.Format(EditorFeaturesResources._0_implementations, FindUsagesHelpers.GetDisplayName(tuple.Value.symbol))); var project = tuple.Value.project; foreach (var implementation in tuple.Value.implementations) { var definitionItem = implementation.ToDefinitionItem( project.Solution, includeHiddenLocations: false); await context.OnDefinitionFoundAsync(definitionItem).ConfigureAwait(false); } }
async Task IFindUsagesService.FindReferencesAsync( Document document, int position, IFindUsagesContext context) { var definitionTrackingContext = new DefinitionTrackingContext(context); // Need ConfigureAwait(true) here so we get back to the UI thread before calling // GetThirdPartyDefinitions. We need to call that on the UI thread to match behavior // of how the language service always worked in the past. // // Any async calls before GetThirdPartyDefinitions must be ConfigureAwait(true). await FindLiteralOrSymbolReferencesAsync( document, position, definitionTrackingContext).ConfigureAwait(true); // After the FAR engine is done call into any third party extensions to see // if they want to add results. var thirdPartyDefinitions = GetThirdPartyDefinitions( document.Project.Solution, definitionTrackingContext.GetDefinitions(), context.CancellationToken); // From this point on we can do ConfigureAwait(false) as we're not calling back // into third parties anymore. foreach (var definition in thirdPartyDefinitions) { // Don't need ConfigureAwait(true) here await context.OnDefinitionFoundAsync(definition).ConfigureAwait(false); } }
public async Task FindImplementationsAsync(Document document, int position, IFindUsagesContext context) { var tuple = await FindUsagesHelpers.FindImplementationsAsync( document, position, context.CancellationToken).ConfigureAwait(false); if (tuple == null) { context.ReportMessage(EditorFeaturesResources.Cannot_navigate_to_the_symbol_under_the_caret); return; } var message = tuple.Value.message; if (message != null) { context.ReportMessage(message); return; } var project = tuple.Value.project; foreach (var implementation in tuple.Value.implementations) { var definitionItem = implementation.ToDefinitionItem( project.Solution, includeHiddenLocations: false); await context.OnDefinitionFoundAsync(definitionItem).ConfigureAwait(false); } }
private static async Task FindImplementationsInCurrentProcessAsync( ISymbol symbol, Project project, IFindUsagesContext context) { var cancellationToken = context.CancellationToken; var solution = project.Solution; var(implementations, message) = await FindSourceImplementationsAsync( solution, symbol, cancellationToken).ConfigureAwait(false); if (message != null) { await context.ReportMessageAsync(message).ConfigureAwait(false); return; } await context.SetSearchTitleAsync( string.Format(EditorFeaturesResources._0_implementations, FindUsagesHelpers.GetDisplayName(symbol))).ConfigureAwait(false); foreach (var implementation in implementations) { var definitionItem = await implementation.ToClassifiedDefinitionItemAsync( solution, isPrimary : true, includeHiddenLocations : false, FindReferencesSearchOptions.Default, cancellationToken).ConfigureAwait(false); await context.OnDefinitionFoundAsync(definitionItem).ConfigureAwait(false); } }
public Task OnDefinitionFoundAsync(DefinitionItem definition) { lock (_gate) { _definitions.Add(definition); } return(_underlyingContext.OnDefinitionFoundAsync(definition)); }
public Task OnDefinitionFoundAsync(SerializableDefinitionItem definition) { var id = definition.Id; var rehydrated = definition.Rehydrate(_solution); lock (_idToDefinition) { _idToDefinition.Add(id, rehydrated); } return(_context.OnDefinitionFoundAsync(rehydrated).AsTask()); }
public async Task FindReferencesAsync(Document document, int position, IFindUsagesContext context) { var text = await document.GetTextAsync().ConfigureAwait(false); var lspClient = _roslynLspClientServiceFactory.ActiveLanguageServerClient; if (lspClient == null) { return; } var referenceParams = new LSP.ReferenceParams { Context = new LSP.ReferenceContext { IncludeDeclaration = false }, TextDocument = ProtocolConversions.DocumentToTextDocumentIdentifier(document), Position = ProtocolConversions.LinePositionToPosition(text.Lines.GetLinePosition(position)) }; var locations = await lspClient.RequestAsync(LSP.Methods.TextDocumentReferences, referenceParams, context.CancellationToken).ConfigureAwait(false); if (locations == null) { return; } // TODO: Need to get real definition data from the server. var dummyDef = DefinitionItem.CreateNonNavigableItem(ImmutableArray <string> .Empty, ImmutableArray <TaggedText> .Empty); await context.OnDefinitionFoundAsync(dummyDef).ConfigureAwait(false); foreach (var location in locations) { var documentSpan = await _remoteLanguageServiceWorkspace.GetDocumentSpanFromLocation(location, context.CancellationToken).ConfigureAwait(false); if (documentSpan == null) { continue; } #pragma warning disable CS0612 // Type or member is obsolete. TODO. await context.OnReferenceFoundAsync(new SourceReferenceItem(dummyDef, documentSpan.Value, isWrittenTo : false)).ConfigureAwait(false); #pragma warning restore CS0612 // Type or member is obsolete } }
async Task IFindUsagesService.FindReferencesAsync( IFindUsagesContext context, Document document, int position, CancellationToken cancellationToken) { var definitionTrackingContext = new DefinitionTrackingContext(context); await FindLiteralOrSymbolReferencesAsync( definitionTrackingContext, document, position, cancellationToken).ConfigureAwait(false); // After the FAR engine is done call into any third party extensions to see // if they want to add results. var thirdPartyDefinitions = await GetThirdPartyDefinitionsAsync( document.Project.Solution, definitionTrackingContext.GetDefinitions(), cancellationToken).ConfigureAwait(false); foreach (var definition in thirdPartyDefinitions) { await context.OnDefinitionFoundAsync(definition, cancellationToken).ConfigureAwait(false); } }
private static async Task FindSymbolMonikerReferencesAsync( IFindSymbolMonikerUsagesService monikerUsagesService, ISymbol definition, IFindUsagesContext context, CancellationToken cancellationToken) { var moniker = SymbolMoniker.TryCreate(definition); if (moniker == null) { return; } // Let the find-refs window know we have outstanding work await using var _ = await context.ProgressTracker.AddSingleItemAsync().ConfigureAwait(false); var displayParts = GetDisplayParts(definition).AddRange(new[] { new TaggedText(TextTags.Space, " "), new TaggedText(TextTags.Text, EditorFeaturesResources.external), }); var definitionItem = DefinitionItem.CreateNonNavigableItem( tags: GlyphTags.GetTags(definition.GetGlyph()), displayParts, originationParts: DefinitionItem.GetOriginationParts(definition)); var monikers = ImmutableArray.Create(moniker); var first = true; await foreach (var referenceItem in monikerUsagesService.FindReferencesByMoniker( definitionItem, monikers, context.ProgressTracker, cancellationToken)) { if (first) { // found some results. Add the definition item to the context. first = false; await context.OnDefinitionFoundAsync(definitionItem).ConfigureAwait(false); } await context.OnExternalReferenceFoundAsync(referenceItem).ConfigureAwait(false); } }
private static async Task InspectInterfaceAsync( IFindUsagesContext context, INamedTypeSymbol interfaceSymbol, INamedTypeSymbol namedTypeSymbol, Project project, CancellationToken cancellationToken) { foreach (var interfaceMember in interfaceSymbol.GetMembers()) { if (cancellationToken.IsCancellationRequested) { return; } var impl = namedTypeSymbol.FindImplementationForInterfaceMember(interfaceMember); if (impl == null) { continue; } var definitionItem = impl.ToNonClassifiedDefinitionItem(project.Solution, true); await context.OnDefinitionFoundAsync(definitionItem, cancellationToken).ConfigureAwait(false); } }
public async Task FindImplementationsAsync(Document document, int position, IFindUsagesContext context) { var text = await document.GetTextAsync().ConfigureAwait(false); var lspClient = _roslynLspClientServiceFactory.ActiveLanguageServerClient; if (lspClient == null) { return; } var documentPositionParams = ProtocolConversions.PositionToTextDocumentPositionParams(position, text, document); var response = await lspClient.RequestAsync(LiveShareProtocol.Methods.TextDocumentImplementations, documentPositionParams, context.CancellationToken).ConfigureAwait(false); var locations = ((JToken)response)?.ToObject <LSP.Location[]>(); if (locations == null) { return; } foreach (var location in locations) { var documentSpan = await _remoteLanguageServiceWorkspace.GetDocumentSpanFromLocation(location, context.CancellationToken).ConfigureAwait(false); if (documentSpan == null) { continue; } // Get the text for the line containing the definition to show in the UI. var docText = await documentSpan.Value.Document.GetTextAsync(context.CancellationToken).ConfigureAwait(false); var lineText = docText.GetSubText(docText.Lines[location.Range.Start.Line].Span).ToString(); await context.OnDefinitionFoundAsync(DefinitionItem.Create(ImmutableArray <string> .Empty, ImmutableArray.Create(new TaggedText(TextTags.Text, lineText)), documentSpan.Value)).ConfigureAwait(false); } }
public async Task FindImplementationsAsync( Document document, int position, IFindUsagesContext context) { var cancellationToken = context.CancellationToken; var tuple = await FindUsagesHelpers.FindImplementationsAsync( document, position, cancellationToken).ConfigureAwait(false); if (tuple == null) { await context.ReportMessageAsync( EditorFeaturesResources.Cannot_navigate_to_the_symbol_under_the_caret).ConfigureAwait(false); return; } var message = tuple.Value.message; if (message != null) { await context.ReportMessageAsync(message).ConfigureAwait(false); return; } await context.SetSearchTitleAsync( string.Format(EditorFeaturesResources._0_implementations, FindUsagesHelpers.GetDisplayName(tuple.Value.symbol))).ConfigureAwait(false); var project = tuple.Value.project; foreach (var implementation in tuple.Value.implementations) { var definitionItem = await implementation.ToClassifiedDefinitionItemAsync( project, includeHiddenLocations : false, FindReferencesSearchOptions.Default, cancellationToken : cancellationToken).ConfigureAwait(false); await context.OnDefinitionFoundAsync(definitionItem).ConfigureAwait(false); } }
private async Task <bool> TryFindLiteralReferencesAsync( Document document, int position, IFindUsagesContext context) { var cancellationToken = context.CancellationToken; cancellationToken.ThrowIfCancellationRequested(); 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 // to be useful. var token = await syntaxTree.GetTouchingTokenAsync( position, t => syntaxFacts.IsNumericLiteral(t) || syntaxFacts.IsCharacterLiteral(t) || syntaxFacts.IsStringLiteral(t), cancellationToken).ConfigureAwait(false); if (token.RawKind == 0) { return(false); } // Searching for decimals not supported currently. Our index can only store 64bits // for numeric values, and a decimal won't fit within that. var tokenValue = token.Value; if (tokenValue == null || tokenValue is decimal) { return(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(); if (title.Length >= 10) { title = title.Substring(0, 10) + "..."; } var searchTitle = string.Format(EditorFeaturesResources._0_references, title); await context.SetSearchTitleAsync(searchTitle).ConfigureAwait(false); var solution = document.Project.Solution; // There will only be one 'definition' that all matching literal reference. // So just create it now and report to the context what it is. var definition = DefinitionItem.CreateNonNavigableItem( ImmutableArray.Create(TextTags.StringLiteral), ImmutableArray.Create(new TaggedText(TextTags.Text, searchTitle))); await context.OnDefinitionFoundAsync(definition).ConfigureAwait(false); var progressAdapter = new FindLiteralsProgressAdapter(context, definition); // Now call into the underlying FAR engine to find reference. The FAR // engine will push results into the 'progress' instance passed into it. // We'll take those results, massage them, and forward them along to the // FindUsagesContext instance we were given. await SymbolFinder.FindLiteralReferencesAsync( tokenValue, Type.GetTypeCode(tokenValue.GetType()), solution, progressAdapter, cancellationToken).ConfigureAwait(false); return(true); }
public Task OnDefinitionFoundAsync(SymbolAndProjectId definition) { return(_context.OnDefinitionFoundAsync(GetDefinitionItem(definition))); }
public async ValueTask OnDefinitionFoundAsync(ISymbol definition) { var definitionItem = await GetDefinitionItemAsync(definition).ConfigureAwait(false); await _context.OnDefinitionFoundAsync(definitionItem).ConfigureAwait(false); }
public async Task OnDefinitionFoundAsync(SymbolAndProjectId definition) { var definitionItem = await GetDefinitionItemAsync(definition).ConfigureAwait(false); await _context.OnDefinitionFoundAsync(definitionItem).ConfigureAwait(false); }
public ValueTask OnDefinitionFoundAsync(VSTypeScriptDefinitionItem definition, CancellationToken cancellationToken) => _context.OnDefinitionFoundAsync(definition.UnderlyingObject, cancellationToken);
public Task OnDefinitionFoundAsync(FSharp.FindUsages.FSharpDefinitionItem definition) { return(_context.OnDefinitionFoundAsync(definition.RoslynDefinitionItem)); }
public Task OnDefinitionFoundAsync(FSharp.FindUsages.FSharpDefinitionItem definition) { return(_context.OnDefinitionFoundAsync(definition.RoslynDefinitionItem, _cancellationToken).AsTask()); }