Browse Source

Remove 'Custom' language version. Unify language settings panels.

pull/1471/head
Siegfried Pammer 7 years ago
parent
commit
535814cce4
  1. 26
      ICSharpCode.Decompiler/DecompilerSettings.cs
  2. 40
      ILSpy/DecompilationOptions.cs
  3. 9
      ILSpy/ILSpy.csproj
  4. 1
      ILSpy/Languages/CSharpLanguage.cs
  5. 58
      ILSpy/Options/CSharpDecompilerSettingsPanel.xaml
  6. 195
      ILSpy/Options/CSharpDecompilerSettingsPanel.xaml.cs
  7. 67
      ILSpy/Options/DecompilerSettingsPanel.xaml
  8. 232
      ILSpy/Options/DecompilerSettingsPanel.xaml.cs
  9. 13
      ILSpy/Options/DisplaySettings.cs
  10. 1
      ILSpy/Options/DisplaySettingsPanel.xaml
  11. 2
      ILSpy/Options/DisplaySettingsPanel.xaml.cs

26
ICSharpCode.Decompiler/DecompilerSettings.cs

@ -40,9 +40,18 @@ namespace ICSharpCode.Decompiler @@ -40,9 +40,18 @@ namespace ICSharpCode.Decompiler
/// appropriate for the specified language version.
/// </summary>
/// <remarks>
/// This does not imply that the resulting
/// This does not imply that the resulting code strictly uses only language features from that version.
/// Language constructs like generics or ref locals cannot be removed from the compiled code.
/// </remarks>
public DecompilerSettings(CSharp.LanguageVersion languageVersion)
{
SetLanguageVersion(languageVersion);
}
/// <summary>
/// Deactivates all language features from versions newer than <paramref name="languageVersion"/>.
/// </summary>
public void SetLanguageVersion(CSharp.LanguageVersion languageVersion)
{
// By default, all decompiler features are enabled.
// Disable some of them based on language version:
@ -198,7 +207,7 @@ namespace ICSharpCode.Decompiler @@ -198,7 +207,7 @@ namespace ICSharpCode.Decompiler
/// Decompile enumerators.
/// </summary>
[Category("C# 2.0 / VS 2005")]
[Description("Decompile enumerators")]
[Description("Decompile enumerators (yield return)")]
public bool YieldReturn {
get { return yieldReturn; }
set {
@ -266,6 +275,7 @@ namespace ICSharpCode.Decompiler @@ -266,6 +275,7 @@ namespace ICSharpCode.Decompiler
/// <summary>
/// Decompile [DecimalConstant(...)] as simple literal values.
/// </summary>
[Category("C# 1.0 / VS .NET")]
[Description("Decompile [DecimalConstant(...)] as simple literal values")]
public bool DecimalConstants {
get { return decimalConstants; }
@ -384,9 +394,8 @@ namespace ICSharpCode.Decompiler @@ -384,9 +394,8 @@ namespace ICSharpCode.Decompiler
/// <summary>
/// Gets/Sets whether to use braces for single-statement-blocks.
/// </summary>
[Category("Formatting")]
[Category("Other")]
[Description("Always use braces")]
[Browsable(false)]
public bool AlwaysUseBraces {
get { return alwaysUseBraces; }
set {
@ -448,7 +457,7 @@ namespace ICSharpCode.Decompiler @@ -448,7 +457,7 @@ namespace ICSharpCode.Decompiler
bool usingDeclarations = true;
[Category("C# 1.0 / VS .NET")]
[Browsable(false)]
[Description("Insert using declarations")]
public bool UsingDeclarations {
get { return usingDeclarations; }
set {
@ -533,7 +542,6 @@ namespace ICSharpCode.Decompiler @@ -533,7 +542,6 @@ namespace ICSharpCode.Decompiler
/// </summary>
[Category("Other")]
[Description("Use variable names from debug symbols, if available")]
[Browsable(false)]
public bool UseDebugSymbols {
get { return useDebugSymbols; }
set {
@ -640,7 +648,8 @@ namespace ICSharpCode.Decompiler @@ -640,7 +648,8 @@ namespace ICSharpCode.Decompiler
/// <summary>
/// Gets/Sets whether to include XML documentation comments in the decompiled code.
/// </summary>
[Browsable(false)]
[Category("Other")]
[Description("Include XML documentation comments in the decompiled code")]
public bool ShowXmlDocumentation {
get { return showXmlDocumentation; }
set {
@ -1030,7 +1039,7 @@ namespace ICSharpCode.Decompiler @@ -1030,7 +1039,7 @@ namespace ICSharpCode.Decompiler
bool removeDeadCode = false;
[Category("F#-specific options")]
[Browsable(false)]
[Description("Remove dead and side effect free code (use with caution!)")]
public bool RemoveDeadCode {
get { return removeDeadCode; }
set {
@ -1074,7 +1083,6 @@ namespace ICSharpCode.Decompiler @@ -1074,7 +1083,6 @@ namespace ICSharpCode.Decompiler
[Category("Other")]
[Description("Apply Windows Runtime projections on loaded assemblies")]
[Browsable(false)]
public bool ApplyWindowsRuntimeProjections {
get { return applyWindowsRuntimeProjections; }
set {

40
ILSpy/DecompilationOptions.cs

@ -18,7 +18,6 @@ @@ -18,7 +18,6 @@
using System;
using System.Threading;
using ICSharpCode.Decompiler;
using ICSharpCode.ILSpy.Options;
namespace ICSharpCode.ILSpy
@ -68,43 +67,24 @@ namespace ICSharpCode.ILSpy @@ -68,43 +67,24 @@ namespace ICSharpCode.ILSpy
internal bool IsDebug = false;
public DecompilationOptions()
: this(MainWindow.Instance.CurrentLanguageVersion, DecompilerSettingsPanel.CurrentDecompilerSettings, DisplaySettingsPanel.CurrentDisplaySettings, CSharpDecompilerSettingsPanel.CurrentCSharpSettings)
: this(MainWindow.Instance.CurrentLanguageVersion, DecompilerSettingsPanel.CurrentDecompilerSettings, DisplaySettingsPanel.CurrentDisplaySettings)
{
}
public DecompilationOptions(LanguageVersion version)
: this(version, DecompilerSettingsPanel.CurrentDecompilerSettings, DisplaySettingsPanel.CurrentDisplaySettings, CSharpDecompilerSettingsPanel.CurrentCSharpSettings)
: this(version, DecompilerSettingsPanel.CurrentDecompilerSettings, DisplaySettingsPanel.CurrentDisplaySettings)
{
}
public DecompilationOptions(LanguageVersion version, Options.DecompilerSettings settings, Options.DisplaySettings displaySettings, Decompiler.DecompilerSettings csharpSettings)
public DecompilationOptions(LanguageVersion version, Decompiler.DecompilerSettings settings, Options.DisplaySettings displaySettings)
{
if (version.Version == "Custom") {
var newSettings = this.DecompilerSettings = csharpSettings.Clone();
newSettings.AlwaysUseBraces = settings.AlwaysUseBraces;
newSettings.ExpandMemberDefinitions = displaySettings.ExpandMemberDefinitions;
newSettings.FoldBraces = displaySettings.FoldBraces;
newSettings.RemoveDeadCode = settings.RemoveDeadCode;
newSettings.ShowDebugInfo = settings.ShowDebugInfo;
newSettings.ShowXmlDocumentation = settings.ShowXmlDocumentation;
newSettings.UseDebugSymbols = settings.UseDebugSymbols;
newSettings.UsingDeclarations = settings.UsingDeclarations;
newSettings.ApplyWindowsRuntimeProjections = settings.ApplyWindowsRuntimeProjections;
} else {
if (!Enum.TryParse(version.Version, out Decompiler.CSharp.LanguageVersion languageVersion))
languageVersion = Decompiler.CSharp.LanguageVersion.Latest;
this.DecompilerSettings = new Decompiler.DecompilerSettings(languageVersion) {
AlwaysUseBraces = settings.AlwaysUseBraces,
ExpandMemberDefinitions = displaySettings.ExpandMemberDefinitions,
FoldBraces = displaySettings.FoldBraces,
RemoveDeadCode = settings.RemoveDeadCode,
ShowDebugInfo = settings.ShowDebugInfo,
ShowXmlDocumentation = settings.ShowXmlDocumentation,
UseDebugSymbols = settings.UseDebugSymbols,
UsingDeclarations = settings.UsingDeclarations,
ApplyWindowsRuntimeProjections = settings.ApplyWindowsRuntimeProjections,
};
}
if (!Enum.TryParse(version.Version, out Decompiler.CSharp.LanguageVersion languageVersion))
languageVersion = Decompiler.CSharp.LanguageVersion.Latest;
var newSettings = this.DecompilerSettings = settings.Clone();
newSettings.SetLanguageVersion(languageVersion);
newSettings.ExpandMemberDefinitions = displaySettings.ExpandMemberDefinitions;
newSettings.FoldBraces = displaySettings.FoldBraces;
newSettings.ShowDebugInfo = displaySettings.ShowDebugInfo;
}
}
}

9
ILSpy/ILSpy.csproj

@ -158,7 +158,7 @@ @@ -158,7 +158,7 @@
<Compile Include="Languages\IResourceFileHandler.cs" />
<Compile Include="Languages\Language.cs" />
<Compile Include="Languages\Languages.cs" />
<Compile Include="Options\CSharpDecompilerSettingsPanel.xaml.cs" />
<Compile Include="Options\DecompilerSettingsPanel.xaml.cs" />
<Compile Include="Search\LiteralSearchStrategy.cs" />
<Compile Include="LoadedAssembly.cs" />
<Compile Include="LoadedAssemblyExtensions.cs" />
@ -185,10 +185,6 @@ @@ -185,10 +185,6 @@
<Compile Include="OpenListDialog.xaml.cs">
<DependentUpon>OpenListDialog.xaml</DependentUpon>
</Compile>
<Compile Include="Options\DecompilerSettingsPanel.xaml.cs">
<DependentUpon>DecompilerSettingsPanel.xaml</DependentUpon>
<SubType>Code</SubType>
</Compile>
<Compile Include="Options\DisplaySettings.cs" />
<Compile Include="Options\DisplaySettingsPanel.xaml.cs">
<DependentUpon>DisplaySettingsPanel.xaml</DependentUpon>
@ -317,7 +313,6 @@ @@ -317,7 +313,6 @@
<Page Include="OpenFromGacDialog.xaml" />
<Page Include="OpenListDialog.xaml" />
<Page Include="NugetPackageBrowserDialog.xaml" />
<Page Include="Options\CSharpDecompilerSettingsPanel.xaml" />
<Page Include="Options\DecompilerSettingsPanel.xaml" />
<Page Include="Options\DisplaySettingsPanel.xaml" />
<Page Include="Options\MiscSettingsPanel.xaml" />
@ -391,7 +386,7 @@ @@ -391,7 +386,7 @@
<ItemGroup>
<Page Update="@(Page)" SubType="Designer" Generator="MSBuild:Compile" />
<Page Update="Options\CSharpDecompilerSettingsPanel.xaml">
<Page Update="Options\DecompilerSettingsPanel.xaml">
<Generator>MSBuild:Compile</Generator>
</Page>
</ItemGroup>

1
ILSpy/Languages/CSharpLanguage.cs

@ -102,7 +102,6 @@ namespace ICSharpCode.ILSpy @@ -102,7 +102,6 @@ namespace ICSharpCode.ILSpy
new LanguageVersion(Decompiler.CSharp.LanguageVersion.CSharp7_2.ToString(), "C# 7.2 / VS 2017.4"),
new LanguageVersion(Decompiler.CSharp.LanguageVersion.CSharp7_3.ToString(), "C# 7.3 / VS 2017.7"),
new LanguageVersion(Decompiler.CSharp.LanguageVersion.CSharp8_0.ToString(), "C# 8.0 / VS 2019"),
new LanguageVersion("Custom", "Custom"),
};
}
return versions;

58
ILSpy/Options/CSharpDecompilerSettingsPanel.xaml

@ -1,58 +0,0 @@ @@ -1,58 +0,0 @@
<UserControl x:Class="ICSharpCode.ILSpy.Options.CSharpDecompilerSettingsPanel"
x:ClassModifier="internal"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:options="clr-namespace:ICSharpCode.ILSpy.Options"
xmlns:controls="clr-namespace:ICSharpCode.ILSpy.Controls">
<UserControl.Resources>
<controls:BoolToVisibilityConverter x:Key="boolConv" />
<CollectionViewSource x:Key="SettingsCollection" Source="{Binding Settings}">
<CollectionViewSource.GroupDescriptions>
<PropertyGroupDescription PropertyName="Category" />
</CollectionViewSource.GroupDescriptions>
</CollectionViewSource>
</UserControl.Resources>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<TextBlock Margin="3" Grid.ColumnSpan="3" TextWrapping="Wrap" Text="The settings selected below are applied to the 'Custom' setting in the language drop-down. Note that some settings implicitly depend on each other, e.g.: LINQ expressions cannot be introduced without first transforming static calls to extension method calls." />
<ListBox Grid.Row="1" ItemsSource="{Binding Source={StaticResource SettingsCollection}}">
<ListBox.GroupStyle>
<GroupStyle>
<GroupStyle.Panel>
<ItemsPanelTemplate>
<VirtualizingStackPanel Orientation="Vertical" />
</ItemsPanelTemplate>
</GroupStyle.Panel>
<GroupStyle.ContainerStyle>
<Style TargetType="{x:Type GroupItem}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate>
<Expander Padding="0" BorderThickness="0" IsExpanded="True">
<Expander.Header>
<CheckBox Checked="OnGroupChecked" Unchecked="OnGroupUnchecked" Loaded="OnGroupLoaded" VerticalContentAlignment="Center"
FontSize="16" FontWeight="Bold" Content="{Binding Name}" />
</Expander.Header>
<ItemsPresenter/>
</Expander>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</GroupStyle.ContainerStyle>
</GroupStyle>
</ListBox.GroupStyle>
<ListBox.ItemTemplate>
<DataTemplate>
<CheckBox IsChecked="{Binding IsEnabled}" Content="{Binding Description}" />
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</Grid>
</UserControl>

195
ILSpy/Options/CSharpDecompilerSettingsPanel.xaml.cs

@ -1,195 +0,0 @@ @@ -1,195 +0,0 @@
// Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team
//
// Permission is hereby granted, free of charge, to any person obtaining a copy of this
// software and associated documentation files (the "Software"), to deal in the Software
// without restriction, including without limitation the rights to use, copy, modify, merge,
// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons
// to whom the Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all copies or
// substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
using System.ComponentModel;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Xml.Linq;
namespace ICSharpCode.ILSpy.Options
{
/// <summary>
/// Interaction logic for CSharpDecompilerSettingsPanel.xaml
/// </summary>
[ExportOptionPage(Title = "C# Decompiler", Order = 10)]
internal partial class CSharpDecompilerSettingsPanel : UserControl, IOptionPage
{
public CSharpDecompilerSettingsPanel()
{
InitializeComponent();
}
static Decompiler.DecompilerSettings currentCSharpSettings;
public static Decompiler.DecompilerSettings CurrentCSharpSettings {
get {
return currentCSharpSettings ?? (currentCSharpSettings = LoadDecompilerSettings(ILSpySettings.Load()));
}
}
public static Decompiler.DecompilerSettings LoadDecompilerSettings(ILSpySettings settings)
{
XElement e = settings["CustomCSharpDecompilerSettings"];
var newSettings = new Decompiler.DecompilerSettings();
var properties = typeof(Decompiler.DecompilerSettings).GetProperties()
.Where(p => p.GetCustomAttribute<BrowsableAttribute>()?.Browsable != false);
foreach (var p in properties) {
p.SetValue(newSettings, (bool?)e.Attribute(p.Name) ?? true);
}
return newSettings;
}
public void Load(ILSpySettings settings)
{
this.DataContext = new CSharpDecompilerSettings(LoadDecompilerSettings(settings));
}
public void Save(XElement root)
{
XElement section = new XElement("CustomCSharpDecompilerSettings");
var newSettings = ((CSharpDecompilerSettings)this.DataContext).ToDecompilerSettings();
var properties = typeof(Decompiler.DecompilerSettings).GetProperties()
.Where(p => p.GetCustomAttribute<BrowsableAttribute>()?.Browsable != false);
foreach (var p in properties) {
section.SetAttributeValue(p.Name, p.GetValue(newSettings));
}
XElement existingElement = root.Element("CustomCSharpDecompilerSettings");
if (existingElement != null)
existingElement.ReplaceWith(section);
else
root.Add(section);
currentCSharpSettings = newSettings;
}
private void OnGroupChecked(object sender, RoutedEventArgs e)
{
CheckGroup((CollectionViewGroup)((CheckBox)sender).DataContext, true);
}
private void OnGroupUnchecked(object sender, RoutedEventArgs e)
{
CheckGroup((CollectionViewGroup)((CheckBox)sender).DataContext, false);
}
void CheckGroup(CollectionViewGroup group, bool value)
{
foreach (var item in group.Items) {
switch (item) {
case CollectionViewGroup subGroup:
CheckGroup(subGroup, value);
break;
case CSharpDecompilerSetting setting:
setting.IsEnabled = value;
break;
}
}
}
bool IsGroupChecked(CollectionViewGroup group)
{
bool value = true;
foreach (var item in group.Items) {
switch (item) {
case CollectionViewGroup subGroup:
value = value && IsGroupChecked(subGroup);
break;
case CSharpDecompilerSetting setting:
value = value && setting.IsEnabled;
break;
}
}
return value;
}
private void OnGroupLoaded(object sender, RoutedEventArgs e)
{
CheckBox checkBox = (CheckBox)sender;
checkBox.IsChecked = IsGroupChecked((CollectionViewGroup)checkBox.DataContext);
}
}
public class CSharpDecompilerSettings : INotifyPropertyChanged
{
public CSharpDecompilerSetting[] Settings { get; set; }
public CSharpDecompilerSettings(Decompiler.DecompilerSettings settings)
{
Settings = typeof(Decompiler.DecompilerSettings).GetProperties()
.Where(p => p.GetCustomAttribute<BrowsableAttribute>()?.Browsable != false)
.Select(p => new CSharpDecompilerSetting(p) { IsEnabled = (bool)p.GetValue(settings) })
.OrderBy(item => item.Category)
.ThenBy(item => item.Description)
.ToArray();
}
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
public Decompiler.DecompilerSettings ToDecompilerSettings()
{
var settings = new Decompiler.DecompilerSettings();
foreach (var item in Settings) {
item.Property.SetValue(settings, item.IsEnabled);
}
return settings;
}
}
public class CSharpDecompilerSetting : INotifyPropertyChanged
{
bool isEnabled;
public CSharpDecompilerSetting(PropertyInfo p)
{
this.Property = p;
this.Category = p.GetCustomAttribute<CategoryAttribute>()?.Category ?? "Other";
this.Description = p.GetCustomAttribute<DescriptionAttribute>()?.Description ?? p.Name;
}
public PropertyInfo Property { get; }
public bool IsEnabled {
get => isEnabled;
set {
if (value != isEnabled) {
isEnabled = value;
OnPropertyChanged();
}
}
}
public string Description { get; set; }
public string Category { get; set; }
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
}

67
ILSpy/Options/DecompilerSettingsPanel.xaml

@ -2,18 +2,61 @@ @@ -2,18 +2,61 @@
x:ClassModifier="internal"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:options="clr-namespace:ICSharpCode.ILSpy.Options"
xmlns:controls="clr-namespace:ICSharpCode.ILSpy.Controls">
xmlns:options="clr-namespace:ICSharpCode.ILSpy.Options">
<UserControl.Resources>
<controls:BoolToVisibilityConverter x:Key="boolConv" />
<CollectionViewSource x:Key="SettingsCollection" Source="{Binding Settings}">
<CollectionViewSource.GroupDescriptions>
<PropertyGroupDescription PropertyName="Category" />
</CollectionViewSource.GroupDescriptions>
</CollectionViewSource>
</UserControl.Resources>
<StackPanel Margin="10">
<CheckBox IsChecked="{Binding UseDebugSymbols}">Use variable names from debug symbols, if available</CheckBox>
<CheckBox IsChecked="{Binding ShowDebugInfo}">Show info from debug symbols, if available</CheckBox>
<CheckBox IsChecked="{Binding ShowXmlDocumentation}">Show XML documentation in decompiled code</CheckBox>
<CheckBox IsChecked="{Binding RemoveDeadCode}">Remove dead and side effect free code (use with caution!)</CheckBox>
<CheckBox IsChecked="{Binding UsingDeclarations}">Insert using declarations</CheckBox>
<CheckBox IsChecked="{Binding AlwaysUseBraces}">Always use braces</CheckBox>
<CheckBox IsChecked="{Binding ApplyWindowsRuntimeProjections}">Apply Windows Runtime projections on loaded assemblies</CheckBox>
</StackPanel>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<TextBlock Margin="3" Grid.ColumnSpan="3" TextWrapping="Wrap" Text="The settings selected below are applied to the decompiler output in addition to the setting selected in the language drop-down. Note that some settings implicitly depend on each other, e.g.: LINQ expressions cannot be introduced without first transforming static calls to extension method calls." />
<ListBox Grid.Row="1" ItemsSource="{Binding Source={StaticResource SettingsCollection}}">
<ListBox.ItemContainerStyle>
<Style TargetType="ListBoxItem">
<Setter Property="IsTabStop" Value="False"/>
<Setter Property="Focusable" Value="False"/>
</Style>
</ListBox.ItemContainerStyle>
<ListBox.GroupStyle>
<GroupStyle>
<GroupStyle.Panel>
<ItemsPanelTemplate>
<VirtualizingStackPanel Orientation="Vertical" />
</ItemsPanelTemplate>
</GroupStyle.Panel>
<GroupStyle.ContainerStyle>
<Style TargetType="{x:Type GroupItem}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate>
<Expander Padding="0" BorderThickness="0" IsExpanded="True">
<Expander.Header>
<CheckBox Checked="OnGroupChecked" Unchecked="OnGroupUnchecked" Loaded="OnGroupLoaded" VerticalContentAlignment="Center"
FontSize="16" FontWeight="Bold" Content="{Binding Name}" />
</Expander.Header>
<ItemsPresenter/>
</Expander>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</GroupStyle.ContainerStyle>
</GroupStyle>
</ListBox.GroupStyle>
<ListBox.ItemTemplate>
<DataTemplate>
<CheckBox IsChecked="{Binding IsEnabled}" Content="{Binding Description}" />
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</Grid>
</UserControl>

232
ILSpy/Options/DecompilerSettingsPanel.xaml.cs

@ -17,8 +17,12 @@ @@ -17,8 +17,12 @@
// DEALINGS IN THE SOFTWARE.
using System.ComponentModel;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Xml.Linq;
namespace ICSharpCode.ILSpy.Options
@ -26,182 +30,166 @@ namespace ICSharpCode.ILSpy.Options @@ -26,182 +30,166 @@ namespace ICSharpCode.ILSpy.Options
/// <summary>
/// Interaction logic for DecompilerSettingsPanel.xaml
/// </summary>
[ExportOptionPage(Title = "Decompiler", Order = 0)]
partial class DecompilerSettingsPanel : UserControl, IOptionPage
[ExportOptionPage(Title = "Decompiler", Order = 10)]
internal partial class DecompilerSettingsPanel : UserControl, IOptionPage
{
public DecompilerSettingsPanel()
{
InitializeComponent();
}
public void Load(ILSpySettings settings)
{
this.DataContext = currentDecompilerSettings ?? LoadDecompilerSettings(settings);
}
static DecompilerSettings currentDecompilerSettings;
public static DecompilerSettings CurrentDecompilerSettings {
static Decompiler.DecompilerSettings currentDecompilerSettings;
public static Decompiler.DecompilerSettings CurrentDecompilerSettings {
get {
return currentDecompilerSettings ?? (currentDecompilerSettings = LoadDecompilerSettings(ILSpySettings.Load()));
}
}
public static DecompilerSettings LoadDecompilerSettings(ILSpySettings settings)
public static Decompiler.DecompilerSettings LoadDecompilerSettings(ILSpySettings settings)
{
XElement e = settings["DecompilerSettings"];
DecompilerSettings s = new DecompilerSettings();
s.ShowDebugInfo = (bool?)e.Attribute("showDebugInfo") ?? s.ShowDebugInfo;
s.ShowXmlDocumentation = (bool?)e.Attribute("xmlDoc") ?? s.ShowXmlDocumentation;
s.RemoveDeadCode = (bool?)e.Attribute("removeDeadCode") ?? s.RemoveDeadCode;
s.UsingDeclarations = (bool?)e.Attribute("usingDeclarations") ?? s.UsingDeclarations;
s.AlwaysUseBraces = (bool?)e.Attribute("alwaysUseBraces") ?? s.AlwaysUseBraces;
s.ApplyWindowsRuntimeProjections = (bool?)e.Attribute("applyWindowsRuntimeProjections") ?? s.ApplyWindowsRuntimeProjections;
return s;
}
var newSettings = new Decompiler.DecompilerSettings();
var properties = typeof(Decompiler.DecompilerSettings).GetProperties()
.Where(p => p.GetCustomAttribute<BrowsableAttribute>()?.Browsable != false);
foreach (var p in properties) {
p.SetValue(newSettings, (bool?)e.Attribute(p.Name) ?? true);
}
return newSettings;
}
public void Load(ILSpySettings settings)
{
this.DataContext = new DecompilerSettings(LoadDecompilerSettings(settings));
}
public void Save(XElement root)
{
DecompilerSettings s = (DecompilerSettings)this.DataContext;
XElement section = new XElement("DecompilerSettings");
section.SetAttributeValue("useDebugSymbols", s.UseDebugSymbols);
section.SetAttributeValue("showDebugInfo", s.ShowDebugInfo);
section.SetAttributeValue("xmlDoc", s.ShowXmlDocumentation);
section.SetAttributeValue("removeDeadCode", s.RemoveDeadCode);
section.SetAttributeValue("usingDeclarations", s.UsingDeclarations);
section.SetAttributeValue("alwaysUseBraces", s.AlwaysUseBraces);
section.SetAttributeValue("applyWindowsRuntimeProjections", s.ApplyWindowsRuntimeProjections);
var newSettings = ((DecompilerSettings)this.DataContext).ToDecompilerSettings();
var properties = typeof(Decompiler.DecompilerSettings).GetProperties()
.Where(p => p.GetCustomAttribute<BrowsableAttribute>()?.Browsable != false);
foreach (var p in properties) {
section.SetAttributeValue(p.Name, p.GetValue(newSettings));
}
XElement existingElement = root.Element("DecompilerSettings");
if (existingElement != null)
existingElement.ReplaceWith(section);
else
root.Add(section);
currentDecompilerSettings = s; // update cached settings
currentDecompilerSettings = newSettings;
}
}
public class DecompilerSettings : INotifyPropertyChanged
{
bool showXmlDocumentation = true;
private void OnGroupChecked(object sender, RoutedEventArgs e)
{
CheckGroup((CollectionViewGroup)((CheckBox)sender).DataContext, true);
}
private void OnGroupUnchecked(object sender, RoutedEventArgs e)
{
CheckGroup((CollectionViewGroup)((CheckBox)sender).DataContext, false);
}
/// <summary>
/// Gets/Sets whether to include XML documentation comments in the decompiled code.
/// </summary>
public bool ShowXmlDocumentation {
get { return showXmlDocumentation; }
set {
if (showXmlDocumentation != value) {
showXmlDocumentation = value;
OnPropertyChanged();
void CheckGroup(CollectionViewGroup group, bool value)
{
foreach (var item in group.Items) {
switch (item) {
case CollectionViewGroup subGroup:
CheckGroup(subGroup, value);
break;
case CSharpDecompilerSetting setting:
setting.IsEnabled = value;
break;
}
}
}
bool decompileMemberBodies = true;
/// <summary>
/// Gets/Sets whether member bodies should be decompiled.
/// </summary>
public bool DecompileMemberBodies {
get { return decompileMemberBodies; }
set {
if (decompileMemberBodies != value) {
decompileMemberBodies = value;
OnPropertyChanged();
bool IsGroupChecked(CollectionViewGroup group)
{
bool value = true;
foreach (var item in group.Items) {
switch (item) {
case CollectionViewGroup subGroup:
value = value && IsGroupChecked(subGroup);
break;
case CSharpDecompilerSetting setting:
value = value && setting.IsEnabled;
break;
}
}
return value;
}
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();
}
}
private void OnGroupLoaded(object sender, RoutedEventArgs e)
{
CheckBox checkBox = (CheckBox)sender;
checkBox.IsChecked = IsGroupChecked((CollectionViewGroup)checkBox.DataContext);
}
}
bool usingDeclarations = true;
public class DecompilerSettings : INotifyPropertyChanged
{
public CSharpDecompilerSetting[] Settings { get; set; }
public bool UsingDeclarations {
get { return usingDeclarations; }
set {
if (usingDeclarations != value) {
usingDeclarations = value;
OnPropertyChanged();
}
}
public DecompilerSettings(Decompiler.DecompilerSettings settings)
{
Settings = typeof(Decompiler.DecompilerSettings).GetProperties()
.Where(p => p.GetCustomAttribute<BrowsableAttribute>()?.Browsable != false)
.Select(p => new CSharpDecompilerSetting(p) { IsEnabled = (bool)p.GetValue(settings) })
.OrderBy(item => item.Category)
.ThenBy(item => item.Description)
.ToArray();
}
bool showDebugInfo;
public event PropertyChangedEventHandler PropertyChanged;
public bool ShowDebugInfo {
get { return showDebugInfo; }
set {
if (showDebugInfo != value) {
showDebugInfo = value;
OnPropertyChanged();
}
}
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
bool removeDeadCode = false;
public bool RemoveDeadCode {
get { return removeDeadCode; }
set {
if (removeDeadCode != value) {
removeDeadCode = value;
OnPropertyChanged();
}
public Decompiler.DecompilerSettings ToDecompilerSettings()
{
var settings = new Decompiler.DecompilerSettings();
foreach (var item in Settings) {
item.Property.SetValue(settings, item.IsEnabled);
}
return settings;
}
}
bool alwaysUseBraces = true;
public class CSharpDecompilerSetting : INotifyPropertyChanged
{
bool isEnabled;
/// <summary>
/// Gets/Sets whether to use braces for single-statement-blocks.
/// </summary>
public bool AlwaysUseBraces {
get { return alwaysUseBraces; }
set {
if (alwaysUseBraces != value) {
alwaysUseBraces = value;
OnPropertyChanged();
}
}
public CSharpDecompilerSetting(PropertyInfo p)
{
this.Property = p;
this.Category = p.GetCustomAttribute<CategoryAttribute>()?.Category ?? "Other";
this.Description = p.GetCustomAttribute<DescriptionAttribute>()?.Description ?? p.Name;
}
bool applyWindowsRuntimeProjections = true;
public PropertyInfo Property { get; }
/// <summary>
/// Gets/Sets whether to Windows Runtime projections to all loaded assemblies.
/// </summary>
public bool ApplyWindowsRuntimeProjections {
get { return applyWindowsRuntimeProjections; }
public bool IsEnabled {
get => isEnabled;
set {
if (applyWindowsRuntimeProjections != value) {
applyWindowsRuntimeProjections = value;
if (value != isEnabled) {
isEnabled = value;
OnPropertyChanged();
}
}
}
public string Description { get; set; }
public string Category { get; set; }
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
if (PropertyChanged != null) {
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
}
}

13
ILSpy/Options/DisplaySettings.cs

@ -155,6 +155,18 @@ namespace ICSharpCode.ILSpy.Options @@ -155,6 +155,18 @@ namespace ICSharpCode.ILSpy.Options
}
}
bool showDebugInfo;
public bool ShowDebugInfo {
get { return showDebugInfo; }
set {
if (showDebugInfo != value) {
showDebugInfo = value;
OnPropertyChanged();
}
}
}
public void CopyValues(DisplaySettings s)
{
this.SelectedFont = s.selectedFont;
@ -162,6 +174,7 @@ namespace ICSharpCode.ILSpy.Options @@ -162,6 +174,7 @@ namespace ICSharpCode.ILSpy.Options
this.ShowLineNumbers = s.showLineNumbers;
this.ShowMetadataTokens = s.showMetadataTokens;
this.ShowMetadataTokensInBase10 = s.showMetadataTokensInBase10;
this.ShowDebugInfo = s.showDebugInfo;
this.EnableWordWrap = s.enableWordWrap;
this.SortResults = s.sortResults;
this.FoldBraces = s.foldBraces;

1
ILSpy/Options/DisplaySettingsPanel.xaml

@ -62,6 +62,7 @@ @@ -62,6 +62,7 @@
<CheckBox IsChecked="{Binding ShowLineNumbers}">Show line numbers</CheckBox>
<CheckBox IsChecked="{Binding ShowMetadataTokens}">Show metadata tokens</CheckBox>
<CheckBox IsChecked="{Binding ShowMetadataTokensInBase10}">Show metadata tokens in base 10</CheckBox>
<CheckBox IsChecked="{Binding ShowDebugInfo}">Show info from debug symbols, if available</CheckBox>
<CheckBox IsChecked="{Binding EnableWordWrap}">Enable word wrap</CheckBox>
<CheckBox IsChecked="{Binding FoldBraces}">Enable folding on all blocks in braces</CheckBox>
<CheckBox IsChecked="{Binding SortResults}">Sort results by fitness</CheckBox>

2
ILSpy/Options/DisplaySettingsPanel.xaml.cs

@ -102,6 +102,7 @@ namespace ICSharpCode.ILSpy.Options @@ -102,6 +102,7 @@ namespace ICSharpCode.ILSpy.Options
s.ShowLineNumbers = (bool?)e.Attribute("ShowLineNumbers") ?? false;
s.ShowMetadataTokens = (bool?)e.Attribute("ShowMetadataTokens") ?? false;
s.ShowMetadataTokensInBase10 = (bool?)e.Attribute("ShowMetadataTokensInBase10") ?? false;
s.ShowDebugInfo = (bool?)e.Attribute("ShowDebugInfo") ?? false;
s.EnableWordWrap = (bool?)e.Attribute("EnableWordWrap") ?? false;
s.SortResults = (bool?)e.Attribute("SortResults") ?? true;
s.FoldBraces = (bool?)e.Attribute("FoldBraces") ?? false;
@ -120,6 +121,7 @@ namespace ICSharpCode.ILSpy.Options @@ -120,6 +121,7 @@ namespace ICSharpCode.ILSpy.Options
section.SetAttributeValue("ShowLineNumbers", s.ShowLineNumbers);
section.SetAttributeValue("ShowMetadataTokens", s.ShowMetadataTokens);
section.SetAttributeValue("ShowMetadataTokensInBase10", s.ShowMetadataTokensInBase10);
section.SetAttributeValue("ShowDebugInfo", s.ShowDebugInfo);
section.SetAttributeValue("EnableWordWrap", s.EnableWordWrap);
section.SetAttributeValue("SortResults", s.SortResults);
section.SetAttributeValue("FoldBraces", s.FoldBraces);

Loading…
Cancel
Save