@@ -45,6 +45,7 @@ namespace ts {
45
45
[ "es2018.promise" , "lib.es2018.promise.d.ts" ] ,
46
46
[ "es2018.regexp" , "lib.es2018.regexp.d.ts" ] ,
47
47
[ "es2019.array" , "lib.es2019.array.d.ts" ] ,
48
+ [ "es2019.object" , "lib.es2019.object.d.ts" ] ,
48
49
[ "es2019.string" , "lib.es2019.string.d.ts" ] ,
49
50
[ "es2019.symbol" , "lib.es2019.symbol.d.ts" ] ,
50
51
[ "es2020.string" , "lib.es2020.string.d.ts" ] ,
@@ -218,6 +219,7 @@ namespace ts {
218
219
} ) ,
219
220
affectsSourceFile : true ,
220
221
affectsModuleResolution : true ,
222
+ affectsEmit : true ,
221
223
paramType : Diagnostics . VERSION ,
222
224
showInSimplifiedHelpView : true ,
223
225
category : Diagnostics . Basic_Options ,
@@ -1345,7 +1347,12 @@ namespace ts {
1345
1347
/**
1346
1348
* Reads the config file, reports errors if any and exits if the config file cannot be found
1347
1349
*/
1348
- export function getParsedCommandLineOfConfigFile ( configFileName : string , optionsToExtend : CompilerOptions , host : ParseConfigFileHost ) : ParsedCommandLine | undefined {
1350
+ export function getParsedCommandLineOfConfigFile (
1351
+ configFileName : string ,
1352
+ optionsToExtend : CompilerOptions ,
1353
+ host : ParseConfigFileHost ,
1354
+ extendedConfigCache ?: Map < ExtendedConfigCacheEntry >
1355
+ ) : ParsedCommandLine | undefined {
1349
1356
let configFileText : string | undefined ;
1350
1357
try {
1351
1358
configFileText = host . readFile ( configFileName ) ;
@@ -1366,7 +1373,16 @@ namespace ts {
1366
1373
result . path = toPath ( configFileName , cwd , createGetCanonicalFileName ( host . useCaseSensitiveFileNames ) ) ;
1367
1374
result . resolvedPath = result . path ;
1368
1375
result . originalFileName = result . fileName ;
1369
- return parseJsonSourceFileConfigFileContent ( result , host , getNormalizedAbsolutePath ( getDirectoryPath ( configFileName ) , cwd ) , optionsToExtend , getNormalizedAbsolutePath ( configFileName , cwd ) ) ;
1376
+ return parseJsonSourceFileConfigFileContent (
1377
+ result ,
1378
+ host ,
1379
+ getNormalizedAbsolutePath ( getDirectoryPath ( configFileName ) , cwd ) ,
1380
+ optionsToExtend ,
1381
+ getNormalizedAbsolutePath ( configFileName , cwd ) ,
1382
+ /*resolutionStack*/ undefined ,
1383
+ /*extraFileExtension*/ undefined ,
1384
+ extendedConfigCache
1385
+ ) ;
1370
1386
}
1371
1387
1372
1388
/**
@@ -1980,8 +1996,8 @@ namespace ts {
1980
1996
* @param basePath A root directory to resolve relative path entries in the config
1981
1997
* file to. e.g. outDir
1982
1998
*/
1983
- export function parseJsonSourceFileConfigFileContent ( sourceFile : TsConfigSourceFile , host : ParseConfigHost , basePath : string , existingOptions ?: CompilerOptions , configFileName ?: string , resolutionStack ?: Path [ ] , extraFileExtensions ?: ReadonlyArray < FileExtensionInfo > ) : ParsedCommandLine {
1984
- return parseJsonConfigFileContentWorker ( /*json*/ undefined , sourceFile , host , basePath , existingOptions , configFileName , resolutionStack , extraFileExtensions ) ;
1999
+ export function parseJsonSourceFileConfigFileContent ( sourceFile : TsConfigSourceFile , host : ParseConfigHost , basePath : string , existingOptions ?: CompilerOptions , configFileName ?: string , resolutionStack ?: Path [ ] , extraFileExtensions ?: ReadonlyArray < FileExtensionInfo > , /* @internal */ extendedConfigCache ?: Map < ExtendedConfigCacheEntry > ) : ParsedCommandLine {
2000
+ return parseJsonConfigFileContentWorker ( /*json*/ undefined , sourceFile , host , basePath , existingOptions , configFileName , resolutionStack , extraFileExtensions , extendedConfigCache ) ;
1985
2001
}
1986
2002
1987
2003
/*@internal */
@@ -2020,11 +2036,12 @@ namespace ts {
2020
2036
configFileName ?: string ,
2021
2037
resolutionStack : Path [ ] = [ ] ,
2022
2038
extraFileExtensions : ReadonlyArray < FileExtensionInfo > = [ ] ,
2039
+ extendedConfigCache ?: Map < ExtendedConfigCacheEntry >
2023
2040
) : ParsedCommandLine {
2024
2041
Debug . assert ( ( json === undefined && sourceFile !== undefined ) || ( json !== undefined && sourceFile === undefined ) ) ;
2025
2042
const errors : Diagnostic [ ] = [ ] ;
2026
2043
2027
- const parsedConfig = parseConfig ( json , sourceFile , host , basePath , configFileName , resolutionStack , errors ) ;
2044
+ const parsedConfig = parseConfig ( json , sourceFile , host , basePath , configFileName , resolutionStack , errors , extendedConfigCache ) ;
2028
2045
const { raw } = parsedConfig ;
2029
2046
const options = extend ( existingOptions , parsedConfig . options || { } ) ;
2030
2047
options . configFilePath = configFileName && normalizeSlashes ( configFileName ) ;
@@ -2172,7 +2189,7 @@ namespace ts {
2172
2189
return existingErrors !== configParseDiagnostics . length ;
2173
2190
}
2174
2191
2175
- interface ParsedTsconfig {
2192
+ export interface ParsedTsconfig {
2176
2193
raw : any ;
2177
2194
options ?: CompilerOptions ;
2178
2195
typeAcquisition ?: TypeAcquisition ;
@@ -2191,13 +2208,14 @@ namespace ts {
2191
2208
* It does *not* resolve the included files.
2192
2209
*/
2193
2210
function parseConfig (
2194
- json : any ,
2195
- sourceFile : TsConfigSourceFile | undefined ,
2196
- host : ParseConfigHost ,
2197
- basePath : string ,
2198
- configFileName : string | undefined ,
2199
- resolutionStack : string [ ] ,
2200
- errors : Push < Diagnostic > ,
2211
+ json : any ,
2212
+ sourceFile : TsConfigSourceFile | undefined ,
2213
+ host : ParseConfigHost ,
2214
+ basePath : string ,
2215
+ configFileName : string | undefined ,
2216
+ resolutionStack : string [ ] ,
2217
+ errors : Push < Diagnostic > ,
2218
+ extendedConfigCache ?: Map < ExtendedConfigCacheEntry >
2201
2219
) : ParsedTsconfig {
2202
2220
basePath = normalizeSlashes ( basePath ) ;
2203
2221
const resolvedPath = getNormalizedAbsolutePath ( configFileName || "" , basePath ) ;
@@ -2214,7 +2232,7 @@ namespace ts {
2214
2232
if ( ownConfig . extendedConfigPath ) {
2215
2233
// copy the resolution stack so it is never reused between branches in potential diamond-problem scenarios.
2216
2234
resolutionStack = resolutionStack . concat ( [ resolvedPath ] ) ;
2217
- const extendedConfig = getExtendedConfig ( sourceFile , ownConfig . extendedConfigPath , host , basePath , resolutionStack , errors ) ;
2235
+ const extendedConfig = getExtendedConfig ( sourceFile , ownConfig . extendedConfigPath , host , basePath , resolutionStack , errors , extendedConfigCache ) ;
2218
2236
if ( extendedConfig && isSuccessfulParsedTsconfig ( extendedConfig ) ) {
2219
2237
const baseRaw = extendedConfig . raw ;
2220
2238
const raw = ownConfig . raw ;
@@ -2358,47 +2376,65 @@ namespace ts {
2358
2376
return undefined ;
2359
2377
}
2360
2378
2379
+ export interface ExtendedConfigCacheEntry {
2380
+ extendedResult : TsConfigSourceFile ;
2381
+ extendedConfig : ParsedTsconfig | undefined ;
2382
+ }
2383
+
2361
2384
function getExtendedConfig (
2362
2385
sourceFile : TsConfigSourceFile | undefined ,
2363
2386
extendedConfigPath : string ,
2364
2387
host : ParseConfigHost ,
2365
2388
basePath : string ,
2366
2389
resolutionStack : string [ ] ,
2367
2390
errors : Push < Diagnostic > ,
2391
+ extendedConfigCache ?: Map < ExtendedConfigCacheEntry >
2368
2392
) : ParsedTsconfig | undefined {
2369
- const extendedResult = readJsonConfigFile ( extendedConfigPath , path => host . readFile ( path ) ) ;
2393
+ const path = host . useCaseSensitiveFileNames ? extendedConfigPath : toLowerCase ( extendedConfigPath ) ;
2394
+ let value : ExtendedConfigCacheEntry | undefined ;
2395
+ let extendedResult : TsConfigSourceFile ;
2396
+ let extendedConfig : ParsedTsconfig | undefined ;
2397
+ if ( extendedConfigCache && ( value = extendedConfigCache . get ( path ) ) ) {
2398
+ ( { extendedResult, extendedConfig } = value ) ;
2399
+ }
2400
+ else {
2401
+ extendedResult = readJsonConfigFile ( extendedConfigPath , path => host . readFile ( path ) ) ;
2402
+ if ( ! extendedResult . parseDiagnostics . length ) {
2403
+ const extendedDirname = getDirectoryPath ( extendedConfigPath ) ;
2404
+ extendedConfig = parseConfig ( /*json*/ undefined , extendedResult , host , extendedDirname ,
2405
+ getBaseFileName ( extendedConfigPath ) , resolutionStack , errors , extendedConfigCache ) ;
2406
+
2407
+ if ( isSuccessfulParsedTsconfig ( extendedConfig ) ) {
2408
+ // Update the paths to reflect base path
2409
+ const relativeDifference = convertToRelativePath ( extendedDirname , basePath , identity ) ;
2410
+ const updatePath = ( path : string ) => isRootedDiskPath ( path ) ? path : combinePaths ( relativeDifference , path ) ;
2411
+ const mapPropertiesInRawIfNotUndefined = ( propertyName : string ) => {
2412
+ if ( raw [ propertyName ] ) {
2413
+ raw [ propertyName ] = map ( raw [ propertyName ] , updatePath ) ;
2414
+ }
2415
+ } ;
2416
+
2417
+ const { raw } = extendedConfig ;
2418
+ mapPropertiesInRawIfNotUndefined ( "include" ) ;
2419
+ mapPropertiesInRawIfNotUndefined ( "exclude" ) ;
2420
+ mapPropertiesInRawIfNotUndefined ( "files" ) ;
2421
+ }
2422
+ }
2423
+ if ( extendedConfigCache ) {
2424
+ extendedConfigCache . set ( path , { extendedResult, extendedConfig } ) ;
2425
+ }
2426
+ }
2370
2427
if ( sourceFile ) {
2371
2428
sourceFile . extendedSourceFiles = [ extendedResult . fileName ] ;
2429
+ if ( extendedResult . extendedSourceFiles ) {
2430
+ sourceFile . extendedSourceFiles . push ( ...extendedResult . extendedSourceFiles ) ;
2431
+ }
2372
2432
}
2373
2433
if ( extendedResult . parseDiagnostics . length ) {
2374
2434
errors . push ( ...extendedResult . parseDiagnostics ) ;
2375
2435
return undefined ;
2376
2436
}
2377
-
2378
- const extendedDirname = getDirectoryPath ( extendedConfigPath ) ;
2379
- const extendedConfig = parseConfig ( /*json*/ undefined , extendedResult , host , extendedDirname ,
2380
- getBaseFileName ( extendedConfigPath ) , resolutionStack , errors ) ;
2381
- if ( sourceFile && extendedResult . extendedSourceFiles ) {
2382
- sourceFile . extendedSourceFiles ! . push ( ...extendedResult . extendedSourceFiles ) ;
2383
- }
2384
-
2385
- if ( isSuccessfulParsedTsconfig ( extendedConfig ) ) {
2386
- // Update the paths to reflect base path
2387
- const relativeDifference = convertToRelativePath ( extendedDirname , basePath , identity ) ;
2388
- const updatePath = ( path : string ) => isRootedDiskPath ( path ) ? path : combinePaths ( relativeDifference , path ) ;
2389
- const mapPropertiesInRawIfNotUndefined = ( propertyName : string ) => {
2390
- if ( raw [ propertyName ] ) {
2391
- raw [ propertyName ] = map ( raw [ propertyName ] , updatePath ) ;
2392
- }
2393
- } ;
2394
-
2395
- const { raw } = extendedConfig ;
2396
- mapPropertiesInRawIfNotUndefined ( "include" ) ;
2397
- mapPropertiesInRawIfNotUndefined ( "exclude" ) ;
2398
- mapPropertiesInRawIfNotUndefined ( "files" ) ;
2399
- }
2400
-
2401
- return extendedConfig ;
2437
+ return extendedConfig ! ;
2402
2438
}
2403
2439
2404
2440
function convertCompileOnSaveOptionFromJson ( jsonOption : any , basePath : string , errors : Push < Diagnostic > ) : boolean {
0 commit comments