Skip to content

Commit

Permalink
Improve sequence point placement in primary constructors and records
Browse files Browse the repository at this point in the history
  • Loading branch information
tmat committed Jul 19, 2023
1 parent ab1d1f1 commit 0cca3de
Show file tree
Hide file tree
Showing 55 changed files with 3,110 additions and 877 deletions.
236 changes: 236 additions & 0 deletions src/Compilers/CSharp/Test/Emit/PDB/PDBTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12202,6 +12202,242 @@ .maxstack 2
");
}

[Fact]
public void SyntaxOffset_OutVarInPrimaryConstructorInitializer()
{
var source = @"
class B(int x, int y)
{
}
class C(int x) : B(F(out var y), y)
{
int Z = F(out var z);
static int F(out int a) => a = 1;
}";

var c = CreateCompilationWithMscorlib40AndSystemCore(source, options: TestOptions.DebugDll);
c.VerifyPdb(@"
<symbols>
<methods>
<method containingType=""B"" name="".ctor"" parameterNames=""x, y"">
<customDebugInfo>
<using>
<namespace usingCount=""0"" />
</using>
</customDebugInfo>
</method>
<method containingType=""C"" name="".ctor"" parameterNames=""x"">
<customDebugInfo>
<forward declaringType=""B"" methodName="".ctor"" parameterNames=""x, y"" />
<encLocalSlotMap>
<slot kind=""0"" offset=""-6"" />
<slot kind=""0"" offset=""-20"" />
</encLocalSlotMap>
</customDebugInfo>
</method>
<method containingType=""C"" name=""F"" parameterNames=""a"">
<customDebugInfo>
<forward declaringType=""B"" methodName="".ctor"" parameterNames=""x, y"" />
</customDebugInfo>
<sequencePoints>
<entry offset=""0x0"" startLine=""9"" startColumn=""32"" endLine=""9"" endColumn=""37"" document=""1"" />
</sequencePoints>
</method>
</methods>
</symbols>
", options: SyntaxOffsetPdbValidationOptions);
}

#endregion

#region Primary Constructors

[Fact]
[WorkItem("https://github.com/dotnet/roslyn/issues/63299")]
public void SequencePoints_PrimaryConstructor_ExplicitBaseInitializer()
{
var source = @"
class B() : object()
{
}
class C(int x) : B()
{
int y = 1;
}";

var c = CompileAndVerify(source);
c.VerifyMethodBody("B..ctor", @"
{
// Code size 7 (0x7)
.maxstack 1
// sequence point: object()
IL_0000: ldarg.0
IL_0001: call ""object..ctor()""
IL_0006: ret
}
");
c.VerifyMethodBody("C..ctor", @"
{
// Code size 14 (0xe)
.maxstack 2
// sequence point: int y = 1;
IL_0000: ldarg.0
IL_0001: ldc.i4.1
IL_0002: stfld ""int C.y""
// sequence point: B()
IL_0007: ldarg.0
IL_0008: call ""B..ctor()""
IL_000d: ret
}
");
}

[Fact]
[WorkItem("https://github.com/dotnet/roslyn/issues/63299")]
public void SequencePoints_PrimaryConstructor_ImplicitBaseInitializer()
{
var source = @"
class B()
{
}
class C(int x) : B
{
}";

var c = CompileAndVerify(source);
c.VerifyMethodBody("B..ctor", @"
{
// Code size 7 (0x7)
.maxstack 1
// sequence point: B()
IL_0000: ldarg.0
IL_0001: call ""object..ctor()""
IL_0006: ret
}
");
c.VerifyMethodBody("C..ctor", @"
{
// Code size 7 (0x7)
.maxstack 1
// sequence point: C(int x)
IL_0000: ldarg.0
IL_0001: call ""B..ctor()""
IL_0006: ret
}
");
}

[Fact]
[WorkItem("https://github.com/dotnet/roslyn/issues/63299")]
public void SequencePoints_RecordConstructors_ModifiersAndDefault()
{
var source = @"
record C<T>([A]in T P = default) where T : struct;
class A : System.Attribute {}
" + IsExternalInitTypeDefinition;

var c = CompileAndVerify(source, verify: Verification.Skipped);

// primary constructor
c.VerifyMethodBody("C<T>..ctor(in T)", @"
{
// Code size 19 (0x13)
.maxstack 2
// sequence point: <hidden>
IL_0000: ldarg.0
IL_0001: ldarg.1
IL_0002: ldobj ""T""
IL_0007: stfld ""T C<T>.<P>k__BackingField""
// sequence point: C<T>([A]in T P = default)
IL_000c: ldarg.0
IL_000d: call ""object..ctor()""
IL_0012: ret
}
");
// copy constructor
c.VerifyMethodBody("C<T>..ctor(C<T>)", @"
{
// Code size 19 (0x13)
.maxstack 2
// sequence point: <hidden>
IL_0000: ldarg.0
IL_0001: call ""object..ctor()""
IL_0006: ldarg.0
IL_0007: ldarg.1
IL_0008: ldfld ""T C<T>.<P>k__BackingField""
IL_000d: stfld ""T C<T>.<P>k__BackingField""
// sequence point: C<T>
IL_0012: ret
}
");
// primary auto-property getter
c.VerifyMethodBody("C<T>.P.get", @"
{
// Code size 7 (0x7)
.maxstack 1
// sequence point: in T P
IL_0000: ldarg.0
IL_0001: ldfld ""T C<T>.<P>k__BackingField""
IL_0006: ret
}
");
// primary auto-property setter
c.VerifyMethodBody("C<T>.P.init", @"
{
// Code size 8 (0x8)
.maxstack 2
// sequence point: in T P
IL_0000: ldarg.0
IL_0001: ldarg.1
IL_0002: stfld ""T C<T>.<P>k__BackingField""
IL_0007: ret
}
");
}

[Theory]
[InlineData("int[] P = default", "int[] P")]
[InlineData("[A]int[] P", "int[] P")]
[InlineData("params int[] P", "params int[] P")]
[WorkItem("https://github.com/dotnet/roslyn/issues/63299")]
public void SequencePoints_RecordPropertyAccessors(string parameterSyntax, string expectedSpan)
{
var source =
"record C(" + parameterSyntax + ");" +
"class A : System.Attribute { }" +
IsExternalInitTypeDefinition;

var c = CompileAndVerify(source, verify: Verification.Skipped);

// primary auto-property getter
c.VerifyMethodBody("C.P.get", $@"
{{
// Code size 7 (0x7)
.maxstack 1
// sequence point: {expectedSpan}
IL_0000: ldarg.0
IL_0001: ldfld ""int[] C.<P>k__BackingField""
IL_0006: ret
}}
");
// primary auto-property setter
c.VerifyMethodBody("C.P.init", $@"
{{
// Code size 8 (0x8)
.maxstack 2
// sequence point: {expectedSpan}
IL_0000: ldarg.0
IL_0001: ldarg.1
IL_0002: stfld ""int[] C.<P>k__BackingField""
IL_0007: ret
}}
");
}

#endregion

[WorkItem(4370, "https://github.com/dotnet/roslyn/issues/4370")]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -595,7 +595,7 @@ class C
var active = GetActiveStatements(src1, src2);

edits.VerifySemanticDiagnostics(active,
Diagnostic(RudeEditKind.DeleteActiveStatement, "get", FeaturesResources.code));
Diagnostic(RudeEditKind.ActiveStatementUpdate, "{"));
}

[Fact]
Expand Down
Loading

0 comments on commit 0cca3de

Please sign in to comment.