Remove slow regex from threading analyzers#1547
Conversation
There was a problem hiding this comment.
Pull request overview
Removes regex-based parsing from threading analyzers to avoid pathological backtracking/timeout scenarios and improve performance determinism.
Changes:
- Removed regex fields (and timeout handling) used to parse additional-file entries.
- Added non-regex parsers for type/member reference lines and updated call sites to use them.
src/Microsoft.VisualStudio.Threading.Analyzers/CommonInterest.cs
Outdated
Show resolved
Hide resolved
src/Microsoft.VisualStudio.Threading.Analyzers/CommonInterest.cs
Outdated
Show resolved
Hide resolved
src/Microsoft.VisualStudio.Threading.Analyzers/CommonInterest.cs
Outdated
Show resolved
Hide resolved
src/Microsoft.VisualStudio.Threading.Analyzers/CommonInterest.cs
Outdated
Show resolved
Hide resolved
src/Microsoft.VisualStudio.Threading.Analyzers/CommonInterest.cs
Outdated
Show resolved
Hide resolved
src/Microsoft.VisualStudio.Threading.Analyzers/CommonInterest.cs
Outdated
Show resolved
Hide resolved
a56023c to
13513b5
Compare
13513b5 to
4abe4eb
Compare
src/Microsoft.VisualStudio.Threading.Analyzers/CommonInterest.cs
Outdated
Show resolved
Hide resolved
4abe4eb to
0df6788
Compare
src/Microsoft.VisualStudio.Threading.Analyzers/CommonInterest.cs
Outdated
Show resolved
Hide resolved
0df6788 to
c4644e8
Compare
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 7 out of 7 changed files in this pull request and generated 2 comments.
Comments suppressed due to low confidence (1)
src/Microsoft.VisualStudio.Threading.Analyzers/CommonInterest.cs:91
SplitQualifiedIdentifierreturns a non-nullstringtype name, but the deconstruction usesstring? typeName, which can trigger nullable warnings when passingtypeNametoQualifiedType(expectsstring). Consider deconstructing intostring typeName(or otherwise ensure the value is statically non-null).
(ImmutableArray<string> containingNamespace, string? typeName) = SplitQualifiedIdentifier(typeNameMemory);
var type = new QualifiedType(containingNamespace, typeName);
QualifiedMember member = memberNameValue is not null ? new QualifiedMember(type, memberNameValue) : default(QualifiedMember);
| } | ||
| catch (RegexMatchTimeoutException) | ||
|
|
||
| (ImmutableArray<string> containingNamespace, string? typeName) = SplitQualifiedIdentifier(typeNameMemory); |
There was a problem hiding this comment.
Same nullable flow issue here: SplitQualifiedIdentifier returns a non-null string, but you deconstruct into string? typeName and then pass it to QualifiedType, which may produce nullable warnings. Use a non-null string local (or apply a null-forgiving operator if truly intended).
This issue also appears on line 89 of the same file.
| (ImmutableArray<string> containingNamespace, string? typeName) = SplitQualifiedIdentifier(typeNameMemory); | |
| (ImmutableArray<string> containingNamespace, string typeName) = SplitQualifiedIdentifier(typeNameMemory); |
| // Copyright (c) Microsoft Corporation. All rights reserved. | ||
| // Licensed under the MIT license. See LICENSE file in the project root for full license information. | ||
|
|
||
| using Microsoft.VisualStudio.Threading.Analyzers; |
There was a problem hiding this comment.
using Microsoft.VisualStudio.Threading.Analyzers; is redundant here because the test project already defines global using Microsoft.VisualStudio.Threading.Analyzers; in Usings.cs. Keeping both can cause unnecessary-using style diagnostics in some configurations.
| using Microsoft.VisualStudio.Threading.Analyzers; |
Root cause: Both
NegatableTypeOrMemberReferenceRegexandMemberReferenceRegexcontained(?<typeName>[^\[\]\:]+)+— a character-class group with an unnecessary outer + quantifier. When the overall match failed on a long type name, the regex engine tried exponentially many ways to split the type-name substring across the group, causing catastrophic backtracking.Fix: Removed both Regex fields and RegexMatchTimeout entirely from CommonInterest.cs, replacing each call site with custom string parsers.
Also add an mcp.json file.