Browse Source

Read variable names from debug symbols (.pdb files), if available. Based on #122.

pull/150/head
Daniel Grunwald 15 years ago
parent
commit
51c2321a92
  1. 22
      ICSharpCode.Decompiler/Ast/NameVariables.cs
  2. 15
      ICSharpCode.Decompiler/DecompilerSettings.cs
  3. 30
      ILSpy.sln
  4. 1
      ILSpy/DecompilerSettingsPanel.xaml
  5. 2
      ILSpy/DecompilerSettingsPanel.xaml.cs
  6. 6
      ILSpy/ILSpy.csproj
  7. 22
      ILSpy/LoadedAssembly.cs
  8. 3
      ILSpy/OptionsDialog.xaml.cs
  9. 2
      Mono.Cecil/symbols/pdb/Mono.Cecil.Pdb/PdbHelper.cs
  10. 4
      TestPlugin/TestPlugin.csproj

22
ICSharpCode.Decompiler/Ast/NameVariables.cs

@ -42,8 +42,23 @@ namespace ICSharpCode.Decompiler.Ast @@ -42,8 +42,23 @@ namespace ICSharpCode.Decompiler.Ast
foreach (var p in parameters)
nv.AddExistingName(p.Name);
foreach (var v in variables) {
if (v.IsGenerated)
if (v.IsGenerated) {
// don't introduce names for variables generated by ILSpy - keep "expr"/"arg"
nv.AddExistingName(v.Name);
} else if (v.OriginalVariable != null && context.Settings.UseDebugSymbols) {
string varName = v.OriginalVariable.Name;
if (string.IsNullOrEmpty(varName) || varName.StartsWith("V_", StringComparison.Ordinal) || varName.StartsWith("CS$", StringComparison.Ordinal))
{
// don't use the name from the debug symbols if it looks like a generated name
v.Name = null;
} else {
// use the name from the debug symbols
// (but ensure we don't use the same name for two variables)
v.Name = nv.GetAlternativeName(varName);
}
} else {
v.Name = null;
}
}
// Now generate names:
foreach (ILVariable p in parameters) {
@ -51,9 +66,8 @@ namespace ICSharpCode.Decompiler.Ast @@ -51,9 +66,8 @@ namespace ICSharpCode.Decompiler.Ast
p.Name = nv.GenerateNameForVariable(p, methodBody);
}
foreach (ILVariable varDef in variables) {
if (!varDef.IsGenerated) {
if (string.IsNullOrEmpty(varDef.Name))
varDef.Name = nv.GenerateNameForVariable(varDef, methodBody);
}
}
}
@ -107,7 +121,7 @@ namespace ICSharpCode.Decompiler.Ast @@ -107,7 +121,7 @@ namespace ICSharpCode.Decompiler.Ast
string nameWithoutDigits = SplitName(oldVariableName, out number);
if (!typeNames.ContainsKey(nameWithoutDigits)) {
typeNames.Add(nameWithoutDigits, 0);
typeNames.Add(nameWithoutDigits, number - 1);
}
int count = ++typeNames[nameWithoutDigits];
if (count > 1) {

15
ICSharpCode.Decompiler/DecompilerSettings.cs

@ -164,6 +164,21 @@ namespace ICSharpCode.Decompiler @@ -164,6 +164,21 @@ namespace ICSharpCode.Decompiler
}
}
bool useDebugSymbols = true;
/// <summary>
/// Gets/Sets whether to use variable names from debug symbols, if available.
/// </summary>
public bool UseDebugSymbols {
get { return useDebugSymbols; }
set {
if (useDebugSymbols != value) {
useDebugSymbols = value;
OnPropertyChanged("UseDebugSymbols");
}
}
}
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged(string propertyName)

30
ILSpy.sln

@ -23,6 +23,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ICSharpCode.Decompiler.Test @@ -23,6 +23,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ICSharpCode.Decompiler.Test
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TestPlugin", "TestPlugin\TestPlugin.csproj", "{F32EBCC8-0E53-4421-867E-05B3D6E10C70}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Mono.Cecil.Pdb", "Mono.Cecil\symbols\pdb\Mono.Cecil.Pdb.csproj", "{63E6915C-7EA4-4D76-AB28-0D7191EEA626}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@ -50,11 +52,11 @@ Global @@ -50,11 +52,11 @@ Global
{D68133BD-1E63-496E-9EDE-4FBDBF77B486}.Debug|Any CPU.ActiveCfg = net_4_0_Debug|Any CPU
{D68133BD-1E63-496E-9EDE-4FBDBF77B486}.Debug|Any CPU.Build.0 = net_4_0_Debug|Any CPU
{D68133BD-1E63-496E-9EDE-4FBDBF77B486}.Debug|x86.ActiveCfg = net_4_0_Debug|Any CPU
{D68133BD-1E63-496E-9EDE-4FBDBF77B486}.Debug|x86.Build.0 = net_2_0_Debug|Any CPU
{D68133BD-1E63-496E-9EDE-4FBDBF77B486}.Debug|x86.Build.0 = net_4_0_Debug|Any CPU
{D68133BD-1E63-496E-9EDE-4FBDBF77B486}.Release|Any CPU.ActiveCfg = net_4_0_Release|Any CPU
{D68133BD-1E63-496E-9EDE-4FBDBF77B486}.Release|Any CPU.Build.0 = net_4_0_Release|Any CPU
{D68133BD-1E63-496E-9EDE-4FBDBF77B486}.Release|x86.ActiveCfg = net_4_0_Release|Any CPU
{D68133BD-1E63-496E-9EDE-4FBDBF77B486}.Release|x86.Build.0 = net_2_0_Debug|Any CPU
{D68133BD-1E63-496E-9EDE-4FBDBF77B486}.Release|x86.Build.0 = net_4_0_Debug|Any CPU
{6C55B776-26D4-4DB3-A6AB-87E783B2F3D1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{6C55B776-26D4-4DB3-A6AB-87E783B2F3D1}.Debug|Any CPU.Build.0 = Debug|Any CPU
{6C55B776-26D4-4DB3-A6AB-87E783B2F3D1}.Debug|x86.ActiveCfg = Debug|Any CPU
@ -87,14 +89,22 @@ Global @@ -87,14 +89,22 @@ Global
{FEC0DA52-C4A6-4710-BE36-B484A20C5E22}.Release|Any CPU.Build.0 = Release|x86
{FEC0DA52-C4A6-4710-BE36-B484A20C5E22}.Release|x86.ActiveCfg = Release|x86
{FEC0DA52-C4A6-4710-BE36-B484A20C5E22}.Release|x86.Build.0 = Release|x86
{F32EBCC8-0E53-4421-867E-05B3D6E10C70}.Debug|Any CPU.Build.0 = Debug|x86
{F32EBCC8-0E53-4421-867E-05B3D6E10C70}.Debug|Any CPU.ActiveCfg = Debug|x86
{F32EBCC8-0E53-4421-867E-05B3D6E10C70}.Debug|x86.Build.0 = Debug|x86
{F32EBCC8-0E53-4421-867E-05B3D6E10C70}.Debug|x86.ActiveCfg = Debug|x86
{F32EBCC8-0E53-4421-867E-05B3D6E10C70}.Release|Any CPU.Build.0 = Release|x86
{F32EBCC8-0E53-4421-867E-05B3D6E10C70}.Release|Any CPU.ActiveCfg = Release|x86
{F32EBCC8-0E53-4421-867E-05B3D6E10C70}.Release|x86.Build.0 = Release|x86
{F32EBCC8-0E53-4421-867E-05B3D6E10C70}.Release|x86.ActiveCfg = Release|x86
{F32EBCC8-0E53-4421-867E-05B3D6E10C70}.Debug|Any CPU.Build.0 = Debug|Any CPU
{F32EBCC8-0E53-4421-867E-05B3D6E10C70}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{F32EBCC8-0E53-4421-867E-05B3D6E10C70}.Debug|x86.Build.0 = Debug|Any CPU
{F32EBCC8-0E53-4421-867E-05B3D6E10C70}.Debug|x86.ActiveCfg = Debug|Any CPU
{F32EBCC8-0E53-4421-867E-05B3D6E10C70}.Release|Any CPU.Build.0 = Release|Any CPU
{F32EBCC8-0E53-4421-867E-05B3D6E10C70}.Release|Any CPU.ActiveCfg = Release|Any CPU
{F32EBCC8-0E53-4421-867E-05B3D6E10C70}.Release|x86.Build.0 = Release|Any CPU
{F32EBCC8-0E53-4421-867E-05B3D6E10C70}.Release|x86.ActiveCfg = Release|Any CPU
{63E6915C-7EA4-4D76-AB28-0D7191EEA626}.Debug|Any CPU.Build.0 = net_4_0_Debug|Any CPU
{63E6915C-7EA4-4D76-AB28-0D7191EEA626}.Debug|Any CPU.ActiveCfg = net_4_0_Debug|Any CPU
{63E6915C-7EA4-4D76-AB28-0D7191EEA626}.Debug|x86.Build.0 = net_4_0_Debug|Any CPU
{63E6915C-7EA4-4D76-AB28-0D7191EEA626}.Debug|x86.ActiveCfg = net_4_0_Debug|Any CPU
{63E6915C-7EA4-4D76-AB28-0D7191EEA626}.Release|Any CPU.Build.0 = net_4_0_Debug|Any CPU
{63E6915C-7EA4-4D76-AB28-0D7191EEA626}.Release|Any CPU.ActiveCfg = net_4_0_Release|Any CPU
{63E6915C-7EA4-4D76-AB28-0D7191EEA626}.Release|x86.Build.0 = net_4_0_Debug|Any CPU
{63E6915C-7EA4-4D76-AB28-0D7191EEA626}.Release|x86.ActiveCfg = net_4_0_Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE

1
ILSpy/DecompilerSettingsPanel.xaml

@ -6,5 +6,6 @@ @@ -6,5 +6,6 @@
<CheckBox IsChecked="{Binding AnonymousMethods}">Decompile anonymous methods/lambdas</CheckBox>
<CheckBox IsChecked="{Binding YieldReturn}">Decompile enumerators (yield return)</CheckBox>
<CheckBox IsChecked="{Binding QueryExpressions}" IsEnabled="{Binding AnonymousMethods}">Decompile query expressions</CheckBox>
<CheckBox IsChecked="{Binding UseDebugSymbols}">Use variable names from debug symbols, if available</CheckBox>
</StackPanel>
</UserControl>

2
ILSpy/DecompilerSettingsPanel.xaml.cs

@ -46,6 +46,7 @@ namespace ICSharpCode.ILSpy @@ -46,6 +46,7 @@ namespace ICSharpCode.ILSpy
s.AnonymousMethods = (bool?)e.Attribute("anonymousMethods") ?? s.AnonymousMethods;
s.YieldReturn = (bool?)e.Attribute("yieldReturn") ?? s.YieldReturn;
s.QueryExpressions = (bool?)e.Attribute("queryExpressions") ?? s.QueryExpressions;
s.UseDebugSymbols = (bool?)e.Attribute("useDebugSymbols") ?? s.UseDebugSymbols;
return s;
}
@ -56,6 +57,7 @@ namespace ICSharpCode.ILSpy @@ -56,6 +57,7 @@ namespace ICSharpCode.ILSpy
section.SetAttributeValue("anonymousMethods", s.AnonymousMethods);
section.SetAttributeValue("yieldReturn", s.YieldReturn);
section.SetAttributeValue("queryExpressions", s.QueryExpressions);
section.SetAttributeValue("useDebugSymbols", s.UseDebugSymbols);
XElement existingElement = root.Element("DecompilerSettings");
if (existingElement != null)

6
ILSpy/ILSpy.csproj

@ -262,6 +262,10 @@ @@ -262,6 +262,10 @@
<Project>{6C55B776-26D4-4DB3-A6AB-87E783B2F3D1}</Project>
<Name>ICSharpCode.AvalonEdit</Name>
</ProjectReference>
<ProjectReference Include="..\Mono.Cecil\symbols\pdb\Mono.Cecil.Pdb.csproj">
<Project>{63E6915C-7EA4-4D76-AB28-0D7191EEA626}</Project>
<Name>Mono.Cecil.Pdb</Name>
</ProjectReference>
<ProjectReference Include="..\NRefactory\ICSharpCode.NRefactory\ICSharpCode.NRefactory.csproj">
<Project>{3B2A5653-EC97-4001-BB9B-D90F1AF2C371}</Project>
<Name>ICSharpCode.NRefactory</Name>
@ -273,4 +277,4 @@ @@ -273,4 +277,4 @@
</ItemGroup>
<ItemGroup />
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.Targets" />
</Project>
</Project>

22
ILSpy/LoadedAssembly.cs

@ -69,7 +69,27 @@ namespace ICSharpCode.ILSpy @@ -69,7 +69,27 @@ namespace ICSharpCode.ILSpy
// runs on background thread
ReaderParameters p = new ReaderParameters();
p.AssemblyResolver = new MyAssemblyResolver(this);
return AssemblyDefinition.ReadAssembly(fileName, p);
try {
if (DecompilerSettingsPanel.CurrentDecompilerSettings.UseDebugSymbols) {
SetSymbolSettings(p);
}
return AssemblyDefinition.ReadAssembly(fileName, p);
} finally {
if (p.SymbolStream != null)
p.SymbolStream.Dispose();
}
}
private void SetSymbolSettings(ReaderParameters p)
{
// search for pdb in same directory as dll
string pdbName = Path.Combine(Path.GetDirectoryName(fileName), Path.GetFileNameWithoutExtension(fileName) + ".pdb");
if (File.Exists(pdbName)) {
p.ReadSymbols = true;
p.SymbolStream = File.OpenRead(pdbName);
}
// TODO: use symbol cache, get symbols from microsoft
}
[ThreadStatic]

3
ILSpy/OptionsDialog.xaml.cs

@ -87,8 +87,7 @@ namespace ICSharpCode.ILSpy @@ -87,8 +87,7 @@ namespace ICSharpCode.ILSpy
OptionsDialog dlg = new OptionsDialog();
dlg.Owner = MainWindow.Instance;
if (dlg.ShowDialog() == true) {
MainWindow.Instance.RefreshTreeViewFilter();
MainWindow.Instance.RefreshDecompiledView();
new RefreshCommand().Execute(parameter);
}
}
}

2
Mono.Cecil/symbols/pdb/Mono.Cecil.Pdb/PdbHelper.cs

@ -65,7 +65,7 @@ namespace Mono.Cecil.Pdb { @@ -65,7 +65,7 @@ namespace Mono.Cecil.Pdb {
public ISymbolReader GetSymbolReader (ModuleDefinition module, Stream symbolStream)
{
throw new NotImplementedException ();
return new PdbReader (symbolStream);
}
}

4
TestPlugin/TestPlugin.csproj

@ -3,7 +3,7 @@ @@ -3,7 +3,7 @@
<PropertyGroup>
<ProjectGuid>{F32EBCC8-0E53-4421-867E-05B3D6E10C70}</ProjectGuid>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">x86</Platform>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<OutputType>Library</OutputType>
<RootNamespace>TestPlugin</RootNamespace>
<AssemblyName>Test.Plugin</AssemblyName>
@ -15,7 +15,7 @@ @@ -15,7 +15,7 @@
<TreatWarningsAsErrors>false</TreatWarningsAsErrors>
<StartArguments>/separate</StartArguments>
</PropertyGroup>
<PropertyGroup Condition=" '$(Platform)' == 'x86' ">
<PropertyGroup Condition=" '$(Platform)' == 'AnyCPU' ">
<PlatformTarget>x86</PlatformTarget>
<RegisterForComInterop>False</RegisterForComInterop>
<GenerateSerializationAssemblies>Auto</GenerateSerializationAssemblies>

Loading…
Cancel
Save