Browse Source

Fix #989: Local variable naming conflict

pull/992/head
Siegfried Pammer 8 years ago
parent
commit
69c764722c
  1. 2
      ICSharpCode.Decompiler.Tests/ICSharpCode.Decompiler.Tests.csproj
  2. 16
      ICSharpCode.Decompiler.Tests/PrettyTestRunner.cs
  3. 21
      ICSharpCode.Decompiler.Tests/TestCases/Pretty/VariableNaming.cs
  4. 100
      ICSharpCode.Decompiler.Tests/TestCases/Pretty/VariableNaming.il
  5. 96
      ICSharpCode.Decompiler.Tests/TestCases/Pretty/VariableNaming.opt.il
  6. 99
      ICSharpCode.Decompiler.Tests/TestCases/Pretty/VariableNaming.opt.roslyn.il
  7. 105
      ICSharpCode.Decompiler.Tests/TestCases/Pretty/VariableNaming.roslyn.il
  8. 21
      ICSharpCode.Decompiler.Tests/TestCases/Pretty/VariableNamingWithoutSymbols.cs
  9. 100
      ICSharpCode.Decompiler.Tests/TestCases/Pretty/VariableNamingWithoutSymbols.il
  10. 96
      ICSharpCode.Decompiler.Tests/TestCases/Pretty/VariableNamingWithoutSymbols.opt.il
  11. 99
      ICSharpCode.Decompiler.Tests/TestCases/Pretty/VariableNamingWithoutSymbols.opt.roslyn.il
  12. 105
      ICSharpCode.Decompiler.Tests/TestCases/Pretty/VariableNamingWithoutSymbols.roslyn.il
  13. 2
      ICSharpCode.Decompiler/CSharp/Transforms/DeclareVariables.cs
  14. 47
      ICSharpCode.Decompiler/IL/Transforms/AssignVariableNames.cs

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

@ -63,6 +63,8 @@ @@ -63,6 +63,8 @@
<Compile Include="TestCases\Correctness\MiniJSON.cs" />
<Compile Include="TestCases\ILPretty\Issue982.cs" />
<Compile Include="TestCases\Pretty\ExpressionTrees.cs" />
<Compile Include="TestCases\Pretty\VariableNaming.cs" />
<Compile Include="TestCases\Pretty\VariableNamingWithoutSymbols.cs" />
<None Include="TestCases\ILPretty\Issue959.cs" />
<None Include="TestCases\ILPretty\FSharpLoops_Debug.cs" />
<None Include="TestCases\ILPretty\FSharpLoops_Release.cs" />

16
ICSharpCode.Decompiler.Tests/PrettyTestRunner.cs

@ -212,7 +212,19 @@ namespace ICSharpCode.Decompiler.Tests @@ -212,7 +212,19 @@ namespace ICSharpCode.Decompiler.Tests
Run(cscOptions: cscOptions);
}
void Run([CallerMemberName] string testName = null, AssemblerOptions asmOptions = AssemblerOptions.None, CompilerOptions cscOptions = CompilerOptions.None)
[Test]
public void VariableNaming([ValueSource("defaultOptions")] CompilerOptions cscOptions)
{
Run(cscOptions: cscOptions);
}
[Test]
public void VariableNamingWithoutSymbols([ValueSource("defaultOptions")] CompilerOptions cscOptions)
{
Run(cscOptions: cscOptions, decompilerSettings: new DecompilerSettings { UseDebugSymbols = false });
}
void Run([CallerMemberName] string testName = null, AssemblerOptions asmOptions = AssemblerOptions.None, CompilerOptions cscOptions = CompilerOptions.None, DecompilerSettings decompilerSettings = null)
{
var ilFile = Path.Combine(TestCasePath, testName) + Tester.GetSuffix(cscOptions) + ".il";
var csFile = Path.Combine(TestCasePath, testName + ".cs");
@ -230,7 +242,7 @@ namespace ICSharpCode.Decompiler.Tests @@ -230,7 +242,7 @@ namespace ICSharpCode.Decompiler.Tests
}
var executable = Tester.AssembleIL(ilFile, asmOptions | AssemblerOptions.Library);
var decompiled = Tester.DecompileCSharp(executable);
var decompiled = Tester.DecompileCSharp(executable, decompilerSettings);
CodeAssert.FilesAreEqual(csFile, decompiled, Tester.GetPreprocessorSymbols(cscOptions).ToArray());
}

21
ICSharpCode.Decompiler.Tests/TestCases/Pretty/VariableNaming.cs

@ -0,0 +1,21 @@ @@ -0,0 +1,21 @@
namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty
{
internal class VariableNaming
{
private class C
{
public string Name;
public string Text;
}
private void Test(string text, C c)
{
string name = c.Name;
}
private void Test2(string text, C c)
{
string text2 = c.Text;
}
}
}

100
ICSharpCode.Decompiler.Tests/TestCases/Pretty/VariableNaming.il

@ -0,0 +1,100 @@ @@ -0,0 +1,100 @@
// Microsoft (R) .NET Framework IL Disassembler. Version 4.6.1055.0
// 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 sw5i42xa
{
.custom instance void [mscorlib]System.Runtime.CompilerServices.CompilationRelaxationsAttribute::.ctor(int32) = ( 01 00 08 00 00 00 00 00 )
.custom instance void [mscorlib]System.Runtime.CompilerServices.RuntimeCompatibilityAttribute::.ctor() = ( 01 00 01 00 54 02 16 57 72 61 70 4E 6F 6E 45 78 // ....T..WrapNonEx
63 65 70 74 69 6F 6E 54 68 72 6F 77 73 01 ) // ceptionThrows.
.permissionset reqmin
= {[mscorlib]System.Security.Permissions.SecurityPermissionAttribute = {property bool 'SkipVerification' = bool(true)}}
.hash algorithm 0x00008004
.ver 0:0:0:0
}
.module sw5i42xa.dll
// MVID: {863C0756-F3DB-4C0E-BC40-5DDA3E7F1B18}
.custom instance void [mscorlib]System.Security.UnverifiableCodeAttribute::.ctor() = ( 01 00 00 00 )
.imagebase 0x10000000
.file alignment 0x00000200
.stackreserve 0x00100000
.subsystem 0x0003 // WINDOWS_CUI
.corflags 0x00000001 // ILONLY
// Image base: 0x02C40000
// =============== CLASS MEMBERS DECLARATION ===================
.class private auto ansi beforefieldinit ICSharpCode.Decompiler.Tests.TestCases.Pretty.VariableNaming
extends [mscorlib]System.Object
{
.class auto ansi nested private beforefieldinit C
extends [mscorlib]System.Object
{
.field public string Name
.field public string Text
.method public hidebysig 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 C::.ctor
} // end of class C
.method private hidebysig instance void
Test(string text,
class ICSharpCode.Decompiler.Tests.TestCases.Pretty.VariableNaming/C c) cil managed
{
// Code size 9 (0x9)
.maxstack 1
.locals init (string V_0)
IL_0000: nop
IL_0001: ldarg.2
IL_0002: ldfld string ICSharpCode.Decompiler.Tests.TestCases.Pretty.VariableNaming/C::Name
IL_0007: stloc.0
IL_0008: ret
} // end of method VariableNaming::Test
.method private hidebysig instance void
Test2(string text,
class ICSharpCode.Decompiler.Tests.TestCases.Pretty.VariableNaming/C c) cil managed
{
// Code size 9 (0x9)
.maxstack 1
.locals init (string V_0)
IL_0000: nop
IL_0001: ldarg.2
IL_0002: ldfld string ICSharpCode.Decompiler.Tests.TestCases.Pretty.VariableNaming/C::Text
IL_0007: stloc.0
IL_0008: ret
} // end of method VariableNaming::Test2
.method public hidebysig 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 VariableNaming::.ctor
} // end of class ICSharpCode.Decompiler.Tests.TestCases.Pretty.VariableNaming
// =============================================================
// *********** DISASSEMBLY COMPLETE ***********************
// WARNING: Created Win32 resource file ../../../TestCases/Pretty\VariableNaming.res

96
ICSharpCode.Decompiler.Tests/TestCases/Pretty/VariableNaming.opt.il

@ -0,0 +1,96 @@ @@ -0,0 +1,96 @@
// Microsoft (R) .NET Framework IL Disassembler. Version 4.6.1055.0
// 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 kt4vyfax
{
.custom instance void [mscorlib]System.Runtime.CompilerServices.CompilationRelaxationsAttribute::.ctor(int32) = ( 01 00 08 00 00 00 00 00 )
.custom instance void [mscorlib]System.Runtime.CompilerServices.RuntimeCompatibilityAttribute::.ctor() = ( 01 00 01 00 54 02 16 57 72 61 70 4E 6F 6E 45 78 // ....T..WrapNonEx
63 65 70 74 69 6F 6E 54 68 72 6F 77 73 01 ) // ceptionThrows.
.permissionset reqmin
= {[mscorlib]System.Security.Permissions.SecurityPermissionAttribute = {property bool 'SkipVerification' = bool(true)}}
.hash algorithm 0x00008004
.ver 0:0:0:0
}
.module kt4vyfax.dll
// MVID: {2FDC68D5-1FEC-45A6-BADC-43373DBD141E}
.custom instance void [mscorlib]System.Security.UnverifiableCodeAttribute::.ctor() = ( 01 00 00 00 )
.imagebase 0x10000000
.file alignment 0x00000200
.stackreserve 0x00100000
.subsystem 0x0003 // WINDOWS_CUI
.corflags 0x00000001 // ILONLY
// Image base: 0x05090000
// =============== CLASS MEMBERS DECLARATION ===================
.class private auto ansi beforefieldinit ICSharpCode.Decompiler.Tests.TestCases.Pretty.VariableNaming
extends [mscorlib]System.Object
{
.class auto ansi nested private beforefieldinit C
extends [mscorlib]System.Object
{
.field public string Name
.field public string Text
.method public hidebysig 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 C::.ctor
} // end of class C
.method private hidebysig instance void
Test(string text,
class ICSharpCode.Decompiler.Tests.TestCases.Pretty.VariableNaming/C c) cil managed
{
// Code size 8 (0x8)
.maxstack 8
IL_0000: ldarg.2
IL_0001: ldfld string ICSharpCode.Decompiler.Tests.TestCases.Pretty.VariableNaming/C::Name
IL_0006: pop
IL_0007: ret
} // end of method VariableNaming::Test
.method private hidebysig instance void
Test2(string text,
class ICSharpCode.Decompiler.Tests.TestCases.Pretty.VariableNaming/C c) cil managed
{
// Code size 8 (0x8)
.maxstack 8
IL_0000: ldarg.2
IL_0001: ldfld string ICSharpCode.Decompiler.Tests.TestCases.Pretty.VariableNaming/C::Text
IL_0006: pop
IL_0007: ret
} // end of method VariableNaming::Test2
.method public hidebysig 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 VariableNaming::.ctor
} // end of class ICSharpCode.Decompiler.Tests.TestCases.Pretty.VariableNaming
// =============================================================
// *********** DISASSEMBLY COMPLETE ***********************
// WARNING: Created Win32 resource file ../../../TestCases/Pretty\VariableNaming.opt.res

99
ICSharpCode.Decompiler.Tests/TestCases/Pretty/VariableNaming.opt.roslyn.il

@ -0,0 +1,99 @@ @@ -0,0 +1,99 @@
// Microsoft (R) .NET Framework IL Disassembler. Version 4.6.1055.0
// 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 VariableNaming
{
.custom instance void [mscorlib]System.Runtime.CompilerServices.CompilationRelaxationsAttribute::.ctor(int32) = ( 01 00 08 00 00 00 00 00 )
.custom instance void [mscorlib]System.Runtime.CompilerServices.RuntimeCompatibilityAttribute::.ctor() = ( 01 00 01 00 54 02 16 57 72 61 70 4E 6F 6E 45 78 // ....T..WrapNonEx
63 65 70 74 69 6F 6E 54 68 72 6F 77 73 01 ) // ceptionThrows.
// --- The following custom attribute is added automatically, do not uncomment -------
// .custom instance void [mscorlib]System.Diagnostics.DebuggableAttribute::.ctor(valuetype [mscorlib]System.Diagnostics.DebuggableAttribute/DebuggingModes) = ( 01 00 02 00 00 00 00 00 )
.permissionset reqmin
= {[mscorlib]System.Security.Permissions.SecurityPermissionAttribute = {property bool 'SkipVerification' = bool(true)}}
.hash algorithm 0x00008004
.ver 0:0:0:0
}
.module VariableNaming.dll
// MVID: {9DEFE92E-9732-41C2-99CE-44CA361163E2}
.custom instance void [mscorlib]System.Security.UnverifiableCodeAttribute::.ctor() = ( 01 00 00 00 )
.imagebase 0x10000000
.file alignment 0x00000200
.stackreserve 0x00100000
.subsystem 0x0003 // WINDOWS_CUI
.corflags 0x00000001 // ILONLY
// Image base: 0x046D0000
// =============== CLASS MEMBERS DECLARATION ===================
.class private auto ansi beforefieldinit ICSharpCode.Decompiler.Tests.TestCases.Pretty.VariableNaming
extends [mscorlib]System.Object
{
.class auto ansi nested private beforefieldinit C
extends [mscorlib]System.Object
{
.field public string Name
.field public string Text
.method public hidebysig 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 C::.ctor
} // end of class C
.method private hidebysig instance void
Test(string text,
class ICSharpCode.Decompiler.Tests.TestCases.Pretty.VariableNaming/C c) cil managed
{
// Code size 8 (0x8)
.maxstack 8
IL_0000: ldarg.2
IL_0001: ldfld string ICSharpCode.Decompiler.Tests.TestCases.Pretty.VariableNaming/C::Name
IL_0006: pop
IL_0007: ret
} // end of method VariableNaming::Test
.method private hidebysig instance void
Test2(string text,
class ICSharpCode.Decompiler.Tests.TestCases.Pretty.VariableNaming/C c) cil managed
{
// Code size 8 (0x8)
.maxstack 8
IL_0000: ldarg.2
IL_0001: ldfld string ICSharpCode.Decompiler.Tests.TestCases.Pretty.VariableNaming/C::Text
IL_0006: pop
IL_0007: ret
} // end of method VariableNaming::Test2
.method public hidebysig 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 VariableNaming::.ctor
} // end of class ICSharpCode.Decompiler.Tests.TestCases.Pretty.VariableNaming
// =============================================================
// *********** DISASSEMBLY COMPLETE ***********************

105
ICSharpCode.Decompiler.Tests/TestCases/Pretty/VariableNaming.roslyn.il

@ -0,0 +1,105 @@ @@ -0,0 +1,105 @@
// Microsoft (R) .NET Framework IL Disassembler. Version 4.6.1055.0
// 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 VariableNaming
{
.custom instance void [mscorlib]System.Runtime.CompilerServices.CompilationRelaxationsAttribute::.ctor(int32) = ( 01 00 08 00 00 00 00 00 )
.custom instance void [mscorlib]System.Runtime.CompilerServices.RuntimeCompatibilityAttribute::.ctor() = ( 01 00 01 00 54 02 16 57 72 61 70 4E 6F 6E 45 78 // ....T..WrapNonEx
63 65 70 74 69 6F 6E 54 68 72 6F 77 73 01 ) // ceptionThrows.
// --- The following custom attribute is added automatically, do not uncomment -------
// .custom instance void [mscorlib]System.Diagnostics.DebuggableAttribute::.ctor(valuetype [mscorlib]System.Diagnostics.DebuggableAttribute/DebuggingModes) = ( 01 00 07 01 00 00 00 00 )
.permissionset reqmin
= {[mscorlib]System.Security.Permissions.SecurityPermissionAttribute = {property bool 'SkipVerification' = bool(true)}}
.hash algorithm 0x00008004
.ver 0:0:0:0
}
.module VariableNaming.dll
// MVID: {E0E0C356-381B-487C-973F-FB9568F9D931}
.custom instance void [mscorlib]System.Security.UnverifiableCodeAttribute::.ctor() = ( 01 00 00 00 )
.imagebase 0x10000000
.file alignment 0x00000200
.stackreserve 0x00100000
.subsystem 0x0003 // WINDOWS_CUI
.corflags 0x00000001 // ILONLY
// Image base: 0x03420000
// =============== CLASS MEMBERS DECLARATION ===================
.class private auto ansi beforefieldinit ICSharpCode.Decompiler.Tests.TestCases.Pretty.VariableNaming
extends [mscorlib]System.Object
{
.class auto ansi nested private beforefieldinit C
extends [mscorlib]System.Object
{
.field public string Name
.field public string Text
.method public hidebysig specialname rtspecialname
instance void .ctor() cil managed
{
// Code size 8 (0x8)
.maxstack 8
IL_0000: ldarg.0
IL_0001: call instance void [mscorlib]System.Object::.ctor()
IL_0006: nop
IL_0007: ret
} // end of method C::.ctor
} // end of class C
.method private hidebysig instance void
Test(string text,
class ICSharpCode.Decompiler.Tests.TestCases.Pretty.VariableNaming/C c) cil managed
{
// Code size 9 (0x9)
.maxstack 1
.locals init (string V_0)
IL_0000: nop
IL_0001: ldarg.2
IL_0002: ldfld string ICSharpCode.Decompiler.Tests.TestCases.Pretty.VariableNaming/C::Name
IL_0007: stloc.0
IL_0008: ret
} // end of method VariableNaming::Test
.method private hidebysig instance void
Test2(string text,
class ICSharpCode.Decompiler.Tests.TestCases.Pretty.VariableNaming/C c) cil managed
{
// Code size 9 (0x9)
.maxstack 1
.locals init (string V_0)
IL_0000: nop
IL_0001: ldarg.2
IL_0002: ldfld string ICSharpCode.Decompiler.Tests.TestCases.Pretty.VariableNaming/C::Text
IL_0007: stloc.0
IL_0008: ret
} // end of method VariableNaming::Test2
.method public hidebysig specialname rtspecialname
instance void .ctor() cil managed
{
// Code size 8 (0x8)
.maxstack 8
IL_0000: ldarg.0
IL_0001: call instance void [mscorlib]System.Object::.ctor()
IL_0006: nop
IL_0007: ret
} // end of method VariableNaming::.ctor
} // end of class ICSharpCode.Decompiler.Tests.TestCases.Pretty.VariableNaming
// =============================================================
// *********** DISASSEMBLY COMPLETE ***********************

21
ICSharpCode.Decompiler.Tests/TestCases/Pretty/VariableNamingWithoutSymbols.cs

@ -0,0 +1,21 @@ @@ -0,0 +1,21 @@
namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty
{
internal class VariableNamingWithoutSymbols
{
private class C
{
public string Name;
public string Text;
}
private void Test(string text, C c)
{
string name = c.Name;
}
private void Test2(string text, C c)
{
string text2 = c.Text;
}
}
}

100
ICSharpCode.Decompiler.Tests/TestCases/Pretty/VariableNamingWithoutSymbols.il

@ -0,0 +1,100 @@ @@ -0,0 +1,100 @@
// Microsoft (R) .NET Framework IL Disassembler. Version 4.6.1055.0
// 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 guxeth2f
{
.custom instance void [mscorlib]System.Runtime.CompilerServices.CompilationRelaxationsAttribute::.ctor(int32) = ( 01 00 08 00 00 00 00 00 )
.custom instance void [mscorlib]System.Runtime.CompilerServices.RuntimeCompatibilityAttribute::.ctor() = ( 01 00 01 00 54 02 16 57 72 61 70 4E 6F 6E 45 78 // ....T..WrapNonEx
63 65 70 74 69 6F 6E 54 68 72 6F 77 73 01 ) // ceptionThrows.
.permissionset reqmin
= {[mscorlib]System.Security.Permissions.SecurityPermissionAttribute = {property bool 'SkipVerification' = bool(true)}}
.hash algorithm 0x00008004
.ver 0:0:0:0
}
.module guxeth2f.dll
// MVID: {D7E12634-3178-4FDA-B3F4-CE4846CACB94}
.custom instance void [mscorlib]System.Security.UnverifiableCodeAttribute::.ctor() = ( 01 00 00 00 )
.imagebase 0x10000000
.file alignment 0x00000200
.stackreserve 0x00100000
.subsystem 0x0003 // WINDOWS_CUI
.corflags 0x00000001 // ILONLY
// Image base: 0x04ED0000
// =============== CLASS MEMBERS DECLARATION ===================
.class private auto ansi beforefieldinit ICSharpCode.Decompiler.Tests.TestCases.Pretty.VariableNamingWithoutSymbols
extends [mscorlib]System.Object
{
.class auto ansi nested private beforefieldinit C
extends [mscorlib]System.Object
{
.field public string Name
.field public string Text
.method public hidebysig 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 C::.ctor
} // end of class C
.method private hidebysig instance void
Test(string text,
class ICSharpCode.Decompiler.Tests.TestCases.Pretty.VariableNamingWithoutSymbols/C c) cil managed
{
// Code size 9 (0x9)
.maxstack 1
.locals init (string V_0)
IL_0000: nop
IL_0001: ldarg.2
IL_0002: ldfld string ICSharpCode.Decompiler.Tests.TestCases.Pretty.VariableNamingWithoutSymbols/C::Name
IL_0007: stloc.0
IL_0008: ret
} // end of method VariableNamingWithoutSymbols::Test
.method private hidebysig instance void
Test2(string text,
class ICSharpCode.Decompiler.Tests.TestCases.Pretty.VariableNamingWithoutSymbols/C c) cil managed
{
// Code size 9 (0x9)
.maxstack 1
.locals init (string V_0)
IL_0000: nop
IL_0001: ldarg.2
IL_0002: ldfld string ICSharpCode.Decompiler.Tests.TestCases.Pretty.VariableNamingWithoutSymbols/C::Text
IL_0007: stloc.0
IL_0008: ret
} // end of method VariableNamingWithoutSymbols::Test2
.method public hidebysig 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 VariableNamingWithoutSymbols::.ctor
} // end of class ICSharpCode.Decompiler.Tests.TestCases.Pretty.VariableNamingWithoutSymbols
// =============================================================
// *********** DISASSEMBLY COMPLETE ***********************
// WARNING: Created Win32 resource file ../../../TestCases/Pretty\VariableNamingWithoutSymbols.res

96
ICSharpCode.Decompiler.Tests/TestCases/Pretty/VariableNamingWithoutSymbols.opt.il

@ -0,0 +1,96 @@ @@ -0,0 +1,96 @@
// Microsoft (R) .NET Framework IL Disassembler. Version 4.6.1055.0
// 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 wl1juwwv
{
.custom instance void [mscorlib]System.Runtime.CompilerServices.CompilationRelaxationsAttribute::.ctor(int32) = ( 01 00 08 00 00 00 00 00 )
.custom instance void [mscorlib]System.Runtime.CompilerServices.RuntimeCompatibilityAttribute::.ctor() = ( 01 00 01 00 54 02 16 57 72 61 70 4E 6F 6E 45 78 // ....T..WrapNonEx
63 65 70 74 69 6F 6E 54 68 72 6F 77 73 01 ) // ceptionThrows.
.permissionset reqmin
= {[mscorlib]System.Security.Permissions.SecurityPermissionAttribute = {property bool 'SkipVerification' = bool(true)}}
.hash algorithm 0x00008004
.ver 0:0:0:0
}
.module wl1juwwv.dll
// MVID: {F60C4045-F949-4857-AE4D-AD0ED806A44F}
.custom instance void [mscorlib]System.Security.UnverifiableCodeAttribute::.ctor() = ( 01 00 00 00 )
.imagebase 0x10000000
.file alignment 0x00000200
.stackreserve 0x00100000
.subsystem 0x0003 // WINDOWS_CUI
.corflags 0x00000001 // ILONLY
// Image base: 0x03250000
// =============== CLASS MEMBERS DECLARATION ===================
.class private auto ansi beforefieldinit ICSharpCode.Decompiler.Tests.TestCases.Pretty.VariableNamingWithoutSymbols
extends [mscorlib]System.Object
{
.class auto ansi nested private beforefieldinit C
extends [mscorlib]System.Object
{
.field public string Name
.field public string Text
.method public hidebysig 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 C::.ctor
} // end of class C
.method private hidebysig instance void
Test(string text,
class ICSharpCode.Decompiler.Tests.TestCases.Pretty.VariableNamingWithoutSymbols/C c) cil managed
{
// Code size 8 (0x8)
.maxstack 8
IL_0000: ldarg.2
IL_0001: ldfld string ICSharpCode.Decompiler.Tests.TestCases.Pretty.VariableNamingWithoutSymbols/C::Name
IL_0006: pop
IL_0007: ret
} // end of method VariableNamingWithoutSymbols::Test
.method private hidebysig instance void
Test2(string text,
class ICSharpCode.Decompiler.Tests.TestCases.Pretty.VariableNamingWithoutSymbols/C c) cil managed
{
// Code size 8 (0x8)
.maxstack 8
IL_0000: ldarg.2
IL_0001: ldfld string ICSharpCode.Decompiler.Tests.TestCases.Pretty.VariableNamingWithoutSymbols/C::Text
IL_0006: pop
IL_0007: ret
} // end of method VariableNamingWithoutSymbols::Test2
.method public hidebysig 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 VariableNamingWithoutSymbols::.ctor
} // end of class ICSharpCode.Decompiler.Tests.TestCases.Pretty.VariableNamingWithoutSymbols
// =============================================================
// *********** DISASSEMBLY COMPLETE ***********************
// WARNING: Created Win32 resource file ../../../TestCases/Pretty\VariableNamingWithoutSymbols.opt.res

99
ICSharpCode.Decompiler.Tests/TestCases/Pretty/VariableNamingWithoutSymbols.opt.roslyn.il

@ -0,0 +1,99 @@ @@ -0,0 +1,99 @@
// Microsoft (R) .NET Framework IL Disassembler. Version 4.6.1055.0
// 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 VariableNamingWithoutSymbols
{
.custom instance void [mscorlib]System.Runtime.CompilerServices.CompilationRelaxationsAttribute::.ctor(int32) = ( 01 00 08 00 00 00 00 00 )
.custom instance void [mscorlib]System.Runtime.CompilerServices.RuntimeCompatibilityAttribute::.ctor() = ( 01 00 01 00 54 02 16 57 72 61 70 4E 6F 6E 45 78 // ....T..WrapNonEx
63 65 70 74 69 6F 6E 54 68 72 6F 77 73 01 ) // ceptionThrows.
// --- The following custom attribute is added automatically, do not uncomment -------
// .custom instance void [mscorlib]System.Diagnostics.DebuggableAttribute::.ctor(valuetype [mscorlib]System.Diagnostics.DebuggableAttribute/DebuggingModes) = ( 01 00 02 00 00 00 00 00 )
.permissionset reqmin
= {[mscorlib]System.Security.Permissions.SecurityPermissionAttribute = {property bool 'SkipVerification' = bool(true)}}
.hash algorithm 0x00008004
.ver 0:0:0:0
}
.module VariableNamingWithoutSymbols.dll
// MVID: {6DCCA4EB-C62E-49F5-9C21-5607777AD7D1}
.custom instance void [mscorlib]System.Security.UnverifiableCodeAttribute::.ctor() = ( 01 00 00 00 )
.imagebase 0x10000000
.file alignment 0x00000200
.stackreserve 0x00100000
.subsystem 0x0003 // WINDOWS_CUI
.corflags 0x00000001 // ILONLY
// Image base: 0x00970000
// =============== CLASS MEMBERS DECLARATION ===================
.class private auto ansi beforefieldinit ICSharpCode.Decompiler.Tests.TestCases.Pretty.VariableNamingWithoutSymbols
extends [mscorlib]System.Object
{
.class auto ansi nested private beforefieldinit C
extends [mscorlib]System.Object
{
.field public string Name
.field public string Text
.method public hidebysig 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 C::.ctor
} // end of class C
.method private hidebysig instance void
Test(string text,
class ICSharpCode.Decompiler.Tests.TestCases.Pretty.VariableNamingWithoutSymbols/C c) cil managed
{
// Code size 8 (0x8)
.maxstack 8
IL_0000: ldarg.2
IL_0001: ldfld string ICSharpCode.Decompiler.Tests.TestCases.Pretty.VariableNamingWithoutSymbols/C::Name
IL_0006: pop
IL_0007: ret
} // end of method VariableNamingWithoutSymbols::Test
.method private hidebysig instance void
Test2(string text,
class ICSharpCode.Decompiler.Tests.TestCases.Pretty.VariableNamingWithoutSymbols/C c) cil managed
{
// Code size 8 (0x8)
.maxstack 8
IL_0000: ldarg.2
IL_0001: ldfld string ICSharpCode.Decompiler.Tests.TestCases.Pretty.VariableNamingWithoutSymbols/C::Text
IL_0006: pop
IL_0007: ret
} // end of method VariableNamingWithoutSymbols::Test2
.method public hidebysig 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 VariableNamingWithoutSymbols::.ctor
} // end of class ICSharpCode.Decompiler.Tests.TestCases.Pretty.VariableNamingWithoutSymbols
// =============================================================
// *********** DISASSEMBLY COMPLETE ***********************

105
ICSharpCode.Decompiler.Tests/TestCases/Pretty/VariableNamingWithoutSymbols.roslyn.il

@ -0,0 +1,105 @@ @@ -0,0 +1,105 @@
// Microsoft (R) .NET Framework IL Disassembler. Version 4.6.1055.0
// 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 VariableNamingWithoutSymbols
{
.custom instance void [mscorlib]System.Runtime.CompilerServices.CompilationRelaxationsAttribute::.ctor(int32) = ( 01 00 08 00 00 00 00 00 )
.custom instance void [mscorlib]System.Runtime.CompilerServices.RuntimeCompatibilityAttribute::.ctor() = ( 01 00 01 00 54 02 16 57 72 61 70 4E 6F 6E 45 78 // ....T..WrapNonEx
63 65 70 74 69 6F 6E 54 68 72 6F 77 73 01 ) // ceptionThrows.
// --- The following custom attribute is added automatically, do not uncomment -------
// .custom instance void [mscorlib]System.Diagnostics.DebuggableAttribute::.ctor(valuetype [mscorlib]System.Diagnostics.DebuggableAttribute/DebuggingModes) = ( 01 00 07 01 00 00 00 00 )
.permissionset reqmin
= {[mscorlib]System.Security.Permissions.SecurityPermissionAttribute = {property bool 'SkipVerification' = bool(true)}}
.hash algorithm 0x00008004
.ver 0:0:0:0
}
.module VariableNamingWithoutSymbols.dll
// MVID: {F6531449-0EBC-4EFD-BFD6-4FF158C836FF}
.custom instance void [mscorlib]System.Security.UnverifiableCodeAttribute::.ctor() = ( 01 00 00 00 )
.imagebase 0x10000000
.file alignment 0x00000200
.stackreserve 0x00100000
.subsystem 0x0003 // WINDOWS_CUI
.corflags 0x00000001 // ILONLY
// Image base: 0x04C30000
// =============== CLASS MEMBERS DECLARATION ===================
.class private auto ansi beforefieldinit ICSharpCode.Decompiler.Tests.TestCases.Pretty.VariableNamingWithoutSymbols
extends [mscorlib]System.Object
{
.class auto ansi nested private beforefieldinit C
extends [mscorlib]System.Object
{
.field public string Name
.field public string Text
.method public hidebysig specialname rtspecialname
instance void .ctor() cil managed
{
// Code size 8 (0x8)
.maxstack 8
IL_0000: ldarg.0
IL_0001: call instance void [mscorlib]System.Object::.ctor()
IL_0006: nop
IL_0007: ret
} // end of method C::.ctor
} // end of class C
.method private hidebysig instance void
Test(string text,
class ICSharpCode.Decompiler.Tests.TestCases.Pretty.VariableNamingWithoutSymbols/C c) cil managed
{
// Code size 9 (0x9)
.maxstack 1
.locals init (string V_0)
IL_0000: nop
IL_0001: ldarg.2
IL_0002: ldfld string ICSharpCode.Decompiler.Tests.TestCases.Pretty.VariableNamingWithoutSymbols/C::Name
IL_0007: stloc.0
IL_0008: ret
} // end of method VariableNamingWithoutSymbols::Test
.method private hidebysig instance void
Test2(string text,
class ICSharpCode.Decompiler.Tests.TestCases.Pretty.VariableNamingWithoutSymbols/C c) cil managed
{
// Code size 9 (0x9)
.maxstack 1
.locals init (string V_0)
IL_0000: nop
IL_0001: ldarg.2
IL_0002: ldfld string ICSharpCode.Decompiler.Tests.TestCases.Pretty.VariableNamingWithoutSymbols/C::Text
IL_0007: stloc.0
IL_0008: ret
} // end of method VariableNamingWithoutSymbols::Test2
.method public hidebysig specialname rtspecialname
instance void .ctor() cil managed
{
// Code size 8 (0x8)
.maxstack 8
IL_0000: ldarg.0
IL_0001: call instance void [mscorlib]System.Object::.ctor()
IL_0006: nop
IL_0007: ret
} // end of method VariableNamingWithoutSymbols::.ctor
} // end of class ICSharpCode.Decompiler.Tests.TestCases.Pretty.VariableNamingWithoutSymbols
// =============================================================
// *********** DISASSEMBLY COMPLETE ***********************

2
ICSharpCode.Decompiler/CSharp/Transforms/DeclareVariables.cs

@ -161,7 +161,7 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms @@ -161,7 +161,7 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms
var v = function.RegisterVariable(
VariableKind.StackSlot,
type,
AssignVariableNames.GenerateVariableName(function, type)
AssignVariableNames.GenerateVariableName(function, type, stmt.Expression.Annotations.OfType<ILInstruction>().Where(AssignVariableNames.IsSupportedInstruction).FirstOrDefault())
);
stmt.Expression = new AssignmentExpression(
new IdentifierExpression(v.Name).WithRR(new ILVariableResolveResult(v, v.Type)),

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

@ -158,6 +158,22 @@ namespace ICSharpCode.Decompiler.IL.Transforms @@ -158,6 +158,22 @@ namespace ICSharpCode.Decompiler.IL.Transforms
}
}
/// <remarks>
/// Must be in sync with <see cref="GetNameFromInstruction" />.
/// </remarks>
internal static bool IsSupportedInstruction(object arg)
{
switch (arg) {
case LdObj ldobj:
case LdFlda ldflda:
case LdsFlda ldsflda:
case CallInstruction call:
return true;
default:
return false;
}
}
bool ConflictWithLocal(ILVariable v)
{
if (v.Kind == VariableKind.UsingLocal || v.Kind == VariableKind.ForeachLocal) {
@ -420,18 +436,29 @@ namespace ICSharpCode.Decompiler.IL.Transforms @@ -420,18 +436,29 @@ namespace ICSharpCode.Decompiler.IL.Transforms
return variableType;
}
internal static string GenerateForeachVariableName(ILFunction function, ILInstruction valueContext, ILVariable existingVariable = null)
static Dictionary<string, int> CollectReservedVariableNames(ILFunction function, ILVariable existingVariable)
{
if (function == null)
throw new ArgumentNullException(nameof(function));
var reservedVariableNames = new Dictionary<string, int>();
var rootFunction = function.Ancestors.OfType<ILFunction>().Single(f => f.Parent == null);
foreach (var v in rootFunction.Descendants.OfType<ILFunction>().SelectMany(m => m.Variables)) {
foreach (var f in rootFunction.Descendants.OfType<ILFunction>()) {
foreach (var p in rootFunction.Parameters) {
AddExistingName(reservedVariableNames, p.Name);
}
foreach (var v in f.Variables.Where(v => v.Kind != VariableKind.Parameter)) {
if (v != existingVariable)
AddExistingName(reservedVariableNames, v.Name);
}
}
foreach (var f in rootFunction.CecilMethod.DeclaringType.Fields.Select(f => f.Name))
AddExistingName(reservedVariableNames, f);
return reservedVariableNames;
}
internal static string GenerateForeachVariableName(ILFunction function, ILInstruction valueContext, ILVariable existingVariable = null)
{
if (function == null)
throw new ArgumentNullException(nameof(function));
var reservedVariableNames = CollectReservedVariableNames(function, existingVariable);
string baseName = GetNameFromInstruction(valueContext);
if (string.IsNullOrEmpty(baseName)) {
@ -467,19 +494,13 @@ namespace ICSharpCode.Decompiler.IL.Transforms @@ -467,19 +494,13 @@ namespace ICSharpCode.Decompiler.IL.Transforms
}
}
internal static string GenerateVariableName(ILFunction function, IType type, ILVariable existingVariable = null)
internal static string GenerateVariableName(ILFunction function, IType type, ILInstruction valueContext = null, ILVariable existingVariable = null)
{
if (function == null)
throw new ArgumentNullException(nameof(function));
var reservedVariableNames = new Dictionary<string, int>();
foreach (var v in function.Descendants.OfType<ILFunction>().SelectMany(m => m.Variables)) {
if (v != existingVariable)
AddExistingName(reservedVariableNames, v.Name);
}
foreach (var f in function.CecilMethod.DeclaringType.Fields.Select(f => f.Name))
AddExistingName(reservedVariableNames, f);
var reservedVariableNames = CollectReservedVariableNames(function, existingVariable);
string baseName = GetNameByType(type);
string baseName = valueContext != null ? GetNameFromInstruction(valueContext) ?? GetNameByType(type) : GetNameByType(type);
string proposedName = "obj";
if (!string.IsNullOrEmpty(baseName)) {

Loading…
Cancel
Save