From 831b4ffd39c9847e89ca8ff23599337c3e63be21 Mon Sep 17 00:00:00 2001 From: Daniel Grunwald Date: Sat, 5 Feb 2011 21:26:29 +0100 Subject: [PATCH] Disassemble assembly header. --- ILSpy/AssemblyTreeNode.cs | 5 ++ ILSpy/DecompilationOptions.cs | 25 ++++++ ILSpy/Decompiler/CSharpLanguage.cs | 7 +- ILSpy/Disassembler/DisassemblerHelpers.cs | 4 +- ILSpy/Disassembler/ILLanguage.cs | 40 +++++----- ILSpy/Disassembler/MethodBodyDisassembler.cs | 2 +- ILSpy/Disassembler/ReflectionDisassembler.cs | 80 +++++++++++++++++--- ILSpy/EventTreeNode.cs | 6 +- ILSpy/FieldTreeNode.cs | 6 +- ILSpy/ILSpy.csproj | 1 + ILSpy/ILSpyTreeNode.cs | 3 +- ILSpy/Language.cs | 21 +++-- ILSpy/MethodTreeNode.cs | 7 +- ILSpy/NamespaceTreeNode.cs | 8 +- ILSpy/PropertyTreeNode.cs | 6 +- ILSpy/TextView/DecompilerTextView.cs | 33 ++++++-- ILSpy/TextView/DecompilerTextView.xaml | 2 +- ILSpy/TypeTreeNode.cs | 7 +- 18 files changed, 188 insertions(+), 75 deletions(-) create mode 100644 ILSpy/DecompilationOptions.cs diff --git a/ILSpy/AssemblyTreeNode.cs b/ILSpy/AssemblyTreeNode.cs index 7efa9c67e..8e66a8aa5 100644 --- a/ILSpy/AssemblyTreeNode.cs +++ b/ILSpy/AssemblyTreeNode.cs @@ -209,5 +209,10 @@ namespace ICSharpCode.ILSpy else return FilterResult.Recurse; } + + public override void Decompile(Language language, ITextOutput output, DecompilationOptions options) + { + language.DecompileAssembly(assemblyTask.Result, output, options); + } } } diff --git a/ILSpy/DecompilationOptions.cs b/ILSpy/DecompilationOptions.cs new file mode 100644 index 000000000..06d46d75a --- /dev/null +++ b/ILSpy/DecompilationOptions.cs @@ -0,0 +1,25 @@ +// 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.Threading; + +namespace ICSharpCode.ILSpy +{ + /// + /// Options passed to the decompiler. + /// + public class DecompilationOptions + { + /// + /// Gets whether a full decompilation (all members recursively) is desired. + /// If this option is false, language bindings are allowed to show the only headers of the decompiled element's children. + /// + public bool FullDecompilation { get; set; } + + /// + /// Gets the cancellation token that is used to abort the decompiler. + /// + public CancellationToken CancellationToken { get; set; } + } +} diff --git a/ILSpy/Decompiler/CSharpLanguage.cs b/ILSpy/Decompiler/CSharpLanguage.cs index 615008c60..8d5dd1a23 100644 --- a/ILSpy/Decompiler/CSharpLanguage.cs +++ b/ILSpy/Decompiler/CSharpLanguage.cs @@ -17,12 +17,7 @@ // DEALINGS IN THE SOFTWARE. using System; -using System.IO; -using System.Threading; -using ICSharpCode.Decompiler; -using ICSharpCode.Decompiler.FlowAnalysis; using Mono.Cecil; -using Mono.Cecil.Rocks; namespace ICSharpCode.ILSpy.Decompiler { @@ -35,7 +30,7 @@ namespace ICSharpCode.ILSpy.Decompiler get { return "C#"; } } - public override void Decompile(MethodDefinition method, ITextOutput output, CancellationToken cancellationToken) + public override void DecompileMethod(MethodDefinition method, ITextOutput output, DecompilationOptions options) { throw new NotImplementedException(); } diff --git a/ILSpy/Disassembler/DisassemblerHelpers.cs b/ILSpy/Disassembler/DisassemblerHelpers.cs index 6d261d091..2747f4690 100644 --- a/ILSpy/Disassembler/DisassemblerHelpers.cs +++ b/ILSpy/Disassembler/DisassemblerHelpers.cs @@ -86,9 +86,11 @@ namespace ICSharpCode.ILSpy.Disassembler public static void WriteTo(this MethodReference method, ITextOutput writer) { + if (method.HasThis) + writer.Write("instance "); method.ReturnType.WriteTo(writer); writer.Write(' '); - method.DeclaringType.WriteTo(writer); + method.DeclaringType.WriteTo(writer, true); writer.Write("::"); writer.WriteReference(method.Name, method); writer.Write("("); diff --git a/ILSpy/Disassembler/ILLanguage.cs b/ILSpy/Disassembler/ILLanguage.cs index fd976e066..ee48c8098 100644 --- a/ILSpy/Disassembler/ILLanguage.cs +++ b/ILSpy/Disassembler/ILLanguage.cs @@ -5,7 +5,7 @@ // 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: -// 4 +// // The above copyright notice and this permission notice shall be included in all copies or // substantial portions of the Software. // @@ -17,14 +17,8 @@ // DEALINGS IN THE SOFTWARE. using System; -using System.ComponentModel; -using System.Linq; -using System.Threading; - -using ICSharpCode.Decompiler; -using ICSharpCode.Decompiler.FlowAnalysis; +using System.Collections.Generic; using Mono.Cecil; -using Mono.Cecil.Rocks; namespace ICSharpCode.ILSpy.Disassembler { @@ -45,29 +39,39 @@ namespace ICSharpCode.ILSpy.Disassembler get { return ICSharpCode.AvalonEdit.Highlighting.HighlightingManager.Instance.GetDefinition("ILAsm"); } } - public override void Decompile(MethodDefinition method, ITextOutput output, CancellationToken cancellationToken) + public override void DecompileMethod(MethodDefinition method, ITextOutput output, DecompilationOptions options) + { + new ReflectionDisassembler(output, detectControlStructure, options.CancellationToken).DisassembleMethod(method); + } + + public override void DecompileField(FieldDefinition field, ITextOutput output, DecompilationOptions options) + { + new ReflectionDisassembler(output, detectControlStructure, options.CancellationToken).DisassembleField(field); + } + + public override void DecompileProperty(PropertyDefinition property, ITextOutput output, DecompilationOptions options) { - new ReflectionDisassembler(output, detectControlStructure, cancellationToken).DisassembleMethod(method); + new ReflectionDisassembler(output, detectControlStructure, options.CancellationToken).DisassembleProperty(property); } - public override void Decompile(FieldDefinition field, ITextOutput output, CancellationToken cancellationToken) + public override void DecompileEvent(EventDefinition ev, ITextOutput output, DecompilationOptions options) { - new ReflectionDisassembler(output, detectControlStructure, cancellationToken).DisassembleField(field); + new ReflectionDisassembler(output, detectControlStructure, options.CancellationToken).DisassembleEvent(ev); } - public override void Decompile(PropertyDefinition property, ITextOutput output, CancellationToken cancellationToken) + public override void DecompileType(TypeDefinition type, ITextOutput output, DecompilationOptions options) { - new ReflectionDisassembler(output, detectControlStructure, cancellationToken).DisassembleProperty(property); + new ReflectionDisassembler(output, detectControlStructure, options.CancellationToken).DisassembleType(type); } - public override void Decompile(EventDefinition ev, ITextOutput output, CancellationToken cancellationToken) + public override void DecompileNamespace(string nameSpace, IEnumerable types, ITextOutput output, DecompilationOptions options) { - new ReflectionDisassembler(output, detectControlStructure, cancellationToken).DisassembleEvent(ev); + new ReflectionDisassembler(output, detectControlStructure, options.CancellationToken).DisassembleNamespace(nameSpace, types); } - public override void Decompile(TypeDefinition type, ITextOutput output, CancellationToken cancellationToken) + public override void DecompileAssembly(AssemblyDefinition assembly, ITextOutput output, DecompilationOptions options) { - new ReflectionDisassembler(output, detectControlStructure, cancellationToken).DisassembleType(type); + new ReflectionDisassembler(output, detectControlStructure, options.CancellationToken).WriteAssemblyHeader(assembly); } public override string TypeToString(TypeReference t) diff --git a/ILSpy/Disassembler/MethodBodyDisassembler.cs b/ILSpy/Disassembler/MethodBodyDisassembler.cs index 740a26ba7..4738bba02 100644 --- a/ILSpy/Disassembler/MethodBodyDisassembler.cs +++ b/ILSpy/Disassembler/MethodBodyDisassembler.cs @@ -5,7 +5,7 @@ // 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: -// 4 +// // The above copyright notice and this permission notice shall be included in all copies or // substantial portions of the Software. // diff --git a/ILSpy/Disassembler/ReflectionDisassembler.cs b/ILSpy/Disassembler/ReflectionDisassembler.cs index 8992240ae..005a7e0c7 100644 --- a/ILSpy/Disassembler/ReflectionDisassembler.cs +++ b/ILSpy/Disassembler/ReflectionDisassembler.cs @@ -1,5 +1,20 @@ -// 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) +// 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; using System.Collections.Generic; @@ -73,6 +88,8 @@ namespace ICSharpCode.ILSpy.Disassembler EnumNameCollection methodImpl = new EnumNameCollection() { { MethodImplAttributes.Synchronized, "synchronized" }, + { MethodImplAttributes.NoInlining, "noinlining" }, + { MethodImplAttributes.NoOptimization, "nooptimization" }, }; public void DisassembleMethod(MethodDefinition method) @@ -131,7 +148,7 @@ namespace ICSharpCode.ILSpy.Disassembler if (method.HasBody) methodBodyDisassembler.Disassemble(method.Body); - CloseBlock(); + CloseBlock("End of method " + method.DeclaringType.Name + "." + method.Name); } void WriteParameters(Collection parameters) @@ -248,7 +265,7 @@ namespace ICSharpCode.ILSpy.Disassembler } #endregion - #region Disassembly Type + #region Disassemble Type EnumNameCollection typeVisibility = new EnumNameCollection() { { TypeAttributes.Public, "public" }, { TypeAttributes.NotPublic, "private" }, @@ -299,7 +316,7 @@ namespace ICSharpCode.ILSpy.Disassembler output.WriteLine(); output.Indent(); output.Write("extends "); - type.BaseType.WriteTo(output); + type.BaseType.WriteTo(output, true); output.Unindent(); } @@ -317,6 +334,7 @@ namespace ICSharpCode.ILSpy.Disassembler foreach (var nestedType in type.NestedTypes) { cancellationToken.ThrowIfCancellationRequested(); DisassembleType(nestedType); + output.WriteLine(); } output.WriteLine(); } @@ -358,7 +376,7 @@ namespace ICSharpCode.ILSpy.Disassembler } output.WriteLine(); } - CloseBlock(); + CloseBlock("// End of class " + type.FullName); isInType = oldIsInType; } #endregion @@ -405,10 +423,12 @@ namespace ICSharpCode.ILSpy.Disassembler output.Indent(); } - void CloseBlock() + void CloseBlock(string comment = null) { output.Unindent(); output.Write("}"); + if (comment != null) + output.Write("// " + comment); output.MarkFoldEnd(); output.WriteLine(); } @@ -425,7 +445,7 @@ namespace ICSharpCode.ILSpy.Disassembler } } if ((val & ~tested) != 0) - output.Write("flag({0}) ", val & ~tested); + output.Write("flag({0:x4}) ", val & ~tested); } void WriteEnum(T enumValue, EnumNameCollection enumNames) where T : struct @@ -439,7 +459,7 @@ namespace ICSharpCode.ILSpy.Disassembler } } if (val != 0) { - output.Write("flag({0})", val); + output.Write("flag({0:x4})", val); output.Write(' '); } @@ -465,5 +485,47 @@ namespace ICSharpCode.ILSpy.Disassembler } } #endregion + + public void DisassembleNamespace(string nameSpace, IEnumerable types) + { + if (!string.IsNullOrEmpty(nameSpace)) { + output.Write(".namespace " + DisassemblerHelpers.Escape(nameSpace)); + OpenBlock(false); + } + bool oldIsInType = isInType; + isInType = true; + foreach (TypeDefinition td in types) { + cancellationToken.ThrowIfCancellationRequested(); + DisassembleType(td); + output.WriteLine(); + } + if (!string.IsNullOrEmpty(nameSpace)) { + CloseBlock(); + isInType = oldIsInType; + } + } + + public void WriteAssemblyHeader(AssemblyDefinition asm) + { + output.Write(".assembly " + DisassemblerHelpers.Escape(asm.Name.Name)); + OpenBlock(false); + Version v = asm.Name.Version; + if (v != null) { + output.WriteLine(".ver {0}:{1}:{2}:{3}", v.Major, v.Minor, v.Build, v.Revision); + } + if (asm.Name.HashAlgorithm != AssemblyHashAlgorithm.None) { + output.Write(".hash algorithm 0x{0:x8}", (int)asm.Name.HashAlgorithm); + if (asm.Name.HashAlgorithm == AssemblyHashAlgorithm.SHA1) + output.Write(" // SHA1"); + output.WriteLine(); + } + if (asm.Name.PublicKey != null && asm.Name.PublicKey.Length > 0) { + output.Write(".publickey = "); + WriteBlob(asm.Name.PublicKey); + output.WriteLine(); + } + WriteAttributes(asm.CustomAttributes); + CloseBlock(); + } } } diff --git a/ILSpy/EventTreeNode.cs b/ILSpy/EventTreeNode.cs index d52a0d5e3..23d2fb3e8 100644 --- a/ILSpy/EventTreeNode.cs +++ b/ILSpy/EventTreeNode.cs @@ -17,8 +17,6 @@ // DEALINGS IN THE SOFTWARE. using System; -using System.Threading; -using ICSharpCode.TreeView; using Mono.Cecil; namespace ICSharpCode.ILSpy @@ -74,9 +72,9 @@ namespace ICSharpCode.ILSpy return FilterResult.Hidden; } - public override void Decompile(Language language, ITextOutput output, CancellationToken cancellationToken) + public override void Decompile(Language language, ITextOutput output, DecompilationOptions options) { - language.Decompile(ev, output, cancellationToken); + language.DecompileEvent(ev, output, options); } } } diff --git a/ILSpy/FieldTreeNode.cs b/ILSpy/FieldTreeNode.cs index 057c3fa21..1e181ecee 100644 --- a/ILSpy/FieldTreeNode.cs +++ b/ILSpy/FieldTreeNode.cs @@ -17,8 +17,6 @@ // DEALINGS IN THE SOFTWARE. using System; -using System.Threading; -using ICSharpCode.TreeView; using Mono.Cecil; namespace ICSharpCode.ILSpy @@ -62,9 +60,9 @@ namespace ICSharpCode.ILSpy return FilterResult.Hidden; } - public override void Decompile(Language language, ITextOutput output, CancellationToken cancellationToken) + public override void Decompile(Language language, ITextOutput output, DecompilationOptions options) { - language.Decompile(field, output, cancellationToken); + language.DecompileField(field, output, options); } } } diff --git a/ILSpy/ILSpy.csproj b/ILSpy/ILSpy.csproj index 5e6e16718..241874ce1 100644 --- a/ILSpy/ILSpy.csproj +++ b/ILSpy/ILSpy.csproj @@ -86,6 +86,7 @@ + diff --git a/ILSpy/ILSpyTreeNode.cs b/ILSpy/ILSpyTreeNode.cs index f26873119..1ebd47364 100644 --- a/ILSpy/ILSpyTreeNode.cs +++ b/ILSpy/ILSpyTreeNode.cs @@ -20,7 +20,6 @@ using System; using System.Collections.ObjectModel; using System.Collections.Specialized; using System.ComponentModel; -using System.Threading; using ICSharpCode.TreeView; @@ -54,7 +53,7 @@ namespace ICSharpCode.ILSpy return FilterResult.Hidden; } - public virtual void Decompile(Language language, ITextOutput output, CancellationToken cancellationToken) + public virtual void Decompile(Language language, ITextOutput output, DecompilationOptions options) { } } diff --git a/ILSpy/Language.cs b/ILSpy/Language.cs index b4d6a8574..3beb2d238 100644 --- a/ILSpy/Language.cs +++ b/ILSpy/Language.cs @@ -17,13 +17,14 @@ // DEALINGS IN THE SOFTWARE. using System; +using System.Collections.Generic; using System.Threading; using Mono.Cecil; namespace ICSharpCode.ILSpy { /// - /// Description of ILanguage. + /// Base class for language-specific decompiler implementations. /// public abstract class Language { @@ -35,23 +36,31 @@ namespace ICSharpCode.ILSpy get { return ICSharpCode.AvalonEdit.Highlighting.HighlightingManager.Instance.GetDefinition(this.Name); } } - public virtual void Decompile(MethodDefinition method, ITextOutput output, CancellationToken cancellationToken) + public virtual void DecompileMethod(MethodDefinition method, ITextOutput output, DecompilationOptions options) { } - public virtual void Decompile(PropertyDefinition property, ITextOutput output, CancellationToken cancellationToken) + public virtual void DecompileProperty(PropertyDefinition property, ITextOutput output, DecompilationOptions options) { } - public virtual void Decompile(FieldDefinition field, ITextOutput output, CancellationToken cancellationToken) + public virtual void DecompileField(FieldDefinition field, ITextOutput output, DecompilationOptions options) { } - public virtual void Decompile(EventDefinition ev, ITextOutput output, CancellationToken cancellationToken) + public virtual void DecompileEvent(EventDefinition ev, ITextOutput output, DecompilationOptions options) { } - public virtual void Decompile(TypeDefinition type, ITextOutput output, CancellationToken cancellationToken) + public virtual void DecompileType(TypeDefinition type, ITextOutput output, DecompilationOptions options) + { + } + + public virtual void DecompileNamespace(string nameSpace, IEnumerable types, ITextOutput output, DecompilationOptions options) + { + } + + public virtual void DecompileAssembly(AssemblyDefinition assembly, ITextOutput output, DecompilationOptions options) { } diff --git a/ILSpy/MethodTreeNode.cs b/ILSpy/MethodTreeNode.cs index 2e4dfeb72..4b37bb8cb 100644 --- a/ILSpy/MethodTreeNode.cs +++ b/ILSpy/MethodTreeNode.cs @@ -18,9 +18,6 @@ using System; using System.Text; -using System.Threading; - -using ICSharpCode.TreeView; using Mono.Cecil; namespace ICSharpCode.ILSpy @@ -72,9 +69,9 @@ namespace ICSharpCode.ILSpy } } - public override void Decompile(Language language, ITextOutput output, CancellationToken cancellationToken) + public override void Decompile(Language language, ITextOutput output, DecompilationOptions options) { - language.Decompile(method, output, cancellationToken); + language.DecompileMethod(method, output, options); } public override FilterResult Filter(FilterSettings settings) diff --git a/ILSpy/NamespaceTreeNode.cs b/ILSpy/NamespaceTreeNode.cs index 7e54d9e92..5b8931360 100644 --- a/ILSpy/NamespaceTreeNode.cs +++ b/ILSpy/NamespaceTreeNode.cs @@ -17,8 +17,7 @@ // DEALINGS IN THE SOFTWARE. using System; -using System.Collections.ObjectModel; -using ICSharpCode.TreeView; +using System.Linq; namespace ICSharpCode.ILSpy { @@ -52,5 +51,10 @@ namespace ICSharpCode.ILSpy else return FilterResult.Recurse; } + + public override void Decompile(Language language, ITextOutput output, DecompilationOptions options) + { + language.DecompileNamespace(name, this.Children.Select(t => t.TypeDefinition), output, options); + } } } diff --git a/ILSpy/PropertyTreeNode.cs b/ILSpy/PropertyTreeNode.cs index cbac01259..1d032b566 100644 --- a/ILSpy/PropertyTreeNode.cs +++ b/ILSpy/PropertyTreeNode.cs @@ -17,8 +17,6 @@ // DEALINGS IN THE SOFTWARE. using System; -using System.Threading; -using ICSharpCode.TreeView; using Mono.Cecil; namespace ICSharpCode.ILSpy @@ -74,9 +72,9 @@ namespace ICSharpCode.ILSpy return FilterResult.Hidden; } - public override void Decompile(Language language, ITextOutput output, CancellationToken cancellationToken) + public override void Decompile(Language language, ITextOutput output, DecompilationOptions options) { - language.Decompile(property, output, cancellationToken); + language.DecompileProperty(property, output, options); } } } diff --git a/ILSpy/TextView/DecompilerTextView.cs b/ILSpy/TextView/DecompilerTextView.cs index e78a61f0b..aee8d6945 100644 --- a/ILSpy/TextView/DecompilerTextView.cs +++ b/ILSpy/TextView/DecompilerTextView.cs @@ -1,5 +1,20 @@ -// 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) +// 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; using System.Collections.Generic; @@ -12,7 +27,7 @@ using System.Windows.Controls; using System.Windows.Media.Animation; using System.Windows.Threading; using System.Xml; -using ICSharpCode.AvalonEdit; + using ICSharpCode.AvalonEdit.Folding; using ICSharpCode.AvalonEdit.Highlighting; using ICSharpCode.AvalonEdit.Highlighting.Xshd; @@ -63,7 +78,11 @@ namespace ICSharpCode.ILSpy.TextView // cancel the previous only after current was set to the new one (avoid that the old one still finishes successfully) if (previousCancellationTokenSource != null) previousCancellationTokenSource.Cancel(); - var task = RunDecompiler(ILSpy.Language.Current, treeNodes.ToArray(), myCancellationTokenSource.Token); + + DecompilationOptions options = new DecompilationOptions(); + options.CancellationToken = myCancellationTokenSource.Token; + + var task = RunDecompiler(ILSpy.Language.Current, treeNodes.ToArray(), options); Action continuation = delegate { try { if (currentCancellationTokenSource == myCancellationTokenSource) { @@ -97,14 +116,14 @@ namespace ICSharpCode.ILSpy.TextView task.ContinueWith(delegate { Dispatcher.BeginInvoke(DispatcherPriority.Normal, continuation); }); } - static Task RunDecompiler(ILSpy.Language language, ILSpyTreeNodeBase[] nodes, CancellationToken cancellationToken) + static Task RunDecompiler(ILSpy.Language language, ILSpyTreeNodeBase[] nodes, DecompilationOptions options) { return Task.Factory.StartNew( delegate { SmartTextOutput textOutput = new SmartTextOutput(); foreach (var node in nodes) { - cancellationToken.ThrowIfCancellationRequested(); - node.Decompile(language, textOutput, cancellationToken); + options.CancellationToken.ThrowIfCancellationRequested(); + node.Decompile(language, textOutput, options); } return textOutput; }); diff --git a/ILSpy/TextView/DecompilerTextView.xaml b/ILSpy/TextView/DecompilerTextView.xaml index f6e10a533..d5852ff2d 100644 --- a/ILSpy/TextView/DecompilerTextView.xaml +++ b/ILSpy/TextView/DecompilerTextView.xaml @@ -13,7 +13,7 @@ IsReadOnly="True" Background="{DynamicResource {x:Static SystemColors.InfoBrushKey}}" Foreground="{DynamicResource {x:Static SystemColors.InfoTextBrushKey}}" /> - + Decompiling... diff --git a/ILSpy/TypeTreeNode.cs b/ILSpy/TypeTreeNode.cs index 0030d1394..8ee30daa0 100644 --- a/ILSpy/TypeTreeNode.cs +++ b/ILSpy/TypeTreeNode.cs @@ -18,12 +18,9 @@ using System; using System.Collections.Generic; -using System.Collections.ObjectModel; using System.Linq; -using System.Threading; using System.Windows.Media; -using ICSharpCode.TreeView; using Mono.Cecil; namespace ICSharpCode.ILSpy @@ -121,9 +118,9 @@ namespace ICSharpCode.ILSpy } } - public override void Decompile(Language language, ITextOutput output, CancellationToken cancellationToken) + public override void Decompile(Language language, ITextOutput output, DecompilationOptions options) { - language.Decompile(type, output, cancellationToken); + language.DecompileType(type, output, options); } #region Icon