@@ -2308,53 +2308,48 @@ namespace ts {
2308
2308
} ;
2309
2309
2310
2310
function getFileNames ( ) : ExpandResult {
2311
- let filesSpecs : readonly string [ ] | undefined ;
2312
- if ( hasProperty ( raw , "files" ) && ! isNullOrUndefined ( raw . files ) ) {
2313
- if ( isArray ( raw . files ) ) {
2314
- filesSpecs = < readonly string [ ] > raw . files ;
2315
- const hasReferences = hasProperty ( raw , "references" ) && ! isNullOrUndefined ( raw . references ) ;
2316
- const hasZeroOrNoReferences = ! hasReferences || raw . references . length === 0 ;
2317
- const hasExtends = hasProperty ( raw , "extends" ) ;
2318
- if ( filesSpecs . length === 0 && hasZeroOrNoReferences && ! hasExtends ) {
2319
- if ( sourceFile ) {
2320
- const fileName = configFileName || "tsconfig.json" ;
2321
- const diagnosticMessage = Diagnostics . The_files_list_in_config_file_0_is_empty ;
2322
- const nodeValue = firstDefined ( getTsConfigPropArray ( sourceFile , "files" ) , property => property . initializer ) ;
2323
- const error = nodeValue
2324
- ? createDiagnosticForNodeInSourceFile ( sourceFile , nodeValue , diagnosticMessage , fileName )
2325
- : createCompilerDiagnostic ( diagnosticMessage , fileName ) ;
2326
- errors . push ( error ) ;
2327
- }
2328
- else {
2329
- createCompilerDiagnosticOnlyIfJson ( Diagnostics . The_files_list_in_config_file_0_is_empty , configFileName || "tsconfig.json" ) ;
2330
- }
2311
+ const referencesOfRaw = getPropFromRaw < ProjectReference > ( "references" , element => typeof element === "object" , "object" ) ;
2312
+ if ( isArray ( referencesOfRaw ) ) {
2313
+ for ( const ref of referencesOfRaw ) {
2314
+ if ( typeof ref . path !== "string" ) {
2315
+ createCompilerDiagnosticOnlyIfJson ( Diagnostics . Compiler_option_0_requires_a_value_of_type_1 , "reference.path" , "string" ) ;
2316
+ }
2317
+ else {
2318
+ ( projectReferences || ( projectReferences = [ ] ) ) . push ( {
2319
+ path : getNormalizedAbsolutePath ( ref . path , basePath ) ,
2320
+ originalPath : ref . path ,
2321
+ prepend : ref . prepend ,
2322
+ circular : ref . circular
2323
+ } ) ;
2331
2324
}
2332
- }
2333
- else {
2334
- createCompilerDiagnosticOnlyIfJson ( Diagnostics . Compiler_option_0_requires_a_value_of_type_1 , "files" , "Array" ) ;
2335
2325
}
2336
2326
}
2337
2327
2338
- let includeSpecs : readonly string [ ] | undefined ;
2339
- if ( hasProperty ( raw , "include" ) && ! isNullOrUndefined ( raw . include ) ) {
2340
- if ( isArray ( raw . include ) ) {
2341
- includeSpecs = < readonly string [ ] > raw . include ;
2342
- }
2343
- else {
2344
- createCompilerDiagnosticOnlyIfJson ( Diagnostics . Compiler_option_0_requires_a_value_of_type_1 , "include" , "Array" ) ;
2328
+ const filesSpecs = toPropValue ( getSpecsFromRaw ( "files" ) ) ;
2329
+ if ( filesSpecs ) {
2330
+ const hasZeroOrNoReferences = referencesOfRaw === "no-prop" || isArray ( referencesOfRaw ) && referencesOfRaw . length === 0 ;
2331
+ const hasExtends = hasProperty ( raw , "extends" ) ;
2332
+ if ( filesSpecs . length === 0 && hasZeroOrNoReferences && ! hasExtends ) {
2333
+ if ( sourceFile ) {
2334
+ const fileName = configFileName || "tsconfig.json" ;
2335
+ const diagnosticMessage = Diagnostics . The_files_list_in_config_file_0_is_empty ;
2336
+ const nodeValue = firstDefined ( getTsConfigPropArray ( sourceFile , "files" ) , property => property . initializer ) ;
2337
+ const error = nodeValue
2338
+ ? createDiagnosticForNodeInSourceFile ( sourceFile , nodeValue , diagnosticMessage , fileName )
2339
+ : createCompilerDiagnostic ( diagnosticMessage , fileName ) ;
2340
+ errors . push ( error ) ;
2341
+ }
2342
+ else {
2343
+ createCompilerDiagnosticOnlyIfJson ( Diagnostics . The_files_list_in_config_file_0_is_empty , configFileName || "tsconfig.json" ) ;
2344
+ }
2345
2345
}
2346
2346
}
2347
2347
2348
- let excludeSpecs : readonly string [ ] | undefined ;
2349
- if ( hasProperty ( raw , "exclude" ) && ! isNullOrUndefined ( raw . exclude ) ) {
2350
- if ( isArray ( raw . exclude ) ) {
2351
- excludeSpecs = < readonly string [ ] > raw . exclude ;
2352
- }
2353
- else {
2354
- createCompilerDiagnosticOnlyIfJson ( Diagnostics . Compiler_option_0_requires_a_value_of_type_1 , "exclude" , "Array" ) ;
2355
- }
2356
- }
2357
- else if ( raw . compilerOptions ) {
2348
+ let includeSpecs = toPropValue ( getSpecsFromRaw ( "include" ) ) ;
2349
+
2350
+ const excludeOfRaw = getSpecsFromRaw ( "exclude" ) ;
2351
+ let excludeSpecs = toPropValue ( excludeOfRaw ) ;
2352
+ if ( excludeOfRaw === "no-prop" && raw . compilerOptions ) {
2358
2353
const outDir = raw . compilerOptions . outDir ;
2359
2354
const declarationDir = raw . compilerOptions . declarationDir ;
2360
2355
@@ -2372,28 +2367,33 @@ namespace ts {
2372
2367
errors . push ( getErrorForNoInputFiles ( result . spec , configFileName ) ) ;
2373
2368
}
2374
2369
2375
- if ( hasProperty ( raw , "references" ) && ! isNullOrUndefined ( raw . references ) ) {
2376
- if ( isArray ( raw . references ) ) {
2377
- for ( const ref of raw . references ) {
2378
- if ( typeof ref . path !== "string" ) {
2379
- createCompilerDiagnosticOnlyIfJson ( Diagnostics . Compiler_option_0_requires_a_value_of_type_1 , "reference.path" , "string" ) ;
2380
- }
2381
- else {
2382
- ( projectReferences || ( projectReferences = [ ] ) ) . push ( {
2383
- path : getNormalizedAbsolutePath ( ref . path , basePath ) ,
2384
- originalPath : ref . path ,
2385
- prepend : ref . prepend ,
2386
- circular : ref . circular
2387
- } ) ;
2388
- }
2370
+ return result ;
2371
+ }
2372
+
2373
+ type PropOfRaw < T > = readonly T [ ] | "not-array" | "no-prop" ;
2374
+ function toPropValue < T > ( specResult : PropOfRaw < T > ) {
2375
+ return isArray ( specResult ) ? specResult : undefined ;
2376
+ }
2377
+
2378
+ function getSpecsFromRaw ( prop : "files" | "include" | "exclude" ) : PropOfRaw < string > {
2379
+ return getPropFromRaw ( prop , isString , "string" ) ;
2380
+ }
2381
+
2382
+ function getPropFromRaw < T > ( prop : "files" | "include" | "exclude" | "references" , validateElement : ( value : unknown ) => boolean , elementTypeName : string ) : PropOfRaw < T > {
2383
+ if ( hasProperty ( raw , prop ) && ! isNullOrUndefined ( raw [ prop ] ) ) {
2384
+ if ( isArray ( raw [ prop ] ) ) {
2385
+ const result = raw [ prop ] ;
2386
+ if ( ! sourceFile && ! every ( result , validateElement ) ) {
2387
+ errors . push ( createCompilerDiagnostic ( Diagnostics . Compiler_option_0_requires_a_value_of_type_1 , prop , elementTypeName ) ) ;
2389
2388
}
2389
+ return result ;
2390
2390
}
2391
2391
else {
2392
- createCompilerDiagnosticOnlyIfJson ( Diagnostics . Compiler_option_0_requires_a_value_of_type_1 , "references" , "Array" ) ;
2392
+ createCompilerDiagnosticOnlyIfJson ( Diagnostics . Compiler_option_0_requires_a_value_of_type_1 , prop , "Array" ) ;
2393
+ return "not-array" ;
2393
2394
}
2394
2395
}
2395
-
2396
- return result ;
2396
+ return "no-prop" ;
2397
2397
}
2398
2398
2399
2399
function createCompilerDiagnosticOnlyIfJson ( message : DiagnosticMessage , arg0 ?: string , arg1 ?: string ) {
@@ -2941,7 +2941,15 @@ namespace ts {
2941
2941
// new entries in these paths.
2942
2942
const wildcardDirectories = getWildcardDirectories ( validatedIncludeSpecs , validatedExcludeSpecs , basePath , host . useCaseSensitiveFileNames ) ;
2943
2943
2944
- const spec : ConfigFileSpecs = { filesSpecs, includeSpecs, excludeSpecs, validatedIncludeSpecs, validatedExcludeSpecs, wildcardDirectories } ;
2944
+ const spec : ConfigFileSpecs = {
2945
+ filesSpecs,
2946
+ includeSpecs,
2947
+ excludeSpecs,
2948
+ validatedFilesSpec : filter ( filesSpecs , isString ) ,
2949
+ validatedIncludeSpecs,
2950
+ validatedExcludeSpecs,
2951
+ wildcardDirectories
2952
+ } ;
2945
2953
return getFileNamesFromConfigSpecs ( spec , basePath , options , host , extraFileExtensions ) ;
2946
2954
}
2947
2955
@@ -2980,7 +2988,7 @@ namespace ts {
2980
2988
// file map with a possibly case insensitive key. We use this map to store paths matched
2981
2989
// via wildcard of *.json kind
2982
2990
const wildCardJsonFileMap = new Map < string , string > ( ) ;
2983
- const { filesSpecs , validatedIncludeSpecs, validatedExcludeSpecs, wildcardDirectories } = spec ;
2991
+ const { validatedFilesSpec , validatedIncludeSpecs, validatedExcludeSpecs, wildcardDirectories } = spec ;
2984
2992
2985
2993
// Rather than requery this for each file and filespec, we query the supported extensions
2986
2994
// once and store it on the expansion context.
@@ -2989,8 +2997,8 @@ namespace ts {
2989
2997
2990
2998
// Literal files are always included verbatim. An "include" or "exclude" specification cannot
2991
2999
// remove a literal file.
2992
- if ( filesSpecs ) {
2993
- for ( const fileName of filesSpecs ) {
3000
+ if ( validatedFilesSpec ) {
3001
+ for ( const fileName of validatedFilesSpec ) {
2994
3002
const file = getNormalizedAbsolutePath ( fileName , basePath ) ;
2995
3003
literalFileMap . set ( keyMapper ( file ) , file ) ;
2996
3004
}
@@ -3056,14 +3064,14 @@ namespace ts {
3056
3064
useCaseSensitiveFileNames : boolean ,
3057
3065
currentDirectory : string
3058
3066
) : boolean {
3059
- const { filesSpecs , validatedIncludeSpecs, validatedExcludeSpecs } = spec ;
3067
+ const { validatedFilesSpec , validatedIncludeSpecs, validatedExcludeSpecs } = spec ;
3060
3068
if ( ! length ( validatedIncludeSpecs ) || ! length ( validatedExcludeSpecs ) ) return false ;
3061
3069
3062
3070
basePath = normalizePath ( basePath ) ;
3063
3071
3064
3072
const keyMapper = createGetCanonicalFileName ( useCaseSensitiveFileNames ) ;
3065
- if ( filesSpecs ) {
3066
- for ( const fileName of filesSpecs ) {
3073
+ if ( validatedFilesSpec ) {
3074
+ for ( const fileName of validatedFilesSpec ) {
3067
3075
if ( keyMapper ( getNormalizedAbsolutePath ( fileName , basePath ) ) === pathToCheck ) return false ;
3068
3076
}
3069
3077
}
@@ -3077,6 +3085,7 @@ namespace ts {
3077
3085
3078
3086
function validateSpecs ( specs : readonly string [ ] , errors : Push < Diagnostic > , allowTrailingRecursion : boolean , jsonSourceFile : TsConfigSourceFile | undefined , specKey : string ) : readonly string [ ] {
3079
3087
return specs . filter ( spec => {
3088
+ if ( ! isString ( spec ) ) return false ;
3080
3089
const diag = specToDiagnostic ( spec , allowTrailingRecursion ) ;
3081
3090
if ( diag !== undefined ) {
3082
3091
errors . push ( createDiagnostic ( diag , spec ) ) ;
0 commit comments