Skip to content

Commit 1d4d179

Browse files
committed
Simplify project reference parsing and file parsing
1 parent 29441f1 commit 1d4d179

File tree

4 files changed

+124
-123
lines changed

4 files changed

+124
-123
lines changed

internal/compiler/fileloader.go

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

25-
parseTasks *fileLoaderWorker[*parseTask]
26-
projectReferenceParseTasks *fileLoaderWorker[*projectReferenceParseTask]
27-
rootTasks []*parseTask
25+
parseTasks *fileLoaderWorker[*parseTask]
26+
rootTasks []*parseTask
2827

2928
totalFileCount atomic.Int32
3029
libFileCount atomic.Int32
@@ -84,13 +83,10 @@ func processAllProgramFiles(
8483
wg: core.NewWorkGroup(singleThreaded),
8584
maxDepth: maxNodeModuleJsDepth,
8685
},
87-
projectReferenceParseTasks: &fileLoaderWorker[*projectReferenceParseTask]{
88-
wg: core.NewWorkGroup(singleThreaded),
89-
},
9086
rootTasks: make([]*parseTask, 0, len(rootFiles)+len(compilerOptions.Lib)),
9187
supportedExtensions: core.Flatten(tsoptions.GetSupportedExtensionsWithJsonIfResolveJsonModule(compilerOptions, supportedExtensions)),
9288
}
93-
loader.addProjectReferenceTasks()
89+
loader.addProjectReferenceTasks(singleThreaded)
9490
loader.resolver = module.NewResolver(loader.projectReferenceFileMapper.host, compilerOptions, opts.TypingsLocation, opts.ProjectName)
9591

9692
var libs []string
@@ -280,7 +276,7 @@ func (p *fileLoader) resolveAutomaticTypeDirectives(containingFileName string) (
280276
return toParse, typeResolutionsInFile
281277
}
282278

283-
func (p *fileLoader) addProjectReferenceTasks() {
279+
func (p *fileLoader) addProjectReferenceTasks(singleThreaded bool) {
284280
p.projectReferenceFileMapper = &projectReferenceFileMapper{
285281
opts: p.opts,
286282
host: p.opts.Host,
@@ -290,9 +286,12 @@ func (p *fileLoader) addProjectReferenceTasks() {
290286
return
291287
}
292288

289+
projectReferenceParser := &projectReferenceParser{
290+
loader: p,
291+
wg: core.NewWorkGroup(singleThreaded),
292+
}
293293
rootTasks := createProjectReferenceParseTasks(projectReferences)
294-
p.projectReferenceParseTasks.runAndWait(p, rootTasks)
295-
p.projectReferenceFileMapper.init(p, rootTasks)
294+
projectReferenceParser.parse(rootTasks)
296295

297296
// Add files from project references as root if the module kind is 'none'.
298297
// This ensures that files from project references are included in the root tasks
@@ -567,11 +566,6 @@ func getInferredLibraryNameResolveFrom(options *core.CompilerOptions, currentDir
567566
return tspath.CombinePaths(containingDirectory, "__lib_node_modules_lookup_"+libFileName+"__.ts")
568567
}
569568

570-
type resolution struct {
571-
node *ast.Node
572-
resolvedModule *module.ResolvedModule
573-
}
574-
575569
func getModeForTypeReferenceDirectiveInFile(ref *ast.FileReference, file *ast.SourceFile, meta ast.SourceFileMetaData, options *core.CompilerOptions) core.ResolutionMode {
576570
if ref.ResolutionMode != core.ResolutionModeNone {
577571
return ref.ResolutionMode

internal/compiler/projectreferencefilemapper.go

Lines changed: 0 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -25,44 +25,6 @@ type projectReferenceFileMapper struct {
2525
realpathDtsToSource collections.SyncMap[tspath.Path, *tsoptions.SourceAndProjectReference]
2626
}
2727

28-
func (mapper *projectReferenceFileMapper) init(loader *fileLoader, rootTasks []*projectReferenceParseTask) {
29-
totalReferences := loader.projectReferenceParseTasks.tasksByFileName.Size() + 1
30-
mapper.loader = loader
31-
mapper.configToProjectReference = make(map[tspath.Path]*tsoptions.ParsedCommandLine, totalReferences)
32-
mapper.referencesInConfigFile = make(map[tspath.Path][]tspath.Path, totalReferences)
33-
mapper.sourceToOutput = make(map[tspath.Path]*tsoptions.OutputDtsAndProjectReference)
34-
mapper.outputDtsToSource = make(map[tspath.Path]*tsoptions.SourceAndProjectReference)
35-
mapper.referencesInConfigFile[mapper.opts.Config.ConfigFile.SourceFile.Path()] = loader.projectReferenceParseTasks.collect(
36-
loader,
37-
rootTasks,
38-
func(task *projectReferenceParseTask, referencesInConfig []tspath.Path) {
39-
path := loader.toPath(task.configName)
40-
mapper.configToProjectReference[path] = task.resolved
41-
if task.resolved == nil || mapper.opts.Config.ConfigFile == task.resolved.ConfigFile {
42-
return
43-
}
44-
mapper.referencesInConfigFile[path] = referencesInConfig
45-
for key, value := range task.resolved.SourceToOutput() {
46-
mapper.sourceToOutput[key] = value
47-
}
48-
for key, value := range task.resolved.OutputDtsToSource() {
49-
mapper.outputDtsToSource[key] = value
50-
}
51-
if mapper.opts.canUseProjectReferenceSource() {
52-
declDir := task.resolved.CompilerOptions().DeclarationDir
53-
if declDir == "" {
54-
declDir = task.resolved.CompilerOptions().OutDir
55-
}
56-
if declDir != "" {
57-
loader.dtsDirectories.Add(loader.toPath(declDir))
58-
}
59-
}
60-
})
61-
if mapper.opts.canUseProjectReferenceSource() && len(loader.projectReferenceFileMapper.outputDtsToSource) != 0 {
62-
mapper.host = newProjectReferenceDtsFakingHost(loader)
63-
}
64-
}
65-
6628
func (mapper *projectReferenceFileMapper) getParseFileRedirect(file ast.HasFileName) string {
6729
if mapper.opts.canUseProjectReferenceSource() {
6830
// Map to source file from project reference
Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
package compiler
2+
3+
import (
4+
"github.com/microsoft/typescript-go/internal/collections"
5+
"github.com/microsoft/typescript-go/internal/core"
6+
"github.com/microsoft/typescript-go/internal/tsoptions"
7+
"github.com/microsoft/typescript-go/internal/tspath"
8+
)
9+
10+
type projectReferenceParseTask struct {
11+
configName string
12+
resolved *tsoptions.ParsedCommandLine
13+
subTasks []*projectReferenceParseTask
14+
}
15+
16+
func (t *projectReferenceParseTask) parse(projectReferenceParser *projectReferenceParser) {
17+
t.resolved = projectReferenceParser.loader.opts.Host.GetResolvedProjectReference(t.configName, projectReferenceParser.loader.toPath(t.configName))
18+
if t.resolved == nil {
19+
return
20+
}
21+
if t.resolved.SourceToOutput() == nil {
22+
projectReferenceParser.wg.Queue(func() {
23+
t.resolved.ParseInputOutputNames()
24+
})
25+
}
26+
if subReferences := t.resolved.ResolvedProjectReferencePaths(); subReferences != nil {
27+
t.subTasks = createProjectReferenceParseTasks(subReferences)
28+
}
29+
}
30+
31+
func createProjectReferenceParseTasks(projectReferences []string) []*projectReferenceParseTask {
32+
return core.Map(projectReferences, func(configName string) *projectReferenceParseTask {
33+
return &projectReferenceParseTask{
34+
configName: configName,
35+
}
36+
})
37+
}
38+
39+
type projectReferenceParser struct {
40+
loader *fileLoader
41+
wg core.WorkGroup
42+
tasksByFileName collections.SyncMap[tspath.Path, *projectReferenceParseTask]
43+
}
44+
45+
func (p *projectReferenceParser) parse(tasks []*projectReferenceParseTask) {
46+
p.loader.projectReferenceFileMapper.loader = p.loader
47+
p.start(tasks)
48+
p.wg.RunAndWait()
49+
p.initMapper(tasks)
50+
}
51+
52+
func (p *projectReferenceParser) start(tasks []*projectReferenceParseTask) {
53+
for i, task := range tasks {
54+
path := p.loader.toPath(task.configName)
55+
if loadedTask, loaded := p.tasksByFileName.LoadOrStore(path, task); loaded {
56+
// dedup tasks to ensure correct file order, regardless of which task would be started first
57+
tasks[i] = loadedTask
58+
} else {
59+
p.wg.Queue(func() {
60+
task.parse(p)
61+
p.start(task.subTasks)
62+
})
63+
}
64+
}
65+
}
66+
67+
func (p *projectReferenceParser) initMapper(tasks []*projectReferenceParseTask) {
68+
totalReferences := p.tasksByFileName.Size() + 1
69+
p.loader.projectReferenceFileMapper.configToProjectReference = make(map[tspath.Path]*tsoptions.ParsedCommandLine, totalReferences)
70+
p.loader.projectReferenceFileMapper.referencesInConfigFile = make(map[tspath.Path][]tspath.Path, totalReferences)
71+
p.loader.projectReferenceFileMapper.sourceToOutput = make(map[tspath.Path]*tsoptions.OutputDtsAndProjectReference)
72+
p.loader.projectReferenceFileMapper.outputDtsToSource = make(map[tspath.Path]*tsoptions.SourceAndProjectReference)
73+
p.loader.projectReferenceFileMapper.referencesInConfigFile[p.loader.opts.Config.ConfigFile.SourceFile.Path()] = p.initMapperWorker(tasks, &collections.Set[*projectReferenceParseTask]{})
74+
if p.loader.projectReferenceFileMapper.opts.canUseProjectReferenceSource() && len(p.loader.projectReferenceFileMapper.outputDtsToSource) != 0 {
75+
p.loader.projectReferenceFileMapper.host = newProjectReferenceDtsFakingHost(p.loader)
76+
}
77+
}
78+
79+
func (p *projectReferenceParser) initMapperWorker(tasks []*projectReferenceParseTask, seen *collections.Set[*projectReferenceParseTask]) []tspath.Path {
80+
if len(tasks) == 0 {
81+
return nil
82+
}
83+
results := make([]tspath.Path, 0, len(tasks))
84+
for _, task := range tasks {
85+
path := p.loader.toPath(task.configName)
86+
results = append(results, path)
87+
// ensure we only walk each task once
88+
if !seen.AddIfAbsent(task) {
89+
continue
90+
}
91+
var referencesInConfig []tspath.Path
92+
referencesInConfig = p.initMapperWorker(task.subTasks, seen)
93+
p.loader.projectReferenceFileMapper.configToProjectReference[path] = task.resolved
94+
p.loader.projectReferenceFileMapper.referencesInConfigFile[path] = referencesInConfig
95+
if task.resolved == nil || p.loader.projectReferenceFileMapper.opts.Config.ConfigFile == task.resolved.ConfigFile {
96+
continue
97+
}
98+
for key, value := range task.resolved.SourceToOutput() {
99+
p.loader.projectReferenceFileMapper.sourceToOutput[key] = value
100+
}
101+
for key, value := range task.resolved.OutputDtsToSource() {
102+
p.loader.projectReferenceFileMapper.outputDtsToSource[key] = value
103+
}
104+
if p.loader.projectReferenceFileMapper.opts.canUseProjectReferenceSource() {
105+
declDir := task.resolved.CompilerOptions().DeclarationDir
106+
if declDir == "" {
107+
declDir = task.resolved.CompilerOptions().OutDir
108+
}
109+
if declDir != "" {
110+
p.loader.dtsDirectories.Add(p.loader.toPath(declDir))
111+
}
112+
}
113+
}
114+
return results
115+
}

internal/compiler/projectreferenceparsetask.go

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

0 commit comments

Comments
 (0)