|
|
|
@ -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(); |
|
|
|
|
} |
|
|
|
|