public bool TryDecompile()
        {
            Debug.Assert(output == null);
            output = new DecompilerOutputImpl();

            if (!StateMachineHelpers.TryGetKickoffMethod(method, out var containingMethod))
            {
                containingMethod = method;
            }

            var ctx = new DecompilationContext()
            {
                CancellationToken            = cancellationToken,
                CalculateILSpans             = true,
                AsyncMethodBodyDecompilation = false,
            };
            var info = TryDecompileCode(containingMethod, method.MDToken.Raw, ctx, output);

            if (info.debugInfo == null && containingMethod != method)
            {
                output.Clear();
                // The decompiler can't decompile the iterator / async method, try again,
                // but only decompile the MoveNext method
                info = TryDecompileCode(method, method.MDToken.Raw, ctx, output);
            }
            debugInfo = info.debugInfo;
            return(debugInfo != null);
        }
 public DecompiledCodeProvider(IDecompiler decompiler, MethodDef method, CancellationToken cancellationToken)
 {
     this.decompiler        = decompiler ?? throw new ArgumentNullException(nameof(decompiler));
     this.method            = method ?? throw new ArgumentNullException(nameof(method));
     this.cancellationToken = cancellationToken;
     output    = null;
     debugInfo = null;
 }
        (MethodDebugInfo debugInfo, MethodDebugInfo?stateMachineDebugInfo) TryDecompileCode(MethodDef method, uint methodToken, DecompilationContext ctx, DecompilerOutputImpl output)
        {
            output.Initialize(methodToken);
            decompiler.Decompile(method, output, ctx);
            var info = output.TryGetMethodDebugInfo();

            cancellationToken.ThrowIfCancellationRequested();
            return(info);
        }