mirror of https://github.com/icsharpcode/ILSpy.git
15 changed files with 388 additions and 1 deletions
@ -0,0 +1,55 @@
@@ -0,0 +1,55 @@
|
||||
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
|
||||
// This code is distributed under MIT X11 license (for details please see \doc\license.txt)
|
||||
|
||||
using System; |
||||
using System.ComponentModel; |
||||
|
||||
namespace ICSharpCode.Decompiler |
||||
{ |
||||
/// <summary>
|
||||
/// Settings for the decompiler.
|
||||
/// </summary>
|
||||
public class DecompilerSettings : INotifyPropertyChanged |
||||
{ |
||||
bool anonymousMethods = true; |
||||
|
||||
/// <summary>
|
||||
/// Decompile anonymous methods/lambdas.
|
||||
/// </summary>
|
||||
public bool AnonymousMethods { |
||||
get { return anonymousMethods; } |
||||
set { |
||||
if (anonymousMethods != value) { |
||||
anonymousMethods = value; |
||||
OnPropertyChanged("AnonymousMethods"); |
||||
} |
||||
} |
||||
} |
||||
|
||||
bool yieldReturn = true; |
||||
|
||||
/// <summary>
|
||||
/// Decompile enumerators.
|
||||
/// </summary>
|
||||
public bool YieldReturn { |
||||
get { return yieldReturn; } |
||||
set { |
||||
if (yieldReturn != value) { |
||||
yieldReturn = value; |
||||
OnPropertyChanged("YieldReturn"); |
||||
} |
||||
} |
||||
} |
||||
|
||||
public event EventHandler YieldReturnChanged; |
||||
|
||||
public event PropertyChangedEventHandler PropertyChanged; |
||||
|
||||
protected virtual void OnPropertyChanged(string propertyName) |
||||
{ |
||||
if (PropertyChanged != null) { |
||||
PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); |
||||
} |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,15 @@
@@ -0,0 +1,15 @@
|
||||
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
|
||||
// This code is distributed under MIT X11 license (for details please see \doc\license.txt)
|
||||
|
||||
using System; |
||||
|
||||
namespace ICSharpCode.Decompiler.ILAst |
||||
{ |
||||
public class YieldReturnDecompiler |
||||
{ |
||||
// For a description on the code generated by the C# compiler for yield return:
|
||||
// http://csharpindepth.com/Articles/Chapter6/IteratorBlockImplementation.aspx
|
||||
|
||||
// not implemented yet...
|
||||
} |
||||
} |
@ -0,0 +1,103 @@
@@ -0,0 +1,103 @@
|
||||
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
|
||||
// This code is distributed under MIT X11 license (for details please see \doc\license.txt)
|
||||
|
||||
using System; |
||||
using System.Collections.Generic; |
||||
|
||||
public static class YieldReturn |
||||
{ |
||||
public static IEnumerable<string> SimpleYieldReturn() |
||||
{ |
||||
yield return "A"; |
||||
yield return "B"; |
||||
yield return "C"; |
||||
} |
||||
|
||||
public static IEnumerable<int> YieldReturnInLoop() |
||||
{ |
||||
for (int i = 0; i < 100; i++) { |
||||
yield return i; |
||||
} |
||||
} |
||||
|
||||
public static IEnumerable<int> YieldReturnWithTryFinally() |
||||
{ |
||||
yield return 0; |
||||
try { |
||||
yield return 1; |
||||
} finally { |
||||
Console.WriteLine("Finally!"); |
||||
} |
||||
yield return 2; |
||||
} |
||||
|
||||
|
||||
public static IEnumerable<string> YieldReturnWithNestedTryFinally(bool breakInMiddle) |
||||
{ |
||||
Console.WriteLine("Start of method - 1"); |
||||
yield return "Start of method"; |
||||
Console.WriteLine("Start of method - 2"); |
||||
try { |
||||
Console.WriteLine("Within outer try - 1"); |
||||
yield return "Within outer try"; |
||||
Console.WriteLine("Within outer try - 2"); |
||||
try { |
||||
Console.WriteLine("Within inner try - 1"); |
||||
yield return "Within inner try"; |
||||
Console.WriteLine("Within inner try - 2"); |
||||
if (breakInMiddle) |
||||
yield break; |
||||
Console.WriteLine("End of inner try - 1"); |
||||
yield return "End of inner try"; |
||||
Console.WriteLine("End of inner try - 2"); |
||||
} finally { |
||||
Console.WriteLine("Inner Finally"); |
||||
} |
||||
Console.WriteLine("End of outer try - 1"); |
||||
yield return "End of outer try"; |
||||
Console.WriteLine("End of outer try - 2"); |
||||
} finally { |
||||
Console.WriteLine("Outer Finally"); |
||||
} |
||||
Console.WriteLine("End of method - 1"); |
||||
yield return "End of method"; |
||||
Console.WriteLine("End of method - 2"); |
||||
} |
||||
|
||||
public static IEnumerable<string> YieldReturnWithTwoNonNestedFinallyBlocks(IEnumerable<string> input) |
||||
{ |
||||
// outer try-finally block
|
||||
foreach (string line in input) { |
||||
// nested try-finally block
|
||||
try { |
||||
yield return line; |
||||
} finally { |
||||
Console.WriteLine("Processed " + line); |
||||
} |
||||
} |
||||
yield return "A"; |
||||
yield return "B"; |
||||
yield return "C"; |
||||
yield return "D"; |
||||
yield return "E"; |
||||
yield return "F"; |
||||
// outer try-finally block
|
||||
foreach (string line in input) |
||||
yield return line.ToUpper(); |
||||
} |
||||
|
||||
public static IEnumerable<Func<string>> YieldReturnWithAnonymousMethods1(IEnumerable<string> input) |
||||
{ |
||||
foreach (string line in input) { |
||||
yield return () => line; |
||||
} |
||||
} |
||||
|
||||
public static IEnumerable<Func<string>> YieldReturnWithAnonymousMethods2(IEnumerable<string> input) |
||||
{ |
||||
foreach (string line in input) { |
||||
string copy = line; |
||||
yield return () => copy; |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,9 @@
@@ -0,0 +1,9 @@
|
||||
<UserControl x:Class="ICSharpCode.ILSpy.DecompilerSettingsPanel" |
||||
x:ClassModifier="internal" |
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" |
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"> |
||||
<StackPanel Margin="10"> |
||||
<CheckBox IsChecked="{Binding AnonymousMethods}">Decompile anonymous methods/lambdas</CheckBox> |
||||
<CheckBox IsChecked="{Binding YieldReturn}">Decompile enumerators (yield return)</CheckBox> |
||||
</StackPanel> |
||||
</UserControl> |
@ -0,0 +1,57 @@
@@ -0,0 +1,57 @@
|
||||
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
|
||||
// This code is distributed under MIT X11 license (for details please see \doc\license.txt)
|
||||
|
||||
using System; |
||||
using System.Collections.Generic; |
||||
using System.Text; |
||||
using System.Windows; |
||||
using System.Windows.Controls; |
||||
using System.Windows.Data; |
||||
using System.Windows.Documents; |
||||
using System.Windows.Input; |
||||
using System.Windows.Media; |
||||
using System.Xml.Linq; |
||||
using ICSharpCode.Decompiler; |
||||
|
||||
namespace ICSharpCode.ILSpy |
||||
{ |
||||
/// <summary>
|
||||
/// Interaction logic for DecompilerSettingsPanel.xaml
|
||||
/// </summary>
|
||||
[ExportOptionPage("Decompiler")] |
||||
partial class DecompilerSettingsPanel : UserControl, IOptionPage |
||||
{ |
||||
public DecompilerSettingsPanel() |
||||
{ |
||||
InitializeComponent(); |
||||
} |
||||
|
||||
public void Load(ILSpySettings settings) |
||||
{ |
||||
this.DataContext = LoadDecompilerSettings(settings); |
||||
} |
||||
|
||||
public static DecompilerSettings LoadDecompilerSettings(ILSpySettings settings) |
||||
{ |
||||
XElement e = settings["DecompilerSettings"]; |
||||
DecompilerSettings s = new DecompilerSettings(); |
||||
s.AnonymousMethods = (bool?)e.Attribute("anonymousMethods") ?? s.AnonymousMethods; |
||||
s.YieldReturn = (bool?)e.Attribute("yieldReturn") ?? s.YieldReturn; |
||||
return s; |
||||
} |
||||
|
||||
public void Save(XElement root) |
||||
{ |
||||
DecompilerSettings s = (DecompilerSettings)this.DataContext; |
||||
XElement section = new XElement("DecompilerSettings"); |
||||
section.SetAttributeValue("anonymousMethods", s.AnonymousMethods); |
||||
section.SetAttributeValue("yieldReturn", s.YieldReturn); |
||||
|
||||
XElement existingElement = root.Element("DecompilerSettings"); |
||||
if (existingElement != null) |
||||
existingElement.ReplaceWith(section); |
||||
else |
||||
root.Add(section); |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,21 @@
@@ -0,0 +1,21 @@
|
||||
<Window x:Class="ICSharpCode.ILSpy.OptionsDialog" |
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" |
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" |
||||
Style="{DynamicResource DialogWindow}" |
||||
WindowStartupLocation="CenterOwner" |
||||
ResizeMode="CanResizeWithGrip" |
||||
Title="Options" Height="400" Width="500"> |
||||
<Grid> |
||||
<Grid.RowDefinitions> |
||||
<RowDefinition |
||||
Height="1*" /> |
||||
<RowDefinition |
||||
Height="Auto" /> |
||||
</Grid.RowDefinitions> |
||||
<TabControl Name="tabControl" /> |
||||
<StackPanel Grid.Row="1" Orientation="Horizontal" HorizontalAlignment="Right" Margin="12,8"> |
||||
<Button IsDefault="True" Margin="2,0" Name="okButton" Click="OKButton_Click">OK</Button> |
||||
<Button IsCancel="True" Margin="2,0">Cancel</Button> |
||||
</StackPanel> |
||||
</Grid> |
||||
</Window> |
@ -0,0 +1,93 @@
@@ -0,0 +1,93 @@
|
||||
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
|
||||
// This code is distributed under MIT X11 license (for details please see \doc\license.txt)
|
||||
|
||||
using System; |
||||
using System.Collections.Generic; |
||||
using System.ComponentModel.Composition; |
||||
using System.Text; |
||||
using System.Windows; |
||||
using System.Windows.Controls; |
||||
using System.Windows.Data; |
||||
using System.Windows.Documents; |
||||
using System.Windows.Input; |
||||
using System.Windows.Media; |
||||
using System.Xml.Linq; |
||||
|
||||
namespace ICSharpCode.ILSpy |
||||
{ |
||||
/// <summary>
|
||||
/// Interaction logic for OptionsDialog.xaml
|
||||
/// </summary>
|
||||
public partial class OptionsDialog : Window |
||||
{ |
||||
[ImportMany("OptionPages", typeof(UIElement), RequiredCreationPolicy = CreationPolicy.NonShared)] |
||||
Lazy<UIElement, IOptionsMetadata>[] optionPages = null; |
||||
|
||||
public OptionsDialog() |
||||
{ |
||||
InitializeComponent(); |
||||
App.CompositionContainer.ComposeParts(this); |
||||
ILSpySettings settings = ILSpySettings.Load(); |
||||
foreach (var optionPage in optionPages) { |
||||
TabItem tabItem = new TabItem(); |
||||
tabItem.Header = optionPage.Metadata.Title; |
||||
tabItem.Content = optionPage.Value; |
||||
tabControl.Items.Add(tabItem); |
||||
|
||||
IOptionPage page = optionPage.Value as IOptionPage; |
||||
if (page != null) |
||||
page.Load(settings); |
||||
} |
||||
} |
||||
|
||||
void OKButton_Click(object sender, RoutedEventArgs e) |
||||
{ |
||||
ILSpySettings.Update( |
||||
delegate (XElement root) { |
||||
foreach (var optionPage in optionPages) { |
||||
IOptionPage page = optionPage.Value as IOptionPage; |
||||
if (page != null) |
||||
page.Save(root); |
||||
} |
||||
}); |
||||
this.DialogResult = true; |
||||
Close(); |
||||
} |
||||
} |
||||
|
||||
public interface IOptionsMetadata |
||||
{ |
||||
string Title { get; } |
||||
} |
||||
|
||||
public interface IOptionPage |
||||
{ |
||||
void Load(ILSpySettings settings); |
||||
void Save(XElement root); |
||||
} |
||||
|
||||
[MetadataAttribute] |
||||
[AttributeUsage(AttributeTargets.Class, AllowMultiple=false)] |
||||
public class ExportOptionPageAttribute : ExportAttribute |
||||
{ |
||||
public ExportOptionPageAttribute(string title) |
||||
: base("OptionPages", typeof(UIElement)) |
||||
{ |
||||
this.Title = title; |
||||
} |
||||
|
||||
public string Title { get; private set; } |
||||
} |
||||
|
||||
[ExportMainMenuCommand(Menu = "_View", Header = "_Options", MenuCategory = "Options", MenuOrder = 999)] |
||||
sealed class ShowOptionsCommand : SimpleCommand |
||||
{ |
||||
public override void Execute(object parameter) |
||||
{ |
||||
OptionsDialog dlg = new OptionsDialog(); |
||||
dlg.Owner = MainWindow.Instance; |
||||
if (dlg.ShowDialog() == true) |
||||
MainWindow.Instance.RefreshDecompiledView(); |
||||
} |
||||
} |
||||
} |
Loading…
Reference in new issue