| File: QuickInfo\CommonQuickInfoProvider.cs | Web Access |
| Project: src\roslyn\src\Features\Core\Portable\Microsoft.CodeAnalysis.Features.csproj (Microsoft.CodeAnalysis.Features) |
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. using System.Collections.Immutable; using System.Threading.Tasks; using Microsoft.CodeAnalysis.Collections; using Microsoft.CodeAnalysis.Shared.Extensions; namespace Microsoft.CodeAnalysis.QuickInfo; internal abstract class CommonQuickInfoProvider : QuickInfoProvider { protected abstract Task<QuickInfoItem?> BuildQuickInfoAsync(QuickInfoContext context, SyntaxToken token); public override async Task<QuickInfoItem?> GetQuickInfoAsync(QuickInfoContext context) { var cancellationToken = context.CancellationToken; var tree = await context.Document.GetRequiredSyntaxTreeAsync(cancellationToken).ConfigureAwait(false); var tokens = await GetTokensAsync(tree, context.Position, context.CancellationToken).ConfigureAwait(false); foreach (var token in tokens) { var info = await GetQuickInfoAsync(context, token).ConfigureAwait(false); if (info != null) return info; } return null; } protected async Task<ImmutableArray<SyntaxToken>> GetTokensAsync(SyntaxTree tree, int position, System.Threading.CancellationToken cancellationToken) { using var result = TemporaryArray<SyntaxToken>.Empty; var token = await tree.GetTouchingTokenAsync(position, cancellationToken, findInsideTrivia: true).ConfigureAwait(false); if (token != default) { result.Add(token); if (ShouldCheckPreviousToken(token)) { token = token.GetPreviousToken(); if (token != default && token.Span.IntersectsWith(position)) result.Add(token); } } return result.ToImmutableAndClear(); } protected virtual bool ShouldCheckPreviousToken(SyntaxToken token) => true; private async Task<QuickInfoItem?> GetQuickInfoAsync( QuickInfoContext context, SyntaxToken token) { if (token != default && token.Span.IntersectsWith(context.Position)) { return await BuildQuickInfoAsync(context, token).ConfigureAwait(false); } return null; } }