1212
1313import { parse } from '@babel/parser' ;
1414import LRU from 'lru-cache' ;
15- import { SourceMapConsumer } from 'source-map-js' ;
1615import { getHookName } from '../astUtils' ;
1716import { areSourceMapsAppliedToErrors } from '../ErrorTester' ;
1817import { __DEBUG__ } from 'react-devtools-shared/src/constants' ;
@@ -33,8 +32,6 @@ import type {HookSource} from 'react-debug-tools/src/ReactDebugHooks';
3332import type { HookNames , LRUCache } from 'react-devtools-shared/src/types' ;
3433import type { SourceConsumer } from '../astUtils' ;
3534
36- const USE_ALTERNATE_SOURCE_MAP = true ;
37-
3835type AST = mixed ;
3936
4037type HookParsedMetadata = { |
@@ -84,7 +81,7 @@ const runtimeURLToMetadataCache: LRUCache<
8481 ) ;
8582 }
8683
87- console . log ( `runtimeURLToMetadataCache() dispose of "${ runtimeSourceURL } "` ) ;
84+ console . log ( `runtimeURLToMetadataCache() dispose of "${ runtimeSourceURL } "` ) ;
8885 const sourceConsumer = metadata . sourceConsumer ;
8986 if ( sourceConsumer !== null ) {
9087 sourceConsumer . destroy ( ) ;
@@ -121,35 +118,19 @@ export async function parseSourceAndMetadata(
121118 ( ) => initializeHookParsedMetadata ( locationKeyToHookSourceAndMetadata ) ,
122119 ) ;
123120
124- if ( USE_ALTERNATE_SOURCE_MAP ) {
125- withSyncPerfMeasurements ( 'parseSourceMapsAlternate' , ( ) =>
126- parseSourceMapsAlternate (
127- locationKeyToHookSourceAndMetadata ,
128- locationKeyToHookParsedMetadata ,
129- ) ,
130- ) ;
131-
132- withSyncPerfMeasurements ( 'parseSourceASTAlternate()' , ( ) =>
133- parseSourceASTAlternate (
134- locationKeyToHookSourceAndMetadata ,
135- locationKeyToHookParsedMetadata ,
136- ) ,
137- ) ;
138- } else {
139- withSyncPerfMeasurements ( 'parseSourceMaps' , ( ) =>
140- parseSourceMaps (
141- locationKeyToHookSourceAndMetadata ,
142- locationKeyToHookParsedMetadata ,
143- ) ,
144- ) ;
121+ withSyncPerfMeasurements ( 'parseSourceMaps' , ( ) =>
122+ parseSourceMaps (
123+ locationKeyToHookSourceAndMetadata ,
124+ locationKeyToHookParsedMetadata ,
125+ ) ,
126+ ) ;
145127
146- withSyncPerfMeasurements ( 'parseSourceAST()' , ( ) =>
147- parseSourceAST (
148- locationKeyToHookSourceAndMetadata ,
149- locationKeyToHookParsedMetadata ,
150- ) ,
151- ) ;
152- }
128+ withSyncPerfMeasurements ( 'parseSourceAST()' , ( ) =>
129+ parseSourceAST (
130+ locationKeyToHookSourceAndMetadata ,
131+ locationKeyToHookParsedMetadata ,
132+ ) ,
133+ ) ;
153134
154135 return withSyncPerfMeasurements ( 'findHookNames()' , ( ) =>
155136 findHookNames ( hooksList , locationKeyToHookParsedMetadata ) ,
@@ -289,194 +270,6 @@ function parseSourceAST(
289270 throw Error ( 'Hook source code location not found.' ) ;
290271 }
291272
292- const { metadataConsumer, sourceConsumer} = hookParsedMetadata ;
293- const runtimeSourceCode = ( ( hookSourceAndMetadata . runtimeSourceCode : any ) : string ) ;
294-
295- let hasHookMap = false ;
296- let originalSourceURL ;
297- let originalSourceCode ;
298- let originalSourceColumnNumber ;
299- let originalSourceLineNumber ;
300- if ( areSourceMapsAppliedToErrors ( ) || sourceConsumer == null ) {
301- // Either the current environment automatically applies source maps to errors,
302- // or the current code had no source map to begin with.
303- // Either way, we don't need to convert the Error stack frame locations.
304- originalSourceColumnNumber = columnNumber ;
305- originalSourceLineNumber = lineNumber ;
306- // There's no source map to parse here so we can just parse the original source itself.
307- originalSourceCode = runtimeSourceCode ;
308- // TODO (named hooks) This mixes runtimeSourceURLs with source mapped URLs in the same cache key space.
309- // Namespace them?
310- originalSourceURL = hookSourceAndMetadata . runtimeSourceURL ;
311- } else {
312- // Parse and extract the AST from the source map.
313- // Now that the source map has been loaded,
314- // extract the original source for later.
315- // TODO (named hooks) Refactor this read, github.com/facebook/react/pull/22181
316- const { column, line, source} = withSyncPerfMeasurements (
317- 'sourceConsumer.originalPositionFor()' ,
318- ( ) =>
319- sourceConsumer . originalPositionFor ( {
320- line : lineNumber ,
321-
322- // Column numbers are represented differently between tools/engines.
323- // Error.prototype.stack columns are 1-based (like most IDEs) but ASTs are 0-based.
324- // For more info see https://github.com/facebook/react/issues/21792#issuecomment-873171991
325- column : columnNumber - 1 ,
326- } ) ,
327- ) ;
328-
329- if ( source == null ) {
330- // TODO (named hooks) maybe fall back to the runtime source instead of throwing?
331- throw new Error (
332- 'Could not map hook runtime location to original source location' ,
333- ) ;
334- }
335-
336- originalSourceColumnNumber = column ;
337- originalSourceLineNumber = line ;
338- // TODO (named hooks) maybe canonicalize this URL somehow?
339- // It can be relative if the source map specifies it that way,
340- // but we use it as a cache key across different source maps and there can be collisions.
341- originalSourceURL = ( source : string ) ;
342- originalSourceCode = withSyncPerfMeasurements (
343- 'sourceConsumer.sourceContentFor()' ,
344- ( ) => ( sourceConsumer . sourceContentFor ( source , true ) : string ) ,
345- ) ;
346-
347- if ( __DEBUG__ ) {
348- console . groupCollapsed (
349- `parseSourceAST() Extracted source code from source map for "${ originalSourceURL } "` ,
350- ) ;
351- console . log ( originalSourceCode ) ;
352- console . groupEnd ( ) ;
353- }
354-
355- if (
356- metadataConsumer != null &&
357- metadataConsumer . hasHookMap ( originalSourceURL )
358- ) {
359- hasHookMap = true ;
360- }
361- }
362-
363- if ( __DEBUG__ ) {
364- console . log (
365- `parseSourceAST() mapped line ${ lineNumber } ->${ originalSourceLineNumber } and column ${ columnNumber } ->${ originalSourceColumnNumber } ` ,
366- ) ;
367- }
368-
369- hookParsedMetadata . originalSourceCode = originalSourceCode ;
370- hookParsedMetadata . originalSourceURL = originalSourceURL ;
371- hookParsedMetadata . originalSourceLineNumber = originalSourceLineNumber ;
372- hookParsedMetadata . originalSourceColumnNumber = originalSourceColumnNumber ;
373-
374- if ( hasHookMap ) {
375- if ( __DEBUG__ ) {
376- console . log (
377- `parseSourceAST() Found hookMap and skipping parsing for "${ originalSourceURL } "` ,
378- ) ;
379- }
380- // If there's a hook map present from an extended sourcemap then
381- // we don't need to parse the source files and instead can use the
382- // hook map to extract hook names.
383- return ;
384- }
385-
386- if ( __DEBUG__ ) {
387- console . log (
388- `parseSourceAST() Did not find hook map for "${ originalSourceURL } "` ,
389- ) ;
390- }
391-
392- // The cache also serves to deduplicate parsing by URL in our loop over location keys.
393- // This may need to change if we switch to async parsing.
394- const sourceMetadata = originalURLToMetadataCache . get ( originalSourceURL ) ;
395- if ( sourceMetadata != null ) {
396- if ( __DEBUG__ ) {
397- console . groupCollapsed (
398- `parseSourceAST() Found cached source metadata for "${ originalSourceURL } "` ,
399- ) ;
400- console . log ( sourceMetadata ) ;
401- console . groupEnd ( ) ;
402- }
403- hookParsedMetadata . originalSourceAST = sourceMetadata . originalSourceAST ;
404- hookParsedMetadata . originalSourceCode =
405- sourceMetadata . originalSourceCode ;
406- } else {
407- try {
408- // TypeScript is the most commonly used typed JS variant so let's default to it
409- // unless we detect explicit Flow usage via the "@flow" pragma.
410- const plugin =
411- originalSourceCode . indexOf ( '@flow' ) > 0 ? 'flow' : 'typescript' ;
412-
413- // TODO (named hooks) This is probably where we should check max source length,
414- // rather than in loadSourceAndMetatada -> loadSourceFiles().
415- // TODO(#22319): Support source files that are html files with inline script tags.
416- const originalSourceAST = withSyncPerfMeasurements (
417- '[@babel/parser] parse(originalSourceCode)' ,
418- ( ) =>
419- parse ( originalSourceCode , {
420- sourceType : 'unambiguous' ,
421- plugins : [ 'jsx' , plugin ] ,
422- } ) ,
423- ) ;
424- hookParsedMetadata . originalSourceAST = originalSourceAST ;
425-
426- if ( __DEBUG__ ) {
427- console . log (
428- `parseSourceAST() Caching source metadata for "${ originalSourceURL } "` ,
429- ) ;
430- }
431-
432- originalURLToMetadataCache . set ( originalSourceURL , {
433- originalSourceAST,
434- originalSourceCode,
435- } ) ;
436- } catch ( error ) {
437- throw new Error (
438- `Failed to parse source file: ${ originalSourceURL } \n\n` +
439- `Original error: ${ error } ` ,
440- ) ;
441- }
442- }
443- } ,
444- ) ;
445- }
446-
447- function parseSourceASTAlternate (
448- locationKeyToHookSourceAndMetadata : LocationKeyToHookSourceAndMetadata ,
449- locationKeyToHookParsedMetadata : LocationKeyToHookParsedMetadata ,
450- ) : void {
451- locationKeyToHookSourceAndMetadata . forEach (
452- ( hookSourceAndMetadata , locationKey ) => {
453- const hookParsedMetadata = locationKeyToHookParsedMetadata . get (
454- locationKey ,
455- ) ;
456- if ( hookParsedMetadata == null ) {
457- throw Error ( `Expected to find HookParsedMetadata for "${ locationKey } "` ) ;
458- }
459-
460- if ( hookParsedMetadata . originalSourceAST !== null ) {
461- // Use cached metadata.
462- return ;
463- }
464-
465- if (
466- hookParsedMetadata . originalSourceURL != null &&
467- hookParsedMetadata . originalSourceCode != null &&
468- hookParsedMetadata . originalSourceColumnNumber != null &&
469- hookParsedMetadata . originalSourceLineNumber != null
470- ) {
471- // Use cached metadata.
472- return ;
473- }
474-
475- const { lineNumber, columnNumber} = hookSourceAndMetadata . hookSource ;
476- if ( lineNumber == null || columnNumber == null ) {
477- throw Error ( 'Hook source code location not found.' ) ;
478- }
479-
480273 const { metadataConsumer, sourceMapConsumer} = hookParsedMetadata ;
481274 const runtimeSourceCode = ( ( hookSourceAndMetadata . runtimeSourceCode : any ) : string ) ;
482275 let hasHookMap = false ;
@@ -616,59 +409,6 @@ function parseSourceMaps(
616409 throw Error ( `Expected to find HookParsedMetadata for "${ locationKey } "` ) ;
617410 }
618411
619- const sourceMapJSON = hookSourceAndMetadata . sourceMapJSON ;
620-
621- if ( hookParsedMetadata . sourceConsumer === null ) {
622- if ( sourceMapJSON != null ) {
623- hookParsedMetadata . sourceConsumer = withSyncPerfMeasurements (
624- 'new SourceMapConsumer(sourceMapJSON)' ,
625- ( ) => new SourceMapConsumer ( sourceMapJSON ) ,
626- ) ;
627- }
628- }
629-
630- if ( hookParsedMetadata . metadataConsumer === null ) {
631- if ( sourceMapJSON != null ) {
632- hookParsedMetadata . metadataConsumer = withSyncPerfMeasurements (
633- 'new SourceMapMetadataConsumer(sourceMapJSON)' ,
634- ( ) => new SourceMapMetadataConsumer ( sourceMapJSON ) ,
635- ) ;
636- }
637- }
638-
639- const runtimeSourceURL = hookSourceAndMetadata . runtimeSourceURL ;
640-
641- // Only set once to avoid triggering eviction/cleanup code.
642- if ( ! runtimeURLToMetadataCache . has ( runtimeSourceURL ) ) {
643- if ( __DEBUG__ ) {
644- console . log (
645- `parseSourceMaps() Caching runtime metadata for "${ runtimeSourceURL } "` ,
646- ) ;
647- }
648-
649- runtimeURLToMetadataCache . set ( runtimeSourceURL , {
650- metadataConsumer : hookParsedMetadata . metadataConsumer ,
651- sourceConsumer : hookParsedMetadata . sourceConsumer ,
652- sourceMapConsumer : null ,
653- } ) ;
654- }
655- } ,
656- ) ;
657- }
658-
659- function parseSourceMapsAlternate (
660- locationKeyToHookSourceAndMetadata : LocationKeyToHookSourceAndMetadata ,
661- locationKeyToHookParsedMetadata : LocationKeyToHookParsedMetadata ,
662- ) {
663- locationKeyToHookSourceAndMetadata . forEach (
664- ( hookSourceAndMetadata , locationKey ) => {
665- const hookParsedMetadata = locationKeyToHookParsedMetadata . get (
666- locationKey ,
667- ) ;
668- if ( hookParsedMetadata == null ) {
669- throw Error ( `Expected to find HookParsedMetadata for "${ locationKey } "` ) ;
670- }
671-
672412 const { runtimeSourceURL, sourceMapJSON} = hookSourceAndMetadata ;
673413
674414 // If we've already loaded the source map info for this file,
@@ -685,7 +425,8 @@ function parseSourceMapsAlternate(
685425
686426 hookParsedMetadata . metadataConsumer = runtimeMetadata . metadataConsumer ;
687427 hookParsedMetadata . sourceConsumer = runtimeMetadata . sourceConsumer ;
688- hookParsedMetadata . sourceMapConsumer = runtimeMetadata . sourceMapConsumer ;
428+ hookParsedMetadata . sourceMapConsumer =
429+ runtimeMetadata . sourceMapConsumer ;
689430 } else {
690431 if ( sourceMapJSON != null ) {
691432 const sourceMapConsumer = withSyncPerfMeasurements (
0 commit comments