12
import {dehydrate} from 'react-devtools-shared/src/hydration';
13
import isArray from 'shared/isArray';
14
15
-import type {Source} from 'react-devtools-shared/src/shared/types';
15
+import type {ReactFunctionLocation} from 'shared/ReactTypes';
16
import type {DehydratedData} from 'react-devtools-shared/src/frontend/types';
17
18
export {default as formatWithStyles} from './formatWithStyles';
258
return window.document == null;
259
};
260
261
-function extractLocation(
262
- url: string,
263
-): null | {sourceURL: string, line?: string, column?: string} {
261
+function extractLocation(url: string): null | {
262
+ functionName?: string,
263
+ sourceURL: string,
264
+ line?: string,
265
+ column?: string,
266
+} {
267
if (url.indexOf(':') === -1) {
268
return null;
269
}
278
return null;
279
}
280
281
+ const functionName = ''; // TODO: Parse this in the regexp.
282
const [, , sourceURL, line, column] = locationParts;
279
- return {sourceURL, line, column};
283
+ return {functionName, sourceURL, line, column};
284
}
285
286
const CHROME_STACK_REGEXP = /^\s*at .*(\S+:\d+|\(native\))/m;
283
-function parseSourceFromChromeStack(stack: string): Source | null {
287
+function parseSourceFromChromeStack(
288
+ stack: string,
289
+): ReactFunctionLocation | null {
290
const frames = stack.split('\n');
291
// eslint-disable-next-line no-for-of-loops/no-for-of-loops
292
for (const frame of frames) {
303
continue;
304
}
305
300
- const {sourceURL, line = '1', column = '1'} = location;
306
+ const {functionName, sourceURL, line = '1', column = '1'} = location;
307
302
- return {
308
+ return [
309
+ functionName || '',
310
sourceURL,
304
- line: parseInt(line, 10),
305
- column: parseInt(column, 10),
306
- };
311
+ parseInt(line, 10),
312
+ parseInt(column, 10),
313
+ ];
314
}
315
316
return null;
317
}
318
312
-function parseSourceFromFirefoxStack(stack: string): Source | null {
319
+function parseSourceFromFirefoxStack(
320
+ stack: string,
321
+): ReactFunctionLocation | null {
322
const frames = stack.split('\n');
323
// eslint-disable-next-line no-for-of-loops/no-for-of-loops
324
for (const frame of frames) {
334
continue;
335
}
336
328
- const {sourceURL, line = '1', column = '1'} = location;
337
+ const {functionName, sourceURL, line = '1', column = '1'} = location;
338
330
- return {
339
+ return [
340
+ functionName || '',
341
sourceURL,
332
- line: parseInt(line, 10),
333
- column: parseInt(column, 10),
334
- };
342
+ parseInt(line, 10),
343
+ parseInt(column, 10),
344
+ ];
345
}
346
347
return null;
349
350
export function parseSourceFromComponentStack(
351
componentStack: string,
342
-): Source | null {
352
+): ReactFunctionLocation | null {
353
if (componentStack.match(CHROME_STACK_REGEXP)) {
354
return parseSourceFromChromeStack(componentStack);
355
}
357
return parseSourceFromFirefoxStack(componentStack);
358
}
359
350
-let collectedLocation: Source | null = null;
360
+let collectedLocation: ReactFunctionLocation | null = null;
361
362
function collectStackTrace(
363
error: Error,
364
structuredStackTrace: CallSite[],
365
): string {
356
- let result: null | Source = null;
366
+ let result: null | ReactFunctionLocation = null;
367
// Collect structured stack traces from the callsites.
368
// We mirror how V8 serializes stack frames and how we later parse them.
369
for (let i = 0; i < structuredStackTrace.length; i++) {
396
// Skip eval etc. without source url. They don't have location.
397
continue;
398
}
389
- result = {
390
- sourceURL,
391
- line: line,
392
- column: col,
393
- };
399
+ result = [name, sourceURL, line, col];
400
}
401
}
402
// At the same time we generate a string stack trace just in case someone
410
return stack;
411
}
412
407
-export function parseSourceFromOwnerStack(error: Error): Source | null {
413
+export function parseSourceFromOwnerStack(
414
+ error: Error,
415
+): ReactFunctionLocation | null {
416
// First attempt to collected the structured data using prepareStackTrace.
417
collectedLocation = null;
418
const previousPrepare = Error.prepareStackTrace;