From 5d8681784c2231d49f811bc97a295f97fc936fa0 Mon Sep 17 00:00:00 2001 From: Josef Pihrt Date: Thu, 2 Jun 2022 23:53:32 +0200 Subject: [PATCH 1/3] Add case --- src/CSharp/CSharp/Extensions/SyntaxExtensions.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/CSharp/CSharp/Extensions/SyntaxExtensions.cs b/src/CSharp/CSharp/Extensions/SyntaxExtensions.cs index f7506745e0..2f74b216ea 100644 --- a/src/CSharp/CSharp/Extensions/SyntaxExtensions.cs +++ b/src/CSharp/CSharp/Extensions/SyntaxExtensions.cs @@ -3229,6 +3229,7 @@ public static bool IsInExpressionTree( #if DEBUG case SyntaxKind.Argument: case SyntaxKind.ArgumentList: + case SyntaxKind.ArrayRankSpecifier: case SyntaxKind.EqualsValueClause: case SyntaxKind.Interpolation: case SyntaxKind.SwitchExpressionArm: From f4834a959df84a4b768b3db755068ff63e72b851 Mon Sep 17 00:00:00 2001 From: Josef Pihrt Date: Thu, 2 Jun 2022 23:57:45 +0200 Subject: [PATCH 2/3] Convert more syntax to implicit object creation --- ...mplicitOrExplicitObjectCreationAnalyzer.cs | 55 +++++++++++++++++-- ...seImplicitOrExplicitObjectCreationTests.cs | 54 ++++++++++++++++++ 2 files changed, 103 insertions(+), 6 deletions(-) diff --git a/src/Analyzers/CSharp/Analysis/UseImplicitOrExplicitObjectCreationAnalyzer.cs b/src/Analyzers/CSharp/Analysis/UseImplicitOrExplicitObjectCreationAnalyzer.cs index 985cd07220..59e8794084 100644 --- a/src/Analyzers/CSharp/Analysis/UseImplicitOrExplicitObjectCreationAnalyzer.cs +++ b/src/Analyzers/CSharp/Analysis/UseImplicitOrExplicitObjectCreationAnalyzer.cs @@ -121,14 +121,42 @@ private static void AnalyzeObjectCreationExpression(SyntaxNodeAnalysisContext co } case SyntaxKind.ArrayInitializerExpression: { - SyntaxDebug.Assert(parent.IsParentKind(SyntaxKind.ArrayCreationExpression, SyntaxKind.ImplicitArrayCreationExpression), parent.Parent); + SyntaxDebug.Assert(parent.IsParentKind(SyntaxKind.ArrayCreationExpression, SyntaxKind.ImplicitArrayCreationExpression, SyntaxKind.EqualsValueClause), parent.Parent); - if (UseImplicitObjectCreation(context) - && parent.IsParentKind(SyntaxKind.ArrayCreationExpression)) + if (UseImplicitObjectCreation(context)) { - var arrayCreationExpression = (ArrayCreationExpressionSyntax)parent.Parent; + if (parent.IsParentKind(SyntaxKind.ArrayCreationExpression)) + { + var arrayCreationExpression = (ArrayCreationExpressionSyntax)parent.Parent; + + AnalyzeType(context, objectCreation, arrayCreationExpression.Type.ElementType); + } + else if (parent.IsParentKind(SyntaxKind.EqualsValueClause)) + { + parent = parent.Parent.Parent; + + if (parent.IsKind(SyntaxKind.VariableDeclarator)) + { + parent = parent.Parent; - AnalyzeType(context, objectCreation, arrayCreationExpression.Type.ElementType); + if (parent is VariableDeclarationSyntax variableDeclaration) + { + if (parent.IsParentKind(SyntaxKind.FieldDeclaration)) + { + AnalyzeArrayType(context, objectCreation, variableDeclaration.Type); + } + else if (parent.IsParentKind(SyntaxKind.LocalDeclarationStatement, SyntaxKind.UsingStatement)) + { + if (!variableDeclaration.Type.IsVar) + AnalyzeArrayType(context, objectCreation, variableDeclaration.Type); + } + } + } + else if (parent.IsKind(SyntaxKind.PropertyDeclaration)) + { + AnalyzeArrayType(context, objectCreation, ((PropertyDeclarationSyntax)parent).Type); + } + } } break; @@ -316,7 +344,7 @@ private void AnalyzeImplicitObjectCreationExpression(SyntaxNodeAnalysisContext c } case SyntaxKind.ArrayInitializerExpression: { - SyntaxDebug.Assert(parent.IsParentKind(SyntaxKind.ArrayCreationExpression, SyntaxKind.ImplicitArrayCreationExpression), parent.Parent); + SyntaxDebug.Assert(parent.IsParentKind(SyntaxKind.ArrayCreationExpression, SyntaxKind.ImplicitArrayCreationExpression, SyntaxKind.EqualsValueClause), parent.Parent); if (UseExplicitObjectCreation(context) && parent.IsParentKind(SyntaxKind.ArrayCreationExpression)) @@ -450,6 +478,21 @@ private static void AnalyzeType( } } + private static void AnalyzeArrayType( + SyntaxNodeAnalysisContext context, + ObjectCreationExpressionSyntax objectCreation, + TypeSyntax type, + bool isGenericType = false) + { + if (type is ArrayTypeSyntax arrayType) + { + type = arrayType.ElementType; + + if (!type.IsVar) + AnalyzeExpression(context, objectCreation, type, isGenericType: isGenericType); + } + } + private static void AnalyzeExpression( SyntaxNodeAnalysisContext context, ObjectCreationExpressionSyntax objectCreation, diff --git a/src/Tests/Analyzers.Tests/RCS1250UseImplicitOrExplicitObjectCreationTests.cs b/src/Tests/Analyzers.Tests/RCS1250UseImplicitOrExplicitObjectCreationTests.cs index 756ce83a3c..7dea0a854e 100644 --- a/src/Tests/Analyzers.Tests/RCS1250UseImplicitOrExplicitObjectCreationTests.cs +++ b/src/Tests/Analyzers.Tests/RCS1250UseImplicitOrExplicitObjectCreationTests.cs @@ -799,6 +799,60 @@ void M() ", options: Options.AddConfigOption(ConfigOptionKeys.ObjectCreationTypeStyle, ConfigOptionValues.ObjectCreationTypeStyle_ImplicitWhenTypeIsObvious)); } + [Fact, Trait(Traits.Analyzer, DiagnosticIdentifiers.UseImplicitOrExplicitObjectCreation)] + public async Task Test_PreferImplicitWhenTypeIsObvious_ArrayInitializerInFieldInitializer() + { + await VerifyDiagnosticAndFixAsync(@" +class C +{ + public string[] f = { new [|string|](' ', 0) }; +} +", @" +class C +{ + public string[] f = { new(' ', 0) }; +} +", options: Options.AddConfigOption(ConfigOptionKeys.ObjectCreationTypeStyle, ConfigOptionValues.ObjectCreationTypeStyle_ImplicitWhenTypeIsObvious)); + } + + [Fact, Trait(Traits.Analyzer, DiagnosticIdentifiers.UseImplicitOrExplicitObjectCreation)] + public async Task Test_PreferImplicitWhenTypeIsObvious_ArrayInitializerInPropertyInitializer() + { + await VerifyDiagnosticAndFixAsync(@" +class C +{ + public string[] P { get; } = { new [|string|](' ', 0) }; +} +", @" +class C +{ + public string[] P { get; } = { new(' ', 0) }; +} +", options: Options.AddConfigOption(ConfigOptionKeys.ObjectCreationTypeStyle, ConfigOptionValues.ObjectCreationTypeStyle_ImplicitWhenTypeIsObvious)); + } + + [Fact, Trait(Traits.Analyzer, DiagnosticIdentifiers.UseImplicitOrExplicitObjectCreation)] + public async Task Test_PreferImplicitWhenTypeIsObvious_ArrayInitializerInLocalVariableInitializer() + { + await VerifyDiagnosticAndFixAsync(@" +class C +{ + void M() + { + string[] x = { new [|string|](' ', 0) }; + } +} +", @" +class C +{ + void M() + { + string[] x = { new(' ', 0) }; + } +} +", options: Options.AddConfigOption(ConfigOptionKeys.ObjectCreationTypeStyle, ConfigOptionValues.ObjectCreationTypeStyle_ImplicitWhenTypeIsObvious)); + } + [Fact, Trait(Traits.Analyzer, DiagnosticIdentifiers.UseImplicitOrExplicitObjectCreation)] public async Task Test_ConvertImplicitToExplicit_ThrowStatement() { From 1517f09f0109208681d720c43f9d3fb7e1d7df75 Mon Sep 17 00:00:00 2001 From: Josef Pihrt Date: Fri, 3 Jun 2022 00:17:04 +0200 Subject: [PATCH 3/3] Update changelog --- ChangeLog.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ChangeLog.md b/ChangeLog.md index 6450586628..a818b3e3e9 100644 --- a/ChangeLog.md +++ b/ChangeLog.md @@ -1,5 +1,7 @@ ### Unreleased +* Convert more syntax to implicit object creation (RCS1250) ([PR](https://github.com/JosefPihrt/Roslynator/pull/910)) + ### 4.1.1 (2022-05-29) * Bug fixes