Browse Source

Merge pull request #3092 from fowl2/assemblyUsedBy

add "Referenced Types" under References
natural-type-lambdas-methods
Siegfried Pammer 1 year ago committed by GitHub
parent
commit
f0380558cd
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
  1. 4
      ICSharpCode.Decompiler/ICSharpCode.Decompiler.csproj
  2. 37
      ICSharpCode.Decompiler/Metadata/AssemblyReferences.cs
  3. 103
      ICSharpCode.Decompiler/Metadata/ExportedTypeMetadata.cs
  4. 69
      ICSharpCode.Decompiler/Metadata/MemberReferenceMetadata.cs
  5. 132
      ICSharpCode.Decompiler/Metadata/ModuleReferenceMetadata.cs
  6. 16
      ICSharpCode.Decompiler/Metadata/PEFile.cs
  7. 112
      ICSharpCode.Decompiler/Metadata/TypeReferenceMetadata.cs
  8. 16
      ICSharpCode.Decompiler/TypeSystem/FullTypeName.cs
  9. 4
      ICSharpCode.Decompiler/TypeSystem/Implementation/UnknownType.cs
  10. 86
      ILSpy/Images/ExportOverlay.svg
  11. 18
      ILSpy/Images/ExportOverlay.xaml
  12. 81
      ILSpy/Images/Images.cs
  13. 4
      ILSpy/Images/README.md
  14. 55
      ILSpy/Images/ReferenceOverlay.svg
  15. 12
      ILSpy/Images/ReferenceOverlay.xaml
  16. 64
      ILSpy/TreeNodes/AssemblyReferenceReferencedTypesTreeNode.cs
  17. 18
      ILSpy/TreeNodes/AssemblyReferenceTreeNode.cs
  18. 63
      ILSpy/TreeNodes/ExportedTypeTreeNode.cs
  19. 67
      ILSpy/TreeNodes/MemberReferenceTreeNode.cs
  20. 18
      ILSpy/TreeNodes/ModuleReferenceTreeNode.cs
  21. 6
      ILSpy/TreeNodes/ReferenceFolderTreeNode.cs
  22. 73
      ILSpy/TreeNodes/TypeReferenceTreeNode.cs

4
ICSharpCode.Decompiler/ICSharpCode.Decompiler.csproj

@ -98,6 +98,7 @@ @@ -98,6 +98,7 @@
<Compile Include="Disassembler\IEntityProcessor.cs" />
<Compile Include="Disassembler\SortByNameProcessor.cs" />
<Compile Include="IL\ApplyPdbLocalTypeInfoTypeVisitor.cs" />
<Compile Include="Metadata\ModuleReferenceMetadata.cs" />
<Compile Include="NRTAttributes.cs" />
<Compile Include="PartialTypeInfo.cs" />
<Compile Include="CSharp\ProjectDecompiler\IProjectFileWriter.cs" />
@ -362,6 +363,9 @@ @@ -362,6 +363,9 @@
<Compile Include="IL\Transforms\TransformDisplayClassUsage.cs" />
<Compile Include="IL\Transforms\UserDefinedLogicTransform.cs" />
<Compile Include="Metadata\AssemblyReferences.cs" />
<Compile Include="Metadata\ExportedTypeMetadata.cs" />
<Compile Include="Metadata\MemberReferenceMetadata.cs" />
<Compile Include="Metadata\TypeReferenceMetadata.cs" />
<Compile Include="Metadata\CodeMappingInfo.cs" />
<Compile Include="Metadata\EnumUnderlyingTypeResolveException.cs" />
<Compile Include="Metadata\MetadataTokenHelpers.cs" />

37
ICSharpCode.Decompiler/Metadata/AssemblyReferences.cs

@ -19,6 +19,7 @@ @@ -19,6 +19,7 @@
#nullable enable
using System;
using System.Collections.Immutable;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using System.Reflection;
@ -275,6 +276,42 @@ namespace ICSharpCode.Decompiler.Metadata @@ -275,6 +276,42 @@ namespace ICSharpCode.Decompiler.Metadata
return bytes;
}
ImmutableArray<TypeReferenceMetadata> typeReferences;
public ImmutableArray<TypeReferenceMetadata> TypeReferences {
get {
var value = typeReferences;
if (value.IsDefault)
{
value = Metadata.TypeReferences
.Select(r => new TypeReferenceMetadata(Metadata, r))
.Where(r => r.ResolutionScope == Handle)
.OrderBy(r => r.Namespace)
.ThenBy(r => r.Name)
.ToImmutableArray();
typeReferences = value;
}
return value;
}
}
ImmutableArray<ExportedTypeMetadata> exportedTypes;
public ImmutableArray<ExportedTypeMetadata> ExportedTypes {
get {
var value = exportedTypes;
if (value.IsDefault)
{
value = Metadata.ExportedTypes
.Select(r => new ExportedTypeMetadata(Metadata, r))
.Where(r => r.Implementation == Handle)
.OrderBy(r => r.Namespace)
.ThenBy(r => r.Name)
.ToImmutableArray();
exportedTypes = value;
}
return value;
}
}
public AssemblyReference(MetadataReader metadata, AssemblyReferenceHandle handle)
{
if (metadata == null)

103
ICSharpCode.Decompiler/Metadata/ExportedTypeMetadata.cs

@ -0,0 +1,103 @@ @@ -0,0 +1,103 @@
// Copyright (c) 2023 James May
//
// 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.
#nullable enable
using System;
using System.Collections.Immutable;
using System.Linq;
using System.Reflection;
using System.Reflection.Metadata;
namespace ICSharpCode.Decompiler.Metadata
{
#if !VSADDIN
/// <summary>
/// Convenience wrapper for <see cref="ExportedType"/> and <see cref="ExportedTypeHandle"/>.
/// </summary>
public sealed class ExportedTypeMetadata
{
readonly ExportedType entry;
public MetadataReader Metadata { get; }
public ExportedTypeHandle Handle { get; }
string? name;
public string Name {
get {
try
{
return name ??= Metadata.GetString(entry.Name);
}
catch (BadImageFormatException)
{
return name = $"ET:{Handle}";
}
}
}
string? @namespace;
public string Namespace {
get {
try
{
return @namespace ??= Metadata.GetString(entry.Namespace);
}
catch (BadImageFormatException)
{
return @namespace = $"namespace(ET:{Handle})";
}
}
}
public EntityHandle Implementation => entry.Implementation;
public TypeAttributes Attributes => entry.Attributes;
public bool IsForwarder => entry.IsForwarder;
public NamespaceDefinition NamespaceDefinition => Metadata.GetNamespaceDefinition(entry.NamespaceDefinition);
ImmutableArray<ExportedTypeMetadata> exportedTypes;
public ImmutableArray<ExportedTypeMetadata> ExportedTypes {
get {
var value = exportedTypes;
if (value.IsDefault)
{
value = Metadata.ExportedTypes
.Select(r => new ExportedTypeMetadata(Metadata, r))
.Where(r => r.Implementation == Handle)
.OrderBy(r => r.Namespace)
.ThenBy(r => r.Name)
.ToImmutableArray();
exportedTypes = value;
}
return value;
}
}
public ExportedTypeMetadata(MetadataReader metadata, ExportedTypeHandle handle)
{
Metadata = metadata ?? throw new ArgumentNullException(nameof(metadata));
if (handle.IsNil)
throw new ArgumentNullException(nameof(handle));
Handle = handle;
entry = metadata.GetExportedType(handle);
}
public override string ToString() => $"{Namespace}::{Name}";
}
#endif
}

69
ICSharpCode.Decompiler/Metadata/MemberReferenceMetadata.cs

@ -0,0 +1,69 @@ @@ -0,0 +1,69 @@
// Copyright (c) 2023 James May
//
// 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.
#nullable enable
using System;
using System.Reflection.Metadata;
namespace ICSharpCode.Decompiler.Metadata
{
#if !VSADDIN
/// <summary>
/// Convenience wrapper for <see cref="MemberReference"/> and <see cref="MemberReferenceHandle"/>.
/// </summary>
public sealed class MemberReferenceMetadata
{
readonly MemberReference entry;
public MetadataReader Metadata { get; }
public MemberReferenceHandle Handle { get; }
string? name;
public string Name {
get {
try
{
return name ??= Metadata.GetString(entry.Name);
}
catch (BadImageFormatException)
{
return name = $"MR:{Handle}";
}
}
}
public EntityHandle Parent => entry.Parent;
public MemberReferenceKind MemberReferenceKind => entry.GetKind();
public MemberReferenceMetadata(MetadataReader metadata, MemberReferenceHandle handle)
{
Metadata = metadata ?? throw new ArgumentNullException(nameof(metadata));
if (handle.IsNil)
throw new ArgumentNullException(nameof(handle));
Handle = handle;
entry = metadata.GetMemberReference(handle);
}
public override string ToString()
=> Name;
}
#endif
}

132
ICSharpCode.Decompiler/Metadata/ModuleReferenceMetadata.cs

@ -0,0 +1,132 @@ @@ -0,0 +1,132 @@
// Copyright (c) 2023 James May
//
// 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.
#nullable enable
using System;
using System.Collections.Immutable;
using System.Linq;
using System.Reflection;
using System.Reflection.Metadata;
namespace ICSharpCode.Decompiler.Metadata
{
#if !VSADDIN
public class ModuleReferenceMetadata /* : IModuleReference*/
{
readonly ModuleReference entry;
public MetadataReader Metadata { get; }
public ModuleReferenceHandle Handle { get; }
string? name;
public string Name {
get {
if (name == null)
{
try
{
name = Metadata.GetString(entry.Name);
}
catch (BadImageFormatException)
{
name = $"AR:{Handle}";
}
}
return name;
}
}
ImmutableArray<CustomAttribute> attributes;
public ImmutableArray<CustomAttribute> Attributes {
get {
var value = attributes;
if (value.IsDefault)
{
value = entry.GetCustomAttributes().Select(Metadata.GetCustomAttribute).ToImmutableArray();
attributes = value;
}
return value;
}
}
ImmutableArray<TypeReferenceMetadata> typeReferences;
public ImmutableArray<TypeReferenceMetadata> TypeReferences {
get {
var value = typeReferences;
if (value.IsDefault)
{
value = Metadata.TypeReferences
.Select(r => new TypeReferenceMetadata(Metadata, r))
.Where(r => r.ResolutionScope == Handle)
.OrderBy(r => r.Namespace)
.ThenBy(r => r.Name)
.ToImmutableArray();
typeReferences = value;
}
return value;
}
}
ImmutableArray<ExportedTypeMetadata> exportedTypes;
public ImmutableArray<ExportedTypeMetadata> ExportedTypes {
get {
var value = exportedTypes;
if (value.IsDefault)
{
value = Metadata.ExportedTypes
.Select(r => new ExportedTypeMetadata(Metadata, r))
.Where(r => r.Implementation == Handle)
.OrderBy(r => r.Namespace)
.ThenBy(r => r.Name)
.ToImmutableArray();
exportedTypes = value;
}
return value;
}
}
public ModuleReferenceMetadata(MetadataReader metadata, ModuleReferenceHandle handle)
{
if (metadata == null)
throw new ArgumentNullException(nameof(metadata));
if (handle.IsNil)
throw new ArgumentNullException(nameof(handle));
Metadata = metadata;
Handle = handle;
entry = metadata.GetModuleReference(handle);
}
public ModuleReferenceMetadata(PEFile module, ModuleReferenceHandle handle)
{
if (module == null)
throw new ArgumentNullException(nameof(module));
if (handle.IsNil)
throw new ArgumentNullException(nameof(handle));
Metadata = module.Metadata;
Handle = handle;
entry = Metadata.GetModuleReference(handle);
}
public override string ToString()
{
return Name;
}
}
#endif
}

16
ICSharpCode.Decompiler/Metadata/PEFile.cs

@ -177,6 +177,22 @@ namespace ICSharpCode.Decompiler.Metadata @@ -177,6 +177,22 @@ namespace ICSharpCode.Decompiler.Metadata
}
}
ImmutableArray<ModuleReferenceMetadata> moduleReferences;
public ImmutableArray<ModuleReferenceMetadata> ModuleReferences {
get {
var value = moduleReferences;
if (value.IsDefault)
{
value = Metadata.GetModuleReferences()
.Select(m => new ModuleReferenceMetadata(this, m))
.ToImmutableArray();
moduleReferences = value;
}
return value;
}
}
public ImmutableArray<Resource> Resources => GetResources().ToImmutableArray();
IEnumerable<Resource> GetResources()

112
ICSharpCode.Decompiler/Metadata/TypeReferenceMetadata.cs

@ -0,0 +1,112 @@ @@ -0,0 +1,112 @@
// Copyright (c) 2023 James May
//
// 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.
#nullable enable
using System;
using System.Collections.Immutable;
using System.Linq;
using System.Reflection.Metadata;
namespace ICSharpCode.Decompiler.Metadata
{
#if !VSADDIN
public sealed class TypeReferenceMetadata
{
readonly TypeReference entry;
public MetadataReader Metadata { get; }
public TypeReferenceHandle Handle { get; }
string? name;
public string Name {
get {
try
{
return name ??= Metadata.GetString(entry.Name);
}
catch (BadImageFormatException)
{
return name = $"TR:{Handle}";
}
}
}
string? @namespace;
public string Namespace {
get {
try
{
return @namespace ??= Metadata.GetString(entry.Namespace);
}
catch (BadImageFormatException)
{
return @namespace = $"namespace(TR:{Handle})";
}
}
}
public EntityHandle ResolutionScope => entry.ResolutionScope;
ImmutableArray<MemberReferenceMetadata> memberReferences;
public ImmutableArray<MemberReferenceMetadata> MemberReferences {
get {
var value = memberReferences;
if (value.IsDefault)
{
value = Metadata.MemberReferences
.Select(r => new MemberReferenceMetadata(Metadata, r))
.Where(r => r.Parent == Handle)
.OrderBy(r => r.Name)
.ToImmutableArray();
memberReferences = value;
}
return value;
}
}
ImmutableArray<TypeReferenceMetadata> typeReferences;
public ImmutableArray<TypeReferenceMetadata> TypeReferences {
get {
var value = typeReferences;
if (value.IsDefault)
{
value = Metadata.TypeReferences
.Select(r => new TypeReferenceMetadata(Metadata, r))
.Where(r => r.ResolutionScope == Handle)
.OrderBy(r => r.Name)
.ToImmutableArray();
typeReferences = value;
}
return value;
}
}
public TypeReferenceMetadata(MetadataReader metadata, TypeReferenceHandle handle)
{
Metadata = metadata ?? throw new ArgumentNullException(nameof(metadata));
if (handle.IsNil)
throw new ArgumentNullException(nameof(handle));
Handle = handle;
entry = metadata.GetTypeReference(handle);
}
public override string ToString() => $"{Namespace}::{Name}";
}
#endif
}

16
ICSharpCode.Decompiler/TypeSystem/FullTypeName.cs

@ -165,6 +165,22 @@ namespace ICSharpCode.Decompiler.TypeSystem @@ -165,6 +165,22 @@ namespace ICSharpCode.Decompiler.TypeSystem
}
}
public string FullName {
get {
if (nestedTypes == null)
return topLevelType.Namespace + "." + topLevelType.Name;
StringBuilder b = new StringBuilder(topLevelType.Namespace);
b.Append('.');
b.Append(topLevelType.Name);
foreach (NestedTypeName nt in nestedTypes)
{
b.Append('.');
b.Append(nt.Name);
}
return b.ToString();
}
}
/// <summary>
/// Gets the total type parameter count.
/// </summary>

4
ICSharpCode.Decompiler/TypeSystem/Implementation/UnknownType.cs

@ -95,6 +95,10 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation @@ -95,6 +95,10 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation
get { return namespaceKnown ? fullTypeName.ReflectionName : "?"; }
}
public override string FullName {
get { return namespaceKnown ? fullTypeName.FullName : "?"; }
}
public FullTypeName FullTypeName => fullTypeName;
public override int TypeParameterCount => fullTypeName.TypeParameterCount;

86
ILSpy/Images/ExportOverlay.svg

@ -0,0 +1,86 @@ @@ -0,0 +1,86 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Generator: Adobe Illustrator 21.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg
version="1.1"
x="0px"
y="0px"
viewBox="0 0 16 16"
style="enable-background:new 0 0 16 16;"
xml:space="preserve"
id="svg8"
sodipodi:docname="ExportOverlay.svg"
inkscape:version="1.3.2 (091e20e, 2023-11-25, custom)"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg"><defs
id="defs8" /><sodipodi:namedview
id="namedview8"
pagecolor="#ffffff"
bordercolor="#000000"
borderopacity="0.25"
inkscape:showpageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#d1d1d1"
inkscape:zoom="51.3125"
inkscape:cx="10.98173"
inkscape:cy="8"
inkscape:window-width="1920"
inkscape:window-height="1017"
inkscape:window-x="2552"
inkscape:window-y="-8"
inkscape:window-maximized="1"
inkscape:current-layer="svg8" />
<style
type="text/css"
id="style1">
.icon_x002D_canvas_x002D_transparent{opacity:0;fill:#F6F6F6;}
.icon_x002D_vs_x002D_out{fill:#F6F6F6;}
.icon_x002D_vs_x002D_action_x002D_blue{fill:#00539C;}
</style>
<g
id="canvas"
transform="matrix(0.5625,0,0,1,7,12.444445)">
<path
class="icon_x002D_canvas_x002D_transparent"
d="M 16,-12.444444 V 3.5555556 H -12.444444 V -12.444444 Z"
id="path1"
style="stroke-width:1.33333" />
</g>
<g
id="outline"
transform="matrix(0.5625,0,0,0.5625,7,7)">
<path
class="icon_x002D_vs_x002D_out"
d="M 5.793,0.879 8.621,3.707 7.328,5 H 10.5 c 3.033,0 5.5,2.467 5.5,5.5 0,3.032 -2.467,5.5 -5.5,5.5 h -1 v -4 h 1 C 11.327,12 12,11.327 12,10.5 12,9.673 11.327,9 10.5,9 H 7.328 L 8.621,10.293 5.793,13.121 0,7.328 V 6.672 Z"
id="path2" />
</g>
<g
id="iconBg"
transform="matrix(0.5625,0,0,0.5625,7,7)">
<path
class="icon_x002D_vs_x002D_action_x002D_blue"
d="M 5.793,2.293 7.207,3.707 4.914,6 H 10.5 C 12.981,6 15,8.019 15,10.5 15,12.981 12.981,15 10.5,15 V 13 C 11.878,13 13,11.879 13,10.5 13,9.121 11.878,8 10.5,8 H 4.914 L 7.207,10.293 5.793,11.707 1.086,7 Z"
id="path3" />
<g
id="g3">
</g>
<g
id="g4">
</g>
<g
id="g5">
</g>
<g
id="g6">
</g>
<g
id="g7">
</g>
<g
id="g8">
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 2.4 KiB

18
ILSpy/Images/ExportOverlay.xaml

@ -0,0 +1,18 @@ @@ -0,0 +1,18 @@
<DrawingGroup xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" ClipGeometry="M0,0 V16 H16 V0 H0 Z">
<DrawingGroup.Transform>
<TranslateTransform X="12.444443702697754" Y="12.444443702697754" />
</DrawingGroup.Transform>
<DrawingGroup Opacity="1" Transform="0.5625,0,0,1,7,12.444445">
<GeometryDrawing Geometry="F1 M16,16z M0,0z M16,-12.444444L16,3.5555556 -12.444444,3.5555556 -12.444444,-12.444444z">
<GeometryDrawing.Brush>
<SolidColorBrush Color="#FFF6F6F6" Opacity="0" />
</GeometryDrawing.Brush>
</GeometryDrawing>
</DrawingGroup>
<DrawingGroup Opacity="1" Transform="0.5625,0,0,0.5625,7,7">
<GeometryDrawing Brush="#FFF6F6F6" Geometry="F1 M16,16z M0,0z M5.793,0.879L8.621,3.707 7.328,5 10.5,5C13.533,5 16,7.467 16,10.5 16,13.532 13.533,16 10.5,16L9.5,16 9.5,12 10.5,12C11.327,12 12,11.327 12,10.5 12,9.673 11.327,9 10.5,9L7.328,9 8.621,10.293 5.793,13.121 0,7.328 0,6.672z" />
</DrawingGroup>
<DrawingGroup Opacity="1" Transform="0.5625,0,0,0.5625,7,7">
<GeometryDrawing Brush="#FF00539C" Geometry="F1 M16,16z M0,0z M5.793,2.293L7.207,3.707 4.914,6 10.5,6C12.981,6 15,8.019 15,10.5 15,12.981 12.981,15 10.5,15L10.5,13C11.878,13 13,11.879 13,10.5 13,9.121 11.878,8 10.5,8L4.914,8 7.207,10.293 5.793,11.707 1.086,7z" />
</DrawingGroup>
</DrawingGroup>

81
ILSpy/Images/Images.cs

@ -27,6 +27,8 @@ namespace ICSharpCode.ILSpy @@ -27,6 +27,8 @@ namespace ICSharpCode.ILSpy
{
static class Images
{
private static readonly Rect iconRect = new Rect(0, 0, 16, 16);
static ImageSource Load(string icon)
{
var image = new DrawingImage(LoadDrawingGroup(null, "Images/" + icon));
@ -85,6 +87,7 @@ namespace ICSharpCode.ILSpy @@ -85,6 +87,7 @@ namespace ICSharpCode.ILSpy
public static readonly ImageSource Interface = Load("Interface");
public static readonly ImageSource Delegate = Load("Delegate");
public static readonly ImageSource Enum = Load("Enum");
public static readonly ImageSource Type = Load("ShowPublicOnly");
public static readonly ImageSource Field = Load("Field");
public static readonly ImageSource FieldReadOnly = Load("FieldReadOnly");
@ -109,9 +112,15 @@ namespace ICSharpCode.ILSpy @@ -109,9 +112,15 @@ namespace ICSharpCode.ILSpy
private static readonly ImageSource OverlayPrivate = Load("OverlayPrivate");
private static readonly ImageSource OverlayPrivateProtected = Load("OverlayPrivateProtected");
private static readonly ImageSource OverlayCompilerControlled = Load("OverlayCompilerControlled");
private static readonly ImageSource OverlayReference = Load("ReferenceOverlay");
private static readonly ImageSource OverlayStatic = Load("OverlayStatic");
public static readonly ImageSource TypeReference = GetIcon("ShowPublicOnly", "ReferenceOverlay");
public static readonly ImageSource MethodReference = GetIcon("Method", "ReferenceOverlay");
public static readonly ImageSource FieldReference = GetIcon("Field", "ReferenceOverlay");
public static readonly ImageSource ExportedType = GetIcon("ShowPublicOnly", "ExportOverlay");
public static ImageSource Load(object part, string icon)
{
if (icon.EndsWith(".png", StringComparison.OrdinalIgnoreCase))
@ -202,6 +211,45 @@ namespace ICSharpCode.ILSpy @@ -202,6 +211,45 @@ namespace ICSharpCode.ILSpy
return memberIconCache.GetIcon(icon, overlay, isStatic);
}
private static ImageSource GetIcon(string baseImage, string overlay = null, bool isStatic = false)
{
ImageSource baseImageSource = Load(baseImage);
ImageSource overlayImageSource = overlay != null ? Load(overlay) : null;
return CreateOverlayImage(baseImageSource, overlayImageSource, isStatic);
}
private static ImageSource CreateOverlayImage(ImageSource baseImage, ImageSource overlay, bool isStatic)
{
var group = new DrawingGroup();
Drawing baseDrawing = new ImageDrawing(baseImage, iconRect);
if (overlay != null)
{
var nestedGroup = new DrawingGroup { Transform = new ScaleTransform(0.8, 0.8) };
nestedGroup.Children.Add(baseDrawing);
group.Children.Add(nestedGroup);
group.Children.Add(new ImageDrawing(overlay, iconRect));
}
else
{
group.Children.Add(baseDrawing);
}
if (isStatic)
{
group.Children.Add(new ImageDrawing(Images.OverlayStatic, iconRect));
}
var image = new DrawingImage(group);
if (image.CanFreeze)
{
image.Freeze();
}
return image;
}
#region icon caches & overlay management
private class TypeIconCache : IconCache<TypeIcon>
@ -380,39 +428,6 @@ namespace ICSharpCode.ILSpy @@ -380,39 +428,6 @@ namespace ICSharpCode.ILSpy
}
return overlayImage;
}
private static readonly Rect iconRect = new Rect(0, 0, 16, 16);
private static ImageSource CreateOverlayImage(ImageSource baseImage, ImageSource overlay, bool isStatic)
{
var group = new DrawingGroup();
Drawing baseDrawing = new ImageDrawing(baseImage, iconRect);
if (overlay != null)
{
var nestedGroup = new DrawingGroup { Transform = new ScaleTransform(0.8, 0.8) };
nestedGroup.Children.Add(baseDrawing);
group.Children.Add(nestedGroup);
group.Children.Add(new ImageDrawing(overlay, iconRect));
}
else
{
group.Children.Add(baseDrawing);
}
if (isStatic)
{
group.Children.Add(new ImageDrawing(Images.OverlayStatic, iconRect));
}
var image = new DrawingImage(group);
if (image.CanFreeze)
{
image.Freeze();
}
return image;
}
}
#endregion

4
ILSpy/Images/README.md

@ -18,6 +18,7 @@ Icons used in ILSpy: @@ -18,6 +18,7 @@ Icons used in ILSpy:
| Enum | x | x | VS 2017 Icon Pack (Enumerator) | |
| EnumValue | x | x | VS 2017 Icon Pack (EnumItem) | |
| Event | x | x | VS 2017 Icon Pack (Event) | |
| ExportOverlay | x | x | slightly modified VS 2017 Icon Pack (Export) | |
| ExtensionMethod | x | x | VS 2017 Icon Pack (ExtensionMethod) | |
| Field | x | x | VS 2017 Icon Pack (Field) | |
| FieldReadOnly | x | x | VS 2017 Icon Pack (Field) with different color | |
@ -53,12 +54,13 @@ Icons used in ILSpy: @@ -53,12 +54,13 @@ Icons used in ILSpy:
| ProgramDebugDatabase | x | x | VS 2017 Icon Pack (ProgramDebugDatabase) | |
| Property | x | x | VS 2017 Icon Pack (Property) | |
| ReferenceFolder | x | x | combined VS 2017 Icon Pack (Reference) two times | |
| ReferenceOverlay | x | x | extracted arrow from VS 2017 Icon Pack (TypeShortcut) | |
| Refresh | x | x | VS 2017 Icon Pack (Refresh) | |
| Resource | x | x | VS 2017 Icon Pack (Document) | |
| ResourceImage | x | x | VS 2017 Icon Pack (Image) | |
| ResourceResourcesFile | x | x | VS 2017 Icon Pack (LocalResources) | |
| ResourceXml | x | x | VS 2017 Icon Pack (XMLFile) | |
| ResourceXsd | x | x | combined VS 2017 Icon Pack (XMLSchema) with the "file symbol in ResourceXslt | |
| ResourceXsd | x | x | combined VS 2017 Icon Pack (XMLSchema) with the file symbol in ResourceXslt | |
| ResourceXsl | x | x | VS 2017 Icon Pack (XMLTransformation) | |
| ResourceXslt | x | x | VS 2017 Icon Pack (XSLTTemplate) | |
| Save | x | x | VS 2017 Icon Pack (Save) | |

55
ILSpy/Images/ReferenceOverlay.svg

@ -0,0 +1,55 @@ @@ -0,0 +1,55 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
viewBox="0 0 16 16"
version="1.1"
id="svg4"
sodipodi:docname="TypeReference.svg"
inkscape:version="1.3.2 (091e20e, 2023-11-25, custom)"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<defs
id="defs4" />
<sodipodi:namedview
id="namedview4"
pagecolor="#ffffff"
bordercolor="#000000"
borderopacity="0.25"
inkscape:showpageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#d1d1d1"
inkscape:zoom="51.3125"
inkscape:cx="3.6930572"
inkscape:cy="9.3057247"
inkscape:window-width="1920"
inkscape:window-height="1017"
inkscape:window-x="2552"
inkscape:window-y="-8"
inkscape:window-maximized="1"
inkscape:current-layer="svg4" />
<style
id="style1">.st0{opacity:0}.st0,.st1{fill:#f6f6f6}.st2{fill:#424242}.st3{fill:#f0eff1}</style>
<g
id="outline"
style="display:inline">
<path
class="st0"
d="M 0,0 H 16 V 16 H 0 Z"
id="path1" />
<path
class="st1"
d="m 9,9 v 7 h 7 V 9 Z"
id="path2"
sodipodi:nodetypes="ccccc" />
</g>
<path
class="st2"
d="M10 10v5h5v-5h-5zm4 3l-1 1v-1.5L11.5 14l-.5-.5 1.5-1.5H11l1-1h2v2z"
id="not_x5F_bg" />
<path
class="st3"
d="M14 11v2l-1 1v-1.5L11.5 14l-.5-.5 1.5-1.5H11l1-1z"
id="not_x5F_fg" />
</svg>

After

Width:  |  Height:  |  Size: 1.6 KiB

12
ILSpy/Images/ReferenceOverlay.xaml

@ -0,0 +1,12 @@ @@ -0,0 +1,12 @@
<DrawingGroup xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" ClipGeometry="M0,0 V16 H16 V0 H0 Z">
<DrawingGroup Opacity="1">
<GeometryDrawing Geometry="F1 M16,16z M0,0z M0,0L16,0 16,16 0,16z">
<GeometryDrawing.Brush>
<SolidColorBrush Color="#FFF6F6F6" Opacity="0" />
</GeometryDrawing.Brush>
</GeometryDrawing>
<GeometryDrawing Brush="#FFF6F6F6" Geometry="F1 M16,16z M0,0z M9,9L9,16 16,16 16,9z" />
</DrawingGroup>
<GeometryDrawing Brush="#FF424242" Geometry="F1 M16,16z M0,0z M10,10L10,15 15,15 15,10 10,10z M14,13L13,14 13,12.5 11.5,14 11,13.5 12.5,12 11,12 12,11 14,11 14,13z" />
<GeometryDrawing Brush="#FFF0EFF1" Geometry="F1 M16,16z M0,0z M14,11L14,13 13,14 13,12.5 11.5,14 11,13.5 12.5,12 11,12 12,11z" />
</DrawingGroup>

64
ILSpy/TreeNodes/AssemblyReferenceReferencedTypesTreeNode.cs

@ -0,0 +1,64 @@ @@ -0,0 +1,64 @@
// Copyright (c) 2023 James May
//
// 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 ICSharpCode.Decompiler;
using ICSharpCode.Decompiler.Metadata;
using ICSharpCode.Decompiler.TypeSystem;
namespace ICSharpCode.ILSpy.TreeNodes
{
/// <summary>
/// Referenced Types node in assembly reference list
/// </summary>
public sealed class AssemblyReferenceReferencedTypesTreeNode : ILSpyTreeNode
{
readonly MetadataModule module;
readonly AssemblyReference r;
public AssemblyReferenceReferencedTypesTreeNode(MetadataModule module, AssemblyReference r)
{
this.module = module ?? throw new ArgumentNullException(nameof(module));
this.r = r ?? throw new ArgumentNullException(nameof(r));
this.LazyLoading = true;
}
public override object Text => $"Referenced Types ({r.TypeReferences.Length + r.ExportedTypes.Length})";
public override object Icon => Images.MetadataTable;
protected override void LoadChildren()
{
foreach (var typeRef in r.TypeReferences)
this.Children.Add(new TypeReferenceTreeNode(module, typeRef));
foreach (var exportedType in r.ExportedTypes)
this.Children.Add(new ExportedTypeTreeNode(module, exportedType));
}
public override bool ShowExpander => !r.TypeReferences.IsEmpty || !r.ExportedTypes.IsEmpty;
public override void Decompile(Language language, ITextOutput output, DecompilationOptions options)
{
EnsureLazyChildren();
foreach (ILSpyTreeNode child in Children)
child.Decompile(language, output, options);
}
}
}

18
ILSpy/TreeNodes/AssemblyReferenceTreeNode.cs

@ -21,6 +21,7 @@ using System.Windows.Threading; @@ -21,6 +21,7 @@ using System.Windows.Threading;
using ICSharpCode.Decompiler;
using ICSharpCode.Decompiler.Metadata;
using ICSharpCode.Decompiler.TypeSystem;
namespace ICSharpCode.ILSpy.TreeNodes
{
@ -29,17 +30,19 @@ namespace ICSharpCode.ILSpy.TreeNodes @@ -29,17 +30,19 @@ namespace ICSharpCode.ILSpy.TreeNodes
/// </summary>
public sealed class AssemblyReferenceTreeNode : ILSpyTreeNode
{
readonly MetadataModule module;
readonly AssemblyReference r;
readonly AssemblyTreeNode parentAssembly;
public AssemblyReferenceTreeNode(AssemblyReference r, AssemblyTreeNode parentAssembly)
public AssemblyReferenceTreeNode(MetadataModule module, AssemblyReference r, AssemblyTreeNode parentAssembly)
{
this.module = module ?? throw new ArgumentNullException(nameof(module));
this.r = r ?? throw new ArgumentNullException(nameof(r));
this.parentAssembly = parentAssembly ?? throw new ArgumentNullException(nameof(parentAssembly));
this.LazyLoading = true;
}
public IAssemblyReference AssemblyNameReference => r;
public AssemblyReference AssemblyReference => r;
public override object Text {
get { return Language.EscapeName(r.Name) + GetSuffixString(r.Handle); }
@ -75,12 +78,15 @@ namespace ICSharpCode.ILSpy.TreeNodes @@ -75,12 +78,15 @@ namespace ICSharpCode.ILSpy.TreeNodes
protected override void LoadChildren()
{
this.Children.Add(new AssemblyReferenceReferencedTypesTreeNode(module, r));
var resolver = parentAssembly.LoadedAssembly.GetAssemblyResolver(MainWindow.Instance.CurrentDecompilerSettings.AutoLoadAssemblyReferences);
var module = resolver.Resolve(r);
if (module != null)
var referencedModule = resolver.Resolve(r);
if (referencedModule != null)
{
foreach (var childRef in module.AssemblyReferences)
this.Children.Add(new AssemblyReferenceTreeNode(childRef, parentAssembly));
var module = (MetadataModule)referencedModule.GetTypeSystemWithCurrentOptionsOrNull().MainModule;
foreach (var childRef in referencedModule.AssemblyReferences)
this.Children.Add(new AssemblyReferenceTreeNode(module, childRef, parentAssembly));
}
}

63
ILSpy/TreeNodes/ExportedTypeTreeNode.cs

@ -0,0 +1,63 @@ @@ -0,0 +1,63 @@
// Copyright (c) 2023 James May
//
// 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 ICSharpCode.Decompiler;
using ICSharpCode.Decompiler.Metadata;
using ICSharpCode.Decompiler.TypeSystem;
namespace ICSharpCode.ILSpy.TreeNodes
{
/// <summary>
/// exported type within assembly reference list.
/// </summary>
public sealed class ExportedTypeTreeNode : ILSpyTreeNode
{
readonly MetadataModule module;
readonly ExportedTypeMetadata r;
readonly IType resolvedType;
public ExportedTypeTreeNode(MetadataModule module, ExportedTypeMetadata r)
{
this.module = module ?? throw new ArgumentNullException(nameof(module));
this.r = r ?? throw new ArgumentNullException(nameof(r));
this.resolvedType = module.ResolveType(r.Handle, default);
this.LazyLoading = true;
}
public override object Text
=> Language.TypeToString(resolvedType, includeNamespace: true) + GetSuffixString(r.Handle);
public override object Icon => Images.ExportedType;
protected override void LoadChildren()
{
foreach (var exportedType in r.ExportedTypes)
this.Children.Add(new ExportedTypeTreeNode(module, exportedType));
}
public override bool ShowExpander => !r.ExportedTypes.IsEmpty;
public override void Decompile(Language language, ITextOutput output, DecompilationOptions options)
{
language.WriteCommentLine(output, $"{Language.TypeToString(resolvedType, includeNamespace: true)} (Exported, IsForwarder: {r.IsForwarder}, Attributes: {(int)r.Attributes:X8})");
}
}
}

67
ILSpy/TreeNodes/MemberReferenceTreeNode.cs

@ -0,0 +1,67 @@ @@ -0,0 +1,67 @@
// Copyright (c) 2023 James May
//
// 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.
#nullable enable
using System;
using System.Reflection.Metadata;
using ICSharpCode.Decompiler;
using ICSharpCode.Decompiler.Metadata;
using ICSharpCode.Decompiler.TypeSystem;
namespace ICSharpCode.ILSpy.TreeNodes
{
/// <summary>
/// Reference to member from assembly reference list.
/// </summary>
public sealed class MemberReferenceTreeNode : ILSpyTreeNode
{
readonly MetadataModule module;
readonly MemberReferenceMetadata r;
readonly IMember resolvedMember;
public MemberReferenceTreeNode(MetadataModule module, MemberReferenceMetadata r)
{
this.module = module ?? throw new ArgumentNullException(nameof(module));
this.r = r;
this.resolvedMember = r.MemberReferenceKind switch {
MemberReferenceKind.Method => module.ResolveMethod(r.Handle, default),
MemberReferenceKind.Field => (IMember)module.ResolveEntity(r.Handle),
_ => throw new NotSupportedException(),
};
}
public override object Text => Signature + GetSuffixString(r.Handle);
public override object Icon => r.MemberReferenceKind switch {
MemberReferenceKind.Method => Images.MethodReference,
MemberReferenceKind.Field => Images.FieldReference,
_ => throw new NotSupportedException(),
};
public string Signature => resolvedMember is IMethod m ? Language.MethodToString(m, false, false, false) : Language.FieldToString((IField)resolvedMember, false, false, false);
public override void Decompile(Language language, ITextOutput output, DecompilationOptions options)
{
language.WriteCommentLine(output, Signature);
}
public override object ToolTip => Language.GetRichTextTooltip(resolvedMember);
}
}

18
ILSpy/TreeNodes/ModuleReferenceTreeNode.cs

@ -17,9 +17,13 @@ @@ -17,9 +17,13 @@
// DEALINGS IN THE SOFTWARE.
using System;
using System.Linq;
using System.Reflection.Metadata;
using System.Reflection.Metadata.Ecma335;
using ICSharpCode.Decompiler;
using ICSharpCode.Decompiler.Metadata;
using ICSharpCode.ILSpy.Metadata;
namespace ICSharpCode.ILSpy.TreeNodes
{
@ -28,6 +32,7 @@ namespace ICSharpCode.ILSpy.TreeNodes @@ -28,6 +32,7 @@ namespace ICSharpCode.ILSpy.TreeNodes
/// </summary>
sealed class ModuleReferenceTreeNode : ILSpyTreeNode
{
readonly PEFile module;
readonly AssemblyTreeNode parentAssembly;
readonly MetadataReader metadata;
readonly ModuleReferenceHandle handle;
@ -37,20 +42,21 @@ namespace ICSharpCode.ILSpy.TreeNodes @@ -37,20 +42,21 @@ namespace ICSharpCode.ILSpy.TreeNodes
readonly string moduleName;
readonly bool containsMetadata;
public ModuleReferenceTreeNode(AssemblyTreeNode parentAssembly, ModuleReferenceHandle r, MetadataReader module)
public ModuleReferenceTreeNode(AssemblyTreeNode parentAssembly, ModuleReferenceHandle r, PEFile module)
{
this.parentAssembly = parentAssembly ?? throw new ArgumentNullException(nameof(parentAssembly));
if (r.IsNil)
throw new ArgumentNullException(nameof(r));
this.metadata = module;
this.handle = r;
this.reference = module.GetModuleReference(r);
this.module = module ?? throw new ArgumentNullException(nameof(module));
this.metadata = module.Metadata;
this.reference = module.Metadata.GetModuleReference(r);
this.moduleName = Language.EscapeName(metadata.GetString(reference.Name));
foreach (var h in module.AssemblyFiles)
foreach (var h in metadata.AssemblyFiles)
{
var file = module.GetAssemblyFile(h);
if (module.StringComparer.Equals(file.Name, moduleName))
var file = metadata.GetAssemblyFile(h);
if (metadata.StringComparer.Equals(file.Name, moduleName))
{
this.file = file;
this.fileHandle = h;

6
ILSpy/TreeNodes/ReferenceFolderTreeNode.cs

@ -22,6 +22,7 @@ using System.Windows.Threading; @@ -22,6 +22,7 @@ using System.Windows.Threading;
using ICSharpCode.Decompiler;
using ICSharpCode.Decompiler.Metadata;
using ICSharpCode.Decompiler.TypeSystem;
using ICSharpCode.ILSpy.Properties;
namespace ICSharpCode.ILSpy.TreeNodes
@ -48,10 +49,11 @@ namespace ICSharpCode.ILSpy.TreeNodes @@ -48,10 +49,11 @@ namespace ICSharpCode.ILSpy.TreeNodes
protected override void LoadChildren()
{
var metadata = module.Metadata;
var metadataModule = (MetadataModule)module.GetTypeSystemWithCurrentOptionsOrNull().MainModule;
foreach (var r in module.AssemblyReferences.OrderBy(r => r.Name))
this.Children.Add(new AssemblyReferenceTreeNode(r, parentAssembly));
this.Children.Add(new AssemblyReferenceTreeNode(metadataModule, r, parentAssembly));
foreach (var r in metadata.GetModuleReferences().OrderBy(r => metadata.GetString(metadata.GetModuleReference(r).Name)))
this.Children.Add(new ModuleReferenceTreeNode(parentAssembly, r, metadata));
this.Children.Add(new ModuleReferenceTreeNode(parentAssembly, r, module));
}
public override void Decompile(Language language, ITextOutput output, DecompilationOptions options)

73
ILSpy/TreeNodes/TypeReferenceTreeNode.cs

@ -0,0 +1,73 @@ @@ -0,0 +1,73 @@
// Copyright (c) 2023 James May
//
// 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 ICSharpCode.Decompiler;
using ICSharpCode.Decompiler.Metadata;
using ICSharpCode.Decompiler.TypeSystem;
namespace ICSharpCode.ILSpy.TreeNodes
{
/// <summary>
/// referenced type within assembly reference list.
/// </summary>
public sealed class TypeReferenceTreeNode : ILSpyTreeNode
{
readonly MetadataModule module;
readonly TypeReferenceMetadata r;
readonly IType resolvedType;
public TypeReferenceTreeNode(MetadataModule module, TypeReferenceMetadata r)
{
this.module = module ?? throw new ArgumentNullException(nameof(module));
this.r = r ?? throw new ArgumentNullException(nameof(r));
this.resolvedType = module.ResolveType(r.Handle, default);
this.LazyLoading = true;
}
public override object Text
=> Language.TypeToString(resolvedType, includeNamespace: false) + GetSuffixString(r.Handle);
public override object Icon => Images.TypeReference;
protected override void LoadChildren()
{
foreach (var typeRef in r.TypeReferences)
this.Children.Add(new TypeReferenceTreeNode(module, typeRef));
foreach (var memberRef in r.MemberReferences)
this.Children.Add(new MemberReferenceTreeNode(module, memberRef));
}
public override bool ShowExpander => !r.TypeReferences.IsEmpty || !r.MemberReferences.IsEmpty;
public override void Decompile(Language language, ITextOutput output, DecompilationOptions options)
{
language.WriteCommentLine(output, Language.TypeToString(resolvedType, includeNamespace: true));
EnsureLazyChildren();
foreach (ILSpyTreeNode child in Children)
{
output.Indent();
child.Decompile(language, output, options);
output.Unindent();
}
}
}
}
Loading…
Cancel
Save