|
// 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.
#nullable disable
using System;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.CodeAnalysis.Classification;
using Microsoft.CodeAnalysis.Editor.Host;
using Microsoft.CodeAnalysis.Editor.Shared.Utilities;
using Microsoft.CodeAnalysis.ErrorReporting;
using Microsoft.CodeAnalysis.Formatting;
using Microsoft.CodeAnalysis.Internal.Log;
using Microsoft.CodeAnalysis.LanguageService;
using Microsoft.CodeAnalysis.QuickInfo;
using Microsoft.CodeAnalysis.Shared.TestHooks;
using Microsoft.CodeAnalysis.Options;
using Microsoft.CodeAnalysis.Text;
using Microsoft.CodeAnalysis.Text.Shared.Extensions;
using Microsoft.VisualStudio.Language.Intellisense;
using Microsoft.VisualStudio.Text;
using Microsoft.VisualStudio.Utilities;
using Roslyn.Utilities;
using IntellisenseQuickInfoItem = Microsoft.VisualStudio.Language.Intellisense.QuickInfoItem;
using Microsoft.CodeAnalysis.Editor.InlineRename;
namespace Microsoft.CodeAnalysis.Editor.Implementation.IntelliSense.QuickInfo;
internal partial class QuickInfoSourceProvider
{
private sealed class QuickInfoSource(
ITextBuffer subjectBuffer,
IThreadingContext threadingContext,
IUIThreadOperationExecutor operationExecutor,
IAsynchronousOperationListener asyncListener,
Lazy<IStreamingFindUsagesPresenter> streamingPresenter,
EditorOptionsService editorOptionsService,
IInlineRenameService inlineRenameService) : IAsyncQuickInfoSource
{
private readonly ITextBuffer _subjectBuffer = subjectBuffer;
private readonly IThreadingContext _threadingContext = threadingContext;
private readonly IUIThreadOperationExecutor _operationExecutor = operationExecutor;
private readonly IAsynchronousOperationListener _asyncListener = asyncListener;
private readonly Lazy<IStreamingFindUsagesPresenter> _streamingPresenter = streamingPresenter;
private readonly EditorOptionsService _editorOptionsService = editorOptionsService;
private readonly IInlineRenameService _inlineRenameService = inlineRenameService;
public async Task<IntellisenseQuickInfoItem> GetQuickInfoItemAsync(IAsyncQuickInfoSession session, CancellationToken cancellationToken)
{
// Until https://devdiv.visualstudio.com/DevDiv/_workitems/edit/1611398 is resolved we can't disable
// quickinfo in InlineRename. Instead, we return no quickinfo information while the adornment
// is being shown. This can be removed after IFeaturesService supports disabling quickinfo
if (_editorOptionsService.GlobalOptions.GetOption(InlineRenameUIOptionsStorage.UseInlineAdornment) && _inlineRenameService.ActiveSession is not null)
return null;
var triggerPoint = session.GetTriggerPoint(_subjectBuffer.CurrentSnapshot);
if (!triggerPoint.HasValue)
return null;
var snapshot = triggerPoint.Value.Snapshot;
var document = snapshot.GetOpenDocumentInCurrentContextWithChanges();
if (document == null)
return null;
var service = QuickInfoService.GetService(document);
if (service == null)
return null;
try
{
using (Logger.LogBlock(FunctionId.Get_QuickInfo_Async, cancellationToken))
{
cancellationToken.ThrowIfCancellationRequested();
var options = _editorOptionsService.GlobalOptions.GetSymbolDescriptionOptions(document.Project.Language);
var item = await service.GetQuickInfoAsync(document, triggerPoint.Value, options, cancellationToken).ConfigureAwait(false);
if (item != null)
{
var textVersion = snapshot.Version;
var trackingSpan = textVersion.CreateTrackingSpan(item.Span.ToSpan(), SpanTrackingMode.EdgeInclusive);
var classificationOptions = _editorOptionsService.GlobalOptions.GetClassificationOptions(document.Project.Language);
var lineFormattingOptions = snapshot.TextBuffer.GetLineFormattingOptions(_editorOptionsService, explicitFormat: false);
var navigationActionFactory = new NavigationActionFactory(document, _threadingContext, _operationExecutor, _asyncListener, _streamingPresenter);
return await IntellisenseQuickInfoBuilder
.BuildItemAsync(trackingSpan, item, document, classificationOptions, lineFormattingOptions, navigationActionFactory, cancellationToken)
.ConfigureAwait(false);
}
return null;
}
}
catch (Exception e) when (FatalError.ReportAndPropagateUnlessCanceled(e, cancellationToken, ErrorSeverity.Critical))
{
throw ExceptionUtilities.Unreachable();
}
}
public void Dispose()
{
}
}
}
|