Skip to content

Commit 61265c4

Browse files
authored
Fix property/field lazy init (RCS1250) (#1205)
1 parent ffa3f81 commit 61265c4

File tree

3 files changed

+108
-1
lines changed

3 files changed

+108
-1
lines changed

ChangeLog.md

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

1212
- Fix [RCS1164](https://josefpihrt.github.io/docs/roslynator/analyzers/RCS1164) ([#1196](https://github.com/JosefPihrt/Roslynator/pull/1196)).
1313
- Fix [RCS1241](https://josefpihrt.github.io/docs/roslynator/analyzers/RCS1241) ([#1197](https://github.com/JosefPihrt/Roslynator/pull/1197)).
14+
- Fix [RCS1250](https://josefpihrt.github.io/docs/roslynator/analyzers/RCS1250) ([#1205](https://github.com/JosefPihrt/Roslynator/pull/1205)).
1415

1516
## [4.5.0] - 2023-08-27
1617

src/Analyzers/CSharp/Analysis/UseImplicitOrExplicitObjectCreationAnalyzer.cs

Lines changed: 51 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -215,11 +215,29 @@ private static void AnalyzeObjectCreationExpression(SyntaxNodeAnalysisContext co
215215
}
216216
case SyntaxKind.CoalesceExpression:
217217
{
218-
if (UseImplicitObjectCreationWhenTypeIsNotObvious(context))
218+
ObjectCreationTypeStyle style = context.GetObjectCreationTypeStyle();
219+
220+
if (style == ObjectCreationTypeStyle.Implicit)
219221
{
220222
var coalesceExpression = (BinaryExpressionSyntax)parent;
221223
AnalyzeExpression(context, objectCreation, coalesceExpression.Left);
222224
}
225+
else if (style == ObjectCreationTypeStyle.ImplicitWhenTypeIsObvious
226+
&& parent.IsParentKind(SyntaxKind.EqualsValueClause))
227+
{
228+
if (parent.Parent.Parent is VariableDeclaratorSyntax variableDeclarator)
229+
{
230+
if (variableDeclarator.Parent is VariableDeclarationSyntax variableDeclaration
231+
&& variableDeclaration.IsParentKind(SyntaxKind.FieldDeclaration))
232+
{
233+
AnalyzeType(context, objectCreation, variableDeclaration.Type);
234+
}
235+
}
236+
else if (parent.Parent.Parent is PropertyDeclarationSyntax propertyDeclaration)
237+
{
238+
AnalyzeType(context, objectCreation, propertyDeclaration.Type);
239+
}
240+
}
223241

224242
break;
225243
}
@@ -391,8 +409,40 @@ private static void AnalyzeImplicitObjectCreationExpression(SyntaxNodeAnalysisCo
391409
case SyntaxKind.CoalesceAssignmentExpression:
392410
case SyntaxKind.AddAssignmentExpression:
393411
case SyntaxKind.SubtractAssignmentExpression:
412+
{
413+
if (UseExplicitObjectCreationWhenTypeIsNotObvious(context))
414+
ReportDiagnostic(context, implicitObjectCreation);
415+
416+
break;
417+
}
394418
case SyntaxKind.CoalesceExpression:
395419
{
420+
if (parent.IsParentKind(SyntaxKind.EqualsValueClause))
421+
{
422+
switch (parent.Parent.Parent)
423+
{
424+
case VariableDeclaratorSyntax variableDeclarator:
425+
{
426+
if (variableDeclarator.Parent is VariableDeclarationSyntax)
427+
{
428+
if (UseExplicitObjectCreation(context))
429+
ReportDiagnostic(context, implicitObjectCreation);
430+
431+
return;
432+
}
433+
434+
break;
435+
}
436+
case PropertyDeclarationSyntax:
437+
{
438+
if (UseExplicitObjectCreation(context))
439+
ReportDiagnostic(context, implicitObjectCreation);
440+
441+
return;
442+
}
443+
}
444+
}
445+
396446
if (UseExplicitObjectCreationWhenTypeIsNotObvious(context))
397447
ReportDiagnostic(context, implicitObjectCreation);
398448

src/Tests/Analyzers.Tests/RCS1250UseImplicitOrExplicitObjectCreationTests.cs

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -853,6 +853,62 @@ void M()
853853
", options: Options.AddConfigOption(ConfigOptionKeys.ObjectCreationTypeStyle, ConfigOptionValues.ObjectCreationTypeStyle_ImplicitWhenTypeIsObvious));
854854
}
855855

856+
[Fact, Trait(Traits.Analyzer, DiagnosticIdentifiers.UseImplicitOrExplicitObjectCreation)]
857+
public async Task Test_PreferImplicitWhenTypeIsObvious_PropertyLazyInitialization()
858+
{
859+
await VerifyDiagnosticAndFixAsync(@"
860+
#nullable enable
861+
862+
public record R(C? P = null)
863+
{
864+
public C P { get; init; } = P ?? new [|C|]();
865+
}
866+
867+
public class C
868+
{
869+
}
870+
", @"
871+
#nullable enable
872+
873+
public record R(C? P = null)
874+
{
875+
public C P { get; init; } = P ?? new();
876+
}
877+
878+
public class C
879+
{
880+
}
881+
", options: Options.AddConfigOption(ConfigOptionKeys.ObjectCreationTypeStyle, ConfigOptionValues.ObjectCreationTypeStyle_ImplicitWhenTypeIsObvious));
882+
}
883+
884+
[Fact, Trait(Traits.Analyzer, DiagnosticIdentifiers.UseImplicitOrExplicitObjectCreation)]
885+
public async Task Test_PreferImplicitWhenTypeIsObvious_FieldLazyInitialization()
886+
{
887+
await VerifyDiagnosticAndFixAsync(@"
888+
#nullable enable
889+
890+
public record R(C? P = null)
891+
{
892+
public C F = P ?? new [|C|]();
893+
}
894+
895+
public class C
896+
{
897+
}
898+
", @"
899+
#nullable enable
900+
901+
public record R(C? P = null)
902+
{
903+
public C F = P ?? new();
904+
}
905+
906+
public class C
907+
{
908+
}
909+
", options: Options.AddConfigOption(ConfigOptionKeys.ObjectCreationTypeStyle, ConfigOptionValues.ObjectCreationTypeStyle_ImplicitWhenTypeIsObvious));
910+
}
911+
856912
[Fact, Trait(Traits.Analyzer, DiagnosticIdentifiers.UseImplicitOrExplicitObjectCreation)]
857913
public async Task Test_ConvertImplicitToExplicit_ThrowStatement()
858914
{

0 commit comments

Comments
 (0)