@@ -289,50 +289,84 @@ function extractManualMemoizationArgs(
289
289
instr : TInstruction < CallExpression > | TInstruction < MethodCall > ,
290
290
kind : 'useCallback' | 'useMemo' ,
291
291
sidemap : IdentifierSidemap ,
292
+ errors : CompilerError ,
292
293
) : {
293
- fnPlace : Place ;
294
+ fnPlace : Place | null ;
294
295
depsList : Array < ManualMemoDependency > | null ;
295
296
} {
296
297
const [ fnPlace , depsListPlace ] = instr . value . args as Array <
297
298
Place | SpreadPattern | undefined
298
299
> ;
299
300
if ( fnPlace == null ) {
300
- CompilerError . throwInvalidReact ( {
301
- reason : `Expected a callback function to be passed to ${ kind } ` ,
302
- loc : instr . value . loc ,
303
- suggestions : null ,
304
- } ) ;
301
+ errors . pushDiagnostic (
302
+ CompilerDiagnostic . create ( {
303
+ severity : ErrorSeverity . InvalidReact ,
304
+ category : `Expected a callback function to be passed to ${ kind } ` ,
305
+ description : `Expected a callback function to be passed to ${ kind } ` ,
306
+ suggestions : null ,
307
+ } ) . withDetail ( {
308
+ kind : 'error' ,
309
+ loc : instr . value . loc ,
310
+ message : `Expected a callback function to be passed to ${ kind } ` ,
311
+ } ) ,
312
+ ) ;
313
+ return { fnPlace : null , depsList : null } ;
305
314
}
306
315
if ( fnPlace . kind === 'Spread' || depsListPlace ?. kind === 'Spread' ) {
307
- CompilerError . throwInvalidReact ( {
308
- reason : `Unexpected spread argument to ${ kind } ` ,
309
- loc : instr . value . loc ,
310
- suggestions : null ,
311
- } ) ;
316
+ errors . pushDiagnostic (
317
+ CompilerDiagnostic . create ( {
318
+ severity : ErrorSeverity . InvalidReact ,
319
+ category : `Unexpected spread argument to ${ kind } ` ,
320
+ description : `Unexpected spread argument to ${ kind } ` ,
321
+ suggestions : null ,
322
+ } ) . withDetail ( {
323
+ kind : 'error' ,
324
+ loc : instr . value . loc ,
325
+ message : `Unexpected spread argument to ${ kind } ` ,
326
+ } ) ,
327
+ ) ;
328
+ return { fnPlace : null , depsList : null } ;
312
329
}
313
330
let depsList : Array < ManualMemoDependency > | null = null ;
314
331
if ( depsListPlace != null ) {
315
332
const maybeDepsList = sidemap . maybeDepsLists . get (
316
333
depsListPlace . identifier . id ,
317
334
) ;
318
335
if ( maybeDepsList == null ) {
319
- CompilerError . throwInvalidReact ( {
320
- reason : `Expected the dependency list for ${ kind } to be an array literal` ,
321
- suggestions : null ,
322
- loc : depsListPlace . loc ,
323
- } ) ;
336
+ errors . pushDiagnostic (
337
+ CompilerDiagnostic . create ( {
338
+ severity : ErrorSeverity . InvalidReact ,
339
+ category : `Expected the dependency list for ${ kind } to be an array literal` ,
340
+ description : `Expected the dependency list for ${ kind } to be an array literal` ,
341
+ suggestions : null ,
342
+ } ) . withDetail ( {
343
+ kind : 'error' ,
344
+ loc : depsListPlace . loc ,
345
+ message : `Expected the dependency list for ${ kind } to be an array literal` ,
346
+ } ) ,
347
+ ) ;
348
+ return { fnPlace, depsList : null } ;
324
349
}
325
- depsList = maybeDepsList . map ( dep => {
350
+ depsList = [ ] ;
351
+ for ( const dep of maybeDepsList ) {
326
352
const maybeDep = sidemap . maybeDeps . get ( dep . identifier . id ) ;
327
353
if ( maybeDep == null ) {
328
- CompilerError . throwInvalidReact ( {
329
- reason : `Expected the dependency list to be an array of simple expressions (e.g. \`x\`, \`x.y.z\`, \`x?.y?.z\`)` ,
330
- suggestions : null ,
331
- loc : dep . loc ,
332
- } ) ;
354
+ errors . pushDiagnostic (
355
+ CompilerDiagnostic . create ( {
356
+ severity : ErrorSeverity . InvalidReact ,
357
+ category : `Expected the dependency list to be an array of simple expressions (e.g. \`x\`, \`x.y.z\`, \`x?.y?.z\`)` ,
358
+ description : `Expected the dependency list to be an array of simple expressions (e.g. \`x\`, \`x.y.z\`, \`x?.y?.z\`)` ,
359
+ suggestions : null ,
360
+ } ) . withDetail ( {
361
+ kind : 'error' ,
362
+ loc : dep . loc ,
363
+ message : `Expected the dependency list to be an array of simple expressions (e.g. \`x\`, \`x.y.z\`, \`x?.y?.z\`)` ,
364
+ } ) ,
365
+ ) ;
366
+ } else {
367
+ depsList . push ( maybeDep ) ;
333
368
}
334
- return maybeDep ;
335
- } ) ;
369
+ }
336
370
}
337
371
return {
338
372
fnPlace,
@@ -401,8 +435,13 @@ export function dropManualMemoization(
401
435
instr as TInstruction < CallExpression > | TInstruction < MethodCall > ,
402
436
manualMemo . kind ,
403
437
sidemap ,
438
+ errors ,
404
439
) ;
405
440
441
+ if ( fnPlace == null ) {
442
+ continue ;
443
+ }
444
+
406
445
/**
407
446
* Bailout on void return useMemos. This is an anti-pattern where code might be using
408
447
* useMemo like useEffect: running arbirtary side-effects synced to changes in specific
@@ -457,11 +496,19 @@ export function dropManualMemoization(
457
496
* is rare and likely sketchy.
458
497
*/
459
498
if ( ! sidemap . functions . has ( fnPlace . identifier . id ) ) {
460
- CompilerError . throwInvalidReact ( {
461
- reason : `Expected the first argument to be an inline function expression` ,
462
- suggestions : [ ] ,
463
- loc : fnPlace . loc ,
464
- } ) ;
499
+ errors . pushDiagnostic (
500
+ CompilerDiagnostic . create ( {
501
+ severity : ErrorSeverity . InvalidReact ,
502
+ category : `Expected the first argument to be an inline function expression` ,
503
+ description : `Expected the first argument to be an inline function expression` ,
504
+ suggestions : [ ] ,
505
+ } ) . withDetail ( {
506
+ kind : 'error' ,
507
+ loc : fnPlace . loc ,
508
+ message : `Expected the first argument to be an inline function expression` ,
509
+ } ) ,
510
+ ) ;
511
+ continue ;
465
512
}
466
513
const memoDecl : Place =
467
514
manualMemo . kind === 'useMemo'
0 commit comments