зеркало из https://github.com/mozilla/gecko-dev.git
Merge mozilla-central to autoland. a=merge CLOSED TREE
This commit is contained in:
Коммит
dfaadda751
|
@ -1,112 +0,0 @@
|
|||
/* 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/>. */
|
||||
|
||||
// @flow
|
||||
import { setBreakpointPositions } from "./breakpointPositions";
|
||||
import {
|
||||
assertBreakpoint,
|
||||
createBreakpoint,
|
||||
getASTLocation,
|
||||
makeBreakpointId,
|
||||
makeBreakpointLocation
|
||||
} from "../../utils/breakpoint";
|
||||
import { PROMISE } from "../utils/middleware/promise";
|
||||
import {
|
||||
getSymbols,
|
||||
getFirstBreakpointPosition,
|
||||
getBreakpointPositionsForLocation,
|
||||
getSourceFromId
|
||||
} from "../../selectors";
|
||||
|
||||
import { getTextAtPosition } from "../../utils/source";
|
||||
import { recordEvent } from "../../utils/telemetry";
|
||||
|
||||
import type {
|
||||
BreakpointOptions,
|
||||
Breakpoint,
|
||||
SourceLocation
|
||||
} from "../../types";
|
||||
import type { ThunkArgs } from "../types";
|
||||
|
||||
async function addBreakpointPromise(getState, client, sourceMaps, breakpoint) {
|
||||
const state = getState();
|
||||
const { location, generatedLocation } = breakpoint;
|
||||
const source = getSourceFromId(state, location.sourceId);
|
||||
const generatedSource = getSourceFromId(state, generatedLocation.sourceId);
|
||||
|
||||
const breakpointLocation = makeBreakpointLocation(
|
||||
getState(),
|
||||
generatedLocation
|
||||
);
|
||||
await client.setBreakpoint(breakpointLocation, breakpoint.options);
|
||||
|
||||
const symbols = getSymbols(getState(), source);
|
||||
const astLocation = await getASTLocation(source, symbols, location);
|
||||
|
||||
const originalText = getTextAtPosition(source, location);
|
||||
const text = getTextAtPosition(generatedSource, generatedLocation);
|
||||
|
||||
const newBreakpoint = {
|
||||
id: makeBreakpointId(generatedLocation),
|
||||
disabled: false,
|
||||
options: breakpoint.options,
|
||||
location,
|
||||
astLocation,
|
||||
generatedLocation,
|
||||
text,
|
||||
originalText
|
||||
};
|
||||
|
||||
assertBreakpoint(newBreakpoint);
|
||||
|
||||
return newBreakpoint;
|
||||
}
|
||||
|
||||
export function addHiddenBreakpoint(location: SourceLocation) {
|
||||
return ({ dispatch }: ThunkArgs) => {
|
||||
return dispatch(addBreakpoint(location, { hidden: true }));
|
||||
};
|
||||
}
|
||||
|
||||
export function enableBreakpoint(breakpoint: Breakpoint) {
|
||||
return async ({ dispatch, getState, client, sourceMaps }: ThunkArgs) => {
|
||||
// To instantly reflect in the UI, we optimistically enable the breakpoint
|
||||
const enabledBreakpoint = { ...breakpoint, disabled: false };
|
||||
|
||||
return dispatch({
|
||||
type: "ENABLE_BREAKPOINT",
|
||||
breakpoint: enabledBreakpoint,
|
||||
[PROMISE]: addBreakpointPromise(getState, client, sourceMaps, breakpoint)
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
export function addBreakpoint(
|
||||
location: SourceLocation,
|
||||
options: BreakpointOptions = {}
|
||||
) {
|
||||
return async ({ dispatch, getState, sourceMaps, client }: ThunkArgs) => {
|
||||
recordEvent("add_breakpoint");
|
||||
|
||||
const { sourceId, column } = location;
|
||||
|
||||
await dispatch(setBreakpointPositions(sourceId));
|
||||
|
||||
const position = column
|
||||
? getBreakpointPositionsForLocation(getState(), location)
|
||||
: getFirstBreakpointPosition(getState(), location);
|
||||
|
||||
if (!position) {
|
||||
return;
|
||||
}
|
||||
|
||||
const breakpoint = createBreakpoint(position, { options });
|
||||
|
||||
return dispatch({
|
||||
type: "ADD_BREAKPOINT",
|
||||
breakpoint,
|
||||
[PROMISE]: addBreakpointPromise(getState, client, sourceMaps, breakpoint)
|
||||
});
|
||||
};
|
||||
}
|
|
@ -11,7 +11,6 @@
|
|||
|
||||
import { PROMISE } from "../utils/middleware/promise";
|
||||
import {
|
||||
getBreakpoint,
|
||||
getBreakpointsList,
|
||||
getXHRBreakpoints,
|
||||
getSelectedSource,
|
||||
|
@ -21,86 +20,33 @@ import {
|
|||
isEmptyLineInSource,
|
||||
getBreakpointsAtLine
|
||||
} from "../../selectors";
|
||||
import {
|
||||
assertBreakpoint,
|
||||
createXHRBreakpoint,
|
||||
makeBreakpointLocation
|
||||
} from "../../utils/breakpoint";
|
||||
import { createXHRBreakpoint } from "../../utils/breakpoint";
|
||||
import {
|
||||
addBreakpoint,
|
||||
addHiddenBreakpoint,
|
||||
enableBreakpoint
|
||||
} from "./addBreakpoint";
|
||||
removeBreakpoint,
|
||||
enableBreakpoint,
|
||||
disableBreakpoint
|
||||
} from "./modify";
|
||||
import remapLocations from "./remapLocations";
|
||||
import { syncBreakpoint } from "./syncBreakpoint";
|
||||
import { closeConditionalPanel } from "../ui";
|
||||
|
||||
// this will need to be changed so that addCLientBreakpoint is removed
|
||||
|
||||
import type { ThunkArgs, Action } from "../types";
|
||||
import type { ThunkArgs } from "../types";
|
||||
import type {
|
||||
Breakpoint,
|
||||
BreakpointOptions,
|
||||
Source,
|
||||
SourceLocation,
|
||||
XHRBreakpoint
|
||||
} from "../../types";
|
||||
|
||||
import { recordEvent } from "../../utils/telemetry";
|
||||
|
||||
export * from "./breakpointPositions";
|
||||
export * from "./modify";
|
||||
export * from "./syncBreakpoint";
|
||||
|
||||
async function removeBreakpointsPromise(client, state, breakpoint) {
|
||||
const breakpointLocation = makeBreakpointLocation(
|
||||
state,
|
||||
breakpoint.generatedLocation
|
||||
);
|
||||
await client.removeBreakpoint(breakpointLocation);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove a single breakpoint
|
||||
*
|
||||
* @memberof actions/breakpoints
|
||||
* @static
|
||||
*/
|
||||
export function removeBreakpoint(breakpoint: Breakpoint) {
|
||||
return ({ dispatch, getState, client }: ThunkArgs) => {
|
||||
recordEvent("remove_breakpoint");
|
||||
|
||||
// If the breakpoint is already disabled, we don't need to communicate
|
||||
// with the server. We just need to dispatch an action
|
||||
// simulating a successful server request
|
||||
if (breakpoint.disabled) {
|
||||
return dispatch(
|
||||
({ type: "REMOVE_BREAKPOINT", breakpoint, status: "done" }: Action)
|
||||
);
|
||||
}
|
||||
|
||||
return dispatch({
|
||||
type: "REMOVE_BREAKPOINT",
|
||||
breakpoint,
|
||||
disabled: false,
|
||||
[PROMISE]: removeBreakpointsPromise(client, getState(), breakpoint)
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Disable a single breakpoint
|
||||
*
|
||||
* @memberof actions/breakpoints
|
||||
* @static
|
||||
*/
|
||||
export function disableBreakpoint(breakpoint: Breakpoint) {
|
||||
return async ({ dispatch, getState, client }: ThunkArgs) => {
|
||||
await removeBreakpointsPromise(client, getState(), breakpoint);
|
||||
|
||||
const newBreakpoint: Breakpoint = { ...breakpoint, disabled: true };
|
||||
|
||||
return dispatch(
|
||||
({ type: "DISABLE_BREAKPOINT", breakpoint: newBreakpoint }: Action)
|
||||
);
|
||||
export function addHiddenBreakpoint(location: SourceLocation) {
|
||||
return ({ dispatch }: ThunkArgs) => {
|
||||
return dispatch(addBreakpoint(location, { hidden: true }));
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -148,34 +94,13 @@ export function toggleAllBreakpoints(shouldDisableBreakpoints: boolean) {
|
|||
return async ({ dispatch, getState, client }: ThunkArgs) => {
|
||||
const breakpoints = getBreakpointsList(getState());
|
||||
|
||||
const modifiedBreakpoints = [];
|
||||
|
||||
for (const breakpoint of breakpoints) {
|
||||
if (shouldDisableBreakpoints) {
|
||||
await removeBreakpointsPromise(client, getState(), breakpoint);
|
||||
const newBreakpoint: Breakpoint = { ...breakpoint, disabled: true };
|
||||
modifiedBreakpoints.push(newBreakpoint);
|
||||
dispatch(disableBreakpoint(breakpoint));
|
||||
} else {
|
||||
const newBreakpoint: Breakpoint = { ...breakpoint, disabled: false };
|
||||
modifiedBreakpoints.push(newBreakpoint);
|
||||
dispatch(enableBreakpoint(breakpoint));
|
||||
}
|
||||
}
|
||||
|
||||
if (shouldDisableBreakpoints) {
|
||||
return dispatch(
|
||||
({
|
||||
type: "DISABLE_ALL_BREAKPOINTS",
|
||||
breakpoints: modifiedBreakpoints
|
||||
}: Action)
|
||||
);
|
||||
}
|
||||
|
||||
return dispatch(
|
||||
({
|
||||
type: "ENABLE_ALL_BREAKPOINTS",
|
||||
breakpoints: modifiedBreakpoints
|
||||
}: Action)
|
||||
);
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -262,56 +187,9 @@ export function remapBreakpoints(sourceId: string) {
|
|||
sourceMaps
|
||||
);
|
||||
|
||||
return dispatch(
|
||||
({
|
||||
type: "REMAP_BREAKPOINTS",
|
||||
breakpoints: newBreakpoints
|
||||
}: Action)
|
||||
);
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the options of a breakpoint.
|
||||
*
|
||||
* @throws {Error} "not implemented"
|
||||
* @memberof actions/breakpoints
|
||||
* @static
|
||||
* @param {SourceLocation} location
|
||||
* @see DebuggerController.Breakpoints.addBreakpoint
|
||||
* @param {Object} options
|
||||
* Any options to set on the breakpoint
|
||||
*/
|
||||
export function setBreakpointOptions(
|
||||
location: SourceLocation,
|
||||
options: BreakpointOptions = {}
|
||||
) {
|
||||
return async ({ dispatch, getState, client, sourceMaps }: ThunkArgs) => {
|
||||
const bp = getBreakpoint(getState(), location);
|
||||
if (!bp) {
|
||||
return dispatch(addBreakpoint(location, options));
|
||||
for (const bp of newBreakpoints) {
|
||||
await dispatch(addBreakpoint(bp.location, bp.options, bp.disabled));
|
||||
}
|
||||
|
||||
if (bp.disabled) {
|
||||
await dispatch(enableBreakpoint(bp));
|
||||
}
|
||||
|
||||
const breakpointLocation = makeBreakpointLocation(
|
||||
getState(),
|
||||
bp.generatedLocation
|
||||
);
|
||||
await client.setBreakpoint(breakpointLocation, options);
|
||||
|
||||
const newBreakpoint = { ...bp, disabled: false, options };
|
||||
|
||||
assertBreakpoint(newBreakpoint);
|
||||
|
||||
return dispatch(
|
||||
({
|
||||
type: "SET_BREAKPOINT_OPTIONS",
|
||||
breakpoint: newBreakpoint
|
||||
}: Action)
|
||||
);
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -514,5 +392,3 @@ export function removeXHRBreakpoint(index: number) {
|
|||
});
|
||||
};
|
||||
}
|
||||
|
||||
export { addBreakpoint, addHiddenBreakpoint, enableBreakpoint, syncBreakpoint };
|
||||
|
|
|
@ -0,0 +1,262 @@
|
|||
/* 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/>. */
|
||||
|
||||
// @flow
|
||||
|
||||
import type { ThunkArgs } from "../types";
|
||||
import type {
|
||||
Breakpoint,
|
||||
BreakpointOptions,
|
||||
SourceLocation
|
||||
} from "../../types";
|
||||
|
||||
import {
|
||||
makeBreakpointLocation,
|
||||
makeBreakpointId,
|
||||
getASTLocation
|
||||
} from "../../utils/breakpoint";
|
||||
|
||||
import { getTextAtPosition } from "../../utils/source";
|
||||
|
||||
import {
|
||||
getBreakpoint,
|
||||
getBreakpointPositionsForLocation,
|
||||
getFirstBreakpointPosition,
|
||||
getSourceFromId,
|
||||
getSymbols
|
||||
} from "../../selectors";
|
||||
|
||||
import { loadSourceText } from "../sources/loadSourceText";
|
||||
import { setBreakpointPositions } from "./breakpointPositions";
|
||||
|
||||
import { recordEvent } from "../../utils/telemetry";
|
||||
|
||||
// This file has the primitive operations used to modify individual breakpoints
|
||||
// and keep them in sync with the breakpoints installed on server threads. These
|
||||
// are collected here to make it easier to preserve the following invariant:
|
||||
//
|
||||
// Breakpoints are included in reducer state iff they are disabled or requests
|
||||
// have been dispatched to set them in all server threads.
|
||||
//
|
||||
// To maintain this property, updates to the reducer and installed breakpoints
|
||||
// must happen with no intervening await. Using await allows other operations to
|
||||
// modify the breakpoint state in the interim and potentially cause breakpoint
|
||||
// state to go out of sync.
|
||||
//
|
||||
// The reducer is optimistically updated when users set or remove a breakpoint,
|
||||
// but it might take a little while before the breakpoints have been set or
|
||||
// removed in each thread. Once all outstanding requests sent to a thread have
|
||||
// been processed, the reducer and server threads will be in sync.
|
||||
//
|
||||
// There is another exception to the above invariant when first connecting to
|
||||
// the server: breakpoints have been installed on all generated locations in the
|
||||
// pending breakpoints, but no breakpoints have been added to the reducer. When
|
||||
// a matching source appears, either the server breakpoint will be removed or a
|
||||
// breakpoint will be added to the reducer, to restore the above invariant.
|
||||
// See syncBreakpoint.js for more.
|
||||
|
||||
function clientSetBreakpoint(breakpoint: Breakpoint) {
|
||||
return ({ getState, client }: ThunkArgs) => {
|
||||
const breakpointLocation = makeBreakpointLocation(
|
||||
getState(),
|
||||
breakpoint.generatedLocation
|
||||
);
|
||||
return client.setBreakpoint(breakpointLocation, breakpoint.options);
|
||||
};
|
||||
}
|
||||
|
||||
function clientRemoveBreakpoint(breakpoint: Breakpoint) {
|
||||
return ({ getState, client }: ThunkArgs) => {
|
||||
const breakpointLocation = makeBreakpointLocation(
|
||||
getState(),
|
||||
breakpoint.generatedLocation
|
||||
);
|
||||
return client.removeBreakpoint(breakpointLocation);
|
||||
};
|
||||
}
|
||||
|
||||
export function enableBreakpoint(initialBreakpoint: Breakpoint) {
|
||||
return async ({ dispatch, getState, client, sourceMaps }: ThunkArgs) => {
|
||||
const breakpoint = getBreakpoint(getState(), initialBreakpoint.location);
|
||||
if (!breakpoint || !breakpoint.disabled) {
|
||||
return;
|
||||
}
|
||||
|
||||
dispatch({
|
||||
type: "SET_BREAKPOINT",
|
||||
breakpoint: { ...breakpoint, disabled: false }
|
||||
});
|
||||
|
||||
return dispatch(clientSetBreakpoint(breakpoint));
|
||||
};
|
||||
}
|
||||
|
||||
export function addBreakpoint(
|
||||
initialLocation: SourceLocation,
|
||||
options: BreakpointOptions = {},
|
||||
disabled: boolean = false
|
||||
) {
|
||||
return async ({ dispatch, getState, sourceMaps, client }: ThunkArgs) => {
|
||||
recordEvent("add_breakpoint");
|
||||
|
||||
const { sourceId, column } = initialLocation;
|
||||
|
||||
await dispatch(setBreakpointPositions(sourceId));
|
||||
|
||||
const position = column
|
||||
? getBreakpointPositionsForLocation(getState(), initialLocation)
|
||||
: getFirstBreakpointPosition(getState(), initialLocation);
|
||||
|
||||
if (!position) {
|
||||
return;
|
||||
}
|
||||
|
||||
const { location, generatedLocation } = position;
|
||||
|
||||
// Both the original and generated sources must be loaded to get the
|
||||
// breakpoint's text.
|
||||
await dispatch(
|
||||
loadSourceText(getSourceFromId(getState(), location.sourceId))
|
||||
);
|
||||
await dispatch(
|
||||
loadSourceText(getSourceFromId(getState(), generatedLocation.sourceId))
|
||||
);
|
||||
|
||||
const source = getSourceFromId(getState(), location.sourceId);
|
||||
const generatedSource = getSourceFromId(
|
||||
getState(),
|
||||
generatedLocation.sourceId
|
||||
);
|
||||
|
||||
const symbols = getSymbols(getState(), source);
|
||||
const astLocation = await getASTLocation(source, symbols, location);
|
||||
|
||||
const originalText = getTextAtPosition(source, location);
|
||||
const text = getTextAtPosition(generatedSource, generatedLocation);
|
||||
|
||||
const id = makeBreakpointId(location);
|
||||
const breakpoint = {
|
||||
id,
|
||||
disabled,
|
||||
options,
|
||||
location,
|
||||
astLocation,
|
||||
generatedLocation,
|
||||
text,
|
||||
originalText
|
||||
};
|
||||
|
||||
// There cannot be multiple breakpoints with the same generated location.
|
||||
// Because a generated location cannot map to multiple original locations,
|
||||
// the only breakpoints that can map to this generated location have the
|
||||
// new breakpoint's |location| or |generatedLocation| as their own
|
||||
// |location|. We will overwrite any breakpoint at |location| with the
|
||||
// SET_BREAKPOINT action below, but need to manually remove any breakpoint
|
||||
// at |generatedLocation|.
|
||||
const generatedId = makeBreakpointId(breakpoint.generatedLocation);
|
||||
if (id != generatedId && getBreakpoint(getState(), generatedLocation)) {
|
||||
dispatch({
|
||||
type: "REMOVE_BREAKPOINT",
|
||||
location: generatedLocation
|
||||
});
|
||||
}
|
||||
|
||||
dispatch({
|
||||
type: "SET_BREAKPOINT",
|
||||
breakpoint
|
||||
});
|
||||
|
||||
if (disabled) {
|
||||
// If we just clobbered an enabled breakpoint with a disabled one, we need
|
||||
// to remove any installed breakpoint in the server.
|
||||
return dispatch(clientRemoveBreakpoint(breakpoint));
|
||||
}
|
||||
|
||||
return dispatch(clientSetBreakpoint(breakpoint));
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove a single breakpoint
|
||||
*
|
||||
* @memberof actions/breakpoints
|
||||
* @static
|
||||
*/
|
||||
export function removeBreakpoint(initialBreakpoint: Breakpoint) {
|
||||
return ({ dispatch, getState, client }: ThunkArgs) => {
|
||||
recordEvent("remove_breakpoint");
|
||||
|
||||
const breakpoint = getBreakpoint(getState(), initialBreakpoint.location);
|
||||
if (!breakpoint) {
|
||||
return;
|
||||
}
|
||||
|
||||
dispatch({
|
||||
type: "REMOVE_BREAKPOINT",
|
||||
location: breakpoint.location
|
||||
});
|
||||
|
||||
// If the breakpoint is disabled then it is not installed in the server.
|
||||
if (breakpoint.disabled) {
|
||||
return;
|
||||
}
|
||||
|
||||
return dispatch(clientRemoveBreakpoint(breakpoint));
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Disable a single breakpoint
|
||||
*
|
||||
* @memberof actions/breakpoints
|
||||
* @static
|
||||
*/
|
||||
export function disableBreakpoint(initialBreakpoint: Breakpoint) {
|
||||
return ({ dispatch, getState, client }: ThunkArgs) => {
|
||||
const breakpoint = getBreakpoint(getState(), initialBreakpoint.location);
|
||||
if (!breakpoint || breakpoint.disabled) {
|
||||
return;
|
||||
}
|
||||
|
||||
dispatch({
|
||||
type: "SET_BREAKPOINT",
|
||||
breakpoint: { ...breakpoint, disabled: true }
|
||||
});
|
||||
|
||||
return dispatch(clientRemoveBreakpoint(breakpoint));
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the options of a breakpoint.
|
||||
*
|
||||
* @throws {Error} "not implemented"
|
||||
* @memberof actions/breakpoints
|
||||
* @static
|
||||
* @param {SourceLocation} location
|
||||
* @see DebuggerController.Breakpoints.addBreakpoint
|
||||
* @param {Object} options
|
||||
* Any options to set on the breakpoint
|
||||
*/
|
||||
export function setBreakpointOptions(
|
||||
location: SourceLocation,
|
||||
options: BreakpointOptions = {}
|
||||
) {
|
||||
return ({ dispatch, getState, client, sourceMaps }: ThunkArgs) => {
|
||||
let breakpoint = getBreakpoint(getState(), location);
|
||||
if (!breakpoint) {
|
||||
return dispatch(addBreakpoint(location, options));
|
||||
}
|
||||
|
||||
// Note: setting a breakpoint's options implicitly enables it.
|
||||
breakpoint = { ...breakpoint, disabled: false, options };
|
||||
|
||||
dispatch({
|
||||
type: "SET_BREAKPOINT",
|
||||
breakpoint
|
||||
});
|
||||
|
||||
return dispatch(clientSetBreakpoint(breakpoint));
|
||||
};
|
||||
}
|
|
@ -8,9 +8,9 @@ DIRS += [
|
|||
]
|
||||
|
||||
CompiledModules(
|
||||
'addBreakpoint.js',
|
||||
'breakpointPositions.js',
|
||||
'index.js',
|
||||
'modify.js',
|
||||
'remapLocations.js',
|
||||
'syncBreakpoint.js',
|
||||
)
|
||||
|
|
|
@ -6,36 +6,27 @@
|
|||
|
||||
import { setBreakpointPositions } from "./breakpointPositions";
|
||||
import {
|
||||
createBreakpoint,
|
||||
assertBreakpoint,
|
||||
assertPendingBreakpoint,
|
||||
findFunctionByName,
|
||||
findPosition,
|
||||
makeBreakpointLocation
|
||||
} from "../../utils/breakpoint";
|
||||
|
||||
import { getTextAtPosition, isInlineScript } from "../../utils/source";
|
||||
import { comparePosition } from "../../utils/location";
|
||||
import { comparePosition, createLocation } from "../../utils/location";
|
||||
|
||||
import { originalToGeneratedId, isOriginalId } from "devtools-source-map";
|
||||
import { getSource, getBreakpointsList } from "../../selectors";
|
||||
import { removeBreakpoint } from ".";
|
||||
import { getSource, getBreakpoint } from "../../selectors";
|
||||
import { removeBreakpoint, addBreakpoint } from ".";
|
||||
|
||||
import type { ThunkArgs, Action } from "../types";
|
||||
import type { ThunkArgs } from "../types";
|
||||
|
||||
import type {
|
||||
SourceLocation,
|
||||
ASTLocation,
|
||||
PendingBreakpoint,
|
||||
SourceId,
|
||||
Breakpoint
|
||||
SourceId
|
||||
} from "../../types";
|
||||
|
||||
type BreakpointSyncData = {
|
||||
previousLocation: SourceLocation,
|
||||
breakpoint: ?Breakpoint
|
||||
};
|
||||
|
||||
async function findBreakpointPosition(
|
||||
{ getState, dispatch },
|
||||
location: SourceLocation
|
||||
|
@ -66,172 +57,123 @@ async function findNewLocation(
|
|||
};
|
||||
}
|
||||
|
||||
function createSyncData(
|
||||
pendingBreakpoint: PendingBreakpoint,
|
||||
location: SourceLocation,
|
||||
generatedLocation: SourceLocation,
|
||||
previousLocation: SourceLocation,
|
||||
text: string,
|
||||
originalText: string
|
||||
): BreakpointSyncData {
|
||||
const overrides = {
|
||||
...pendingBreakpoint,
|
||||
text,
|
||||
originalText
|
||||
};
|
||||
const breakpoint = createBreakpoint(
|
||||
{ generatedLocation, location },
|
||||
overrides
|
||||
);
|
||||
|
||||
assertBreakpoint(breakpoint);
|
||||
return { breakpoint, previousLocation };
|
||||
}
|
||||
|
||||
// Look for an existing breakpoint at the specified generated location.
|
||||
function findExistingBreakpoint(state, generatedLocation) {
|
||||
const breakpoints = getBreakpointsList(state);
|
||||
|
||||
return breakpoints.find(bp => {
|
||||
return (
|
||||
bp.generatedLocation.sourceUrl == generatedLocation.sourceUrl &&
|
||||
bp.generatedLocation.line == generatedLocation.line &&
|
||||
bp.generatedLocation.column == generatedLocation.column
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
// we have three forms of syncing: disabled syncing, existing server syncing
|
||||
// and adding a new breakpoint
|
||||
export async function syncBreakpointPromise(
|
||||
thunkArgs: ThunkArgs,
|
||||
sourceId: SourceId,
|
||||
pendingBreakpoint: PendingBreakpoint
|
||||
): Promise<?BreakpointSyncData> {
|
||||
const { getState, client, dispatch } = thunkArgs;
|
||||
assertPendingBreakpoint(pendingBreakpoint);
|
||||
|
||||
const source = getSource(getState(), sourceId);
|
||||
|
||||
const generatedSourceId = isOriginalId(sourceId)
|
||||
? originalToGeneratedId(sourceId)
|
||||
: sourceId;
|
||||
|
||||
const generatedSource = getSource(getState(), generatedSourceId);
|
||||
|
||||
if (!source || !generatedSource) {
|
||||
return;
|
||||
}
|
||||
|
||||
const { location, generatedLocation, astLocation } = pendingBreakpoint;
|
||||
const previousLocation = { ...location, sourceId };
|
||||
|
||||
const newLocation = await findNewLocation(
|
||||
astLocation,
|
||||
previousLocation,
|
||||
source
|
||||
);
|
||||
|
||||
const newGeneratedLocation = await findBreakpointPosition(
|
||||
thunkArgs,
|
||||
newLocation
|
||||
);
|
||||
|
||||
const isSameLocation = comparePosition(
|
||||
generatedLocation,
|
||||
newGeneratedLocation
|
||||
);
|
||||
|
||||
/** ******* CASE 1: No server change ***********/
|
||||
// early return if breakpoint is disabled or we are in the sameLocation
|
||||
if (newGeneratedLocation && (pendingBreakpoint.disabled || isSameLocation)) {
|
||||
// Make sure the breakpoint is installed on all source actors.
|
||||
if (!pendingBreakpoint.disabled) {
|
||||
await client.setBreakpoint(
|
||||
makeBreakpointLocation(getState(), newGeneratedLocation),
|
||||
pendingBreakpoint.options
|
||||
);
|
||||
}
|
||||
|
||||
const originalText = getTextAtPosition(source, previousLocation);
|
||||
const text = getTextAtPosition(generatedSource, newGeneratedLocation);
|
||||
|
||||
return createSyncData(
|
||||
pendingBreakpoint,
|
||||
newLocation,
|
||||
newGeneratedLocation,
|
||||
previousLocation,
|
||||
text,
|
||||
originalText
|
||||
);
|
||||
}
|
||||
|
||||
// Clear any breakpoint for the generated location.
|
||||
const bp = findExistingBreakpoint(getState(), generatedLocation);
|
||||
if (bp) {
|
||||
await dispatch(removeBreakpoint(bp));
|
||||
}
|
||||
|
||||
if (!newGeneratedLocation) {
|
||||
return {
|
||||
previousLocation,
|
||||
// We return the original bp here for HTML scripts because there may
|
||||
// be multiple <script> elements in a source and not all of them may
|
||||
// have loaded yet to allow synching. This means we need to leave
|
||||
// breakpoints on these pages pending.
|
||||
breakpoint: isInlineScript(generatedSource) ? bp : null
|
||||
};
|
||||
}
|
||||
|
||||
/** ******* Case 2: Add New Breakpoint ***********/
|
||||
// If we are not disabled, set the breakpoint on the server and get
|
||||
// that info so we can set it on our breakpoints.
|
||||
await client.setBreakpoint(
|
||||
makeBreakpointLocation(getState(), newGeneratedLocation),
|
||||
pendingBreakpoint.options
|
||||
);
|
||||
|
||||
const originalText = getTextAtPosition(source, newLocation);
|
||||
const text = getTextAtPosition(generatedSource, newGeneratedLocation);
|
||||
|
||||
return createSyncData(
|
||||
pendingBreakpoint,
|
||||
newLocation,
|
||||
newGeneratedLocation,
|
||||
previousLocation,
|
||||
text,
|
||||
originalText
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Syncing a breakpoint add breakpoint information that is stored, and
|
||||
* contact the server for more data.
|
||||
*/
|
||||
// Breakpoint syncing occurs when a source is found that matches either the
|
||||
// original or generated URL of a pending breakpoint. A new breakpoint is
|
||||
// constructed that might have a different original and/or generated location,
|
||||
// if the original source has changed since the pending breakpoint was created.
|
||||
// There are a couple subtle aspects to syncing:
|
||||
//
|
||||
// - We handle both the original and generated source because there is no
|
||||
// guarantee that seeing the generated source means we will also see the
|
||||
// original source. When connecting, a breakpoint will be installed in the
|
||||
// client for the generated location in the pending breakpoint, and we need
|
||||
// to make sure that either a breakpoint is added to the reducer or that this
|
||||
// client breakpoint is deleted.
|
||||
//
|
||||
// - If we see both the original and generated sources and the source mapping
|
||||
// has changed, we need to make sure that only a single breakpoint is added
|
||||
// to the reducer for the new location corresponding to the original location
|
||||
// in the pending breakpoint.
|
||||
export function syncBreakpoint(
|
||||
sourceId: SourceId,
|
||||
pendingBreakpoint: PendingBreakpoint
|
||||
) {
|
||||
return async (thunkArgs: ThunkArgs) => {
|
||||
const { dispatch } = thunkArgs;
|
||||
const { getState, client, dispatch } = thunkArgs;
|
||||
assertPendingBreakpoint(pendingBreakpoint);
|
||||
|
||||
const response = await syncBreakpointPromise(
|
||||
thunkArgs,
|
||||
sourceId,
|
||||
pendingBreakpoint
|
||||
);
|
||||
const source = getSource(getState(), sourceId);
|
||||
|
||||
if (!response) {
|
||||
const generatedSourceId = isOriginalId(sourceId)
|
||||
? originalToGeneratedId(sourceId)
|
||||
: sourceId;
|
||||
|
||||
const generatedSource = getSource(getState(), generatedSourceId);
|
||||
|
||||
if (!source || !generatedSource) {
|
||||
return;
|
||||
}
|
||||
|
||||
const { breakpoint, previousLocation } = response;
|
||||
const { location, generatedLocation, astLocation } = pendingBreakpoint;
|
||||
const sourceGeneratedLocation = createLocation({
|
||||
...generatedLocation,
|
||||
sourceId: generatedSourceId
|
||||
});
|
||||
|
||||
if (
|
||||
source == generatedSource &&
|
||||
location.sourceUrl != generatedLocation.sourceUrl
|
||||
) {
|
||||
// We are handling the generated source and the pending breakpoint has a
|
||||
// source mapping. Watch out for the case when the original source has
|
||||
// already been processed, in which case either a breakpoint has already
|
||||
// been added at this generated location or the client breakpoint has been
|
||||
// removed.
|
||||
const breakpointLocation = makeBreakpointLocation(
|
||||
getState(),
|
||||
sourceGeneratedLocation
|
||||
);
|
||||
if (
|
||||
getBreakpoint(getState(), sourceGeneratedLocation) ||
|
||||
!client.hasBreakpoint(breakpointLocation)
|
||||
) {
|
||||
return;
|
||||
}
|
||||
return dispatch(
|
||||
addBreakpoint(
|
||||
sourceGeneratedLocation,
|
||||
pendingBreakpoint.options,
|
||||
pendingBreakpoint.disabled
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
const previousLocation = { ...location, sourceId };
|
||||
|
||||
const newLocation = await findNewLocation(
|
||||
astLocation,
|
||||
previousLocation,
|
||||
source
|
||||
);
|
||||
|
||||
const newGeneratedLocation = await findBreakpointPosition(
|
||||
thunkArgs,
|
||||
newLocation
|
||||
);
|
||||
|
||||
if (!newGeneratedLocation) {
|
||||
return;
|
||||
}
|
||||
|
||||
const isSameLocation = comparePosition(
|
||||
generatedLocation,
|
||||
newGeneratedLocation
|
||||
);
|
||||
|
||||
// If the new generated location has changed from that in the pending
|
||||
// breakpoint, remove any breakpoint associated with the old generated
|
||||
// location. This could either be in the reducer or only in the client,
|
||||
// depending on whether the pending breakpoint has been processed for the
|
||||
// generated source yet.
|
||||
if (!isSameLocation) {
|
||||
const bp = getBreakpoint(getState(), sourceGeneratedLocation);
|
||||
if (bp) {
|
||||
dispatch(removeBreakpoint(bp));
|
||||
} else {
|
||||
const breakpointLocation = makeBreakpointLocation(
|
||||
getState(),
|
||||
sourceGeneratedLocation
|
||||
);
|
||||
client.removeBreakpoint(breakpointLocation);
|
||||
}
|
||||
}
|
||||
|
||||
return dispatch(
|
||||
({
|
||||
type: "SYNC_BREAKPOINT",
|
||||
breakpoint,
|
||||
previousLocation
|
||||
}: Action)
|
||||
addBreakpoint(
|
||||
newLocation,
|
||||
pendingBreakpoint.options,
|
||||
pendingBreakpoint.disabled
|
||||
)
|
||||
);
|
||||
};
|
||||
}
|
||||
|
|
|
@ -29,11 +29,7 @@ Array [
|
|||
"sourceId": "a",
|
||||
"sourceUrl": "http://localhost:8000/examples/a",
|
||||
},
|
||||
"options": Object {
|
||||
"condition": null,
|
||||
"hidden": false,
|
||||
"logValue": null,
|
||||
},
|
||||
"options": Object {},
|
||||
"originalText": "return a",
|
||||
"text": "return a",
|
||||
},
|
||||
|
@ -64,12 +60,10 @@ exports[`breakpoints should remap breakpoints on pretty print 1`] = `
|
|||
Object {
|
||||
"astLocation": Object {
|
||||
"index": 0,
|
||||
"name": undefined,
|
||||
"name": "a",
|
||||
"offset": Object {
|
||||
"column": 0,
|
||||
"line": 1,
|
||||
"sourceId": "a.js",
|
||||
"sourceUrl": "http://localhost:8000/examples/a.js",
|
||||
"column": undefined,
|
||||
"line": 0,
|
||||
},
|
||||
},
|
||||
"disabled": false,
|
||||
|
@ -79,18 +73,14 @@ Object {
|
|||
"sourceId": "a.js",
|
||||
"sourceUrl": "http://localhost:8000/examples/a.js",
|
||||
},
|
||||
"id": "a.js:1:",
|
||||
"id": "a.js/originalSource-d6d70368d5c252598541e693a7ad6c27:1:",
|
||||
"location": Object {
|
||||
"column": 0,
|
||||
"line": 1,
|
||||
"sourceId": "a.js/originalSource-d6d70368d5c252598541e693a7ad6c27",
|
||||
"sourceUrl": "http://localhost:8000/examples/a.js:formatted",
|
||||
},
|
||||
"options": Object {
|
||||
"condition": null,
|
||||
"hidden": false,
|
||||
"logValue": null,
|
||||
},
|
||||
"options": Object {},
|
||||
"originalText": "function a() {",
|
||||
"text": "function a() {",
|
||||
}
|
||||
|
@ -125,11 +115,7 @@ Array [
|
|||
"sourceId": "a",
|
||||
"sourceUrl": "http://localhost:8000/examples/a",
|
||||
},
|
||||
"options": Object {
|
||||
"condition": null,
|
||||
"hidden": false,
|
||||
"logValue": null,
|
||||
},
|
||||
"options": Object {},
|
||||
"originalText": "",
|
||||
"text": "",
|
||||
},
|
||||
|
|
|
@ -99,7 +99,12 @@ describe("breakpoints", () => {
|
|||
})
|
||||
);
|
||||
|
||||
const breakpoint = await dispatch(actions.addBreakpoint(loc1));
|
||||
await dispatch(actions.addBreakpoint(loc1));
|
||||
const breakpoint = selectors.getBreakpoint(getState(), loc1);
|
||||
if (!breakpoint) {
|
||||
throw new Error("no breakpoint");
|
||||
}
|
||||
|
||||
await dispatch(actions.disableBreakpoint(breakpoint));
|
||||
|
||||
expect(selectors.getBreakpointCount(getState())).toEqual(1);
|
||||
|
@ -211,9 +216,14 @@ describe("breakpoints", () => {
|
|||
await dispatch(actions.newSource(bSource));
|
||||
await dispatch(actions.loadSourceText(bSource));
|
||||
|
||||
const breakpoint = await dispatch(actions.addBreakpoint(loc1));
|
||||
await dispatch(actions.addBreakpoint(loc1));
|
||||
await dispatch(actions.addBreakpoint(loc2));
|
||||
|
||||
const breakpoint = selectors.getBreakpoint(getState(), loc1);
|
||||
if (!breakpoint) {
|
||||
throw new Error("no breakpoint");
|
||||
}
|
||||
|
||||
await dispatch(actions.disableBreakpoint(breakpoint));
|
||||
|
||||
const bp = selectors.getBreakpoint(getState(), loc1);
|
||||
|
@ -235,13 +245,22 @@ describe("breakpoints", () => {
|
|||
await dispatch(actions.newSource(aSource));
|
||||
await dispatch(actions.loadSourceText(aSource));
|
||||
|
||||
const breakpoint = await dispatch(actions.addBreakpoint(loc));
|
||||
await dispatch(actions.disableBreakpoint(breakpoint));
|
||||
|
||||
await dispatch(actions.addBreakpoint(loc));
|
||||
let bp = selectors.getBreakpoint(getState(), loc);
|
||||
if (!bp) {
|
||||
throw new Error("no breakpoint");
|
||||
}
|
||||
|
||||
await dispatch(actions.disableBreakpoint(bp));
|
||||
|
||||
bp = selectors.getBreakpoint(getState(), loc);
|
||||
if (!bp) {
|
||||
throw new Error("no breakpoint");
|
||||
}
|
||||
|
||||
expect(bp && bp.disabled).toBe(true);
|
||||
|
||||
await dispatch(actions.enableBreakpoint(breakpoint));
|
||||
await dispatch(actions.enableBreakpoint(bp));
|
||||
|
||||
bp = selectors.getBreakpoint(getState(), loc);
|
||||
expect(bp && !bp.disabled).toBe(true);
|
||||
|
@ -354,7 +373,7 @@ describe("breakpoints", () => {
|
|||
await dispatch(actions.addBreakpoint(loc));
|
||||
|
||||
let bp = selectors.getBreakpoint(getState(), loc);
|
||||
expect(bp && bp.options.condition).toBe(null);
|
||||
expect(bp && bp.options.condition).toBe(undefined);
|
||||
|
||||
await dispatch(
|
||||
actions.setBreakpointOptions(loc, {
|
||||
|
@ -381,11 +400,16 @@ describe("breakpoints", () => {
|
|||
await dispatch(actions.newSource(source));
|
||||
await dispatch(actions.loadSourceText(source));
|
||||
|
||||
const breakpoint = await dispatch(actions.addBreakpoint(loc));
|
||||
await dispatch(actions.disableBreakpoint(breakpoint));
|
||||
await dispatch(actions.addBreakpoint(loc));
|
||||
let bp = selectors.getBreakpoint(getState(), loc);
|
||||
if (!bp) {
|
||||
throw new Error("no breakpoint");
|
||||
}
|
||||
|
||||
const bp = selectors.getBreakpoint(getState(), loc);
|
||||
expect(bp && bp.options.condition).toBe(null);
|
||||
await dispatch(actions.disableBreakpoint(bp));
|
||||
|
||||
bp = selectors.getBreakpoint(getState(), loc);
|
||||
expect(bp && bp.options.condition).toBe(undefined);
|
||||
|
||||
await dispatch(
|
||||
actions.setBreakpointOptions(loc, {
|
||||
|
|
|
@ -88,11 +88,6 @@ async function loadSourceTextPromise(
|
|||
return;
|
||||
}
|
||||
|
||||
dispatch({
|
||||
type: "UPDATE_BREAKPOINT_TEXT",
|
||||
source: newSource
|
||||
});
|
||||
|
||||
if (!newSource.isWasm && isLoaded(newSource)) {
|
||||
parser.setSource(newSource);
|
||||
dispatch(setBreakpointPositions(newSource.id));
|
||||
|
|
|
@ -13,11 +13,7 @@ import { generatedToOriginalId } from "devtools-source-map";
|
|||
import { flatten } from "lodash";
|
||||
|
||||
import { toggleBlackBox } from "./blackbox";
|
||||
import {
|
||||
syncBreakpoint,
|
||||
addBreakpoint,
|
||||
setBreakpointPositions
|
||||
} from "../breakpoints";
|
||||
import { syncBreakpoint, setBreakpointPositions } from "../breakpoints";
|
||||
import { loadSourceText } from "./loadSourceText";
|
||||
import { togglePrettyPrint } from "./prettyPrint";
|
||||
import { selectLocation } from "../sources";
|
||||
|
@ -198,18 +194,9 @@ function checkPendingBreakpoints(sourceId: string) {
|
|||
// load the source text if there is a pending breakpoint for it
|
||||
await dispatch(loadSourceText(source));
|
||||
|
||||
// Matching pending breakpoints could have either the same generated or the
|
||||
// same original source. We expect the generated source to appear first and
|
||||
// will add a breakpoint at that location initially. If the original source
|
||||
// appears later then we use syncBreakpoint to see if the generated location
|
||||
// changed and we need to remove the breakpoint we added earlier.
|
||||
await Promise.all(
|
||||
pendingBreakpoints.map(bp => {
|
||||
if (source.url == bp.location.sourceUrl) {
|
||||
return dispatch(syncBreakpoint(sourceId, bp));
|
||||
}
|
||||
const { line, column } = bp.generatedLocation;
|
||||
return dispatch(addBreakpoint({ sourceId, line, column }, bp.options));
|
||||
return dispatch(syncBreakpoint(sourceId, bp));
|
||||
})
|
||||
);
|
||||
};
|
||||
|
|
|
@ -16,7 +16,6 @@ import {
|
|||
createSource,
|
||||
sourceThreadClient
|
||||
} from "../../tests/helpers/threadClient.js";
|
||||
import { addBreakpoint } from "../../breakpoints/addBreakpoint";
|
||||
import { getBreakpointsList } from "../../../selectors";
|
||||
|
||||
describe("loadSourceText", () => {
|
||||
|
@ -79,21 +78,24 @@ describe("loadSourceText", () => {
|
|||
await dispatch(actions.newSource(fooOrigSource));
|
||||
await dispatch(actions.newSource(fooGenSource));
|
||||
|
||||
const breakpoint = await dispatch(
|
||||
addBreakpoint({
|
||||
sourceId: fooOrigSource.id,
|
||||
line: 1,
|
||||
column: 0
|
||||
})
|
||||
);
|
||||
const location = {
|
||||
sourceId: fooOrigSource.id,
|
||||
line: 1,
|
||||
column: 0
|
||||
};
|
||||
await dispatch(actions.addBreakpoint(location, {}));
|
||||
const breakpoint = selectors.getBreakpoint(getState(), location);
|
||||
if (!breakpoint) {
|
||||
throw new Error("no breakpoint");
|
||||
}
|
||||
|
||||
expect(breakpoint.text).toBe("");
|
||||
expect(breakpoint.originalText).toBe("");
|
||||
expect(breakpoint.text).toBe("var fooGen = 42;");
|
||||
expect(breakpoint.originalText).toBe("var fooOrig = 42;");
|
||||
|
||||
await dispatch(actions.loadSourceText(fooOrigSource));
|
||||
|
||||
const breakpoint1 = getBreakpointsList(getState())[0];
|
||||
expect(breakpoint1.text).toBe("");
|
||||
expect(breakpoint1.text).toBe("var fooGen = 42;");
|
||||
expect(breakpoint1.originalText).toBe("var fooOrig = 42;");
|
||||
|
||||
await dispatch(actions.loadSourceText(fooGenSource));
|
||||
|
|
|
@ -53,11 +53,7 @@ Object {
|
|||
"line": 5,
|
||||
"sourceUrl": "http://localhost:8000/examples/foo.js",
|
||||
},
|
||||
"options": Object {
|
||||
"condition": null,
|
||||
"hidden": false,
|
||||
"logValue": null,
|
||||
},
|
||||
"options": Object {},
|
||||
}
|
||||
`;
|
||||
|
||||
|
@ -84,11 +80,7 @@ Object {
|
|||
"line": 5,
|
||||
"sourceUrl": "http://localhost:8000/examples/foo",
|
||||
},
|
||||
"options": Object {
|
||||
"condition": null,
|
||||
"hidden": false,
|
||||
"logValue": null,
|
||||
},
|
||||
"options": Object {},
|
||||
}
|
||||
`;
|
||||
|
||||
|
@ -115,10 +107,6 @@ Object {
|
|||
"line": 5,
|
||||
"sourceUrl": "http://localhost:8000/examples/foo2",
|
||||
},
|
||||
"options": Object {
|
||||
"condition": null,
|
||||
"hidden": false,
|
||||
"logValue": null,
|
||||
},
|
||||
"options": Object {},
|
||||
}
|
||||
`;
|
||||
|
|
|
@ -15,19 +15,6 @@ import type {
|
|||
import type { PromiseAction } from "../utils/middleware/promise";
|
||||
|
||||
export type BreakpointAction =
|
||||
| PromiseAction<
|
||||
{|
|
||||
+type: "ADD_BREAKPOINT",
|
||||
+breakpoint: Breakpoint,
|
||||
+condition?: string
|
||||
|},
|
||||
Breakpoint
|
||||
>
|
||||
| PromiseAction<{|
|
||||
+type: "REMOVE_BREAKPOINT",
|
||||
+breakpoint: Breakpoint,
|
||||
+disabled: boolean
|
||||
|}>
|
||||
| PromiseAction<{|
|
||||
+type: "SET_XHR_BREAKPOINT",
|
||||
+breakpoint: XHRBreakpoint
|
||||
|
@ -52,53 +39,16 @@ export type BreakpointAction =
|
|||
+index: number,
|
||||
+breakpoint: XHRBreakpoint
|
||||
|}>
|
||||
| {|
|
||||
+type: "SET_BREAKPOINT",
|
||||
+breakpoint: Breakpoint
|
||||
|}
|
||||
| {|
|
||||
+type: "REMOVE_BREAKPOINT",
|
||||
+breakpoint: Breakpoint,
|
||||
+status: "done"
|
||||
|}
|
||||
| {|
|
||||
+type: "SET_BREAKPOINT_OPTIONS",
|
||||
+breakpoint: Breakpoint
|
||||
|}
|
||||
| PromiseAction<{|
|
||||
+type: "TOGGLE_BREAKPOINTS",
|
||||
+shouldDisableBreakpoints: boolean
|
||||
|}>
|
||||
| {|
|
||||
+type: "SYNC_BREAKPOINT",
|
||||
+breakpoint: ?Breakpoint,
|
||||
+previousLocation: SourceLocation
|
||||
|}
|
||||
| PromiseAction<
|
||||
{|
|
||||
+type: "ENABLE_BREAKPOINT",
|
||||
+breakpoint: Breakpoint
|
||||
|},
|
||||
Breakpoint
|
||||
>
|
||||
| {|
|
||||
+type: "DISABLE_BREAKPOINT",
|
||||
+breakpoint: Breakpoint
|
||||
|}
|
||||
| {|
|
||||
+type: "DISABLE_ALL_BREAKPOINTS",
|
||||
+breakpoints: Breakpoint[]
|
||||
|}
|
||||
| {|
|
||||
+type: "ENABLE_ALL_BREAKPOINTS",
|
||||
+breakpoints: Breakpoint[]
|
||||
|}
|
||||
| {|
|
||||
+type: "REMAP_BREAKPOINTS",
|
||||
+breakpoints: Breakpoint[]
|
||||
+location: SourceLocation
|
||||
|}
|
||||
| {|
|
||||
type: "ADD_BREAKPOINT_POSITIONS",
|
||||
positions: BreakpointPositions,
|
||||
source: Source
|
||||
|}
|
||||
| {|
|
||||
+type: "UPDATE_BREAKPOINT_TEXT",
|
||||
+source: Source
|
||||
|};
|
||||
|
|
|
@ -100,6 +100,9 @@ function listWorkerThreadClients() {
|
|||
function forEachWorkerThread(iteratee) {
|
||||
const promises = listWorkerThreadClients().map(thread => iteratee(thread));
|
||||
|
||||
// Do not return promises for the caller to wait on unless a flag is set.
|
||||
// Currently, worker threads are not guaranteed to respond to all requests,
|
||||
// if we send a request while they are shutting down. See bug 1529163.
|
||||
if (shouldWaitForWorkers) {
|
||||
return Promise.all(promises);
|
||||
}
|
||||
|
@ -210,6 +213,10 @@ function maybeClearLogpoint(location: BreakpointLocation) {
|
|||
}
|
||||
}
|
||||
|
||||
function hasBreakpoint(location: BreakpointLocation) {
|
||||
return !!breakpoints[locationKey(location)];
|
||||
}
|
||||
|
||||
async function setBreakpoint(
|
||||
location: BreakpointLocation,
|
||||
options: BreakpointOptions
|
||||
|
@ -217,25 +224,28 @@ async function setBreakpoint(
|
|||
maybeClearLogpoint(location);
|
||||
options = maybeGenerateLogGroupId(options);
|
||||
breakpoints[locationKey(location)] = { location, options };
|
||||
await threadClient.setBreakpoint(location, options);
|
||||
|
||||
// Set breakpoints in other threads as well, but do not wait for the requests
|
||||
// to complete, so that we don't get hung up if one of the threads stops
|
||||
// responding. We don't strictly need to wait for the main thread to finish
|
||||
// setting its breakpoint, but this leads to more consistent behavior if the
|
||||
// user sets a breakpoint and immediately starts interacting with the page.
|
||||
// If the main thread stops responding then we're toast regardless.
|
||||
// We have to be careful here to atomically initiate the setBreakpoint() call
|
||||
// on every thread, with no intervening await. Otherwise, other code could run
|
||||
// and change or remove the breakpoint before we finish calling setBreakpoint
|
||||
// on all threads. Requests on server threads will resolve in FIFO order, and
|
||||
// this could result in the breakpoint state here being out of sync with the
|
||||
// breakpoints that are installed in the server.
|
||||
const mainThreadPromise = threadClient.setBreakpoint(location, options);
|
||||
|
||||
await forEachWorkerThread(thread => thread.setBreakpoint(location, options));
|
||||
await mainThreadPromise;
|
||||
}
|
||||
|
||||
async function removeBreakpoint(location: PendingLocation) {
|
||||
maybeClearLogpoint((location: any));
|
||||
delete breakpoints[locationKey((location: any))];
|
||||
await threadClient.removeBreakpoint(location);
|
||||
|
||||
// Remove breakpoints without waiting for the thread to respond, for the same
|
||||
// reason as in setBreakpoint.
|
||||
// Delay waiting on this promise, for the same reason as in setBreakpoint.
|
||||
const mainThreadPromise = threadClient.removeBreakpoint(location);
|
||||
|
||||
await forEachWorkerThread(thread => thread.removeBreakpoint(location));
|
||||
await mainThreadPromise;
|
||||
}
|
||||
|
||||
async function evaluateInFrame(script: Script, options: EvaluateParam) {
|
||||
|
@ -484,6 +494,7 @@ const clientCommands = {
|
|||
sourceContents,
|
||||
getSourceForActor,
|
||||
getBreakpointPositions,
|
||||
hasBreakpoint,
|
||||
setBreakpoint,
|
||||
setXHRBreakpoint,
|
||||
removeXHRBreakpoint,
|
||||
|
|
|
@ -359,13 +359,6 @@ export type ThreadClient = {
|
|||
skipBreakpoints: boolean => Promise<{| skip: boolean |}>
|
||||
};
|
||||
|
||||
export type FirefoxClientConnection = {
|
||||
getTabTarget: () => TabTarget,
|
||||
getThreadClient: () => ThreadClient,
|
||||
setTabTarget: (target: TabTarget) => void,
|
||||
setThreadClient: (client: ThreadClient) => void
|
||||
};
|
||||
|
||||
export type Panel = {|
|
||||
emit: (eventName: string) => void,
|
||||
openLink: (url: string) => void,
|
||||
|
|
|
@ -84,7 +84,7 @@ export async function onConnect(
|
|||
const workers = bootstrapWorkers();
|
||||
await client.onConnect(connection, actions);
|
||||
|
||||
syncBreakpoints();
|
||||
await syncBreakpoints();
|
||||
syncXHRBreakpoints();
|
||||
setupHelper({
|
||||
store,
|
||||
|
|
|
@ -8,12 +8,11 @@ import React from "react";
|
|||
import { shallow } from "enzyme";
|
||||
|
||||
import BreakpointsContextMenu from "../BreakpointsContextMenu";
|
||||
import { createBreakpoint } from "../../../../utils/breakpoint";
|
||||
import { buildMenu } from "devtools-contextmenu";
|
||||
|
||||
import {
|
||||
makeMockSource,
|
||||
makeMappedLocation
|
||||
makeMockBreakpoint,
|
||||
makeMockSource
|
||||
} from "../../../../utils/test-mockup";
|
||||
|
||||
jest.mock("devtools-contextmenu");
|
||||
|
@ -25,52 +24,34 @@ function render(disabled = false) {
|
|||
}
|
||||
|
||||
function generateDefaults(disabled) {
|
||||
const source = makeMockSource(
|
||||
"https://example.com/main.js",
|
||||
"source-https://example.com/main.js"
|
||||
);
|
||||
const breakpoints = [
|
||||
createBreakpoint(
|
||||
makeMappedLocation({
|
||||
line: 1,
|
||||
column: undefined,
|
||||
sourceId: "source-https://example.com/main.js",
|
||||
sourceUrl: "https://example.com/main.js"
|
||||
}),
|
||||
{
|
||||
id: "https://example.com/main.js:1:",
|
||||
disabled: disabled,
|
||||
options: {
|
||||
condition: "",
|
||||
logValue: "",
|
||||
hidden: false
|
||||
}
|
||||
{
|
||||
...makeMockBreakpoint(source, 1),
|
||||
id: "https://example.com/main.js:1:",
|
||||
disabled: disabled,
|
||||
options: {
|
||||
condition: "",
|
||||
logValue: "",
|
||||
hidden: false
|
||||
}
|
||||
),
|
||||
createBreakpoint(
|
||||
makeMappedLocation({
|
||||
line: 2,
|
||||
column: undefined,
|
||||
sourceId: "source-https://example.com/main.js",
|
||||
sourceUrl: "https://example.com/main.js"
|
||||
}),
|
||||
{
|
||||
id: "https://example.com/main.js:2:",
|
||||
disabled: disabled,
|
||||
options: {
|
||||
hidden: false
|
||||
}
|
||||
},
|
||||
{
|
||||
...makeMockBreakpoint(source, 2),
|
||||
id: "https://example.com/main.js:2:",
|
||||
disabled: disabled,
|
||||
options: {
|
||||
hidden: false
|
||||
}
|
||||
),
|
||||
createBreakpoint(
|
||||
makeMappedLocation({
|
||||
line: 3,
|
||||
column: undefined,
|
||||
sourceId: "source-https://example.com/main.js",
|
||||
sourceUrl: "https://example.com/main.js"
|
||||
}),
|
||||
{
|
||||
id: "https://example.com/main.js:3:",
|
||||
disabled: disabled,
|
||||
options: {}
|
||||
}
|
||||
)
|
||||
},
|
||||
{
|
||||
...makeMockBreakpoint(source, 3),
|
||||
id: "https://example.com/main.js:3:",
|
||||
disabled: disabled
|
||||
}
|
||||
];
|
||||
|
||||
const props = {
|
||||
|
|
|
@ -14,7 +14,7 @@ import { isEqual } from "lodash";
|
|||
|
||||
import { makeBreakpointId, findPosition } from "../utils/breakpoint";
|
||||
import { findEmptyLines } from "../utils/empty-lines";
|
||||
import { getTextAtPosition, isInlineScript } from "../utils/source";
|
||||
import { isInlineScript } from "../utils/source";
|
||||
|
||||
// eslint-disable-next-line max-len
|
||||
import { getBreakpointsList as getBreakpointsListSelector } from "../selectors/breakpoints";
|
||||
|
@ -24,11 +24,10 @@ import type {
|
|||
Breakpoint,
|
||||
BreakpointId,
|
||||
MappedLocation,
|
||||
Source,
|
||||
SourceLocation,
|
||||
BreakpointPositions
|
||||
} from "../types";
|
||||
import type { Action, DonePromiseAction } from "../actions/types";
|
||||
import type { Action } from "../actions/types";
|
||||
|
||||
export type BreakpointsMap = { [BreakpointId]: Breakpoint };
|
||||
export type XHRBreakpointsList = $ReadOnlyArray<XHRBreakpoint>;
|
||||
|
@ -59,66 +58,14 @@ function update(
|
|||
action: Action
|
||||
): BreakpointsState {
|
||||
switch (action.type) {
|
||||
case "UPDATE_BREAKPOINT_TEXT": {
|
||||
return updateBreakpointText(state, action.source);
|
||||
}
|
||||
|
||||
case "ADD_SOURCES": {
|
||||
const { sources } = action;
|
||||
|
||||
const scriptSources = sources.filter(source => isInlineScript(source));
|
||||
|
||||
if (scriptSources.length > 0) {
|
||||
const { ...breakpointPositions } = state.breakpointPositions;
|
||||
|
||||
// If new HTML sources are being added, we need to clear the breakpoint
|
||||
// positions since the new source is a <script> with new breakpoints.
|
||||
for (const source of scriptSources) {
|
||||
delete breakpointPositions[source.id];
|
||||
}
|
||||
|
||||
state = { ...state, breakpointPositions };
|
||||
}
|
||||
|
||||
return state;
|
||||
}
|
||||
|
||||
case "ADD_BREAKPOINT": {
|
||||
return addBreakpoint(state, action);
|
||||
}
|
||||
|
||||
case "SYNC_BREAKPOINT": {
|
||||
return syncBreakpoint(state, action);
|
||||
}
|
||||
|
||||
case "ENABLE_BREAKPOINT": {
|
||||
return addBreakpoint(state, action);
|
||||
}
|
||||
|
||||
case "DISABLE_BREAKPOINT": {
|
||||
return updateBreakpoint(state, action);
|
||||
}
|
||||
|
||||
case "DISABLE_ALL_BREAKPOINTS": {
|
||||
return updateAllBreakpoints(state, action);
|
||||
}
|
||||
|
||||
case "ENABLE_ALL_BREAKPOINTS": {
|
||||
return updateAllBreakpoints(state, action);
|
||||
}
|
||||
|
||||
case "SET_BREAKPOINT_OPTIONS": {
|
||||
return updateBreakpoint(state, action);
|
||||
case "SET_BREAKPOINT": {
|
||||
return setBreakpoint(state, action);
|
||||
}
|
||||
|
||||
case "REMOVE_BREAKPOINT": {
|
||||
return removeBreakpoint(state, action);
|
||||
}
|
||||
|
||||
case "REMAP_BREAKPOINTS": {
|
||||
return remapBreakpoints(state, action);
|
||||
}
|
||||
|
||||
case "NAVIGATE": {
|
||||
return initialBreakpointsState(state.xhrBreakpoints);
|
||||
}
|
||||
|
@ -159,55 +106,28 @@ function update(
|
|||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
return state;
|
||||
}
|
||||
case "ADD_SOURCES": {
|
||||
const { sources } = action;
|
||||
|
||||
function updateBreakpointText(
|
||||
state: BreakpointsState,
|
||||
source: Source
|
||||
): BreakpointsState {
|
||||
const updates = [];
|
||||
for (const id of Object.keys(state.breakpoints)) {
|
||||
const breakpoint = state.breakpoints[id];
|
||||
const { location, generatedLocation } = breakpoint;
|
||||
let { text, originalText } = breakpoint;
|
||||
let needsUpdate = false;
|
||||
const scriptSources = sources.filter(source => isInlineScript(source));
|
||||
|
||||
if (location.sourceId === source.id) {
|
||||
const result = getTextAtPosition(source, location);
|
||||
if (result !== originalText) {
|
||||
originalText = result;
|
||||
needsUpdate = true;
|
||||
if (scriptSources.length > 0) {
|
||||
const { ...breakpointPositions } = state.breakpointPositions;
|
||||
|
||||
// If new HTML sources are being added, we need to clear the breakpoint
|
||||
// positions since the new source is a <script> with new breakpoints.
|
||||
for (const source of scriptSources) {
|
||||
delete breakpointPositions[source.id];
|
||||
}
|
||||
|
||||
state = { ...state, breakpointPositions };
|
||||
}
|
||||
}
|
||||
if (generatedLocation.sourceId === source.id) {
|
||||
const result = getTextAtPosition(source, generatedLocation);
|
||||
if (result !== text) {
|
||||
text = result;
|
||||
needsUpdate = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (needsUpdate) {
|
||||
updates.push({ id, text, originalText });
|
||||
return state;
|
||||
}
|
||||
}
|
||||
|
||||
if (updates.length > 0) {
|
||||
const { ...breakpoints } = state.breakpoints;
|
||||
|
||||
for (const { id, text, originalText } of updates) {
|
||||
breakpoints[id] = { ...breakpoints[id], text, originalText };
|
||||
}
|
||||
|
||||
state = {
|
||||
...state,
|
||||
breakpoints
|
||||
};
|
||||
}
|
||||
|
||||
return state;
|
||||
}
|
||||
|
||||
|
@ -262,98 +182,17 @@ function updateXHRBreakpoint(state, action) {
|
|||
};
|
||||
}
|
||||
|
||||
function setBreakpoint(state, locationId, breakpoint) {
|
||||
return {
|
||||
...state,
|
||||
breakpoints: { ...state.breakpoints, [locationId]: breakpoint }
|
||||
};
|
||||
}
|
||||
|
||||
function unsetBreakpoint(state, locationId) {
|
||||
const breakpoints = { ...state.breakpoints };
|
||||
delete breakpoints[locationId];
|
||||
return {
|
||||
...state,
|
||||
breakpoints: { ...breakpoints }
|
||||
};
|
||||
}
|
||||
|
||||
function addBreakpoint(state, action): BreakpointsState {
|
||||
if (action.status === "start" && action.breakpoint) {
|
||||
const { breakpoint } = action;
|
||||
const locationId = makeBreakpointId(breakpoint.location);
|
||||
return setBreakpoint(state, locationId, breakpoint);
|
||||
}
|
||||
|
||||
// when the action completes, we can commit the breakpoint
|
||||
if (action.status === "done") {
|
||||
const { value } = ((action: any): DonePromiseAction);
|
||||
return syncBreakpoint(state, { breakpoint: value, previousLocation: null });
|
||||
}
|
||||
|
||||
// Remove the optimistic update
|
||||
if (action.status === "error" && action.breakpoint) {
|
||||
const locationId = makeBreakpointId(action.breakpoint.location);
|
||||
return unsetBreakpoint(state, locationId);
|
||||
}
|
||||
|
||||
return state;
|
||||
}
|
||||
|
||||
function syncBreakpoint(state, data): BreakpointsState {
|
||||
const { breakpoint, previousLocation } = data;
|
||||
|
||||
if (previousLocation) {
|
||||
state = {
|
||||
...state,
|
||||
breakpoints: { ...state.breakpoints }
|
||||
};
|
||||
delete state.breakpoints[makeBreakpointId(previousLocation)];
|
||||
}
|
||||
|
||||
if (!breakpoint) {
|
||||
return state;
|
||||
}
|
||||
|
||||
const locationId = makeBreakpointId(breakpoint.location);
|
||||
return setBreakpoint(state, locationId, breakpoint);
|
||||
}
|
||||
|
||||
function updateBreakpoint(state, action): BreakpointsState {
|
||||
const { breakpoint } = action;
|
||||
const locationId = makeBreakpointId(breakpoint.location);
|
||||
return setBreakpoint(state, locationId, breakpoint);
|
||||
}
|
||||
|
||||
function updateAllBreakpoints(state, action): BreakpointsState {
|
||||
const { breakpoints } = action;
|
||||
state = {
|
||||
...state,
|
||||
breakpoints: { ...state.breakpoints }
|
||||
};
|
||||
breakpoints.forEach(breakpoint => {
|
||||
const locationId = makeBreakpointId(breakpoint.location);
|
||||
state.breakpoints[locationId] = breakpoint;
|
||||
});
|
||||
return state;
|
||||
}
|
||||
|
||||
function remapBreakpoints(state, action): BreakpointsState {
|
||||
const breakpoints = action.breakpoints.reduce(
|
||||
(updatedBreakpoints, breakpoint) => {
|
||||
const locationId = makeBreakpointId(breakpoint.location);
|
||||
return { ...updatedBreakpoints, [locationId]: breakpoint };
|
||||
},
|
||||
{}
|
||||
);
|
||||
|
||||
function setBreakpoint(state, { breakpoint }): BreakpointsState {
|
||||
const id = makeBreakpointId(breakpoint.location);
|
||||
const breakpoints = { ...state.breakpoints, [id]: breakpoint };
|
||||
return { ...state, breakpoints };
|
||||
}
|
||||
|
||||
function removeBreakpoint(state, action): BreakpointsState {
|
||||
const { breakpoint } = action;
|
||||
const id = makeBreakpointId(breakpoint.location);
|
||||
return unsetBreakpoint(state, id);
|
||||
function removeBreakpoint(state, { location }): BreakpointsState {
|
||||
const id = makeBreakpointId(location);
|
||||
const breakpoints = { ...state.breakpoints };
|
||||
delete breakpoints[id];
|
||||
return { ...state, breakpoints };
|
||||
}
|
||||
|
||||
function isMatchingLocation(location1, location2) {
|
||||
|
|
|
@ -19,73 +19,24 @@ import { isGenerated } from "../utils/source";
|
|||
|
||||
import type { SourcesState } from "./sources";
|
||||
import type { PendingBreakpoint, Source } from "../types";
|
||||
import type { Action, DonePromiseAction } from "../actions/types";
|
||||
import type { Action } from "../actions/types";
|
||||
|
||||
export type PendingBreakpointsState = { [string]: PendingBreakpoint };
|
||||
|
||||
function update(state: PendingBreakpointsState = {}, action: Action) {
|
||||
switch (action.type) {
|
||||
case "ADD_BREAKPOINT": {
|
||||
return addBreakpoint(state, action);
|
||||
}
|
||||
case "SET_BREAKPOINT":
|
||||
return setBreakpoint(state, action);
|
||||
|
||||
case "SYNC_BREAKPOINT": {
|
||||
return syncBreakpoint(state, action);
|
||||
}
|
||||
|
||||
case "ENABLE_BREAKPOINT": {
|
||||
return addBreakpoint(state, action);
|
||||
}
|
||||
|
||||
case "DISABLE_BREAKPOINT": {
|
||||
return updateBreakpoint(state, action);
|
||||
}
|
||||
|
||||
case "DISABLE_ALL_BREAKPOINTS": {
|
||||
return updateAllBreakpoints(state, action);
|
||||
}
|
||||
|
||||
case "ENABLE_ALL_BREAKPOINTS": {
|
||||
return updateAllBreakpoints(state, action);
|
||||
}
|
||||
|
||||
case "SET_BREAKPOINT_OPTIONS": {
|
||||
return updateBreakpoint(state, action);
|
||||
}
|
||||
|
||||
case "REMOVE_BREAKPOINT": {
|
||||
if (action.breakpoint.options.hidden) {
|
||||
return state;
|
||||
}
|
||||
case "REMOVE_BREAKPOINT":
|
||||
return removeBreakpoint(state, action);
|
||||
}
|
||||
}
|
||||
|
||||
return state;
|
||||
}
|
||||
|
||||
function addBreakpoint(state, action) {
|
||||
if (action.breakpoint.options.hidden || action.status !== "done") {
|
||||
return state;
|
||||
}
|
||||
// when the action completes, we can commit the breakpoint
|
||||
const breakpoint = ((action: any): DonePromiseAction).value;
|
||||
|
||||
const locationId = makePendingLocationId(breakpoint.location);
|
||||
const pendingBreakpoint = createPendingBreakpoint(breakpoint);
|
||||
|
||||
return { ...state, [locationId]: pendingBreakpoint };
|
||||
}
|
||||
|
||||
function syncBreakpoint(state, action) {
|
||||
const { breakpoint, previousLocation } = action;
|
||||
|
||||
if (previousLocation) {
|
||||
const previousLocationId = makePendingLocationId(previousLocation);
|
||||
state = deleteBreakpoint(state, previousLocationId);
|
||||
}
|
||||
|
||||
if (!breakpoint) {
|
||||
function setBreakpoint(state, { breakpoint }) {
|
||||
if (breakpoint.options.hidden) {
|
||||
return state;
|
||||
}
|
||||
|
||||
|
@ -95,39 +46,9 @@ function syncBreakpoint(state, action) {
|
|||
return { ...state, [locationId]: pendingBreakpoint };
|
||||
}
|
||||
|
||||
function updateBreakpoint(state, action) {
|
||||
const { breakpoint } = action;
|
||||
const locationId = makePendingLocationId(breakpoint.location);
|
||||
const pendingBreakpoint = createPendingBreakpoint(breakpoint);
|
||||
function removeBreakpoint(state, { location }) {
|
||||
const locationId = makePendingLocationId(location);
|
||||
|
||||
return { ...state, [locationId]: pendingBreakpoint };
|
||||
}
|
||||
|
||||
function updateAllBreakpoints(state, action) {
|
||||
const { breakpoints } = action;
|
||||
breakpoints.forEach(breakpoint => {
|
||||
const locationId = makePendingLocationId(breakpoint.location);
|
||||
const pendingBreakpoint = createPendingBreakpoint(breakpoint);
|
||||
|
||||
state = { ...state, [locationId]: pendingBreakpoint };
|
||||
});
|
||||
return state;
|
||||
}
|
||||
|
||||
function removeBreakpoint(state, action) {
|
||||
const { breakpoint } = action;
|
||||
|
||||
const locationId = makePendingLocationId(breakpoint.location);
|
||||
const pendingBp = state[locationId];
|
||||
|
||||
if (!pendingBp && action.status == "start") {
|
||||
return {};
|
||||
}
|
||||
|
||||
return deleteBreakpoint(state, locationId);
|
||||
}
|
||||
|
||||
function deleteBreakpoint(state, locationId) {
|
||||
state = { ...state };
|
||||
delete state[locationId];
|
||||
return state;
|
||||
|
|
|
@ -12,8 +12,7 @@ import {
|
|||
initialBreakpointsState
|
||||
} from "../breakpoints";
|
||||
|
||||
import { createBreakpoint } from "../../utils/breakpoint";
|
||||
import { makeMappedLocation } from "../../utils/test-mockup";
|
||||
import { makeMockBreakpoint, makeMockSource } from "../../utils/test-mockup";
|
||||
|
||||
function initializeStateWith(data) {
|
||||
const state = initialBreakpointsState();
|
||||
|
@ -25,17 +24,11 @@ describe("Breakpoints Selectors", () => {
|
|||
it("it gets a breakpoint for an original source", () => {
|
||||
const sourceId = "server1.conn1.child1/source1/originalSource";
|
||||
const matchingBreakpoints = {
|
||||
id1: createBreakpoint(
|
||||
makeMappedLocation({ line: 1, sourceId: sourceId }),
|
||||
{ options: {} }
|
||||
)
|
||||
id1: makeMockBreakpoint(makeMockSource(undefined, sourceId), 1)
|
||||
};
|
||||
|
||||
const otherBreakpoints = {
|
||||
id2: createBreakpoint(
|
||||
makeMappedLocation({ line: 1, sourceId: "not-this-source" }),
|
||||
{ options: {} }
|
||||
)
|
||||
id2: makeMockBreakpoint(makeMockSource(undefined, "not-this-source"), 1)
|
||||
};
|
||||
|
||||
const data = {
|
||||
|
@ -57,27 +50,17 @@ describe("Breakpoints Selectors", () => {
|
|||
it("it gets a breakpoint for a generated source", () => {
|
||||
const generatedSourceId = "random-source";
|
||||
const matchingBreakpoints = {
|
||||
id1: createBreakpoint(
|
||||
makeMappedLocation(
|
||||
{ line: 1, sourceId: "original-source-id-1" },
|
||||
{ line: 1, sourceId: generatedSourceId }
|
||||
),
|
||||
{
|
||||
options: {}
|
||||
}
|
||||
)
|
||||
id1: {
|
||||
...makeMockBreakpoint(makeMockSource(undefined, generatedSourceId), 1),
|
||||
location: { line: 1, sourceId: "original-source-id-1" }
|
||||
}
|
||||
};
|
||||
|
||||
const otherBreakpoints = {
|
||||
id2: createBreakpoint(
|
||||
makeMappedLocation(
|
||||
{ line: 1, sourceId: "original-source-id-2" },
|
||||
{ line: 1, sourceId: "not-this-source" }
|
||||
),
|
||||
{
|
||||
options: {}
|
||||
}
|
||||
)
|
||||
id2: {
|
||||
...makeMockBreakpoint(makeMockSource(undefined, "not-this-source"), 1),
|
||||
location: { line: 1, sourceId: "original-source-id-2" }
|
||||
}
|
||||
};
|
||||
|
||||
const data = {
|
||||
|
|
|
@ -21,8 +21,7 @@ import type {
|
|||
PendingLocation,
|
||||
Breakpoint,
|
||||
BreakpointLocation,
|
||||
PendingBreakpoint,
|
||||
MappedLocation
|
||||
PendingBreakpoint
|
||||
} from "../../types";
|
||||
|
||||
import type { State } from "../../reducers/types";
|
||||
|
@ -153,34 +152,6 @@ export function breakpointExists(state: State, location: SourceLocation) {
|
|||
return currentBp && !currentBp.disabled;
|
||||
}
|
||||
|
||||
export function createBreakpoint(
|
||||
mappedLocation: MappedLocation,
|
||||
overrides: Object = {}
|
||||
): Breakpoint {
|
||||
const { disabled, astLocation, text, originalText, options } = overrides;
|
||||
|
||||
const defaultASTLocation = {
|
||||
name: undefined,
|
||||
offset: mappedLocation.location,
|
||||
index: 0
|
||||
};
|
||||
const properties = {
|
||||
id: makeBreakpointId(mappedLocation.location),
|
||||
...mappedLocation,
|
||||
options: {
|
||||
condition: options.condition || null,
|
||||
logValue: options.logValue || null,
|
||||
hidden: options.hidden || false
|
||||
},
|
||||
disabled: disabled || false,
|
||||
astLocation: astLocation || defaultASTLocation,
|
||||
text,
|
||||
originalText
|
||||
};
|
||||
|
||||
return properties;
|
||||
}
|
||||
|
||||
export function createXHRBreakpoint(
|
||||
path: string,
|
||||
method: string,
|
||||
|
|
|
@ -22,7 +22,6 @@ import type {
|
|||
WasmSource,
|
||||
Source,
|
||||
SourceId,
|
||||
SourceLocation,
|
||||
Why
|
||||
} from "../types";
|
||||
|
||||
|
@ -155,14 +154,6 @@ function makeMockExpression(value: Object): Expression {
|
|||
};
|
||||
}
|
||||
|
||||
export function makeMappedLocation(
|
||||
location: SourceLocation,
|
||||
generatedLocation: ?SourceLocation
|
||||
) {
|
||||
generatedLocation = generatedLocation || location;
|
||||
return { location, generatedLocation };
|
||||
}
|
||||
|
||||
export {
|
||||
makeMockSource,
|
||||
makeMockWasmSource,
|
||||
|
|
|
@ -38,11 +38,11 @@ add_task(async function() {
|
|||
openFirstBreakpointContextMenu(dbg);
|
||||
// select "Disable Others"
|
||||
// FIXME bug 1524374 this waitForDispatch call only sees one dispatch for
|
||||
// DISABLE_BREAKPOINT even though three are triggered, due to the order in
|
||||
// SET_BREAKPOINT even though three are triggered, due to the order in
|
||||
// which promises get resolved. The problem seems to indicate a coverage gap
|
||||
// in waitUntilService(). Workaround this by only waiting for one dispatch,
|
||||
// though this is fragile and could break again in the future.
|
||||
let dispatched = waitForDispatch(dbg, "DISABLE_BREAKPOINT", /* 2*/ 1);
|
||||
let dispatched = waitForDispatch(dbg, "SET_BREAKPOINT", /* 2*/ 1);
|
||||
selectContextMenuItem(dbg, selectors.breakpointContextMenu.disableOthers);
|
||||
await waitForState(dbg, state =>
|
||||
dbg.selectors
|
||||
|
@ -54,7 +54,7 @@ add_task(async function() {
|
|||
|
||||
openFirstBreakpointContextMenu(dbg);
|
||||
// select "Disable All"
|
||||
dispatched = waitForDispatch(dbg, "DISABLE_ALL_BREAKPOINTS");
|
||||
dispatched = waitForDispatch(dbg, "SET_BREAKPOINT");
|
||||
selectContextMenuItem(dbg, selectors.breakpointContextMenu.disableAll);
|
||||
await waitForState(dbg, state =>
|
||||
dbg.selectors.getBreakpointsList(state).every(bp => bp.disabled)
|
||||
|
@ -64,7 +64,7 @@ add_task(async function() {
|
|||
|
||||
openFirstBreakpointContextMenu(dbg);
|
||||
// select "Enable Others"
|
||||
dispatched = waitForDispatch(dbg, "ENABLE_BREAKPOINT", 2);
|
||||
dispatched = waitForDispatch(dbg, "SET_BREAKPOINT", 2);
|
||||
selectContextMenuItem(dbg, selectors.breakpointContextMenu.enableOthers);
|
||||
await waitForState(dbg, state =>
|
||||
dbg.selectors
|
||||
|
|
|
@ -113,7 +113,7 @@ add_task(async function() {
|
|||
await waitForSelectedSource(dbg, "simple2");
|
||||
|
||||
await setConditionalBreakpoint(dbg, 5, "1");
|
||||
await waitForDispatch(dbg, "ADD_BREAKPOINT");
|
||||
await waitForDispatch(dbg, "SET_BREAKPOINT");
|
||||
await waitForBreakpointWithCondition(dbg, "simple2", 5);
|
||||
|
||||
let bp = findBreakpoint(dbg, "simple2", 5);
|
||||
|
@ -136,7 +136,7 @@ add_task(async function() {
|
|||
|
||||
info("Adding a condition to a breakpoint");
|
||||
clickElement(dbg, "gutter", 5);
|
||||
await waitForDispatch(dbg, "ADD_BREAKPOINT");
|
||||
await waitForDispatch(dbg, "SET_BREAKPOINT");
|
||||
await setConditionalBreakpoint(dbg, 5, "1");
|
||||
await waitForBreakpointWithCondition(dbg, "simple2", 5);
|
||||
|
||||
|
|
|
@ -17,7 +17,7 @@ function getLineEl(dbg, line) {
|
|||
|
||||
function addBreakpoint(dbg, line) {
|
||||
clickGutter(dbg, line);
|
||||
return waitForDispatch(dbg, "ADD_BREAKPOINT");
|
||||
return waitForDispatch(dbg, "SET_BREAKPOINT");
|
||||
}
|
||||
|
||||
function assertEditorBreakpoint(dbg, line) {
|
||||
|
@ -34,7 +34,7 @@ add_task(async function() {
|
|||
await addBreakpoint(dbg, 5);
|
||||
await addBreakpoint(dbg, 4);
|
||||
|
||||
const syncedBps = waitForDispatch(dbg, "SYNC_BREAKPOINT", 2);
|
||||
const syncedBps = waitForDispatch(dbg, "SET_BREAKPOINT", 2);
|
||||
await reload(dbg, "simple1");
|
||||
await waitForSelectedSource(dbg, "simple1");
|
||||
await syncedBps;
|
||||
|
|
|
@ -9,13 +9,13 @@ function toggleBreakpoint(dbg, index) {
|
|||
}
|
||||
|
||||
async function disableBreakpoint(dbg, index) {
|
||||
const disabled = waitForDispatch(dbg, "DISABLE_BREAKPOINT");
|
||||
const disabled = waitForDispatch(dbg, "SET_BREAKPOINT");
|
||||
toggleBreakpoint(dbg, index);
|
||||
await disabled;
|
||||
}
|
||||
|
||||
async function enableBreakpoint(dbg, index) {
|
||||
const enabled = waitForDispatch(dbg, "ENABLE_BREAKPOINT");
|
||||
const enabled = waitForDispatch(dbg, "SET_BREAKPOINT");
|
||||
toggleBreakpoint(dbg, index);
|
||||
await enabled;
|
||||
}
|
||||
|
@ -54,7 +54,7 @@ add_task(async function() {
|
|||
assertBreakpointSnippet(dbg, 3, "return x + y;");
|
||||
|
||||
rightClickElement(dbg, "breakpointItem", 3);
|
||||
const disableBreakpointDispatch = waitForDispatch(dbg, "DISABLE_BREAKPOINT");
|
||||
const disableBreakpointDispatch = waitForDispatch(dbg, "SET_BREAKPOINT");
|
||||
selectContextMenuItem(dbg, selectors.breakpointContextMenu.disableSelf);
|
||||
await disableBreakpointDispatch;
|
||||
|
||||
|
@ -64,7 +64,7 @@ add_task(async function() {
|
|||
is(bp2.disabled, false, "second breakpoint is enabled");
|
||||
|
||||
rightClickElement(dbg, "breakpointItem", 3);
|
||||
const enableBreakpointDispatch = waitForDispatch(dbg, "ENABLE_BREAKPOINT");
|
||||
const enableBreakpointDispatch = waitForDispatch(dbg, "SET_BREAKPOINT");
|
||||
selectContextMenuItem(dbg, selectors.breakpointContextMenu.enableSelf);
|
||||
await enableBreakpointDispatch;
|
||||
|
||||
|
|
|
@ -20,13 +20,13 @@ function toggleBreakpoint(dbg, index) {
|
|||
}
|
||||
|
||||
async function disableBreakpoint(dbg, index) {
|
||||
const disabled = waitForDispatch(dbg, "DISABLE_BREAKPOINT");
|
||||
const disabled = waitForDispatch(dbg, "SET_BREAKPOINT");
|
||||
toggleBreakpoint(dbg, index);
|
||||
await disabled;
|
||||
}
|
||||
|
||||
async function enableBreakpoint(dbg, index) {
|
||||
const enabled = waitForDispatch(dbg, "ENABLE_BREAKPOINT");
|
||||
const enabled = waitForDispatch(dbg, "SET_BREAKPOINT");
|
||||
toggleBreakpoint(dbg, index);
|
||||
await enabled;
|
||||
}
|
||||
|
|
|
@ -26,7 +26,7 @@ add_task(async function() {
|
|||
|
||||
// Make sure that clicking the gutter creates a breakpoint icon.
|
||||
clickGutter(dbg, 4);
|
||||
await waitForDispatch(dbg, "ADD_BREAKPOINT");
|
||||
await waitForDispatch(dbg, "SET_BREAKPOINT");
|
||||
is(dbg.selectors.getBreakpointCount(getState()), 1, "One breakpoint exists");
|
||||
await assertEditorBreakpoint(dbg, 4, true);
|
||||
|
||||
|
|
|
@ -39,7 +39,7 @@ add_task(async function() {
|
|||
is(breakpoint.location.line, 6);
|
||||
|
||||
info("Reload with a new version of the file");
|
||||
let syncBp = waitForDispatch(dbg, "SYNC_BREAKPOINT");
|
||||
let syncBp = waitForDispatch(dbg, "SET_BREAKPOINT");
|
||||
await navigate(dbg, "doc-sourcemaps-reload2.html", "v1.js");
|
||||
|
||||
await syncBp;
|
||||
|
@ -55,10 +55,12 @@ add_task(async function() {
|
|||
// NOTE: When we reload, the `foo` function and the
|
||||
// module is no longer 13 lines long
|
||||
info("Reload and observe no breakpoints");
|
||||
syncBp = waitForDispatch(dbg, "SYNC_BREAKPOINT", 2);
|
||||
await navigate(dbg, "doc-sourcemaps-reload3.html", "v1.js");
|
||||
await waitForSource(dbg, "v1");
|
||||
await syncBp;
|
||||
|
||||
// There will initially be zero breakpoints, but wait to make sure none are
|
||||
// installed while syncing.
|
||||
await waitForTime(1000);
|
||||
|
||||
is(getBreakpointCount(dbg), 0, "No breakpoints");
|
||||
});
|
||||
|
|
|
@ -40,6 +40,14 @@ async function clickGutter(dbg, line) {
|
|||
clickDOMElement(dbg, el);
|
||||
}
|
||||
|
||||
async function waitForBreakpointCount(dbg, count) {
|
||||
const {
|
||||
selectors: { getBreakpointCount },
|
||||
getState
|
||||
} = dbg;
|
||||
await waitForState(dbg, state => getBreakpointCount(getState()) == count);
|
||||
}
|
||||
|
||||
add_task(async function() {
|
||||
// NOTE: the CORS call makes the test run times inconsistent
|
||||
const dbg = await initDebugger(
|
||||
|
@ -61,11 +69,11 @@ add_task(async function() {
|
|||
await selectSource(dbg, bundleSrc);
|
||||
|
||||
await clickGutter(dbg, 70);
|
||||
await waitForDispatch(dbg, "ADD_BREAKPOINT");
|
||||
await waitForBreakpointCount(dbg, 1);
|
||||
await assertEditorBreakpoint(dbg, 70, true);
|
||||
|
||||
await clickGutter(dbg, 70);
|
||||
await waitForDispatch(dbg, "REMOVE_BREAKPOINT");
|
||||
await waitForBreakpointCount(dbg, 0);
|
||||
is(dbg.selectors.getBreakpointCount(getState()), 0, "No breakpoints exists");
|
||||
|
||||
const entrySrc = findSource(dbg, "entry.js");
|
||||
|
|
|
@ -777,8 +777,7 @@ async function addBreakpoint(dbg, source, line, column, options) {
|
|||
source = findSource(dbg, source);
|
||||
const sourceId = source.id;
|
||||
const bpCount = dbg.selectors.getBreakpointCount(dbg.getState());
|
||||
dbg.actions.addBreakpoint({ sourceId, line, column }, options);
|
||||
await waitForDispatch(dbg, "ADD_BREAKPOINT");
|
||||
await dbg.actions.addBreakpoint({ sourceId, line, column }, options);
|
||||
is(
|
||||
dbg.selectors.getBreakpointCount(dbg.getState()),
|
||||
bpCount + 1,
|
||||
|
@ -791,16 +790,14 @@ function disableBreakpoint(dbg, source, line, column) {
|
|||
column || getFirstBreakpointColumn(dbg, { line, sourceId: source.id });
|
||||
const location = { sourceId: source.id, sourceUrl: source.url, line, column };
|
||||
const bp = dbg.selectors.getBreakpointForLocation(dbg.getState(), location);
|
||||
dbg.actions.disableBreakpoint(bp);
|
||||
return waitForDispatch(dbg, "DISABLE_BREAKPOINT");
|
||||
return dbg.actions.disableBreakpoint(bp);
|
||||
}
|
||||
|
||||
function setBreakpointOptions(dbg, source, line, column, options) {
|
||||
source = findSource(dbg, source);
|
||||
const sourceId = source.id;
|
||||
column = column || getFirstBreakpointColumn(dbg, {line, sourceId});
|
||||
dbg.actions.setBreakpointOptions({ sourceId, line, column }, options);
|
||||
return waitForDispatch(dbg, "SET_BREAKPOINT_OPTIONS");
|
||||
return dbg.actions.setBreakpointOptions({ sourceId, line, column }, options);
|
||||
}
|
||||
|
||||
function findBreakpoint(dbg, url, line) {
|
||||
|
@ -938,8 +935,7 @@ function removeBreakpoint(dbg, sourceId, line, column) {
|
|||
column = column || getFirstBreakpointColumn(dbg, {line, sourceId});
|
||||
const location = { sourceId, sourceUrl: source.url, line, column };
|
||||
const bp = dbg.selectors.getBreakpointForLocation(dbg.getState(), location);
|
||||
dbg.actions.removeBreakpoint(bp);
|
||||
return waitForDispatch(dbg, "REMOVE_BREAKPOINT");
|
||||
return dbg.actions.removeBreakpoint(bp);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -62,37 +62,16 @@ struct DevTools : public ::testing::Test {
|
|||
}
|
||||
|
||||
static const JSClass* getGlobalClass() {
|
||||
static const JSClassOps globalClassOps = {nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
JS_GlobalObjectTraceHook};
|
||||
static const JSClass globalClass = {"global", JSCLASS_GLOBAL_FLAGS,
|
||||
&globalClassOps};
|
||||
&JS::DefaultGlobalClassOps};
|
||||
return &globalClass;
|
||||
}
|
||||
|
||||
JSObject* createGlobal() {
|
||||
/* Create the global object. */
|
||||
JS::RootedObject newGlobal(cx);
|
||||
JS::RealmOptions options;
|
||||
newGlobal = JS_NewGlobalObject(cx, getGlobalClass(), nullptr,
|
||||
JS::FireOnNewGlobalHook, options);
|
||||
if (!newGlobal) return nullptr;
|
||||
|
||||
JSAutoRealm ar(cx, newGlobal);
|
||||
|
||||
/* Populate the global object with the standard globals, like Object and
|
||||
Array. */
|
||||
if (!JS::InitRealmStandardClasses(cx)) return nullptr;
|
||||
|
||||
return newGlobal;
|
||||
return JS_NewGlobalObject(cx, getGlobalClass(), nullptr,
|
||||
JS::FireOnNewGlobalHook, options);
|
||||
}
|
||||
|
||||
virtual void TearDown() {
|
||||
|
|
|
@ -1048,7 +1048,7 @@ FetchDriver::OnStartRequest(nsIRequest* aRequest) {
|
|||
// Fail to generate a paddingInfo for opaque response.
|
||||
MOZ_DIAGNOSTIC_ASSERT(mResponse->Type() == ResponseType::Opaque);
|
||||
FailWithNetworkError(NS_ERROR_UNEXPECTED);
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
return rv;
|
||||
}
|
||||
|
||||
// From "Main Fetch" step 19: SRI-part1.
|
||||
|
|
|
@ -11,7 +11,6 @@
|
|||
#include "mozilla/dom/cache/CacheTypes.h"
|
||||
#include "mozilla/ipc/PBackgroundSharedTypes.h"
|
||||
#include "mozilla/ipc/IPCStreamUtils.h"
|
||||
#include "mozilla/RandomNum.h"
|
||||
#include "nsIRandomGenerator.h"
|
||||
#include "nsIURI.h"
|
||||
#include "nsStreamUtils.h"
|
||||
|
@ -123,11 +122,6 @@ nsresult InternalResponse::GeneratePaddingInfo() {
|
|||
nsCOMPtr<nsIRandomGenerator> randomGenerator =
|
||||
do_GetService("@mozilla.org/security/random-generator;1", &rv);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
Maybe<uint64_t> maybeRandomNum = RandomUint64();
|
||||
if (maybeRandomNum.isSome()) {
|
||||
mPaddingInfo.emplace(uint32_t(maybeRandomNum.value() % kMaxRandomNumber));
|
||||
return NS_OK;
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
@ -136,11 +130,6 @@ nsresult InternalResponse::GeneratePaddingInfo() {
|
|||
uint8_t* buffer;
|
||||
rv = randomGenerator->GenerateRandomBytes(sizeof(randomNumber), &buffer);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
Maybe<uint64_t> maybeRandomNum = RandomUint64();
|
||||
if (maybeRandomNum.isSome()) {
|
||||
mPaddingInfo.emplace(uint32_t(maybeRandomNum.value() % kMaxRandomNumber));
|
||||
return NS_OK;
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
|
|
@ -23,45 +23,21 @@ JS::PersistentRootedObject gGlobal;
|
|||
JSContext* gCx = nullptr;
|
||||
|
||||
static const JSClass* getGlobalClass() {
|
||||
static const JSClassOps cOps = {nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
JS_GlobalObjectTraceHook};
|
||||
static const JSClass c = {"global", JSCLASS_GLOBAL_FLAGS, &cOps};
|
||||
static const JSClass c = {"global", JSCLASS_GLOBAL_FLAGS,
|
||||
&JS::DefaultGlobalClassOps};
|
||||
return &c;
|
||||
}
|
||||
|
||||
static JSObject* jsfuzz_createGlobal(JSContext* cx, JSPrincipals* principals) {
|
||||
/* Create the global object. */
|
||||
JS::RootedObject newGlobal(cx);
|
||||
JS::RealmOptions options;
|
||||
options.creationOptions()
|
||||
.setStreamsEnabled(true)
|
||||
.setBigIntEnabled(true)
|
||||
.setFieldsEnabled(false)
|
||||
.setAwaitFixEnabled(true);
|
||||
newGlobal = JS_NewGlobalObject(cx, getGlobalClass(), principals,
|
||||
JS::FireOnNewGlobalHook, options);
|
||||
if (!newGlobal) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
JSAutoRealm ar(cx, newGlobal);
|
||||
|
||||
// Populate the global object with the standard globals like Object and
|
||||
// Array.
|
||||
if (!JS::InitRealmStandardClasses(cx)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return newGlobal;
|
||||
return JS_NewGlobalObject(cx, getGlobalClass(), principals,
|
||||
JS::FireOnNewGlobalHook, options);
|
||||
}
|
||||
|
||||
static bool jsfuzz_init(JSContext** cx, JS::PersistentRootedObject* global) {
|
||||
|
|
|
@ -13,21 +13,9 @@
|
|||
|
||||
using namespace JS;
|
||||
|
||||
static const JSClassOps global_classOps = {nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
JS_GlobalObjectTraceHook};
|
||||
|
||||
/* The class of the global object. */
|
||||
static const JSClass global_class = {"global", JSCLASS_GLOBAL_FLAGS,
|
||||
&global_classOps};
|
||||
&DefaultGlobalClassOps};
|
||||
|
||||
static volatile int dontOptimizeMeAway = 0;
|
||||
|
||||
|
@ -83,10 +71,6 @@ int main(int argc, const char** argv) {
|
|||
JS::FireOnNewGlobalHook, options)));
|
||||
JSAutoRealm ar(cx, global);
|
||||
|
||||
/* Populate the global object with the standard globals,
|
||||
like Object and Array. */
|
||||
checkBool(JS::InitRealmStandardClasses(cx));
|
||||
|
||||
argv++;
|
||||
while (*argv) {
|
||||
const char* name = *argv++;
|
||||
|
|
|
@ -10,20 +10,9 @@
|
|||
|
||||
static TestJSPrincipals system_principals(1);
|
||||
|
||||
static const JSClassOps global_classOps = {nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
JS_GlobalObjectTraceHook};
|
||||
|
||||
static const JSClass global_class = {
|
||||
"global", JSCLASS_IS_GLOBAL | JSCLASS_GLOBAL_FLAGS, &global_classOps};
|
||||
"global", JSCLASS_IS_GLOBAL | JSCLASS_GLOBAL_FLAGS,
|
||||
&JS::DefaultGlobalClassOps};
|
||||
|
||||
static JS::PersistentRootedObject trusted_glob;
|
||||
static JS::PersistentRootedObject trusted_fun;
|
||||
|
|
|
@ -17,10 +17,6 @@ BEGIN_TEST(testDebugger_newScriptHook) {
|
|||
JS::RootedObject g(cx, JS_NewGlobalObject(cx, getGlobalClass(), nullptr,
|
||||
JS::FireOnNewGlobalHook, options));
|
||||
CHECK(g);
|
||||
{
|
||||
JSAutoRealm ar(cx, g);
|
||||
CHECK(JS::InitRealmStandardClasses(cx));
|
||||
}
|
||||
|
||||
JS::RootedObject gWrapper(cx, g);
|
||||
CHECK(JS_WrapObject(cx, &gWrapper));
|
||||
|
|
|
@ -55,7 +55,6 @@ bool eval(const char* asciiChars, bool mutedErrors,
|
|||
JS::FireOnNewGlobalHook, globalOptions));
|
||||
CHECK(global);
|
||||
JSAutoRealm ar(cx, global);
|
||||
CHECK(JS::InitRealmStandardClasses(cx));
|
||||
|
||||
JS::CompileOptions options(cx);
|
||||
options.setMutedErrors(mutedErrors).setFileAndLine("", 0);
|
||||
|
|
|
@ -8,11 +8,13 @@
|
|||
#include "jsapi-tests/tests.h"
|
||||
|
||||
BEGIN_TEST(testSetProperty_InheritedGlobalSetter) {
|
||||
// This is a JSAPI test because jsapi-test globals do not have a resolve
|
||||
// hook and therefore can use the property cache in some cases where the
|
||||
// shell can't.
|
||||
// This is a JSAPI test because jsapi-test globals can be set up to not have
|
||||
// a resolve hook and therefore can use the property cache in some cases
|
||||
// where the shell can't.
|
||||
MOZ_RELEASE_ASSERT(!JS_GetClass(global)->getResolve());
|
||||
|
||||
CHECK(JS::InitRealmStandardClasses(cx));
|
||||
|
||||
CHECK(JS_DefineProperty(cx, global, "HOTLOOP", 8, 0));
|
||||
EXEC(
|
||||
"var n = 0;\n"
|
||||
|
@ -26,4 +28,24 @@ BEGIN_TEST(testSetProperty_InheritedGlobalSetter) {
|
|||
" throw 'FAIL';\n");
|
||||
return true;
|
||||
}
|
||||
|
||||
const JSClass* getGlobalClass(void) override {
|
||||
static const JSClassOps noResolveGlobalClassOps = {nullptr, // add
|
||||
nullptr, // delete
|
||||
nullptr, // enumerate
|
||||
nullptr, // newEnumerate
|
||||
nullptr, // resolve
|
||||
nullptr, // mayResolve
|
||||
nullptr, // finalize
|
||||
nullptr, // call
|
||||
nullptr, // hasInstance
|
||||
nullptr, // construct
|
||||
JS_GlobalObjectTraceHook};
|
||||
|
||||
static const JSClass noResolveGlobalClass = {
|
||||
"testSetProperty_InheritedGlobalSetter_noResolveGlobalClass",
|
||||
JSCLASS_GLOBAL_FLAGS, &noResolveGlobalClassOps};
|
||||
|
||||
return &noResolveGlobalClass;
|
||||
}
|
||||
END_TEST(testSetProperty_InheritedGlobalSetter)
|
||||
|
|
|
@ -90,14 +90,6 @@ JSObject* JSAPITest::createGlobal(JSPrincipals* principals) {
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
JSAutoRealm ar(cx, newGlobal);
|
||||
|
||||
// Populate the global object with the standard globals like Object and
|
||||
// Array.
|
||||
if (!JS::InitRealmStandardClasses(cx)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
global = newGlobal;
|
||||
return newGlobal;
|
||||
}
|
||||
|
|
|
@ -267,18 +267,8 @@ class JSAPITest {
|
|||
JSAPITestString messages() const { return msgs; }
|
||||
|
||||
static const JSClass* basicGlobalClass() {
|
||||
static const JSClassOps cOps = {nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
JS_GlobalObjectTraceHook};
|
||||
static const JSClass c = {"global", JSCLASS_GLOBAL_FLAGS, &cOps};
|
||||
static const JSClass c = {"global", JSCLASS_GLOBAL_FLAGS,
|
||||
&JS::DefaultGlobalClassOps};
|
||||
return &c;
|
||||
}
|
||||
|
||||
|
|
|
@ -415,21 +415,9 @@ bool js::HasOffThreadIonCompile(Realm* realm) {
|
|||
}
|
||||
#endif
|
||||
|
||||
static const JSClassOps parseTaskGlobalClassOps = {nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
JS_GlobalObjectTraceHook};
|
||||
|
||||
static const JSClass parseTaskGlobalClass = {"internal-parse-task-global",
|
||||
JSCLASS_GLOBAL_FLAGS,
|
||||
&parseTaskGlobalClassOps};
|
||||
&JS::DefaultGlobalClassOps};
|
||||
|
||||
ParseTask::ParseTask(ParseTaskKind kind, JSContext* cx,
|
||||
JS::OffThreadCompileCallback callback, void* callbackData)
|
||||
|
|
|
@ -626,9 +626,6 @@ class JSContextWrapper {
|
|||
|
||||
JSAutoRealm ar(mContext, global);
|
||||
AutoPACErrorReporter aper(mContext);
|
||||
if (!JS::InitRealmStandardClasses(mContext)) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
if (!JS_DefineFunctions(mContext, global, PACGlobalFunctions)) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
@ -639,22 +636,9 @@ class JSContextWrapper {
|
|||
}
|
||||
};
|
||||
|
||||
static const JSClassOps sJSContextWrapperGlobalClassOps = {
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
JS_GlobalObjectTraceHook};
|
||||
|
||||
const JSClass JSContextWrapper::sGlobalClass = {
|
||||
"PACResolutionThreadGlobal", JSCLASS_GLOBAL_FLAGS,
|
||||
&sJSContextWrapperGlobalClassOps};
|
||||
&JS::DefaultGlobalClassOps};
|
||||
|
||||
void ProxyAutoConfig::SetThreadLocalIndex(uint32_t index) {
|
||||
sRunningIndex = index;
|
||||
|
|
|
@ -249,10 +249,7 @@ async function addBreakpoint(dbg, line, url) {
|
|||
};
|
||||
|
||||
await selectSource(dbg, url);
|
||||
|
||||
const onDispatched = waitForDispatch(dbg, "ADD_BREAKPOINT");
|
||||
dbg.actions.addBreakpoint(location);
|
||||
return onDispatched;
|
||||
await dbg.actions.addBreakpoint(location);
|
||||
}
|
||||
exports.addBreakpoint = addBreakpoint;
|
||||
|
||||
|
|
|
@ -78,20 +78,8 @@ static void RunTest(JSContext* cx, ArrayT* array) {
|
|||
}
|
||||
|
||||
static void CreateGlobalAndRunTest(JSContext* cx) {
|
||||
static const JSClassOps GlobalClassOps = {nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
JS_GlobalObjectTraceHook};
|
||||
|
||||
static const JSClass GlobalClass = {"global", JSCLASS_GLOBAL_FLAGS,
|
||||
&GlobalClassOps};
|
||||
&JS::DefaultGlobalClassOps};
|
||||
|
||||
JS::RealmOptions options;
|
||||
JS::PersistentRootedObject global(cx);
|
||||
|
|
Загрузка…
Ссылка в новой задаче