Browse Source

Fix #982: ILSpy should ignore the parameter name of property setter and always use "value" instead in C#

pull/992/head
Siegfried Pammer 8 years ago
parent
commit
9b160c13e7
  1. 2
      ICSharpCode.Decompiler.Tests/ICSharpCode.Decompiler.Tests.csproj
  2. 6
      ICSharpCode.Decompiler.Tests/ILPrettyTestRunner.cs
  3. 27
      ICSharpCode.Decompiler.Tests/TestCases/ILPretty/Issue982.cs
  4. 125
      ICSharpCode.Decompiler.Tests/TestCases/ILPretty/Issue982.il
  5. 50
      ICSharpCode.Decompiler/IL/Transforms/AssignVariableNames.cs

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

@ -61,6 +61,7 @@ @@ -61,6 +61,7 @@
<Compile Include="TestCases\Correctness\ExpressionTrees.cs" />
<Compile Include="TestCases\Correctness\LINQRaytracer.cs" />
<Compile Include="TestCases\Correctness\MiniJSON.cs" />
<Compile Include="TestCases\ILPretty\Issue982.cs" />
<Compile Include="TestCases\Pretty\ExpressionTrees.cs" />
<None Include="TestCases\ILPretty\Issue959.cs" />
<None Include="TestCases\ILPretty\FSharpLoops_Debug.cs" />
@ -141,6 +142,7 @@ @@ -141,6 +142,7 @@
<ItemGroup>
<None Include="TestCases\ILPretty\Issue646.il" />
<None Include="TestCases\ILPretty\Issue379.il" />
<None Include="TestCases\ILPretty\Issue982.il" />
<None Include="TestCases\Pretty\Readme.txt" />
</ItemGroup>

6
ICSharpCode.Decompiler.Tests/ILPrettyTestRunner.cs

@ -48,6 +48,12 @@ namespace ICSharpCode.Decompiler.Tests @@ -48,6 +48,12 @@ namespace ICSharpCode.Decompiler.Tests
Run();
}
[Test]
public void Issue982()
{
Run();
}
[Test]
public void FSharpUsing_Debug()
{

27
ICSharpCode.Decompiler.Tests/TestCases/ILPretty/Issue982.cs

@ -0,0 +1,27 @@ @@ -0,0 +1,27 @@
namespace ICSharpCode.Decompiler.Tests.TestCases.ILPretty
{
internal class Issue982
{
private string textStr;
private string textStr2;
public string Text {
get {
return this.textStr;
}
set {
this.textStr = value;
}
}
public string this[int index] {
get {
return this.textStr2;
}
set {
this.textStr2 = value;
}
}
}
}

125
ICSharpCode.Decompiler.Tests/TestCases/ILPretty/Issue982.il

@ -0,0 +1,125 @@ @@ -0,0 +1,125 @@

// Microsoft (R) .NET Framework IL Disassembler. Version 3.5.30729.1
// Copyright (c) Microsoft Corporation. All rights reserved.
// Metadata version: v4.0.30319
.assembly extern mscorlib
{
.publickeytoken = (B7 7A 5C 56 19 34 E0 89 ) // .z\V.4..
.ver 4:0:0:0
}
.assembly extern System
{
.publickeytoken = (B7 7A 5C 56 19 34 E0 89 ) // .z\V.4..
.ver 4:0:0:0
}
.assembly extern Microsoft.VisualBasic
{
.publickeytoken = (B0 3F 5F 7F 11 D5 0A 3A ) // .?_....:
.ver 10:0:0:0
}
.assembly ICSharpCode.Decompiler.Tests.TestCases.ILPretty
{
.hash algorithm 0x00008004
.ver 1:0:0:0
}
.module Issue982.exe
// MVID: {1DAED9CF-459B-4BA6-A091-CB3BDEF963F8}
.imagebase 0x00400000
.file alignment 0x00000200
.stackreserve 0x00100000
.subsystem 0x0003 // WINDOWS_CUI
.corflags 0x00020003 // ILONLY 32BITREQUIRED
// Image base: 0x06E80000
// =============== CLASS MEMBERS DECLARATION ===================
.class private auto ansi ICSharpCode.Decompiler.Tests.TestCases.ILPretty.Issue982
extends [mscorlib]System.Object
{
.custom instance void [mscorlib]System.Reflection.DefaultMemberAttribute::.ctor(string) = ( 01 00 05 54 65 78 74 32 00 00 ) // ...Text2..
.field private string textStr
.field private string textStr2
.method public specialname rtspecialname
instance void .ctor() cil managed
{
// Code size 7 (0x7)
.maxstack 8
IL_0000: ldarg.0
IL_0001: call instance void [mscorlib]System.Object::.ctor()
IL_0006: ret
} // end of method Issue982::.ctor
.method public specialname instance string
get_Text() cil managed
{
// Code size 12 (0xc)
.maxstack 1
.locals init ([0] string Text)
IL_0000: nop
IL_0001: ldarg.0
IL_0002: ldfld string ICSharpCode.Decompiler.Tests.TestCases.ILPretty.Issue982::textStr
IL_0007: stloc.0
IL_0008: br.s IL_000a
IL_000a: ldloc.0
IL_000b: ret
} // end of method Issue982::get_Text
.method public specialname instance void
set_Text(string str) cil managed
{
// Code size 9 (0x9)
.maxstack 8
IL_0000: nop
IL_0001: ldarg.0
IL_0002: ldarg.1
IL_0003: stfld string ICSharpCode.Decompiler.Tests.TestCases.ILPretty.Issue982::textStr
IL_0008: ret
} // end of method Issue982::set_Text
.method public specialname instance string
get_Text2(int32 index) cil managed
{
// Code size 12 (0xc)
.maxstack 1
.locals init ([0] string Text2)
IL_0000: nop
IL_0001: ldarg.0
IL_0002: ldfld string ICSharpCode.Decompiler.Tests.TestCases.ILPretty.Issue982::textStr2
IL_0007: stloc.0
IL_0008: br.s IL_000a
IL_000a: ldloc.0
IL_000b: ret
} // end of method Issue982::get_Text2
.method public specialname instance void
set_Text2(int32 index,
string str) cil managed
{
// Code size 9 (0x9)
.maxstack 8
IL_0000: nop
IL_0001: ldarg.0
IL_0002: ldarg.2
IL_0003: stfld string ICSharpCode.Decompiler.Tests.TestCases.ILPretty.Issue982::textStr2
IL_0008: ret
} // end of method Issue982::set_Text2
.property instance string Text()
{
.get instance string ICSharpCode.Decompiler.Tests.TestCases.ILPretty.Issue982::get_Text()
.set instance void ICSharpCode.Decompiler.Tests.TestCases.ILPretty.Issue982::set_Text(string)
} // end of property Issue982::Text
.property instance string Text2(int32)
{
.get instance string ICSharpCode.Decompiler.Tests.TestCases.ILPretty.Issue982::get_Text2(int32)
.set instance void ICSharpCode.Decompiler.Tests.TestCases.ILPretty.Issue982::set_Text2(int32,
string)
} // end of property Issue982::Text2
} // end of class ICSharpCode.Decompiler.Tests.TestCases.ILPretty.Issue982

50
ICSharpCode.Decompiler/IL/Transforms/AssignVariableNames.cs

@ -63,8 +63,54 @@ namespace ICSharpCode.Decompiler.IL.Transforms @@ -63,8 +63,54 @@ namespace ICSharpCode.Decompiler.IL.Transforms
loopCounters = CollectLoopCounters(function);
foreach (var f in function.Descendants.OfType<ILFunction>()) {
if (f.Method != null) {
foreach (var p in f.Method.Parameters)
AddExistingName(reservedVariableNames, p.Name);
if (f.Method.IsAccessor && f.Method.Parameters.Count > 0) {
for (int i = 0; i < f.Method.Parameters.Count - 1; i++) {
AddExistingName(reservedVariableNames, f.Method.Parameters[i].Name);
}
var lastParameter = f.Method.Parameters.Last();
switch (f.Method.AccessorOwner) {
case IProperty prop:
if (prop.Setter == f.Method) {
if (prop.Parameters.Any(p => p.Name == "value")) {
f.Warnings.Add("Parameter named \"value\" already present in property signature!");
break;
}
var variableForLastParameter = f.Variables.FirstOrDefault(v => v.Function == f
&& v.Kind == VariableKind.Parameter
&& v.Index == f.Method.Parameters.Count - 1);
if (variableForLastParameter == null) {
AddExistingName(reservedVariableNames, lastParameter.Name);
} else {
if (variableForLastParameter.Name != "value") {
variableForLastParameter.Name = "value";
}
AddExistingName(reservedVariableNames, variableForLastParameter.Name);
}
}
break;
case IEvent ev:
if (f.Method != ev.InvokeAccessor) {
var variableForLastParameter = f.Variables.FirstOrDefault(v => v.Function == f
&& v.Kind == VariableKind.Parameter
&& v.Index == f.Method.Parameters.Count - 1);
if (variableForLastParameter == null) {
AddExistingName(reservedVariableNames, lastParameter.Name);
} else {
if (variableForLastParameter.Name != "value") {
variableForLastParameter.Name = "value";
}
AddExistingName(reservedVariableNames, variableForLastParameter.Name);
}
}
break;
default:
AddExistingName(reservedVariableNames, lastParameter.Name);
break;
}
} else {
foreach (var p in f.Method.Parameters)
AddExistingName(reservedVariableNames, p.Name);
}
} else {
foreach (var p in f.Variables.Where(v => v.Kind == VariableKind.Parameter))
AddExistingName(reservedVariableNames, p.Name);

Loading…
Cancel
Save