Skip to content

Commit bb2ff48

Browse files
committed
Watch type reference locations too and handle auto type refs
1 parent 96bcae5 commit bb2ff48

File tree

5 files changed

+92
-36
lines changed

5 files changed

+92
-36
lines changed

internal/compiler/fileloader.go

Lines changed: 29 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -113,10 +113,16 @@ func processAllProgramFiles(
113113
var unsupportedExtensions []string
114114

115115
loader.parseTasks.collect(&loader, loader.rootTasks, func(task *parseTask, _ []tspath.Path) {
116-
file := task.file
117116
if task.isRedirected {
118117
return
119118
}
119+
120+
if task.isForAutomaticTypeDirective {
121+
typeResolutionsInFile[task.path] = task.typeResolutionsInFile
122+
return
123+
}
124+
file := task.file
125+
path := task.path
120126
if file == nil {
121127
missingFiles = append(missingFiles, task.normalizedFilePath)
122128
return
@@ -126,7 +132,6 @@ func processAllProgramFiles(
126132
} else {
127133
files = append(files, file)
128134
}
129-
path := file.Path()
130135

131136
filesByPath[path] = file
132137
resolvedModules[path] = task.resolutionsInFile
@@ -189,14 +194,31 @@ func (p *fileLoader) addAutomaticTypeDirectiveTasks() {
189194
containingDirectory = p.opts.Host.GetCurrentDirectory()
190195
}
191196
containingFileName := tspath.CombinePaths(containingDirectory, module.InferredTypesContainingFile)
197+
p.rootTasks = append(p.rootTasks, &parseTask{normalizedFilePath: containingFileName, isLib: false, isForAutomaticTypeDirective: true})
198+
}
192199

193-
automaticTypeDirectiveNames := module.GetAutomaticTypeDirectiveNames(compilerOptions, p.opts.Host)
194-
for _, name := range automaticTypeDirectiveNames {
195-
resolved := p.resolver.ResolveTypeReferenceDirective(name, containingFileName, core.ModuleKindNodeNext, nil)
196-
if resolved.IsResolved() {
197-
p.rootTasks = append(p.rootTasks, &parseTask{normalizedFilePath: resolved.ResolvedFileName, isLib: false})
200+
func (p *fileLoader) resolveAutomaticTypeDirectives(containingFileName string) (
201+
toParse []resolvedRef,
202+
typeResolutionsInFile module.ModeAwareCache[*module.ResolvedTypeReferenceDirective],
203+
) {
204+
automaticTypeDirectiveNames := module.GetAutomaticTypeDirectiveNames(p.opts.Config.CompilerOptions(), p.opts.Host)
205+
if len(automaticTypeDirectiveNames) != 0 {
206+
toParse = make([]resolvedRef, 0, len(automaticTypeDirectiveNames))
207+
typeResolutionsInFile = make(module.ModeAwareCache[*module.ResolvedTypeReferenceDirective], len(automaticTypeDirectiveNames))
208+
for _, name := range automaticTypeDirectiveNames {
209+
resolutionMode := core.ModuleKindNodeNext
210+
resolved := p.resolver.ResolveTypeReferenceDirective(name, containingFileName, resolutionMode, nil)
211+
typeResolutionsInFile[module.ModeAwareCacheKey{Name: name, Mode: resolutionMode}] = resolved
212+
if resolved.IsResolved() {
213+
toParse = append(toParse, resolvedRef{
214+
fileName: resolved.ResolvedFileName,
215+
increaseDepth: resolved.IsExternalLibraryImport,
216+
elideOnDepth: false,
217+
})
218+
}
198219
}
199220
}
221+
return toParse, typeResolutionsInFile
200222
}
201223

202224
func (p *fileLoader) addProjectReferenceTasks() {

internal/compiler/parsetask.go

Lines changed: 20 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,14 @@ import (
99
)
1010

1111
type parseTask struct {
12-
normalizedFilePath string
13-
path tspath.Path
14-
file *ast.SourceFile
15-
isLib bool
16-
isRedirected bool
17-
subTasks []*parseTask
18-
loaded bool
12+
normalizedFilePath string
13+
path tspath.Path
14+
file *ast.SourceFile
15+
isLib bool
16+
isRedirected bool
17+
subTasks []*parseTask
18+
loaded bool
19+
isForAutomaticTypeDirective bool
1920

2021
metadata ast.SourceFileMetaData
2122
resolutionsInFile module.ModeAwareCache[*module.ResolvedModule]
@@ -36,8 +37,11 @@ func (t *parseTask) Path() tspath.Path {
3637

3738
func (t *parseTask) load(loader *fileLoader) {
3839
t.loaded = true
39-
4040
t.path = loader.toPath(t.normalizedFilePath)
41+
if t.isForAutomaticTypeDirective {
42+
t.loadAutomaticTypeDirectives(loader)
43+
return
44+
}
4145
redirect := loader.projectReferenceFileMapper.getParseFileRedirect(t)
4246
if redirect != "" {
4347
t.redirect(loader, redirect)
@@ -97,6 +101,14 @@ func (t *parseTask) redirect(loader *fileLoader, fileName string) {
97101
t.subTasks = []*parseTask{{normalizedFilePath: tspath.NormalizePath(fileName), isLib: t.isLib}}
98102
}
99103

104+
func (t *parseTask) loadAutomaticTypeDirectives(loader *fileLoader) {
105+
toParseTypeRefs, typeResolutionsInFile := loader.resolveAutomaticTypeDirectives(t.normalizedFilePath)
106+
t.typeResolutionsInFile = typeResolutionsInFile
107+
for _, typeResolution := range toParseTypeRefs {
108+
t.addSubTask(typeResolution, false)
109+
}
110+
}
111+
100112
type resolvedRef struct {
101113
fileName string
102114
increaseDepth bool

internal/compiler/program.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -813,6 +813,10 @@ func (p *Program) GetResolvedTypeReferenceDirectiveFromTypeReferenceDirective(ty
813813
return nil
814814
}
815815

816+
func (p *Program) GetResolvedTypeReferenceDirectives() map[tspath.Path]module.ModeAwareCache[*module.ResolvedTypeReferenceDirective] {
817+
return p.typeResolutionsInFile
818+
}
819+
816820
func (p *Program) getModeForTypeReferenceDirectiveInFile(ref *ast.FileReference, sourceFile *ast.SourceFile) core.ResolutionMode {
817821
if ref.ResolutionMode != core.ResolutionModeNone {
818822
return ref.ResolutionMode

internal/module/types.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,10 @@ func (r *ResolvedModule) IsResolved() bool {
8181
return r != nil && r.ResolvedFileName != ""
8282
}
8383

84+
func (r *ResolvedModule) GetLookupLocations() *LookupLocations {
85+
return &r.LookupLocations
86+
}
87+
8488
type ResolvedTypeReferenceDirective struct {
8589
LookupLocations
8690
Primary bool
@@ -94,6 +98,10 @@ func (r *ResolvedTypeReferenceDirective) IsResolved() bool {
9498
return r.ResolvedFileName != ""
9599
}
96100

101+
func (r *ResolvedTypeReferenceDirective) GetLookupLocations() *LookupLocations {
102+
return &r.LookupLocations
103+
}
104+
97105
type extensions int32
98106

99107
const (

internal/project/project.go

Lines changed: 31 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -347,37 +347,47 @@ func (p *Project) GetLanguageServiceForRequest(ctx context.Context) (*ls.Languag
347347
return languageService, cleanup
348348
}
349349

350-
func (p *Project) getModuleResolutionWatchGlobs() (failedLookups map[tspath.Path]string, affectingLocaions map[tspath.Path]string) {
351-
failedLookups = make(map[tspath.Path]string)
352-
affectingLocaions = make(map[tspath.Path]string)
353-
for _, resolvedModulesInFile := range p.program.GetResolvedModules() {
350+
func (p *Project) updateModuleResolutionWatches(ctx context.Context) {
351+
client := p.Client()
352+
if !p.host.IsWatchEnabled() || client == nil {
353+
return
354+
}
355+
356+
failedLookups := make(map[tspath.Path]string)
357+
affectingLocations := make(map[tspath.Path]string)
358+
extractLookups(p, failedLookups, affectingLocations, p.program.GetResolvedModules())
359+
extractLookups(p, failedLookups, affectingLocations, p.program.GetResolvedTypeReferenceDirectives())
360+
361+
p.failedLookupsWatch.update(ctx, failedLookups)
362+
p.affectingLocationsWatch.update(ctx, affectingLocations)
363+
}
364+
365+
type ResolutionWithLookupLocations interface {
366+
GetLookupLocations() *module.LookupLocations
367+
}
368+
369+
func extractLookups[T ResolutionWithLookupLocations](
370+
p *Project,
371+
failedLookups map[tspath.Path]string,
372+
affectingLocations map[tspath.Path]string,
373+
cache map[tspath.Path]module.ModeAwareCache[T],
374+
) {
375+
for _, resolvedModulesInFile := range cache {
354376
for _, resolvedModule := range resolvedModulesInFile {
355-
for _, failedLookupLocation := range resolvedModule.FailedLookupLocations {
377+
for _, failedLookupLocation := range resolvedModule.GetLookupLocations().FailedLookupLocations {
356378
path := p.toPath(failedLookupLocation)
357379
if _, ok := failedLookups[path]; !ok {
358380
failedLookups[path] = failedLookupLocation
359381
}
360382
}
361-
for _, affectingLocation := range resolvedModule.AffectingLocations {
383+
for _, affectingLocation := range resolvedModule.GetLookupLocations().AffectingLocations {
362384
path := p.toPath(affectingLocation)
363-
if _, ok := affectingLocaions[path]; !ok {
364-
affectingLocaions[path] = affectingLocation
385+
if _, ok := affectingLocations[path]; !ok {
386+
affectingLocations[path] = affectingLocation
365387
}
366388
}
367389
}
368390
}
369-
return failedLookups, affectingLocaions
370-
}
371-
372-
func (p *Project) updateWatchers(ctx context.Context) {
373-
client := p.Client()
374-
if !p.host.IsWatchEnabled() || client == nil {
375-
return
376-
}
377-
378-
failedLookupGlobs, affectingLocationGlobs := p.getModuleResolutionWatchGlobs()
379-
p.failedLookupsWatch.update(ctx, failedLookupGlobs)
380-
p.affectingLocationsWatch.update(ctx, affectingLocationGlobs)
381391
}
382392

383393
// onWatchEventForNilScriptInfo is fired for watch events that are not the
@@ -530,7 +540,7 @@ func (p *Project) updateGraph() (*compiler.Program, bool) {
530540
p.enqueueInstallTypingsForProject(oldProgram, hasAddedOrRemovedFiles)
531541
// TODO: this is currently always synchronously called by some kind of updating request,
532542
// but in Strada we throttle, so at least sometimes this should be considered top-level?
533-
p.updateWatchers(context.TODO())
543+
p.updateModuleResolutionWatches(context.TODO())
534544
}
535545
p.Logf("Finishing updateGraph: Project: %s version: %d in %s", p.name, p.version, time.Since(start))
536546
return p.program, true

0 commit comments

Comments
 (0)