Skip to content

Commit 1100d64

Browse files
Merge pull request #3032 from KirillOsenkov/dev/kirillo/sequencePoints
Fix #3031: emit sequence points for expression-bodied properties and indexers
2 parents fa98b3c + e8c1270 commit 1100d64

File tree

7 files changed

+155
-6
lines changed

7 files changed

+155
-6
lines changed

ICSharpCode.Decompiler.Tests/ICSharpCode.Decompiler.Tests.csproj

+1
Original file line numberDiff line numberDiff line change
@@ -325,6 +325,7 @@
325325
</ItemGroup>
326326

327327
<ItemGroup>
328+
<Content Include="TestCases\PdbGen\Members.xml" />
328329
<Content Include="TestCases\PdbGen\ProgressReporting.xml" />
329330
<Content Include="TestCases\PdbGen\ForLoopTests.xml" />
330331
<Content Include="TestCases\PdbGen\CustomPdbId.xml" />

ICSharpCode.Decompiler.Tests/PdbGenerationTestRunner.cs

+8-1
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,13 @@ public void LambdaCapturing()
4343
TestGeneratePdb();
4444
}
4545

46+
[Test]
47+
[Ignore("Duplicate sequence points for local function")]
48+
public void Members()
49+
{
50+
TestGeneratePdb();
51+
}
52+
4653
[Test]
4754
public void CustomPdbId()
4855
{
@@ -155,7 +162,7 @@ private void TestGeneratePdb([CallerMemberName] string testName = null)
155162
ProcessXmlFile(expectedFileName);
156163
string generatedFileName = Path.ChangeExtension(xmlFile, ".generated.xml");
157164
ProcessXmlFile(generatedFileName);
158-
Assert.AreEqual(Normalize(expectedFileName), Normalize(generatedFileName));
165+
CodeAssert.AreEqual(Normalize(expectedFileName), Normalize(generatedFileName));
159166
}
160167

161168
private (string peFileName, string pdbFileName) CompileTestCase(string testName)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<symbols>
3+
<files>
4+
<file id="1" name="-\C.cs" language="C#" checksumAlgorithm="SHA256">
5+
<![CDATA[using System;
6+
7+
internal class C : IDisposable
8+
{
9+
private int ExpressionProperty => 42;
10+
11+
private int Property
12+
{
13+
get
14+
{
15+
return 0;
16+
}
17+
set
18+
{
19+
}
20+
}
21+
22+
private C this[int index] => null;
23+
24+
private C this[string s]
25+
{
26+
get
27+
{
28+
return null;
29+
}
30+
set
31+
{
32+
}
33+
}
34+
35+
public event Action Event
36+
{
37+
add
38+
{
39+
}
40+
remove
41+
{
42+
}
43+
}
44+
45+
public static implicit operator C(int i)
46+
{
47+
return null;
48+
}
49+
50+
static C()
51+
{
52+
}
53+
54+
public C()
55+
{
56+
Console.WriteLine();
57+
}
58+
59+
~C()
60+
{
61+
}
62+
63+
void IDisposable.Dispose()
64+
{
65+
}
66+
67+
private static void Main()
68+
{
69+
C c = new C();
70+
71+
c.Event += delegate
72+
{
73+
};
74+
_ = c.Property;
75+
_ = c.ExpressionProperty;
76+
_ = c[0];
77+
_ = c[""];
78+
79+
_ = (C)1;
80+
81+
Local();
82+
83+
static void Local()
84+
{
85+
Console.WriteLine();
86+
}
87+
}
88+
}
89+
]]></file>
90+
</files>
91+
<methods>
92+
</methods>
93+
<method-spans>
94+
</method-spans>
95+
</symbols>

ICSharpCode.Decompiler/CSharp/CSharpDecompiler.cs

+1-5
Original file line numberDiff line numberDiff line change
@@ -1698,10 +1698,7 @@ void DecompileBody(IMethod method, EntityDeclaration entityDecl, DecompileRun de
16981698
var function = ilReader.ReadIL((MethodDefinitionHandle)method.MetadataToken, methodBody, cancellationToken: CancellationToken);
16991699
function.CheckInvariant(ILPhase.Normal);
17001700

1701-
if (entityDecl != null)
1702-
{
1703-
AddAnnotationsToDeclaration(method, entityDecl, function);
1704-
}
1701+
AddAnnotationsToDeclaration(method, entityDecl, function);
17051702

17061703
var localSettings = settings.Clone();
17071704
if (IsWindowsFormsInitializeComponentMethod(method))
@@ -1751,7 +1748,6 @@ void DecompileBody(IMethod method, EntityDeclaration entityDecl, DecompileRun de
17511748

17521749
entityDecl.AddChild(body, Roles.Body);
17531750
}
1754-
entityDecl.AddAnnotation(function);
17551751

17561752
CleanUpMethodDeclaration(entityDecl, body, function, localSettings.DecompileMemberBodies);
17571753
}

ICSharpCode.Decompiler/CSharp/SequencePointBuilder.cs

+24
Original file line numberDiff line numberDiff line change
@@ -164,6 +164,30 @@ public override void VisitBlockStatement(BlockStatement blockStatement)
164164
}
165165
}
166166

167+
public override void VisitPropertyDeclaration(PropertyDeclaration propertyDeclaration)
168+
{
169+
if (!propertyDeclaration.ExpressionBody.IsNull)
170+
{
171+
VisitAsSequencePoint(propertyDeclaration.ExpressionBody);
172+
}
173+
else
174+
{
175+
base.VisitPropertyDeclaration(propertyDeclaration);
176+
}
177+
}
178+
179+
public override void VisitIndexerDeclaration(IndexerDeclaration indexerDeclaration)
180+
{
181+
if (!indexerDeclaration.ExpressionBody.IsNull)
182+
{
183+
VisitAsSequencePoint(indexerDeclaration.ExpressionBody);
184+
}
185+
else
186+
{
187+
base.VisitIndexerDeclaration(indexerDeclaration);
188+
}
189+
}
190+
167191
public override void VisitForStatement(ForStatement forStatement)
168192
{
169193
// Every element of a for-statement is its own sequence point.

ICSharpCode.Decompiler/CSharp/Transforms/NormalizeBlockStatements.cs

+2
Original file line numberDiff line numberDiff line change
@@ -218,6 +218,7 @@ void SimplifyPropertyDeclaration(PropertyDeclaration propertyDeclaration)
218218
return;
219219
propertyDeclaration.Modifiers |= propertyDeclaration.Getter.Modifiers;
220220
propertyDeclaration.ExpressionBody = m.Get<Expression>("expression").Single().Detach();
221+
propertyDeclaration.CopyAnnotationsFrom(propertyDeclaration.Getter);
221222
propertyDeclaration.Getter.Remove();
222223
}
223224

@@ -230,6 +231,7 @@ void SimplifyIndexerDeclaration(IndexerDeclaration indexerDeclaration)
230231
return;
231232
indexerDeclaration.Modifiers |= indexerDeclaration.Getter.Modifiers;
232233
indexerDeclaration.ExpressionBody = m.Get<Expression>("expression").Single().Detach();
234+
indexerDeclaration.CopyAnnotationsFrom(indexerDeclaration.Getter);
233235
indexerDeclaration.Getter.Remove();
234236
}
235237
}

ICSharpCode.Decompiler/DebugInfo/DebugInfoGenerator.cs

+24
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,30 @@ public override void VisitAnonymousMethodExpression(AnonymousMethodExpression an
136136
HandleMethod(anonymousMethodExpression);
137137
}
138138

139+
public override void VisitPropertyDeclaration(PropertyDeclaration propertyDeclaration)
140+
{
141+
if (!propertyDeclaration.ExpressionBody.IsNull)
142+
{
143+
HandleMethod(propertyDeclaration.ExpressionBody, propertyDeclaration.Annotation<ILFunction>());
144+
}
145+
else
146+
{
147+
base.VisitPropertyDeclaration(propertyDeclaration);
148+
}
149+
}
150+
151+
public override void VisitIndexerDeclaration(IndexerDeclaration indexerDeclaration)
152+
{
153+
if (!indexerDeclaration.ExpressionBody.IsNull)
154+
{
155+
HandleMethod(indexerDeclaration.ExpressionBody, indexerDeclaration.Annotation<ILFunction>());
156+
}
157+
else
158+
{
159+
base.VisitIndexerDeclaration(indexerDeclaration);
160+
}
161+
}
162+
139163
public override void VisitQueryFromClause(QueryFromClause queryFromClause)
140164
{
141165
if (queryFromClause.Parent.FirstChild != queryFromClause)

0 commit comments

Comments
 (0)