@@ -1060,24 +1060,39 @@ namespace ts {
1060
1060
1061
1061
let moduleResolutionCache : ModuleResolutionCache | undefined ;
1062
1062
let typeReferenceDirectiveResolutionCache : TypeReferenceDirectiveResolutionCache | undefined ;
1063
- let actualResolveModuleNamesWorker : ( moduleNames : string [ ] , containingFile : SourceFile , containingFileName : string , reusedNames ?: string [ ] , redirectedReference ?: ResolvedProjectReference ) => ResolvedModuleFull [ ] ;
1063
+ let actualResolveModuleNamesWorker : (
1064
+ moduleNames : string [ ] ,
1065
+ containingFile : SourceFile ,
1066
+ containingFileName : string ,
1067
+ redirectedReference : ResolvedProjectReference | undefined ,
1068
+ partialResolutionInfo : PartialResolutionInfo | undefined ,
1069
+ ) => ResolvedModuleFull [ ] ;
1064
1070
const hasInvalidatedResolution = host . hasInvalidatedResolution || returnFalse ;
1065
1071
if ( host . resolveModuleNames ) {
1066
- actualResolveModuleNamesWorker = ( moduleNames , containingFile , containingFileName , reusedNames , redirectedReference ) => host . resolveModuleNames ! ( Debug . checkEachDefined ( moduleNames ) , containingFileName , reusedNames , redirectedReference , options , containingFile ) . map ( resolved => {
1067
- // An older host may have omitted extension, in which case we should infer it from the file extension of resolvedFileName.
1068
- if ( ! resolved || ( resolved as ResolvedModuleFull ) . extension !== undefined ) {
1069
- return resolved as ResolvedModuleFull ;
1070
- }
1071
- const withExtension = clone ( resolved ) as ResolvedModuleFull ;
1072
- withExtension . extension = extensionFromPath ( resolved . resolvedFileName ) ;
1073
- return withExtension ;
1074
- } ) ;
1072
+ actualResolveModuleNamesWorker = ( moduleNames , containingFile , containingFileName , redirectedReference , partialResolutionInfo ) =>
1073
+ host . resolveModuleNames ! (
1074
+ Debug . checkEachDefined ( moduleNames ) ,
1075
+ containingFileName ,
1076
+ partialResolutionInfo ?. reusedNames ?. map ( ( { name } ) => name ) ,
1077
+ redirectedReference ,
1078
+ options ,
1079
+ containingFile ,
1080
+ partialResolutionInfo
1081
+ ) . map ( resolved => {
1082
+ // An older host may have omitted extension, in which case we should infer it from the file extension of resolvedFileName.
1083
+ if ( ! resolved || ( resolved as ResolvedModuleFull ) . extension !== undefined ) {
1084
+ return resolved as ResolvedModuleFull ;
1085
+ }
1086
+ const withExtension = clone ( resolved ) as ResolvedModuleFull ;
1087
+ withExtension . extension = extensionFromPath ( resolved . resolvedFileName ) ;
1088
+ return withExtension ;
1089
+ } ) ;
1075
1090
moduleResolutionCache = host . getModuleResolutionCache ?.( ) ;
1076
1091
}
1077
1092
else {
1078
1093
moduleResolutionCache = createModuleResolutionCache ( currentDirectory , getCanonicalFileName , options ) ;
1079
1094
const loader = ( moduleName : string , resolverMode : ModuleKind . CommonJS | ModuleKind . ESNext | undefined , containingFileName : string , redirectedReference : ResolvedProjectReference | undefined ) => resolveModuleName ( moduleName , containingFileName , options , host , moduleResolutionCache , redirectedReference , resolverMode ) . resolvedModule ! ; // TODO: GH#18217
1080
- actualResolveModuleNamesWorker = ( moduleNames , containingFile , containingFileName , _reusedNames , redirectedReference ) => loadWithModeAwareCache < ResolvedModuleFull > ( Debug . checkEachDefined ( moduleNames ) , containingFile , containingFileName , redirectedReference , loader ) ;
1095
+ actualResolveModuleNamesWorker = ( moduleNames , containingFile , containingFileName , redirectedReference ) => loadWithModeAwareCache < ResolvedModuleFull > ( Debug . checkEachDefined ( moduleNames ) , containingFile , containingFileName , redirectedReference , loader ) ;
1081
1096
}
1082
1097
1083
1098
let actualResolveTypeReferenceDirectiveNamesWorker : ( typeDirectiveNames : string [ ] | readonly FileReference [ ] , containingFile : string , redirectedReference ?: ResolvedProjectReference , containingFileMode ?: SourceFile [ "impliedNodeFormat" ] | undefined ) => ( ResolvedTypeReferenceDirective | undefined ) [ ] ;
@@ -1383,13 +1398,13 @@ namespace ts {
1383
1398
}
1384
1399
}
1385
1400
1386
- function resolveModuleNamesWorker ( moduleNames : string [ ] , containingFile : SourceFile , reusedNames : string [ ] | undefined ) : readonly ResolvedModuleFull [ ] {
1401
+ function resolveModuleNamesWorker ( moduleNames : string [ ] , containingFile : SourceFile , partialResolutionInfo : PartialResolutionInfo | undefined ) : readonly ResolvedModuleFull [ ] {
1387
1402
if ( ! moduleNames . length ) return emptyArray ;
1388
1403
const containingFileName = getNormalizedAbsolutePath ( containingFile . originalFileName , currentDirectory ) ;
1389
1404
const redirectedReference = getRedirectReferenceForResolution ( containingFile ) ;
1390
1405
tracing ?. push ( tracing . Phase . Program , "resolveModuleNamesWorker" , { containingFileName } ) ;
1391
1406
performance . mark ( "beforeResolveModule" ) ;
1392
- const result = actualResolveModuleNamesWorker ( moduleNames , containingFile , containingFileName , reusedNames , redirectedReference ) ;
1407
+ const result = actualResolveModuleNamesWorker ( moduleNames , containingFile , containingFileName , redirectedReference , partialResolutionInfo ) ;
1393
1408
performance . mark ( "afterResolveModule" ) ;
1394
1409
performance . measure ( "ResolveModule" , "beforeResolveModule" , "afterResolveModule" ) ;
1395
1410
tracing ?. pop ( ) ;
@@ -1496,7 +1511,7 @@ namespace ts {
1496
1511
if ( structureIsReused === StructureIsReused . Not && ! file . ambientModuleNames . length ) {
1497
1512
// If the old program state does not permit reusing resolutions and `file` does not contain locally defined ambient modules,
1498
1513
// the best we can do is fallback to the default logic.
1499
- return resolveModuleNamesWorker ( moduleNames , file , /*reusedNames */ undefined ) ;
1514
+ return resolveModuleNamesWorker ( moduleNames , file , /*partialResolutionInfo */ undefined ) ;
1500
1515
}
1501
1516
1502
1517
const oldSourceFile = oldProgram && oldProgram . getSourceFile ( file . fileName ) ;
@@ -1525,6 +1540,7 @@ namespace ts {
1525
1540
1526
1541
/** An ordered list of module names for which we cannot recover the resolution. */
1527
1542
let unknownModuleNames : string [ ] | undefined ;
1543
+ let unknownModuleNamesIndex : number [ ] | undefined ;
1528
1544
/**
1529
1545
* The indexing of elements in this list matches that of `moduleNames`.
1530
1546
*
@@ -1535,15 +1551,16 @@ namespace ts {
1535
1551
* * ResolvedModuleFull instance: can be reused.
1536
1552
*/
1537
1553
let result : ResolvedModuleFull [ ] | undefined ;
1538
- let reusedNames : string [ ] | undefined ;
1554
+ let reusedNames : { name : string ; mode : ModuleKind . CommonJS | ModuleKind . ESNext | undefined ; } [ ] | undefined ;
1539
1555
/** A transient placeholder used to mark predicted resolution in the result list. */
1540
1556
const predictedToResolveToAmbientModuleMarker : ResolvedModuleFull = { } as any ;
1541
1557
1542
1558
for ( let i = 0 ; i < moduleNames . length ; i ++ ) {
1543
1559
const moduleName = moduleNames [ i ] ;
1544
1560
// If the source file is unchanged and doesnt have invalidated resolution, reuse the module resolutions
1545
1561
if ( file === oldSourceFile && ! hasInvalidatedResolution ( oldSourceFile . path ) ) {
1546
- const oldResolvedModule = getResolvedModule ( oldSourceFile , moduleName , getModeForResolutionAtIndex ( oldSourceFile , i ) ) ;
1562
+ const mode = getModeForResolutionAtIndex ( oldSourceFile , i ) ;
1563
+ const oldResolvedModule = getResolvedModule ( oldSourceFile , moduleName , mode ) ;
1547
1564
if ( oldResolvedModule ) {
1548
1565
if ( isTraceEnabled ( options , host ) ) {
1549
1566
trace ( host ,
@@ -1556,8 +1573,8 @@ namespace ts {
1556
1573
oldResolvedModule . packageId && packageIdToString ( oldResolvedModule . packageId )
1557
1574
) ;
1558
1575
}
1559
- ( result || ( result = new Array ( moduleNames . length ) ) ) [ i ] = oldResolvedModule ;
1560
- ( reusedNames || ( reusedNames = [ ] ) ) . push ( moduleName ) ;
1576
+ ( result ?? = new Array ( moduleNames . length ) ) [ i ] = oldResolvedModule ;
1577
+ ( reusedNames ?? = [ ] ) . push ( { name : moduleName , mode } ) ;
1561
1578
continue ;
1562
1579
}
1563
1580
}
@@ -1581,12 +1598,13 @@ namespace ts {
1581
1598
}
1582
1599
else {
1583
1600
// Resolution failed in the old program, or resolved to an ambient module for which we can't reuse the result.
1584
- ( unknownModuleNames || ( unknownModuleNames = [ ] ) ) . push ( moduleName ) ;
1601
+ ( unknownModuleNames ??= [ ] ) . push ( moduleName ) ;
1602
+ ( unknownModuleNamesIndex ??= [ ] ) . push ( i ) ;
1585
1603
}
1586
1604
}
1587
1605
1588
1606
const resolutions = unknownModuleNames && unknownModuleNames . length
1589
- ? resolveModuleNamesWorker ( unknownModuleNames , file , reusedNames )
1607
+ ? resolveModuleNamesWorker ( unknownModuleNames , file , { reusedNames, namesIndex : unknownModuleNamesIndex ! } )
1590
1608
: emptyArray ;
1591
1609
1592
1610
// Combine results of resolutions and predicted results
0 commit comments