@@ -434,7 +434,8 @@ namespace ts {
434
434
getFileProcessingDiagnostics : ( ) => fileProcessingDiagnostics ,
435
435
getResolvedTypeReferenceDirectives : ( ) => resolvedTypeReferenceDirectives ,
436
436
isSourceFileFromExternalLibrary,
437
- dropDiagnosticsProducingTypeChecker
437
+ dropDiagnosticsProducingTypeChecker,
438
+ getSourceFileFromReference,
438
439
} ;
439
440
440
441
verifyCompilerOptions ( ) ;
@@ -1348,48 +1349,60 @@ namespace ts {
1348
1349
}
1349
1350
}
1350
1351
1351
- function processSourceFile ( fileName : string , isDefaultLib : boolean , refFile ?: SourceFile , refPos ?: number , refEnd ?: number ) {
1352
- let diagnosticArgument : string [ ] ;
1353
- let diagnostic : DiagnosticMessage ;
1352
+ /** This should have similar behavior to 'processSourceFile' without diagnostics or mutation. */
1353
+ function getSourceFileFromReference ( referencingFile : SourceFile , ref : FileReference ) : SourceFile | undefined {
1354
+ return getSourceFileFromReferenceWorker ( resolveTripleslashReference ( ref . fileName , referencingFile . fileName ) , fileName => filesByName . get ( toPath ( fileName , currentDirectory , getCanonicalFileName ) ) ) ;
1355
+ }
1356
+
1357
+ function getSourceFileFromReferenceWorker (
1358
+ fileName : string ,
1359
+ getSourceFile : ( fileName : string ) => SourceFile | undefined ,
1360
+ fail ?: ( diagnostic : DiagnosticMessage , ...argument : string [ ] ) => void ,
1361
+ refFile ?: SourceFile ) : SourceFile | undefined {
1362
+
1354
1363
if ( hasExtension ( fileName ) ) {
1355
1364
if ( ! options . allowNonTsExtensions && ! forEach ( supportedExtensions , extension => fileExtensionIs ( host . getCanonicalFileName ( fileName ) , extension ) ) ) {
1356
- diagnostic = Diagnostics . File_0_has_unsupported_extension_The_only_supported_extensions_are_1 ;
1357
- diagnosticArgument = [ fileName , "'" + supportedExtensions . join ( "', '" ) + "'" ] ;
1358
- }
1359
- else if ( ! findSourceFile ( fileName , toPath ( fileName , currentDirectory , getCanonicalFileName ) , isDefaultLib , refFile , refPos , refEnd ) ) {
1360
- diagnostic = Diagnostics . File_0_not_found ;
1361
- diagnosticArgument = [ fileName ] ;
1365
+ if ( fail ) fail ( Diagnostics . File_0_has_unsupported_extension_The_only_supported_extensions_are_1 , fileName , "'" + supportedExtensions . join ( "', '" ) + "'" ) ;
1366
+ return undefined ;
1362
1367
}
1363
- else if ( refFile && host . getCanonicalFileName ( fileName ) === host . getCanonicalFileName ( refFile . fileName ) ) {
1364
- diagnostic = Diagnostics . A_file_cannot_have_a_reference_to_itself ;
1365
- diagnosticArgument = [ fileName ] ;
1366
- }
1367
- }
1368
- else {
1369
- const nonTsFile : SourceFile = options . allowNonTsExtensions && findSourceFile ( fileName , toPath ( fileName , currentDirectory , getCanonicalFileName ) , isDefaultLib , refFile , refPos , refEnd ) ;
1370
- if ( ! nonTsFile ) {
1371
- if ( options . allowNonTsExtensions ) {
1372
- diagnostic = Diagnostics . File_0_not_found ;
1373
- diagnosticArgument = [ fileName ] ;
1368
+
1369
+ const sourceFile = getSourceFile ( fileName ) ;
1370
+ if ( fail ) {
1371
+ if ( ! sourceFile ) {
1372
+ fail ( Diagnostics . File_0_not_found , fileName ) ;
1374
1373
}
1375
- else if ( ! forEach ( supportedExtensions , extension => findSourceFile ( fileName + extension , toPath ( fileName + extension , currentDirectory , getCanonicalFileName ) , isDefaultLib , refFile , refPos , refEnd ) ) ) {
1376
- diagnostic = Diagnostics . File_0_not_found ;
1377
- fileName += ".ts" ;
1378
- diagnosticArgument = [ fileName ] ;
1374
+ else if ( refFile && host . getCanonicalFileName ( fileName ) === host . getCanonicalFileName ( refFile . fileName ) ) {
1375
+ fail ( Diagnostics . A_file_cannot_have_a_reference_to_itself , fileName ) ;
1379
1376
}
1380
1377
}
1381
- }
1378
+ return sourceFile ;
1379
+ } else {
1380
+ const sourceFileNoExtension = options . allowNonTsExtensions && getSourceFile ( fileName ) ;
1381
+ if ( sourceFileNoExtension ) return sourceFileNoExtension ;
1382
1382
1383
- if ( diagnostic ) {
1384
- if ( refFile !== undefined && refEnd !== undefined && refPos !== undefined ) {
1385
- fileProcessingDiagnostics . add ( createFileDiagnostic ( refFile , refPos , refEnd - refPos , diagnostic , ...diagnosticArgument ) ) ;
1386
- }
1387
- else {
1388
- fileProcessingDiagnostics . add ( createCompilerDiagnostic ( diagnostic , ...diagnosticArgument ) ) ;
1383
+ if ( fail && options . allowNonTsExtensions ) {
1384
+ fail ( Diagnostics . File_0_not_found , fileName ) ;
1385
+ return undefined ;
1389
1386
}
1387
+
1388
+ const sourceFileWithAddedExtension = forEach ( supportedExtensions , extension => getSourceFile ( fileName + extension ) ) ;
1389
+ if ( fail && ! sourceFileWithAddedExtension ) fail ( Diagnostics . File_0_not_found , fileName + ".ts" ) ;
1390
+ return sourceFileWithAddedExtension ;
1390
1391
}
1391
1392
}
1392
1393
1394
+ /** This has side effects through `findSourceFile`. */
1395
+ function processSourceFile ( fileName : string , isDefaultLib : boolean , refFile ?: SourceFile , refPos ?: number , refEnd ?: number ) : void {
1396
+ getSourceFileFromReferenceWorker ( fileName ,
1397
+ fileName => findSourceFile ( fileName , toPath ( fileName , currentDirectory , getCanonicalFileName ) , isDefaultLib , refFile , refPos , refEnd ) ,
1398
+ ( diagnostic , ...args ) => {
1399
+ fileProcessingDiagnostics . add ( refFile !== undefined && refEnd !== undefined && refPos !== undefined
1400
+ ? createFileDiagnostic ( refFile , refPos , refEnd - refPos , diagnostic , ...args )
1401
+ : createCompilerDiagnostic ( diagnostic , ...args ) ) ;
1402
+ } ,
1403
+ refFile ) ;
1404
+ }
1405
+
1393
1406
function reportFileNamesDifferOnlyInCasingError ( fileName : string , existingFileName : string , refFile : SourceFile , refPos : number , refEnd : number ) : void {
1394
1407
if ( refFile !== undefined && refPos !== undefined && refEnd !== undefined ) {
1395
1408
fileProcessingDiagnostics . add ( createFileDiagnostic ( refFile , refPos , refEnd - refPos ,
0 commit comments