Skip to content

Commit b594699

Browse files
authored
Ensure we use the right checker in declaration diagnostics, fix lifetime (#1309)
1 parent 6072f10 commit b594699

File tree

9 files changed

+42
-36
lines changed

9 files changed

+42
-36
lines changed

internal/checker/checker.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30572,7 +30572,7 @@ func (c *Checker) GetTypeAtLocation(node *ast.Node) *Type {
3057230572
return c.getTypeOfNode(node)
3057330573
}
3057430574

30575-
func (c *Checker) GetEmitResolver(file *ast.SourceFile) *emitResolver {
30575+
func (c *Checker) GetEmitResolver() *emitResolver {
3057630576
c.emitResolverOnce.Do(func() {
3057730577
c.emitResolver = newEmitResolver(c)
3057830578
})

internal/checker/nodebuilderimpl.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1450,7 +1450,7 @@ func (b *nodeBuilderImpl) symbolToParameterDeclaration(parameterSymbol *ast.Symb
14501450
}
14511451
name := b.parameterToParameterDeclarationName(parameterSymbol, parameterDeclaration)
14521452
// TODO: isOptionalParameter on emit resolver here is silly - hoist to checker and reexpose on emit resolver?
1453-
isOptional := parameterDeclaration != nil && b.ch.GetEmitResolver(nil).isOptionalParameter(parameterDeclaration) || parameterSymbol.CheckFlags&ast.CheckFlagsOptionalParameter != 0
1453+
isOptional := parameterDeclaration != nil && b.ch.GetEmitResolver().isOptionalParameter(parameterDeclaration) || parameterSymbol.CheckFlags&ast.CheckFlagsOptionalParameter != 0
14541454
var questionToken *ast.Node
14551455
if isOptional {
14561456
questionToken = b.f.NewToken(ast.KindQuestionToken)
@@ -1887,7 +1887,7 @@ func (b *nodeBuilderImpl) serializeTypeForDeclaration(declaration *ast.Declarati
18871887
}
18881888
}
18891889
// !!! TODO: JSDoc, getEmitResolver call is unfortunate layering for the helper - hoist it into checker
1890-
addUndefinedForParameter := declaration != nil && (ast.IsParameter(declaration) /*|| ast.IsJSDocParameterTag(declaration)*/) && b.ch.GetEmitResolver(nil).requiresAddingImplicitUndefined(declaration, symbol, b.ctx.enclosingDeclaration)
1890+
addUndefinedForParameter := declaration != nil && (ast.IsParameter(declaration) /*|| ast.IsJSDocParameterTag(declaration)*/) && b.ch.GetEmitResolver().requiresAddingImplicitUndefined(declaration, symbol, b.ctx.enclosingDeclaration)
18911891
if addUndefinedForParameter {
18921892
t = b.ch.getOptionalType(t, false)
18931893
}

internal/checker/symbolaccessibility.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ func (ch *Checker) IsAnySymbolAccessible(symbols []*ast.Symbol, enclosingDeclara
3838
if len(accessibleSymbolChain) > 0 {
3939
hadAccessibleChain = symbol
4040
// TODO: going through emit resolver here is weird. Relayer these APIs.
41-
hasAccessibleDeclarations := ch.GetEmitResolver(nil).hasVisibleDeclarations(accessibleSymbolChain[0], shouldComputeAliasesToMakeVisible)
41+
hasAccessibleDeclarations := ch.GetEmitResolver().hasVisibleDeclarations(accessibleSymbolChain[0], shouldComputeAliasesToMakeVisible)
4242
if hasAccessibleDeclarations != nil {
4343
return hasAccessibleDeclarations
4444
}

internal/compiler/emitHost.go

Lines changed: 14 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -32,14 +32,22 @@ type EmitHost interface {
3232
GetCurrentDirectory() string
3333
CommonSourceDirectory() string
3434
IsEmitBlocked(file string) bool
35-
GetEmitResolver(file *ast.SourceFile) printer.EmitResolver
3635
}
3736

3837
var _ EmitHost = (*emitHost)(nil)
3938

4039
// NOTE: emitHost operations must be thread-safe
4140
type emitHost struct {
42-
program *Program
41+
program *Program
42+
emitResolver printer.EmitResolver
43+
}
44+
45+
func newEmitHost(ctx context.Context, program *Program, file *ast.SourceFile) (*emitHost, func()) {
46+
checker, done := program.GetTypeCheckerForFile(ctx, file)
47+
return &emitHost{
48+
program: program,
49+
emitResolver: checker.GetEmitResolver(),
50+
}, done
4351
}
4452

4553
func (host *emitHost) GetModeForUsageLocation(file ast.HasFileName, moduleSpecifier *ast.StringLiteralLike) core.ResolutionMode {
@@ -83,7 +91,7 @@ func (host *emitHost) GetRedirectTargets(path tspath.Path) []string {
8391
}
8492

8593
func (host *emitHost) GetEffectiveDeclarationFlags(node *ast.Node, flags ast.ModifierFlags) ast.ModifierFlags {
86-
return host.GetEmitResolver(ast.GetSourceFileOfNode(node)).GetEffectiveDeclarationFlags(node, flags)
94+
return host.GetEmitResolver().GetEffectiveDeclarationFlags(node, flags)
8795
}
8896

8997
func (host *emitHost) GetOutputPathsFor(file *ast.SourceFile, forceDtsPaths bool) declarations.OutputPaths {
@@ -92,7 +100,7 @@ func (host *emitHost) GetOutputPathsFor(file *ast.SourceFile, forceDtsPaths bool
92100
}
93101

94102
func (host *emitHost) GetResolutionModeOverride(node *ast.Node) core.ResolutionMode {
95-
return host.GetEmitResolver(ast.GetSourceFileOfNode(node)).GetResolutionModeOverride(node)
103+
return host.GetEmitResolver().GetResolutionModeOverride(node)
96104
}
97105

98106
func (host *emitHost) GetSourceFileFromReference(origin *ast.SourceFile, ref *ast.FileReference) *ast.SourceFile {
@@ -116,13 +124,8 @@ func (host *emitHost) WriteFile(fileName string, text string, writeByteOrderMark
116124
return host.program.Host().FS().WriteFile(fileName, text, writeByteOrderMark)
117125
}
118126

119-
func (host *emitHost) GetEmitResolver(file *ast.SourceFile) printer.EmitResolver {
120-
// The context and done function don't matter in tsc, currently the only caller of this function.
121-
// But if this ever gets used by LSP code, we'll need to thread the context properly and pass the
122-
// done function to the caller to ensure resources are cleaned up at the end of the request.
123-
checker, done := host.program.GetTypeCheckerForFile(context.TODO(), file)
124-
defer done()
125-
return checker.GetEmitResolver(file)
127+
func (host *emitHost) GetEmitResolver() printer.EmitResolver {
128+
return host.emitResolver
126129
}
127130

128131
func (host *emitHost) IsSourceFileFromExternalLibrary(file *ast.SourceFile) bool {

internal/compiler/emitter.go

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -49,9 +49,8 @@ func (e *emitter) emit() {
4949
e.emitBuildInfo(e.paths.BuildInfoPath())
5050
}
5151

52-
func (e *emitter) getDeclarationTransformers(emitContext *printer.EmitContext, sourceFile *ast.SourceFile, declarationFilePath string, declarationMapPath string) []*declarations.DeclarationTransformer {
53-
emitResolver := e.host.GetEmitResolver(sourceFile)
54-
transform := declarations.NewDeclarationTransformer(e.host, emitResolver, emitContext, e.host.Options(), declarationFilePath, declarationMapPath)
52+
func (e *emitter) getDeclarationTransformers(emitContext *printer.EmitContext, declarationFilePath string, declarationMapPath string) []*declarations.DeclarationTransformer {
53+
transform := declarations.NewDeclarationTransformer(e.host, emitContext, e.host.Options(), declarationFilePath, declarationMapPath)
5554
return []*declarations.DeclarationTransformer{transform}
5655
}
5756

@@ -86,7 +85,7 @@ func getScriptTransformers(emitContext *printer.EmitContext, host printer.EmitHo
8685
var emitResolver printer.EmitResolver
8786
var referenceResolver binder.ReferenceResolver
8887
if importElisionEnabled || options.GetJSXTransformEnabled() {
89-
emitResolver = host.GetEmitResolver(sourceFile)
88+
emitResolver = host.GetEmitResolver()
9089
emitResolver.MarkLinkedReferencesRecursively(sourceFile)
9190
referenceResolver = emitResolver
9291
} else {
@@ -179,7 +178,7 @@ func (e *emitter) emitDeclarationFile(sourceFile *ast.SourceFile, declarationFil
179178
var diags []*ast.Diagnostic
180179
emitContext, putEmitContext := printer.GetEmitContext()
181180
defer putEmitContext()
182-
for _, transformer := range e.getDeclarationTransformers(emitContext, sourceFile, declarationFilePath, declarationMapPath) {
181+
for _, transformer := range e.getDeclarationTransformers(emitContext, declarationFilePath, declarationMapPath) {
183182
sourceFile = transformer.TransformSourceFile(sourceFile)
184183
diags = append(diags, transformer.GetDiagnostics()...)
185184
}
@@ -378,6 +377,7 @@ type SourceFileMayBeEmittedHost interface {
378377
IsSourceFileFromExternalLibrary(file *ast.SourceFile) bool
379378
GetCurrentDirectory() string
380379
UseCaseSensitiveFileNames() bool
380+
SourceFiles() []*ast.SourceFile
381381
}
382382

383383
func sourceFileMayBeEmitted(sourceFile *ast.SourceFile, host SourceFileMayBeEmittedHost, forceDtsEmit bool) bool {
@@ -435,7 +435,7 @@ func sourceFileMayBeEmitted(sourceFile *ast.SourceFile, host SourceFileMayBeEmit
435435
return true
436436
}
437437

438-
func getSourceFilesToEmit(host printer.EmitHost, targetSourceFile *ast.SourceFile, forceDtsEmit bool) []*ast.SourceFile {
438+
func getSourceFilesToEmit(host SourceFileMayBeEmittedHost, targetSourceFile *ast.SourceFile, forceDtsEmit bool) []*ast.SourceFile {
439439
// !!! outFile not yet implemented, may be deprecated
440440
var sourceFiles []*ast.SourceFile
441441
if targetSourceFile != nil {
@@ -452,13 +452,13 @@ func isSourceFileNotJson(file *ast.SourceFile) bool {
452452
return !ast.IsJsonSourceFile(file)
453453
}
454454

455-
func getDeclarationDiagnostics(host EmitHost, resolver printer.EmitResolver, file *ast.SourceFile) []*ast.Diagnostic {
455+
func getDeclarationDiagnostics(host EmitHost, file *ast.SourceFile) []*ast.Diagnostic {
456456
fullFiles := core.Filter(getSourceFilesToEmit(host, file, false), isSourceFileNotJson)
457457
if !core.Some(fullFiles, func(f *ast.SourceFile) bool { return f == file }) {
458458
return []*ast.Diagnostic{}
459459
}
460460
options := host.Options()
461-
transform := declarations.NewDeclarationTransformer(host, resolver, nil, options, "", "")
461+
transform := declarations.NewDeclarationTransformer(host, nil, options, "", "")
462462
transform.TransformSourceFile(file)
463463
return transform.GetDiagnostics()
464464
}

internal/compiler/program.go

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -449,7 +449,7 @@ func (p *Program) getSemanticDiagnosticsForFile(ctx context.Context, sourceFile
449449
return filtered
450450
}
451451

452-
func (p *Program) getDeclarationDiagnosticsForFile(_ctx context.Context, sourceFile *ast.SourceFile) []*ast.Diagnostic {
452+
func (p *Program) getDeclarationDiagnosticsForFile(ctx context.Context, sourceFile *ast.SourceFile) []*ast.Diagnostic {
453453
if sourceFile.IsDeclarationFile {
454454
return []*ast.Diagnostic{}
455455
}
@@ -458,8 +458,9 @@ func (p *Program) getDeclarationDiagnosticsForFile(_ctx context.Context, sourceF
458458
return cached
459459
}
460460

461-
host := &emitHost{program: p}
462-
diagnostics := getDeclarationDiagnostics(host, host.GetEmitResolver(sourceFile), sourceFile)
461+
host, done := newEmitHost(ctx, p, sourceFile)
462+
defer done()
463+
diagnostics := getDeclarationDiagnostics(host, sourceFile)
463464
diagnostics, _ = p.declarationDiagnosticCache.LoadOrStore(sourceFile, diagnostics)
464465
return diagnostics
465466
}
@@ -651,9 +652,8 @@ func (p *Program) CommonSourceDirectory() string {
651652
p.Options(),
652653
func() []string {
653654
var files []string
654-
host := &emitHost{program: p}
655655
for _, file := range p.files {
656-
if sourceFileMayBeEmitted(file, host, false /*forceDtsEmit*/) {
656+
if sourceFileMayBeEmitted(file, p, false /*forceDtsEmit*/) {
657657
files = append(files, file.FileName())
658658
}
659659
}
@@ -688,27 +688,28 @@ func (p *Program) Emit(options EmitOptions) *EmitResult {
688688
// !!! performance measurement
689689
p.BindSourceFiles()
690690

691-
host := &emitHost{program: p}
692-
693691
writerPool := &sync.Pool{
694692
New: func() any {
695-
return printer.NewTextWriter(host.Options().NewLine.GetNewLineCharacter())
693+
return printer.NewTextWriter(p.Options().NewLine.GetNewLineCharacter())
696694
},
697695
}
698696
wg := core.NewWorkGroup(p.singleThreaded())
699697
var emitters []*emitter
700-
sourceFiles := getSourceFilesToEmit(host, options.TargetSourceFile, options.forceDtsEmit)
698+
sourceFiles := getSourceFilesToEmit(p, options.TargetSourceFile, options.forceDtsEmit)
701699

702700
for _, sourceFile := range sourceFiles {
703701
emitter := &emitter{
704-
host: host,
705702
emittedFilesList: nil,
706703
sourceMapDataList: nil,
707704
writer: nil,
708705
sourceFile: sourceFile,
709706
}
710707
emitters = append(emitters, emitter)
711708
wg.Queue(func() {
709+
host, done := newEmitHost(context.TODO(), p, sourceFile)
710+
defer done()
711+
emitter.host = host
712+
712713
// take an unused writer
713714
writer := writerPool.Get().(printer.EmitTextWriter)
714715
writer.Clear()

internal/printer/emithost.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ type EmitHost interface {
2525
IsEmitBlocked(file string) bool
2626
WriteFile(fileName string, text string, writeByteOrderMark bool, relatedSourceFiles []*ast.SourceFile, data *WriteFileData) error
2727
GetEmitModuleFormatOfFile(file ast.HasFileName) core.ModuleKind
28-
GetEmitResolver(file *ast.SourceFile) EmitResolver
28+
GetEmitResolver() EmitResolver
2929
GetOutputAndProjectReference(path tspath.Path) *tsoptions.OutputDtsAndProjectReference
3030
IsSourceFileFromExternalLibrary(file *ast.SourceFile) bool
3131
}

internal/transformers/declarations/transform.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ type DeclarationEmitHost interface {
3535
GetOutputPathsFor(file *ast.SourceFile, forceDtsPaths bool) OutputPaths
3636
GetResolutionModeOverride(node *ast.Node) core.ResolutionMode
3737
GetEffectiveDeclarationFlags(node *ast.Node, flags ast.ModifierFlags) ast.ModifierFlags
38+
GetEmitResolver() printer.EmitResolver
3839
}
3940

4041
type DeclarationTransformer struct {
@@ -60,7 +61,8 @@ type DeclarationTransformer struct {
6061
rawLibReferenceDirectives []*ast.FileReference
6162
}
6263

63-
func NewDeclarationTransformer(host DeclarationEmitHost, resolver printer.EmitResolver, context *printer.EmitContext, compilerOptions *core.CompilerOptions, declarationFilePath string, declarationMapPath string) *DeclarationTransformer {
64+
func NewDeclarationTransformer(host DeclarationEmitHost, context *printer.EmitContext, compilerOptions *core.CompilerOptions, declarationFilePath string, declarationMapPath string) *DeclarationTransformer {
65+
resolver := host.GetEmitResolver()
6466
state := &SymbolTrackerSharedState{isolatedDeclarations: compilerOptions.IsolatedDeclarations.IsTrue(), resolver: resolver}
6567
tracker := NewSymbolTracker(host, resolver, state)
6668
// TODO: Use new host GetOutputPathsFor method instead of passing in entrypoint paths (which will also better support bundled emit)

internal/transformers/tstransforms/importelision_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -241,7 +241,7 @@ func TestImportElision(t *testing.T) {
241241
},
242242
})
243243

244-
emitResolver := c.GetEmitResolver(file)
244+
emitResolver := c.GetEmitResolver()
245245
emitResolver.MarkLinkedReferencesRecursively(file)
246246

247247
emitContext := printer.NewEmitContext()

0 commit comments

Comments
 (0)