@@ -39,7 +39,6 @@ func (p *ProgramOptions) canUseProjectReferenceSource() bool {
39
39
40
40
type Program struct {
41
41
opts ProgramOptions
42
- nodeModules map [string ]* ast.SourceFile
43
42
checkerPool CheckerPool
44
43
45
44
comparePathsOptions tspath.ComparePathsOptions
@@ -178,7 +177,7 @@ func (p *Program) GetSourceFileFromReference(origin *ast.SourceFile, ref *ast.Fi
178
177
func NewProgram (opts ProgramOptions ) * Program {
179
178
p := & Program {opts : opts }
180
179
p .initCheckerPool ()
181
- p .processedFiles = processAllProgramFiles (p .opts , p .singleThreaded ())
180
+ p .processedFiles = processAllProgramFiles (p .opts , p .SingleThreaded ())
182
181
return p
183
182
}
184
183
@@ -192,7 +191,6 @@ func (p *Program) UpdateProgram(changedFilePath tspath.Path) (*Program, bool) {
192
191
}
193
192
result := & Program {
194
193
opts : p .opts ,
195
- nodeModules : p .nodeModules ,
196
194
comparePathsOptions : p .comparePathsOptions ,
197
195
processedFiles : p .processedFiles ,
198
196
usesUriStyleNodeCoreModules : p .usesUriStyleNodeCoreModules ,
@@ -210,7 +208,7 @@ func (p *Program) initCheckerPool() {
210
208
if p .opts .CreateCheckerPool != nil {
211
209
p .checkerPool = p .opts .CreateCheckerPool (p )
212
210
} else {
213
- p .checkerPool = newCheckerPool (core .IfElse (p .singleThreaded (), 1 , 4 ), p )
211
+ p .checkerPool = newCheckerPool (core .IfElse (p .SingleThreaded (), 1 , 4 ), p )
214
212
}
215
213
}
216
214
@@ -250,12 +248,12 @@ func (p *Program) GetConfigFileParsingDiagnostics() []*ast.Diagnostic {
250
248
return slices .Clip (p .opts .Config .GetConfigFileParsingDiagnostics ())
251
249
}
252
250
253
- func (p * Program ) singleThreaded () bool {
251
+ func (p * Program ) SingleThreaded () bool {
254
252
return p .opts .SingleThreaded .DefaultIfUnknown (p .Options ().SingleThreaded ).IsTrue ()
255
253
}
256
254
257
255
func (p * Program ) BindSourceFiles () {
258
- wg := core .NewWorkGroup (p .singleThreaded ())
256
+ wg := core .NewWorkGroup (p .SingleThreaded ())
259
257
for _ , file := range p .files {
260
258
if ! file .IsBound () {
261
259
wg .Queue (func () {
@@ -266,14 +264,16 @@ func (p *Program) BindSourceFiles() {
266
264
wg .RunAndWait ()
267
265
}
268
266
269
- func (p * Program ) CheckSourceFiles (ctx context.Context ) {
270
- wg := core .NewWorkGroup (p .singleThreaded ())
267
+ func (p * Program ) CheckSourceFiles (ctx context.Context , files [] * ast. SourceFile ) {
268
+ wg := core .NewWorkGroup (p .SingleThreaded ())
271
269
checkers , done := p .checkerPool .GetAllCheckers (ctx )
272
270
defer done ()
273
271
for _ , checker := range checkers {
274
272
wg .Queue (func () {
275
273
for file := range p .checkerPool .Files (checker ) {
276
- checker .CheckSourceFile (ctx , file )
274
+ if files == nil || slices .Contains (files , file ) {
275
+ checker .CheckSourceFile (ctx , file )
276
+ }
277
277
}
278
278
})
279
279
}
@@ -330,6 +330,19 @@ func (p *Program) GetSemanticDiagnostics(ctx context.Context, sourceFile *ast.So
330
330
return p .getDiagnosticsHelper (ctx , sourceFile , true /*ensureBound*/ , true /*ensureChecked*/ , p .getSemanticDiagnosticsForFile )
331
331
}
332
332
333
+ func (p * Program ) GetSemanticDiagnosticsNoFilter (ctx context.Context , sourceFiles []* ast.SourceFile ) map [* ast.SourceFile ][]* ast.Diagnostic {
334
+ p .BindSourceFiles ()
335
+ p .CheckSourceFiles (ctx , sourceFiles )
336
+ if ctx .Err () != nil {
337
+ return nil
338
+ }
339
+ result := make (map [* ast.SourceFile ][]* ast.Diagnostic , len (sourceFiles ))
340
+ for _ , file := range sourceFiles {
341
+ result [file ] = SortAndDeduplicateDiagnostics (p .getSemanticDiagnosticsForFileNotFilter (ctx , file ))
342
+ }
343
+ return result
344
+ }
345
+
333
346
func (p * Program ) GetSuggestionDiagnostics (ctx context.Context , sourceFile * ast.SourceFile ) []* ast.Diagnostic {
334
347
return p .getDiagnosticsHelper (ctx , sourceFile , true /*ensureBound*/ , true /*ensureChecked*/ , p .getSuggestionDiagnosticsForFile )
335
348
}
@@ -389,6 +402,14 @@ func FilterNoEmitSemanticDiagnostics(diagnostics []*ast.Diagnostic, options *cor
389
402
}
390
403
391
404
func (p * Program ) getSemanticDiagnosticsForFile (ctx context.Context , sourceFile * ast.SourceFile ) []* ast.Diagnostic {
405
+ diagnostics := p .getSemanticDiagnosticsForFileNotFilter (ctx , sourceFile )
406
+ if diagnostics == nil {
407
+ return nil
408
+ }
409
+ return FilterNoEmitSemanticDiagnostics (diagnostics , p .Options ())
410
+ }
411
+
412
+ func (p * Program ) getSemanticDiagnosticsForFileNotFilter (ctx context.Context , sourceFile * ast.SourceFile ) []* ast.Diagnostic {
392
413
compilerOptions := p .Options ()
393
414
if checker .SkipTypeChecking (sourceFile , compilerOptions , p , false ) {
394
415
return nil
@@ -421,13 +442,13 @@ func (p *Program) getSemanticDiagnosticsForFile(ctx context.Context, sourceFile
421
442
422
443
isPlainJS := ast .IsPlainJSFile (sourceFile , compilerOptions .CheckJs )
423
444
if isPlainJS {
424
- return FilterNoEmitSemanticDiagnostics ( core .Filter (diags , func (d * ast.Diagnostic ) bool {
445
+ return core .Filter (diags , func (d * ast.Diagnostic ) bool {
425
446
return plainJSErrors .Has (d .Code ())
426
- }), p . Options ())
447
+ })
427
448
}
428
449
429
450
if len (sourceFile .CommentDirectives ) == 0 {
430
- return FilterNoEmitSemanticDiagnostics ( diags , p . Options ())
451
+ return diags
431
452
}
432
453
// Build map of directives by line number
433
454
directivesByLine := make (map [int ]ast.CommentDirective )
@@ -464,7 +485,7 @@ func (p *Program) getSemanticDiagnosticsForFile(ctx context.Context, sourceFile
464
485
filtered = append (filtered , ast .NewDiagnostic (sourceFile , directive .Loc , diagnostics .Unused_ts_expect_error_directive ))
465
486
}
466
487
}
467
- return FilterNoEmitSemanticDiagnostics ( filtered , p . Options ())
488
+ return filtered
468
489
}
469
490
470
491
func (p * Program ) getDeclarationDiagnosticsForFile (ctx context.Context , sourceFile * ast.SourceFile ) []* ast.Diagnostic {
@@ -575,7 +596,7 @@ func (p *Program) getDiagnosticsHelper(ctx context.Context, sourceFile *ast.Sour
575
596
p .BindSourceFiles ()
576
597
}
577
598
if ensureChecked {
578
- p .CheckSourceFiles (ctx )
599
+ p .CheckSourceFiles (ctx , nil )
579
600
if ctx .Err () != nil {
580
601
return nil
581
602
}
@@ -715,23 +736,22 @@ func (p *Program) Emit(ctx context.Context, options EmitOptions) *EmitResult {
715
736
// !!! performance measurement
716
737
p .BindSourceFiles ()
717
738
if options .EmitOnly != EmitOnlyForcedDts {
718
- result := HandleNoEmitOptions (
739
+ result := HandleNoEmitOnError (
719
740
ctx ,
720
741
p ,
721
742
options .TargetSourceFile ,
722
743
)
723
- if result != nil {
744
+ if result != nil || ctx . Err () != nil {
724
745
return result
725
746
}
726
- context .TODO ()
727
747
}
728
748
729
749
writerPool := & sync.Pool {
730
750
New : func () any {
731
751
return printer .NewTextWriter (p .Options ().NewLine .GetNewLineCharacter ())
732
752
},
733
753
}
734
- wg := core .NewWorkGroup (p .singleThreaded ())
754
+ wg := core .NewWorkGroup (p .SingleThreaded ())
735
755
var emitters []* emitter
736
756
sourceFiles := getSourceFilesToEmit (p , options .TargetSourceFile , options .EmitOnly == EmitOnlyForcedDts )
737
757
0 commit comments