Browse Source

Remove TypeDefinitionToString, add BaseTypesTreeNode

pull/1198/head
Siegfried Pammer 7 years ago
parent
commit
3630edab81
  1. 55
      ILSpy/Languages/CSharpLanguage.cs
  2. 18
      ILSpy/Languages/Language.cs
  3. 2
      ILSpy/Languages/Languages.cs
  4. 13
      ILSpy/LoadedAssemblyExtensions.cs
  5. 12
      ILSpy/SearchStrategies.cs
  6. 44
      ILSpy/TreeNodes/BaseTypesEntryNode.cs
  7. 3
      ILSpy/TreeNodes/BaseTypesTreeNode.cs
  8. 35
      ILSpy/TreeNodes/DerivedTypesTreeNode.cs
  9. 4
      ILSpy/TreeNodes/IMemberTreeNode.cs
  10. 8
      ILSpy/TreeNodes/TypeTreeNode.cs

55
ILSpy/Languages/CSharpLanguage.cs

@ -403,8 +403,8 @@ namespace ICSharpCode.ILSpy @@ -403,8 +403,8 @@ namespace ICSharpCode.ILSpy
return base.WriteResourceToFile(fileName, resourceName, entryStream);
}
}
static readonly CSharpFormattingOptions TypeToStringFormattingOptions = FormattingOptionsFactory.CreateEmpty();
static readonly CSharpFormattingOptions TypeToStringFormattingOptions = FormattingOptionsFactory.CreateEmpty();
public override string TypeToString(IType type, bool includeNamespace)
{
@ -419,30 +419,6 @@ namespace ICSharpCode.ILSpy @@ -419,30 +419,6 @@ namespace ICSharpCode.ILSpy
return w.ToString();
}
public override string TypeDefinitionToString(ITypeDefinition type, bool includeNamespace)
{
if (type == null)
throw new ArgumentNullException(nameof(type));
var buffer = new System.Text.StringBuilder();
if (includeNamespace) {
buffer.Append(type.FullName);
} else {
buffer.Append(type.Name);
}
if (type.TypeParameterCount > 0) {
buffer.Append('<');
int i = 0;
foreach (var tp in type.TypeParameters) {
if (i > 0)
buffer.Append(", ");
buffer.Append(tp.Name);
i++;
}
buffer.Append('>');
}
return buffer.ToString();
}
public override string FieldToString(IField field, bool includeTypeName, bool includeNamespace)
{
if (field == null)
@ -451,21 +427,13 @@ namespace ICSharpCode.ILSpy @@ -451,21 +427,13 @@ namespace ICSharpCode.ILSpy
string simple = field.Name + " : " + TypeToString(field.Type, includeNamespace);
if (!includeTypeName)
return simple;
var typeName = field.DeclaringTypeDefinition.FullTypeName;
if (!includeNamespace)
return typeName.Name + "." + simple;
return typeName + "." + simple;
return TypeToString(MakeParameterizedType(field.DeclaringTypeDefinition), includeNamespace) + "." + simple;
}
public override string PropertyToString(IProperty property, bool includeTypeName, bool includeNamespace, bool? isIndexer = null)
{
if (property == null)
throw new ArgumentNullException(nameof(property));
ConvertTypeOptions convertTypeOptions = ConvertTypeOptions.IncludeTypeParameterDefinitions;
if (includeNamespace)
convertTypeOptions |= ConvertTypeOptions.IncludeNamespace;
if (includeTypeName)
convertTypeOptions |= ConvertTypeOptions.IncludeOuterTypeName;
var buffer = new System.Text.StringBuilder();
if (isIndexer.Value) {
if (property.IsExplicitInterfaceImplementation) {
@ -493,25 +461,21 @@ namespace ICSharpCode.ILSpy @@ -493,25 +461,21 @@ namespace ICSharpCode.ILSpy
}
buffer.Append(" : ");
buffer.Append(TypeToString(property.ReturnType, includeNamespace));
return buffer.ToString();
if (!includeTypeName)
return buffer.ToString();
return TypeToString(MakeParameterizedType(property.DeclaringTypeDefinition), includeNamespace) + "." + buffer.ToString();
}
public override string MethodToString(IMethod method, bool includeTypeName, bool includeNamespace)
{
if (method == null)
throw new ArgumentNullException(nameof(method));
ConvertTypeOptions convertTypeOptions = ConvertTypeOptions.IncludeTypeParameterDefinitions;
if (includeNamespace)
convertTypeOptions |= ConvertTypeOptions.IncludeNamespace;
if (includeTypeName)
convertTypeOptions |= ConvertTypeOptions.IncludeOuterTypeName;
string name;
if (method.IsConstructor) {
name = TypeDefinitionToString(method.DeclaringTypeDefinition, includeNamespace: includeNamespace);
name = TypeToString(MakeParameterizedType(method.DeclaringTypeDefinition), includeNamespace: includeNamespace);
} else {
if (includeTypeName) {
name = TypeDefinitionToString(method.DeclaringTypeDefinition, includeNamespace: includeNamespace) + ".";
name = TypeToString(MakeParameterizedType(method.DeclaringTypeDefinition), includeNamespace: includeNamespace) + ".";
} else {
name = "";
}
@ -552,7 +516,10 @@ namespace ICSharpCode.ILSpy @@ -552,7 +516,10 @@ namespace ICSharpCode.ILSpy
if (@event == null)
throw new ArgumentNullException(nameof(@event));
var buffer = new System.Text.StringBuilder();
buffer.Append(GetDisplayName(@event, includeTypeName, includeNamespace));
if (includeTypeName) {
buffer.Append(TypeToString(MakeParameterizedType(@event.DeclaringTypeDefinition), includeNamespace) + ".");
}
buffer.Append(@event.Name);
buffer.Append(" : ");
buffer.Append(TypeToString(@event.ReturnType, includeNamespace));
return buffer.ToString();

18
ILSpy/Languages/Language.cs

@ -159,17 +159,6 @@ namespace ICSharpCode.ILSpy @@ -159,17 +159,6 @@ namespace ICSharpCode.ILSpy
return type.Name;
}
/// <summary>
/// Converts a type definition into a string. This method is used by tree nodes and search results.
/// </summary>
public virtual string TypeDefinitionToString(ITypeDefinition type, bool includeNamespace)
{
if (includeNamespace)
return type.FullName;
else
return type.Name;
}
/// <summary>
/// Converts a member signature to a string.
/// This is used for displaying the tooltip on a member reference.
@ -254,6 +243,13 @@ namespace ICSharpCode.ILSpy @@ -254,6 +243,13 @@ namespace ICSharpCode.ILSpy
}
}
public static IType MakeParameterizedType(ITypeDefinition type)
{
if (type.TypeParameterCount == 0)
return type;
return new ParameterizedType(type, type.TypeParameters);
}
/// <summary>
/// Used for WPF keyboard navigation.
/// </summary>

2
ILSpy/Languages/Languages.cs

@ -45,7 +45,7 @@ namespace ICSharpCode.ILSpy @@ -45,7 +45,7 @@ namespace ICSharpCode.ILSpy
List<Language> languages = new List<Language>();
languages.AddRange(ep.GetExportedValues<Language>());
languages.Sort((a, b) => a.Name.CompareTo(b.Name));
#if false
#if DEBUG
languages.AddRange(ILAstLanguage.GetDebugLanguages());
languages.AddRange(CSharpLanguage.GetDebugLanguages());
#endif

13
ILSpy/LoadedAssemblyExtensions.cs

@ -5,12 +5,23 @@ using System.Runtime.CompilerServices; @@ -5,12 +5,23 @@ using System.Runtime.CompilerServices;
using System.Text;
using System.Threading.Tasks;
using ICSharpCode.Decompiler.Metadata;
using ICSharpCode.Decompiler.TypeSystem;
namespace ICSharpCode.ILSpy
{
public static class LoadedAssemblyExtensions
{
public static IAssemblyResolver GetAssemblyResolver(this PEFile file)
{
return GetLoadedAssembly(file).GetAssemblyResolver();
}
public static ICompilation GetTypeSystemOrNull(this PEFile file)
{
return GetLoadedAssembly(file).GetTypeSystemOrNull();
}
static LoadedAssembly GetLoadedAssembly(PEFile file)
{
if (file == null)
throw new ArgumentNullException(nameof(file));
@ -19,7 +30,7 @@ namespace ICSharpCode.ILSpy @@ -19,7 +30,7 @@ namespace ICSharpCode.ILSpy
if (!LoadedAssembly.loadedAssemblies.TryGetValue(file, out loadedAssembly))
throw new ArgumentException("The specified file is not associated with a LoadedAssembly!");
}
return loadedAssembly.GetAssemblyResolver();
return loadedAssembly;
}
}
}

12
ILSpy/SearchStrategies.cs

@ -163,7 +163,7 @@ namespace ICSharpCode.ILSpy @@ -163,7 +163,7 @@ namespace ICSharpCode.ILSpy
{
switch (member) {
case ITypeDefinition t:
return language.TypeDefinitionToString(t, includeNamespace: fullName);
return language.TypeToString(Language.MakeParameterizedType(t), includeNamespace: fullName);
case IField f:
return language.FieldToString(f, fullName, fullName);
case IProperty p:
@ -193,7 +193,7 @@ namespace ICSharpCode.ILSpy @@ -193,7 +193,7 @@ namespace ICSharpCode.ILSpy
Image = image(item),
Name = GetLanguageSpecificName(language, item),
LocationImage = TypeTreeNode.GetIcon(type),
Location = language.TypeDefinitionToString(type, includeNamespace: true)
Location = language.TypeToString(Language.MakeParameterizedType(type), includeNamespace: true)
});
}
}
@ -497,7 +497,7 @@ namespace ICSharpCode.ILSpy @@ -497,7 +497,7 @@ namespace ICSharpCode.ILSpy
public override void Search(ITypeDefinition type, Language language, Action<SearchResult> addResult)
{
if (MatchName(type, language)) {
string name = language.TypeDefinitionToString(type, includeNamespace: false);
string name = language.TypeToString(Language.MakeParameterizedType(type), includeNamespace: false);
var declaringType = type.DeclaringTypeDefinition;
addResult(new SearchResult {
Member = type,
@ -505,7 +505,7 @@ namespace ICSharpCode.ILSpy @@ -505,7 +505,7 @@ namespace ICSharpCode.ILSpy
Image = TypeTreeNode.GetIcon(type),
Name = name,
LocationImage = declaringType != null ? TypeTreeNode.GetIcon(declaringType) : Images.Namespace,
Location = declaringType != null ? language.TypeDefinitionToString(declaringType, includeNamespace: true) : type.Namespace
Location = declaringType != null ? language.TypeToString(Language.MakeParameterizedType(declaringType), includeNamespace: true) : type.Namespace
});
}
@ -526,7 +526,7 @@ namespace ICSharpCode.ILSpy @@ -526,7 +526,7 @@ namespace ICSharpCode.ILSpy
{
if (MatchName(type, language))
{
string name = language.TypeDefinitionToString(type, includeNamespace: false);
string name = language.TypeToString(Language.MakeParameterizedType(type), includeNamespace: false);
var declaringType = type.DeclaringTypeDefinition;
addResult(new SearchResult {
Member = type,
@ -534,7 +534,7 @@ namespace ICSharpCode.ILSpy @@ -534,7 +534,7 @@ namespace ICSharpCode.ILSpy
Fitness = CalculateFitness(type),
Name = name,
LocationImage = declaringType != null ? TypeTreeNode.GetIcon(declaringType) : Images.Namespace,
Location = declaringType != null ? language.TypeDefinitionToString(declaringType, includeNamespace: true) : type.Namespace
Location = declaringType != null ? language.TypeToString(Language.MakeParameterizedType(declaringType), includeNamespace: true) : type.Namespace
});
}

44
ILSpy/TreeNodes/BaseTypesEntryNode.cs

@ -17,6 +17,7 @@ @@ -17,6 +17,7 @@
// DEALINGS IN THE SOFTWARE.
using System;
using System.Diagnostics;
using System.Linq;
using System.Reflection.Metadata;
using ICSharpCode.Decompiler;
@ -32,7 +33,8 @@ namespace ICSharpCode.ILSpy.TreeNodes @@ -32,7 +33,8 @@ namespace ICSharpCode.ILSpy.TreeNodes
readonly EntityHandle handle;
readonly IType type;
readonly bool isInterface;
readonly bool showExpander;
bool showExpander;
object text;
public BaseTypesEntryNode(PEFile module, EntityHandle handle, IType type, bool isInterface)
{
@ -43,30 +45,37 @@ namespace ICSharpCode.ILSpy.TreeNodes @@ -43,30 +45,37 @@ namespace ICSharpCode.ILSpy.TreeNodes
this.type = type;
this.isInterface = isInterface;
this.LazyLoading = true;
showExpander = true;
TryResolve(module, handle, type);
}
/*var td = tr.ResolveAsType();
if (!td.IsNil) {
var typeDef = td.Module.Metadata.GetTypeDefinition(td.Handle);
showExpander = !typeDef.BaseType.IsNil || typeDef.GetInterfaceImplementations().Any();
ITypeDefinition TryResolve(PEFile module, EntityHandle handle, IType type, bool mayRetry = true)
{
DecompilerTypeSystem typeSystem = new DecompilerTypeSystem(module, module.GetAssemblyResolver());
var t = typeSystem.ResolveAsType(handle).GetDefinition();
if (t != null) {
showExpander = t.DirectBaseTypes.Any();
var other = t.ParentAssembly.PEFile.GetTypeSystemOrNull();
Debug.Assert(other != null);
t = other.FindType(t.FullTypeName).GetDefinition();
text = this.Language.TypeToString(Language.MakeParameterizedType(t), includeNamespace: true) + handle.ToSuffixString();
} else {
showExpander = false;
}*/
showExpander = mayRetry;
text = this.Language.TypeToString(type, includeNamespace: true) + handle.ToSuffixString();
}
RaisePropertyChanged(nameof(Text));
RaisePropertyChanged(nameof(ShowExpander));
return t;
}
public override bool ShowExpander => showExpander;
public override object Text
{
get { return this.Language.TypeToString(type, includeNamespace: true) + handle.ToSuffixString(); }
}
public override object Text => text;
public override object Icon => isInterface ? Images.Interface : Images.Class;
protected override void LoadChildren()
{
DecompilerTypeSystem typeSystem = new DecompilerTypeSystem(module, module.GetAssemblyResolver());
var t = typeSystem.ResolveAsType(handle).GetDefinition();
var t = TryResolve(module, handle, type, false);
if (t != null) {
BaseTypesTreeNode.AddBaseTypes(this.Children, t.ParentAssembly.PEFile, t);
}
@ -74,8 +83,7 @@ namespace ICSharpCode.ILSpy.TreeNodes @@ -74,8 +83,7 @@ namespace ICSharpCode.ILSpy.TreeNodes
public override void ActivateItem(System.Windows.RoutedEventArgs e)
{
DecompilerTypeSystem typeSystem = new DecompilerTypeSystem(module, module.GetAssemblyResolver());
var t = typeSystem.ResolveAsType(handle).GetDefinition();
var t = TryResolve(module, handle, type, false);
e.Handled = ActivateItem(this, t);
}
@ -98,9 +106,7 @@ namespace ICSharpCode.ILSpy.TreeNodes @@ -98,9 +106,7 @@ namespace ICSharpCode.ILSpy.TreeNodes
IEntity IMemberTreeNode.Member {
get {
DecompilerTypeSystem typeSystem = new DecompilerTypeSystem(module, module.GetAssemblyResolver());
var t = typeSystem.ResolveAsType(handle).GetDefinition();
return t;
return TryResolve(module, handle, type, false);
}
}
}

3
ILSpy/TreeNodes/BaseTypesTreeNode.cs

@ -63,7 +63,8 @@ namespace ICSharpCode.ILSpy.TreeNodes @@ -63,7 +63,8 @@ namespace ICSharpCode.ILSpy.TreeNodes
i++;
}
foreach (var h in typeDef.GetInterfaceImplementations()) {
children.Add(new BaseTypesEntryNode(module, h, baseTypes[i], true));
var impl = module.Metadata.GetInterfaceImplementation(h);
children.Add(new BaseTypesEntryNode(module, impl.Interface, baseTypes[i], true));
i++;
}
}

35
ILSpy/TreeNodes/DerivedTypesTreeNode.cs

@ -21,22 +21,23 @@ using System.Linq; @@ -21,22 +21,23 @@ using System.Linq;
using System.Threading;
using ICSharpCode.Decompiler;
using ICSharpCode.Decompiler.Metadata;
using ICSharpCode.Decompiler.TypeSystem;
using ICSharpCode.Decompiler.Util;
using SRM = System.Reflection.Metadata;
namespace ICSharpCode.ILSpy.TreeNodes
{/*
{
/// <summary>
/// Lists the sub types of a class.
/// </summary>
sealed class DerivedTypesTreeNode : ILSpyTreeNode
{
readonly AssemblyList list;
readonly TypeDefinition type;
readonly ITypeDefinition type;
readonly ThreadingSupport threading;
public DerivedTypesTreeNode(AssemblyList list, TypeDefinition type)
public DerivedTypesTreeNode(AssemblyList list, ITypeDefinition type)
{
this.list = list;
this.type = type;
@ -44,15 +45,9 @@ namespace ICSharpCode.ILSpy.TreeNodes @@ -44,15 +45,9 @@ namespace ICSharpCode.ILSpy.TreeNodes
this.threading = new ThreadingSupport();
}
public override object Text
{
get { return "Derived Types"; }
}
public override object Text => "Derived Types";
public override object Icon
{
get { return Images.SubTypes; }
}
public override object Icon => Images.SubTypes;
protected override void LoadChildren()
{
@ -66,11 +61,11 @@ namespace ICSharpCode.ILSpy.TreeNodes @@ -66,11 +61,11 @@ namespace ICSharpCode.ILSpy.TreeNodes
return FindDerivedTypes(type, assemblies, cancellationToken);
}
internal static IEnumerable<DerivedTypesEntryNode> FindDerivedTypes(TypeDefinition type, PEFile[] assemblies, CancellationToken cancellationToken)
internal static IEnumerable<DerivedTypesEntryNode> FindDerivedTypes(ITypeDefinition type, PEFile[] assemblies, CancellationToken cancellationToken)
{
foreach (var module in assemblies) {
var metadata = module.Metadata;
foreach (var h in TreeTraversal.PreOrder(metadata.GetTopLevelTypeDefinitions(), t => metadata.GetTypeDefinition(t).GetNestedTypes())) {
/*foreach (var module in assemblies) {
var typeSystem = new DecompilerTypeSystem(module, module.GetAssemblyResolver());
foreach (var td in typeSystem.MainAssembly.TypeDefinitions) {
cancellationToken.ThrowIfCancellationRequested();
var td = new TypeDefinition(module, h);
var typeDefinition = metadata.GetTypeDefinition(h);
@ -83,19 +78,19 @@ namespace ICSharpCode.ILSpy.TreeNodes @@ -83,19 +78,19 @@ namespace ICSharpCode.ILSpy.TreeNodes
yield return new DerivedTypesEntryNode(td, assemblies);
}
}
}
}*/
yield break;
}
static bool IsSameType(SRM.MetadataReader referenceMetadata, SRM.EntityHandle typeRef, TypeDefinition type)
/*
static bool IsSameType(SRM.MetadataReader referenceMetadata, SRM.EntityHandle typeRef, ITypeDefinition type)
{
// FullName contains only namespace, name and type parameter count, therefore this should suffice.
return typeRef.GetFullTypeName(referenceMetadata) == type.Handle.GetFullTypeName(type.Module.Metadata);
}
}*/
public override void Decompile(Language language, ITextOutput output, DecompilationOptions options)
{
threading.Decompile(language, output, options, EnsureLazyChildren);
}
}*/
}
}

4
ILSpy/TreeNodes/IMemberTreeNode.cs

@ -27,6 +27,10 @@ namespace ICSharpCode.ILSpy.TreeNodes @@ -27,6 +27,10 @@ namespace ICSharpCode.ILSpy.TreeNodes
/// </summary>
public interface IMemberTreeNode
{
/// <summary>
/// Returns the entity that is represented by this tree node.
/// May return null, if the member cannot be resolved.
/// </summary>
IEntity Member { get; }
}
}

8
ILSpy/TreeNodes/TypeTreeNode.cs

@ -40,7 +40,7 @@ namespace ICSharpCode.ILSpy.TreeNodes @@ -40,7 +40,7 @@ namespace ICSharpCode.ILSpy.TreeNodes
public AssemblyTreeNode ParentAssemblyNode { get; }
public override object Text => this.Language.TypeDefinitionToString(TypeDefinition, includeNamespace: false)
public override object Text => this.Language.TypeToString(Language.MakeParameterizedType(TypeDefinition), includeNamespace: false)
+ TypeDefinition.MetadataToken.ToSuffixString();
public override bool IsPublicAPI {
@ -72,10 +72,10 @@ namespace ICSharpCode.ILSpy.TreeNodes @@ -72,10 +72,10 @@ namespace ICSharpCode.ILSpy.TreeNodes
protected override void LoadChildren()
{
if (!TypeDefinition.DirectBaseTypes.Any())
if (TypeDefinition.DirectBaseTypes.Any())
this.Children.Add(new BaseTypesTreeNode(ParentAssemblyNode.LoadedAssembly.GetPEFileOrNull(), TypeDefinition));
/*if (!TypeDefinition.IsSealed)
this.Children.Add(new DerivedTypesTreeNode(ParentAssemblyNode.AssemblyList, TypeDefinition));*/
if (!TypeDefinition.IsSealed)
this.Children.Add(new DerivedTypesTreeNode(ParentAssemblyNode.AssemblyList, TypeDefinition));
foreach (var nestedType in TypeDefinition.NestedTypes.OrderBy(t => t.Name, NaturalStringComparer.Instance)) {
this.Children.Add(new TypeTreeNode(nestedType, ParentAssemblyNode));
}

Loading…
Cancel
Save