diff --git a/ICSharpCode.Decompiler/Ast/NameVariables.cs b/ICSharpCode.Decompiler/Ast/NameVariables.cs index 22e32d8f0..66f50ff13 100644 --- a/ICSharpCode.Decompiler/Ast/NameVariables.cs +++ b/ICSharpCode.Decompiler/Ast/NameVariables.cs @@ -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 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 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) { diff --git a/ICSharpCode.Decompiler/DecompilerSettings.cs b/ICSharpCode.Decompiler/DecompilerSettings.cs index 6c93f1d44..b4fd86485 100644 --- a/ICSharpCode.Decompiler/DecompilerSettings.cs +++ b/ICSharpCode.Decompiler/DecompilerSettings.cs @@ -164,6 +164,21 @@ namespace ICSharpCode.Decompiler } } + bool useDebugSymbols = true; + + /// + /// Gets/Sets whether to use variable names from debug symbols, if available. + /// + public bool UseDebugSymbols { + get { return useDebugSymbols; } + set { + if (useDebugSymbols != value) { + useDebugSymbols = value; + OnPropertyChanged("UseDebugSymbols"); + } + } + } + public event PropertyChangedEventHandler PropertyChanged; protected virtual void OnPropertyChanged(string propertyName) diff --git a/ILSpy.sln b/ILSpy.sln index 40c5aca08..7af0dee1b 100644 --- a/ILSpy.sln +++ b/ILSpy.sln @@ -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 {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 {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 diff --git a/ILSpy/DecompilerSettingsPanel.xaml b/ILSpy/DecompilerSettingsPanel.xaml index 2e72d4ce3..d9f0e938e 100644 --- a/ILSpy/DecompilerSettingsPanel.xaml +++ b/ILSpy/DecompilerSettingsPanel.xaml @@ -6,5 +6,6 @@ Decompile anonymous methods/lambdas Decompile enumerators (yield return) Decompile query expressions + Use variable names from debug symbols, if available \ No newline at end of file diff --git a/ILSpy/DecompilerSettingsPanel.xaml.cs b/ILSpy/DecompilerSettingsPanel.xaml.cs index b18161b62..56894411d 100644 --- a/ILSpy/DecompilerSettingsPanel.xaml.cs +++ b/ILSpy/DecompilerSettingsPanel.xaml.cs @@ -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 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) diff --git a/ILSpy/ILSpy.csproj b/ILSpy/ILSpy.csproj index 8d3896afa..5edcea10e 100644 --- a/ILSpy/ILSpy.csproj +++ b/ILSpy/ILSpy.csproj @@ -262,6 +262,10 @@ {6C55B776-26D4-4DB3-A6AB-87E783B2F3D1} ICSharpCode.AvalonEdit + + {63E6915C-7EA4-4D76-AB28-0D7191EEA626} + Mono.Cecil.Pdb + {3B2A5653-EC97-4001-BB9B-D90F1AF2C371} ICSharpCode.NRefactory @@ -273,4 +277,4 @@ - + \ No newline at end of file diff --git a/ILSpy/LoadedAssembly.cs b/ILSpy/LoadedAssembly.cs index d0e3f182c..d1184ebed 100644 --- a/ILSpy/LoadedAssembly.cs +++ b/ILSpy/LoadedAssembly.cs @@ -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] diff --git a/ILSpy/OptionsDialog.xaml.cs b/ILSpy/OptionsDialog.xaml.cs index fa975c82f..ebb7015d2 100644 --- a/ILSpy/OptionsDialog.xaml.cs +++ b/ILSpy/OptionsDialog.xaml.cs @@ -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); } } } diff --git a/Mono.Cecil/symbols/pdb/Mono.Cecil.Pdb/PdbHelper.cs b/Mono.Cecil/symbols/pdb/Mono.Cecil.Pdb/PdbHelper.cs index 0820b17f6..c5d4882ea 100644 --- a/Mono.Cecil/symbols/pdb/Mono.Cecil.Pdb/PdbHelper.cs +++ b/Mono.Cecil/symbols/pdb/Mono.Cecil.Pdb/PdbHelper.cs @@ -65,7 +65,7 @@ namespace Mono.Cecil.Pdb { public ISymbolReader GetSymbolReader (ModuleDefinition module, Stream symbolStream) { - throw new NotImplementedException (); + return new PdbReader (symbolStream); } } diff --git a/TestPlugin/TestPlugin.csproj b/TestPlugin/TestPlugin.csproj index 1dd33ea0e..54fe0e6f8 100644 --- a/TestPlugin/TestPlugin.csproj +++ b/TestPlugin/TestPlugin.csproj @@ -3,7 +3,7 @@ {F32EBCC8-0E53-4421-867E-05B3D6E10C70} Debug - x86 + AnyCPU Library TestPlugin Test.Plugin @@ -15,7 +15,7 @@ false /separate - + x86 False Auto