Browse Source

Fix #2666: Namespace Nesting in the Tree View (based on code by @ds5678 provided in #2667)

pull/2639/head
Siegfried Pammer 4 years ago
parent
commit
f1d06e2e83
  1. 14
      ILSpy/Options/DisplaySettings.cs
  2. 1
      ILSpy/Options/DisplaySettingsPanel.xaml
  3. 2
      ILSpy/Options/DisplaySettingsPanel.xaml.cs
  4. 11
      ILSpy/Properties/Resources.Designer.cs
  5. 3
      ILSpy/Properties/Resources.resx
  6. 58
      ILSpy/TreeNodes/AssemblyTreeNode.cs

14
ILSpy/Options/DisplaySettings.cs

@ -273,6 +273,19 @@ namespace ICSharpCode.ILSpy.Options @@ -273,6 +273,19 @@ namespace ICSharpCode.ILSpy.Options
}
}
bool useNestedNamespaceNodes = true;
public bool UseNestedNamespaceNodes {
get { return useNestedNamespaceNodes; }
set {
if (useNestedNamespaceNodes != value)
{
useNestedNamespaceNodes = value;
OnPropertyChanged();
}
}
}
private bool styleWindowTitleBar;
public bool StyleWindowTitleBar {
@ -318,6 +331,7 @@ namespace ICSharpCode.ILSpy.Options @@ -318,6 +331,7 @@ namespace ICSharpCode.ILSpy.Options
this.HighlightMatchingBraces = s.highlightMatchingBraces;
this.HighlightCurrentLine = s.highlightCurrentLine;
this.HideEmptyMetadataTables = s.hideEmptyMetadataTables;
this.UseNestedNamespaceNodes = s.useNestedNamespaceNodes;
this.ShowRawOffsetsAndBytesBeforeInstruction = s.showRawOffsetsAndBytesBeforeInstruction;
this.StyleWindowTitleBar = s.styleWindowTitleBar;
}

1
ILSpy/Options/DisplaySettingsPanel.xaml

@ -90,6 +90,7 @@ @@ -90,6 +90,7 @@
<CheckBox IsChecked="{Binding ShowMetadataTokens}" Content="{x:Static properties:Resources.ShowMetadataTokens}"></CheckBox>
<CheckBox IsChecked="{Binding ShowMetadataTokensInBase10}" Content="{x:Static properties:Resources.ShowMetadataTokensInBase10}"></CheckBox>
<CheckBox IsChecked="{Binding HideEmptyMetadataTables}" Content="{x:Static properties:Resources.HideEmptyMetadataTables}"></CheckBox>
<CheckBox IsChecked="{Binding UseNestedNamespaceNodes}" Content="{x:Static properties:Resources.UseNestedNamespaceNodes}"></CheckBox>
</StackPanel>
</GroupBox>
<GroupBox Header="{x:Static properties:Resources.OtherOptions}">

2
ILSpy/Options/DisplaySettingsPanel.xaml.cs

@ -123,6 +123,7 @@ namespace ICSharpCode.ILSpy.Options @@ -123,6 +123,7 @@ namespace ICSharpCode.ILSpy.Options
s.HighlightMatchingBraces = (bool?)e.Attribute("HighlightMatchingBraces") ?? true;
s.HighlightCurrentLine = (bool?)e.Attribute("HighlightCurrentLine") ?? false;
s.HideEmptyMetadataTables = (bool?)e.Attribute("HideEmptyMetadataTables") ?? true;
s.UseNestedNamespaceNodes = (bool?)e.Attribute("UseNestedNamespaceNodes") ?? false;
s.ShowRawOffsetsAndBytesBeforeInstruction = (bool?)e.Attribute("ShowRawOffsetsAndBytesBeforeInstruction") ?? false;
s.StyleWindowTitleBar = (bool?)e.Attribute("StyleWindowTitleBar") ?? false;
@ -151,6 +152,7 @@ namespace ICSharpCode.ILSpy.Options @@ -151,6 +152,7 @@ namespace ICSharpCode.ILSpy.Options
section.SetAttributeValue("HighlightMatchingBraces", s.HighlightMatchingBraces);
section.SetAttributeValue("HighlightCurrentLine", s.HighlightCurrentLine);
section.SetAttributeValue("HideEmptyMetadataTables", s.HideEmptyMetadataTables);
section.SetAttributeValue("UseNestedNamespaceNodes", s.UseNestedNamespaceNodes);
section.SetAttributeValue("ShowRawOffsetsAndBytesBeforeInstruction", s.ShowRawOffsetsAndBytesBeforeInstruction);
section.SetAttributeValue("StyleWindowTitleBar", s.StyleWindowTitleBar);

11
ILSpy/Properties/Resources.Designer.cs generated

@ -19,7 +19,7 @@ namespace ICSharpCode.ILSpy.Properties { @@ -19,7 +19,7 @@ namespace ICSharpCode.ILSpy.Properties {
// class via a tool like ResGen or Visual Studio.
// To add or remove a member, edit your .ResX file then rerun ResGen
// with the /str option, or rebuild your VS project.
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "16.0.0.0")]
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
public class Resources {
@ -2673,6 +2673,15 @@ namespace ICSharpCode.ILSpy.Properties { @@ -2673,6 +2673,15 @@ namespace ICSharpCode.ILSpy.Properties {
}
}
/// <summary>
/// Looks up a localized string similar to Use nested namespace structure.
/// </summary>
public static string UseNestedNamespaceNodes {
get {
return ResourceManager.GetString("UseNestedNamespaceNodes", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Use tabs instead of spaces.
/// </summary>

3
ILSpy/Properties/Resources.resx

@ -916,6 +916,9 @@ Do you want to continue?</value> @@ -916,6 +916,9 @@ Do you want to continue?</value>
<data name="UseLogicOperationSugar" xml:space="preserve">
<value>UseLogicOperationSugar</value>
</data>
<data name="UseNestedNamespaceNodes" xml:space="preserve">
<value>Use nested namespace structure</value>
</data>
<data name="UseTabsInsteadOfSpaces" xml:space="preserve">
<value>Use tabs instead of spaces</value>
</data>

58
ILSpy/TreeNodes/AssemblyTreeNode.cs

@ -29,6 +29,7 @@ using ICSharpCode.Decompiler; @@ -29,6 +29,7 @@ using ICSharpCode.Decompiler;
using ICSharpCode.Decompiler.CSharp.ProjectDecompiler;
using ICSharpCode.Decompiler.Metadata;
using ICSharpCode.Decompiler.TypeSystem;
using ICSharpCode.ILSpy.Options;
using ICSharpCode.ILSpy.Properties;
using ICSharpCode.ILSpy.ViewModels;
using ICSharpCode.ILSpyX;
@ -218,24 +219,61 @@ namespace ICSharpCode.ILSpy.TreeNodes @@ -218,24 +219,61 @@ namespace ICSharpCode.ILSpy.TreeNodes
{
ns.Children.Clear();
}
namespaces.Clear();
bool useNestedStructure = DisplaySettingsPanel.CurrentDisplaySettings.UseNestedNamespaceNodes;
foreach (var type in assembly.TopLevelTypeDefinitions.OrderBy(t => t.ReflectionName, NaturalStringComparer.Instance))
{
var escapedNamespace = Language.EscapeName(type.Namespace);
if (!namespaces.TryGetValue(type.Namespace, out NamespaceTreeNode ns))
{
ns = new NamespaceTreeNode(escapedNamespace);
namespaces.Add(type.Namespace, ns);
}
var ns = GetOrCreateNamespaceTreeNode(type.Namespace);
TypeTreeNode node = new TypeTreeNode(type, this);
typeDict[(TypeDefinitionHandle)type.MetadataToken] = node;
ns.Children.Add(node);
}
foreach (NamespaceTreeNode ns in namespaces.Values.OrderBy(n => n.Name, NaturalStringComparer.Instance))
foreach (NamespaceTreeNode ns in namespaces.Values
.Where(ns => ns.Children.Count > 0 && ns.Parent == null)
.OrderBy(n => n.Name, NaturalStringComparer.Instance))
{
this.Children.Add(ns);
SetPublicAPI(ns);
}
NamespaceTreeNode GetOrCreateNamespaceTreeNode(string @namespace)
{
if (!namespaces.TryGetValue(@namespace, out NamespaceTreeNode ns))
{
if (useNestedStructure)
{
int decimalIndex = @namespace.LastIndexOf('.');
if (decimalIndex < 0)
{
var escapedNamespace = Language.EscapeName(@namespace);
ns = new NamespaceTreeNode(escapedNamespace);
}
else
{
var parentNamespaceTreeNode = GetOrCreateNamespaceTreeNode(@namespace.Substring(0, decimalIndex));
var escapedInnerNamespace = Language.EscapeName(@namespace.Substring(decimalIndex + 1));
ns = new NamespaceTreeNode(escapedInnerNamespace);
parentNamespaceTreeNode.Children.Add(ns);
}
}
else
{
var escapedNamespace = Language.EscapeName(@namespace);
ns = new NamespaceTreeNode(escapedNamespace);
}
namespaces.Add(@namespace, ns);
}
return ns;
}
}
private static void SetPublicAPI(NamespaceTreeNode ns)
{
foreach (NamespaceTreeNode innerNamespace in ns.Children.OfType<NamespaceTreeNode>())
{
if (ns.Children.Count > 0)
this.Children.Add(ns);
ns.SetPublicAPI(ns.Children.OfType<ILSpyTreeNode>().Any(n => n.IsPublicAPI));
SetPublicAPI(innerNamespace);
}
ns.SetPublicAPI(ns.Children.OfType<ILSpyTreeNode>().Any(n => n.IsPublicAPI));
}
/// <summary>

Loading…
Cancel
Save