diff --git a/devtools/client/debugger/panel.js b/devtools/client/debugger/panel.js index 169e3986be35..bce45f5e74fa 100644 --- a/devtools/client/debugger/panel.js +++ b/devtools/client/debugger/panel.js @@ -233,12 +233,7 @@ class DebuggerPanel { // select worker's source const source = this.getSourceByURL(workerDescriptorFront._url); - const sourceActor = this._selectors.getFirstSourceActorForGeneratedSource( - this._getState(), - source.id, - threadActorID - ); - await this.selectSource(source.id, sourceActor.actor, 1, 1); + await this.selectSource(source.id, 1, 1); } selectThread(threadActorID) { @@ -246,11 +241,11 @@ class DebuggerPanel { this._actions.selectThread(cx, threadActorID); } - async selectSource(sourceId, sourceActorId, line, column) { + async selectSource(sourceId, line, column) { const cx = this._selectors.getContext(this._getState()); const location = { sourceId, line, column }; - await this._actions.selectSource(cx, sourceId, sourceActorId, location); + await this._actions.selectSource(cx, sourceId, location); if (this._selectors.hasLogpoint(this._getState(), location)) { this._actions.openConditionalPanel(location, true); } diff --git a/devtools/client/debugger/src/actions/breakpoints/tests/breakpointPositions.spec.js b/devtools/client/debugger/src/actions/breakpoints/tests/breakpointPositions.spec.js new file mode 100644 index 000000000000..b8fa60b59925 --- /dev/null +++ b/devtools/client/debugger/src/actions/breakpoints/tests/breakpointPositions.spec.js @@ -0,0 +1,110 @@ +/* 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 . */ + +import { + actions, + selectors, + createStore, + makeSource, + waitForState, +} from "../../../utils/test-head"; +import { createSource } from "../../tests/helpers/mockCommandClient"; + +describe("breakpointPositions", () => { + it("fetches positions", async () => { + const fooContent = createSource("foo", ""); + + const store = createStore({ + getSourceActorBreakpointPositions: async () => ({ "9": [1] }), + getSourceActorBreakableLines: async () => [], + sourceContents: async () => fooContent, + }); + + const { dispatch, getState, cx } = store; + const source = await dispatch( + actions.newGeneratedSource(makeSource("foo")) + ); + await dispatch(actions.loadSourceById(cx, source.id)); + + dispatch(actions.setBreakpointPositions({ cx, sourceId: "foo", line: 9 })); + + await waitForState(store, state => + selectors.hasBreakpointPositions(state, "foo") + ); + + expect( + selectors.getBreakpointPositionsForSource(getState(), "foo") + ).toEqual({ + [9]: [ + { + location: { + line: 9, + column: 1, + sourceId: "foo", + sourceUrl: "http://localhost:8000/examples/foo", + }, + generatedLocation: { + line: 9, + column: 1, + sourceId: "foo", + sourceUrl: "http://localhost:8000/examples/foo", + }, + }, + ], + }); + }); + + it("doesn't re-fetch positions", async () => { + const fooContent = createSource("foo", ""); + + let resolve = _ => {}; + let count = 0; + const store = createStore({ + getSourceActorBreakpointPositions: () => + new Promise(r => { + count++; + resolve = r; + }), + getSourceActorBreakableLines: async () => [], + sourceContents: async () => fooContent, + }); + + const { dispatch, getState, cx } = store; + const source = await dispatch( + actions.newGeneratedSource(makeSource("foo")) + ); + await dispatch(actions.loadSourceById(cx, source.id)); + + dispatch(actions.setBreakpointPositions({ cx, sourceId: "foo", line: 9 })); + dispatch(actions.setBreakpointPositions({ cx, sourceId: "foo", line: 9 })); + + resolve({ "9": [1] }); + await waitForState(store, state => + selectors.hasBreakpointPositions(state, "foo") + ); + + expect( + selectors.getBreakpointPositionsForSource(getState(), "foo") + ).toEqual({ + [9]: [ + { + location: { + line: 9, + column: 1, + sourceId: "foo", + sourceUrl: "http://localhost:8000/examples/foo", + }, + generatedLocation: { + line: 9, + column: 1, + sourceId: "foo", + sourceUrl: "http://localhost:8000/examples/foo", + }, + }, + ], + }); + + expect(count).toEqual(1); + }); +}); diff --git a/devtools/client/debugger/src/actions/breakpoints/tests/breakpoints.spec.js b/devtools/client/debugger/src/actions/breakpoints/tests/breakpoints.spec.js index 6963ee83e5d8..cb5cdcaa5a0a 100644 --- a/devtools/client/debugger/src/actions/breakpoints/tests/breakpoints.spec.js +++ b/devtools/client/debugger/src/actions/breakpoints/tests/breakpoints.spec.js @@ -50,8 +50,9 @@ describe("breakpoints", () => { }; const source = await dispatch(actions.newGeneratedSource(makeSource("a"))); + await dispatch(actions.loadSourceText({ cx, source })); await dispatch( - actions.selectLocation(cx, { + actions.setSelectedLocation(cx, source, { line: 1, column: 1, sourceId: source.id, @@ -78,8 +79,9 @@ describe("breakpoints", () => { sourceUrl: "http://localhost:8000/examples/a", }; const source = await dispatch(actions.newGeneratedSource(makeSource("a"))); + await dispatch(actions.loadSourceText({ cx, source })); await dispatch( - actions.selectLocation(cx, { + actions.setSelectedLocation(cx, source, { line: 1, column: 1, sourceId: source.id, @@ -103,8 +105,9 @@ describe("breakpoints", () => { sourceUrl: "http://localhost:8000/examples/a", }; const source = await dispatch(actions.newGeneratedSource(makeSource("a"))); + await dispatch(actions.loadSourceText({ cx, source })); await dispatch( - actions.selectLocation(cx, { + actions.setSelectedLocation(cx, source, { line: 1, column: 1, sourceId: source.id, @@ -135,8 +138,9 @@ describe("breakpoints", () => { }; const source = await dispatch(actions.newGeneratedSource(makeSource("a"))); + await dispatch(actions.loadSourceText({ cx, source })); await dispatch( - actions.selectLocation(cx, { + actions.setSelectedLocation(cx, source, { line: 1, column: 1, sourceId: source.id, @@ -172,19 +176,13 @@ describe("breakpoints", () => { }; const aSource = await dispatch(actions.newGeneratedSource(makeSource("a"))); + await dispatch(actions.loadSourceText({ cx, source: aSource })); const bSource = await dispatch(actions.newGeneratedSource(makeSource("b"))); - const bSourceActor = selectors.getFirstSourceActorForGeneratedSource( - getState(), - bSource.id - ); + await dispatch(actions.loadSourceText({ cx, source: bSource })); await dispatch( - actions.loadSourceText({ cx, source: bSource, sourceActor: bSourceActor }) - ); - - await dispatch( - actions.selectLocation(cx, { + actions.setSelectedLocation(cx, aSource, { line: 1, column: 1, sourceId: aSource.id, @@ -223,22 +221,10 @@ describe("breakpoints", () => { }; const aSource = await dispatch(actions.newGeneratedSource(makeSource("a"))); - const aSourceActor = selectors.getFirstSourceActorForGeneratedSource( - getState(), - aSource.id - ); - await dispatch( - actions.loadSourceText({ cx, source: aSource, sourceActor: aSourceActor }) - ); + await dispatch(actions.loadSourceText({ cx, source: aSource })); const bSource = await dispatch(actions.newGeneratedSource(makeSource("b"))); - const bSourceActor = selectors.getFirstSourceActorForGeneratedSource( - getState(), - bSource.id - ); - await dispatch( - actions.loadSourceText({ cx, source: bSource, sourceActor: bSourceActor }) - ); + await dispatch(actions.loadSourceText({ cx, source: bSource })); await dispatch(actions.addBreakpoint(cx, loc1)); await dispatch(actions.addBreakpoint(cx, loc2)); @@ -266,13 +252,7 @@ describe("breakpoints", () => { }; const aSource = await dispatch(actions.newGeneratedSource(makeSource("a"))); - const aSourceActor = selectors.getFirstSourceActorForGeneratedSource( - getState(), - aSource.id - ); - await dispatch( - actions.loadSourceText({ cx, source: aSource, sourceActor: aSourceActor }) - ); + await dispatch(actions.loadSourceText({ cx, source: aSource })); await dispatch(actions.addBreakpoint(cx, loc)); let bp = selectors.getBreakpoint(getState(), loc); @@ -315,22 +295,10 @@ describe("breakpoints", () => { }; const aSource = await dispatch(actions.newGeneratedSource(makeSource("a"))); - const aSourceActor = selectors.getFirstSourceActorForGeneratedSource( - getState(), - aSource.id - ); - await dispatch( - actions.loadSourceText({ cx, source: aSource, sourceActor: aSourceActor }) - ); + await dispatch(actions.loadSourceText({ cx, source: aSource })); const bSource = await dispatch(actions.newGeneratedSource(makeSource("b"))); - const bSourceActor = selectors.getFirstSourceActorForGeneratedSource( - getState(), - bSource.id - ); - await dispatch( - actions.loadSourceText({ cx, source: bSource, sourceActor: bSourceActor }) - ); + await dispatch(actions.loadSourceText({ cx, source: bSource })); await dispatch(actions.addBreakpoint(cx, loc1)); await dispatch(actions.addBreakpoint(cx, loc2)); @@ -398,22 +366,10 @@ describe("breakpoints", () => { }; const aSource = await dispatch(actions.newGeneratedSource(makeSource("a"))); - const aSourceActor = selectors.getFirstSourceActorForGeneratedSource( - getState(), - aSource.id - ); - await dispatch( - actions.loadSourceText({ cx, source: aSource, sourceActor: aSourceActor }) - ); + await dispatch(actions.loadSourceText({ cx, source: aSource })); const bSource = await dispatch(actions.newGeneratedSource(makeSource("b"))); - const bSourceActor = selectors.getFirstSourceActorForGeneratedSource( - getState(), - bSource.id - ); - await dispatch( - actions.loadSourceText({ cx, source: bSource, sourceActor: bSourceActor }) - ); + await dispatch(actions.loadSourceText({ cx, source: bSource })); expect(selectors.getBreakpointsList(getState())).toHaveLength(0); expect(selectors.getPendingBreakpointList(getState())).toHaveLength(1); @@ -441,7 +397,11 @@ describe("breakpoints", () => { const { dispatch, getState, cx } = createStore(mockClient({ "5": [1] })); - await dispatch(actions.newGeneratedSource(makeSource("foo1"))); + const source = await dispatch( + actions.newGeneratedSource(makeSource("foo1")) + ); + await dispatch(actions.loadSourceText({ cx, source })); + await dispatch(actions.selectLocation(cx, loc)); await dispatch(actions.toggleBreakpointAtLine(cx, 5)); @@ -458,7 +418,11 @@ describe("breakpoints", () => { const { dispatch, getState, cx } = createStore(mockClient({ "5": [1] })); - await dispatch(actions.newGeneratedSource(makeSource("foo1"))); + const source = await dispatch( + actions.newGeneratedSource(makeSource("foo1")) + ); + await dispatch(actions.loadSourceText({ cx, source })); + await dispatch(actions.selectLocation(cx, { sourceId: "foo1", line: 1 })); await dispatch(actions.toggleBreakpointAtLine(cx, 5)); @@ -484,11 +448,7 @@ describe("breakpoints", () => { }; const source = await dispatch(actions.newGeneratedSource(makeSource("a"))); - const sourceActor = selectors.getFirstSourceActorForGeneratedSource( - getState(), - source.id - ); - await dispatch(actions.loadSourceText({ cx, source, sourceActor })); + await dispatch(actions.loadSourceText({ cx, source })); await dispatch(actions.addBreakpoint(cx, loc)); @@ -517,11 +477,7 @@ describe("breakpoints", () => { }; const source = await dispatch(actions.newGeneratedSource(makeSource("a"))); - const sourceActor = selectors.getFirstSourceActorForGeneratedSource( - getState(), - source.id - ); - await dispatch(actions.loadSourceText({ cx, source, sourceActor })); + await dispatch(actions.loadSourceText({ cx, source })); await dispatch(actions.addBreakpoint(cx, loc)); let bp = selectors.getBreakpoint(getState(), loc); @@ -560,11 +516,7 @@ describe("breakpoints", () => { const source = await dispatch( actions.newGeneratedSource(makeSource("a.js")) ); - const sourceActor = selectors.getFirstSourceActorForGeneratedSource( - getState(), - source.id - ); - await dispatch(actions.loadSourceText({ cx, source, sourceActor })); + await dispatch(actions.loadSourceText({ cx, source })); await dispatch(actions.addBreakpoint(cx, loc)); await dispatch(actions.togglePrettyPrint(cx, "a.js")); @@ -591,11 +543,7 @@ describe("breakpoints", () => { const source = await dispatch( actions.newGeneratedSource(makeSource("a.js")) ); - const sourceActor = selectors.getFirstSourceActorForGeneratedSource( - getState(), - source.id - ); - await dispatch(actions.loadSourceText({ cx, source, sourceActor })); + await dispatch(actions.loadSourceText({ cx, source })); await dispatch(actions.addBreakpoint(cx, loc)); await dispatch(actions.togglePrettyPrint(cx, "a.js")); diff --git a/devtools/client/debugger/src/actions/pause/mapScopes.js b/devtools/client/debugger/src/actions/pause/mapScopes.js index 11655f1db1ba..bb4bc31bba35 100644 --- a/devtools/client/debugger/src/actions/pause/mapScopes.js +++ b/devtools/client/debugger/src/actions/pause/mapScopes.js @@ -12,7 +12,6 @@ import { getSelectedGeneratedScope, getSelectedOriginalScope, getThreadContext, - getFirstSourceActorForGeneratedSource, } from "../../selectors"; import { loadSourceText } from "../sources/loadSourceText"; import { PROMISE } from "../utils/middleware/promise"; @@ -150,22 +149,10 @@ export function getMappedScopes(cx, scopes, frame) { return null; } - // Load source text for the original source - await dispatch(loadSourceText({ cx, source, sourceActor: null })); - - const generatedSourceActor = getFirstSourceActorForGeneratedSource( - getState(), - generatedSource.id - ); - - // Also load source text for its corresponding generated source - await dispatch( - loadSourceText({ - cx, - source: generatedSource, - sourceActor: generatedSourceActor, - }) - ); + await dispatch(loadSourceText({ cx, source })); + if (source.isOriginal) { + await dispatch(loadSourceText({ cx, source: generatedSource })); + } try { const content = diff --git a/devtools/client/debugger/src/actions/pause/tests/pause.spec.js b/devtools/client/debugger/src/actions/pause/tests/pause.spec.js index 202c354445ce..c9b0115faf7b 100644 --- a/devtools/client/debugger/src/actions/pause/tests/pause.spec.js +++ b/devtools/client/debugger/src/actions/pause/tests/pause.spec.js @@ -168,12 +168,7 @@ describe("pause", () => { { generatedLocation: { column: 0, line: 1, sourceId: "foo" }, id: mockFrameId, - location: { - column: 0, - line: 1, - sourceId: "foo", - sourceActorId: "foo-1-actor", - }, + location: { column: 0, line: 1, sourceId: "foo" }, originalDisplayName: "foo", scope: { bindings: { @@ -245,12 +240,7 @@ describe("pause", () => { { generatedLocation: { column: 0, line: 1, sourceId: "foo" }, id: mockFrameId, - location: { - column: 0, - line: 3, - sourceActorId: "foo-original-1-actor", - sourceId: "foo-original", - }, + location: { column: 0, line: 3, sourceId: "foo-original" }, originalDisplayName: "fooOriginal", scope: { bindings: { arguments: [], variables: {} } }, thread: "FakeThread", @@ -322,12 +312,7 @@ describe("pause", () => { id: "1", index: undefined, isOriginal: true, - location: { - column: 1, - line: 1, - sourceActorId: null, - sourceId: "foo-wasm/originalSource", - }, + location: { column: 1, line: 1, sourceId: "foo-wasm/originalSource" }, originalDisplayName: "fooBar", originalVariables: undefined, scope: { bindings: { arguments: [], variables: {} } }, diff --git a/devtools/client/debugger/src/actions/project-text-search.js b/devtools/client/debugger/src/actions/project-text-search.js index 9bf83113c9f1..4b895d7c6c74 100644 --- a/devtools/client/debugger/src/actions/project-text-search.js +++ b/devtools/client/debugger/src/actions/project-text-search.js @@ -11,7 +11,6 @@ import { isFulfilled } from "../utils/async-value"; import { findSourceMatches } from "../workers/search"; import { getSource, - getFirstSourceActorForGeneratedSource, hasPrettySource, getSourceList, getSourceContent, @@ -93,12 +92,7 @@ export function searchSources(cx, query) { if (cancelled) { return; } - - const sourceActor = getFirstSourceActorForGeneratedSource( - getState(), - source.id - ); - await dispatch(loadSourceText({ cx, source, sourceActor })); + await dispatch(loadSourceText({ cx, source })); await dispatch(searchSource(cx, source.id, query)); } dispatch(updateSearchStatus(cx, statusType.done)); diff --git a/devtools/client/debugger/src/actions/sources/loadSourceText.js b/devtools/client/debugger/src/actions/sources/loadSourceText.js index 593a0ca1cd0c..b072620cc95f 100644 --- a/devtools/client/debugger/src/actions/sources/loadSourceText.js +++ b/devtools/client/debugger/src/actions/sources/loadSourceText.js @@ -5,6 +5,7 @@ import { PROMISE } from "../utils/middleware/promise"; import { getSource, + getSourceFromId, getSourceTextContent, getSourceContent, getGeneratedSource, @@ -62,19 +63,27 @@ async function loadSource( return result; } - // If no source actor can be found then the text for the - // source cannot be loaded. - if (!sourceActor) { - throw new Error("Unknown source"); - } - let response; - try { - telemetry.start(loadSourceHistogram, source); - response = await client.sourceContents(sourceActor); - telemetry.finish(loadSourceHistogram, source); - } catch (e) { - throw new Error(`sourceContents failed: ${e}`); + if (!sourceActor) { + // We only need the source text from one actor, but messages sent to retrieve + // the source might fail if the actor has or is about to shut down. Keep + // trying with different actors until one request succeeds. + const handledActors = new Set(); + while (true) { + const actors = getSourceActorsForSource(state, source.id); + sourceActor = actors.find(({ actor: a }) => !handledActors.has(a)); + if (!sourceActor) { + throw new Error("Unknown source"); + } + handledActors.add(sourceActor.actor); + + response = await fetchTextContent(client, source, sourceActor); + if (response) { + break; + } + } + } else { + response = await fetchTextContent(client, source, sourceActor); } return { @@ -84,6 +93,18 @@ async function loadSource( }; } +async function fetchTextContent(client, source, sourceActor) { + let response; + try { + telemetry.start(loadSourceHistogram, source); + response = await client.sourceContents(sourceActor); + telemetry.finish(loadSourceHistogram, source); + } catch (e) { + console.warn(`sourceContents failed: ${e}`); + } + return response; +} + async function loadSourceTextPromise( cx, source, @@ -126,16 +147,13 @@ async function loadSourceTextPromise( } } -/** - * Loads the source text for a source and source actor - * @param {Object} source - * The source to load the source text - * @param {Object|null} sourceActor - * There can be more than one source actor per source - * so the source actor needs to be specified. This is - * required for generated sources but will be null for - * original/pretty printed sources. - */ +export function loadSourceById(cx, sourceId) { + return ({ getState, dispatch }) => { + const source = getSourceFromId(getState(), sourceId); + return dispatch(loadSourceText({ cx, source })); + }; +} + export const loadSourceText = memoizeableAction("loadSourceText", { getValue: ({ source, sourceActor }, { getState }) => { if (!source) { @@ -147,7 +165,7 @@ export const loadSourceText = memoizeableAction("loadSourceText", { return sourceTextContent; } - // if a source actor is specified,lets also check that the source actor for the + // if a source actor is specified,lets check the source actor for the // currently loaded text. if (sourceActor && sourceTextContent && isFulfilled(sourceTextContent)) { if ( diff --git a/devtools/client/debugger/src/actions/sources/newSources.js b/devtools/client/debugger/src/actions/sources/newSources.js index b105a4106561..c78ea4ae4a8e 100644 --- a/devtools/client/debugger/src/actions/sources/newSources.js +++ b/devtools/client/debugger/src/actions/sources/newSources.js @@ -35,7 +35,6 @@ import { getPendingBreakpointsForSource, getContext, getSourceTextContent, - getFirstSourceActorForGeneratedSource, } from "../../selectors"; import { prefs } from "../../utils/prefs"; @@ -173,11 +172,7 @@ function checkPendingBreakpoints(cx, sourceId) { } // load the source text if there is a pending breakpoint for it - const sourceActor = getFirstSourceActorForGeneratedSource( - getState(), - source.id - ); - await dispatch(loadSourceText({ cx, source, sourceActor })); + await dispatch(loadSourceText({ cx, source })); await dispatch(setBreakableLines(cx, source.id)); diff --git a/devtools/client/debugger/src/actions/sources/prettyPrint.js b/devtools/client/debugger/src/actions/sources/prettyPrint.js index aa0b7f484d89..164540801c09 100644 --- a/devtools/client/debugger/src/actions/sources/prettyPrint.js +++ b/devtools/client/debugger/src/actions/sources/prettyPrint.js @@ -22,7 +22,6 @@ import { createPrettyPrintOriginalSource } from "../../client/firefox/create"; import { getSource, - getFirstSourceActorForGeneratedSource, getSourceFromId, getSourceByURL, getSelectedLocation, @@ -122,11 +121,8 @@ export function togglePrettyPrint(cx, sourceId) { if (!source.isPrettyPrinted) { recordEvent("pretty_print"); } - const sourceActor = getFirstSourceActorForGeneratedSource( - getState(), - source.id - ); - await dispatch(loadSourceText({ cx, source, sourceActor })); + + await dispatch(loadSourceText({ cx, source })); assert( isGenerated(source), "Pretty-printing only allowed on generated sources" @@ -146,7 +142,7 @@ export function togglePrettyPrint(cx, sourceId) { const threadcx = getThreadContext(getState()); await dispatch(mapFrames(threadcx)); - await dispatch(setSymbols({ cx, source: newPrettySource, sourceActor })); + await dispatch(setSymbols({ cx, source: newPrettySource })); await dispatch(updateBreakpointsForNewPrettyPrintedSource(cx, sourceId)); diff --git a/devtools/client/debugger/src/actions/sources/select.js b/devtools/client/debugger/src/actions/sources/select.js index c5102c1686ce..943c743d7232 100644 --- a/devtools/client/debugger/src/actions/sources/select.js +++ b/devtools/client/debugger/src/actions/sources/select.js @@ -25,8 +25,6 @@ import { getRelatedMapLocation } from "../../utils/source-maps"; import { getSource, - getSourceActor, - getFirstSourceActorForGeneratedSource, getSourceByURL, getPrettySource, getActiveSearch, @@ -77,7 +75,8 @@ export function selectSourceURL(cx, url, options) { return dispatch(setPendingSelectedLocation(cx, url, options)); } - const location = createLocation({ ...options, sourceId: source.id }); + const sourceId = source.id; + const location = createLocation({ ...options, sourceId }); return dispatch(selectLocation(cx, location)); }; } @@ -90,16 +89,13 @@ export function selectSourceURL(cx, url, options) { * @param {Object} cx * @param {String} sourceId * The precise source to select. - * @param {String} sourceActorId - * The specific source actor of the source to - * select the source text. This is optional. * @param {Object} location * Optional precise location to select, if we need to select * a precise line/column. */ -export function selectSource(cx, sourceId, sourceActorId, location = {}) { +export function selectSource(cx, sourceId, location = {}) { return async ({ dispatch }) => { - location = createLocation({ ...location, sourceId, sourceActorId }); + location = createLocation({ ...location, sourceId }); return dispatch(selectSpecificLocation(cx, location)); }; } @@ -168,19 +164,9 @@ export function selectLocation(cx, location, { keepContext = true } = {}) { dispatch(addTab(source)); } - let sourceActor; - if (!location.sourceActorId) { - sourceActor = getFirstSourceActorForGeneratedSource( - getState(), - source.id - ); - location.sourceActorId = sourceActor ? sourceActor.actor : null; - } else { - sourceActor = getSourceActor(getState(), location.sourceActorId); - } - dispatch(setSelectedLocation(cx, source, location)); - await dispatch(loadSourceText({ cx, source, sourceActor })); + + await dispatch(loadSourceText({ cx, source })); await dispatch(setBreakableLines(cx, source.id)); const loadedSource = getSource(getState(), source.id); @@ -203,7 +189,7 @@ export function selectLocation(cx, location, { keepContext = true } = {}) { dispatch(closeTab(cx, loadedSource)); } - await dispatch(setSymbols({ cx, source: loadedSource, sourceActor })); + await dispatch(setSymbols({ cx, source: loadedSource })); dispatch(setInScopeLines(cx)); if (getIsCurrentThreadPaused(getState())) { diff --git a/devtools/client/debugger/src/actions/sources/symbols.js b/devtools/client/debugger/src/actions/sources/symbols.js index 1c05d7d85326..057399f54db6 100644 --- a/devtools/client/debugger/src/actions/sources/symbols.js +++ b/devtools/client/debugger/src/actions/sources/symbols.js @@ -2,7 +2,7 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at . */ -import { getSymbols, getSourceActorForSymbols } from "../../selectors"; +import { getSymbols } from "../../selectors"; import { PROMISE } from "../utils/middleware/promise"; import { loadSourceText } from "./loadSourceText"; @@ -10,27 +10,21 @@ import { loadSourceText } from "./loadSourceText"; import { memoizeableAction } from "../../utils/memoizableAction"; import { fulfilled } from "../../utils/async-value"; -async function doSetSymbols( - cx, - source, - sourceActor, - { dispatch, getState, parser } -) { +async function doSetSymbols(cx, source, { dispatch, getState, parser }) { const sourceId = source.id; - await dispatch(loadSourceText({ cx, source, sourceActor })); + await dispatch(loadSourceText({ cx, source })); + await dispatch({ type: "SET_SYMBOLS", cx, sourceId, - // sourceActor can be null for original and pretty-printed sources - sourceActorId: sourceActor ? sourceActor.actor : null, [PROMISE]: parser.getSymbols(sourceId), }); } export const setSymbols = memoizeableAction("setSymbols", { - getValue: ({ source, sourceActor }, { getState }) => { + getValue: ({ source }, { getState }) => { if (source.isWasm) { return fulfilled(null); } @@ -40,17 +34,8 @@ export const setSymbols = memoizeableAction("setSymbols", { return null; } - // Also check the spcific actor for the cached symbols - if ( - sourceActor && - getSourceActorForSymbols(getState(), source) !== sourceActor.actor - ) { - return null; - } - return fulfilled(symbols); }, createKey: ({ source }) => source.id, - action: ({ cx, source, sourceActor }, thunkArgs) => - doSetSymbols(cx, source, sourceActor, thunkArgs), + action: ({ cx, source }, thunkArgs) => doSetSymbols(cx, source, thunkArgs), }); diff --git a/devtools/client/debugger/src/actions/sources/tests/loadSource.spec.js b/devtools/client/debugger/src/actions/sources/tests/loadSource.spec.js index 02bb13749dcf..40be39e7fc19 100644 --- a/devtools/client/debugger/src/actions/sources/tests/loadSource.spec.js +++ b/devtools/client/debugger/src/actions/sources/tests/loadSource.spec.js @@ -25,17 +25,7 @@ describe("loadSourceText", () => { const foo1Source = await dispatch( actions.newGeneratedSource(makeSource("foo1")) ); - const foo1SourceActor = selectors.getFirstSourceActorForGeneratedSource( - getState(), - foo1Source.id - ); - await dispatch( - actions.loadSourceText({ - cx, - source: foo1Source, - sourceActor: foo1SourceActor, - }) - ); + await dispatch(actions.loadSourceText({ cx, source: foo1Source })); const foo1Content = selectors.getSourceContent(getState(), foo1Source.id); expect( @@ -49,18 +39,7 @@ describe("loadSourceText", () => { const foo2Source = await dispatch( actions.newGeneratedSource(makeSource("foo2")) ); - const foo2SourceActor = selectors.getFirstSourceActorForGeneratedSource( - getState(), - foo2Source.id - ); - - await dispatch( - actions.loadSourceText({ - cx, - source: foo2Source, - sourceActor: foo2SourceActor, - }) - ); + await dispatch(actions.loadSourceText({ cx, source: foo2Source })); const foo2Content = selectors.getSourceContent(getState(), foo2Source.id); expect( @@ -117,6 +96,30 @@ describe("loadSourceText", () => { : -1 ).not.toBe(-1); + // Load the source text which has been cached when the source + // actor is not specified. + await dispatch( + actions.loadSourceText({ + cx, + source: testSource1, + }) + ); + + const testSource1ContentAfterSecondLoad = selectors.getSourceContent( + getState(), + testSource1.id + ); + + expect( + testSource1ContentAfterSecondLoad && + isFulfilled(testSource1ContentAfterSecondLoad) && + testSource1ContentAfterSecondLoad.value.type === "text" + ? testSource1ContentAfterSecondLoad.value.value.indexOf( + mockContents["testSource2-0-actor"] + ) + : -1 + ).not.toBe(-1); + // Load the new source text when a different source actor is specified await dispatch( actions.loadSourceText({ @@ -187,18 +190,7 @@ describe("loadSourceText", () => { actions.newOriginalSource(makeOriginalSource(fooGenSource2)) ); - const fooOrigSource1SourceActor = selectors.getFirstSourceActorForGeneratedSource( - getState(), - fooOrigSource1.id - ); - - await dispatch( - actions.loadSourceText({ - cx, - source: fooOrigSource1, - sourceActor: fooOrigSource1SourceActor, - }) - ); + await dispatch(actions.loadSourceText({ cx, source: fooOrigSource1 })); await dispatch( actions.addBreakpoint( @@ -216,35 +208,13 @@ describe("loadSourceText", () => { expect(breakpoint1.text).toBe(""); expect(breakpoint1.originalText).toBe("var fooOrig = 42;"); - const fooGenSource1SourceActor = selectors.getFirstSourceActorForGeneratedSource( - getState(), - fooGenSource1.id - ); - - await dispatch( - actions.loadSourceText({ - cx, - source: fooGenSource1, - sourceActor: fooGenSource1SourceActor, - }) - ); + await dispatch(actions.loadSourceText({ cx, source: fooGenSource1 })); const breakpoint2 = getBreakpointsList(getState())[0]; expect(breakpoint2.text).toBe("var fooGen = 42;"); expect(breakpoint2.originalText).toBe("var fooOrig = 42;"); - const fooGenSource2SourceActor = selectors.getFirstSourceActorForGeneratedSource( - getState(), - fooGenSource2.id - ); - - await dispatch( - actions.loadSourceText({ - cx, - source: fooGenSource2, - sourceActor: fooGenSource2SourceActor, - }) - ); + await dispatch(actions.loadSourceText({ cx, source: fooGenSource2 })); await dispatch( actions.addBreakpoint( @@ -262,18 +232,7 @@ describe("loadSourceText", () => { expect(breakpoint3.text).toBe("var fooGen = 42;"); expect(breakpoint3.originalText).toBe(""); - const fooOrigSource2SourceActor = selectors.getFirstSourceActorForGeneratedSource( - getState(), - fooOrigSource2.id - ); - - await dispatch( - actions.loadSourceText({ - cx, - source: fooOrigSource2, - sourceActor: fooOrigSource2SourceActor, - }) - ); + await dispatch(actions.loadSourceText({ cx, source: fooOrigSource2 })); const breakpoint4 = getBreakpointsList(getState())[1]; expect(breakpoint4.text).toBe("var fooGen = 42;"); @@ -297,21 +256,10 @@ describe("loadSourceText", () => { await dispatch(actions.newGeneratedSource(makeSource(id))); let source = selectors.getSourceFromId(getState(), id); - let sourceActor = selectors.getFirstSourceActorForGeneratedSource( - getState(), - source.id - ); - - dispatch(actions.loadSourceText({ cx, source, sourceActor })); + dispatch(actions.loadSourceText({ cx, source })); source = selectors.getSourceFromId(getState(), id); - sourceActor = selectors.getFirstSourceActorForGeneratedSource( - getState(), - source.id - ); - const loading = dispatch( - actions.loadSourceText({ cx, source, sourceActor }) - ); + const loading = dispatch(actions.loadSourceText({ cx, source })); if (!resolve) { throw new Error("no resolve"); @@ -345,13 +293,7 @@ describe("loadSourceText", () => { await dispatch(actions.newGeneratedSource(makeSource(id))); let source = selectors.getSourceFromId(getState(), id); - let sourceActor = selectors.getFirstSourceActorForGeneratedSource( - getState(), - source.id - ); - const loading = dispatch( - actions.loadSourceText({ cx, source, sourceActor }) - ); + const loading = dispatch(actions.loadSourceText({ cx, source })); if (!resolve) { throw new Error("no resolve"); @@ -360,11 +302,7 @@ describe("loadSourceText", () => { await loading; source = selectors.getSourceFromId(getState(), id); - sourceActor = selectors.getFirstSourceActorForGeneratedSource( - getState(), - source.id - ); - await dispatch(actions.loadSourceText({ cx, source, sourceActor })); + await dispatch(actions.loadSourceText({ cx, source })); expect(count).toEqual(1); const content = selectors.getSourceContent(getState(), id); @@ -382,24 +320,10 @@ describe("loadSourceText", () => { const source = await dispatch( actions.newGeneratedSource(makeSource("foo1")) ); - const sourceActor = selectors.getFirstSourceActorForGeneratedSource( - getState(), - source.id - ); - await dispatch(actions.loadSourceText({ cx, source, sourceActor })); - + await dispatch(actions.loadSourceText({ cx, source })); const prevSource = selectors.getSourceFromId(getState(), "foo1"); - const prevSourceSourceActor = selectors.getFirstSourceActorForGeneratedSource( - getState(), - prevSource.id - ); - await dispatch( - actions.loadSourceText({ - cx, - source: prevSource, - sourceActor: prevSourceSourceActor, - }) - ); + + await dispatch(actions.loadSourceText({ cx, source: prevSource })); const curSource = selectors.getSource(getState(), "foo1"); expect(prevSource === curSource).toBeTruthy(); @@ -407,7 +331,7 @@ describe("loadSourceText", () => { it("should indicate a loading source", async () => { const store = createStore(mockCommandClient); - const { dispatch, cx, getState } = store; + const { dispatch, cx } = store; const source = await dispatch( actions.newGeneratedSource(makeSource("foo2")) @@ -416,11 +340,8 @@ describe("loadSourceText", () => { const wasLoading = watchForState(store, state => { return !selectors.getSourceContent(state, "foo2"); }); - const sourceActor = selectors.getFirstSourceActorForGeneratedSource( - getState(), - source.id - ); - await dispatch(actions.loadSourceText({ cx, source, sourceActor })); + + await dispatch(actions.loadSourceText({ cx, source })); expect(wasLoading()).toBe(true); }); @@ -431,11 +352,7 @@ describe("loadSourceText", () => { const source = await dispatch( actions.newGeneratedSource(makeSource("bad-id")) ); - const sourceActor = selectors.getFirstSourceActorForGeneratedSource( - getState(), - source.id - ); - await dispatch(actions.loadSourceText({ cx, source, sourceActor })); + await dispatch(actions.loadSourceText({ cx, source })); const badSource = selectors.getSource(getState(), "bad-id"); const content = badSource @@ -443,7 +360,7 @@ describe("loadSourceText", () => { : null; expect( content && isRejected(content) && typeof content.value === "string" - ? content.value.indexOf("sourceContents failed") + ? content.value.indexOf("Unknown source") : -1 ).not.toBe(-1); }); diff --git a/devtools/client/debugger/src/actions/sources/tests/prettyPrint.spec.js b/devtools/client/debugger/src/actions/sources/tests/prettyPrint.spec.js index 067a16a2c3c4..d0748beaa798 100644 --- a/devtools/client/debugger/src/actions/sources/tests/prettyPrint.spec.js +++ b/devtools/client/debugger/src/actions/sources/tests/prettyPrint.spec.js @@ -18,11 +18,7 @@ describe("sources - pretty print", () => { const url = "base.js"; const source = await dispatch(actions.newGeneratedSource(makeSource(url))); - const sourceActor = selectors.getFirstSourceActorForGeneratedSource( - getState(), - source.id - ); - await dispatch(actions.loadSourceText({ cx, source, sourceActor })); + await dispatch(actions.loadSourceText({ cx, source })); await dispatch(createPrettySource(cx, source.id)); @@ -49,12 +45,7 @@ describe("sources - pretty print", () => { const source = await dispatch( actions.newGeneratedSource(makeSource("foobar.js")) ); - const sourceActor = selectors.getFirstSourceActorForGeneratedSource( - getState(), - source.id - ); - - await dispatch(actions.loadSourceText({ cx, source, sourceActor })); + await dispatch(actions.loadSourceText({ cx, source })); await dispatch(actions.togglePrettyPrint(cx, source.id)); expect(selectors.getSourceCount(getState())).toEqual(2); diff --git a/devtools/client/debugger/src/actions/tests/__snapshots__/preview.spec.js.snap b/devtools/client/debugger/src/actions/tests/__snapshots__/preview.spec.js.snap index 60ea7f20a5b1..026bfe4a8958 100644 --- a/devtools/client/debugger/src/actions/tests/__snapshots__/preview.spec.js.snap +++ b/devtools/client/debugger/src/actions/tests/__snapshots__/preview.spec.js.snap @@ -1,5 +1,3 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`preview queued previews (w/ the 1st finishing first) 1`] = `null`; - exports[`preview should generate previews 1`] = `null`; diff --git a/devtools/client/debugger/src/actions/tests/ast.spec.js b/devtools/client/debugger/src/actions/tests/ast.spec.js index c997b039925a..a05621fb20bf 100644 --- a/devtools/client/debugger/src/actions/tests/ast.spec.js +++ b/devtools/client/debugger/src/actions/tests/ast.spec.js @@ -48,28 +48,10 @@ describe("ast", () => { const base = await dispatch( actions.newGeneratedSource(makeSource("base.js")) ); - - const baseSourceActor = selectors.getFirstSourceActorForGeneratedSource( - getState(), - base.id - ); - - await dispatch( - actions.loadSourceText({ - cx, - source: base, - sourceActor: baseSourceActor, - }) - ); + await dispatch(actions.loadSourceText({ cx, source: base })); const loadedSource = selectors.getSourceFromId(getState(), base.id); - await dispatch( - actions.setSymbols({ - cx, - source: loadedSource, - sourceActor: baseSourceActor, - }) - ); + await dispatch(actions.setSymbols({ cx, source: loadedSource })); await waitForState(store, state => getSymbols(state, base)); const baseSymbols = getSymbols(getState(), base); diff --git a/devtools/client/debugger/src/actions/tests/project-text-search.spec.js b/devtools/client/debugger/src/actions/tests/project-text-search.spec.js index b9bf589de869..cedb69897ba4 100644 --- a/devtools/client/debugger/src/actions/tests/project-text-search.spec.js +++ b/devtools/client/debugger/src/actions/tests/project-text-search.spec.js @@ -81,14 +81,7 @@ describe("project text search", () => { const source1 = await dispatch( actions.newGeneratedSource(makeSource("bar")) ); - const sourceActor1 = selectors.getFirstSourceActorForGeneratedSource( - getState(), - source1.id - ); - - await dispatch( - actions.loadSourceText({ cx, source: source1, sourceActor: sourceActor1 }) - ); + await dispatch(actions.loadSourceText({ cx, source: source1 })); await dispatch(actions.togglePrettyPrint(cx, source1.id)); @@ -104,12 +97,7 @@ describe("project text search", () => { const source = await dispatch( actions.newGeneratedSource(makeSource("bar")) ); - const sourceActor = selectors.getFirstSourceActorForGeneratedSource( - getState(), - source.id - ); - - await dispatch(actions.loadSourceText({ cx, source, sourceActor })); + await dispatch(actions.loadSourceText({ cx, source })); dispatch(actions.addSearchQuery(cx, "bla")); diff --git a/devtools/client/debugger/src/client/firefox/create.js b/devtools/client/debugger/src/client/firefox/create.js index 7c30880621b9..6c5b8ccde8c2 100644 --- a/devtools/client/debugger/src/client/firefox/create.js +++ b/devtools/client/debugger/src/client/firefox/create.js @@ -244,7 +244,7 @@ function createSourceObject({ // True if WASM is enabled *and* the generated source is a WASM source isWasm, - // True if this source is an HTML and relates to many sources actors, + // True is this source is an HTML and relates to many sources actors, // one for each of its inline