@@ -817,6 +817,8 @@ namespace ts {
817
817
let resolvedProjectReferences : readonly ( ResolvedProjectReference | undefined ) [ ] | undefined ;
818
818
let projectReferenceRedirects : Map < ResolvedProjectReference | false > | undefined ;
819
819
let mapFromFileToProjectReferenceRedirects : Map < Path > | undefined ;
820
+ let mapFromToProjectReferenceRedirectSource : Map < SourceOfProjectReferenceRedirect > | undefined ;
821
+ const useSourceOfProjectReferenceRedirect = ! ! host . useSourceOfProjectReferenceRedirect && host . useSourceOfProjectReferenceRedirect ( ) ;
820
822
821
823
const shouldCreateNewSourceFile = shouldProgramCreateNewSourceFiles ( oldProgram , options ) ;
822
824
// We set `structuralIsReused` to `undefined` because `tryReuseStructureFromOldProgram` calls `tryReuseStructureFromOldProgram` which checks
@@ -831,17 +833,32 @@ namespace ts {
831
833
if ( ! resolvedProjectReferences ) {
832
834
resolvedProjectReferences = projectReferences . map ( parseProjectReferenceConfigFile ) ;
833
835
}
836
+ if ( host . setResolvedProjectReferenceCallbacks ) {
837
+ host . setResolvedProjectReferenceCallbacks ( {
838
+ getSourceOfProjectReferenceRedirect,
839
+ forEachResolvedProjectReference
840
+ } ) ;
841
+ }
834
842
if ( rootNames . length ) {
835
843
for ( const parsedRef of resolvedProjectReferences ) {
836
844
if ( ! parsedRef ) continue ;
837
845
const out = parsedRef . commandLine . options . outFile || parsedRef . commandLine . options . out ;
838
- if ( out ) {
839
- processSourceFile ( changeExtension ( out , ".d.ts" ) , /*isDefaultLib*/ false , /*ignoreNoDefaultLib*/ false , /*packageId*/ undefined ) ;
846
+ if ( useSourceOfProjectReferenceRedirect ) {
847
+ if ( out || getEmitModuleKind ( parsedRef . commandLine . options ) === ModuleKind . None ) {
848
+ for ( const fileName of parsedRef . commandLine . fileNames ) {
849
+ processSourceFile ( fileName , /*isDefaultLib*/ false , /*ignoreNoDefaultLib*/ false , /*packageId*/ undefined ) ;
850
+ }
851
+ }
840
852
}
841
- else if ( getEmitModuleKind ( parsedRef . commandLine . options ) === ModuleKind . None ) {
842
- for ( const fileName of parsedRef . commandLine . fileNames ) {
843
- if ( ! fileExtensionIs ( fileName , Extension . Dts ) && hasTSFileExtension ( fileName ) ) {
844
- processSourceFile ( getOutputDeclarationFileName ( fileName , parsedRef . commandLine , ! host . useCaseSensitiveFileNames ( ) ) , /*isDefaultLib*/ false , /*ignoreNoDefaultLib*/ false , /*packageId*/ undefined ) ;
853
+ else {
854
+ if ( out ) {
855
+ processSourceFile ( changeExtension ( out , ".d.ts" ) , /*isDefaultLib*/ false , /*ignoreNoDefaultLib*/ false , /*packageId*/ undefined ) ;
856
+ }
857
+ else if ( getEmitModuleKind ( parsedRef . commandLine . options ) === ModuleKind . None ) {
858
+ for ( const fileName of parsedRef . commandLine . fileNames ) {
859
+ if ( ! fileExtensionIs ( fileName , Extension . Dts ) && hasTSFileExtension ( fileName ) ) {
860
+ processSourceFile ( getOutputDeclarationFileName ( fileName , parsedRef . commandLine , ! host . useCaseSensitiveFileNames ( ) ) , /*isDefaultLib*/ false , /*ignoreNoDefaultLib*/ false , /*packageId*/ undefined ) ;
861
+ }
845
862
}
846
863
}
847
864
}
@@ -955,6 +972,7 @@ namespace ts {
955
972
getResolvedProjectReferenceToRedirect,
956
973
getResolvedProjectReferenceByPath,
957
974
forEachResolvedProjectReference,
975
+ isSourceOfProjectReferenceRedirect,
958
976
emitBuildInfo
959
977
} ;
960
978
@@ -987,9 +1005,15 @@ namespace ts {
987
1005
return ts . toPath ( fileName , currentDirectory , getCanonicalFileName ) ;
988
1006
}
989
1007
1008
+ function isValidSourceFileForEmit ( file : SourceFile ) {
1009
+ // source file is allowed to be emitted and its not source of project reference redirect
1010
+ return sourceFileMayBeEmitted ( file , options , isSourceFileFromExternalLibrary , getResolvedProjectReferenceToRedirect ) &&
1011
+ ! isSourceOfProjectReferenceRedirect ( file . fileName ) ;
1012
+ }
1013
+
990
1014
function getCommonSourceDirectory ( ) {
991
1015
if ( commonSourceDirectory === undefined ) {
992
- const emittedFiles = filter ( files , file => sourceFileMayBeEmitted ( file , options , isSourceFileFromExternalLibrary , getResolvedProjectReferenceToRedirect ) ) ;
1016
+ const emittedFiles = filter ( files , file => isValidSourceFileForEmit ( file ) ) ;
993
1017
if ( options . rootDir && checkSourceFilesBelongToPath ( emittedFiles , options . rootDir ) ) {
994
1018
// If a rootDir is specified use it as the commonSourceDirectory
995
1019
commonSourceDirectory = getNormalizedAbsolutePath ( options . rootDir , currentDirectory ) ;
@@ -1220,6 +1244,12 @@ namespace ts {
1220
1244
}
1221
1245
if ( projectReferences ) {
1222
1246
resolvedProjectReferences = projectReferences . map ( parseProjectReferenceConfigFile ) ;
1247
+ if ( host . setResolvedProjectReferenceCallbacks ) {
1248
+ host . setResolvedProjectReferenceCallbacks ( {
1249
+ getSourceOfProjectReferenceRedirect,
1250
+ forEachResolvedProjectReference
1251
+ } ) ;
1252
+ }
1223
1253
}
1224
1254
1225
1255
// check if program source files has changed in the way that can affect structure of the program
@@ -1403,6 +1433,13 @@ namespace ts {
1403
1433
for ( const newSourceFile of newSourceFiles ) {
1404
1434
const filePath = newSourceFile . path ;
1405
1435
addFileToFilesByName ( newSourceFile , filePath , newSourceFile . resolvedPath ) ;
1436
+ if ( useSourceOfProjectReferenceRedirect ) {
1437
+ const redirectProject = getProjectReferenceRedirectProject ( newSourceFile . fileName ) ;
1438
+ if ( redirectProject && ! ( redirectProject . commandLine . options . outFile || redirectProject . commandLine . options . out ) ) {
1439
+ const redirect = getProjectReferenceOutputName ( redirectProject , newSourceFile . fileName ) ;
1440
+ addFileToFilesByName ( newSourceFile , toPath ( redirect ) , /*redirectedPath*/ undefined ) ;
1441
+ }
1442
+ }
1406
1443
// Set the file as found during node modules search if it was found that way in old progra,
1407
1444
if ( oldProgram . isSourceFileFromExternalLibrary ( oldProgram . getSourceFileByPath ( newSourceFile . resolvedPath ) ! ) ) {
1408
1445
sourceFilesFoundSearchingNodeModules . set ( filePath , true ) ;
@@ -1682,7 +1719,7 @@ namespace ts {
1682
1719
1683
1720
function getSemanticDiagnosticsForFileNoCache ( sourceFile : SourceFile , cancellationToken : CancellationToken ) : Diagnostic [ ] | undefined {
1684
1721
return runWithCancellationToken ( ( ) => {
1685
- if ( skipTypeChecking ( sourceFile , options ) ) {
1722
+ if ( skipTypeChecking ( sourceFile , options , program ) ) {
1686
1723
return emptyArray ;
1687
1724
}
1688
1725
@@ -2234,6 +2271,16 @@ namespace ts {
2234
2271
2235
2272
// Get source file from normalized fileName
2236
2273
function findSourceFile ( fileName : string , path : Path , isDefaultLib : boolean , ignoreNoDefaultLib : boolean , refFile : RefFile | undefined , packageId : PackageId | undefined ) : SourceFile | undefined {
2274
+ if ( useSourceOfProjectReferenceRedirect ) {
2275
+ const source = getSourceOfProjectReferenceRedirect ( fileName ) ;
2276
+ if ( source ) {
2277
+ const file = isString ( source ) ?
2278
+ findSourceFile ( source , toPath ( source ) , isDefaultLib , ignoreNoDefaultLib , refFile , packageId ) :
2279
+ undefined ;
2280
+ if ( file ) addFileToFilesByName ( file , path , /*redirectedPath*/ undefined ) ;
2281
+ return file ;
2282
+ }
2283
+ }
2237
2284
const originalFileName = fileName ;
2238
2285
if ( filesByName . has ( path ) ) {
2239
2286
const file = filesByName . get ( path ) ;
@@ -2282,7 +2329,7 @@ namespace ts {
2282
2329
}
2283
2330
2284
2331
let redirectedPath : Path | undefined ;
2285
- if ( refFile ) {
2332
+ if ( refFile && ! useSourceOfProjectReferenceRedirect ) {
2286
2333
const redirectProject = getProjectReferenceRedirectProject ( fileName ) ;
2287
2334
if ( redirectProject ) {
2288
2335
if ( redirectProject . commandLine . options . outFile || redirectProject . commandLine . options . out ) {
@@ -2451,6 +2498,36 @@ namespace ts {
2451
2498
} ) ;
2452
2499
}
2453
2500
2501
+ function getSourceOfProjectReferenceRedirect ( file : string ) {
2502
+ if ( ! isDeclarationFileName ( file ) ) return undefined ;
2503
+ if ( mapFromToProjectReferenceRedirectSource === undefined ) {
2504
+ mapFromToProjectReferenceRedirectSource = createMap ( ) ;
2505
+ forEachResolvedProjectReference ( resolvedRef => {
2506
+ if ( resolvedRef ) {
2507
+ const out = resolvedRef . commandLine . options . outFile || resolvedRef . commandLine . options . out ;
2508
+ if ( out ) {
2509
+ // Dont know which source file it means so return true?
2510
+ const outputDts = changeExtension ( out , Extension . Dts ) ;
2511
+ mapFromToProjectReferenceRedirectSource ! . set ( toPath ( outputDts ) , true ) ;
2512
+ }
2513
+ else {
2514
+ forEach ( resolvedRef . commandLine . fileNames , fileName => {
2515
+ if ( ! fileExtensionIs ( fileName , Extension . Dts ) && hasTSFileExtension ( fileName ) ) {
2516
+ const outputDts = getOutputDeclarationFileName ( fileName , resolvedRef . commandLine , host . useCaseSensitiveFileNames ( ) ) ;
2517
+ mapFromToProjectReferenceRedirectSource ! . set ( toPath ( outputDts ) , fileName ) ;
2518
+ }
2519
+ } ) ;
2520
+ }
2521
+ }
2522
+ } ) ;
2523
+ }
2524
+ return mapFromToProjectReferenceRedirectSource . get ( toPath ( file ) ) ;
2525
+ }
2526
+
2527
+ function isSourceOfProjectReferenceRedirect ( fileName : string ) {
2528
+ return useSourceOfProjectReferenceRedirect && ! ! getResolvedProjectReferenceToRedirect ( fileName ) ;
2529
+ }
2530
+
2454
2531
function forEachProjectReference < T > (
2455
2532
projectReferences : readonly ProjectReference [ ] | undefined ,
2456
2533
resolvedProjectReferences : readonly ( ResolvedProjectReference | undefined ) [ ] | undefined ,
@@ -2858,8 +2935,7 @@ namespace ts {
2858
2935
const rootPaths = arrayToSet ( rootNames , toPath ) ;
2859
2936
for ( const file of files ) {
2860
2937
// Ignore file that is not emitted
2861
- if ( ! sourceFileMayBeEmitted ( file , options , isSourceFileFromExternalLibrary , getResolvedProjectReferenceToRedirect ) ) continue ;
2862
- if ( ! rootPaths . has ( file . path ) ) {
2938
+ if ( isValidSourceFileForEmit ( file ) && ! rootPaths . has ( file . path ) ) {
2863
2939
addProgramDiagnosticAtRefPath (
2864
2940
file ,
2865
2941
rootPaths ,
0 commit comments