Skip to content
This repository was archived by the owner on Jan 11, 2023. It is now read-only.

Commit caa26e3

Browse files
iocalebsjasonLaster
authored andcommitted
Map frame display names (#5790)
1 parent d77574a commit caa26e3

File tree

7 files changed

+117
-28
lines changed

7 files changed

+117
-28
lines changed

src/actions/ast.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import {
1111
isPaused
1212
} from "../selectors";
1313

14+
import { mapFrames } from "./pause";
1415
import { setInScopeLines } from "./ast/setInScopeLines";
1516
import {
1617
getSymbols,
@@ -59,6 +60,10 @@ export function setSymbols(sourceId: SourceId) {
5960
[PROMISE]: getSymbols(source.id)
6061
});
6162

63+
if (isPaused(getState())) {
64+
await dispatch(mapFrames());
65+
}
66+
6267
await dispatch(setPausePoints(sourceId));
6368
await dispatch(setSourceMetaData(sourceId));
6469
};

src/actions/pause/mapFrames.js

Lines changed: 30 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
// @flow
22

3-
import { getFrames } from "../../selectors";
3+
import { getFrames, getSymbols, getSource } from "../../selectors";
4+
import { findClosestFunction } from "../../utils/ast";
45

56
import type { Frame } from "../../types";
7+
import type { State } from "../../reducers/types";
68
import type { ThunkArgs } from "../types";
79

810
export function updateFrameLocation(frame: Frame, sourceMaps: any) {
@@ -26,12 +28,35 @@ function updateFrameLocations(
2628
);
2729
}
2830

31+
export function mapDisplayNames(frames: Frame[], getState: () => State) {
32+
return frames.map(frame => {
33+
const source = getSource(getState(), frame.location.sourceId);
34+
const symbols = getSymbols(getState(), source);
35+
36+
if (!symbols || !symbols.functions) {
37+
return frame;
38+
}
39+
40+
const originalFunction = findClosestFunction(
41+
symbols.functions,
42+
frame.location
43+
);
44+
45+
if (!originalFunction) {
46+
return frame;
47+
}
48+
49+
const originalDisplayName = originalFunction.name;
50+
return { ...frame, originalDisplayName };
51+
});
52+
}
53+
2954
/**
30-
* Map call stack frame locations to original locations.
55+
* Map call stack frame locations and display names to originals.
3156
* e.g.
3257
* 1. When the debuggee pauses
3358
* 2. When a source is pretty printed
34-
*
59+
* 3. When symbols are loaded
3560
* @memberof actions/pause
3661
* @static
3762
*/
@@ -42,7 +67,8 @@ export function mapFrames() {
4267
return;
4368
}
4469

45-
const mappedFrames = await updateFrameLocations(frames, sourceMaps);
70+
let mappedFrames = await updateFrameLocations(frames, sourceMaps);
71+
mappedFrames = mapDisplayNames(mappedFrames, getState);
4672

4773
dispatch({
4874
type: "MAP_FRAMES",

src/actions/tests/pause.spec.js

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import {
44
createStore,
55
waitForState,
66
makeSource,
7+
makeOriginalSource,
78
makeFrame
89
} from "../../utils/test-head";
910

@@ -42,6 +43,11 @@ const mockThreadClient = {
4243
source: "function foo() {\n return -5;\n}",
4344
contentType: "text/javascript"
4445
});
46+
case "foo-original":
47+
return resolve({
48+
source: "\n\nfunction fooOriginal() {\n return -5;\n}",
49+
contentType: "text/javascript"
50+
});
4551
}
4652
});
4753
}
@@ -145,6 +151,44 @@ describe("pause", () => {
145151
expect(getNextStepSpy).toBeCalled();
146152
getNextStepSpy.mockRestore();
147153
});
154+
155+
describe("pausing in a generated location", () => {
156+
it("maps frame locations and names to original source", async () => {
157+
const generatedLocation = {
158+
sourceId: "foo",
159+
line: 1,
160+
column: 0
161+
};
162+
const originalLocation = {
163+
sourceId: "foo-original",
164+
line: 3,
165+
column: 0
166+
};
167+
const sourceMapsMock = {
168+
getOriginalLocation: () => Promise.resolve(originalLocation)
169+
};
170+
const store = createStore(mockThreadClient, {}, sourceMapsMock);
171+
const { dispatch, getState } = store;
172+
const mockPauseInfo = createPauseInfo(generatedLocation);
173+
174+
await dispatch(actions.newSource(makeSource("foo")));
175+
await dispatch(actions.newSource(makeOriginalSource("foo")));
176+
await dispatch(actions.loadSourceText(I.Map({ id: "foo" })));
177+
await dispatch(actions.loadSourceText(I.Map({ id: "foo-original" })));
178+
await dispatch(actions.setSymbols("foo-original"));
179+
180+
await dispatch(actions.paused(mockPauseInfo));
181+
expect(selectors.getFrames(getState())).toEqual([
182+
{
183+
id: 1,
184+
scope: [],
185+
location: originalLocation,
186+
generatedLocation,
187+
originalDisplayName: "fooOriginal"
188+
}
189+
]);
190+
});
191+
});
148192
});
149193

150194
describe("resumed", () => {

src/selectors/test/getCallStackFrames.spec.js

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ describe("getCallStackFrames selector", () => {
4747
it("annotates frames related to Babel async transforms", () => {
4848
const preAwaitGroup = [
4949
{
50-
displayName: "_callee$",
50+
displayName: "asyncAppFunction",
5151
location: { sourceId: "bundle" }
5252
},
5353
{
@@ -86,7 +86,7 @@ describe("getCallStackFrames selector", () => {
8686

8787
const postAwaitGroup = [
8888
{
89-
displayName: "_callee$",
89+
displayName: "asyncAppFunction",
9090
location: { sourceId: "bundle" }
9191
},
9292
{
@@ -160,6 +160,7 @@ describe("getCallStackFrames selector", () => {
160160
5,
161161
6,
162162
7,
163+
8,
163164
10,
164165
11,
165166
12,

src/utils/pause/frames/annotateFrames.js

Lines changed: 21 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -37,18 +37,28 @@ function annotateBabelAsyncFrames(frames: Frame[]) {
3737
// Receives an array of frames and looks for babel async
3838
// call stack groups.
3939
function getBabelFrameIndexes(frames) {
40-
const startIndexes = getFrameIndices(
41-
frames,
42-
(displayName, url) =>
43-
url.match(/regenerator-runtime/i) && displayName === "tryCatch"
44-
);
40+
const startIndexes = frames.reduce((accumulator, frame, index) => {
41+
if (
42+
getFrameUrl(frame).match(/regenerator-runtime/i) &&
43+
frame.displayName === "tryCatch"
44+
) {
45+
return [...accumulator, index];
46+
}
47+
return accumulator;
48+
}, []);
4549

46-
const endIndexes = getFrameIndices(
47-
frames,
48-
(displayName, url) =>
49-
displayName === "_asyncToGenerator/<" ||
50-
(url.match(/_microtask/i) && displayName === "flush")
51-
);
50+
const endIndexes = frames.reduce((accumulator, frame, index) => {
51+
if (
52+
getFrameUrl(frame).match(/_microtask/i) &&
53+
frame.displayName === "flush"
54+
) {
55+
return [...accumulator, index];
56+
}
57+
if (frame.displayName === "_asyncToGenerator/<") {
58+
return [...accumulator, index + 1];
59+
}
60+
return accumulator;
61+
}, []);
5262

5363
if (startIndexes.length != endIndexes.length || startIndexes.length === 0) {
5464
return frames;
@@ -61,13 +71,3 @@ function getBabelFrameIndexes(frames) {
6171
range(startIndex, endIndex + 1)
6272
);
6373
}
64-
65-
function getFrameIndices(frames, predicate) {
66-
return frames.reduce(
67-
(accumulator, frame, index) =>
68-
predicate(frame.displayName, getFrameUrl(frame))
69-
? [...accumulator, index]
70-
: accumulator,
71-
[]
72-
);
73-
}

src/utils/pause/frames/displayName.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,8 @@ export function formatDisplayName(
7979
frame: LocalFrame,
8080
{ shouldMapDisplayName = true }: formatDisplayNameParams = {}
8181
) {
82-
let { displayName, library } = frame;
82+
let { displayName, originalDisplayName, library } = frame;
83+
displayName = originalDisplayName || displayName;
8384
if (library && shouldMapDisplayName) {
8485
displayName = mapDisplayNames(frame, library);
8586
}

src/utils/pause/frames/tests/displayName.spec.js

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,18 @@ describe("formatting display names", () => {
5454

5555
expect(formatDisplayName(frame)).toEqual("...zbazbazbazbazbazbazbazbaz");
5656
});
57+
58+
it("returns the original function name when present", () => {
59+
const frame = {
60+
originalDisplayName: "originalFn",
61+
displayName: "fn",
62+
source: {
63+
url: "entry.js"
64+
}
65+
};
66+
67+
expect(formatDisplayName(frame)).toEqual("originalFn");
68+
});
5769
});
5870

5971
describe("simplifying display names", () => {

0 commit comments

Comments
 (0)