summaryrefslogtreecommitdiffstats
path: root/devtools/client/debugger/src/actions/pause/commands.js
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-21 11:44:51 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-21 11:44:51 +0000
commit9e3c08db40b8916968b9f30096c7be3f00ce9647 (patch)
treea68f146d7fa01f0134297619fbe7e33db084e0aa /devtools/client/debugger/src/actions/pause/commands.js
parentInitial commit. (diff)
downloadthunderbird-9e3c08db40b8916968b9f30096c7be3f00ce9647.tar.xz
thunderbird-9e3c08db40b8916968b9f30096c7be3f00ce9647.zip
Adding upstream version 1:115.7.0.upstream/1%115.7.0upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'devtools/client/debugger/src/actions/pause/commands.js')
-rw-r--r--devtools/client/debugger/src/actions/pause/commands.js157
1 files changed, 157 insertions, 0 deletions
diff --git a/devtools/client/debugger/src/actions/pause/commands.js b/devtools/client/debugger/src/actions/pause/commands.js
new file mode 100644
index 0000000000..27478d6ad2
--- /dev/null
+++ b/devtools/client/debugger/src/actions/pause/commands.js
@@ -0,0 +1,157 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at <http://mozilla.org/MPL/2.0/>. */
+
+import {
+ getSelectedFrame,
+ getThreadContext,
+ getCurrentThread,
+ getIsCurrentThreadPaused,
+} from "../../selectors";
+import { PROMISE } from "../utils/middleware/promise";
+import { evaluateExpressions } from "../expressions";
+import { selectLocation } from "../sources";
+import { fetchScopes } from "./fetchScopes";
+import { fetchFrames } from "./fetchFrames";
+import { recordEvent } from "../../utils/telemetry";
+import assert from "../../utils/assert";
+
+export function selectThread(cx, thread) {
+ return async ({ dispatch, getState, client }) => {
+ if (getCurrentThread(getState()) === thread) {
+ return;
+ }
+
+ dispatch({ cx, type: "SELECT_THREAD", thread });
+
+ // Get a new context now that the current thread has changed.
+ const threadcx = getThreadContext(getState());
+ // Note that this is a rethorical assertion as threadcx.thread is updated by SELECT_THREAD action
+ assert(threadcx.thread == thread, "Thread mismatch");
+
+ const serverRequests = [];
+ // Update the watched expressions as we may never have evaluated them against this thread
+ serverRequests.push(dispatch(evaluateExpressions(threadcx)));
+
+ // If we were paused on the newly selected thread, ensure:
+ // - select the source where we are paused,
+ // - fetching the paused stackframes,
+ // - fetching the paused scope, so that variable preview are working on the selected source.
+ // (frames and scopes is supposed to be fetched on pause,
+ // but if two threads pause concurrently, it might be cancelled)
+ const frame = getSelectedFrame(getState(), thread);
+ if (frame) {
+ serverRequests.push(dispatch(selectLocation(threadcx, frame.location)));
+ serverRequests.push(dispatch(fetchFrames(threadcx)));
+ serverRequests.push(dispatch(fetchScopes(threadcx)));
+ }
+
+ await Promise.all(serverRequests);
+ };
+}
+
+/**
+ * Debugger commands like stepOver, stepIn, stepUp
+ *
+ * @param string $0.type
+ * @memberof actions/pause
+ * @static
+ */
+export function command(type) {
+ return async ({ dispatch, getState, client }) => {
+ if (!type) {
+ return null;
+ }
+ // For now, all commands are by default against the currently selected thread
+ const thread = getCurrentThread(getState());
+
+ const frame = getSelectedFrame(getState(), thread);
+
+ return dispatch({
+ type: "COMMAND",
+ command: type,
+ thread,
+ [PROMISE]: client[type](thread, frame?.id),
+ });
+ };
+}
+
+/**
+ * StepIn
+ * @memberof actions/pause
+ * @static
+ * @returns {Function} {@link command}
+ */
+export function stepIn() {
+ return ({ dispatch, getState }) => {
+ if (!getIsCurrentThreadPaused(getState())) {
+ return null;
+ }
+ return dispatch(command("stepIn"));
+ };
+}
+
+/**
+ * stepOver
+ * @memberof actions/pause
+ * @static
+ * @returns {Function} {@link command}
+ */
+export function stepOver() {
+ return ({ dispatch, getState }) => {
+ if (!getIsCurrentThreadPaused(getState())) {
+ return null;
+ }
+ return dispatch(command("stepOver"));
+ };
+}
+
+/**
+ * stepOut
+ * @memberof actions/pause
+ * @static
+ * @returns {Function} {@link command}
+ */
+export function stepOut() {
+ return ({ dispatch, getState }) => {
+ if (!getIsCurrentThreadPaused(getState())) {
+ return null;
+ }
+ return dispatch(command("stepOut"));
+ };
+}
+
+/**
+ * resume
+ * @memberof actions/pause
+ * @static
+ * @returns {Function} {@link command}
+ */
+export function resume() {
+ return ({ dispatch, getState }) => {
+ if (!getIsCurrentThreadPaused(getState())) {
+ return null;
+ }
+ recordEvent("continue");
+ return dispatch(command("resume"));
+ };
+}
+
+/**
+ * restart frame
+ * @memberof actions/pause
+ * @static
+ */
+export function restart(cx, frame) {
+ return async ({ dispatch, getState, client }) => {
+ if (!getIsCurrentThreadPaused(getState())) {
+ return null;
+ }
+ return dispatch({
+ type: "COMMAND",
+ command: "restart",
+ thread: cx.thread,
+ [PROMISE]: client.restart(cx.thread, frame.id),
+ });
+ };
+}