// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System; using System.Collections.Generic; using System.Linq; using System.Threading; using System.Threading.Tasks; using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.Classification; using Microsoft.CodeAnalysis.LanguageServer; using Microsoft.VisualStudio.LanguageServices.LiveShare.CustomProtocol; using Microsoft.VisualStudio.LiveShare.LanguageServices; namespace Microsoft.VisualStudio.LanguageServices.LiveShare { /// /// Handler for a request to classify the document. This is used for semantic colorization and only works for C#\VB. /// TODO - Move once defined as a custom protocol. /// Note, this must return object instead of ClassificationSpan b/c liveshare uses dynamic to convert handler results. /// Unfortunately, ClassificationSpan is an internal type and cannot be defined in the external access layer. /// internal class ClassificationsHandler : ILspRequestHandler { public async Task HandleAsync(ClassificationParams request, RequestContext requestContext, CancellationToken cancellationToken) { var actualDocumentURI = requestContext.ProtocolConverter.FromProtocolUri(request.TextDocument.Uri); var document = requestContext.Context.GetDocumentFromURI(actualDocumentURI); var classificationService = document?.Project.LanguageServices.GetService(); if (document == null || classificationService == null) { return Array.Empty(); } var text = await document.GetTextAsync(cancellationToken).ConfigureAwait(false); var textSpan = ProtocolConversions.RangeToTextSpan(request.Range, text); var spans = new List(); await classificationService.AddSemanticClassificationsAsync(document, textSpan, spans, cancellationToken).ConfigureAwait(false); return spans.Select(c => new ClassificationSpan { Classification = c.ClassificationType, Range = ProtocolConversions.TextSpanToRange(c.TextSpan, text) }).ToArray(); } } }