/* 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 {
getExpression,
getExpressions,
getSelectedSource,
getSelectedScopeMappings,
getSelectedFrameBindings,
getIsPaused,
getSelectedFrame,
getCurrentThread,
isMapScopesEnabled,
} from "../selectors/index"; import { PROMISE } from "./utils/middleware/promise"; import { wrapExpression } from "../utils/expressions"; import { features } from "../utils/prefs";
/** * Add expression for debugger to watch * * @param {string} input
*/
export function addExpression(input) { return async ({ dispatch, getState }) => { if (!input) { returnnull;
}
// If the expression already exists, only update its evaluation
let expression = getExpression(getState(), input); if (!expression) { // This will only display the expression input, // evaluateExpression will update its value.
dispatch({ type: "ADD_EXPRESSION", input });
expression = getExpression(getState(), input); // When there is an expression error, we won't store the expression if (!expression) { returnnull;
}
}
/** * Update all the expressions by querying the server for updated values. * * @param {object} selectedFrame * If defined, will evaluate the expression against this given frame, * otherwise it will use the global scope of the thread.
*/
export function evaluateExpressions(selectedFrame) { return async function ({ dispatch, getState, client }) { const expressions = getExpressions(getState()); const inputs = expressions.map(({ input }) => input); // Fallback to global scope of the current thread when selectedFrame is null constthread = selectedFrame?.thread || getCurrentThread(getState()); const results = await client.evaluateExpressions(inputs, { // We will only have a specific frame when passing a Selected frame context.
frameId: selectedFrame?.id,
threadId: thread,
}); // Pass both selectedFrame and thread in case selectedFrame is null
dispatch({
type: "EVALUATE_EXPRESSIONS",
selectedFrame, // As `selectedFrame` can be null, pass `thread` to help // the reducer know what is the related thread of this action. thread,
inputs,
results,
});
};
}
function evaluateExpression(expression) { return async function (thunkArgs) {
let { input } = expression; if (!input) {
console.warn("Expressions should not be empty"); returnnull;
}
const selectedSource = getSelectedSource(getState()); // Only map when we are paused and if the currently selected source is original, // and the paused location is also original. if (
selectedFrame &&
selectedSource &&
selectedFrame.location.source.isOriginal &&
selectedSource.isOriginal
) { const mapResult = await getMappedExpression(
input,
selectedFrame.thread,
thunkArgs
); if (mapResult) {
input = mapResult.expression;
}
}
// Pass both selectedFrame and thread in case selectedFrame is null return dispatch({
type: "EVALUATE_EXPRESSION",
selectedFrame, // When we aren't passing a frame, we have to pass a thread to the pause reducer thread: selectedFrame ? null : thread,
input: expression.input,
[PROMISE]: client.evaluate(wrapExpression(input), { // When evaluating against the global scope (when not paused) // frameId will be null here.
frameId: selectedFrame?.id,
}),
});
};
}
/** * Gets information about original variable names from the source map * and replaces all possible generated names.
*/
export function getMappedExpression(expression, thread, thunkArgs) { const { getState, parserWorker } = thunkArgs; const mappings = getSelectedScopeMappings(getState(), thread); const bindings = getSelectedFrameBindings(getState(), thread);
// We bail early if we do not need to map the expression. This is important // because mapping an expression can be slow if the parserWorker // worker is busy doing other work. // // 1. there are no mappings - we do not need to map original expressions // 2. does not contain `await` - we do not need to map top level awaits // 3. does not contain `=` - we do not need to map assignments const shouldMapScopes = isMapScopesEnabled(getState()) && mappings; if (!shouldMapScopes && !expression.match(/(await|=)/)) { returnnull;
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung ist noch experimentell.