|
// 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 Microsoft.CodeAnalysis.EmbeddedLanguages;
using Microsoft.CodeAnalysis.Shared.Collections;
namespace Microsoft.CodeAnalysis.Classification;
internal abstract class AbstractFallbackEmbeddedLanguageClassifier : IEmbeddedLanguageClassifier
{
private readonly EmbeddedLanguageInfo _info;
private readonly ImmutableArray<int> _supportedKinds;
protected AbstractFallbackEmbeddedLanguageClassifier(EmbeddedLanguageInfo info)
{
_info = info;
using var array = TemporaryArray<int>.Empty;
array.Add(info.SyntaxKinds.CharacterLiteralToken);
array.Add(info.SyntaxKinds.StringLiteralToken);
array.Add(info.SyntaxKinds.InterpolatedStringTextToken);
array.AsRef().AddIfNotNull(info.SyntaxKinds.Utf8StringLiteralToken);
_supportedKinds = array.ToImmutableAndClear();
}
public void RegisterClassifications(EmbeddedLanguageClassificationContext context)
{
var token = context.SyntaxToken;
if (!_supportedKinds.Contains(token.RawKind))
return;
var virtualChars = _info.VirtualCharService.TryConvertToVirtualChars(token);
if (virtualChars.IsDefaultOrEmpty)
return;
// Can avoid any work if we got the same number of virtual characters back as characters in the string. In
// that case, there are clearly no escaped characters.
if (virtualChars.Length == token.Text.Length)
return;
foreach (var vc in virtualChars)
{
// utf-16 virtual char might have either one or two in text span
if (vc.Span.Length > vc.Rune.Utf16SequenceLength)
context.AddClassification(ClassificationTypeNames.StringEscapeCharacter, vc.Span);
}
}
}
|