|
// 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.Collections.Immutable;
using System.Text;
using System.Text.RegularExpressions;
using Microsoft.CodeAnalysis.EmbeddedLanguages.Common;
using Microsoft.CodeAnalysis.EmbeddedLanguages.VirtualChars;
namespace Microsoft.CodeAnalysis.EmbeddedLanguages.RegularExpressions;
using RegexToken = EmbeddedSyntaxToken<RegexKind>;
using RegexTrivia = EmbeddedSyntaxTrivia<RegexKind>;
internal static class RegexHelpers
{
public static bool HasOption(RegexOptions options, RegexOptions val)
=> (options & val) != 0;
public static RegexToken CreateToken(RegexKind kind, ImmutableArray<RegexTrivia> leadingTrivia, VirtualCharSequence virtualChars)
=> new(kind, leadingTrivia, virtualChars, [], [], value: null);
public static RegexToken CreateMissingToken(RegexKind kind)
=> CreateToken(kind, [], VirtualCharSequence.Empty);
public static RegexTrivia CreateTrivia(RegexKind kind, VirtualCharSequence virtualChars)
=> CreateTrivia(kind, virtualChars, []);
public static RegexTrivia CreateTrivia(RegexKind kind, VirtualCharSequence virtualChars, ImmutableArray<EmbeddedDiagnostic> diagnostics)
=> new(kind, virtualChars, diagnostics);
/// <summary>
/// Maps an escaped character to the actual character it was escaping. For something like
/// 'a' this will map to actual '\a' char (the bell character). However, for something like
/// '(' this will just map to '(' as that's all that \( does in a regex.
/// </summary>
public static VirtualChar MapEscapeChar(VirtualChar ch)
=> ch.Value switch
{
'a' => VirtualChar.Create(new Rune('\u0007'), ch.Span), // bell
'b' => VirtualChar.Create(new Rune('\b'), ch.Span), // backspace
'e' => VirtualChar.Create(new Rune('\u001B'), ch.Span), // escape
'f' => VirtualChar.Create(new Rune('\f'), ch.Span), // form feed
'n' => VirtualChar.Create(new Rune('\n'), ch.Span), // new line
'r' => VirtualChar.Create(new Rune('\r'), ch.Span), // carriage return
't' => VirtualChar.Create(new Rune('\t'), ch.Span), // tab
'v' => VirtualChar.Create(new Rune('\u000B'), ch.Span), // vertical tab
_ => ch,
};
public static bool IsSelfEscape(this RegexSimpleEscapeNode node)
{
if (node.TypeToken.VirtualChars.Length > 0)
{
var ch = node.TypeToken.VirtualChars[0];
return MapEscapeChar(ch) == ch;
}
return true;
}
}
|