Skip to content

Commit 8cec0d0

Browse files
Allow user to still create a new field/prop when offering to initialize an existing prop (#79376)
2 parents 3e2cadf + 84d0d4b commit 8cec0d0

File tree

2 files changed

+60
-18
lines changed

2 files changed

+60
-18
lines changed

src/EditorFeatures/CSharpTest/CodeActions/InitializeParameter/InitializeMemberFromPrimaryConstructorParameterTests.cs

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1349,6 +1349,50 @@ public partial class Goo
13491349
</Workspace>
13501350
""");
13511351

1352+
[Fact, WorkItem("https://github.com/dotnet/roslyn/issues/76565")]
1353+
public Task TestCouldInitializeThrowingProperty_ButGeneratePropertyInstead()
1354+
=> TestInRegularAndScript1Async(
1355+
"""
1356+
using System;
1357+
1358+
class C([||]string s)
1359+
{
1360+
private string S => throw new NotImplementedException();
1361+
}
1362+
""",
1363+
"""
1364+
using System;
1365+
1366+
class C(string s)
1367+
{
1368+
public string S1 { get; } = s;
1369+
1370+
private string S => throw new NotImplementedException();
1371+
}
1372+
""", index: 1);
1373+
1374+
[Fact, WorkItem("https://github.com/dotnet/roslyn/issues/76565")]
1375+
public Task TestCouldInitializeThrowingProperty_ButGenerateFieldInstead()
1376+
=> TestInRegularAndScript1Async(
1377+
"""
1378+
using System;
1379+
1380+
class C([||]string s)
1381+
{
1382+
private string S => throw new NotImplementedException();
1383+
}
1384+
""",
1385+
"""
1386+
using System;
1387+
1388+
class C(string s)
1389+
{
1390+
private readonly string s = s;
1391+
1392+
private string S => throw new NotImplementedException();
1393+
}
1394+
""", index: 2);
1395+
13521396
[Fact]
13531397
public Task TestUpdateCodeToReferenceExistingField1()
13541398
=> TestInRegularAndScript1Async(

src/Features/CSharp/Portable/InitializeParameter/CSharpInitializeMemberFromPrimaryConstructorParameterCodeRefactoringProvider.cs

Lines changed: 16 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@
2020
using Microsoft.CodeAnalysis.Editing;
2121
using Microsoft.CodeAnalysis.Formatting;
2222
using Microsoft.CodeAnalysis.InitializeParameter;
23-
using Microsoft.CodeAnalysis.Shared.Collections;
2423
using Microsoft.CodeAnalysis.Shared.Extensions;
2524
using Microsoft.CodeAnalysis.Shared.Naming;
2625
using Roslyn.Utilities;
@@ -73,11 +72,18 @@ public override async Task ComputeRefactoringsAsync(CodeRefactoringContext conte
7372
var formattingOptions = await document.GetSyntaxFormattingOptionsAsync(cancellationToken).ConfigureAwait(false);
7473

7574
var fieldOrProperty = TryFindMatchingUninitializedFieldOrPropertySymbol();
76-
var refactorings = fieldOrProperty == null
77-
? HandleNoExistingFieldOrProperty()
78-
: HandleExistingFieldOrProperty();
75+
using var refactorings = TemporaryArray<CodeAction>.Empty;
76+
if (fieldOrProperty != null)
77+
{
78+
// Found a field/property that this parameter should be assigned to. Just offer the simple assignment to it.
79+
refactorings.Add(CreateCodeAction(
80+
string.Format(fieldOrProperty.Kind == SymbolKind.Field ? FeaturesResources.Initialize_field_0 : FeaturesResources.Initialize_property_0, fieldOrProperty.Name),
81+
cancellationToken => AddAssignmentForPrimaryConstructorAsync(document, parameter, fieldOrProperty, cancellationToken)));
82+
}
83+
84+
AddCreateFieldOrPropertyCodeActions();
7985

80-
context.RegisterRefactorings(refactorings.ToImmutableArray(), context.Span);
86+
context.RegisterRefactorings(refactorings.ToImmutableAndClear(), context.Span);
8187
return;
8288

8389
ISymbol? TryFindMatchingUninitializedFieldOrPropertySymbol()
@@ -133,15 +139,7 @@ public override async Task ComputeRefactoringsAsync(CodeRefactoringContext conte
133139
static CodeAction CreateCodeAction(string title, Func<CancellationToken, Task<Solution>> createSolution)
134140
=> CodeAction.Create(title, createSolution, title);
135141

136-
IEnumerable<CodeAction> HandleExistingFieldOrProperty()
137-
{
138-
// Found a field/property that this parameter should be assigned to. Just offer the simple assignment to it.
139-
yield return CreateCodeAction(
140-
string.Format(fieldOrProperty.Kind == SymbolKind.Field ? FeaturesResources.Initialize_field_0 : FeaturesResources.Initialize_property_0, fieldOrProperty.Name),
141-
cancellationToken => AddAssignmentForPrimaryConstructorAsync(document, parameter, fieldOrProperty, cancellationToken));
142-
}
143-
144-
IEnumerable<CodeAction> HandleNoExistingFieldOrProperty()
142+
void AddCreateFieldOrPropertyCodeActions()
145143
{
146144
// Didn't find a field/prop that this parameter could be assigned to. Offer to create new one and assign to that.
147145

@@ -159,8 +157,8 @@ IEnumerable<CodeAction> HandleNoExistingFieldOrProperty()
159157
string.Format(FeaturesResources.Create_and_assign_property_0, property.Name),
160158
cancellationToken => AddMultipleMembersAsync(document, typeDeclaration, [parameter], [property], cancellationToken));
161159

162-
yield return siblingFieldOrProperty is IFieldSymbol ? fieldAction : propertyAction;
163-
yield return siblingFieldOrProperty is IFieldSymbol ? propertyAction : fieldAction;
160+
refactorings.Add(siblingFieldOrProperty is IFieldSymbol ? fieldAction : propertyAction);
161+
refactorings.Add(siblingFieldOrProperty is IFieldSymbol ? propertyAction : fieldAction);
164162

165163
var parameters = GetParametersWithoutAssociatedMembers();
166164
if (parameters.Length >= 2)
@@ -172,8 +170,8 @@ IEnumerable<CodeAction> HandleNoExistingFieldOrProperty()
172170
FeaturesResources.Create_and_assign_remaining_as_properties,
173171
cancellationToken => AddMultipleMembersAsync(document, typeDeclaration, parameters, parameters.SelectAsArray(CreateProperty), cancellationToken));
174172

175-
yield return siblingFieldOrProperty is IFieldSymbol ? allFieldsAction : allPropertiesAction;
176-
yield return siblingFieldOrProperty is IFieldSymbol ? allPropertiesAction : allFieldsAction;
173+
refactorings.Add(siblingFieldOrProperty is IFieldSymbol ? allFieldsAction : allPropertiesAction);
174+
refactorings.Add(siblingFieldOrProperty is IFieldSymbol ? allPropertiesAction : allFieldsAction);
177175
}
178176
}
179177

0 commit comments

Comments
 (0)