diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 19:33:14 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 19:33:14 +0000 |
commit | 36d22d82aa202bb199967e9512281e9a53db42c9 (patch) | |
tree | 105e8c98ddea1c1e4784a60a5a6410fa416be2de /devtools/client/debugger/src/actions/ast | |
parent | Initial commit. (diff) | |
download | firefox-esr-36d22d82aa202bb199967e9512281e9a53db42c9.tar.xz firefox-esr-36d22d82aa202bb199967e9512281e9a53db42c9.zip |
Adding upstream version 115.7.0esr.upstream/115.7.0esrupstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'devtools/client/debugger/src/actions/ast')
5 files changed, 205 insertions, 0 deletions
diff --git a/devtools/client/debugger/src/actions/ast/index.js b/devtools/client/debugger/src/actions/ast/index.js new file mode 100644 index 0000000000..ec2c1ae84c --- /dev/null +++ b/devtools/client/debugger/src/actions/ast/index.js @@ -0,0 +1,5 @@ +/* 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/>. */ + +export { setInScopeLines } from "./setInScopeLines"; diff --git a/devtools/client/debugger/src/actions/ast/moz.build b/devtools/client/debugger/src/actions/ast/moz.build new file mode 100644 index 0000000000..5b0152d2ad --- /dev/null +++ b/devtools/client/debugger/src/actions/ast/moz.build @@ -0,0 +1,11 @@ +# vim: set filetype=python: +# 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/. + +DIRS += [] + +CompiledModules( + "index.js", + "setInScopeLines.js", +) diff --git a/devtools/client/debugger/src/actions/ast/setInScopeLines.js b/devtools/client/debugger/src/actions/ast/setInScopeLines.js new file mode 100644 index 0000000000..a17510a507 --- /dev/null +++ b/devtools/client/debugger/src/actions/ast/setInScopeLines.js @@ -0,0 +1,94 @@ +/* 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 { + hasInScopeLines, + getSourceTextContent, + getVisibleSelectedFrame, +} from "../../selectors"; + +import { getSourceLineCount } from "../../utils/source"; + +import { isFulfilled } from "../../utils/async-value"; + +function getOutOfScopeLines(outOfScopeLocations) { + if (!outOfScopeLocations) { + return null; + } + + const uniqueLines = new Set(); + for (const location of outOfScopeLocations) { + for (let i = location.start.line; i < location.end.line; i++) { + uniqueLines.add(i); + } + } + + return uniqueLines; +} + +async function getInScopeLines( + cx, + location, + { dispatch, getState, parserWorker } +) { + const sourceTextContent = getSourceTextContent(getState(), location); + + let locations = null; + if (location.line && parserWorker.isLocationSupported(location)) { + locations = await parserWorker.findOutOfScopeLocations(location); + } + + const linesOutOfScope = getOutOfScopeLines(locations); + const sourceNumLines = + !sourceTextContent || !isFulfilled(sourceTextContent) + ? 0 + : getSourceLineCount(sourceTextContent.value); + + const noLinesOutOfScope = + linesOutOfScope == null || linesOutOfScope.size == 0; + + // This operation can be very costly for large files so we sacrifice a bit of readability + // for performance sake. + // We initialize an array with a fixed size and we'll directly assign value for lines + // that are not out of scope. This is much faster than having an empty array and pushing + // into it. + const sourceLines = new Array(sourceNumLines); + for (let i = 0; i < sourceNumLines; i++) { + const line = i + 1; + if (noLinesOutOfScope || !linesOutOfScope.has(line)) { + sourceLines[i] = line; + } + } + + // Finally we need to remove any undefined values, i.e. the ones that were matching + // out of scope lines. + return sourceLines.filter(i => i != undefined); +} + +export function setInScopeLines(cx) { + return async thunkArgs => { + const { getState, dispatch } = thunkArgs; + const visibleFrame = getVisibleSelectedFrame(getState()); + + if (!visibleFrame) { + return; + } + + const { location } = visibleFrame; + const sourceTextContent = getSourceTextContent(getState(), location); + + if (hasInScopeLines(getState(), location) || !sourceTextContent) { + return; + } + + const lines = await getInScopeLines(cx, location, thunkArgs); + + dispatch({ + type: "IN_SCOPE_LINES", + cx, + location, + lines, + }); + }; +} diff --git a/devtools/client/debugger/src/actions/ast/tests/__snapshots__/setInScopeLines.spec.js.snap b/devtools/client/debugger/src/actions/ast/tests/__snapshots__/setInScopeLines.spec.js.snap new file mode 100644 index 0000000000..1b9befc31b --- /dev/null +++ b/devtools/client/debugger/src/actions/ast/tests/__snapshots__/setInScopeLines.spec.js.snap @@ -0,0 +1,16 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`getInScopeLine with selected line 1`] = ` +Array [ + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 10, + 11, + 12, +] +`; diff --git a/devtools/client/debugger/src/actions/ast/tests/setInScopeLines.spec.js b/devtools/client/debugger/src/actions/ast/tests/setInScopeLines.spec.js new file mode 100644 index 0000000000..571dd84d6d --- /dev/null +++ b/devtools/client/debugger/src/actions/ast/tests/setInScopeLines.spec.js @@ -0,0 +1,79 @@ +/* eslint max-nested-callbacks: ["error", 6] */ +/* 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 readFixture from "../../tests/helpers/readFixture"; + +import { makeMockFrame, makeMockSource } from "../../../utils/test-mockup"; +import { + createStore, + selectors, + actions, + makeSource, + waitForState, +} from "../../../utils/test-head"; +import { createLocation } from "../../../utils/location"; + +const { getInScopeLines } = selectors; + +const sourceTexts = { + "scopes.js": readFixture("scopes.js"), +}; + +const mockCommandClient = { + sourceContents: async ({ source }) => ({ + source: sourceTexts[source], + contentType: "text/javascript", + }), + evaluateExpressions: async () => {}, + getFrameScopes: async () => {}, + getFrames: async () => [], + getSourceActorBreakpointPositions: async () => ({}), + getSourceActorBreakableLines: async () => [], +}; + +describe("getInScopeLine", () => { + it("with selected line", async () => { + const client = { ...mockCommandClient }; + const store = createStore(client); + const { dispatch, getState } = store; + const source = makeMockSource("scopes.js", "scopes.js"); + const frame = makeMockFrame("scopes-4", source); + client.getFrames = async () => [frame]; + + const baseSource = await dispatch( + actions.newGeneratedSource(makeSource("scopes.js")) + ); + const sourceActor = selectors.getFirstSourceActorForGeneratedSource( + getState(), + baseSource.id + ); + + await dispatch( + actions.selectLocation( + selectors.getContext(getState()), + createLocation({ + source: baseSource, + sourceActor, + line: 5, + }) + ) + ); + + await dispatch( + actions.paused({ + thread: "FakeThread", + why: { type: "debuggerStatement" }, + frame, + }) + ); + await dispatch(actions.setInScopeLines(selectors.getContext(getState()))); + + await waitForState(store, state => getInScopeLines(state, frame.location)); + + const lines = getInScopeLines(getState(), frame.location); + + expect(lines).toMatchSnapshot(); + }); +}); |