blob: 4b7bceefcf54bfa001c9e9663c204b1f87a8cf21 [file] [log] [blame]
// Copyright 2025 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import * as Protocol from '../generated/protocol.js';
import type * as StackTrace from '../models/stack_trace/stack_trace.js';
/**
* Easily create `Protocol.Runtime.CallFrame`s by passing a string of the format: `<url>:<scriptId>:<name>:<line>:<column>`
*/
export function protocolCallFrame(descriptor: string): Protocol.Runtime.CallFrame {
// Since URLs can contain colons, we count from the end and rejoin the rest again.
const parts = descriptor.split(':');
return {
url: parts.slice(0, -4).join(':'),
scriptId: parts.at(-4) as Protocol.Runtime.ScriptId,
functionName: parts.at(-3) ?? '',
lineNumber: parts.at(-2) ? Number.parseInt(parts.at(-2)!, 10) : -1,
columnNumber: parts.at(-1) ? Number.parseInt(parts.at(-1)!, 10) : -1,
};
}
/**
* Easily create `Protocol.Debugger.CallFrame`s by passing a string of the format: `<url>:<scriptId>:<name>:<line>:<column>`
*/
export function debuggerCallFrame(descriptor: string): Protocol.Debugger.CallFrame {
// Since URLs can contain colons, we count from the end and rejoin the rest again.
const parts = descriptor.split(':');
return {
url: parts.slice(0, -4).join(':'),
callFrameId: 'cfid' + parts.at(-4)! as Protocol.Debugger.CallFrameId,
this: {type: Protocol.Runtime.RemoteObjectType.Undefined},
scopeChain: [],
location: {
scriptId: parts.at(-4) as Protocol.Runtime.ScriptId,
lineNumber: parts.at(-2) ? Number.parseInt(parts.at(-2)!, 10) : -1,
columnNumber: parts.at(-1) ? Number.parseInt(parts.at(-1)!, 10) : -1,
},
functionName: parts.at(-3) ?? '',
};
}
export function stringifyFrame(frame: StackTrace.StackTrace.Frame): string {
let result = `at ${frame.name ?? '<anonymous>'}`;
if (frame.uiSourceCode) {
result += ` (${frame.uiSourceCode.displayName()}:${frame.line}:${frame.column})`;
} else if (frame.url) {
result += ` (${frame.url}:${frame.line}:${frame.column})`;
}
return result;
}
export function stringifyFragment(fragment: StackTrace.StackTrace.Fragment): string {
return fragment.frames.map(stringifyFrame).join('\n');
}
export function stringifyAsyncFragment(fragment: StackTrace.StackTrace.AsyncFragment): string {
const separatorLineLength = 40;
const prefix = `--- ${fragment.description || 'async'} `;
const separator = prefix + '-'.repeat(separatorLineLength - prefix.length);
return separator + '\n' + stringifyFragment(fragment);
}
export function stringifyStackTrace(stackTrace: StackTrace.StackTrace.StackTrace): string {
return [stringifyFragment(stackTrace.syncFragment), ...stackTrace.asyncFragments.map(stringifyAsyncFragment)].join(
'\n');
}