Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

EnC - Support record structs #52989

Merged
merged 9 commits into from
May 14, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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 @@ -3188,6 +3196,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.