diff --git a/ICSharpCode.Decompiler/Ast/AstBuilder.cs b/ICSharpCode.Decompiler/Ast/AstBuilder.cs index 0d22d96c2..3b2b71a7c 100644 --- a/ICSharpCode.Decompiler/Ast/AstBuilder.cs +++ b/ICSharpCode.Decompiler/Ast/AstBuilder.cs @@ -46,6 +46,8 @@ namespace Decompiler // disable whitespace in front of parentheses: formattingPolicy.BeforeMethodCallParentheses = false; formattingPolicy.BeforeMethodDeclarationParentheses = false; + formattingPolicy.BeforeConstructorDeclarationParentheses = false; + formattingPolicy.BeforeDelegateDeclarationParentheses = false; astCompileUnit.AcceptVisitor(new OutputVisitor(outputFormatter, formattingPolicy), null); } @@ -429,6 +431,10 @@ namespace Decompiler { ConstructorDeclaration astMethod = new ConstructorDeclaration(); astMethod.Modifiers = ConvertModifiers(methodDef); + if (methodDef.IsStatic) { + // don't show visibility for static ctors + astMethod.Modifiers &= ~Modifiers.VisibilityMask; + } astMethod.Parameters = MakeParameters(methodDef.Parameters); astMethod.Body = AstMethodBodyBuilder.CreateMethodBody(methodDef); return astMethod; diff --git a/ILSpy/ILSpy.csproj b/ILSpy/ILSpy.csproj index dfb909610..db4595910 100644 --- a/ILSpy/ILSpy.csproj +++ b/ILSpy/ILSpy.csproj @@ -128,6 +128,7 @@ + @@ -208,6 +209,10 @@ {6C55B776-26D4-4DB3-A6AB-87E783B2F3D1} ICSharpCode.AvalonEdit + + {3B2A5653-EC97-4001-BB9B-D90F1AF2C371} + ICSharpCode.NRefactory + {DDE2A481-8271-4EAC-A330-8FA6A38D13D1} ICSharpCode.TreeView diff --git a/ILSpy/TreeNodes/AssemblyTreeNode.cs b/ILSpy/TreeNodes/AssemblyTreeNode.cs index 2a003e4cd..c5ba67dc1 100644 --- a/ILSpy/TreeNodes/AssemblyTreeNode.cs +++ b/ILSpy/TreeNodes/AssemblyTreeNode.cs @@ -65,6 +65,10 @@ namespace ICSharpCode.ILSpy.TreeNodes get { return fileName; } } + public AssemblyList AssemblyList { + get { return assemblyList; } + } + public AssemblyDefinition AssemblyDefinition { get { try { diff --git a/ILSpy/TreeNodes/BaseTypesTreeNode.cs b/ILSpy/TreeNodes/BaseTypesTreeNode.cs index 1e883f8a2..072d173cb 100644 --- a/ILSpy/TreeNodes/BaseTypesTreeNode.cs +++ b/ILSpy/TreeNodes/BaseTypesTreeNode.cs @@ -119,13 +119,19 @@ namespace ICSharpCode.ILSpy.TreeNodes if (def != null) this.LazyLoading = true; // re-load children } + e.Handled = ActivateItem(this, def); + } + + internal static bool ActivateItem(SharpTreeNode node, TypeDefinition def) + { if (def != null) { - var assemblyListNode = this.Ancestors().OfType().FirstOrDefault(); + var assemblyListNode = node.Ancestors().OfType().FirstOrDefault(); if (assemblyListNode != null) { assemblyListNode.Select(assemblyListNode.AssemblyList.FindTypeNode(def)); - e.Handled = true; + return true; } } + return false; } public override void Decompile(Language language, ITextOutput output, DecompilationOptions options) diff --git a/ILSpy/TreeNodes/DerivedTypesTreeNode.cs b/ILSpy/TreeNodes/DerivedTypesTreeNode.cs new file mode 100644 index 000000000..734b8da2d --- /dev/null +++ b/ILSpy/TreeNodes/DerivedTypesTreeNode.cs @@ -0,0 +1,118 @@ +// 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.ObjectModel; +using System.Linq; + +using ICSharpCode.Decompiler; +using ICSharpCode.NRefactory.Utils; +using Mono.Cecil; + +namespace ICSharpCode.ILSpy.TreeNodes +{ + /// + /// Lists the super types of a class. + /// + sealed class DerivedTypesTreeNode : ILSpyTreeNode + { + readonly AssemblyList list; + readonly TypeDefinition type; + + public DerivedTypesTreeNode(AssemblyList list, TypeDefinition type) + { + this.list = list; + this.type = type; + this.LazyLoading = true; + } + + public override object Text { + get { return "Derived Types"; } + } + + public override object Icon { + get { return Images.SubTypes; } + } + + protected override void LoadChildren() + { + AddDerivedTypes(this.Children, type, list); + } + + internal static void AddDerivedTypes(ObservableCollection children, TypeDefinition type, AssemblyList list) + { + foreach (var asmNode in list.Assemblies) { + AssemblyDefinition asm = asmNode.AssemblyDefinition; + if (asm == null) + continue; + foreach (TypeDefinition td in TreeTraversal.PreOrder(asm.MainModule.Types, t => t.NestedTypes)) { + if (type.IsInterface && td.HasInterfaces) { + foreach (TypeReference typeRef in td.Interfaces) { + if (IsSameType(typeRef, type)) + children.Add(new DerivedTypesEntryNode(td, list)); + } + } else if (!type.IsInterface && IsSameType(td.BaseType, type)) { + children.Add(new DerivedTypesEntryNode(td, list)); + } + } + } + } + + static bool IsSameType(TypeReference typeRef, TypeDefinition type) + { + return typeRef.FullName == type.FullName; + } + + public override void Decompile(Language language, ITextOutput output, DecompilationOptions options) + { + EnsureLazyChildren(); + foreach (var child in this.Children) { + child.Decompile(language, output, options); + } + } + } + + class DerivedTypesEntryNode : ILSpyTreeNode + { + TypeDefinition def; + AssemblyList list; + + public DerivedTypesEntryNode(TypeDefinition def, AssemblyList list) + { + this.def = def; + this.list = list; + this.LazyLoading = true; + } + + public override bool ShowExpander { + get { + return !def.IsSealed && base.ShowExpander; + } + } + + public override object Text { + get { return def.FullName; } + } + + public override object Icon { + get { + return TypeTreeNode.GetIcon(def); + } + } + + protected override void LoadChildren() + { + DerivedTypesTreeNode.AddDerivedTypes(this.Children, def, list); + } + + public override void ActivateItem(System.Windows.RoutedEventArgs e) + { + e.Handled = BaseTypesEntryNode.ActivateItem(this, def); + } + + public override void Decompile(Language language, ITextOutput output, DecompilationOptions options) + { + language.WriteCommentLine(output, language.TypeToString(def)); + } + } +} diff --git a/ILSpy/TreeNodes/TypeTreeNode.cs b/ILSpy/TreeNodes/TypeTreeNode.cs index 791e5e318..e0b483907 100644 --- a/ILSpy/TreeNodes/TypeTreeNode.cs +++ b/ILSpy/TreeNodes/TypeTreeNode.cs @@ -90,6 +90,8 @@ namespace ICSharpCode.ILSpy.TreeNodes { if (type.BaseType != null || type.HasInterfaces) this.Children.Add(new BaseTypesTreeNode(type)); + if (!type.IsSealed) + this.Children.Add(new DerivedTypesTreeNode(parentAssemblyNode.AssemblyList, type)); foreach (TypeDefinition nestedType in type.NestedTypes) { this.Children.Add(new TypeTreeNode(nestedType, parentAssemblyNode)); }