Browse Source

Don't require a definition for the task builder type, also accept an UnknownType.

pull/2113/head
Daniel Grunwald 5 years ago
parent
commit
5bd47c171f
  1. 27
      ICSharpCode.Decompiler/IL/ControlFlow/AsyncAwaitDecompiler.cs
  2. 4
      ICSharpCode.Decompiler/TypeSystem/Implementation/UnknownType.cs

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

@ -20,6 +20,7 @@ using ICSharpCode.Decompiler.CSharp; @@ -20,6 +20,7 @@ using ICSharpCode.Decompiler.CSharp;
using ICSharpCode.Decompiler.DebugInfo;
using ICSharpCode.Decompiler.IL.Transforms;
using ICSharpCode.Decompiler.TypeSystem;
using ICSharpCode.Decompiler.TypeSystem.Implementation;
using ICSharpCode.Decompiler.Util;
using System;
using System.Collections.Generic;
@ -74,7 +75,7 @@ namespace ICSharpCode.Decompiler.IL.ControlFlow @@ -74,7 +75,7 @@ namespace ICSharpCode.Decompiler.IL.ControlFlow
IType underlyingReturnType; // return type of the method (only the "T" for Task{T}), for async enumerators this is the type being yielded
AsyncMethodType methodType;
ITypeDefinition stateMachineType;
ITypeDefinition builderType;
IType builderType;
IField builderField;
IField stateField;
int initialState;
@ -218,24 +219,32 @@ namespace ICSharpCode.Decompiler.IL.ControlFlow @@ -218,24 +219,32 @@ namespace ICSharpCode.Decompiler.IL.ControlFlow
if (startCall.Method.Name != "Start")
return false;
taskType = function.Method.ReturnType;
builderType = startCall.Method.DeclaringTypeDefinition;
builderType = startCall.Method.DeclaringType;
FullTypeName builderTypeName;
if (builderType?.GetDefinition() is { } builderTypeDef) {
builderTypeName = builderTypeDef.FullTypeName;
} else if (builderType is UnknownType unknownBuilderType) {
builderTypeName = unknownBuilderType.FullTypeName;
} else {
return false;
}
if (taskType.IsKnownType(KnownTypeCode.Void)) {
methodType = AsyncMethodType.Void;
underlyingReturnType = taskType;
if (builderType?.FullTypeName != new TopLevelTypeName("System.Runtime.CompilerServices", "AsyncVoidMethodBuilder"))
if (builderTypeName != new TopLevelTypeName("System.Runtime.CompilerServices", "AsyncVoidMethodBuilder"))
return false;
} else if (TaskType.IsNonGenericTaskType(taskType, out var builderTypeName)) {
} else if (TaskType.IsNonGenericTaskType(taskType, out var builderTypeNameFromTask)) {
methodType = AsyncMethodType.Task;
underlyingReturnType = context.TypeSystem.FindType(KnownTypeCode.Void);
if (builderType?.FullTypeName != builderTypeName)
if (builderTypeNameFromTask != builderTypeName)
return false;
} else if (TaskType.IsGenericTaskType(taskType, out builderTypeName)) {
} else if (TaskType.IsGenericTaskType(taskType, out builderTypeNameFromTask)) {
methodType = AsyncMethodType.TaskOfT;
if (taskType.IsKnownType(KnownTypeCode.TaskOfT))
underlyingReturnType = TaskType.UnpackTask(context.TypeSystem, taskType);
else
underlyingReturnType = startCall.Method.DeclaringType.TypeArguments[0];
if (builderType?.FullTypeName != builderTypeName)
if (builderTypeNameFromTask != builderTypeName)
return false;
} else {
return false;
@ -484,7 +493,7 @@ namespace ICSharpCode.Decompiler.IL.ControlFlow @@ -484,7 +493,7 @@ namespace ICSharpCode.Decompiler.IL.ControlFlow
return false;
}
static void AnalyzeEnumeratorCtor(IMethod ctor, ILTransformContext context, out IField builderField, out ITypeDefinition builderType, out IField stateField)
static void AnalyzeEnumeratorCtor(IMethod ctor, ILTransformContext context, out IField builderField, out IType builderType, out IField stateField)
{
builderField = null;
stateField = null;
@ -515,7 +524,7 @@ namespace ICSharpCode.Decompiler.IL.ControlFlow @@ -515,7 +524,7 @@ namespace ICSharpCode.Decompiler.IL.ControlFlow
if (stateField == null || builderField == null)
throw new SymbolicAnalysisFailedException();
builderType = builderField.Type.GetDefinition();
builderType = builderField.Type;
if (builderType == null)
throw new SymbolicAnalysisFailedException();
}

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

@ -86,7 +86,9 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation @@ -86,7 +86,9 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation
public override string ReflectionName {
get { return namespaceKnown ? fullTypeName.ReflectionName : "?"; }
}
public FullTypeName FullTypeName => fullTypeName;
public override int TypeParameterCount => fullTypeName.TypeParameterCount;
public override IReadOnlyList<ITypeParameter> TypeParameters => DummyTypeParameter.GetClassTypeParameterList(TypeParameterCount);
public override IReadOnlyList<IType> TypeArguments => TypeParameters;

Loading…
Cancel
Save