Skip to content

Commit f3b2563

Browse files
committed
Parallel!!!
1 parent b52d094 commit f3b2563

File tree

16 files changed

+1679
-1699
lines changed

16 files changed

+1679
-1699
lines changed

internal/checker/checker.go

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -856,6 +856,8 @@ type Checker struct {
856856
skipDirectInferenceNodes collections.Set[*ast.Node]
857857
ctx context.Context
858858
packagesMap map[string]bool
859+
ambientModulesOnce sync.Once
860+
ambientModules []*ast.Symbol
859861
}
860862

861863
func NewChecker(program Program) *Checker {
@@ -14842,6 +14844,17 @@ func (c *Checker) tryFindAmbientModule(moduleName string, withAugmentations bool
1484214844
return symbol
1484314845
}
1484414846

14847+
func (c *Checker) GetAmbientModules() []*ast.Symbol {
14848+
c.ambientModulesOnce.Do(func() {
14849+
for sym, global := range c.globals {
14850+
if strings.HasPrefix(sym, "\"") && strings.HasSuffix(sym, "\"") {
14851+
c.ambientModules = append(c.ambientModules, global)
14852+
}
14853+
}
14854+
})
14855+
return c.ambientModules
14856+
}
14857+
1484514858
func (c *Checker) resolveExternalModuleSymbol(moduleSymbol *ast.Symbol, dontResolveAlias bool) *ast.Symbol {
1484614859
if moduleSymbol != nil {
1484714860
exportEquals := c.resolveSymbolEx(moduleSymbol.Exports[ast.InternalSymbolNameExportEquals], dontResolveAlias)

internal/checker/checker_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ func TestCheckSrcCompiler(t *testing.T) {
7777
Config: parsed,
7878
Host: host,
7979
})
80-
p.CheckSourceFiles(t.Context())
80+
p.CheckSourceFiles(t.Context(), nil)
8181
}
8282

8383
func BenchmarkNewChecker(b *testing.B) {

internal/collections/syncset.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,3 +16,9 @@ func (s *SyncSet[T]) Add(key T) {
1616
func (s *SyncSet[T]) Delete(key T) {
1717
s.m.Delete(key)
1818
}
19+
20+
func (s *SyncSet[T]) Range(fn func(key T) bool) {
21+
s.m.Range(func(key T, value struct{}) bool {
22+
return fn(key)
23+
})
24+
}

internal/compiler/checkerpool.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ func (p *checkerPool) GetChecker(ctx context.Context) (*checker.Checker, func())
5353

5454
func (p *checkerPool) createCheckers() {
5555
p.createCheckersOnce.Do(func() {
56-
wg := core.NewWorkGroup(p.program.singleThreaded())
56+
wg := core.NewWorkGroup(p.program.SingleThreaded())
5757
for i := range p.checkerCount {
5858
wg.Queue(func() {
5959
p.checkers[i] = checker.NewChecker(p.program)

internal/compiler/emitter.go

Lines changed: 12 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -484,15 +484,8 @@ type AnyProgram interface {
484484
Emit(ctx context.Context, options EmitOptions) *EmitResult
485485
}
486486

487-
func HandleNoEmitOptions(ctx context.Context, program AnyProgram, file *ast.SourceFile) *EmitResult {
488-
options := program.Options()
489-
if options.NoEmit.IsTrue() {
490-
return &EmitResult{
491-
EmitSkipped: true,
492-
}
493-
}
494-
495-
if !options.NoEmitOnError.IsTrue() {
487+
func HandleNoEmitOnError(ctx context.Context, program AnyProgram, file *ast.SourceFile) *EmitResult {
488+
if !program.Options().NoEmitOnError.IsTrue() {
496489
return nil // No emit on error is not set, so we can proceed with emitting
497490
}
498491

@@ -549,16 +542,19 @@ func GetDiagnosticsOfAnyProgram(
549542

550543
func CombineEmitResults(results []*EmitResult) *EmitResult {
551544
result := &EmitResult{}
552-
for _, emitter := range results {
553-
if emitter.EmitSkipped {
545+
for _, emitResult := range results {
546+
if emitResult == nil {
547+
continue // Skip nil results
548+
}
549+
if emitResult.EmitSkipped {
554550
result.EmitSkipped = true
555551
}
556-
result.Diagnostics = append(result.Diagnostics, emitter.Diagnostics...)
557-
if emitter.EmittedFiles != nil {
558-
result.EmittedFiles = append(result.EmittedFiles, emitter.EmittedFiles...)
552+
result.Diagnostics = append(result.Diagnostics, emitResult.Diagnostics...)
553+
if emitResult.EmittedFiles != nil {
554+
result.EmittedFiles = append(result.EmittedFiles, emitResult.EmittedFiles...)
559555
}
560-
if emitter.SourceMaps != nil {
561-
result.SourceMaps = append(result.SourceMaps, emitter.SourceMaps...)
556+
if emitResult.SourceMaps != nil {
557+
result.SourceMaps = append(result.SourceMaps, emitResult.SourceMaps...)
562558
}
563559
}
564560
return result

internal/compiler/program.go

Lines changed: 38 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,6 @@ func (p *ProgramOptions) canUseProjectReferenceSource() bool {
3939

4040
type Program struct {
4141
opts ProgramOptions
42-
nodeModules map[string]*ast.SourceFile
4342
checkerPool CheckerPool
4443

4544
comparePathsOptions tspath.ComparePathsOptions
@@ -178,7 +177,7 @@ func (p *Program) GetSourceFileFromReference(origin *ast.SourceFile, ref *ast.Fi
178177
func NewProgram(opts ProgramOptions) *Program {
179178
p := &Program{opts: opts}
180179
p.initCheckerPool()
181-
p.processedFiles = processAllProgramFiles(p.opts, p.singleThreaded())
180+
p.processedFiles = processAllProgramFiles(p.opts, p.SingleThreaded())
182181
return p
183182
}
184183

@@ -192,7 +191,6 @@ func (p *Program) UpdateProgram(changedFilePath tspath.Path) (*Program, bool) {
192191
}
193192
result := &Program{
194193
opts: p.opts,
195-
nodeModules: p.nodeModules,
196194
comparePathsOptions: p.comparePathsOptions,
197195
processedFiles: p.processedFiles,
198196
usesUriStyleNodeCoreModules: p.usesUriStyleNodeCoreModules,
@@ -210,7 +208,7 @@ func (p *Program) initCheckerPool() {
210208
if p.opts.CreateCheckerPool != nil {
211209
p.checkerPool = p.opts.CreateCheckerPool(p)
212210
} else {
213-
p.checkerPool = newCheckerPool(core.IfElse(p.singleThreaded(), 1, 4), p)
211+
p.checkerPool = newCheckerPool(core.IfElse(p.SingleThreaded(), 1, 4), p)
214212
}
215213
}
216214

@@ -250,12 +248,12 @@ func (p *Program) GetConfigFileParsingDiagnostics() []*ast.Diagnostic {
250248
return slices.Clip(p.opts.Config.GetConfigFileParsingDiagnostics())
251249
}
252250

253-
func (p *Program) singleThreaded() bool {
251+
func (p *Program) SingleThreaded() bool {
254252
return p.opts.SingleThreaded.DefaultIfUnknown(p.Options().SingleThreaded).IsTrue()
255253
}
256254

257255
func (p *Program) BindSourceFiles() {
258-
wg := core.NewWorkGroup(p.singleThreaded())
256+
wg := core.NewWorkGroup(p.SingleThreaded())
259257
for _, file := range p.files {
260258
if !file.IsBound() {
261259
wg.Queue(func() {
@@ -266,14 +264,16 @@ func (p *Program) BindSourceFiles() {
266264
wg.RunAndWait()
267265
}
268266

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())
271269
checkers, done := p.checkerPool.GetAllCheckers(ctx)
272270
defer done()
273271
for _, checker := range checkers {
274272
wg.Queue(func() {
275273
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+
}
277277
}
278278
})
279279
}
@@ -330,6 +330,19 @@ func (p *Program) GetSemanticDiagnostics(ctx context.Context, sourceFile *ast.So
330330
return p.getDiagnosticsHelper(ctx, sourceFile, true /*ensureBound*/, true /*ensureChecked*/, p.getSemanticDiagnosticsForFile)
331331
}
332332

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+
333346
func (p *Program) GetSuggestionDiagnostics(ctx context.Context, sourceFile *ast.SourceFile) []*ast.Diagnostic {
334347
return p.getDiagnosticsHelper(ctx, sourceFile, true /*ensureBound*/, true /*ensureChecked*/, p.getSuggestionDiagnosticsForFile)
335348
}
@@ -389,6 +402,14 @@ func FilterNoEmitSemanticDiagnostics(diagnostics []*ast.Diagnostic, options *cor
389402
}
390403

391404
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 {
392413
compilerOptions := p.Options()
393414
if checker.SkipTypeChecking(sourceFile, compilerOptions, p, false) {
394415
return nil
@@ -421,13 +442,13 @@ func (p *Program) getSemanticDiagnosticsForFile(ctx context.Context, sourceFile
421442

422443
isPlainJS := ast.IsPlainJSFile(sourceFile, compilerOptions.CheckJs)
423444
if isPlainJS {
424-
return FilterNoEmitSemanticDiagnostics(core.Filter(diags, func(d *ast.Diagnostic) bool {
445+
return core.Filter(diags, func(d *ast.Diagnostic) bool {
425446
return plainJSErrors.Has(d.Code())
426-
}), p.Options())
447+
})
427448
}
428449

429450
if len(sourceFile.CommentDirectives) == 0 {
430-
return FilterNoEmitSemanticDiagnostics(diags, p.Options())
451+
return diags
431452
}
432453
// Build map of directives by line number
433454
directivesByLine := make(map[int]ast.CommentDirective)
@@ -464,7 +485,7 @@ func (p *Program) getSemanticDiagnosticsForFile(ctx context.Context, sourceFile
464485
filtered = append(filtered, ast.NewDiagnostic(sourceFile, directive.Loc, diagnostics.Unused_ts_expect_error_directive))
465486
}
466487
}
467-
return FilterNoEmitSemanticDiagnostics(filtered, p.Options())
488+
return filtered
468489
}
469490

470491
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
575596
p.BindSourceFiles()
576597
}
577598
if ensureChecked {
578-
p.CheckSourceFiles(ctx)
599+
p.CheckSourceFiles(ctx, nil)
579600
if ctx.Err() != nil {
580601
return nil
581602
}
@@ -715,23 +736,22 @@ func (p *Program) Emit(ctx context.Context, options EmitOptions) *EmitResult {
715736
// !!! performance measurement
716737
p.BindSourceFiles()
717738
if options.EmitOnly != EmitOnlyForcedDts {
718-
result := HandleNoEmitOptions(
739+
result := HandleNoEmitOnError(
719740
ctx,
720741
p,
721742
options.TargetSourceFile,
722743
)
723-
if result != nil {
744+
if result != nil || ctx.Err() != nil {
724745
return result
725746
}
726-
context.TODO()
727747
}
728748

729749
writerPool := &sync.Pool{
730750
New: func() any {
731751
return printer.NewTextWriter(p.Options().NewLine.GetNewLineCharacter())
732752
},
733753
}
734-
wg := core.NewWorkGroup(p.singleThreaded())
754+
wg := core.NewWorkGroup(p.SingleThreaded())
735755
var emitters []*emitter
736756
sourceFiles := getSourceFilesToEmit(p, options.TargetSourceFile, options.EmitOnly == EmitOnlyForcedDts)
737757

internal/execute/tsc.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -362,7 +362,9 @@ func emitFilesAndReportErrors(
362362
emitResult = program.Emit(ctx, compiler.EmitOptions{})
363363
result.emitTime = sys.Now().Sub(emitStart)
364364
}
365-
allDiagnostics = append(allDiagnostics, emitResult.Diagnostics...)
365+
if emitResult != nil {
366+
allDiagnostics = append(allDiagnostics, emitResult.Diagnostics...)
367+
}
366368

367369
allDiagnostics = compiler.SortAndDeduplicateDiagnostics(allDiagnostics)
368370
for _, diagnostic := range allDiagnostics {

0 commit comments

Comments
 (0)