Bug 1633529 - Improve flow coverage of debugger's actions r=loganfsmyth

Differential Revision: https://phabricator.services.mozilla.com/D72734
This commit is contained in:
David Walsh 2020-05-08 18:36:30 +00:00
parent f593e8a09b
commit 623b2f52f6
17 changed files with 79 additions and 46 deletions

View File

@ -19,7 +19,9 @@ import type { AstLocation } from "../../workers/parser";
import type { ThunkArgs } from "../types";
import type { Context, SourceLocation } from "../../types";
function getOutOfScopeLines(outOfScopeLocations: ?(AstLocation[])) {
function getOutOfScopeLines(
outOfScopeLocations: ?(AstLocation[])
): ?(AstLocation[]) {
if (!outOfScopeLocations) {
return null;
}

View File

@ -37,10 +37,14 @@ import { fulfilled } from "../../utils/async-value";
import type { ThunkArgs } from "../../actions/types";
import { loadSourceActorBreakpointColumns } from "../source-actors";
type LocationsList = {
number: ?(number[]),
};
async function mapLocations(
generatedLocations: SourceLocation[],
{ sourceMaps }: ThunkArgs
) {
): Promise<MappedLocation[]> {
if (generatedLocations.length == 0) {
return [];
}
@ -56,18 +60,24 @@ async function mapLocations(
}
// Filter out positions, that are not in the original source Id
function filterBySource(positions: MappedLocation[], sourceId: SourceId) {
function filterBySource(
positions: MappedLocation[],
sourceId: SourceId
): MappedLocation[] {
if (!isOriginalId(sourceId)) {
return positions;
}
return positions.filter(position => position.location.sourceId == sourceId);
}
function filterByUniqLocation(positions: MappedLocation[]) {
function filterByUniqLocation(positions: MappedLocation[]): MappedLocation[] {
return uniqBy(positions, ({ location }) => makeBreakpointId(location));
}
function convertToList(results, source: Source) {
function convertToList(
results: LocationsList,
source: Source
): SourceLocation[] {
const { id, url } = source;
const positions = [];
@ -112,7 +122,7 @@ async function _setBreakpointPositions(
sourceId: SourceId,
line,
thunkArgs: ThunkArgs
) {
): Promise<void> {
const { client, dispatch, getState, sourceMaps } = thunkArgs;
let generatedSource = getSource(getState(), sourceId);
if (!generatedSource) {
@ -199,7 +209,7 @@ async function _setBreakpointPositions(
});
}
function generatedSourceActorKey(state, sourceId: SourceId) {
function generatedSourceActorKey(state, sourceId: SourceId): string {
const generatedSource = getSource(
state,
isOriginalId(sourceId) ? originalToGeneratedId(sourceId) : sourceId

View File

@ -37,6 +37,7 @@ import type {
SourceLocation,
Context,
} from "../../types";
import type { State } from "../../reducers/types";
// This file has the primitive operations used to modify individual breakpoints
// and keep them in sync with the breakpoints installed on server threads. These
@ -62,7 +63,7 @@ import type {
// breakpoint will be added to the reducer, to restore the above invariant.
// See syncBreakpoint.js for more.
function clientSetBreakpoint(client, state, breakpoint: Breakpoint) {
function clientSetBreakpoint(client, state: State, breakpoint: Breakpoint) {
const breakpointLocation = makeBreakpointLocation(
state,
breakpoint.generatedLocation
@ -72,7 +73,7 @@ function clientSetBreakpoint(client, state, breakpoint: Breakpoint) {
function clientRemoveBreakpoint(
client,
state,
state: State,
generatedLocation: SourceLocation
) {
const breakpointLocation = makeBreakpointLocation(state, generatedLocation);

View File

@ -12,7 +12,7 @@ export default function remapLocations(
breakpoints: Breakpoint[],
sourceId: SourceId,
sourceMaps: SourceMaps
) {
): Promise<Breakpoint[]> {
const sourceBreakpoints: Promise<Breakpoint>[] = breakpoints.map(
async breakpoint => {
if (breakpoint.location.sourceId !== sourceId) {

View File

@ -5,6 +5,7 @@
// @flow
import type { ThunkArgs } from "../types";
import type { PauseAction } from "../types/PauseAction";
import type { ThreadContext } from "../../types";
/**
@ -15,7 +16,7 @@ import type { ThreadContext } from "../../types";
* @memberof actions/pause
* @static
*/
export function breakOnNext(cx: ThreadContext) {
export function breakOnNext(cx: ThreadContext): PauseAction {
return async ({ dispatch, getState, client }: ThunkArgs) => {
await client.breakOnNext(cx.thread);
return dispatch({ type: "BREAK_ON_NEXT", thread: cx.thread });

View File

@ -17,7 +17,7 @@ import type { ThunkArgs } from "../types";
// b is a single position (line and column).
// This function tests to see if the b position
// falls within the range given in a.
function inHouseContainsPosition(a: Object, b: Object) {
function inHouseContainsPosition(a: Object, b: Object): boolean {
const bColumn = b.column || 0;
const startsBefore =
a.start.line < b.line ||

View File

@ -16,10 +16,11 @@ import { validateThreadContext } from "../../utils/context";
import type { OriginalScope } from "../../utils/pause/mapScopes";
import type { ThreadContext, Frame, Scope, Preview } from "../../types";
import type { ThunkArgs } from "../types";
import type { SourceScope } from "../../workers/parser/getScopes";
// We need to display all variables in the current functional scope so
// include all data for block scopes until the first functional scope
function getLocalScopeLevels(originalAstScopes): number {
function getLocalScopeLevels(originalAstScopes: SourceScope[]): number {
let levels = 0;
while (
originalAstScopes[levels] &&

View File

@ -8,10 +8,10 @@ import { getFrames, getSymbols, getSource } from "../../selectors";
import { findClosestFunction } from "../../utils/ast";
import type { ThreadContext } from "../../types";
import type { Frame, ThreadContext } from "../../types";
import type { ThunkArgs } from "../types";
function mapDisplayName(frame, { getState }) {
function mapDisplayName(frame: Frame, { getState }) {
if (frame.isOriginal) {
return frame;
}

View File

@ -8,18 +8,28 @@ import { getFrames, getSource, getSelectedFrame } from "../../selectors";
import assert from "../../utils/assert";
import type { Frame, OriginalFrame, ThreadContext } from "../../types";
import type {
Frame,
FrameId,
OriginalFrame,
ThreadContext,
ThreadId,
} from "../../types";
import type { State } from "../../reducers/types";
import type { ThunkArgs } from "../types";
import SourceMaps, { isGeneratedId } from "devtools-source-map";
function isFrameBlackboxed(state, frame) {
function isFrameBlackboxed(state: State, frame: Frame): boolean {
const source = getSource(state, frame.location.sourceId);
return source?.isBlackBoxed;
return !!source?.isBlackBoxed;
}
function getSelectedFrameId(state, thread, frames) {
function getSelectedFrameId(
state: State,
thread: ThreadId,
frames: Frame[]
): ?FrameId {
let selectedFrame = getSelectedFrame(state, thread);
if (selectedFrame && !isFrameBlackboxed(state, selectedFrame)) {
return selectedFrame.id;
@ -32,7 +42,7 @@ function getSelectedFrameId(state, thread, frames) {
export function updateFrameLocation(
frame: Frame,
sourceMaps: typeof SourceMaps
) {
): Promise<Frame> {
if (frame.isOriginal) {
return Promise.resolve(frame);
}

View File

@ -9,7 +9,10 @@
* @module actions/sources
*/
import { isOriginalId, originalToGeneratedId } from "devtools-source-map";
import SourceMaps, {
isOriginalId,
originalToGeneratedId,
} from "devtools-source-map";
import { recordEvent } from "../../utils/telemetry";
import { features } from "../../utils/prefs";
import { getSourceActorsForSource } from "../../selectors";
@ -18,27 +21,27 @@ import { PROMISE } from "../utils/middleware/promise";
import type { Source, Context, SourceId } from "../../types";
import type { ThunkArgs } from "../types";
import type { State } from "../../reducers/types";
async function blackboxActors(
state,
state: State,
client,
sourceId: SourceId,
isBlackBoxed: boolean,
range?
) {
): Promise<{ isBlackBoxed: boolean }> {
for (const actor of getSourceActorsForSource(state, sourceId)) {
await client.blackBox(actor, isBlackBoxed, range);
}
return { isBlackBoxed: !isBlackBoxed };
}
async function getSourceId(source: Source, sourceMaps) {
let sourceId, range;
async function getSourceId(source: Source, sourceMaps: typeof SourceMaps) {
let sourceId = source.id,
range;
if (features.originalBlackbox && isOriginalId(source.id)) {
range = await sourceMaps.getFileGeneratedRange(source.id);
sourceId = originalToGeneratedId(source.id);
} else {
sourceId = source.id;
}
return { sourceId, range };
}

View File

@ -12,7 +12,7 @@ import type { Context, SourceId } from "../../types";
import type { ThunkArgs } from "../../actions/types";
import { loadSourceActorBreakableLines } from "../source-actors";
function calculateBreakableLines(positions) {
function calculateBreakableLines(positions): number[] {
const lines = [];
for (const line in positions) {
if (positions[line].length > 0) {

View File

@ -30,13 +30,14 @@ import { Telemetry } from "devtools-modules";
import type { ThunkArgs } from "../types";
import type { Source, Context, SourceId } from "../../types";
import type { State } from "../../reducers/types";
// Measures the time it takes for a source to load
const loadSourceHistogram = "DEVTOOLS_DEBUGGER_LOAD_SOURCE_MS";
const telemetry = new Telemetry();
async function loadSource(
state,
state: State,
source: Source,
{ sourceMaps, client, getState }
): Promise<?{

View File

@ -46,12 +46,13 @@ import type {
URL,
} from "../../types";
import type { ThunkArgs } from "../types";
import type { SourceAction } from "../types/SourceAction";
export const setSelectedLocation = (
cx: Context,
source: Source,
location: SourceLocation
) => ({
): SourceAction => ({
type: "SET_SELECTED_LOCATION",
cx,
source,
@ -62,15 +63,15 @@ export const setPendingSelectedLocation = (
cx: Context,
url: URL,
options?: PartialPosition
) => ({
): SourceAction => ({
type: "SET_PENDING_SELECTED_LOCATION",
cx,
url,
line: options ? options.line : null,
column: options ? options.column : null,
line: options?.line,
column: options?.column,
});
export const clearSelectedLocation = (cx: Context) => ({
export const clearSelectedLocation = (cx: Context): SourceAction => ({
type: "CLEAR_SELECTED_LOCATION",
cx,
});

View File

@ -21,7 +21,7 @@ import type { Source, Context } from "../../types";
import type { Symbols } from "../../reducers/types";
async function doSetSymbols(
cx,
cx: Context,
source: Source,
{ dispatch, getState, parser }: ThunkArgs
) {

View File

@ -27,12 +27,15 @@ import type {
OrientationType,
SelectedPrimaryPaneTabType,
} from "../reducers/ui";
import type { UIAction } from "./types/UIAction";
export function setPrimaryPaneTab(tabName: SelectedPrimaryPaneTabType) {
export function setPrimaryPaneTab(
tabName: SelectedPrimaryPaneTabType
): UIAction {
return { type: "SET_PRIMARY_PANE_TAB", tabName };
}
export function closeActiveSearch() {
export function closeActiveSearch(): UIAction {
return {
type: "TOGGLE_ACTIVE_SEARCH",
value: null,
@ -157,7 +160,7 @@ export function flashLineRange(location: {
* @memberof actions/sources
* @static
*/
export function clearHighlightLineRange() {
export function clearHighlightLineRange(): UIAction {
return {
type: "CLEAR_HIGHLIGHT_LINES",
};
@ -166,7 +169,7 @@ export function clearHighlightLineRange() {
export function openConditionalPanel(
location: ?SourceLocation,
log: boolean = false
) {
): ?UIAction {
if (!location) {
return;
}
@ -178,13 +181,13 @@ export function openConditionalPanel(
};
}
export function closeConditionalPanel() {
export function closeConditionalPanel(): UIAction {
return {
type: "CLOSE_CONDITIONAL_PANEL",
};
}
export function clearProjectDirectoryRoot(cx: Context) {
export function clearProjectDirectoryRoot(cx: Context): UIAction {
return {
type: "SET_PROJECT_DIRECTORY_ROOT",
cx,
@ -224,18 +227,18 @@ export function setProjectDirectoryRoot(cx: Context, newRoot: string) {
};
}
export function updateViewport() {
export function updateViewport(): UIAction {
return {
type: "SET_VIEWPORT",
viewport: getLocationsInViewport(getEditor()),
};
}
export function updateCursorPosition(cursorPosition: SourceLocation) {
export function updateCursorPosition(cursorPosition: SourceLocation): UIAction {
return { type: "SET_CURSOR_POSITION", cursorPosition };
}
export function setOrientation(orientation: OrientationType) {
export function setOrientation(orientation: OrientationType): UIAction {
return { type: "SET_ORIENTATION", orientation };
}

View File

@ -11,7 +11,7 @@ import {
import type { ThunkArgs } from "../../types";
function validateActionContext(getState, action) {
function validateActionContext(getState, action): void {
if (action.type == "COMMAND" && action.status == "done") {
// The thread will have resumed execution since the action was initiated,
// so just make sure we haven't navigated.

View File

@ -408,7 +408,7 @@ async function toggleEventLogging(logEventBreakpoints: boolean) {
);
}
function getAllThreadFronts() {
function getAllThreadFronts(): ThreadFront[] {
const fronts = [currentThreadFront()];
for (const { threadFront } of (Object.values(targets): any)) {
fronts.push(threadFront);