diff --git a/eng/CodeAnalysis.src.globalconfig b/eng/CodeAnalysis.src.globalconfig index e652c2365daabe..5153388909477e 100644 --- a/eng/CodeAnalysis.src.globalconfig +++ b/eng/CodeAnalysis.src.globalconfig @@ -21,6 +21,30 @@ dotnet_diagnostic.BCL0015.severity = none # BCL0020: Invalid SR.Format call dotnet_diagnostic.BCL0020.severity = warning +# SYSLIB1045: Convert to 'GeneratedRegexAttribute'. +dotnet_diagnostic.SYSLIB1045.severity = warning + +# SYSLIB1054: Use 'LibraryImportAttribute' instead of 'DllImportAttribute' to generate P/Invoke marshalling code at compile time +dotnet_diagnostic.SYSLIB1054.severity = warning + +# SYSLIB1055: Invalid 'CustomMarshallerAttribute' usage +dotnet_diagnostic.SYSLIB1055.severity = error + +# SYSLIB1056:Specified marshaller type is invalid +dotnet_diagnostic.SYSLIB1056.severity = error + +# SYSLIB1057: Marshaller type does not have the required shape +dotnet_diagnostic.SYSLIB1057.severity = error + +# SYSLIB1058: Invalid 'NativeMarshallingAttribute' usage +dotnet_diagnostic.SYSLIB1058.severity = error + +# SYSLIB1060: Specified marshaller type is invalid +dotnet_diagnostic.SYSLIB1060.severity = error + +# SYSLIB1061: Marshaller type has incompatible method signatures +dotnet_diagnostic.SYSLIB1061.severity = error + # CA1000: Do not declare static members on generic types dotnet_diagnostic.CA1000.severity = none diff --git a/eng/CodeAnalysis.test.globalconfig b/eng/CodeAnalysis.test.globalconfig index 925c0ea1409f6a..fd46845091dcb4 100644 --- a/eng/CodeAnalysis.test.globalconfig +++ b/eng/CodeAnalysis.test.globalconfig @@ -21,6 +21,30 @@ dotnet_diagnostic.BCL0015.severity = none # BCL0020: Invalid SR.Format call dotnet_diagnostic.BCL0020.severity = none +# SYSLIB1045: Convert to 'GeneratedRegexAttribute'. +dotnet_diagnostic.SYSLIB1045.severity = none + +# SYSLIB1054: Use 'LibraryImportAttribute' instead of 'DllImportAttribute' to generate P/Invoke marshalling code at compile time +dotnet_diagnostic.SYSLIB1054.severity = none + +# SYSLIB1055: Invalid 'CustomMarshallerAttribute' usage +dotnet_diagnostic.SYSLIB1055.severity = error + +# SYSLIB1056:Specified marshaller type is invalid +dotnet_diagnostic.SYSLIB1056.severity = error + +# SYSLIB1057: Marshaller type does not have the required shape +dotnet_diagnostic.SYSLIB1057.severity = error + +# SYSLIB1058: Invalid 'NativeMarshallingAttribute' usage +dotnet_diagnostic.SYSLIB1058.severity = error + +# SYSLIB1060: Specified marshaller type is invalid +dotnet_diagnostic.SYSLIB1060.severity = error + +# SYSLIB1061: Marshaller type has incompatible method signatures +dotnet_diagnostic.SYSLIB1061.severity = error + # CA1000: Do not declare static members on generic types dotnet_diagnostic.CA1000.severity = none diff --git a/src/coreclr/nativeaot/Runtime.Base/src/System/Runtime/InternalCalls.cs b/src/coreclr/nativeaot/Runtime.Base/src/System/Runtime/InternalCalls.cs index f97a62a9c98f64..6703677489afd5 100644 --- a/src/coreclr/nativeaot/Runtime.Base/src/System/Runtime/InternalCalls.cs +++ b/src/coreclr/nativeaot/Runtime.Base/src/System/Runtime/InternalCalls.cs @@ -10,6 +10,8 @@ using Internal.Runtime; +#pragma warning disable SYSLIB1054 // Use DllImport here instead of LibraryImport because this file is used by Test.CoreLib + namespace System.Runtime { internal enum DispatchCellType diff --git a/src/coreclr/nativeaot/Runtime.Base/src/System/Runtime/RuntimeExports.cs b/src/coreclr/nativeaot/Runtime.Base/src/System/Runtime/RuntimeExports.cs index c6ab819a841673..05f30f8a4cbd0e 100644 --- a/src/coreclr/nativeaot/Runtime.Base/src/System/Runtime/RuntimeExports.cs +++ b/src/coreclr/nativeaot/Runtime.Base/src/System/Runtime/RuntimeExports.cs @@ -285,10 +285,11 @@ public static unsafe int RhGetCurrentThreadStackTrace(IntPtr[] outputBuffer) return RhpGetCurrentThreadStackTrace(pOutputBuffer, (uint)((outputBuffer != null) ? outputBuffer.Length : 0), new UIntPtr(&pOutputBuffer)); } - // Use DllImport here instead of LibraryImport because this file is used by Test.CoreLib. +#pragma warning disable SYSLIB1054 // Use DllImport here instead of LibraryImport because this file is used by Test.CoreLib. [DllImport(Redhawk.BaseName)] [UnmanagedCallConv(CallConvs = new Type[] { typeof(CallConvCdecl) })] private static extern unsafe int RhpGetCurrentThreadStackTrace(IntPtr* pOutputBuffer, uint outputBufferLength, UIntPtr addressInCurrentFrame); +#pragma warning restore SYSLIB1054 // Worker for RhGetCurrentThreadStackTrace. RhGetCurrentThreadStackTrace just allocates a transition // frame that will be used to seed the stack trace and this method does all the real work. diff --git a/src/coreclr/tools/.editorconfig b/src/coreclr/tools/.editorconfig new file mode 100644 index 00000000000000..2604c0c3f48d8a --- /dev/null +++ b/src/coreclr/tools/.editorconfig @@ -0,0 +1,6 @@ +### Code Style Analyzers + +[*.cs] + +# TODO: Update tools to use LibraryImport instead of DllImport +dotnet_diagnostic.SYSLIB1054.severity = suggestion diff --git a/src/coreclr/tools/aot/Mono.Linker.Tests/Mono.Linker.Tests.csproj b/src/coreclr/tools/aot/Mono.Linker.Tests/Mono.Linker.Tests.csproj index 479c971ed03fd7..28814362b0c9f7 100644 --- a/src/coreclr/tools/aot/Mono.Linker.Tests/Mono.Linker.Tests.csproj +++ b/src/coreclr/tools/aot/Mono.Linker.Tests/Mono.Linker.Tests.csproj @@ -3,6 +3,7 @@ $(NetCoreAppToolCurrent) enable + $(NoWarn);SYSLIB1045 false true diff --git a/src/libraries/Common/src/System/Data/Common/DbConnectionOptions.Common.cs b/src/libraries/Common/src/System/Data/Common/DbConnectionOptions.Common.cs index 04fdf51c55984b..936c81c094e45d 100644 --- a/src/libraries/Common/src/System/Data/Common/DbConnectionOptions.Common.cs +++ b/src/libraries/Common/src/System/Data/Common/DbConnectionOptions.Common.cs @@ -4,7 +4,6 @@ using System.Collections.Generic; using System.Diagnostics; using System.Diagnostics.CodeAnalysis; -using System.Globalization; using System.Text; using System.Text.RegularExpressions; @@ -13,19 +12,6 @@ namespace System.Data.Common internal partial class DbConnectionOptions { #if DEBUG - /*private const string ConnectionStringPatternV1 = - "[\\s;]*" - +"(?([^=\\s]|\\s+[^=\\s]|\\s+==|==)+)" - + "\\s*=(?!=)\\s*" - +"(?(" - + "(" + "\"" + "([^\"]|\"\")*" + "\"" + ")" - + "|" - + "(" + "'" + "([^']|'')*" + "'" + ")" - + "|" - + "(" + "(?![\"'])" + "([^\\s;]|\\s+[^\\s;])*" + "(? new Regex(ConnectionStringPattern, RegexOptions.ExplicitCapture | RegexOptions.Compiled); + private static Regex CreateConnectionStringRegexOdbc() => new Regex(ConnectionStringPatternOdbc, RegexOptions.ExplicitCapture | RegexOptions.Compiled); +#endif #endif internal const string DataDirectory = "|datadirectory|"; -#pragma warning disable CA1823 // used in some compilations and not others - private static readonly Regex s_connectionStringValidKeyRegex = new Regex("^(?![;\\s])[^\\p{Cc}]+(? new Regex("^(?![;\\s])[^\\p{Cc}]+(? new Regex("^[^\"'=;\\s\\p{Cc}]*$", RegexOptions.Compiled); + private static Regex CreateConnectionStringQuoteOdbcValueRegex() => new Regex("^\\{([^\\}\u0000]|\\}\\})*\\}$", RegexOptions.ExplicitCapture | RegexOptions.Compiled); +#endif // connection string common keywords private static class KEY diff --git a/src/libraries/Directory.Build.targets b/src/libraries/Directory.Build.targets index 75732bff0f7171..dfd6937366ad9e 100644 --- a/src/libraries/Directory.Build.targets +++ b/src/libraries/Directory.Build.targets @@ -37,7 +37,7 @@ - $(NoWarn);CA1510;CA1511;CA1512;CA1513 + $(NoWarn);CA1510;CA1511;CA1512;CA1513;CA1845;CA1846;CA1847 false - $(NoWarn);CA1847 true Provides types that support using XML configuration files (app.config). This package exists only to support migrating existing .NET Framework code that already uses System.Configuration. When writing new code, use another configuration system instead, such as Microsoft.Extensions.Configuration. diff --git a/src/libraries/System.Data.Common/src/System.Data.Common.csproj b/src/libraries/System.Data.Common/src/System.Data.Common.csproj index 23b92c30795f57..166da6dff47e96 100644 --- a/src/libraries/System.Data.Common/src/System.Data.Common.csproj +++ b/src/libraries/System.Data.Common/src/System.Data.Common.csproj @@ -1,4 +1,4 @@ - + true $(NetCoreAppCurrent) @@ -327,5 +327,9 @@ + diff --git a/src/libraries/System.Data.Odbc/src/System.Data.Odbc.csproj b/src/libraries/System.Data.Odbc/src/System.Data.Odbc.csproj index 7c1e49348ad9a7..7589b6bb2e3a5c 100644 --- a/src/libraries/System.Data.Odbc/src/System.Data.Odbc.csproj +++ b/src/libraries/System.Data.Odbc/src/System.Data.Odbc.csproj @@ -2,9 +2,7 @@ $(NetCoreAppCurrent)-windows;$(NetCoreAppCurrent)-freebsd;$(NetCoreAppCurrent)-illumos;$(NetCoreAppCurrent)-solaris;$(NetCoreAppCurrent)-linux;$(NetCoreAppCurrent)-osx;$(NetCoreAppCurrent)-ios;$(NetCoreAppCurrent)-tvos;$(NetCoreAppCurrent);$(NetCoreAppPrevious)-windows;$(NetCoreAppPrevious)-freebsd;$(NetCoreAppPrevious)-illumos;$(NetCoreAppPrevious)-solaris;$(NetCoreAppPrevious)-linux;$(NetCoreAppPrevious)-osx;$(NetCoreAppPrevious)-ios;$(NetCoreAppPrevious)-tvos;$(NetCoreAppPrevious);$(NetCoreAppMinimum)-windows;$(NetCoreAppMinimum)-freebsd;$(NetCoreAppMinimum)-linux;$(NetCoreAppMinimum)-osx;$(NetCoreAppMinimum);netstandard2.0;$(NetFrameworkMinimum) true - $(NoWarn);CA2249;CA1838;CA1846 - - $(NoWarn);CA1845 + $(NoWarn);CA2249;CA1838 true Provides a collection of classes used to access an ODBC data source in the managed space @@ -135,6 +133,10 @@ System.Data.Odbc.OdbcTransaction Link="Common\DisableRuntimeMarshalling.cs" /> + diff --git a/src/libraries/System.Data.OleDb/src/DbConnectionOptions.cs b/src/libraries/System.Data.OleDb/src/DbConnectionOptions.cs index 5feec7c474b050..0bb5bde47ea416 100644 --- a/src/libraries/System.Data.OleDb/src/DbConnectionOptions.cs +++ b/src/libraries/System.Data.OleDb/src/DbConnectionOptions.cs @@ -5,32 +5,18 @@ using System.Diagnostics; using System.Diagnostics.CodeAnalysis; using System.Globalization; -using System.Runtime.Versioning; using System.Text; using System.Text.RegularExpressions; namespace System.Data.Common { - internal class DbConnectionOptions + internal partial class DbConnectionOptions { // instances of this class are intended to be immutable, i.e readonly // used by pooling classes so it is much easier to verify correctness // when not worried about the class being modified during execution #if DEBUG - /*private const string ConnectionStringPatternV1 = - "[\\s;]*" - +"(?([^=\\s]|\\s+[^=\\s]|\\s+==|==)+)" - + "\\s*=(?!=)\\s*" - +"(?(" - + "(" + "\"" + "([^\"]|\"\")*" + "\"" + ")" - + "|" - + "(" + "'" + "([^']|'')*" + "'" + ")" - + "|" - + "(" + "(?![\"'])" + "([^\\s;]|\\s+[^\\s;])*" + "(? new Regex(ConnectionStringPattern, RegexOptions.ExplicitCapture | RegexOptions.Compiled); + private static Regex CreateConnectionStringRegexOdbc() => new Regex(ConnectionStringPatternOdbc, RegexOptions.ExplicitCapture | RegexOptions.Compiled); +#endif +#endif internal const string DataDirectory = "|datadirectory|"; - private static readonly Regex ConnectionStringQuoteValueRegex = new Regex("^[^\"'=;\\s\\p{Cc}]*$", RegexOptions.Compiled); // generally do not quote the value if it matches the pattern - private static readonly Regex ConnectionStringQuoteOdbcValueRegex = new Regex("^\\{([^\\}\u0000]|\\}\\})*\\}$", RegexOptions.ExplicitCapture | RegexOptions.Compiled); // do not quote odbc value if it matches this pattern + private static readonly Regex ConnectionStringValidKeyRegex = CreateConnectionStringValidKeyRegex(); // key not allowed to start with semi-colon or space or contain non-visible characters or end with space + private static readonly Regex ConnectionStringQuoteValueRegex = CreateConnectionStringQuoteValueRegex(); // generally do not quote the value if it matches the pattern + private static readonly Regex ConnectionStringQuoteOdbcValueRegex = CreateConnectionStringQuoteOdbcValueRegex(); // do not quote odbc value if it matches this pattern + +#if NET7_0_OR_GREATER + [GeneratedRegex("^(?![;\\s])[^\\p{Cc}]+(? new Regex("^(?![;\\s])[^\\p{Cc}]+(? new Regex("^[^\"'=;\\s\\p{Cc}]*$", RegexOptions.Compiled); + private static Regex CreateConnectionStringQuoteOdbcValueRegex() => new Regex("^\\{([^\\}\u0000]|\\}\\})*\\}$", RegexOptions.ExplicitCapture | RegexOptions.Compiled); +#endif // connection string common keywords private static class KEY diff --git a/src/libraries/System.Data.OleDb/src/System.Data.OleDb.csproj b/src/libraries/System.Data.OleDb/src/System.Data.OleDb.csproj index 28aa5e8adca403..e5acc35fdf6c21 100644 --- a/src/libraries/System.Data.OleDb/src/System.Data.OleDb.csproj +++ b/src/libraries/System.Data.OleDb/src/System.Data.OleDb.csproj @@ -1,4 +1,4 @@ - + $(NetCoreAppCurrent)-windows;$(NetCoreAppCurrent);$(NetCoreAppPrevious)-windows;$(NetCoreAppPrevious);$(NetCoreAppMinimum)-windows;$(NetCoreAppMinimum);netstandard2.0;$(NetFrameworkMinimum) true @@ -6,8 +6,6 @@ $(NoWarn);CA2249 $(NoWarn);SYSLIB0004 - - $(NoWarn);CA1845 true Provides a collection of classes for OLEDB. @@ -149,4 +147,11 @@ System.Data.OleDb.OleDbTransaction + + + + diff --git a/src/libraries/System.Diagnostics.DiagnosticSource/src/System.Diagnostics.DiagnosticSource.csproj b/src/libraries/System.Diagnostics.DiagnosticSource/src/System.Diagnostics.DiagnosticSource.csproj index db7ca3770e6326..5bc02a2bb8d23b 100644 --- a/src/libraries/System.Diagnostics.DiagnosticSource/src/System.Diagnostics.DiagnosticSource.csproj +++ b/src/libraries/System.Diagnostics.DiagnosticSource/src/System.Diagnostics.DiagnosticSource.csproj @@ -3,7 +3,7 @@ $(NetCoreAppCurrent);$(NetCoreAppPrevious);$(NetCoreAppMinimum);netstandard2.0;$(NetFrameworkMinimum) true false - $(NoWarn);SA1205;CA1845 + $(NoWarn);SA1205 false true true diff --git a/src/libraries/System.Diagnostics.EventLog/src/System.Diagnostics.EventLog.csproj b/src/libraries/System.Diagnostics.EventLog/src/System.Diagnostics.EventLog.csproj index a0e80d8a8d3292..c74dea7c375c59 100644 --- a/src/libraries/System.Diagnostics.EventLog/src/System.Diagnostics.EventLog.csproj +++ b/src/libraries/System.Diagnostics.EventLog/src/System.Diagnostics.EventLog.csproj @@ -2,11 +2,6 @@ $(NetCoreAppCurrent)-windows;$(NetCoreAppCurrent);$(NetCoreAppPrevious)-windows;$(NetCoreAppPrevious);$(NetCoreAppMinimum)-windows;$(NetCoreAppMinimum);netstandard2.0;$(NetFrameworkMinimum) true - $(NoWarn);CA1847 - - $(NoWarn);CA1845;CA1846 annotations true Provides the System.Diagnostics.EventLog class, which allows the applications to use the Windows event log service. diff --git a/src/libraries/System.Diagnostics.PerformanceCounter/src/System.Diagnostics.PerformanceCounter.csproj b/src/libraries/System.Diagnostics.PerformanceCounter/src/System.Diagnostics.PerformanceCounter.csproj index 012710af4a161d..c3677d6ed38615 100644 --- a/src/libraries/System.Diagnostics.PerformanceCounter/src/System.Diagnostics.PerformanceCounter.csproj +++ b/src/libraries/System.Diagnostics.PerformanceCounter/src/System.Diagnostics.PerformanceCounter.csproj @@ -2,7 +2,6 @@ $(NetCoreAppCurrent)-windows;$(NetCoreAppCurrent);$(NetCoreAppPrevious)-windows;$(NetCoreAppPrevious);$(NetCoreAppMinimum)-windows;$(NetCoreAppMinimum);netstandard2.0;$(NetFrameworkMinimum) true - $(NoWarn);CA1847 annotations true Provides the System.Diagnostics.PerformanceCounter class, which allows access to Windows performance counters. diff --git a/src/libraries/System.DirectoryServices.AccountManagement/src/System.DirectoryServices.AccountManagement.csproj b/src/libraries/System.DirectoryServices.AccountManagement/src/System.DirectoryServices.AccountManagement.csproj index 4ed867c0756234..de3e5656fa7284 100644 --- a/src/libraries/System.DirectoryServices.AccountManagement/src/System.DirectoryServices.AccountManagement.csproj +++ b/src/libraries/System.DirectoryServices.AccountManagement/src/System.DirectoryServices.AccountManagement.csproj @@ -1,13 +1,10 @@ - + $(NetCoreAppCurrent)-windows;$(NetCoreAppCurrent);$(NetCoreAppPrevious)-windows;$(NetCoreAppPrevious);$(NetCoreAppMinimum)-windows;$(NetCoreAppMinimum);netstandard2.0 true true $(NoWarn);CA2249 - - $(NoWarn);CA1845;CA1846;IDE0059;IDE0060;CA1822 + $(NoWarn);IDE0059;IDE0060;CA1822 annotations true true diff --git a/src/libraries/System.DirectoryServices/src/System.DirectoryServices.csproj b/src/libraries/System.DirectoryServices/src/System.DirectoryServices.csproj index c0ce625ae5365c..1b38cffd6febf2 100644 --- a/src/libraries/System.DirectoryServices/src/System.DirectoryServices.csproj +++ b/src/libraries/System.DirectoryServices/src/System.DirectoryServices.csproj @@ -1,12 +1,9 @@ - + $(NetCoreAppCurrent)-windows;$(NetCoreAppCurrent);$(NetCoreAppPrevious)-windows;$(NetCoreAppPrevious);$(NetCoreAppMinimum)-windows;$(NetCoreAppMinimum);netstandard2.0 true true - - $(NoWarn);CA1845;CA1846;IDE0059;IDE0060;CA1822 + $(NoWarn);IDE0059;IDE0060;CA1822 true true true diff --git a/src/libraries/System.IO.Packaging/src/System.IO.Packaging.csproj b/src/libraries/System.IO.Packaging/src/System.IO.Packaging.csproj index 72e3944173e378..3812ff100aaaf5 100644 --- a/src/libraries/System.IO.Packaging/src/System.IO.Packaging.csproj +++ b/src/libraries/System.IO.Packaging/src/System.IO.Packaging.csproj @@ -2,8 +2,6 @@ $(NetCoreAppCurrent);$(NetCoreAppPrevious);$(NetCoreAppMinimum);netstandard2.0;$(NetFrameworkMinimum) true - - $(NoWarn);CA1847 true Provides classes that support storage of multiple data objects in a single container. @@ -51,4 +49,4 @@ - \ No newline at end of file + diff --git a/src/libraries/System.Management/src/System.Management.csproj b/src/libraries/System.Management/src/System.Management.csproj index 5519da09cb3cb8..3c23101e634792 100644 --- a/src/libraries/System.Management/src/System.Management.csproj +++ b/src/libraries/System.Management/src/System.Management.csproj @@ -1,11 +1,9 @@ - + $(NetCoreAppCurrent)-windows;$(NetCoreAppCurrent);$(NetCoreAppPrevious)-windows;$(NetCoreAppPrevious);$(NetCoreAppMinimum)-windows;$(NetCoreAppMinimum);netstandard2.0 true $(NoWarn);0618 - - $(NoWarn);CA1845;IDE0059;IDE0060;CA1822 + $(NoWarn);IDE0059;IDE0060;CA1822 annotations true true diff --git a/src/libraries/System.Net.Quic/src/System.Net.Quic.csproj b/src/libraries/System.Net.Quic/src/System.Net.Quic.csproj index d0c7f936ec85d8..66018e46e00f0b 100644 --- a/src/libraries/System.Net.Quic/src/System.Net.Quic.csproj +++ b/src/libraries/System.Net.Quic/src/System.Net.Quic.csproj @@ -1,8 +1,10 @@ - + true $(NetCoreAppCurrent)-windows;$(NetCoreAppCurrent)-linux;$(NetCoreAppCurrent)-osx;$(NetCoreAppCurrent)-freebsd;$(NetCoreAppCurrent) true + + $(NoWarn);SYSLIB1054 diff --git a/src/libraries/System.Speech/src/System.Speech.csproj b/src/libraries/System.Speech/src/System.Speech.csproj index d2d475676fea58..be40805eec143a 100644 --- a/src/libraries/System.Speech/src/System.Speech.csproj +++ b/src/libraries/System.Speech/src/System.Speech.csproj @@ -4,8 +4,7 @@ true - - $(NoWarn);CS0649;SA1129;CA1846;CA1847;IDE0059;IDE0060;CA1822;CA1852 + $(NoWarn);CS0649;SA1129;IDE0059;IDE0060;CA1822;CA1852 annotations false true diff --git a/src/mono/wasm/debugger/BrowserDebugProxy/DebugStore.cs b/src/mono/wasm/debugger/BrowserDebugProxy/DebugStore.cs index 8596ca4bcf3026..d5d5b5a1c648ae 100644 --- a/src/mono/wasm/debugger/BrowserDebugProxy/DebugStore.cs +++ b/src/mono/wasm/debugger/BrowserDebugProxy/DebugStore.cs @@ -1221,11 +1221,13 @@ internal async Task LoadPDBFromSymbolServer(DebugStore debugStore, CancellationT logger.LogError($"Failed to load symbols from symbol server. ({ex.Message})"); } } + } -} - internal sealed class SourceFile + internal sealed partial class SourceFile { - private static readonly Regex regexForEscapeFileName = new(@"([:/])", RegexOptions.Compiled); + [GeneratedRegex(@"([:/])")] + private static partial Regex RegexForEscapeFileName(); + private Dictionary methods; private AssemblyInfo assembly; private Document doc; @@ -1326,7 +1328,7 @@ private static string GetHashOfString(string str) private static string EscapePathForUri(string path) { var builder = new StringBuilder(); - foreach (var part in regexForEscapeFileName.Split(path)) + foreach (var part in RegexForEscapeFileName().Split(path)) { if (part == ":" || part == "/") builder.Append(part); diff --git a/src/mono/wasm/debugger/BrowserDebugProxy/EvaluateExpression.cs b/src/mono/wasm/debugger/BrowserDebugProxy/EvaluateExpression.cs index 829dc3a8d4f7eb..d5deef7c411e0b 100644 --- a/src/mono/wasm/debugger/BrowserDebugProxy/EvaluateExpression.cs +++ b/src/mono/wasm/debugger/BrowserDebugProxy/EvaluateExpression.cs @@ -24,7 +24,7 @@ namespace Microsoft.WebAssembly.Diagnostics { - internal static class ExpressionEvaluator + internal static partial class ExpressionEvaluator { internal static Script script = CSharpScript.Create( "", @@ -33,9 +33,11 @@ internal static class ExpressionEvaluator typeof(Enumerable).Assembly, typeof(JObject).Assembly )); - private sealed class ExpressionSyntaxReplacer : CSharpSyntaxWalker + private sealed partial class ExpressionSyntaxReplacer : CSharpSyntaxWalker { - private static Regex regexForReplaceVarName = new Regex(@"[^A-Za-z0-9_]", RegexOptions.Singleline); + [GeneratedRegex(@"[^A-Za-z0-9_]", RegexOptions.Singleline)] + private static partial Regex RegexForReplaceVarName(); + public List identifiers = new List(); public List methodCalls = new List(); public List memberAccesses = new List(); @@ -111,7 +113,7 @@ public SyntaxTree ReplaceVars(SyntaxTree syntaxTree, IEnumerable ma_val { // Generate a random suffix string suffix = Guid.NewGuid().ToString().Substring(0, 5); - string prefix = regexForReplaceVarName.Replace(ma_str, "_"); + string prefix = RegexForReplaceVarName().Replace(ma_str, "_"); id_name = $"{prefix}_{suffix}"; memberAccessToParamName[ma_str] = id_name; @@ -128,7 +130,7 @@ public SyntaxTree ReplaceVars(SyntaxTree syntaxTree, IEnumerable ma_val { // Generate a random suffix string suffix = Guid.NewGuid().ToString().Substring(0, 5); - string prefix = regexForReplaceVarName.Replace(iesStr, "_"); + string prefix = RegexForReplaceVarName().Replace(iesStr, "_"); id_name = $"{prefix}_{suffix}"; methodCallToParamName[iesStr] = id_name; } @@ -144,7 +146,7 @@ public SyntaxTree ReplaceVars(SyntaxTree syntaxTree, IEnumerable ma_val { // Generate a random suffix string suffix = Guid.NewGuid().ToString().Substring(0, 5); - string prefix = regexForReplaceVarName.Replace(eaStr, "_"); + string prefix = RegexForReplaceVarName().Replace(eaStr, "_"); id_name = $"{prefix}_{suffix}"; elementAccessToParamName[eaStr] = id_name; } diff --git a/src/mono/wasm/debugger/BrowserDebugProxy/MonoSDBHelper.cs b/src/mono/wasm/debugger/BrowserDebugProxy/MonoSDBHelper.cs index 8f0556b12f6347..6861eef3ccbbcb 100644 --- a/src/mono/wasm/debugger/BrowserDebugProxy/MonoSDBHelper.cs +++ b/src/mono/wasm/debugger/BrowserDebugProxy/MonoSDBHelper.cs @@ -785,7 +785,7 @@ public async Task GetValue(MonoSDBHelper sdbHelper, CancellationToken t return _value; } } - internal sealed class MonoSDBHelper + internal sealed partial class MonoSDBHelper { private static int debuggerObjectId; private static int cmdId = 1; //cmdId == 0 is used by events which come from runtime @@ -804,12 +804,25 @@ internal sealed class MonoSDBHelper private SessionId sessionId; internal readonly ILogger logger; - private static readonly Regex regexForAsyncLocals = new(@"\<(?[^)]*)\>(?[^)]*)(__)(?\d+)", RegexOptions.Singleline); //5__1 // works - private static readonly Regex regexForVBAsyncLocals = new(@"\$VB\$ResumableLocal_(?[^\$]*)\$(?\d+)", RegexOptions.Singleline); //$VB$ResumableLocal_testVbScope$2 - private static readonly Regex regexForVBAsyncMethodName = new(@"VB\$StateMachine_(\d+)_(?.*)", RegexOptions.Singleline); //VB$StateMachine_2_RunVBScope - private static readonly Regex regexForAsyncMethodName = new (@"\<([^>]*)\>([d][_][_])([0-9]*)", RegexOptions.Compiled); - private static readonly Regex regexForGenericArgs = new (@"[`][0-9]+", RegexOptions.Compiled); - private static readonly Regex regexForNestedLeftRightAngleBrackets = new ("^(((?'Open'<)[^<>]*)+((?'Close-Open'>)[^<>]*)+)*(?(Open)(?!))[^<>]*", RegexOptions.Compiled); // b__3_0 + + [GeneratedRegex(@"\<(?[^)]*)\>(?[^)]*)(__)(?\d+)", RegexOptions.Singleline)] + private static partial Regex RegexForAsyncLocals(); //5__1 // works + + [GeneratedRegex(@"\$VB\$ResumableLocal_(?[^\$]*)\$(?\d+)", RegexOptions.Singleline)] + private static partial Regex RegexForVBAsyncLocals(); //$VB$ResumableLocal_testVbScope$2 + + [GeneratedRegex(@"VB\$StateMachine_(\d+)_(?.*)", RegexOptions.Singleline)] + private static partial Regex RegexForVBAsyncMethodName(); //VB$StateMachine_2_RunVBScope + + [GeneratedRegex(@"\<([^>]*)\>([d][_][_])([0-9]*)")] + private static partial Regex RegexForAsyncMethodName(); + + [GeneratedRegex(@"[`][0-9]+")] + private static partial Regex RegexForGenericArgs(); + + [GeneratedRegex("^(((?'Open'<)[^<>]*)+((?'Close-Open'>)[^<>]*)+)*(?(Open)(?!))[^<>]*")] + private static partial Regex RegexForNestedLeftRightAngleBrackets(); // b__3_0 + public JObjectValueCreator ValueCreator { get; init; } public static int GetNewId() { return cmdId++; } @@ -867,7 +880,7 @@ public static string GetPrettierMethodName(string methodName) { methodName = methodName.Replace(':', '.'); methodName = methodName.Replace('/', '.'); - methodName = regexForGenericArgs.Replace(methodName, ""); + methodName = RegexForGenericArgs().Replace(methodName, ""); return methodName; } @@ -1244,7 +1257,7 @@ public async Task GetPrettyMethodName(int methodId, bool isAnonymous, Ca var ret = retDebuggerCmdReader.ReadString(); if (ret.IndexOf(':') is int index && index > 0) ret = ret.Substring(0, index); - ret = regexForAsyncMethodName.Replace(ret, "$1"); + ret = RegexForAsyncMethodName().Replace(ret, "$1"); var numGenericTypeArgs = retDebuggerCmdReader.ReadInt32(); var numGenericMethodArgs = retDebuggerCmdReader.ReadInt32(); int numTotalGenericArgs = numGenericTypeArgs + numGenericMethodArgs; @@ -1252,17 +1265,17 @@ public async Task GetPrettyMethodName(int methodId, bool isAnonymous, Ca for (int i = 0; i < numTotalGenericArgs; i++) { var typeArgC = retDebuggerCmdReader.ReadString(); - typeArgC = regexForGenericArgs.Replace(typeArgC, ""); + typeArgC = RegexForGenericArgs().Replace(typeArgC, ""); genericArgs.Add(typeArgC); } - var match = regexForGenericArgs.Match(ret); + var match = RegexForGenericArgs().Match(ret); while (match.Success) { var countArgs = Convert.ToInt32(match.Value.Remove(0, 1)); ret = ret.Remove(match.Index, match.Value.Length); ret = ret.Insert(match.Index, $"<{string.Join(", ", genericArgs.Take(countArgs))}>"); genericArgs.RemoveRange(0, countArgs); - match = regexForGenericArgs.Match(ret); + match = RegexForGenericArgs().Match(ret); } ret = ret.Replace('/', '.'); return ret; @@ -1282,7 +1295,7 @@ public async Task GetPrettyMethodName(int methodId, bool isAnonymous, Ca } else if (klassName.StartsWith("VB$")) { - var match = regexForVBAsyncMethodName.Match(klassName); + var match = RegexForVBAsyncMethodName().Match(klassName); if (match.Success) ret = ret.Insert(0, match.Groups["methodName"].Value); else @@ -1290,7 +1303,7 @@ public async Task GetPrettyMethodName(int methodId, bool isAnonymous, Ca } else { - var matchOnClassName = regexForNestedLeftRightAngleBrackets.Match(klassName); + var matchOnClassName = RegexForNestedLeftRightAngleBrackets().Match(klassName); if (matchOnClassName.Success && matchOnClassName.Groups["Close"].Captures.Count > 0) klassName = matchOnClassName.Groups["Close"].Captures[0].Value; if (ret.Length > 0) @@ -1299,7 +1312,7 @@ public async Task GetPrettyMethodName(int methodId, bool isAnonymous, Ca } } var methodName = retDebuggerCmdReader.ReadString(); - var matchOnMethodName = regexForNestedLeftRightAngleBrackets.Match(methodName); + var matchOnMethodName = RegexForNestedLeftRightAngleBrackets().Match(methodName); if (matchOnMethodName.Success && matchOnMethodName.Groups["Close"].Captures.Count > 0) { if (isAnonymous && anonymousMethodId.Length == 0 && methodName.Contains("__")) @@ -1653,12 +1666,18 @@ public async Task GetValueFromDebuggerDisplayAttribute(DotnetObjectId do return null; } + [GeneratedRegex(@"`\d+")] + private static partial Regex RegexForGenericArity(); + + [GeneratedRegex(@"[[, ]+]")] + private static partial Regex RegexForSquareBrackets(); + public async Task GetTypeName(int typeId, CancellationToken token) { string className = await GetTypeNameOriginal(typeId, token); className = className.Replace("+", "."); - className = Regex.Replace(className, @"`\d+", ""); - className = Regex.Replace(className, @"[[, ]+]", "__SQUARED_BRACKETS__"); + className = RegexForGenericArity().Replace(className, ""); + className = RegexForSquareBrackets().Replace(className, "__SQUARED_BRACKETS__"); //className = className.Replace("[]", "__SQUARED_BRACKETS__"); className = className.Replace("[", "<"); className = className.Replace("]", ">"); @@ -2001,7 +2020,7 @@ public async Task GetHoistedLocalVariables(MethodInfoWithDebugInformatio } else if (fieldName.StartsWith('<')) //examples: 5__2 { - var match = regexForAsyncLocals.Match(fieldName); + var match = RegexForAsyncLocals().Match(fieldName); if (match.Success) { if (!method.Info.ContainsAsyncScope(Convert.ToInt32(match.Groups["scopeId"].Value), offset)) @@ -2016,7 +2035,7 @@ public async Task GetHoistedLocalVariables(MethodInfoWithDebugInformatio } else if (fieldName.StartsWith("$VB$ResumableLocal_", StringComparison.Ordinal)) { - var match = regexForVBAsyncLocals.Match(fieldName); + var match = RegexForVBAsyncLocals().Match(fieldName); if (match.Success) { if (!method.Info.ContainsAsyncScope(Convert.ToInt32(match.Groups["scopeId"].Value) + 1, offset)) diff --git a/src/mono/wasm/host/Options.cs b/src/mono/wasm/host/Options.cs index 98dbbe77c94a29..5e04e4917f0a01 100644 --- a/src/mono/wasm/host/Options.cs +++ b/src/mono/wasm/host/Options.cs @@ -785,7 +785,7 @@ public string OptionName public delegate void OptionAction(TKey key, TValue value); - public class OptionSet : KeyedCollection + public partial class OptionSet : KeyedCollection { public OptionSet() : this(null, null) @@ -1148,15 +1148,15 @@ private static bool Unprocessed(ICollection extra, Option def, OptionCon return false; } - private readonly Regex ValueOption = new Regex( - @"^(?--|-|/)(?[^:=]+)((?[:=])(?.*))?$"); + [GeneratedRegex(@"^(?--|-|/)(?[^:=]+)((?[:=])(?.*))?$")] + private static partial Regex ValueOption(); protected bool GetOptionParts(string argument, out string flag, out string name, out string sep, out string value) { ArgumentNullException.ThrowIfNull(argument); flag = name = sep = value = null; - Match m = ValueOption.Match(argument); + Match m = ValueOption().Match(argument); if (!m.Success) { return false; @@ -1461,9 +1461,12 @@ private static void Write(TextWriter o, ref int n, string s) o.Write(s); } + [GeneratedRegex(@"(?<=(?