@@ -529,7 +529,8 @@ namespace ts {
529529 getFileProcessingDiagnostics : ( ) => fileProcessingDiagnostics ,
530530 getResolvedTypeReferenceDirectives : ( ) => resolvedTypeReferenceDirectives ,
531531 isSourceFileFromExternalLibrary,
532- dropDiagnosticsProducingTypeChecker
532+ dropDiagnosticsProducingTypeChecker,
533+ getSourceFileFromReference,
533534 } ;
534535
535536 verifyCompilerOptions ( ) ;
@@ -1442,48 +1443,60 @@ namespace ts {
14421443 }
14431444 }
14441445
1445- function processSourceFile ( fileName : string , isDefaultLib : boolean , refFile ?: SourceFile , refPos ?: number , refEnd ?: number ) {
1446- let diagnosticArgument : string [ ] ;
1447- let diagnostic : DiagnosticMessage ;
1446+ /** This should have similar behavior to 'processSourceFile' without diagnostics or mutation. */
1447+ function getSourceFileFromReference ( referencingFile : SourceFile , ref : FileReference ) : SourceFile | undefined {
1448+ return getSourceFileFromReferenceWorker ( resolveTripleslashReference ( ref . fileName , referencingFile . fileName ) , fileName => filesByName . get ( toPath ( fileName , currentDirectory , getCanonicalFileName ) ) ) ;
1449+ }
1450+
1451+ function getSourceFileFromReferenceWorker (
1452+ fileName : string ,
1453+ getSourceFile : ( fileName : string ) => SourceFile | undefined ,
1454+ fail ?: ( diagnostic : DiagnosticMessage , ...argument : string [ ] ) => void ,
1455+ refFile ?: SourceFile ) : SourceFile | undefined {
1456+
14481457 if ( hasExtension ( fileName ) ) {
14491458 if ( ! options . allowNonTsExtensions && ! forEach ( supportedExtensions , extension => fileExtensionIs ( host . getCanonicalFileName ( fileName ) , extension ) ) ) {
1450- diagnostic = Diagnostics . File_0_has_unsupported_extension_The_only_supported_extensions_are_1 ;
1451- diagnosticArgument = [ fileName , "'" + supportedExtensions . join ( "', '" ) + "'" ] ;
1452- }
1453- else if ( ! findSourceFile ( fileName , toPath ( fileName , currentDirectory , getCanonicalFileName ) , isDefaultLib , refFile , refPos , refEnd ) ) {
1454- diagnostic = Diagnostics . File_0_not_found ;
1455- diagnosticArgument = [ fileName ] ;
1459+ if ( fail ) fail ( Diagnostics . File_0_has_unsupported_extension_The_only_supported_extensions_are_1 , fileName , "'" + supportedExtensions . join ( "', '" ) + "'" ) ;
1460+ return undefined ;
14561461 }
1457- else if ( refFile && host . getCanonicalFileName ( fileName ) === host . getCanonicalFileName ( refFile . fileName ) ) {
1458- diagnostic = Diagnostics . A_file_cannot_have_a_reference_to_itself ;
1459- diagnosticArgument = [ fileName ] ;
1460- }
1461- }
1462- else {
1463- const nonTsFile : SourceFile = options . allowNonTsExtensions && findSourceFile ( fileName , toPath ( fileName , currentDirectory , getCanonicalFileName ) , isDefaultLib , refFile , refPos , refEnd ) ;
1464- if ( ! nonTsFile ) {
1465- if ( options . allowNonTsExtensions ) {
1466- diagnostic = Diagnostics . File_0_not_found ;
1467- diagnosticArgument = [ fileName ] ;
1462+
1463+ const sourceFile = getSourceFile ( fileName ) ;
1464+ if ( fail ) {
1465+ if ( ! sourceFile ) {
1466+ fail ( Diagnostics . File_0_not_found , fileName ) ;
14681467 }
1469- else if ( ! forEach ( supportedExtensions , extension => findSourceFile ( fileName + extension , toPath ( fileName + extension , currentDirectory , getCanonicalFileName ) , isDefaultLib , refFile , refPos , refEnd ) ) ) {
1470- diagnostic = Diagnostics . File_0_not_found ;
1471- fileName += ".ts" ;
1472- diagnosticArgument = [ fileName ] ;
1468+ else if ( refFile && host . getCanonicalFileName ( fileName ) === host . getCanonicalFileName ( refFile . fileName ) ) {
1469+ fail ( Diagnostics . A_file_cannot_have_a_reference_to_itself , fileName ) ;
14731470 }
14741471 }
1475- }
1472+ return sourceFile ;
1473+ } else {
1474+ const sourceFileNoExtension = options . allowNonTsExtensions && getSourceFile ( fileName ) ;
1475+ if ( sourceFileNoExtension ) return sourceFileNoExtension ;
14761476
1477- if ( diagnostic ) {
1478- if ( refFile !== undefined && refEnd !== undefined && refPos !== undefined ) {
1479- fileProcessingDiagnostics . add ( createFileDiagnostic ( refFile , refPos , refEnd - refPos , diagnostic , ...diagnosticArgument ) ) ;
1480- }
1481- else {
1482- fileProcessingDiagnostics . add ( createCompilerDiagnostic ( diagnostic , ...diagnosticArgument ) ) ;
1477+ if ( fail && options . allowNonTsExtensions ) {
1478+ fail ( Diagnostics . File_0_not_found , fileName ) ;
1479+ return undefined ;
14831480 }
1481+
1482+ const sourceFileWithAddedExtension = forEach ( supportedExtensions , extension => getSourceFile ( fileName + extension ) ) ;
1483+ if ( fail && ! sourceFileWithAddedExtension ) fail ( Diagnostics . File_0_not_found , fileName + ".ts" ) ;
1484+ return sourceFileWithAddedExtension ;
14841485 }
14851486 }
14861487
1488+ /** This has side effects through `findSourceFile`. */
1489+ function processSourceFile ( fileName : string , isDefaultLib : boolean , refFile ?: SourceFile , refPos ?: number , refEnd ?: number ) : void {
1490+ getSourceFileFromReferenceWorker ( fileName ,
1491+ fileName => findSourceFile ( fileName , toPath ( fileName , currentDirectory , getCanonicalFileName ) , isDefaultLib , refFile , refPos , refEnd ) ,
1492+ ( diagnostic , ...args ) => {
1493+ fileProcessingDiagnostics . add ( refFile !== undefined && refEnd !== undefined && refPos !== undefined
1494+ ? createFileDiagnostic ( refFile , refPos , refEnd - refPos , diagnostic , ...args )
1495+ : createCompilerDiagnostic ( diagnostic , ...args ) ) ;
1496+ } ,
1497+ refFile ) ;
1498+ }
1499+
14871500 function reportFileNamesDifferOnlyInCasingError ( fileName : string , existingFileName : string , refFile : SourceFile , refPos : number , refEnd : number ) : void {
14881501 if ( refFile !== undefined && refPos !== undefined && refEnd !== undefined ) {
14891502 fileProcessingDiagnostics . add ( createFileDiagnostic ( refFile , refPos , refEnd - refPos ,
0 commit comments