diff --git a/ICSharpCode.Decompiler/IL/ControlFlow/AsyncAwaitDecompiler.cs b/ICSharpCode.Decompiler/IL/ControlFlow/AsyncAwaitDecompiler.cs index 67b687362..2cee6081a 100644 --- a/ICSharpCode.Decompiler/IL/ControlFlow/AsyncAwaitDecompiler.cs +++ b/ICSharpCode.Decompiler/IL/ControlFlow/AsyncAwaitDecompiler.cs @@ -234,14 +234,10 @@ namespace ICSharpCode.Decompiler.IL.ControlFlow taskType = function.Method.ReturnType; builderType = startCall.Method.DeclaringType; FullTypeName builderTypeName; - if (builderType?.GetDefinition() is { } builderTypeDef) + if (builderType?.GetDefinitionOrUnknown() is { } builderTypeDef) { builderTypeName = builderTypeDef.FullTypeName; } - else if (builderType is UnknownType unknownBuilderType) - { - builderTypeName = unknownBuilderType.FullTypeName; - } else { return false; diff --git a/ICSharpCode.Decompiler/TypeSystem/FunctionPointerType.cs b/ICSharpCode.Decompiler/TypeSystem/FunctionPointerType.cs index d730daa4e..c2589db4d 100644 --- a/ICSharpCode.Decompiler/TypeSystem/FunctionPointerType.cs +++ b/ICSharpCode.Decompiler/TypeSystem/FunctionPointerType.cs @@ -132,6 +132,11 @@ namespace ICSharpCode.Decompiler.TypeSystem } } + public override ITypeDefinitionOrUnknown GetDefinitionOrUnknown() + { + return GetDefinition(); + } + public override IType AcceptVisitor(TypeVisitor visitor) { return visitor.VisitFunctionPointerType(this); diff --git a/ICSharpCode.Decompiler/TypeSystem/IType.cs b/ICSharpCode.Decompiler/TypeSystem/IType.cs index a5e38fc6a..6226e1315 100644 --- a/ICSharpCode.Decompiler/TypeSystem/IType.cs +++ b/ICSharpCode.Decompiler/TypeSystem/IType.cs @@ -87,6 +87,12 @@ namespace ICSharpCode.Decompiler.TypeSystem /// ITypeDefinition? GetDefinition(); + /// + /// Gets the underlying type definition or UnkownType, if unknown. + /// Can return null for types which do not have a type definition (for example arrays, pointers, type parameters). + /// + ITypeDefinitionOrUnknown? GetDefinitionOrUnknown(); + /// /// Gets the parent type, if this is a nested type. /// Returns null for top-level types. diff --git a/ICSharpCode.Decompiler/TypeSystem/ITypeDefinition.cs b/ICSharpCode.Decompiler/TypeSystem/ITypeDefinition.cs index 2b0672307..fdac74dd9 100644 --- a/ICSharpCode.Decompiler/TypeSystem/ITypeDefinition.cs +++ b/ICSharpCode.Decompiler/TypeSystem/ITypeDefinition.cs @@ -23,10 +23,10 @@ using System.Collections.Generic; namespace ICSharpCode.Decompiler.TypeSystem { /// - /// Represents a class, enum, interface, struct, delegate or VB module. + /// Represents a class, enum, interface, struct, delegate, record or VB module. /// For partial classes, this represents the whole class. /// - public interface ITypeDefinition : IType, IEntity + public interface ITypeDefinition : ITypeDefinitionOrUnknown, IType, IEntity { IReadOnlyList NestedTypes { get; } IReadOnlyList Members { get; } diff --git a/ICSharpCode.Decompiler/TypeSystem/ITypeDefinitionOrUnknown.cs b/ICSharpCode.Decompiler/TypeSystem/ITypeDefinitionOrUnknown.cs new file mode 100644 index 000000000..87de6f5d4 --- /dev/null +++ b/ICSharpCode.Decompiler/TypeSystem/ITypeDefinitionOrUnknown.cs @@ -0,0 +1,34 @@ +// Copyright (c) 2022 Siegfried Pammer +// +// 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 + +namespace ICSharpCode.Decompiler.TypeSystem +{ + /// + /// Represents a class, enum, interface, struct, delegate, record or unknown type. + /// For partial classes, this represents the whole class. + /// + public interface ITypeDefinitionOrUnknown : IType + { + /// + /// Gets the full name of this type. + /// + FullTypeName FullTypeName { get; } + } +} diff --git a/ICSharpCode.Decompiler/TypeSystem/Implementation/AbstractType.cs b/ICSharpCode.Decompiler/TypeSystem/Implementation/AbstractType.cs index 44e63b963..3d7d1e115 100644 --- a/ICSharpCode.Decompiler/TypeSystem/Implementation/AbstractType.cs +++ b/ICSharpCode.Decompiler/TypeSystem/Implementation/AbstractType.cs @@ -91,6 +91,11 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation return null; } + public virtual ITypeDefinitionOrUnknown GetDefinitionOrUnknown() + { + return null; + } + public virtual IEnumerable DirectBaseTypes { get { return EmptyList.Instance; } } diff --git a/ICSharpCode.Decompiler/TypeSystem/Implementation/AbstractTypeParameter.cs b/ICSharpCode.Decompiler/TypeSystem/Implementation/AbstractTypeParameter.cs index c034d1d2a..0660573f0 100644 --- a/ICSharpCode.Decompiler/TypeSystem/Implementation/AbstractTypeParameter.cs +++ b/ICSharpCode.Decompiler/TypeSystem/Implementation/AbstractTypeParameter.cs @@ -270,6 +270,11 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation return null; } + ITypeDefinitionOrUnknown IType.GetDefinitionOrUnknown() + { + return null; + } + public IType AcceptVisitor(TypeVisitor visitor) { return visitor.VisitTypeParameter(this); diff --git a/ICSharpCode.Decompiler/TypeSystem/Implementation/DecoratedType.cs b/ICSharpCode.Decompiler/TypeSystem/Implementation/DecoratedType.cs index 2f949874d..5107044f2 100644 --- a/ICSharpCode.Decompiler/TypeSystem/Implementation/DecoratedType.cs +++ b/ICSharpCode.Decompiler/TypeSystem/Implementation/DecoratedType.cs @@ -59,6 +59,11 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation return baseType.GetDefinition(); } + ITypeDefinitionOrUnknown IType.GetDefinitionOrUnknown() + { + return baseType.GetDefinitionOrUnknown(); + } + IEnumerable IType.GetEvents(Predicate filter, GetMemberOptions options) { return baseType.GetEvents(filter, options); diff --git a/ICSharpCode.Decompiler/TypeSystem/Implementation/MetadataTypeDefinition.cs b/ICSharpCode.Decompiler/TypeSystem/Implementation/MetadataTypeDefinition.cs index 8417e33b0..4fe5a3586 100644 --- a/ICSharpCode.Decompiler/TypeSystem/Implementation/MetadataTypeDefinition.cs +++ b/ICSharpCode.Decompiler/TypeSystem/Implementation/MetadataTypeDefinition.cs @@ -530,6 +530,7 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation public string Namespace => fullTypeName.TopLevelTypeName.Namespace; ITypeDefinition IType.GetDefinition() => this; + ITypeDefinitionOrUnknown IType.GetDefinitionOrUnknown() => this; TypeParameterSubstitution IType.GetSubstitution() => TypeParameterSubstitution.Identity; public IType AcceptVisitor(TypeVisitor visitor) diff --git a/ICSharpCode.Decompiler/TypeSystem/Implementation/MinimalCorlib.cs b/ICSharpCode.Decompiler/TypeSystem/Implementation/MinimalCorlib.cs index 348d05169..28737d670 100644 --- a/ICSharpCode.Decompiler/TypeSystem/Implementation/MinimalCorlib.cs +++ b/ICSharpCode.Decompiler/TypeSystem/Implementation/MinimalCorlib.cs @@ -310,6 +310,7 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation bool ITypeDefinition.IsRecord => false; ITypeDefinition IType.GetDefinition() => this; + ITypeDefinitionOrUnknown IType.GetDefinitionOrUnknown() => this; TypeParameterSubstitution IType.GetSubstitution() => TypeParameterSubstitution.Identity; IType IType.AcceptVisitor(TypeVisitor visitor) diff --git a/ICSharpCode.Decompiler/TypeSystem/Implementation/UnknownType.cs b/ICSharpCode.Decompiler/TypeSystem/Implementation/UnknownType.cs index 51abb1a48..5db919db7 100644 --- a/ICSharpCode.Decompiler/TypeSystem/Implementation/UnknownType.cs +++ b/ICSharpCode.Decompiler/TypeSystem/Implementation/UnknownType.cs @@ -26,7 +26,7 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation /// An unknown type where (part) of the name is known. /// [Serializable] - public class UnknownType : AbstractType, ITypeReference + public class UnknownType : AbstractType, ITypeDefinitionOrUnknown, ITypeReference { readonly bool namespaceKnown; readonly FullTypeName fullTypeName; @@ -78,6 +78,11 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation return this; } + public override ITypeDefinitionOrUnknown GetDefinitionOrUnknown() + { + return this; + } + public override string Name { get { return fullTypeName.Name; } } diff --git a/ICSharpCode.Decompiler/TypeSystem/ModifiedType.cs b/ICSharpCode.Decompiler/TypeSystem/ModifiedType.cs index 31c677e33..d87668c35 100644 --- a/ICSharpCode.Decompiler/TypeSystem/ModifiedType.cs +++ b/ICSharpCode.Decompiler/TypeSystem/ModifiedType.cs @@ -58,6 +58,11 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation return elementType.GetDefinition(); } + public override ITypeDefinitionOrUnknown GetDefinitionOrUnknown() + { + return elementType.GetDefinitionOrUnknown(); + } + public override IEnumerable GetAccessors(Predicate filter = null, GetMemberOptions options = GetMemberOptions.None) { return elementType.GetAccessors(filter, options); diff --git a/ICSharpCode.Decompiler/TypeSystem/ParameterizedType.cs b/ICSharpCode.Decompiler/TypeSystem/ParameterizedType.cs index b20eba7de..3acc57860 100644 --- a/ICSharpCode.Decompiler/TypeSystem/ParameterizedType.cs +++ b/ICSharpCode.Decompiler/TypeSystem/ParameterizedType.cs @@ -180,6 +180,11 @@ namespace ICSharpCode.Decompiler.TypeSystem return genericType.GetDefinition(); } + public ITypeDefinitionOrUnknown GetDefinitionOrUnknown() + { + return genericType.GetDefinitionOrUnknown(); + } + /// /// Gets a type visitor that performs the substitution of class type parameters with the type arguments /// of this parameterized type. diff --git a/ICSharpCode.Decompiler/TypeSystem/TupleType.cs b/ICSharpCode.Decompiler/TypeSystem/TupleType.cs index 26c61cbbf..d77387f4f 100644 --- a/ICSharpCode.Decompiler/TypeSystem/TupleType.cs +++ b/ICSharpCode.Decompiler/TypeSystem/TupleType.cs @@ -312,6 +312,11 @@ namespace ICSharpCode.Decompiler.TypeSystem return UnderlyingType.GetDefinition(); } + public override ITypeDefinitionOrUnknown GetDefinitionOrUnknown() + { + return UnderlyingType.GetDefinitionOrUnknown(); + } + public override IEnumerable GetEvents(Predicate filter = null, GetMemberOptions options = GetMemberOptions.None) { return UnderlyingType.GetEvents(filter, options);