public static async Task<IReadOnlyList<IRStackFrame>> TracebackAsync(
this IRSession session,
bool skipSourceFrames = true,
CancellationToken cancellationToken = default(CancellationToken)
) {
await TaskUtilities.SwitchToBackgroundThread();
var jFrames = await session.EvaluateAsync<JArray>("rtvs:::describe_traceback()", REvaluationKind.Normal, cancellationToken);
Trace.Assert(jFrames.All(t => t is JObject), "rtvs:::describe_traceback(): array of objects expected.\n\n" + jFrames);
var stackFrames = new List<RStackFrame>();
RStackFrame lastFrame = null;
int i = 0;
foreach (JObject jFrame in jFrames) {
lastFrame = new RStackFrame(session, i, lastFrame, jFrame);
stackFrames.Add(lastFrame);
++i;
}
if (skipSourceFrames) {
var firstFrame = stackFrames.FirstOrDefault();
if (firstFrame != null && firstFrame.IsGlobal && firstFrame.Call != null) {
if (firstFrame.Call.StartsWith("source(") || firstFrame.Call.StartsWith("rtvs::debug_source(")) {
// Skip everything until the first frame that has a line number - that will be the sourced code.
stackFrames = stackFrames.SkipWhile(f => f.LineNumber == null).ToList();
}
}
}
return stackFrames;
}
}