@@ -635,7 +635,6 @@ namespace ts {
635
635
// Map storing if there is emit blocking diagnostics for given input
636
636
const hasEmitBlockingDiagnostics = createMap < boolean > ( ) ;
637
637
let _compilerOptionsObjectLiteralSyntax : ObjectLiteralExpression | null | undefined ;
638
- let _referencesArrayLiteralSyntax : ArrayLiteralExpression | null | undefined ;
639
638
640
639
let moduleResolutionCache : ModuleResolutionCache | undefined ;
641
640
let resolveModuleNamesWorker : ( moduleNames : string [ ] , containingFile : string , reusedNames ?: string [ ] , redirectedReference ?: ResolvedProjectReference ) => ResolvedModuleFull [ ] ;
@@ -1084,7 +1083,9 @@ namespace ts {
1084
1083
if ( ! canReuseProjectReferences ( ) ) {
1085
1084
return oldProgram . structureIsReused = StructureIsReused . Not ;
1086
1085
}
1087
- resolvedProjectReferences = oldProgram . getResolvedProjectReferences ( ) ;
1086
+ if ( projectReferences ) {
1087
+ resolvedProjectReferences = projectReferences . map ( parseProjectReferenceConfigFile ) ;
1088
+ }
1088
1089
1089
1090
// check if program source files has changed in the way that can affect structure of the program
1090
1091
const newSourceFiles : SourceFile [ ] = [ ] ;
@@ -1827,11 +1828,22 @@ namespace ts {
1827
1828
fileProcessingDiagnostics . getGlobalDiagnostics ( ) ,
1828
1829
concatenate (
1829
1830
programDiagnostics . getGlobalDiagnostics ( ) ,
1830
- options . configFile ? programDiagnostics . getDiagnostics ( options . configFile . fileName ) : [ ]
1831
+ getOptionsDiagnosticsOfConfigFile ( )
1831
1832
)
1832
1833
) ) ;
1833
1834
}
1834
1835
1836
+ function getOptionsDiagnosticsOfConfigFile ( ) {
1837
+ if ( ! options . configFile ) { return emptyArray ; }
1838
+ let diagnostics = programDiagnostics . getDiagnostics ( options . configFile . fileName ) ;
1839
+ forEachResolvedProjectReference ( resolvedRef => {
1840
+ if ( resolvedRef ) {
1841
+ diagnostics = concatenate ( diagnostics , programDiagnostics . getDiagnostics ( resolvedRef . sourceFile . fileName ) ) ;
1842
+ }
1843
+ } ) ;
1844
+ return diagnostics ;
1845
+ }
1846
+
1835
1847
function getGlobalDiagnostics ( ) : Diagnostic [ ] {
1836
1848
return sortAndDeduplicateDiagnostics ( getDiagnosticsProducingTypeChecker ( ) . getGlobalDiagnostics ( ) . slice ( ) ) ;
1837
1849
}
@@ -2558,31 +2570,7 @@ namespace ts {
2558
2570
}
2559
2571
}
2560
2572
2561
- //TODO:: Errors on transitive references
2562
- if ( projectReferences ) {
2563
- for ( let i = 0 ; i < projectReferences . length ; i ++ ) {
2564
- const ref = projectReferences [ i ] ;
2565
- const resolvedRefOpts = resolvedProjectReferences ! [ i ] && resolvedProjectReferences ! [ i ] ! . commandLine . options ;
2566
- if ( resolvedRefOpts === undefined ) {
2567
- createDiagnosticForReference ( i , Diagnostics . File_0_not_found , ref . path ) ;
2568
- continue ;
2569
- }
2570
- if ( ! resolvedRefOpts . composite ) {
2571
- createDiagnosticForReference ( i , Diagnostics . Referenced_project_0_must_have_setting_composite_Colon_true , ref . path ) ;
2572
- }
2573
- if ( ref . prepend ) {
2574
- const out = resolvedRefOpts . outFile || resolvedRefOpts . out ;
2575
- if ( out ) {
2576
- if ( ! host . fileExists ( out ) ) {
2577
- createDiagnosticForReference ( i , Diagnostics . Output_file_0_from_project_1_does_not_exist , out , ref . path ) ;
2578
- }
2579
- }
2580
- else {
2581
- createDiagnosticForReference ( i , Diagnostics . Cannot_prepend_project_0_because_it_does_not_have_outFile_set , ref . path ) ;
2582
- }
2583
- }
2584
- }
2585
- }
2573
+ verifyProjectReferences ( ) ;
2586
2574
2587
2575
// List of collected files is complete; validate exhautiveness if this is a project with a file list
2588
2576
if ( options . composite ) {
@@ -2800,6 +2788,32 @@ namespace ts {
2800
2788
}
2801
2789
}
2802
2790
2791
+ function verifyProjectReferences ( ) {
2792
+ forEachProjectReference ( projectReferences , resolvedProjectReferences , ( resolvedRef , index , parent ) => {
2793
+ const ref = ( parent ? parent . commandLine . projectReferences : projectReferences ) ! [ index ] ;
2794
+ const parentFile = parent && parent . sourceFile as JsonSourceFile ;
2795
+ if ( ! resolvedRef ) {
2796
+ createDiagnosticForReference ( parentFile , index , Diagnostics . File_0_not_found , ref . path ) ;
2797
+ return ;
2798
+ }
2799
+ const options = resolvedRef . commandLine . options ;
2800
+ if ( ! options . composite ) {
2801
+ createDiagnosticForReference ( parentFile , index , Diagnostics . Referenced_project_0_must_have_setting_composite_Colon_true , ref . path ) ;
2802
+ }
2803
+ if ( ref . prepend ) {
2804
+ const out = options . outFile || options . out ;
2805
+ if ( out ) {
2806
+ if ( ! host . fileExists ( out ) ) {
2807
+ createDiagnosticForReference ( parentFile , index , Diagnostics . Output_file_0_from_project_1_does_not_exist , out , ref . path ) ;
2808
+ }
2809
+ }
2810
+ else {
2811
+ createDiagnosticForReference ( parentFile , index , Diagnostics . Cannot_prepend_project_0_because_it_does_not_have_outFile_set , ref . path ) ;
2812
+ }
2813
+ }
2814
+ } ) ;
2815
+ }
2816
+
2803
2817
function createDiagnosticForOptionPathKeyValue ( key : string , valueIndex : number , message : DiagnosticMessage , arg0 : string | number , arg1 : string | number , arg2 ?: string | number ) {
2804
2818
let needCompilerDiagnostic = true ;
2805
2819
const pathsSyntax = getOptionPathsSyntax ( ) ;
@@ -2856,10 +2870,11 @@ namespace ts {
2856
2870
createDiagnosticForOption ( /*onKey*/ false , option1 , /*option2*/ undefined , message , arg0 ) ;
2857
2871
}
2858
2872
2859
- function createDiagnosticForReference ( index : number , message : DiagnosticMessage , arg0 ?: string | number , arg1 ?: string | number ) {
2860
- const referencesSyntax = getProjectReferencesSyntax ( ) ;
2873
+ function createDiagnosticForReference ( sourceFile : JsonSourceFile | undefined , index : number , message : DiagnosticMessage , arg0 ?: string | number , arg1 ?: string | number ) {
2874
+ const referencesSyntax = firstDefined ( getTsConfigPropArray ( sourceFile || options . configFile , "references" ) ,
2875
+ property => isArrayLiteralExpression ( property . initializer ) ? property . initializer : undefined ) ;
2861
2876
if ( referencesSyntax && referencesSyntax . elements . length > index ) {
2862
- programDiagnostics . add ( createDiagnosticForNodeInSourceFile ( options . configFile ! , referencesSyntax . elements [ index ] , message , arg0 , arg1 ) ) ;
2877
+ programDiagnostics . add ( createDiagnosticForNodeInSourceFile ( sourceFile || options . configFile ! , referencesSyntax . elements [ index ] , message , arg0 , arg1 ) ) ;
2863
2878
}
2864
2879
else {
2865
2880
programDiagnostics . add ( createCompilerDiagnostic ( message , arg0 , arg1 ) ) ;
@@ -2876,22 +2891,6 @@ namespace ts {
2876
2891
}
2877
2892
}
2878
2893
2879
- function getProjectReferencesSyntax ( ) : ArrayLiteralExpression | null {
2880
- if ( _referencesArrayLiteralSyntax === undefined ) {
2881
- _referencesArrayLiteralSyntax = null ; // tslint:disable-line:no-null-keyword
2882
- if ( options . configFile ) {
2883
- const jsonObjectLiteral = getTsConfigObjectLiteralExpression ( options . configFile ) ! ; // TODO: GH#18217
2884
- for ( const prop of getPropertyAssignment ( jsonObjectLiteral , "references" ) ) {
2885
- if ( isArrayLiteralExpression ( prop . initializer ) ) {
2886
- _referencesArrayLiteralSyntax = prop . initializer ;
2887
- break ;
2888
- }
2889
- }
2890
- }
2891
- }
2892
- return _referencesArrayLiteralSyntax ;
2893
- }
2894
-
2895
2894
function getCompilerOptionsObjectLiteralSyntax ( ) {
2896
2895
if ( _compilerOptionsObjectLiteralSyntax === undefined ) {
2897
2896
_compilerOptionsObjectLiteralSyntax = null ; // tslint:disable-line:no-null-keyword
0 commit comments