Skip to content

Commit 12bfd87

Browse files
Copilotmeziantou
andauthored
Fix MA0158 not reported when lock field is initialized in constructor (#1037)
* Initial plan * Fix MA0158 not reported when lock field initialized in .ctor or .cctor Co-authored-by: meziantou <509220+meziantou@users.noreply.github.com> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: meziantou <509220+meziantou@users.noreply.github.com>
1 parent d2bce00 commit 12bfd87

File tree

2 files changed

+98
-0
lines changed

2 files changed

+98
-0
lines changed

src/Meziantou.Analyzer/Rules/UseSystemThreadingLockInsteadOfObjectAnalyzer.cs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,10 @@ private void HandleOperation(ISymbol symbol, IOperation operation)
9999
if (!IsPotentialSymbol(symbol))
100100
return;
101101

102+
// Assignment targets (e.g., initializations in constructors) are not usages
103+
if (operation.Parent is IAssignmentOperation { Target: var assignTarget } && assignTarget == operation)
104+
return;
105+
102106
if (operation.Parent is not ILockOperation)
103107
{
104108
ExcludeSymbol(symbol);

tests/Meziantou.Analyzer.Test/Rules/UseSystemThreadingLockInsteadOfObjectAnalyzerTests.cs

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -260,5 +260,99 @@ void A()
260260
""")
261261
.ValidateAsync();
262262
}
263+
264+
[Fact]
265+
public async Task Field_InitializedInConstructor_OnlyLockUsage()
266+
{
267+
await CreateProjectBuilder()
268+
.WithSourceCode("""
269+
public sealed class A
270+
{
271+
private readonly object [||]_lock;
272+
273+
public A()
274+
{
275+
_lock = new object();
276+
}
277+
278+
public void Run()
279+
{
280+
lock (_lock) { }
281+
}
282+
}
283+
""")
284+
.ValidateAsync();
285+
}
286+
287+
[Fact]
288+
public async Task Field_InitializedInConstructor_LockAndOtherUsages()
289+
{
290+
await CreateProjectBuilder()
291+
.WithSourceCode("""
292+
public sealed class A
293+
{
294+
private readonly object _lock;
295+
296+
public A()
297+
{
298+
_lock = new object();
299+
}
300+
301+
public void Run()
302+
{
303+
lock (_lock) { }
304+
_lock.ToString();
305+
}
306+
}
307+
""")
308+
.ValidateAsync();
309+
}
310+
311+
[Fact]
312+
public async Task StaticField_InitializedInStaticConstructor_OnlyLockUsage()
313+
{
314+
await CreateProjectBuilder()
315+
.WithSourceCode("""
316+
public sealed class B
317+
{
318+
private static readonly object [||]Lock;
319+
320+
static B()
321+
{
322+
Lock = new object();
323+
}
324+
325+
public void Run()
326+
{
327+
lock (Lock) { }
328+
}
329+
}
330+
""")
331+
.ValidateAsync();
332+
}
333+
334+
[Fact]
335+
public async Task StaticField_InitializedInStaticConstructor_LockAndOtherUsages()
336+
{
337+
await CreateProjectBuilder()
338+
.WithSourceCode("""
339+
public sealed class B
340+
{
341+
private static readonly object Lock;
342+
343+
static B()
344+
{
345+
Lock = new object();
346+
}
347+
348+
public void Run()
349+
{
350+
lock (Lock) { }
351+
Lock.ToString();
352+
}
353+
}
354+
""")
355+
.ValidateAsync();
356+
}
263357
#endif
264358
}

0 commit comments

Comments
 (0)