Skip to content
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions internal/checker/checker_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ foo.bar;`
fs = bundled.WrapFS(fs)

cd := "/"
host := compiler.NewCompilerHost(cd, fs, bundled.LibPath(), nil)
host := compiler.NewCompilerHost(cd, fs, bundled.LibPath(), nil, func(msg string) {})

parsed, errors := tsoptions.GetParsedCommandLineOfConfigFile("/tsconfig.json", &core.CompilerOptions{}, host, nil)
assert.Equal(t, len(errors), 0, "Expected no errors in parsed command line")
Expand Down Expand Up @@ -70,7 +70,7 @@ func TestCheckSrcCompiler(t *testing.T) {

rootPath := tspath.CombinePaths(tspath.NormalizeSlashes(repo.TypeScriptSubmodulePath), "src", "compiler")

host := compiler.NewCompilerHost(rootPath, fs, bundled.LibPath(), nil)
host := compiler.NewCompilerHost(rootPath, fs, bundled.LibPath(), nil, func(msg string) {})
parsed, errors := tsoptions.GetParsedCommandLineOfConfigFile(tspath.CombinePaths(rootPath, "tsconfig.json"), &core.CompilerOptions{}, host, nil)
assert.Equal(t, len(errors), 0, "Expected no errors in parsed command line")
p := compiler.NewProgram(compiler.ProgramOptions{
Expand All @@ -87,7 +87,7 @@ func BenchmarkNewChecker(b *testing.B) {

rootPath := tspath.CombinePaths(tspath.NormalizeSlashes(repo.TypeScriptSubmodulePath), "src", "compiler")

host := compiler.NewCompilerHost(rootPath, fs, bundled.LibPath(), nil)
host := compiler.NewCompilerHost(rootPath, fs, bundled.LibPath(), nil, func(msg string) {})
parsed, errors := tsoptions.GetParsedCommandLineOfConfigFile(tspath.CombinePaths(rootPath, "tsconfig.json"), &core.CompilerOptions{}, host, nil)
assert.Equal(b, len(errors), 0, "Expected no errors in parsed command line")
p := compiler.NewProgram(compiler.ProgramOptions{
Expand Down
53 changes: 37 additions & 16 deletions internal/compiler/fileloader.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,12 @@ import (
"github.com/microsoft/typescript-go/internal/tspath"
)

type libResolution struct {
libraryName string
resolution *module.ResolvedModule
trace []string
}

type fileLoader struct {
opts ProgramOptions
resolver *module.Resolver
Expand All @@ -35,7 +41,7 @@ type fileLoader struct {
dtsDirectories collections.Set[tspath.Path]

pathForLibFileCache collections.SyncMap[string, string]
pathForLibFileResolutions collections.SyncMap[tspath.Path, module.ModeAwareCache[*module.ResolvedModule]]
pathForLibFileResolutions collections.SyncMap[tspath.Path, *libResolution]
}

type processedFiles struct {
Expand Down Expand Up @@ -200,15 +206,20 @@ func processAllProgramFiles(
}
}

loader.pathForLibFileResolutions.Range(func(key tspath.Path, value module.ModeAwareCache[*module.ResolvedModule]) bool {
resolvedModules[key] = value
for _, resolvedModule := range value {
for _, diag := range resolvedModule.ResolutionDiagnostics {
fileLoadDiagnostics.Add(diag)
}
keys := slices.Collect(loader.pathForLibFileResolutions.Keys())
slices.Sort(keys)
for _, key := range keys {
value, _ := loader.pathForLibFileResolutions.Load(key)
resolvedModules[key] = module.ModeAwareCache[*module.ResolvedModule]{
module.ModeAwareCacheKey{Name: value.libraryName, Mode: core.ModuleKindCommonJS}: value.resolution,
}
return true
})
for _, trace := range value.trace {
opts.Host.Trace(trace)
}
for _, diag := range value.resolution.ResolutionDiagnostics {
fileLoadDiagnostics.Add(diag)
}
}

return processedFiles{
resolver: loader.resolver,
Expand Down Expand Up @@ -255,15 +266,17 @@ func (p *fileLoader) addAutomaticTypeDirectiveTasks() {
func (p *fileLoader) resolveAutomaticTypeDirectives(containingFileName string) (
toParse []resolvedRef,
typeResolutionsInFile module.ModeAwareCache[*module.ResolvedTypeReferenceDirective],
typeResolutionsTrace []string,
) {
automaticTypeDirectiveNames := module.GetAutomaticTypeDirectiveNames(p.opts.Config.CompilerOptions(), p.opts.Host)
if len(automaticTypeDirectiveNames) != 0 {
toParse = make([]resolvedRef, 0, len(automaticTypeDirectiveNames))
typeResolutionsInFile = make(module.ModeAwareCache[*module.ResolvedTypeReferenceDirective], len(automaticTypeDirectiveNames))
for _, name := range automaticTypeDirectiveNames {
resolutionMode := core.ModuleKindNodeNext
resolved := p.resolver.ResolveTypeReferenceDirective(name, containingFileName, resolutionMode, nil)
resolved, trace := p.resolver.ResolveTypeReferenceDirective(name, containingFileName, resolutionMode, nil)
typeResolutionsInFile[module.ModeAwareCacheKey{Name: name, Mode: resolutionMode}] = resolved
typeResolutionsTrace = append(typeResolutionsTrace, trace...)
if resolved.IsResolved() {
toParse = append(toParse, resolvedRef{
fileName: resolved.ResolvedFileName,
Expand All @@ -273,7 +286,7 @@ func (p *fileLoader) resolveAutomaticTypeDirectives(containingFileName string) (
}
}
}
return toParse, typeResolutionsInFile
return toParse, typeResolutionsInFile, typeResolutionsTrace
}

func (p *fileLoader) addProjectReferenceTasks(singleThreaded bool) {
Expand Down Expand Up @@ -393,11 +406,13 @@ func (p *fileLoader) resolveTypeReferenceDirectives(t *parseTask) {
meta := t.metadata

typeResolutionsInFile := make(module.ModeAwareCache[*module.ResolvedTypeReferenceDirective], len(file.TypeReferenceDirectives))
var typeResolutionsTrace []string
for _, ref := range file.TypeReferenceDirectives {
redirect := p.projectReferenceFileMapper.getRedirectForResolution(file)
resolutionMode := getModeForTypeReferenceDirectiveInFile(ref, file, meta, module.GetCompilerOptionsWithRedirect(p.opts.Config.CompilerOptions(), redirect))
resolved := p.resolver.ResolveTypeReferenceDirective(ref.FileName, file.FileName(), resolutionMode, redirect)
resolved, trace := p.resolver.ResolveTypeReferenceDirective(ref.FileName, file.FileName(), resolutionMode, redirect)
typeResolutionsInFile[module.ModeAwareCacheKey{Name: ref.FileName, Mode: resolutionMode}] = resolved
typeResolutionsTrace = append(typeResolutionsTrace, trace...)

if resolved.IsResolved() {
t.addSubTask(resolvedRef{
Expand All @@ -410,6 +425,7 @@ func (p *fileLoader) resolveTypeReferenceDirectives(t *parseTask) {
}

t.typeResolutionsInFile = typeResolutionsInFile
t.typeResolutionsTrace = typeResolutionsTrace
}

const externalHelpersModuleNameText = "tslib" // TODO(jakebailey): dedupe
Expand Down Expand Up @@ -455,6 +471,7 @@ func (p *fileLoader) resolveImportsAndModuleAugmentations(t *parseTask) {

if len(moduleNames) != 0 {
resolutionsInFile := make(module.ModeAwareCache[*module.ResolvedModule], len(moduleNames))
var resolutionsTrace []string

for index, entry := range moduleNames {
moduleName := entry.Text()
Expand All @@ -463,8 +480,9 @@ func (p *fileLoader) resolveImportsAndModuleAugmentations(t *parseTask) {
}

mode := getModeForUsageLocation(file.FileName(), meta, entry, optionsForFile)
resolvedModule := p.resolver.ResolveModuleName(moduleName, file.FileName(), mode, redirect)
resolvedModule, trace := p.resolver.ResolveModuleName(moduleName, file.FileName(), mode, redirect)
resolutionsInFile[module.ModeAwareCacheKey{Name: moduleName, Mode: mode}] = resolvedModule
resolutionsTrace = append(resolutionsTrace, trace...)

if !resolvedModule.IsResolved() {
continue
Expand Down Expand Up @@ -501,6 +519,7 @@ func (p *fileLoader) resolveImportsAndModuleAugmentations(t *parseTask) {
}

t.resolutionsInFile = resolutionsInFile
t.resolutionsTrace = resolutionsTrace
}
}

Expand All @@ -526,11 +545,13 @@ func (p *fileLoader) pathForLibFile(name string) string {
if p.opts.Config.CompilerOptions().LibReplacement.IsTrue() {
libraryName := getLibraryNameFromLibFileName(name)
resolveFrom := getInferredLibraryNameResolveFrom(p.opts.Config.CompilerOptions(), p.opts.Host.GetCurrentDirectory(), name)
resolution := p.resolver.ResolveModuleName(libraryName, resolveFrom, core.ModuleKindCommonJS, nil)
resolution, trace := p.resolver.ResolveModuleName(libraryName, resolveFrom, core.ModuleKindCommonJS, nil)
if resolution.IsResolved() {
path = resolution.ResolvedFileName
p.pathForLibFileResolutions.LoadOrStore(p.toPath(resolveFrom), module.ModeAwareCache[*module.ResolvedModule]{
module.ModeAwareCacheKey{Name: libraryName, Mode: core.ModuleKindCommonJS}: resolution,
p.pathForLibFileResolutions.LoadOrStore(p.toPath(resolveFrom), &libResolution{
libraryName: libraryName,
resolution: resolution,
trace: trace,
})
}
}
Expand Down
23 changes: 14 additions & 9 deletions internal/compiler/filesparser.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,9 @@ type parseTask struct {

metadata ast.SourceFileMetaData
resolutionsInFile module.ModeAwareCache[*module.ResolvedModule]
resolutionsTrace []string
typeResolutionsInFile module.ModeAwareCache[*module.ResolvedTypeReferenceDirective]
typeResolutionsTrace []string
resolutionDiagnostics []*ast.Diagnostic
importHelpersImportSpecifier *ast.Node
jsxRuntimeImportSpecifier *jsxRuntimeImportSpecifier
Expand Down Expand Up @@ -98,8 +100,9 @@ func (t *parseTask) redirect(loader *fileLoader, fileName string) {
}

func (t *parseTask) loadAutomaticTypeDirectives(loader *fileLoader) {
toParseTypeRefs, typeResolutionsInFile := loader.resolveAutomaticTypeDirectives(t.normalizedFilePath)
toParseTypeRefs, typeResolutionsInFile, typeResolutionsTrace := loader.resolveAutomaticTypeDirectives(t.normalizedFilePath)
t.typeResolutionsInFile = typeResolutionsInFile
t.typeResolutionsTrace = typeResolutionsTrace
for _, typeResolution := range toParseTypeRefs {
t.addSubTask(typeResolution, false)
}
Expand Down Expand Up @@ -193,30 +196,32 @@ func (w *filesParser) start(loader *fileLoader, tasks []*parseTask, depth int, i
}
}

func (w *filesParser) collect(loader *fileLoader, tasks []*parseTask, iterate func(*parseTask)) []tspath.Path {
func (w *filesParser) collect(loader *fileLoader, tasks []*parseTask, iterate func(*parseTask)) {
// Mark all tasks we saw as external after the fact.
w.tasksByFileName.Range(func(key string, value *queuedParseTask) bool {
if value.fromExternalLibrary {
value.task.fromExternalLibrary = true
}
return true
})
return w.collectWorker(loader, tasks, iterate, collections.Set[*parseTask]{})
w.collectWorker(loader, tasks, iterate, collections.Set[*parseTask]{})
}

func (w *filesParser) collectWorker(loader *fileLoader, tasks []*parseTask, iterate func(*parseTask), seen collections.Set[*parseTask]) []tspath.Path {
var results []tspath.Path
func (w *filesParser) collectWorker(loader *fileLoader, tasks []*parseTask, iterate func(*parseTask), seen collections.Set[*parseTask]) {
for _, task := range tasks {
// ensure we only walk each task once
if !task.loaded || seen.Has(task) {
if !task.loaded || !seen.AddIfAbsent(task) {
continue
}
seen.Add(task)
for _, trace := range task.typeResolutionsTrace {
loader.opts.Host.Trace(trace)
}
for _, trace := range task.resolutionsTrace {
loader.opts.Host.Trace(trace)
}
if subTasks := task.subTasks; len(subTasks) > 0 {
w.collectWorker(loader, subTasks, iterate, seen)
}
iterate(task)
results = append(results, loader.toPath(task.FileName()))
}
return results
}
8 changes: 6 additions & 2 deletions internal/compiler/host.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,28 +30,32 @@ type compilerHost struct {
defaultLibraryPath string
extendedConfigCache *collections.SyncMap[tspath.Path, *tsoptions.ExtendedConfigCacheEntry]
extendedConfigCacheOnce sync.Once
trace func(msg string)
}

func NewCachedFSCompilerHost(
currentDirectory string,
fs vfs.FS,
defaultLibraryPath string,
extendedConfigCache *collections.SyncMap[tspath.Path, *tsoptions.ExtendedConfigCacheEntry],
trace func(msg string),
) CompilerHost {
return NewCompilerHost(currentDirectory, cachedvfs.From(fs), defaultLibraryPath, extendedConfigCache)
return NewCompilerHost(currentDirectory, cachedvfs.From(fs), defaultLibraryPath, extendedConfigCache, trace)
}

func NewCompilerHost(
currentDirectory string,
fs vfs.FS,
defaultLibraryPath string,
extendedConfigCache *collections.SyncMap[tspath.Path, *tsoptions.ExtendedConfigCacheEntry],
trace func(msg string),
) CompilerHost {
return &compilerHost{
currentDirectory: currentDirectory,
fs: fs,
defaultLibraryPath: defaultLibraryPath,
extendedConfigCache: extendedConfigCache,
trace: trace,
}
}

Expand All @@ -68,7 +72,7 @@ func (h *compilerHost) GetCurrentDirectory() string {
}

func (h *compilerHost) Trace(msg string) {
//!!! TODO: implement
h.trace(msg)
}

func (h *compilerHost) GetSourceFile(opts ast.SourceFileParseOptions) *ast.SourceFile {
Expand Down
6 changes: 3 additions & 3 deletions internal/compiler/program_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -240,7 +240,7 @@ func TestProgram(t *testing.T) {
CompilerOptions: &opts,
},
},
Host: NewCompilerHost("c:/dev/src", fs, bundled.LibPath(), nil),
Host: NewCompilerHost("c:/dev/src", fs, bundled.LibPath(), nil, func(msg string) {}),
})

actualFiles := []string{}
Expand Down Expand Up @@ -277,7 +277,7 @@ func BenchmarkNewProgram(b *testing.B) {
CompilerOptions: &opts,
},
},
Host: NewCompilerHost("c:/dev/src", fs, bundled.LibPath(), nil),
Host: NewCompilerHost("c:/dev/src", fs, bundled.LibPath(), nil, func(msg string) {}),
}

for b.Loop() {
Expand All @@ -294,7 +294,7 @@ func BenchmarkNewProgram(b *testing.B) {
fs := osvfs.FS()
fs = bundled.WrapFS(fs)

host := NewCompilerHost(rootPath, fs, bundled.LibPath(), nil)
host := NewCompilerHost(rootPath, fs, bundled.LibPath(), nil, func(msg string) {})

parsed, errors := tsoptions.GetParsedCommandLineOfConfigFile(tspath.CombinePaths(rootPath, "tsconfig.json"), nil, host, nil)
assert.Equal(b, len(errors), 0, "Expected no errors in parsed command line")
Expand Down
5 changes: 0 additions & 5 deletions internal/compiler/projectreferencedtsfakinghost.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,11 +41,6 @@ func (h *projectReferenceDtsFakingHost) GetCurrentDirectory() string {
return h.host.GetCurrentDirectory()
}

// Trace implements module.ResolutionHost.
func (h *projectReferenceDtsFakingHost) Trace(msg string) {
h.host.Trace(msg)
}

type projectReferenceDtsFakingVfs struct {
projectReferenceFileMapper *projectReferenceFileMapper
dtsDirectories collections.Set[tspath.Path]
Expand Down
10 changes: 8 additions & 2 deletions internal/execute/tsc.go
Original file line number Diff line number Diff line change
Expand Up @@ -223,6 +223,12 @@ func findConfigFile(searchPath string, fileExists func(string) bool, configName
return result
}

func getTraceFromSys(sys System) func(msg string) {
return func(msg string) {
fmt.Fprintln(sys.Writer(), msg)
}
}

func performIncrementalCompilation(
sys System,
config *tsoptions.ParsedCommandLine,
Expand All @@ -231,7 +237,7 @@ func performIncrementalCompilation(
configTime time.Duration,
testing bool,
) CommandLineResult {
host := compiler.NewCachedFSCompilerHost(sys.GetCurrentDirectory(), sys.FS(), sys.DefaultLibraryPath(), extendedConfigCache)
host := compiler.NewCachedFSCompilerHost(sys.GetCurrentDirectory(), sys.FS(), sys.DefaultLibraryPath(), extendedConfigCache, getTraceFromSys(sys))
buildInfoReadStart := sys.Now()
oldProgram := incremental.ReadBuildInfoProgram(config, incremental.NewBuildInfoReader(host))
buildInfoReadTime := sys.Now().Sub(buildInfoReadStart)
Expand Down Expand Up @@ -270,7 +276,7 @@ func performCompilation(
extendedConfigCache *collections.SyncMap[tspath.Path, *tsoptions.ExtendedConfigCacheEntry],
configTime time.Duration,
) CommandLineResult {
host := compiler.NewCachedFSCompilerHost(sys.GetCurrentDirectory(), sys.FS(), sys.DefaultLibraryPath(), extendedConfigCache)
host := compiler.NewCachedFSCompilerHost(sys.GetCurrentDirectory(), sys.FS(), sys.DefaultLibraryPath(), extendedConfigCache, getTraceFromSys(sys))
// todo: cache, statistics, tracing
parseStart := sys.Now()
program := compiler.NewProgram(compiler.ProgramOptions{
Expand Down
4 changes: 2 additions & 2 deletions internal/execute/watcher.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ func createWatcher(sys System, configParseResult *tsoptions.ParsedCommandLine, r
}

func (w *Watcher) start() {
w.host = compiler.NewCompilerHost(w.sys.GetCurrentDirectory(), w.sys.FS(), w.sys.DefaultLibraryPath(), nil)
w.host = compiler.NewCompilerHost(w.sys.GetCurrentDirectory(), w.sys.FS(), w.sys.DefaultLibraryPath(), nil, getTraceFromSys(w.sys))
w.program = incremental.ReadBuildInfoProgram(w.options, incremental.NewBuildInfoReader(w.host))

if !w.testing {
Expand Down Expand Up @@ -109,7 +109,7 @@ func (w *Watcher) hasErrorsInTsConfig() bool {
w.configModified = true
}
w.options = configParseResult
w.host = compiler.NewCompilerHost(w.sys.GetCurrentDirectory(), w.sys.FS(), w.sys.DefaultLibraryPath(), &extendedConfigCache)
w.host = compiler.NewCompilerHost(w.sys.GetCurrentDirectory(), w.sys.FS(), w.sys.DefaultLibraryPath(), &extendedConfigCache, getTraceFromSys(w.sys))
}
return false
}
Expand Down
Loading
Loading