Skip to content

Commit

Permalink
Use char.IsAsciiLetter in the Regex runtime (dotnet#77559)
Browse files Browse the repository at this point in the history
* Use char.IsAsciiLetter in the Regex runtime

Need to move the duplicated IsAsciiLetter method to just the source generator, since the source generator can't reference the char API. That way the runtime doesn't need to pay for a duplicated method.

* PR feedback.

Move helepr method to Stubs.cs.
  • Loading branch information
eerhardt authored Oct 28, 2022
1 parent a6f4527 commit 7479cbe
Show file tree
Hide file tree
Showing 4 changed files with 11 additions and 8 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -4518,8 +4518,8 @@ private static string MatchCharacterClass(RegexOptions options, string chExpr, s
// Next, handle simple sets of two ASCII letter ranges that are cased versions of each other, e.g. [A-Za-z].
// This can be implemented as if it were a single range, with an additional bitwise operation.
if (RegexCharClass.TryGetDoubleRange(charClass, out (char LowInclusive, char HighInclusive) rangeLower, out (char LowInclusive, char HighInclusive) rangeUpper) &&
RegexCharClass.IsAsciiLetter(rangeUpper.LowInclusive) &&
RegexCharClass.IsAsciiLetter(rangeUpper.HighInclusive) &&
CharExtensions.IsAsciiLetter(rangeUpper.LowInclusive) &&
CharExtensions.IsAsciiLetter(rangeUpper.HighInclusive) &&
(rangeLower.LowInclusive | 0x20) == rangeUpper.LowInclusive &&
(rangeLower.HighInclusive | 0x20) == rangeUpper.HighInclusive)
{
Expand Down
7 changes: 7 additions & 0 deletions src/libraries/System.Text.RegularExpressions/gen/Stubs.cs
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,13 @@ public static int CommonPrefixLength(this ReadOnlySpan<char> span, ReadOnlySpan<
return length;
}
}

internal static class CharExtensions
{
/// <summary>Gets whether the specified character is an ASCII letter.</summary>
public static bool IsAsciiLetter(char c) =>
(uint)((c | 0x20) - 'a') <= 'z' - 'a';
}
}

namespace System.Buffers
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -990,10 +990,6 @@ public static bool IsAscii(ReadOnlySpan<char> s) // TODO https://github.com/dotn
return true;
}

/// <summary>Gets whether the specified character is an ASCII letter.</summary>
public static bool IsAsciiLetter(char c) =>
(uint)((c | 0x20) - 'a') <= 'z' - 'a';

/// <summary>Gets whether we can iterate through the set list pairs in order to completely enumerate the set's contents.</summary>
/// <remarks>This may enumerate negated characters if the set is negated. This will return false if the set has subtraction.</remarks>
private static bool CanEasilyEnumerateSetContents(string set) =>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5443,8 +5443,8 @@ private void EmitMatchCharacterClass(string charClass)
// Next, handle simple sets of two ASCII letter ranges that are cased versions of each other, e.g. [B-Db-d].
// This can be implemented as if it were a single range, with an additional bitwise operation.
if (RegexCharClass.TryGetDoubleRange(charClass, out (char LowInclusive, char HighInclusive) rangeLower, out (char LowInclusive, char HighInclusive) rangeUpper) &&
RegexCharClass.IsAsciiLetter(rangeUpper.LowInclusive) &&
RegexCharClass.IsAsciiLetter(rangeUpper.HighInclusive) &&
char.IsAsciiLetter(rangeUpper.LowInclusive) &&
char.IsAsciiLetter(rangeUpper.HighInclusive) &&
(rangeLower.LowInclusive | 0x20) == rangeUpper.LowInclusive &&
(rangeLower.HighInclusive | 0x20) == rangeUpper.HighInclusive)
{
Expand Down

0 comments on commit 7479cbe

Please sign in to comment.