public override async Task <LSP.SemanticTokens> HandleRequestAsync( LSP.SemanticTokensRangeParams request, RequestContext context, CancellationToken cancellationToken) { Contract.ThrowIfNull(request.TextDocument, "TextDocument is null."); Contract.ThrowIfNull(context.Document, "Document is null."); var options = _globalOptions.GetClassificationOptions(context.Document.Project.Language); // The results from the range handler should not be cached since we don't want to cache // partial token results. In addition, a range request is only ever called with a whole // document request, so caching range results is unnecessary since the whole document // handler will cache the results anyway. var(tokensData, isFinalized) = await SemanticTokensHelpers.ComputeSemanticTokensDataAsync( context.Document, SemanticTokensHelpers.TokenTypeToIndex, request.Range, options, includeSyntacticClassifications : context.Document.IsRazorDocument(), cancellationToken).ConfigureAwait(false); return(new RoslynSemanticTokens { Data = tokensData, IsFinalized = isFinalized }); }
public async Task <IntellisenseQuickInfoItem> GetQuickInfoItemAsync(IAsyncQuickInfoSession session, CancellationToken cancellationToken) { 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 = _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 = _globalOptions.GetClassificationOptions(document.Project.Language); return(await IntellisenseQuickInfoBuilder.BuildItemAsync( trackingSpan, item, document, classificationOptions, _threadingContext, _operationExecutor, _asyncListener, _streamingPresenter, cancellationToken).ConfigureAwait(false)); } return(null); } } catch (Exception e) when(FatalError.ReportAndPropagateUnlessCanceled(e, cancellationToken, ErrorSeverity.Critical)) { throw ExceptionUtilities.Unreachable; } }
protected sealed override Task ProduceTagsAsync( TaggerContext <IClassificationTag> context, CancellationToken cancellationToken) { Debug.Assert(context.SpansToTag.IsSingle()); var spanToTag = context.SpansToTag.Single(); var document = spanToTag.Document; if (document == null) { return(Task.CompletedTask); } // Attempt to get a classification service which will actually produce the results. // If we can't (because we have no Document, or because the language doesn't support // this service), then bail out immediately. var classificationService = document.GetLanguageService <IClassificationService>(); if (classificationService == null) { return(Task.CompletedTask); } // The LSP client will handle producing tags when running under the LSP editor. // Our tagger implementation should return nothing to prevent conflicts. var workspaceContextService = document.Project.Solution.Services.GetRequiredService <IWorkspaceContextService>(); if (workspaceContextService?.IsInLspEditorContext() == true) { return(Task.CompletedTask); } // If the LSP semantic tokens feature flag is enabled, return nothing to prevent conflicts. var isLspSemanticTokensEnabled = _globalOptions.GetOption(LspOptions.LspSemanticTokensFeatureFlag); if (isLspSemanticTokensEnabled) { return(Task.CompletedTask); } var classificationOptions = _globalOptions.GetClassificationOptions(document.Project.Language); return(ClassificationUtilities.ProduceTagsAsync( context, spanToTag, classificationService, _typeMap, classificationOptions, _type, cancellationToken)); }
public async Task <Hover?> HandleRequestAsync(TextDocumentPositionParams request, RequestContext context, CancellationToken cancellationToken) { var document = context.Document; Contract.ThrowIfNull(document); var position = await document.GetPositionFromLinePositionAsync(ProtocolConversions.PositionToLinePosition(request.Position), cancellationToken).ConfigureAwait(false); var quickInfoService = document.Project.LanguageServices.GetRequiredService <QuickInfoService>(); var options = _globalOptions.GetSymbolDescriptionOptions(document.Project.Language); var info = await quickInfoService.GetQuickInfoAsync(document, position, options, cancellationToken).ConfigureAwait(false); if (info == null) { return(null); } var classificationOptions = _globalOptions.GetClassificationOptions(document.Project.Language); var text = await document.GetTextAsync(cancellationToken).ConfigureAwait(false); return(await GetHoverAsync(info, text, document.Project.Language, document, classificationOptions, context.ClientCapabilities, cancellationToken).ConfigureAwait(false)); }
private async Task <ImmutableArray <ReferenceLocationDescriptor> > FixUpDescriptorsAsync( Solution solution, ImmutableArray <ReferenceLocationDescriptor> descriptors, CancellationToken cancellationToken) { using var _ = ArrayBuilder <ReferenceLocationDescriptor> .GetInstance(out var list); foreach (var descriptor in descriptors) { var referencedDocumentId = DocumentId.CreateFromSerialized( ProjectId.CreateFromSerialized(descriptor.ProjectGuid), descriptor.DocumentGuid); var document = await solution.GetDocumentAsync(referencedDocumentId, includeSourceGenerated : true, cancellationToken).ConfigureAwait(false); if (document == null) { continue; } var spanMapper = document.Services.GetService <ISpanMappingService>(); if (spanMapper == null) { // for normal document, just add one as they are list.Add(descriptor); continue; } var span = new TextSpan(descriptor.SpanStart, descriptor.SpanLength); var results = await spanMapper.MapSpansAsync(document, SpecializedCollections.SingletonEnumerable(span), cancellationToken).ConfigureAwait(false); // external component violated contracts. the mapper should preserve input order/count. // since we gave in 1 span, it should return 1 span back Contract.ThrowIfTrue(results.IsDefaultOrEmpty); var result = results[0]; if (result.IsDefault) { // it is allowed for mapper to return default // if it can't map the given span to any usable span continue; } var excerpter = document.Services.GetService <IDocumentExcerptService>(); if (excerpter == null) { continue; } var classificationOptions = _globalOptions.GetClassificationOptions(document.Project.Language); var referenceExcerpt = await excerpter.TryExcerptAsync(document, span, ExcerptMode.SingleLine, classificationOptions, cancellationToken).ConfigureAwait(false); var tooltipExcerpt = await excerpter.TryExcerptAsync(document, span, ExcerptMode.Tooltip, classificationOptions, cancellationToken).ConfigureAwait(false); var(text, start, length) = GetReferenceInfo(referenceExcerpt, descriptor); var(before1, before2, after1, after2) = GetReferenceTexts(referenceExcerpt, tooltipExcerpt, descriptor); list.Add(new ReferenceLocationDescriptor( descriptor.LongDescription, descriptor.Language, descriptor.Glyph, result.Span.Start, result.Span.Length, result.LinePositionSpan.Start.Line, result.LinePositionSpan.Start.Character, descriptor.ProjectGuid, descriptor.DocumentGuid, result.FilePath, text, start, length, before1, before2, after1, after2)); } return(list.ToImmutable()); }