Skip to content

Commit

Permalink
EnC - Support record structs (#52989)
Browse files Browse the repository at this point in the history
  • Loading branch information
davidwengier authored May 14, 2021
1 parent f63fd0f commit fa5a5bb
Show file tree
Hide file tree
Showing 18 changed files with 169 additions and 4 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,9 @@ public void ErrorSpans_TopLevel()
[A, B]
/*<span>*/public abstract partial record R/*</span>*/ { }
[A, B]
/*<span>*/public abstract partial record struct R/*</span>*/ { }
/*<span>*/interface I/*</span>*/ : J, K, L { }
[A]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -587,6 +587,21 @@ public void TypeKindUpdate2()
Diagnostic(RudeEditKind.TypeKindUpdate, "record C", CSharpFeaturesResources.record_));
}

[Fact]
public void TypeKindUpdate3()
{
var src1 = "record C { }";
var src2 = "record struct C { }";

var edits = GetTopEdits(src1, src2);

edits.VerifyEdits(
"Update [record C { }]@0 -> [record struct C { }]@0");

edits.VerifyRudeDiagnostics(
Diagnostic(RudeEditKind.TypeKindUpdate, "record struct C", CSharpFeaturesResources.record_struct));
}

[Fact]
public void Class_Modifiers_Update()
{
Expand Down Expand Up @@ -1693,6 +1708,55 @@ public void Record_Name_Update()
Diagnostic(RudeEditKind.Renamed, "record D", CSharpFeaturesResources.record_));
}

[Fact]
public void RecordStruct_NoModifiers_Insert()
{
var src1 = "";
var src2 = "record struct C { }";

var edits = GetTopEdits(src1, src2);

edits.VerifyRudeDiagnostics();
}

[Fact]
public void RecordStruct_AddField()
{
var src1 = @"
record struct C(int X)
{
}";
var src2 = @"
record struct C(int X)
{
private int _y = 0;
}";

var edits = GetTopEdits(src1, src2);

edits.VerifySemanticDiagnostics(
Diagnostic(RudeEditKind.InsertIntoStruct, "_y = 0", FeaturesResources.field, CSharpFeaturesResources.record_struct));
}

[Fact]
public void RecordStruct_AddProperty()
{
var src1 = @"
record struct C(int X)
{
}";
var src2 = @"
record struct C(int X)
{
public int Y { get; set; } = 0;
}";

var edits = GetTopEdits(src1, src2);

edits.VerifySemanticDiagnostics(
Diagnostic(RudeEditKind.InsertIntoStruct, "public int Y { get; set; } = 0;", FeaturesResources.auto_property, CSharpFeaturesResources.record_struct));
}

[Fact]
public void Record_NoModifiers_Insert()
{
Expand Down Expand Up @@ -1824,7 +1888,28 @@ public void Record_ImplementSynthesized_PrintMembers()
var src2 = @"
record C
{
protected virtual bool PrintMembers(System.Text.StringBuilder builder)
protected bool PrintMembers(System.Text.StringBuilder builder)
{
return true;
}
}";

var edits = GetTopEdits(src1, src2);

edits.VerifySemantics(
SemanticEdit(SemanticEditKind.Update, c => c.GetMember("C.PrintMembers")));

edits.VerifyRudeDiagnostics();
}

[Fact]
public void RecordStruct_ImplementSynthesized_PrintMembers()
{
var src1 = "record struct C { }";
var src2 = @"
record struct C
{
private bool PrintMembers(System.Text.StringBuilder builder)
{
return true;
}
Expand Down
3 changes: 3 additions & 0 deletions src/Features/CSharp/Portable/CSharpFeaturesResources.resx
Original file line number Diff line number Diff line change
Expand Up @@ -621,4 +621,7 @@
<data name="record_" xml:space="preserve">
<value>record</value>
</data>
<data name="record_struct" xml:space="preserve">
<value>record struct</value>
</data>
</root>
Original file line number Diff line number Diff line change
Expand Up @@ -1100,7 +1100,7 @@ internal override bool IsInterfaceDeclaration(SyntaxNode node)
=> node.IsKind(SyntaxKind.InterfaceDeclaration);

internal override bool IsRecordDeclaration(SyntaxNode node)
=> node.IsKind(SyntaxKind.RecordDeclaration);
=> node.IsKind(SyntaxKind.RecordDeclaration, SyntaxKind.RecordStructDeclaration);

internal override SyntaxNode? TryGetContainingTypeDeclaration(SyntaxNode node)
=> node.Parent!.FirstAncestorOrSelf<BaseTypeDeclarationSyntax>();
Expand Down Expand Up @@ -1426,6 +1426,7 @@ private static bool GroupBySignatureComparer(ImmutableArray<IParameterSymbol> ol
case SyntaxKind.StructDeclaration:
case SyntaxKind.InterfaceDeclaration:
case SyntaxKind.RecordDeclaration:
case SyntaxKind.RecordStructDeclaration:
var typeDeclaration = (TypeDeclarationSyntax)node;
return GetDiagnosticSpan(typeDeclaration.Modifiers, typeDeclaration.Keyword,
typeDeclaration.TypeParameterList ?? (SyntaxNodeOrToken)typeDeclaration.Identifier);
Expand Down Expand Up @@ -1777,6 +1778,9 @@ internal override TextSpan GetLambdaParameterDiagnosticSpan(SyntaxNode lambda, i
case SyntaxKind.RecordDeclaration:
return CSharpFeaturesResources.record_;

case SyntaxKind.RecordStructDeclaration:
return CSharpFeaturesResources.record_struct;

case SyntaxKind.EnumDeclaration:
return FeaturesResources.enum_;

Expand Down Expand Up @@ -2136,6 +2140,7 @@ private void ClassifyReorder(SyntaxNode newNode)
case SyntaxKind.StructDeclaration:
case SyntaxKind.InterfaceDeclaration:
case SyntaxKind.RecordDeclaration:
case SyntaxKind.RecordStructDeclaration:
case SyntaxKind.EnumDeclaration:
case SyntaxKind.DelegateDeclaration:
case SyntaxKind.VariableDeclaration:
Expand Down Expand Up @@ -2209,6 +2214,7 @@ private void ClassifyInsert(SyntaxNode node)
case SyntaxKind.ClassDeclaration:
case SyntaxKind.StructDeclaration:
case SyntaxKind.RecordDeclaration:
case SyntaxKind.RecordStructDeclaration:
case SyntaxKind.InterfaceDeclaration:
case SyntaxKind.EnumDeclaration:
case SyntaxKind.DelegateDeclaration:
Expand Down Expand Up @@ -2299,6 +2305,7 @@ private void ClassifyDelete(SyntaxNode oldNode)
case SyntaxKind.StructDeclaration:
case SyntaxKind.InterfaceDeclaration:
case SyntaxKind.RecordDeclaration:
case SyntaxKind.RecordStructDeclaration:
case SyntaxKind.MethodDeclaration:
case SyntaxKind.PropertyDeclaration:
case SyntaxKind.IndexerDeclaration:
Expand Down Expand Up @@ -2387,6 +2394,7 @@ private void ClassifyUpdate(SyntaxNode oldNode, SyntaxNode newNode)
case SyntaxKind.StructDeclaration:
case SyntaxKind.InterfaceDeclaration:
case SyntaxKind.RecordDeclaration:
case SyntaxKind.RecordStructDeclaration:
ClassifyUpdate((TypeDeclarationSyntax)oldNode, (TypeDeclarationSyntax)newNode);
return;

Expand Down Expand Up @@ -3183,6 +3191,7 @@ protected override List<SyntaxNode> GetExceptionHandlingAncestors(SyntaxNode nod
case SyntaxKind.ClassDeclaration:
case SyntaxKind.StructDeclaration:
case SyntaxKind.RecordDeclaration:
case SyntaxKind.RecordStructDeclaration:
return result;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -563,11 +563,11 @@ private static Label ClassifyTopSyntax(SyntaxKind kind, out bool isLeaf)
case SyntaxKind.NamespaceDeclaration:
return Label.NamespaceDeclaration;

// Need to add support for record structs (tracked by https://github.com/dotnet/roslyn/issues/44877)
case SyntaxKind.ClassDeclaration:
case SyntaxKind.StructDeclaration:
case SyntaxKind.InterfaceDeclaration:
case SyntaxKind.RecordDeclaration:
case SyntaxKind.RecordStructDeclaration:
return Label.TypeDeclaration;

case SyntaxKind.MethodDeclaration:
Expand Down Expand Up @@ -1343,11 +1343,11 @@ private static double CombineOptional(
case SyntaxKind.NamespaceDeclaration:
return ((NamespaceDeclarationSyntax)node).Name;

// Need to add support for record structs (tracked by https://github.com/dotnet/roslyn/issues/44877)
case SyntaxKind.ClassDeclaration:
case SyntaxKind.StructDeclaration:
case SyntaxKind.InterfaceDeclaration:
case SyntaxKind.RecordDeclaration:
case SyntaxKind.RecordStructDeclaration:
return ((TypeDeclarationSyntax)node).Identifier;

case SyntaxKind.EnumDeclaration:
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit fa5a5bb

Please sign in to comment.