Browse Source

#2823: Introduce `IType.GetDefinitionOrUnknown()` to allow better detection of async state-machines involving unknown types.

pull/2828/head
Siegfried Pammer 3 years ago
parent
commit
6766ad0c59
  1. 6
      ICSharpCode.Decompiler/IL/ControlFlow/AsyncAwaitDecompiler.cs
  2. 5
      ICSharpCode.Decompiler/TypeSystem/FunctionPointerType.cs
  3. 6
      ICSharpCode.Decompiler/TypeSystem/IType.cs
  4. 4
      ICSharpCode.Decompiler/TypeSystem/ITypeDefinition.cs
  5. 34
      ICSharpCode.Decompiler/TypeSystem/ITypeDefinitionOrUnknown.cs
  6. 5
      ICSharpCode.Decompiler/TypeSystem/Implementation/AbstractType.cs
  7. 5
      ICSharpCode.Decompiler/TypeSystem/Implementation/AbstractTypeParameter.cs
  8. 5
      ICSharpCode.Decompiler/TypeSystem/Implementation/DecoratedType.cs
  9. 1
      ICSharpCode.Decompiler/TypeSystem/Implementation/MetadataTypeDefinition.cs
  10. 1
      ICSharpCode.Decompiler/TypeSystem/Implementation/MinimalCorlib.cs
  11. 7
      ICSharpCode.Decompiler/TypeSystem/Implementation/UnknownType.cs
  12. 5
      ICSharpCode.Decompiler/TypeSystem/ModifiedType.cs
  13. 5
      ICSharpCode.Decompiler/TypeSystem/ParameterizedType.cs
  14. 5
      ICSharpCode.Decompiler/TypeSystem/TupleType.cs

6
ICSharpCode.Decompiler/IL/ControlFlow/AsyncAwaitDecompiler.cs

@ -234,14 +234,10 @@ namespace ICSharpCode.Decompiler.IL.ControlFlow @@ -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;

5
ICSharpCode.Decompiler/TypeSystem/FunctionPointerType.cs

@ -132,6 +132,11 @@ namespace ICSharpCode.Decompiler.TypeSystem @@ -132,6 +132,11 @@ namespace ICSharpCode.Decompiler.TypeSystem
}
}
public override ITypeDefinitionOrUnknown GetDefinitionOrUnknown()
{
return GetDefinition();
}
public override IType AcceptVisitor(TypeVisitor visitor)
{
return visitor.VisitFunctionPointerType(this);

6
ICSharpCode.Decompiler/TypeSystem/IType.cs

@ -87,6 +87,12 @@ namespace ICSharpCode.Decompiler.TypeSystem @@ -87,6 +87,12 @@ namespace ICSharpCode.Decompiler.TypeSystem
/// </summary>
ITypeDefinition? GetDefinition();
/// <summary>
/// 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).
/// </summary>
ITypeDefinitionOrUnknown? GetDefinitionOrUnknown();
/// <summary>
/// Gets the parent type, if this is a nested type.
/// Returns null for top-level types.

4
ICSharpCode.Decompiler/TypeSystem/ITypeDefinition.cs

@ -23,10 +23,10 @@ using System.Collections.Generic; @@ -23,10 +23,10 @@ using System.Collections.Generic;
namespace ICSharpCode.Decompiler.TypeSystem
{
/// <summary>
/// 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.
/// </summary>
public interface ITypeDefinition : IType, IEntity
public interface ITypeDefinition : ITypeDefinitionOrUnknown, IType, IEntity
{
IReadOnlyList<ITypeDefinition> NestedTypes { get; }
IReadOnlyList<IMember> Members { get; }

34
ICSharpCode.Decompiler/TypeSystem/ITypeDefinitionOrUnknown.cs

@ -0,0 +1,34 @@ @@ -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
{
/// <summary>
/// Represents a class, enum, interface, struct, delegate, record or unknown type.
/// For partial classes, this represents the whole class.
/// </summary>
public interface ITypeDefinitionOrUnknown : IType
{
/// <summary>
/// Gets the full name of this type.
/// </summary>
FullTypeName FullTypeName { get; }
}
}

5
ICSharpCode.Decompiler/TypeSystem/Implementation/AbstractType.cs

@ -91,6 +91,11 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation @@ -91,6 +91,11 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation
return null;
}
public virtual ITypeDefinitionOrUnknown GetDefinitionOrUnknown()
{
return null;
}
public virtual IEnumerable<IType> DirectBaseTypes {
get { return EmptyList<IType>.Instance; }
}

5
ICSharpCode.Decompiler/TypeSystem/Implementation/AbstractTypeParameter.cs

@ -270,6 +270,11 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation @@ -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);

5
ICSharpCode.Decompiler/TypeSystem/Implementation/DecoratedType.cs

@ -59,6 +59,11 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation @@ -59,6 +59,11 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation
return baseType.GetDefinition();
}
ITypeDefinitionOrUnknown IType.GetDefinitionOrUnknown()
{
return baseType.GetDefinitionOrUnknown();
}
IEnumerable<IEvent> IType.GetEvents(Predicate<IEvent> filter, GetMemberOptions options)
{
return baseType.GetEvents(filter, options);

1
ICSharpCode.Decompiler/TypeSystem/Implementation/MetadataTypeDefinition.cs

@ -530,6 +530,7 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation @@ -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)

1
ICSharpCode.Decompiler/TypeSystem/Implementation/MinimalCorlib.cs

@ -310,6 +310,7 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation @@ -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)

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

@ -26,7 +26,7 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation @@ -26,7 +26,7 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation
/// An unknown type where (part) of the name is known.
/// </summary>
[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 @@ -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; }
}

5
ICSharpCode.Decompiler/TypeSystem/ModifiedType.cs

@ -58,6 +58,11 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation @@ -58,6 +58,11 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation
return elementType.GetDefinition();
}
public override ITypeDefinitionOrUnknown GetDefinitionOrUnknown()
{
return elementType.GetDefinitionOrUnknown();
}
public override IEnumerable<IMethod> GetAccessors(Predicate<IMethod> filter = null, GetMemberOptions options = GetMemberOptions.None)
{
return elementType.GetAccessors(filter, options);

5
ICSharpCode.Decompiler/TypeSystem/ParameterizedType.cs

@ -180,6 +180,11 @@ namespace ICSharpCode.Decompiler.TypeSystem @@ -180,6 +180,11 @@ namespace ICSharpCode.Decompiler.TypeSystem
return genericType.GetDefinition();
}
public ITypeDefinitionOrUnknown GetDefinitionOrUnknown()
{
return genericType.GetDefinitionOrUnknown();
}
/// <summary>
/// Gets a type visitor that performs the substitution of class type parameters with the type arguments
/// of this parameterized type.

5
ICSharpCode.Decompiler/TypeSystem/TupleType.cs

@ -312,6 +312,11 @@ namespace ICSharpCode.Decompiler.TypeSystem @@ -312,6 +312,11 @@ namespace ICSharpCode.Decompiler.TypeSystem
return UnderlyingType.GetDefinition();
}
public override ITypeDefinitionOrUnknown GetDefinitionOrUnknown()
{
return UnderlyingType.GetDefinitionOrUnknown();
}
public override IEnumerable<IEvent> GetEvents(Predicate<IEvent> filter = null, GetMemberOptions options = GetMemberOptions.None)
{
return UnderlyingType.GetEvents(filter, options);

Loading…
Cancel
Save