From 472587b0d4cb98bc261051e813758df0346ae7f7 Mon Sep 17 00:00:00 2001 From: Simon Cropp Date: Fri, 23 Feb 2024 22:25:50 +1100 Subject: [PATCH] GeneratedRegexAttribute --- src/Polyfill/Regex/GeneratedRegexAttribute.cs | 99 +++++++++++++++++++ src/Tests/PolyfillTests_Regex.cs | 7 ++ 2 files changed, 106 insertions(+) create mode 100644 src/Polyfill/Regex/GeneratedRegexAttribute.cs diff --git a/src/Polyfill/Regex/GeneratedRegexAttribute.cs b/src/Polyfill/Regex/GeneratedRegexAttribute.cs new file mode 100644 index 00000000..f86e768d --- /dev/null +++ b/src/Polyfill/Regex/GeneratedRegexAttribute.cs @@ -0,0 +1,99 @@ +// +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +#pragma warning disable + +#if !NET7_0_OR_GREATER + +namespace System.Text.RegularExpressions; + +using System; +using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; +using Link = System.ComponentModel.DescriptionAttribute; + +/// +/// Instructs the System.Text.RegularExpressions source generator to generate an implementation of the specified regular expression. +/// +[ExcludeFromCodeCoverage] +[DebuggerNonUserCode] +[AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = false)] +[Link("https://learn.microsoft.com/en-us/dotnet/api/system.text.regularexpressions.generatedregexattribute")] +#if PolyPublic +public +#endif +public sealed class GeneratedRegexAttribute : Attribute +{ + /// Initializes a new instance of the with the specified pattern. + /// The regular expression pattern to match. + public GeneratedRegexAttribute([StringSyntax(StringSyntaxAttribute.Regex)] string pattern) + : this(pattern, RegexOptions.None) + { + } + + /// Initializes a new instance of the with the specified pattern and options. + /// The regular expression pattern to match. + /// A bitwise combination of the enumeration values that modify the regular expression. + public GeneratedRegexAttribute([StringSyntax(StringSyntaxAttribute.Regex, nameof(options))] string pattern, RegexOptions options) + : this(pattern, options, -1) + { + } + + /// Initializes a new instance of the with the specified pattern and options. + /// The regular expression pattern to match. + /// A bitwise combination of the enumeration values that modify the regular expression. + /// The name of a culture to be used for case sensitive comparisons. is not case-sensitive. + /// + /// For a list of predefined culture names on Windows systems, see the Language tag column in the list of + /// language/region names suported by Windows. Culture names follow the standard defined by BCP 47. In addition, + /// starting with Windows 10, can be any valid BCP-47 language tag. + /// + /// If is , the invariant culture will be used. + /// + public GeneratedRegexAttribute([StringSyntax(StringSyntaxAttribute.Regex, nameof(options))] string pattern, RegexOptions options, string cultureName) + : this(pattern, options, -1, cultureName) + { + } + + /// Initializes a new instance of the with the specified pattern, options, and timeout. + /// The regular expression pattern to match. + /// A bitwise combination of the enumeration values that modify the regular expression. + /// A time-out interval (milliseconds), or to indicate that the method should not time out. + public GeneratedRegexAttribute([StringSyntax(StringSyntaxAttribute.Regex, nameof(options))] string pattern, RegexOptions options, int matchTimeoutMilliseconds) + : this(pattern, options, matchTimeoutMilliseconds, string.Empty /* Empty string means Invariant culture */) + { + } + + /// Initializes a new instance of the with the specified pattern, options, and timeout. + /// The regular expression pattern to match. + /// A bitwise combination of the enumeration values that modify the regular expression. + /// A time-out interval (milliseconds), or to indicate that the method should not time out. + /// The name of a culture to be used for case sensitive comparisons. is not case-sensitive. + /// + /// For a list of predefined culture names on Windows systems, see the Language tag column in the list of + /// language/region names suported by Windows. Culture names follow the standard defined by BCP 47. In addition, + /// starting with Windows 10, can be any valid BCP-47 language tag. + /// + /// If is , the invariant culture will be used. + /// + public GeneratedRegexAttribute([StringSyntax(StringSyntaxAttribute.Regex, nameof(options))] string pattern, RegexOptions options, int matchTimeoutMilliseconds, string cultureName) + { + Pattern = pattern; + Options = options; + MatchTimeoutMilliseconds = matchTimeoutMilliseconds; + CultureName = cultureName; + } + + /// Gets the regular expression pattern to match. + public string Pattern { get; } + + /// Gets a bitwise combination of the enumeration values that modify the regular expression. + public RegexOptions Options { get; } + + /// Gets a time-out interval (milliseconds), or to indicate that the method should not time out. + public int MatchTimeoutMilliseconds { get; } + + /// Gets the name of the culture to be used for case sensitive comparisons. + public string CultureName { get; } +} +#endif \ No newline at end of file diff --git a/src/Tests/PolyfillTests_Regex.cs b/src/Tests/PolyfillTests_Regex.cs index 5d7335c1..62d9db5a 100644 --- a/src/Tests/PolyfillTests_Regex.cs +++ b/src/Tests/PolyfillTests_Regex.cs @@ -26,6 +26,13 @@ public void EnumerateMatches() Assert.IsTrue(found); } + [GeneratedRegex("abc|def")] + private static partial Regex GeneratedRegex(); + + [Test] + public void GeneratedRegexTest() => + Assert.True(GeneratedRegex().IsMatch("abc")); + [Test] public void EnumerateMatchesStatic() {