Skip to content

Commit 88d9d3f

Browse files
authored
Merge pull request #3432 from sharwell/parameterless-ctor
Allow direct use of explicit parameterless constructors
2 parents 9559e1d + e2b9296 commit 88d9d3f

File tree

3 files changed

+141
-0
lines changed

3 files changed

+141
-0
lines changed

StyleCop.Analyzers/StyleCop.Analyzers.Test.CSharp10/ReadabilityRules/SA1129CSharp10UnitTests.cs

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,89 @@
33

44
namespace StyleCop.Analyzers.Test.CSharp10.ReadabilityRules
55
{
6+
using System.Threading;
7+
using System.Threading.Tasks;
8+
using Microsoft.CodeAnalysis.Testing;
69
using StyleCop.Analyzers.Test.CSharp9.ReadabilityRules;
10+
using Xunit;
11+
using static StyleCop.Analyzers.Test.Verifiers.StyleCopCodeFixVerifier<
12+
StyleCop.Analyzers.ReadabilityRules.SA1129DoNotUseDefaultValueTypeConstructor,
13+
StyleCop.Analyzers.ReadabilityRules.SA1129CodeFixProvider>;
714

815
public class SA1129CSharp10UnitTests : SA1129CSharp9UnitTests
916
{
17+
[Fact]
18+
[WorkItem(3430, "https://github.com/DotNetAnalyzers/StyleCopAnalyzers/issues/3430")]
19+
public async Task VerifyParameterlessStructConstructorAsync()
20+
{
21+
var testCode = @"struct S
22+
{
23+
public S() { }
24+
25+
internal static S F1()
26+
{
27+
S s = new S();
28+
return s;
29+
}
30+
31+
internal static S F2()
32+
{
33+
S s = new();
34+
return s;
35+
}
36+
37+
internal static S F3() => new S();
38+
39+
internal static S F4() => new();
40+
}
41+
";
42+
43+
await VerifyCSharpFixAsync(testCode, DiagnosticResult.EmptyDiagnosticResults, testCode, CancellationToken.None).ConfigureAwait(false);
44+
}
45+
46+
[Fact]
47+
[WorkItem(3430, "https://github.com/DotNetAnalyzers/StyleCopAnalyzers/issues/3430")]
48+
public async Task VerifyParameterlessStructConstructorInMetadataAsync()
49+
{
50+
await new CSharpTest
51+
{
52+
TestState =
53+
{
54+
Sources =
55+
{
56+
@"class B
57+
{
58+
internal static S F1()
59+
{
60+
S s = new S();
61+
return s;
62+
}
63+
64+
internal static S F2()
65+
{
66+
S s = new();
67+
return s;
68+
}
69+
70+
internal static S F3() => new S();
71+
72+
internal static S F4() => new();
73+
}
74+
",
75+
},
76+
AdditionalProjects =
77+
{
78+
["Reference"] =
79+
{
80+
Sources =
81+
{
82+
@"public struct S { public S() { } }",
83+
},
84+
},
85+
},
86+
AdditionalProjectReferences = { "Reference" },
87+
},
88+
}.RunAsync(CancellationToken.None).ConfigureAwait(false);
89+
}
1090
}
1191
}

StyleCop.Analyzers/StyleCop.Analyzers.Test/ReadabilityRules/SA1129UnitTests.cs

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,61 @@ private struct TestStruct
127127
await VerifyCSharpFixAsync(testCode, expected, fixedTestCode, CancellationToken.None).ConfigureAwait(false);
128128
}
129129

130+
[Fact]
131+
public async Task VerifyInvalidValueTypeCreationFromMetadataAsync()
132+
{
133+
var testCode = @"public class TestClass
134+
{
135+
public void TestMethod()
136+
{
137+
var v1 = [|new TestStruct()|];
138+
139+
System.Console.WriteLine([|new TestStruct()|]);
140+
}
141+
}
142+
";
143+
144+
var fixedTestCode = @"public class TestClass
145+
{
146+
public void TestMethod()
147+
{
148+
var v1 = default(TestStruct);
149+
150+
System.Console.WriteLine(default(TestStruct));
151+
}
152+
}
153+
";
154+
155+
DiagnosticResult[] expected =
156+
{
157+
Diagnostic().WithLocation(0),
158+
Diagnostic().WithLocation(1),
159+
};
160+
161+
await new CSharpTest
162+
{
163+
TestState =
164+
{
165+
Sources = { testCode },
166+
AdditionalProjects =
167+
{
168+
["Reference"] =
169+
{
170+
Sources =
171+
{
172+
@"public struct TestStruct { public int TestProperty { get; set; } }",
173+
},
174+
},
175+
},
176+
AdditionalProjectReferences = { "Reference" },
177+
},
178+
FixedState =
179+
{
180+
Sources = { fixedTestCode },
181+
},
182+
}.RunAsync(CancellationToken.None).ConfigureAwait(false);
183+
}
184+
130185
/// <summary>
131186
/// Verifies that the codefix will preserve surrounding trivia.
132187
/// </summary>

StyleCop.Analyzers/StyleCop.Analyzers/ReadabilityRules/SA1129DoNotUseDefaultValueTypeConstructor.cs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,12 @@ private static void HandleObjectCreationOperation(OperationAnalysisContext conte
7070
return;
7171
}
7272

73+
if (!objectCreation.Constructor.IsImplicitlyDeclared)
74+
{
75+
// The value type includes an explicit parameterless constructor
76+
return;
77+
}
78+
7379
if (objectCreation.Initializer.WrappedOperation != null)
7480
{
7581
return;

0 commit comments

Comments
 (0)