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));
}