diff --git a/internal/ast/symbol.go b/internal/ast/symbol.go index e3581a7786..b98832a0b3 100644 --- a/internal/ast/symbol.go +++ b/internal/ast/symbol.go @@ -3,10 +3,10 @@ package ast import ( "iter" "maps" - "strings" "sync/atomic" "github.com/microsoft/typescript-go/internal/collections" + "github.com/microsoft/typescript-go/internal/deno" "github.com/microsoft/typescript-go/internal/tspath" ) @@ -350,17 +350,13 @@ func (c *DenoForkContext) GetGlobalsForName(name string) SymbolTable { } } -func isTypesNodePkgPath(path tspath.Path) bool { - return strings.HasSuffix(string(path), ".d.ts") && strings.Contains(string(path), "/@types/node/") -} - func symbolHasAnyTypesNodePkgDecl(symbol *Symbol, hasNodeSourceFile func(*Node) bool) bool { if symbol == nil || symbol.Declarations == nil { return false } for _, decl := range symbol.Declarations { sourceFile := GetSourceFileOfNode(decl) - if sourceFile != nil && hasNodeSourceFile(decl) && isTypesNodePkgPath(sourceFile.Path()) { + if sourceFile != nil && hasNodeSourceFile(decl) && deno.IsTypesNodePkgPath(sourceFile.Path()) { return true } } @@ -370,7 +366,7 @@ func symbolHasAnyTypesNodePkgDecl(symbol *Symbol, hasNodeSourceFile func(*Node) func (c *DenoForkContext) MergeGlobalSymbolTable(node *Node, source SymbolTable, unidirectional bool) { sourceFile := GetSourceFileOfNode(node) isNodeFile := c.HasNodeSourceFile(node) - isTypesNodeSourceFile := isNodeFile && isTypesNodePkgPath(sourceFile.Path()) + isTypesNodeSourceFile := isNodeFile && deno.IsTypesNodePkgPath(sourceFile.Path()) for id, sourceSymbol := range source.Iter() { var target SymbolTable diff --git a/internal/compiler/fileloader.go b/internal/compiler/fileloader.go index d82f7d3aef..2697b66c8b 100644 --- a/internal/compiler/fileloader.go +++ b/internal/compiler/fileloader.go @@ -10,6 +10,7 @@ import ( "github.com/microsoft/typescript-go/internal/ast" "github.com/microsoft/typescript-go/internal/collections" "github.com/microsoft/typescript-go/internal/core" + "github.com/microsoft/typescript-go/internal/deno" "github.com/microsoft/typescript-go/internal/module" "github.com/microsoft/typescript-go/internal/tsoptions" "github.com/microsoft/typescript-go/internal/tspath" @@ -107,6 +108,11 @@ func processAllProgramFiles( for index, rootFile := range rootFiles { loader.addRootTask(rootFile, nil, &FileIncludeReason{kind: fileIncludeKindRootFile, data: index}) } + + // deno: cause the sub tasks to be loaded which will tell us if there's a @types/node package + loader.filesParser.parse(&loader, loader.rootTasks) + rootTasksBeforeLibs := len(loader.rootTasks) + if len(rootFiles) > 0 && compilerOptions.NoLib.IsFalseOrUnknown() { if compilerOptions.Lib == nil { name := tsoptions.GetDefaultLibFileName(compilerOptions) @@ -117,6 +123,10 @@ func processAllProgramFiles( for index, lib := range compilerOptions.Lib { if name, ok := tsoptions.GetLibFileName(lib); ok { libFile := loader.pathForLibFile(name) + // deno: we skip loading the lib.node.d.ts file if the @types/node package has been loaded + if libFile.Name == "lib.node.d.ts" && loader.hasTypesNodePackage() { + continue + } loader.addRootTask(libFile.path, libFile, &FileIncludeReason{kind: fileIncludeKindLibFile, data: index}) } // !!! error on unknown name @@ -128,7 +138,10 @@ func processAllProgramFiles( loader.addAutomaticTypeDirectiveTasks() } - loader.filesParser.parse(&loader, loader.rootTasks) + // deno: now load the lib and type directive tasks + loader.filesParser.wg = core.NewWorkGroup(singleThreaded) + loader.filesParser.parse(&loader, loader.rootTasks[rootTasksBeforeLibs:]) + // Clear out loader and host to ensure its not used post program creation loader.projectReferenceFileMapper.loader = nil loader.projectReferenceFileMapper.host = nil @@ -257,6 +270,19 @@ func (p *fileLoader) toPath(file string) tspath.Path { return tspath.ToPath(file, p.opts.Host.GetCurrentDirectory(), p.opts.Host.FS().UseCaseSensitiveFileNames()) } +// deno: function for getting if the loader has a @types/node package +func (p *fileLoader) hasTypesNodePackage() bool { + hasTypesNode := false + p.filesParser.tasksByFileName.Range(func(key string, value *queuedParseTask) bool { + if value.task.loaded && deno.IsTypesNodePkgPath(value.task.path) { + hasTypesNode = true + return false // stop iteration + } + return true // continue iteration + }) + return hasTypesNode +} + func (p *fileLoader) addRootTask(fileName string, libFile *LibFile, includeReason *FileIncludeReason) { absPath := tspath.GetNormalizedAbsolutePath(fileName, p.opts.Host.GetCurrentDirectory()) if core.Tristate.IsTrue(p.opts.Config.CompilerOptions().AllowNonTsExtensions) || slices.Contains(p.supportedExtensions, tspath.TryGetExtensionFromPath(absPath)) { @@ -609,7 +635,7 @@ func (p *fileLoader) createSyntheticImport(text string, file *ast.SourceFile) *a } func isDenoLibFile(name string) bool { - return strings.HasPrefix(name, "lib.deno") + return strings.HasPrefix(name, "lib.deno") || name == "lib.node.d.ts" } func (p *fileLoader) pathForLibFile(name string) *LibFile { diff --git a/internal/deno/deno.go b/internal/deno/deno.go new file mode 100644 index 0000000000..2e0eabcc49 --- /dev/null +++ b/internal/deno/deno.go @@ -0,0 +1,11 @@ +package deno + +import ( + "strings" + + "github.com/microsoft/typescript-go/internal/tspath" +) + +func IsTypesNodePkgPath(path tspath.Path) bool { + return strings.HasSuffix(string(path), ".d.ts") && strings.Contains(string(path), "/@types/node/") +} diff --git a/internal/tsoptions/enummaps.go b/internal/tsoptions/enummaps.go index 723613a360..2acbbbcb12 100644 --- a/internal/tsoptions/enummaps.go +++ b/internal/tsoptions/enummaps.go @@ -131,6 +131,7 @@ var LibMap = collections.NewOrderedMapFromList([]collections.MapEntry[string, an {Key: "deno.shared_globals", Value: "lib.deno.shared_globals.d.ts"}, {Key: "deno.unstable", Value: "lib.deno.unstable.d.ts"}, {Key: "dom.extras", Value: "lib.dom.extras.d.ts"}, + {Key: "node", Value: "lib.node.d.ts"}, }) var (