Skip to content

Commit ae5a375

Browse files
authored
Merge branch 'main' into feature/remove-legacy-options
2 parents 1171f2f + 2354f1f commit ae5a375

15 files changed

+240
-57
lines changed

ChangeLog.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
77

88
## [Unreleased]
99

10+
### Fixed
11+
12+
- Fix analyzer [RCS0034](https://josefpihrt.github.io/docs/roslynator/analyzers/RCS0034) ([PR](https://github.com/dotnet/roslynator/pull/1351))
13+
- Fix analyzer [RCS0023](https://josefpihrt.github.io/docs/roslynator/analyzers/RCS0023) ([PR](https://github.com/dotnet/roslynator/pull/1352))
14+
- Fix analyzer [RCS1014](https://josefpihrt.github.io/docs/roslynator/analyzers/RCS1014) ([PR](https://github.com/dotnet/roslynator/pull/1350))
15+
1016
## [4.8.0] - 2024-01-02
1117

1218
### Added

src/Analyzers.CodeFixes/CSharp/CodeFixes/UseExplicitlyOrImplicitlyTypedArrayCodeFixProvider.cs

Lines changed: 28 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,11 @@ public override async Task RegisterCodeFixesAsync(CodeFixContext context)
100100
}
101101
else if (node is ImplicitArrayCreationExpressionSyntax implicitArrayCreation)
102102
{
103-
if (diagnostic.Properties.ContainsKey(DiagnosticPropertyKeys.ImplicitToCollectionExpression))
103+
if (diagnostic.Properties.ContainsKey(DiagnosticPropertyKeys.VarToExplicit))
104+
{
105+
return (ct => ConvertToExplicitAndUseVarAsync(document, implicitArrayCreation, ct), UseCollectionExpressionTitle);
106+
}
107+
else if (diagnostic.Properties.ContainsKey(DiagnosticPropertyKeys.ImplicitToCollectionExpression))
104108
{
105109
return (ct => ConvertToCollectionExpressionAsync(document, implicitArrayCreation, ct), UseCollectionExpressionTitle);
106110
}
@@ -130,6 +134,28 @@ private static async Task<Document> ConvertToExplicitAsync(
130134
Document document,
131135
ImplicitArrayCreationExpressionSyntax implicitArrayCreation,
132136
CancellationToken cancellationToken)
137+
{
138+
ArrayCreationExpressionSyntax newNode = await CreateArrayCreationAsync(document, implicitArrayCreation, cancellationToken).ConfigureAwait(false);
139+
140+
return await document.ReplaceNodeAsync(implicitArrayCreation, newNode, cancellationToken).ConfigureAwait(false);
141+
}
142+
143+
private static async Task<Document> ConvertToExplicitAndUseVarAsync(
144+
Document document,
145+
ImplicitArrayCreationExpressionSyntax implicitArrayCreation,
146+
CancellationToken cancellationToken)
147+
{
148+
ArrayCreationExpressionSyntax arrayCreation = await CreateArrayCreationAsync(document, implicitArrayCreation, cancellationToken).ConfigureAwait(false);
149+
150+
VariableDeclarationSyntax variableDeclaration = implicitArrayCreation.FirstAncestor<VariableDeclarationSyntax>();
151+
152+
VariableDeclarationSyntax newVariableDeclaration = variableDeclaration.ReplaceNode(implicitArrayCreation, arrayCreation)
153+
.WithType(CSharpFactory.VarType().WithTriviaFrom(variableDeclaration.Type));
154+
155+
return await document.ReplaceNodeAsync(variableDeclaration, newVariableDeclaration, cancellationToken).ConfigureAwait(false);
156+
}
157+
158+
private static async Task<ArrayCreationExpressionSyntax> CreateArrayCreationAsync(Document document, ImplicitArrayCreationExpressionSyntax implicitArrayCreation, CancellationToken cancellationToken)
133159
{
134160
SemanticModel semanticModel = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false);
135161
ITypeSymbol typeSymbol = semanticModel.GetTypeSymbol(implicitArrayCreation, cancellationToken);
@@ -146,14 +172,12 @@ private static async Task<Document> ConvertToExplicitAsync(
146172
initializer.Expressions,
147173
(node, _) => (node.IsKind(SyntaxKind.CastExpression)) ? node.WithSimplifierAnnotation() : node);
148174

149-
ArrayCreationExpressionSyntax newNode = ArrayCreationExpression(
175+
return ArrayCreationExpression(
150176
newKeyword,
151177
arrayType
152178
.WithLeadingTrivia(implicitArrayCreation.OpenBracketToken.LeadingTrivia)
153179
.WithTrailingTrivia(implicitArrayCreation.CloseBracketToken.TrailingTrivia),
154180
newInitializer);
155-
156-
return await document.ReplaceNodeAsync(implicitArrayCreation, newNode, cancellationToken).ConfigureAwait(false);
157181
}
158182

159183
private static async Task<Document> ConvertToExplicitAsync(

src/Analyzers.CodeFixes/CSharp/CodeFixes/UseImplicitOrExplicitObjectCreationCodeFixProvider.cs

Lines changed: 32 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -42,8 +42,7 @@ public sealed override async Task RegisterCodeFixesAsync(CodeFixContext context)
4242
predicate: f => f.IsKind(
4343
SyntaxKind.ObjectCreationExpression,
4444
SyntaxKind.ImplicitObjectCreationExpression,
45-
SyntaxKind.CollectionExpression,
46-
SyntaxKind.VariableDeclaration)))
45+
SyntaxKind.CollectionExpression)))
4746
{
4847
return;
4948
}
@@ -97,7 +96,37 @@ public sealed override async Task RegisterCodeFixesAsync(CodeFixContext context)
9796
}
9897
else if (node is ImplicitObjectCreationExpressionSyntax implicitObjectCreation)
9998
{
100-
if (diagnostic.Properties.ContainsKey(DiagnosticPropertyKeys.ImplicitToCollectionExpression))
99+
if (diagnostic.Properties.ContainsKey(DiagnosticPropertyKeys.VarToExplicit))
100+
{
101+
VariableDeclarationSyntax variableDeclaration = node.FirstAncestor<VariableDeclarationSyntax>();
102+
103+
CodeAction codeAction = CodeAction.Create(
104+
UseExplicitObjectCreationTitle,
105+
ct =>
106+
{
107+
var implicitObjectCreation = (ImplicitObjectCreationExpressionSyntax)variableDeclaration.Variables.Single().Initializer.Value;
108+
109+
SyntaxToken newKeyword = implicitObjectCreation.NewKeyword;
110+
111+
if (!newKeyword.TrailingTrivia.Any())
112+
newKeyword = newKeyword.WithTrailingTrivia(ElasticSpace);
113+
114+
ObjectCreationExpressionSyntax objectCreation = ObjectCreationExpression(
115+
newKeyword,
116+
variableDeclaration.Type.WithoutTrivia(),
117+
implicitObjectCreation.ArgumentList,
118+
implicitObjectCreation.Initializer);
119+
120+
VariableDeclarationSyntax newVariableDeclaration = variableDeclaration.ReplaceNode(implicitObjectCreation, objectCreation)
121+
.WithType(CSharpFactory.VarType().WithTriviaFrom(variableDeclaration.Type));
122+
123+
return document.ReplaceNodeAsync(variableDeclaration, newVariableDeclaration, ct);
124+
},
125+
GetEquivalenceKey(diagnostic));
126+
127+
context.RegisterCodeFix(codeAction, diagnostic);
128+
}
129+
else if (diagnostic.Properties.ContainsKey(DiagnosticPropertyKeys.ImplicitToCollectionExpression))
101130
{
102131
CodeAction codeAction = CodeAction.Create(
103132
UseCollectionExpressionTitle,
@@ -199,35 +228,5 @@ public sealed override async Task RegisterCodeFixesAsync(CodeFixContext context)
199228
context.RegisterCodeFix(codeAction, diagnostic);
200229
}
201230
}
202-
else
203-
{
204-
var variableDeclaration = (VariableDeclarationSyntax)node;
205-
206-
CodeAction codeAction = CodeAction.Create(
207-
UseExplicitObjectCreationTitle,
208-
ct =>
209-
{
210-
var implicitObjectCreation = (ImplicitObjectCreationExpressionSyntax)variableDeclaration.Variables.Single().Initializer.Value;
211-
212-
SyntaxToken newKeyword = implicitObjectCreation.NewKeyword;
213-
214-
if (!newKeyword.TrailingTrivia.Any())
215-
newKeyword = newKeyword.WithTrailingTrivia(ElasticSpace);
216-
217-
ObjectCreationExpressionSyntax objectCreation = ObjectCreationExpression(
218-
newKeyword,
219-
variableDeclaration.Type.WithoutTrivia(),
220-
implicitObjectCreation.ArgumentList,
221-
implicitObjectCreation.Initializer);
222-
223-
VariableDeclarationSyntax newVariableDeclaration = variableDeclaration.ReplaceNode(implicitObjectCreation, objectCreation)
224-
.WithType(CSharpFactory.VarType().WithTriviaFrom(variableDeclaration.Type));
225-
226-
return document.ReplaceNodeAsync(variableDeclaration, newVariableDeclaration, ct);
227-
},
228-
GetEquivalenceKey(diagnostic));
229-
230-
context.RegisterCodeFix(codeAction, diagnostic);
231-
}
232231
}
233232
}

src/Analyzers/CSharp/Analysis/ObjectCreation/ImplicitOrExplicitCreationAnalysis.cs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,11 @@ internal abstract class ImplicitOrExplicitCreationAnalysis
2929
new KeyValuePair<string, string>(DiagnosticPropertyKeys.ExplicitToCollectionExpression, null)
3030
});
3131

32+
protected static readonly ImmutableDictionary<string, string> _varToExplicit = ImmutableDictionary.CreateRange(new[]
33+
{
34+
new KeyValuePair<string, string>(DiagnosticPropertyKeys.VarToExplicit, null)
35+
});
36+
3237
public abstract TypeStyle GetTypeStyle(ref SyntaxNodeAnalysisContext context);
3338

3439
protected abstract void ReportExplicitToImplicit(ref SyntaxNodeAnalysisContext context);
@@ -37,6 +42,8 @@ internal abstract class ImplicitOrExplicitCreationAnalysis
3742

3843
protected abstract void ReportImplicitToExplicit(ref SyntaxNodeAnalysisContext context);
3944

45+
protected abstract void ReportVarToExplicit(ref SyntaxNodeAnalysisContext context, TypeSyntax type);
46+
4047
protected abstract void ReportImplicitToCollectionExpression(ref SyntaxNodeAnalysisContext context);
4148

4249
protected abstract void ReportCollectionExpressionToImplicit(ref SyntaxNodeAnalysisContext context);
@@ -343,7 +350,7 @@ private void AnalyzeImplicit(ref SyntaxNodeAnalysisContext context)
343350
&& !isVar
344351
&& context.UseVarInsteadOfImplicitObjectCreation() == true)
345352
{
346-
DiagnosticHelpers.ReportDiagnostic(context, DiagnosticRules.UseImplicitOrExplicitObjectCreation, variableDeclaration, "explicit");
353+
ReportVarToExplicit(ref context, variableDeclaration.Type);
347354
}
348355
}
349356
}

src/Analyzers/CSharp/Analysis/ObjectCreation/ImplicitOrExpressionArrayCreationAnalysis.cs

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -343,6 +343,29 @@ protected override void ReportImplicitToExplicit(ref SyntaxNodeAnalysisContext c
343343
"Use explicitly typed array");
344344
}
345345

346+
protected override void ReportVarToExplicit(ref SyntaxNodeAnalysisContext context, TypeSyntax type)
347+
{
348+
if (context.Node.IsKind(SyntaxKind.CollectionExpression))
349+
return;
350+
351+
ITypeSymbol typeSymbol = context.SemanticModel.GetTypeSymbol(type, context.CancellationToken);
352+
353+
if (typeSymbol?.IsErrorType() != false)
354+
return;
355+
356+
ITypeSymbol expressionTypeSymbol = context.SemanticModel.GetTypeSymbol(context.Node, context.CancellationToken);
357+
358+
if (!SymbolEqualityComparer.IncludeNullability.Equals(typeSymbol, expressionTypeSymbol))
359+
return;
360+
361+
DiagnosticHelpers.ReportDiagnostic(
362+
context,
363+
DiagnosticRules.UseExplicitlyOrImplicitlyTypedArray,
364+
GetLocationFromImplicit(ref context),
365+
properties: _varToExplicit,
366+
"Use explicitly typed array");
367+
}
368+
346369
protected override void ReportImplicitToCollectionExpression(ref SyntaxNodeAnalysisContext context)
347370
{
348371
DiagnosticHelpers.ReportDiagnostic(

src/Analyzers/CSharp/Analysis/ObjectCreation/ImplicitOrExpressionObjectCreationAnalysis.cs

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ protected override void ReportExplicitToImplicit(ref SyntaxNodeAnalysisContext c
2929
context,
3030
DiagnosticRules.UseImplicitOrExplicitObjectCreation,
3131
objectCreation.Type.GetLocation(),
32-
"Simplify array creation");
32+
"Simplify object creation");
3333
}
3434

3535
protected override void ReportExplicitToCollectionExpression(ref SyntaxNodeAnalysisContext context)
@@ -41,7 +41,7 @@ protected override void ReportExplicitToCollectionExpression(ref SyntaxNodeAnaly
4141
DiagnosticRules.UseImplicitOrExplicitObjectCreation,
4242
objectCreation.Type.GetLocation(),
4343
properties: _explicitToCollectionExpression,
44-
"Simplify array creation");
44+
"Simplify object creation");
4545
}
4646

4747
protected override void ReportImplicitToExplicit(ref SyntaxNodeAnalysisContext context)
@@ -53,14 +53,24 @@ protected override void ReportImplicitToExplicit(ref SyntaxNodeAnalysisContext c
5353
"Use explicit object creation");
5454
}
5555

56+
protected override void ReportVarToExplicit(ref SyntaxNodeAnalysisContext context, TypeSyntax type)
57+
{
58+
DiagnosticHelpers.ReportDiagnostic(
59+
context,
60+
DiagnosticRules.UseImplicitOrExplicitObjectCreation,
61+
context.Node.GetLocation(),
62+
properties: _varToExplicit,
63+
"Use explicit object creation");
64+
}
65+
5666
protected override void ReportImplicitToCollectionExpression(ref SyntaxNodeAnalysisContext context)
5767
{
5868
DiagnosticHelpers.ReportDiagnostic(
5969
context,
6070
DiagnosticRules.UseImplicitOrExplicitObjectCreation,
6171
context.Node.GetLocation(),
6272
properties: _implicitToCollectionExpression,
63-
"Simplify array creation");
73+
"Simplify object creation");
6474
}
6575

6676
protected override void ReportCollectionExpressionToImplicit(ref SyntaxNodeAnalysisContext context)
@@ -70,6 +80,6 @@ protected override void ReportCollectionExpressionToImplicit(ref SyntaxNodeAnaly
7080
DiagnosticRules.UseImplicitOrExplicitObjectCreation,
7181
context.Node.GetLocation(),
7282
properties: _collectionExpressionToImplicit,
73-
"Simplify array creation");
83+
"Simplify object creation");
7484
}
7585
}

src/Common/CSharp/Analysis/DiagnosticPropertyKeys.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,4 +7,5 @@ internal static class DiagnosticPropertyKeys
77
internal static readonly string ImplicitToCollectionExpression = nameof(ImplicitToCollectionExpression);
88
internal static readonly string CollectionExpressionToImplicit = nameof(CollectionExpressionToImplicit);
99
internal static readonly string ExplicitToCollectionExpression = nameof(ExplicitToCollectionExpression);
10+
internal static readonly string VarToExplicit = nameof(VarToExplicit);
1011
}

src/Common/ConfigOptions.Generated.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -236,7 +236,7 @@ public static partial class ConfigOptions
236236
key: ConfigOptionKeys.UseVar,
237237
defaultValue: null,
238238
defaultValuePlaceholder: "always|never|when_type_is_obvious",
239-
description: "Use 'var' insted of explicit type");
239+
description: "Use 'var' instead of explicit type");
240240

241241
public static readonly ConfigOptionDescriptor UseVarInsteadOfImplicitObjectCreation = new(
242242
key: ConfigOptionKeys.UseVarInsteadOfImplicitObjectCreation,

src/ConfigOptions.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -230,7 +230,7 @@
230230
<Description>Use collection expression for array/collection creation</Description>
231231
</Option>
232232
<Option Id="UseVar">
233-
<Description>Use 'var' insted of explicit type</Description>
233+
<Description>Use 'var' instead of explicit type</Description>
234234
<Values>
235235
<Value>always</Value>
236236
<Value>never</Value>

src/Formatting.Analyzers/CSharp/FormatTypeDeclarationBracesAnalyzer.cs

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -43,15 +43,26 @@ private static void AnalyzeTypeDeclaration(SyntaxNodeAnalysisContext context)
4343

4444
SyntaxToken openBrace = typeDeclaration.OpenBraceToken;
4545

46-
if (openBrace.IsMissing)
46+
if (openBrace.IsKind(SyntaxKind.None)
47+
|| openBrace.IsMissing)
48+
{
4749
return;
50+
}
4851

49-
if (!typeDeclaration.SyntaxTree.IsSingleLineSpan(TextSpan.FromBounds(openBrace.Span.End, openBrace.GetNextToken().SpanStart)))
52+
SyntaxToken closeBrace = typeDeclaration.CloseBraceToken;
53+
54+
if (closeBrace.IsKind(SyntaxKind.None)
55+
|| closeBrace.IsMissing)
56+
{
5057
return;
58+
}
5159

52-
DiagnosticHelpers.ReportDiagnostic(
53-
context,
54-
DiagnosticRules.FormatTypeDeclarationBraces,
55-
openBrace);
60+
if (typeDeclaration.SyntaxTree.IsSingleLineSpan(TextSpan.FromBounds(openBrace.SpanStart, closeBrace.SpanStart)))
61+
{
62+
DiagnosticHelpers.ReportDiagnostic(
63+
context,
64+
DiagnosticRules.FormatTypeDeclarationBraces,
65+
openBrace);
66+
}
5667
}
5768
}

0 commit comments

Comments
 (0)