@@ -1075,24 +1075,39 @@ namespace ts {
1075
1075
1076
1076
let moduleResolutionCache : ModuleResolutionCache | undefined ;
1077
1077
let typeReferenceDirectiveResolutionCache : TypeReferenceDirectiveResolutionCache | undefined ;
1078
- let actualResolveModuleNamesWorker : ( moduleNames : string [ ] , containingFile : SourceFile , containingFileName : string , reusedNames ?: string [ ] , redirectedReference ?: ResolvedProjectReference ) => ResolvedModuleFull [ ] ;
1078
+ let actualResolveModuleNamesWorker : (
1079
+ moduleNames : string [ ] ,
1080
+ containingFile : SourceFile ,
1081
+ containingFileName : string ,
1082
+ redirectedReference : ResolvedProjectReference | undefined ,
1083
+ partialResolutionInfo : PartialResolutionInfo | undefined ,
1084
+ ) => ResolvedModuleFull [ ] ;
1079
1085
const hasInvalidatedResolution = host . hasInvalidatedResolution || returnFalse ;
1080
1086
if ( host . resolveModuleNames ) {
1081
- actualResolveModuleNamesWorker = ( moduleNames , containingFile , containingFileName , reusedNames , redirectedReference ) => host . resolveModuleNames ! ( Debug . checkEachDefined ( moduleNames ) , containingFileName , reusedNames , redirectedReference , options , containingFile ) . 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
- } ) ;
1087
+ actualResolveModuleNamesWorker = ( moduleNames , containingFile , containingFileName , redirectedReference , partialResolutionInfo ) =>
1088
+ host . resolveModuleNames ! (
1089
+ Debug . checkEachDefined ( moduleNames ) ,
1090
+ containingFileName ,
1091
+ partialResolutionInfo ?. reusedNames ?. map ( ( { name } ) => name ) ,
1092
+ redirectedReference ,
1093
+ options ,
1094
+ containingFile ,
1095
+ partialResolutionInfo
1096
+ ) . map ( resolved => {
1097
+ // An older host may have omitted extension, in which case we should infer it from the file extension of resolvedFileName.
1098
+ if ( ! resolved || ( resolved as ResolvedModuleFull ) . extension !== undefined ) {
1099
+ return resolved as ResolvedModuleFull ;
1100
+ }
1101
+ const withExtension = clone ( resolved ) as ResolvedModuleFull ;
1102
+ withExtension . extension = extensionFromPath ( resolved . resolvedFileName ) ;
1103
+ return withExtension ;
1104
+ } ) ;
1090
1105
moduleResolutionCache = host . getModuleResolutionCache ?.( ) ;
1091
1106
}
1092
1107
else {
1093
1108
moduleResolutionCache = createModuleResolutionCache ( currentDirectory , getCanonicalFileName , options ) ;
1094
1109
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
1095
- actualResolveModuleNamesWorker = ( moduleNames , containingFile , containingFileName , _reusedNames , redirectedReference ) => loadWithModeAwareCache < ResolvedModuleFull > ( Debug . checkEachDefined ( moduleNames ) , containingFile , containingFileName , redirectedReference , loader ) ;
1110
+ actualResolveModuleNamesWorker = ( moduleNames , containingFile , containingFileName , redirectedReference ) => loadWithModeAwareCache < ResolvedModuleFull > ( Debug . checkEachDefined ( moduleNames ) , containingFile , containingFileName , redirectedReference , loader ) ;
1096
1111
}
1097
1112
1098
1113
let actualResolveTypeReferenceDirectiveNamesWorker : ( typeDirectiveNames : string [ ] | readonly FileReference [ ] , containingFile : string , redirectedReference ?: ResolvedProjectReference , containingFileMode ?: SourceFile [ "impliedNodeFormat" ] | undefined ) => ( ResolvedTypeReferenceDirective | undefined ) [ ] ;
@@ -1398,13 +1413,13 @@ namespace ts {
1398
1413
}
1399
1414
}
1400
1415
1401
- function resolveModuleNamesWorker ( moduleNames : string [ ] , containingFile : SourceFile , reusedNames : string [ ] | undefined ) : readonly ResolvedModuleFull [ ] {
1416
+ function resolveModuleNamesWorker ( moduleNames : string [ ] , containingFile : SourceFile , partialResolutionInfo : PartialResolutionInfo | undefined ) : readonly ResolvedModuleFull [ ] {
1402
1417
if ( ! moduleNames . length ) return emptyArray ;
1403
1418
const containingFileName = getNormalizedAbsolutePath ( containingFile . originalFileName , currentDirectory ) ;
1404
1419
const redirectedReference = getRedirectReferenceForResolution ( containingFile ) ;
1405
1420
tracing ?. push ( tracing . Phase . Program , "resolveModuleNamesWorker" , { containingFileName } ) ;
1406
1421
performance . mark ( "beforeResolveModule" ) ;
1407
- const result = actualResolveModuleNamesWorker ( moduleNames , containingFile , containingFileName , reusedNames , redirectedReference ) ;
1422
+ const result = actualResolveModuleNamesWorker ( moduleNames , containingFile , containingFileName , redirectedReference , partialResolutionInfo ) ;
1408
1423
performance . mark ( "afterResolveModule" ) ;
1409
1424
performance . measure ( "ResolveModule" , "beforeResolveModule" , "afterResolveModule" ) ;
1410
1425
tracing ?. pop ( ) ;
@@ -1511,7 +1526,7 @@ namespace ts {
1511
1526
if ( structureIsReused === StructureIsReused . Not && ! file . ambientModuleNames . length ) {
1512
1527
// If the old program state does not permit reusing resolutions and `file` does not contain locally defined ambient modules,
1513
1528
// the best we can do is fallback to the default logic.
1514
- return resolveModuleNamesWorker ( moduleNames , file , /*reusedNames */ undefined ) ;
1529
+ return resolveModuleNamesWorker ( moduleNames , file , /*partialResolutionInfo */ undefined ) ;
1515
1530
}
1516
1531
1517
1532
const oldSourceFile = oldProgram && oldProgram . getSourceFile ( file . fileName ) ;
@@ -1540,6 +1555,7 @@ namespace ts {
1540
1555
1541
1556
/** An ordered list of module names for which we cannot recover the resolution. */
1542
1557
let unknownModuleNames : string [ ] | undefined ;
1558
+ let unknownModuleNamesIndex : number [ ] | undefined ;
1543
1559
/**
1544
1560
* The indexing of elements in this list matches that of `moduleNames`.
1545
1561
*
@@ -1550,15 +1566,16 @@ namespace ts {
1550
1566
* * ResolvedModuleFull instance: can be reused.
1551
1567
*/
1552
1568
let result : ( ResolvedModuleFull | undefined ) [ ] | undefined ;
1553
- let reusedNames : string [ ] | undefined ;
1569
+ let reusedNames : { name : string ; mode : ModuleKind . CommonJS | ModuleKind . ESNext | undefined ; } [ ] | undefined ;
1554
1570
/** A transient placeholder used to mark predicted resolution in the result list. */
1555
1571
const predictedToResolveToAmbientModuleMarker : ResolvedModuleFull = { } as any ;
1556
1572
1557
1573
for ( let i = 0 ; i < moduleNames . length ; i ++ ) {
1558
1574
const moduleName = moduleNames [ i ] ;
1559
1575
// If the source file is unchanged and doesnt have invalidated resolution, reuse the module resolutions
1560
1576
if ( file === oldSourceFile && ! hasInvalidatedResolution ( oldSourceFile . path ) ) {
1561
- const oldResolvedModule = getResolvedModule ( oldSourceFile , moduleName , getModeForResolutionAtIndex ( oldSourceFile , i ) ) ;
1577
+ const mode = getModeForResolutionAtIndex ( oldSourceFile , i ) ;
1578
+ const oldResolvedModule = getResolvedModule ( oldSourceFile , moduleName , mode ) ;
1562
1579
if ( oldResolvedModule ) {
1563
1580
if ( isTraceEnabled ( options , host ) ) {
1564
1581
trace ( host ,
@@ -1571,8 +1588,8 @@ namespace ts {
1571
1588
oldResolvedModule . packageId && packageIdToString ( oldResolvedModule . packageId )
1572
1589
) ;
1573
1590
}
1574
- ( result || ( result = new Array ( moduleNames . length ) ) ) [ i ] = oldResolvedModule ;
1575
- ( reusedNames || ( reusedNames = [ ] ) ) . push ( moduleName ) ;
1591
+ ( result ?? = new Array ( moduleNames . length ) ) [ i ] = oldResolvedModule ;
1592
+ ( reusedNames ?? = [ ] ) . push ( { name : moduleName , mode } ) ;
1576
1593
continue ;
1577
1594
}
1578
1595
}
@@ -1596,12 +1613,13 @@ namespace ts {
1596
1613
}
1597
1614
else {
1598
1615
// Resolution failed in the old program, or resolved to an ambient module for which we can't reuse the result.
1599
- ( unknownModuleNames || ( unknownModuleNames = [ ] ) ) . push ( moduleName ) ;
1616
+ ( unknownModuleNames ??= [ ] ) . push ( moduleName ) ;
1617
+ ( unknownModuleNamesIndex ??= [ ] ) . push ( i ) ;
1600
1618
}
1601
1619
}
1602
1620
1603
1621
const resolutions = unknownModuleNames && unknownModuleNames . length
1604
- ? resolveModuleNamesWorker ( unknownModuleNames , file , reusedNames )
1622
+ ? resolveModuleNamesWorker ( unknownModuleNames , file , { reusedNames, namesIndex : unknownModuleNamesIndex ! } )
1605
1623
: emptyArray ;
1606
1624
1607
1625
// Combine results of resolutions and predicted results
0 commit comments