Skip to content

Commit 245a571

Browse files
committed
Simplify files parsing
1 parent 1d4d179 commit 245a571

File tree

3 files changed

+95
-143
lines changed

3 files changed

+95
-143
lines changed

internal/compiler/fileloader.go

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,8 @@ type fileLoader struct {
2222
comparePathsOptions tspath.ComparePathsOptions
2323
supportedExtensions []string
2424

25-
parseTasks *fileLoaderWorker[*parseTask]
26-
rootTasks []*parseTask
25+
filesParser *filesParser
26+
rootTasks []*parseTask
2727

2828
totalFileCount atomic.Int32
2929
libFileCount atomic.Int32
@@ -79,7 +79,7 @@ func processAllProgramFiles(
7979
UseCaseSensitiveFileNames: opts.Host.FS().UseCaseSensitiveFileNames(),
8080
CurrentDirectory: opts.Host.GetCurrentDirectory(),
8181
},
82-
parseTasks: &fileLoaderWorker[*parseTask]{
82+
filesParser: &filesParser{
8383
wg: core.NewWorkGroup(singleThreaded),
8484
maxDepth: maxNodeModuleJsDepth,
8585
},
@@ -111,7 +111,7 @@ func processAllProgramFiles(
111111
loader.addAutomaticTypeDirectiveTasks()
112112
}
113113

114-
loader.parseTasks.runAndWait(&loader, loader.rootTasks)
114+
loader.filesParser.parse(&loader, loader.rootTasks)
115115
// Clear out loader and host to ensure its not used post program creation
116116
loader.projectReferenceFileMapper.loader = nil
117117
loader.projectReferenceFileMapper.host = nil
@@ -134,7 +134,7 @@ func processAllProgramFiles(
134134
var libFileSet collections.Set[tspath.Path]
135135
fileLoadDiagnostics := &ast.DiagnosticsCollection{}
136136

137-
loader.parseTasks.collect(&loader, loader.rootTasks, func(task *parseTask, _ []tspath.Path) {
137+
loader.filesParser.collect(&loader, loader.rootTasks, func(task *parseTask) {
138138
if task.isRedirected {
139139
return
140140
}
@@ -286,12 +286,12 @@ func (p *fileLoader) addProjectReferenceTasks(singleThreaded bool) {
286286
return
287287
}
288288

289-
projectReferenceParser := &projectReferenceParser{
289+
parser := &projectReferenceParser{
290290
loader: p,
291291
wg: core.NewWorkGroup(singleThreaded),
292292
}
293293
rootTasks := createProjectReferenceParseTasks(projectReferences)
294-
projectReferenceParser.parse(rootTasks)
294+
parser.parse(rootTasks)
295295

296296
// Add files from project references as root if the module kind is 'none'.
297297
// This ensures that files from project references are included in the root tasks

internal/compiler/fileloadertask.go

Lines changed: 0 additions & 121 deletions
This file was deleted.

internal/compiler/parsetask.go renamed to internal/compiler/filesparser.go

Lines changed: 88 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,11 @@
11
package compiler
22

33
import (
4+
"math"
5+
"sync"
6+
47
"github.com/microsoft/typescript-go/internal/ast"
8+
"github.com/microsoft/typescript-go/internal/collections"
59
"github.com/microsoft/typescript-go/internal/core"
610
"github.com/microsoft/typescript-go/internal/module"
711
"github.com/microsoft/typescript-go/internal/tsoptions"
@@ -120,30 +124,99 @@ func (t *parseTask) addSubTask(ref resolvedRef, isLib bool) {
120124
t.subTasks = append(t.subTasks, subTask)
121125
}
122126

123-
func (t *parseTask) getSubTasks() []*parseTask {
124-
return t.subTasks
127+
type filesParser struct {
128+
wg core.WorkGroup
129+
tasksByFileName collections.SyncMap[string, *queuedParseTask]
130+
maxDepth int
125131
}
126132

127-
func (t *parseTask) shouldIncreaseDepth() bool {
128-
return t.increaseDepth
133+
type queuedParseTask struct {
134+
task *parseTask
135+
mu sync.Mutex
136+
lowestDepth int
137+
fromExternalLibrary bool
129138
}
130139

131-
func (t *parseTask) shouldElideOnDepth() bool {
132-
return t.elideOnDepth
140+
func (w *filesParser) parse(loader *fileLoader, tasks []*parseTask) {
141+
w.start(loader, tasks, 0, false)
142+
w.wg.RunAndWait()
133143
}
134144

135-
func (t *parseTask) isLoaded() bool {
136-
return t.loaded
137-
}
145+
func (w *filesParser) start(loader *fileLoader, tasks []*parseTask, depth int, isFromExternalLibrary bool) {
146+
for i, task := range tasks {
147+
taskIsFromExternalLibrary := isFromExternalLibrary || task.fromExternalLibrary
148+
newTask := &queuedParseTask{task: task, lowestDepth: math.MaxInt}
149+
loadedTask, loaded := w.tasksByFileName.LoadOrStore(task.FileName(), newTask)
150+
task = loadedTask.task
151+
if loaded {
152+
tasks[i] = task
153+
// Add in the loaded task's external-ness.
154+
taskIsFromExternalLibrary = taskIsFromExternalLibrary || task.fromExternalLibrary
155+
}
156+
157+
w.wg.Queue(func() {
158+
loadedTask.mu.Lock()
159+
defer loadedTask.mu.Unlock()
160+
161+
startSubtasks := false
162+
163+
currentDepth := depth
164+
if task.increaseDepth {
165+
currentDepth++
166+
}
167+
if currentDepth < loadedTask.lowestDepth {
168+
// If we're seeing this task at a lower depth than before,
169+
// reprocess its subtasks to ensure they are loaded.
170+
loadedTask.lowestDepth = currentDepth
171+
startSubtasks = true
172+
}
173+
174+
if !task.root && taskIsFromExternalLibrary && !loadedTask.fromExternalLibrary {
175+
// If we're seeing this task now as an external library,
176+
// reprocess its subtasks to ensure they are also marked as external.
177+
loadedTask.fromExternalLibrary = true
178+
startSubtasks = true
179+
}
138180

139-
func (t *parseTask) isRoot() bool {
140-
return t.root
181+
if task.elideOnDepth && currentDepth > w.maxDepth {
182+
return
183+
}
184+
185+
if !task.loaded {
186+
task.load(loader)
187+
}
188+
189+
if startSubtasks {
190+
w.start(loader, task.subTasks, loadedTask.lowestDepth, loadedTask.fromExternalLibrary)
191+
}
192+
})
193+
}
141194
}
142195

143-
func (t *parseTask) isFromExternalLibrary() bool {
144-
return t.fromExternalLibrary
196+
func (w *filesParser) collect(loader *fileLoader, tasks []*parseTask, iterate func(*parseTask)) []tspath.Path {
197+
// Mark all tasks we saw as external after the fact.
198+
w.tasksByFileName.Range(func(key string, value *queuedParseTask) bool {
199+
if value.fromExternalLibrary {
200+
value.task.fromExternalLibrary = true
201+
}
202+
return true
203+
})
204+
return w.collectWorker(loader, tasks, iterate, collections.Set[*parseTask]{})
145205
}
146206

147-
func (t *parseTask) markFromExternalLibrary() {
148-
t.fromExternalLibrary = true
207+
func (w *filesParser) collectWorker(loader *fileLoader, tasks []*parseTask, iterate func(*parseTask), seen collections.Set[*parseTask]) []tspath.Path {
208+
var results []tspath.Path
209+
for _, task := range tasks {
210+
// ensure we only walk each task once
211+
if !task.loaded || seen.Has(task) {
212+
continue
213+
}
214+
seen.Add(task)
215+
if subTasks := task.subTasks; len(subTasks) > 0 {
216+
w.collectWorker(loader, subTasks, iterate, seen)
217+
}
218+
iterate(task)
219+
results = append(results, loader.toPath(task.FileName()))
220+
}
221+
return results
149222
}

0 commit comments

Comments
 (0)