@@ -224,6 +224,7 @@ namespace ts {
224
224
path : Path ;
225
225
buildInfo : BuildInfo | false ;
226
226
modifiedTime : Date ;
227
+ dtsChangeTime ?: Date | false ;
227
228
}
228
229
229
230
interface SolutionBuilderState < T extends BuilderProgram = BuilderProgram > extends WatchFactory < WatchType , ResolvedConfigFileName > {
@@ -980,21 +981,17 @@ namespace ts {
980
981
981
982
// Actual Emit
982
983
const { host, compilerHost } = state ;
983
- const hasChangedEmitSignature = program . hasChangedEmitSignature ?.( ) ;
984
- let resultFlags = hasChangedEmitSignature ? BuildResultFlags . None : BuildResultFlags . DeclarationOutputUnchanged ;
984
+ const resultFlags = program . hasChangedEmitSignature ?.( ) ? BuildResultFlags . None : BuildResultFlags . DeclarationOutputUnchanged ;
985
985
const emitterDiagnostics = createDiagnosticCollection ( ) ;
986
986
const emittedOutputs = new Map < Path , string > ( ) ;
987
987
const options = program . getCompilerOptions ( ) ;
988
988
const isIncremental = isIncrementalCompilation ( options ) ;
989
989
let outputTimeStampMap : ESMap < Path , Date > | undefined ;
990
990
let now : Date | undefined ;
991
- // Check dts write only if hasChangedEmitSignature is not implemented
992
- const checkDtsChange = options . composite && hasChangedEmitSignature === undefined ;
993
991
outputFiles . forEach ( ( { name, text, writeByteOrderMark, buildInfo } ) => {
994
992
const path = toPath ( state , name ) ;
995
993
emittedOutputs . set ( toPath ( state , name ) , name ) ;
996
- if ( checkDtsChange && isDeclarationFileName ( name ) ) resultFlags &= ~ BuildResultFlags . DeclarationOutputUnchanged ;
997
- if ( buildInfo ) setBuildInfo ( state , buildInfo , projectPath , options ) ;
994
+ if ( buildInfo ) setBuildInfo ( state , buildInfo , projectPath , options , resultFlags ) ;
998
995
writeFile ( writeFileCallback ? { writeFile : writeFileCallback } : compilerHost , emitterDiagnostics , name , text , writeByteOrderMark ) ;
999
996
if ( ! isIncremental && state . watch ) {
1000
997
( outputTimeStampMap ||= getOutputTimeStampMap ( state , projectPath ) ! ) . set ( path , now ||= getCurrentTime ( state . host ) ) ;
@@ -1014,7 +1011,7 @@ namespace ts {
1014
1011
Debug . assertIsDefined ( program ) ;
1015
1012
Debug . assert ( step === BuildStep . EmitBuildInfo ) ;
1016
1013
const emitResult = program . emitBuildInfo ( ( name , text , writeByteOrderMark , onError , sourceFiles , data ) => {
1017
- if ( data ?. buildInfo ) setBuildInfo ( state , data . buildInfo , projectPath , program ! . getCompilerOptions ( ) ) ;
1014
+ if ( data ?. buildInfo ) setBuildInfo ( state , data . buildInfo , projectPath , program ! . getCompilerOptions ( ) , BuildResultFlags . DeclarationOutputUnchanged ) ;
1018
1015
if ( writeFileCallback ) writeFileCallback ( name , text , writeByteOrderMark , onError , sourceFiles , data ) ;
1019
1016
else state . compilerHost . writeFile ( name , text , writeByteOrderMark , onError , sourceFiles , data ) ;
1020
1017
} , cancellationToken ) ;
@@ -1113,10 +1110,15 @@ namespace ts {
1113
1110
const emitterDiagnostics = createDiagnosticCollection ( ) ;
1114
1111
const emittedOutputs = new Map < Path , string > ( ) ;
1115
1112
let resultFlags = BuildResultFlags . DeclarationOutputUnchanged ;
1113
+ const existingBuildInfo = state . buildInfoCache . get ( projectPath ) ! . buildInfo as BuildInfo ;
1116
1114
outputFiles . forEach ( ( { name, text, writeByteOrderMark, buildInfo } ) => {
1117
1115
emittedOutputs . set ( toPath ( state , name ) , name ) ;
1118
- if ( isDeclarationFileName ( name ) ) resultFlags &= ~ BuildResultFlags . DeclarationOutputUnchanged ;
1119
- if ( buildInfo ) setBuildInfo ( state , buildInfo , projectPath , config . options ) ;
1116
+ if ( buildInfo ) {
1117
+ if ( ( buildInfo . program as ProgramBundleEmitBuildInfo ) ?. outSignature !== ( existingBuildInfo . program as ProgramBundleEmitBuildInfo ) ?. outSignature ) {
1118
+ resultFlags &= ~ BuildResultFlags . DeclarationOutputUnchanged ;
1119
+ }
1120
+ setBuildInfo ( state , buildInfo , projectPath , config . options , resultFlags ) ;
1121
+ }
1120
1122
writeFile ( writeFileCallback ? { writeFile : writeFileCallback } : compilerHost , emitterDiagnostics , name , text , writeByteOrderMark ) ;
1121
1123
} ) ;
1122
1124
@@ -1456,15 +1458,28 @@ namespace ts {
1456
1458
return result ;
1457
1459
}
1458
1460
1459
- function setBuildInfo ( state : SolutionBuilderState , buildInfo : BuildInfo , resolvedConfigPath : ResolvedConfigFilePath , options : CompilerOptions ) {
1461
+ function setBuildInfo (
1462
+ state : SolutionBuilderState ,
1463
+ buildInfo : BuildInfo ,
1464
+ resolvedConfigPath : ResolvedConfigFilePath ,
1465
+ options : CompilerOptions ,
1466
+ resultFlags : BuildResultFlags ,
1467
+ ) {
1460
1468
const buildInfoPath = getTsBuildInfoEmitOutputFilePath ( options ) ! ;
1461
1469
const existing = getBuildInfoCacheEntry ( state , buildInfoPath , resolvedConfigPath ) ;
1470
+ const modifiedTime = getCurrentTime ( state . host ) ;
1462
1471
if ( existing ) {
1463
1472
existing . buildInfo = buildInfo ;
1464
- existing . modifiedTime = getCurrentTime ( state . host ) ;
1473
+ existing . modifiedTime = modifiedTime ;
1474
+ if ( ! ( resultFlags & BuildResultFlags . DeclarationOutputUnchanged ) ) existing . dtsChangeTime = modifiedTime ;
1465
1475
}
1466
1476
else {
1467
- state . buildInfoCache . set ( resolvedConfigPath , { path : toPath ( state , buildInfoPath ) , buildInfo, modifiedTime : getCurrentTime ( state . host ) } ) ;
1477
+ state . buildInfoCache . set ( resolvedConfigPath , {
1478
+ path : toPath ( state , buildInfoPath ) ,
1479
+ buildInfo,
1480
+ modifiedTime,
1481
+ dtsChangeTime : resultFlags & BuildResultFlags . DeclarationOutputUnchanged ? undefined : modifiedTime ,
1482
+ } ) ;
1468
1483
}
1469
1484
}
1470
1485
@@ -1474,17 +1489,19 @@ namespace ts {
1474
1489
return existing ?. path === path ? existing : undefined ;
1475
1490
}
1476
1491
1477
- function getBuildInfo ( state : SolutionBuilderState , buildInfoPath : string , resolvedConfigPath : ResolvedConfigFilePath , modifiedTime : Date | undefined ) : BuildInfo | undefined {
1492
+ function getOrCreateBuildInfoCacheEntry ( state : SolutionBuilderState , buildInfoPath : string , resolvedConfigPath : ResolvedConfigFilePath , modifiedTime : Date | undefined ) {
1478
1493
const path = toPath ( state , buildInfoPath ) ;
1479
- const existing = state . buildInfoCache . get ( resolvedConfigPath ) ;
1480
- if ( existing !== undefined && existing . path === path ) {
1481
- return existing . buildInfo || undefined ;
1482
- }
1494
+ let result = state . buildInfoCache . get ( resolvedConfigPath ) ;
1495
+ if ( result && result . path === path ) return result ;
1483
1496
const value = state . readFileWithCache ( buildInfoPath ) ;
1484
1497
const buildInfo = value ? ts . getBuildInfo ( value ) : undefined ;
1485
1498
Debug . assert ( modifiedTime || ! buildInfo ) ;
1486
- state . buildInfoCache . set ( resolvedConfigPath , { path, buildInfo : buildInfo || false , modifiedTime : modifiedTime || missingFileModifiedTime } ) ;
1487
- return buildInfo ;
1499
+ state . buildInfoCache . set ( resolvedConfigPath , result = { path, buildInfo : buildInfo || false , modifiedTime : modifiedTime || missingFileModifiedTime } ) ;
1500
+ return result ;
1501
+ }
1502
+
1503
+ function getBuildInfo ( state : SolutionBuilderState , buildInfoPath : string , resolvedConfigPath : ResolvedConfigFilePath , modifiedTime : Date | undefined ) : BuildInfo | undefined {
1504
+ return getOrCreateBuildInfoCacheEntry ( state , buildInfoPath , resolvedConfigPath , modifiedTime ) . buildInfo || undefined ;
1488
1505
}
1489
1506
1490
1507
function checkConfigFileUpToDateStatus ( state : SolutionBuilderState , configFile : string , oldestOutputFileTime : Date , oldestOutputFileName : string ) : Status . OutOfDateWithSelf | undefined {
@@ -1555,7 +1572,6 @@ namespace ts {
1555
1572
let buildInfoTime : Date | undefined ;
1556
1573
let buildInfoProgram : ProgramBuildInfo | undefined ;
1557
1574
let buildInfoVersionMap : ESMap < Path , string > | undefined ;
1558
- let newestDeclarationFileContentChangedTime ;
1559
1575
if ( buildInfoPath ) {
1560
1576
const buildInfoCacheEntry = getBuildInfoCacheEntry ( state , buildInfoPath , resolvedPath ) ;
1561
1577
buildInfoTime = buildInfoCacheEntry ?. modifiedTime || ts . getModifiedTime ( host , buildInfoPath ) ;
@@ -1595,8 +1611,6 @@ namespace ts {
1595
1611
1596
1612
oldestOutputFileTime = buildInfoTime ;
1597
1613
oldestOutputFileName = buildInfoPath ;
1598
- // Get the last dtsChange time from build info
1599
- newestDeclarationFileContentChangedTime = buildInfo . program ?. dtsChangeTime ? new Date ( buildInfo . program . dtsChangeTime ) : undefined ;
1600
1614
}
1601
1615
1602
1616
// Check input files
@@ -1756,7 +1770,7 @@ namespace ts {
1756
1770
pseudoInputUpToDate ?
1757
1771
UpToDateStatusType . UpToDateWithInputFileText :
1758
1772
UpToDateStatusType . UpToDate ,
1759
- newestDeclarationFileContentChangedTime,
1773
+ newestDeclarationFileContentChangedTime : getDtsChangeTime ( state , project . options , resolvedPath ) ,
1760
1774
newestInputFileTime,
1761
1775
newestInputFileName,
1762
1776
oldestOutputFileName : oldestOutputFileName !
@@ -1849,8 +1863,13 @@ namespace ts {
1849
1863
function getDtsChangeTime ( state : SolutionBuilderState , options : CompilerOptions , resolvedConfigPath : ResolvedConfigFilePath ) {
1850
1864
if ( ! options . composite ) return undefined ;
1851
1865
const buildInfoPath = getTsBuildInfoEmitOutputFilePath ( options ) ! ;
1852
- const buildInfo = getBuildInfo ( state , buildInfoPath , resolvedConfigPath , /*modifiedTime*/ undefined ) ;
1853
- return buildInfo ?. program ?. dtsChangeTime ? new Date ( buildInfo . program . dtsChangeTime ) : undefined ;
1866
+ const entry = getOrCreateBuildInfoCacheEntry ( state , buildInfoPath , resolvedConfigPath , /*modifiedTime*/ undefined ) ;
1867
+ if ( entry . dtsChangeTime !== undefined ) return entry . dtsChangeTime || undefined ;
1868
+ const dtsChangeTime = entry . buildInfo && entry . buildInfo . program && entry . buildInfo . program . dtsChangeFile ?
1869
+ state . host . getModifiedTime ( getNormalizedAbsolutePath ( entry . buildInfo . program . dtsChangeFile , getDirectoryPath ( entry . path ) ) ) :
1870
+ undefined ;
1871
+ entry . dtsChangeTime = dtsChangeTime || false ;
1872
+ return dtsChangeTime ;
1854
1873
}
1855
1874
1856
1875
function updateOutputTimestamps ( state : SolutionBuilderState , proj : ParsedCommandLine , resolvedPath : ResolvedConfigFilePath ) {
0 commit comments