@@ -290,6 +290,11 @@ namespace ts {
290
290
return resolutions ;
291
291
}
292
292
293
+ interface DiagnosticCache {
294
+ perFile ?: FileMap < Diagnostic [ ] > ;
295
+ allDiagnostics ?: Diagnostic [ ] ;
296
+ }
297
+
293
298
export function createProgram ( rootNames : string [ ] , options : CompilerOptions , host ?: CompilerHost , oldProgram ?: Program ) : Program {
294
299
let program : Program ;
295
300
let files : SourceFile [ ] = [ ] ;
@@ -298,6 +303,9 @@ namespace ts {
298
303
let noDiagnosticsTypeChecker : TypeChecker ;
299
304
let classifiableNames : Map < string > ;
300
305
306
+ let cachedSemanticDiagnosticsForFile : DiagnosticCache = { } ;
307
+ let cachedDeclarationDiagnosticsForFile : DiagnosticCache = { } ;
308
+
301
309
let resolvedTypeReferenceDirectives = createMap < ResolvedTypeReferenceDirective > ( ) ;
302
310
let fileProcessingDiagnostics = createDiagnosticCollection ( ) ;
303
311
@@ -899,6 +907,10 @@ namespace ts {
899
907
}
900
908
901
909
function getSemanticDiagnosticsForFile ( sourceFile : SourceFile , cancellationToken : CancellationToken ) : Diagnostic [ ] {
910
+ return getAndCacheDiagnostics ( sourceFile , cancellationToken , cachedSemanticDiagnosticsForFile , getSemanticDiagnosticsForFileNoCache ) ;
911
+ }
912
+
913
+ function getSemanticDiagnosticsForFileNoCache ( sourceFile : SourceFile , cancellationToken : CancellationToken ) : Diagnostic [ ] {
902
914
return runWithCancellationToken ( ( ) => {
903
915
const typeChecker = getDiagnosticsProducingTypeChecker ( ) ;
904
916
@@ -1094,14 +1106,44 @@ namespace ts {
1094
1106
} ) ;
1095
1107
}
1096
1108
1097
- function getDeclarationDiagnosticsWorker ( sourceFile : SourceFile , cancellationToken : CancellationToken ) : Diagnostic [ ] {
1109
+ function getDeclarationDiagnosticsWorker ( sourceFile : SourceFile | undefined , cancellationToken : CancellationToken ) : Diagnostic [ ] {
1110
+ return getAndCacheDiagnostics ( sourceFile , cancellationToken , cachedDeclarationDiagnosticsForFile , getDeclarationDiagnosticsForFileNoCache ) ;
1111
+ }
1112
+
1113
+ function getDeclarationDiagnosticsForFileNoCache ( sourceFile : SourceFile | undefined , cancellationToken : CancellationToken ) {
1098
1114
return runWithCancellationToken ( ( ) => {
1099
1115
const resolver = getDiagnosticsProducingTypeChecker ( ) . getEmitResolver ( sourceFile , cancellationToken ) ;
1100
1116
// Don't actually write any files since we're just getting diagnostics.
1101
1117
return ts . getDeclarationDiagnostics ( getEmitHost ( noop ) , resolver , sourceFile ) ;
1102
1118
} ) ;
1103
1119
}
1104
1120
1121
+ function getAndCacheDiagnostics (
1122
+ sourceFile : SourceFile | undefined ,
1123
+ cancellationToken : CancellationToken ,
1124
+ cache : DiagnosticCache ,
1125
+ getDiagnostics : ( sourceFile : SourceFile , cancellationToken : CancellationToken ) => Diagnostic [ ] ) {
1126
+
1127
+ const cachedResult = sourceFile
1128
+ ? cache . perFile && cache . perFile . get ( sourceFile . path )
1129
+ : cache . allDiagnostics ;
1130
+
1131
+ if ( cachedResult ) {
1132
+ return cachedResult ;
1133
+ }
1134
+ const result = getDiagnostics ( sourceFile , cancellationToken ) || emptyArray ;
1135
+ if ( sourceFile ) {
1136
+ if ( ! cache . perFile ) {
1137
+ cache . perFile = createFileMap < Diagnostic [ ] > ( ) ;
1138
+ }
1139
+ cache . perFile . set ( sourceFile . path , result ) ;
1140
+ }
1141
+ else {
1142
+ cache . allDiagnostics = result ;
1143
+ }
1144
+ return result ;
1145
+ }
1146
+
1105
1147
function getDeclarationDiagnosticsForFile ( sourceFile : SourceFile , cancellationToken : CancellationToken ) : Diagnostic [ ] {
1106
1148
return isDeclarationFile ( sourceFile ) ? [ ] : getDeclarationDiagnosticsWorker ( sourceFile , cancellationToken ) ;
1107
1149
}
0 commit comments