Skip to content

Commit d30d22a

Browse files
committed
Merge remote-tracking branch 'DotNetAnalyzers/master' into static-anonymous
2 parents 775752d + 1c990cc commit d30d22a

File tree

81 files changed

+3441
-156
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

81 files changed

+3441
-156
lines changed

StyleCop.Analyzers/StyleCop.Analyzers.CodeFixes/MaintainabilityRules/SA1407SA1408CodeFixProvider.cs

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ namespace StyleCop.Analyzers.MaintainabilityRules
1414
using Microsoft.CodeAnalysis.CSharp;
1515
using Microsoft.CodeAnalysis.CSharp.Syntax;
1616
using StyleCop.Analyzers.Helpers;
17+
using StyleCop.Analyzers.Lightup;
1718

1819
/// <summary>
1920
/// Implements a code fix for <see cref="SA1407ArithmeticExpressionsMustDeclarePrecedence"/> and <see cref="SA1408ConditionalExpressionsMustDeclarePrecedence"/>.
@@ -59,6 +60,15 @@ public override async Task RegisterCodeFixesAsync(CodeFixContext context)
5960
nameof(SA1407SA1408CodeFixProvider)),
6061
diagnostic);
6162
}
63+
else if (BinaryPatternSyntaxWrapper.IsInstance(node))
64+
{
65+
context.RegisterCodeFix(
66+
CodeAction.Create(
67+
MaintainabilityResources.SA1407SA1408CodeFix,
68+
cancellationToken => GetTransformedDocumentAsync(context.Document, root, (BinaryPatternSyntaxWrapper)node),
69+
nameof(SA1407SA1408CodeFixProvider)),
70+
diagnostic);
71+
}
6272
}
6373
}
6474

@@ -72,5 +82,17 @@ private static Task<Document> GetTransformedDocumentAsync(Document document, Syn
7282

7383
return Task.FromResult(document.WithSyntaxRoot(newSyntaxRoot));
7484
}
85+
86+
private static Task<Document> GetTransformedDocumentAsync(Document document, SyntaxNode root, BinaryPatternSyntaxWrapper syntax)
87+
{
88+
var newNode = (ParenthesizedPatternSyntaxWrapper)SyntaxFactoryEx.ParenthesizedPattern((PatternSyntaxWrapper)syntax.SyntaxNode.WithoutTrivia())
89+
.SyntaxNode
90+
.WithTriviaFrom(syntax)
91+
.WithoutFormatting();
92+
93+
var newSyntaxRoot = root.ReplaceNode(syntax, newNode);
94+
95+
return Task.FromResult(document.WithSyntaxRoot(newSyntaxRoot));
96+
}
7597
}
7698
}

StyleCop.Analyzers/StyleCop.Analyzers.CodeFixes/MaintainabilityRules/SA1407SA1408FixAllProvider.cs

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ namespace StyleCop.Analyzers.MaintainabilityRules
1313
using Microsoft.CodeAnalysis.CSharp;
1414
using Microsoft.CodeAnalysis.CSharp.Syntax;
1515
using StyleCop.Analyzers.Helpers;
16+
using StyleCop.Analyzers.Lightup;
1617

1718
internal sealed class SA1407SA1408FixAllProvider : DocumentBasedFixAllProvider
1819
{
@@ -44,16 +45,26 @@ protected override async Task<SyntaxNode> FixAllInDocumentAsync(FixAllContext fi
4445

4546
private static SyntaxNode AddParentheses(SyntaxNode node)
4647
{
47-
if (!(node is BinaryExpressionSyntax syntax))
48+
if (node is BinaryExpressionSyntax syntax)
4849
{
49-
return node;
50+
BinaryExpressionSyntax trimmedSyntax = syntax.WithoutTrivia();
51+
52+
return SyntaxFactory.ParenthesizedExpression(trimmedSyntax)
53+
.WithTriviaFrom(syntax)
54+
.WithoutFormatting();
5055
}
5156

52-
BinaryExpressionSyntax trimmedSyntax = syntax.WithoutTrivia();
57+
if (BinaryPatternSyntaxWrapper.IsInstance(node))
58+
{
59+
BinaryPatternSyntaxWrapper trimmedSyntax = (BinaryPatternSyntaxWrapper)node.WithoutTrivia();
60+
61+
return SyntaxFactoryEx.ParenthesizedPattern(trimmedSyntax)
62+
.SyntaxNode
63+
.WithTriviaFrom(node)
64+
.WithoutFormatting();
65+
}
5366

54-
return SyntaxFactory.ParenthesizedExpression(trimmedSyntax)
55-
.WithTriviaFrom(syntax)
56-
.WithoutFormatting();
67+
return node;
5768
}
5869
}
5970
}

StyleCop.Analyzers/StyleCop.Analyzers.CodeFixes/ReadabilityRules/SA1121CodeFixProvider.cs

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -66,8 +66,16 @@ private static SyntaxNode ComputeReplacement(SemanticModel semanticModel, Syntax
6666

6767
var type = semanticModel.GetSymbolInfo(node, cancellationToken).Symbol as INamedTypeSymbol;
6868

69-
PredefinedTypeSyntax typeSyntax;
70-
if (!SpecialTypeHelper.TryGetPredefinedType(type.SpecialType, out typeSyntax))
69+
TypeSyntax typeSyntax;
70+
if (SpecialTypeHelper.TryGetPredefinedType(type.SpecialType, out var predefinedType))
71+
{
72+
typeSyntax = predefinedType;
73+
}
74+
else if (type.SpecialType is SpecialType.System_IntPtr or SpecialType.System_UIntPtr)
75+
{
76+
typeSyntax = SyntaxFactory.IdentifierName(type.SpecialType == SpecialType.System_IntPtr ? "nint" : "nuint");
77+
}
78+
else
7179
{
7280
return node;
7381
}

StyleCop.Analyzers/StyleCop.Analyzers.CodeFixes/ReadabilityRules/SA1129CodeFixProvider.cs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,8 @@ private static SyntaxNode GetReplacementNode(Project project, SyntaxNode node, S
7171
var namedTypeSymbol = (symbolInfo.Symbol as IMethodSymbol)?.ContainingType;
7272

7373
var type = GetOrCreateTypeSyntax(project, newExpression, namedTypeSymbol);
74+
bool supportsNativeSizedIntegers = semanticModel.Compilation.SupportsNativeSizedIntegers();
75+
bool usesNativeSizedIntegerKeyword = IsNativeSizedIntegerKeyword(type);
7476

7577
SyntaxNode replacement;
7678

@@ -83,6 +85,12 @@ private static SyntaxNode GetReplacementNode(Project project, SyntaxNode node, S
8385
{
8486
replacement = SyntaxFactory.DefaultExpression(type);
8587
}
88+
else if (!supportsNativeSizedIntegers && usesNativeSizedIntegerKeyword)
89+
{
90+
// nint.Zero and nuint.Zero are only available in C# 11 with .NET 7+. For older versions, we need to
91+
// keep using 'default(nint)'.
92+
replacement = SyntaxFactory.DefaultExpression(type);
93+
}
8694
else
8795
{
8896
string fieldName;
@@ -121,6 +129,11 @@ private static SyntaxNode GetReplacementNode(Project project, SyntaxNode node, S
121129
.WithTrailingTrivia(newExpression.SyntaxNode.GetTrailingTrivia());
122130
}
123131

132+
private static bool IsNativeSizedIntegerKeyword(TypeSyntax type)
133+
{
134+
return type is IdentifierNameSyntax { Identifier.ValueText: "nint" or "nuint" };
135+
}
136+
124137
private static TypeSyntax GetOrCreateTypeSyntax(Project project, BaseObjectCreationExpressionSyntaxWrapper baseObjectCreationExpression, INamedTypeSymbol constructedType)
125138
{
126139
if (baseObjectCreationExpression.SyntaxNode is ObjectCreationExpressionSyntax objectCreationExpressionSyntax)

StyleCop.Analyzers/StyleCop.Analyzers.Test.CSharp11/ReadabilityRules/SA1121CSharp11UnitTests.cs

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ namespace StyleCop.Analyzers.Test.CSharp11.ReadabilityRules
55
{
66
using System.Threading;
77
using System.Threading.Tasks;
8+
using Microsoft.CodeAnalysis.Testing;
89
using StyleCop.Analyzers.Test.CSharp10.ReadabilityRules;
910
using Xunit;
1011

@@ -64,5 +65,54 @@ class TestClass
6465
FixedSources = { newSource },
6566
}.RunAsync(CancellationToken.None).ConfigureAwait(false);
6667
}
68+
69+
[Fact]
70+
[WorkItem(3969, "https://github.com/DotNetAnalyzers/StyleCopAnalyzers/issues/3969")]
71+
public async Task TestNativeSizedIntegersReportWithNet70Async()
72+
{
73+
var testCode = @"
74+
using System;
75+
76+
class TestClass
77+
{
78+
[|IntPtr|] field1;
79+
[|System.UIntPtr|] field2;
80+
}";
81+
82+
var fixedCode = @"
83+
using System;
84+
85+
class TestClass
86+
{
87+
nint field1;
88+
nuint field2;
89+
}";
90+
91+
await new CSharpTest
92+
{
93+
TestCode = testCode,
94+
FixedCode = fixedCode,
95+
}.RunAsync(CancellationToken.None).ConfigureAwait(false);
96+
}
97+
98+
[Fact]
99+
[WorkItem(3969, "https://github.com/DotNetAnalyzers/StyleCopAnalyzers/issues/3969")]
100+
public async Task TestNativeSizedIntegersDoNotReportWithNet60Async()
101+
{
102+
var testCode = @"
103+
using System;
104+
105+
class TestClass
106+
{
107+
IntPtr field1;
108+
System.UIntPtr field2;
109+
}";
110+
111+
await new CSharpTest
112+
{
113+
ReferenceAssemblies = ReferenceAssemblies.Net.Net60,
114+
TestCode = testCode,
115+
}.RunAsync(CancellationToken.None).ConfigureAwait(false);
116+
}
67117
}
68118
}

StyleCop.Analyzers/StyleCop.Analyzers.Test.CSharp11/ReadabilityRules/SA1129CSharp11UnitTests.cs

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

44
namespace StyleCop.Analyzers.Test.CSharp11.ReadabilityRules
55
{
6+
using System.Threading;
7+
using System.Threading.Tasks;
8+
using Microsoft.CodeAnalysis.Testing;
69
using StyleCop.Analyzers.Test.CSharp10.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 partial class SA1129CSharp11UnitTests : SA1129CSharp10UnitTests
916
{
17+
[Fact]
18+
[WorkItem(3969, "https://github.com/DotNetAnalyzers/StyleCopAnalyzers/issues/3969")]
19+
public async Task VerifyNativeSizedIntegerCreationWithNet70Async()
20+
{
21+
var testCode = @"
22+
using System;
23+
24+
class TestClass
25+
{
26+
void TestMethod()
27+
{
28+
nint nativeInt = [|new nint()|];
29+
nuint nativeUInt = [|new nuint()|];
30+
}
31+
}";
32+
33+
var fixedCode = @"
34+
using System;
35+
36+
class TestClass
37+
{
38+
void TestMethod()
39+
{
40+
nint nativeInt = nint.Zero;
41+
nuint nativeUInt = nuint.Zero;
42+
}
43+
}";
44+
45+
await VerifyCSharpFixAsync(testCode, DiagnosticResult.EmptyDiagnosticResults, fixedCode, CancellationToken.None).ConfigureAwait(false);
46+
}
47+
48+
[Fact]
49+
[WorkItem(3969, "https://github.com/DotNetAnalyzers/StyleCopAnalyzers/issues/3969")]
50+
public async Task VerifyNativeSizedIntegerCreationWithNet60Async()
51+
{
52+
var testCode = @"
53+
using System;
54+
55+
class TestClass
56+
{
57+
void TestMethod()
58+
{
59+
nint nativeInt = [|new nint()|];
60+
nuint nativeUInt = [|new nuint()|];
61+
}
62+
}";
63+
64+
var fixedCode = @"
65+
using System;
66+
67+
class TestClass
68+
{
69+
void TestMethod()
70+
{
71+
nint nativeInt = default(nint);
72+
nuint nativeUInt = default(nuint);
73+
}
74+
}";
75+
76+
await new CSharpTest
77+
{
78+
ReferenceAssemblies = ReferenceAssemblies.Net.Net60,
79+
TestCode = testCode,
80+
FixedCode = fixedCode,
81+
}.RunAsync(CancellationToken.None).ConfigureAwait(false);
82+
}
1083
}
1184
}

StyleCop.Analyzers/StyleCop.Analyzers.Test.CSharp9/DocumentationRules/SA1611CSharp9UnitTests.cs

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,5 +37,24 @@ public async Task TestPrimaryRecordConstructorIncludeMissingParametersAsync(stri
3737

3838
await VerifyCSharpDiagnosticAsync(testCode, DiagnosticResult.EmptyDiagnosticResults, CancellationToken.None).ConfigureAwait(false);
3939
}
40+
41+
[Fact]
42+
[WorkItem(3977, "https://github.com/DotNetAnalyzers/StyleCopAnalyzers/issues/3977")]
43+
public async Task TestLambdaDiscardParametersAsync()
44+
{
45+
var testCode = @"
46+
/// <summary>Test class.</summary>
47+
public class TestClass
48+
{
49+
/// <summary>Test method.</summary>
50+
public void TestMethod()
51+
{
52+
System.Func<int, int, int> handler = (_, _) => 0;
53+
}
54+
}
55+
";
56+
57+
await VerifyCSharpDiagnosticAsync(testCode, DiagnosticResult.EmptyDiagnosticResults, CancellationToken.None).ConfigureAwait(false);
58+
}
4059
}
4160
}

StyleCop.Analyzers/StyleCop.Analyzers.Test.CSharp9/DocumentationRules/SA1612CSharp9UnitTests.cs

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

44
namespace StyleCop.Analyzers.Test.CSharp9.DocumentationRules
55
{
6+
using System.Threading;
7+
using System.Threading.Tasks;
8+
using Microsoft.CodeAnalysis.Testing;
69
using StyleCop.Analyzers.Test.CSharp8.DocumentationRules;
10+
using Xunit;
711

812
public partial class SA1612CSharp9UnitTests : SA1612CSharp8UnitTests
913
{
14+
[Fact]
15+
[WorkItem(3977, "https://github.com/DotNetAnalyzers/StyleCopAnalyzers/issues/3977")]
16+
public async Task TestLambdaDiscardParametersAsync()
17+
{
18+
var testCode = @"
19+
/// <summary>Test class.</summary>
20+
public class TestClass
21+
{
22+
/// <summary>Test method.</summary>
23+
public void TestMethod()
24+
{
25+
System.Func<int, int, int> handler = (_, _) => 0;
26+
}
27+
}
28+
";
29+
30+
await VerifyCSharpDiagnosticAsync(testCode, DiagnosticResult.EmptyDiagnosticResults, CancellationToken.None).ConfigureAwait(false);
31+
}
1032
}
1133
}

0 commit comments

Comments
 (0)