Skip to content

Commit 80aad85

Browse files
authored
Port lib replacement and --libReplacement (#1262)
1 parent 75ece81 commit 80aad85

27 files changed

+167
-269
lines changed

internal/compiler/fileloader.go

Lines changed: 75 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,9 @@ type fileLoader struct {
3434

3535
projectReferenceFileMapper *projectReferenceFileMapper
3636
dtsDirectories collections.Set[tspath.Path]
37+
38+
pathForLibFileCache collections.SyncMap[string, string]
39+
pathForLibFileResolutions collections.SyncMap[tspath.Path, module.ModeAwareCache[*module.ResolvedModule]]
3740
}
3841

3942
type processedFiles struct {
@@ -59,7 +62,6 @@ type jsxRuntimeImportSpecifier struct {
5962

6063
func processAllProgramFiles(
6164
opts ProgramOptions,
62-
libs []string,
6365
singleThreaded bool,
6466
) processedFiles {
6567
compilerOptions := opts.Config.CompilerOptions()
@@ -83,11 +85,27 @@ func processAllProgramFiles(
8385
projectReferenceParseTasks: &fileLoaderWorker[*projectReferenceParseTask]{
8486
wg: core.NewWorkGroup(singleThreaded),
8587
},
86-
rootTasks: make([]*parseTask, 0, len(rootFiles)+len(libs)),
88+
rootTasks: make([]*parseTask, 0, len(rootFiles)+len(compilerOptions.Lib)),
8789
supportedExtensions: core.Flatten(tsoptions.GetSupportedExtensionsWithJsonIfResolveJsonModule(compilerOptions, supportedExtensions)),
8890
}
8991
loader.addProjectReferenceTasks()
9092
loader.resolver = module.NewResolver(loader.projectReferenceFileMapper.host, compilerOptions, opts.TypingsLocation, opts.ProjectName)
93+
94+
var libs []string
95+
if compilerOptions.NoLib.IsFalseOrUnknown() {
96+
if compilerOptions.Lib == nil {
97+
name := tsoptions.GetDefaultLibFileName(compilerOptions)
98+
libs = append(libs, loader.pathForLibFile(name))
99+
} else {
100+
for _, lib := range compilerOptions.Lib {
101+
if name, ok := tsoptions.GetLibFileName(lib); ok {
102+
libs = append(libs, loader.pathForLibFile(name))
103+
}
104+
// !!! error on unknown name
105+
}
106+
}
107+
}
108+
91109
loader.addRootTasks(rootFiles, false)
92110
loader.addRootTasks(libs, true)
93111
loader.addAutomaticTypeDirectiveTasks()
@@ -105,7 +123,7 @@ func processAllProgramFiles(
105123
libFiles := make([]*ast.SourceFile, 0, totalFileCount) // totalFileCount here since we append files to it later to construct the final list
106124

107125
filesByPath := make(map[tspath.Path]*ast.SourceFile, totalFileCount)
108-
resolvedModules := make(map[tspath.Path]module.ModeAwareCache[*module.ResolvedModule], totalFileCount)
126+
resolvedModules := make(map[tspath.Path]module.ModeAwareCache[*module.ResolvedModule], totalFileCount+1)
109127
typeResolutionsInFile := make(map[tspath.Path]module.ModeAwareCache[*module.ResolvedTypeReferenceDirective], totalFileCount)
110128
sourceFileMetaDatas := make(map[tspath.Path]ast.SourceFileMetaData, totalFileCount)
111129
var jsxRuntimeImportSpecifiers map[tspath.Path]*jsxRuntimeImportSpecifier
@@ -162,6 +180,11 @@ func processAllProgramFiles(
162180

163181
allFiles := append(libFiles, files...)
164182

183+
loader.pathForLibFileResolutions.Range(func(key tspath.Path, value module.ModeAwareCache[*module.ResolvedModule]) bool {
184+
resolvedModules[key] = value
185+
return true
186+
})
187+
165188
return processedFiles{
166189
resolver: loader.resolver,
167190
files: allFiles,
@@ -463,6 +486,55 @@ func (p *fileLoader) createSyntheticImport(text string, file *ast.SourceFile) *a
463486
return externalHelpersModuleReference
464487
}
465488

489+
func (p *fileLoader) pathForLibFile(name string) string {
490+
if cached, ok := p.pathForLibFileCache.Load(name); ok {
491+
return cached
492+
}
493+
494+
path := tspath.CombinePaths(p.defaultLibraryPath, name)
495+
if p.opts.Config.CompilerOptions().LibReplacement.IsTrue() {
496+
libraryName := getLibraryNameFromLibFileName(name)
497+
resolveFrom := getInferredLibraryNameResolveFrom(p.opts.Config.CompilerOptions(), p.opts.Host.GetCurrentDirectory(), name)
498+
resolution := p.resolver.ResolveModuleName(libraryName, resolveFrom, core.ModuleKindCommonJS, nil)
499+
if resolution.IsResolved() {
500+
path = resolution.ResolvedFileName
501+
p.pathForLibFileResolutions.LoadOrStore(p.toPath(resolveFrom), module.ModeAwareCache[*module.ResolvedModule]{
502+
module.ModeAwareCacheKey{Name: libraryName, Mode: core.ModuleKindCommonJS}: resolution,
503+
})
504+
}
505+
}
506+
507+
path, _ = p.pathForLibFileCache.LoadOrStore(name, path)
508+
return path
509+
}
510+
511+
func getLibraryNameFromLibFileName(libFileName string) string {
512+
// Support resolving to lib.dom.d.ts -> @typescript/lib-dom, and
513+
// lib.dom.iterable.d.ts -> @typescript/lib-dom/iterable
514+
// lib.es2015.symbol.wellknown.d.ts -> @typescript/lib-es2015/symbol-wellknown
515+
components := strings.Split(libFileName, ".")
516+
var path string
517+
if len(components) > 1 {
518+
path = components[1]
519+
}
520+
i := 2
521+
for i < len(components) && components[i] != "" && components[i] != "d" {
522+
path += core.IfElse(i == 2, "/", "-") + components[i]
523+
i++
524+
}
525+
return "@typescript/lib-" + path
526+
}
527+
528+
func getInferredLibraryNameResolveFrom(options *core.CompilerOptions, currentDirectory string, libFileName string) string {
529+
var containingDirectory string
530+
if options.ConfigFilePath != "" {
531+
containingDirectory = tspath.GetDirectoryPath(options.ConfigFilePath)
532+
} else {
533+
containingDirectory = currentDirectory
534+
}
535+
return tspath.CombinePaths(containingDirectory, "__lib_node_modules_lookup_"+libFileName+"__.ts")
536+
}
537+
466538
type resolution struct {
467539
node *ast.Node
468540
resolvedModule *module.ResolvedModule

internal/compiler/parsetask.go

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -77,11 +77,9 @@ func (t *parseTask) load(loader *fileLoader) {
7777

7878
if compilerOptions.NoLib != core.TSTrue {
7979
for _, lib := range file.LibReferenceDirectives {
80-
name, ok := tsoptions.GetLibFileName(lib.FileName)
81-
if !ok {
82-
continue
80+
if name, ok := tsoptions.GetLibFileName(lib.FileName); ok {
81+
t.addSubTask(resolvedRef{fileName: loader.pathForLibFile(name)}, true)
8382
}
84-
t.addSubTask(resolvedRef{fileName: tspath.CombinePaths(loader.defaultLibraryPath, name)}, true)
8583
}
8684
}
8785

internal/compiler/program.go

Lines changed: 2 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -172,37 +172,9 @@ func (p *Program) GetSourceFileFromReference(origin *ast.SourceFile, ref *ast.Fi
172172
}
173173

174174
func NewProgram(opts ProgramOptions) *Program {
175-
p := &Program{
176-
opts: opts,
177-
}
178-
compilerOptions := p.opts.Config.CompilerOptions()
179-
if compilerOptions == nil {
180-
panic("compiler options required")
181-
}
182-
if p.opts.Host == nil {
183-
panic("host required")
184-
}
175+
p := &Program{opts: opts}
185176
p.initCheckerPool()
186-
187-
var libs []string
188-
189-
if compilerOptions.NoLib != core.TSTrue {
190-
if compilerOptions.Lib == nil {
191-
name := tsoptions.GetDefaultLibFileName(compilerOptions)
192-
libs = append(libs, tspath.CombinePaths(p.Host().DefaultLibraryPath(), name))
193-
} else {
194-
for _, lib := range compilerOptions.Lib {
195-
name, ok := tsoptions.GetLibFileName(lib)
196-
if ok {
197-
libs = append(libs, tspath.CombinePaths(p.Host().DefaultLibraryPath(), name))
198-
}
199-
// !!! error on unknown name
200-
}
201-
}
202-
}
203-
204-
p.processedFiles = processAllProgramFiles(p.opts, libs, p.singleThreaded())
205-
177+
p.processedFiles = processAllProgramFiles(p.opts, p.singleThreaded())
206178
return p
207179
}
208180

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
index.ts(6,1): error TS2304: Cannot find name 'window'.
2+
3+
4+
==== /node_modules/@typescript/lib-dom/index.d.ts (0 errors) ====
5+
interface ABC { abc: string }
6+
==== index.ts (1 errors) ====
7+
/// <reference lib="dom" />
8+
const a: ABC = { abc: "Hello" }
9+
10+
// This should fail because libdom has been replaced
11+
// by the module above ^
12+
window.localStorage
13+
~~~~~~
14+
!!! error TS2304: Cannot find name 'window'.
15+

testdata/baselines/reference/submodule/compiler/libTypeScriptOverrideSimple.errors.txt.diff

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

testdata/baselines/reference/submodule/compiler/libTypeScriptOverrideSimple.symbols

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,4 @@ const a: ABC = { abc: "Hello" }
1515
// This should fail because libdom has been replaced
1616
// by the module above ^
1717
window.localStorage
18-
>window.localStorage : Symbol(localStorage, Decl(lib.dom.d.ts, --, --), Decl(lib.dom.d.ts, --, --))
19-
>window : Symbol(window, Decl(lib.dom.d.ts, --, --))
20-
>localStorage : Symbol(localStorage, Decl(lib.dom.d.ts, --, --), Decl(lib.dom.d.ts, --, --))
2118

testdata/baselines/reference/submodule/compiler/libTypeScriptOverrideSimple.symbols.diff

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,4 @@
88
+>abc : Symbol(abc, Decl(index.d.ts, 0, 15))
99

1010
=== index.ts ===
11-
/// <reference lib="dom" />
12-
@@= skipped -12, +12 lines =@@
13-
// This should fail because libdom has been replaced
14-
// by the module above ^
15-
window.localStorage
16-
+>window.localStorage : Symbol(localStorage, Decl(lib.dom.d.ts, --, --), Decl(lib.dom.d.ts, --, --))
17-
+>window : Symbol(window, Decl(lib.dom.d.ts, --, --))
18-
+>localStorage : Symbol(localStorage, Decl(lib.dom.d.ts, --, --), Decl(lib.dom.d.ts, --, --))
11+
/// <reference lib="dom" />

testdata/baselines/reference/submodule/compiler/libTypeScriptOverrideSimple.types

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ const a: ABC = { abc: "Hello" }
1515
// This should fail because libdom has been replaced
1616
// by the module above ^
1717
window.localStorage
18-
>window.localStorage : Storage
19-
>window : Window & typeof globalThis
20-
>localStorage : Storage
18+
>window.localStorage : any
19+
>window : any
20+
>localStorage : any
2121

testdata/baselines/reference/submodule/compiler/libTypeScriptOverrideSimple.types.diff

Lines changed: 0 additions & 12 deletions
This file was deleted.
Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,17 @@
1-
/somepath/index.ts(2,10): error TS2304: Cannot find name 'ABC'.
1+
/somepath/index.ts(6,1): error TS2304: Cannot find name 'window'.
22

33

44
==== /somepath/tsconfig.json (0 errors) ====
55
{ }
66
==== /somepath/index.ts (1 errors) ====
77
/// <reference lib="dom" />
88
const a: ABC = { abc: "Hello" }
9-
~~~
10-
!!! error TS2304: Cannot find name 'ABC'.
119

1210
// This should fail because libdom has been replaced
1311
// by the module above ^
1412
window.localStorage
13+
~~~~~~
14+
!!! error TS2304: Cannot find name 'window'.
1515

1616
==== /somepath/node_modules/@typescript/lib-dom/index.d.ts (0 errors) ====
1717
interface ABC { abc: string }

testdata/baselines/reference/submodule/compiler/libTypeScriptOverrideSimpleConfig.errors.txt.diff

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

testdata/baselines/reference/submodule/compiler/libTypeScriptOverrideSimpleConfig.symbols

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,15 @@
44
/// <reference lib="dom" />
55
const a: ABC = { abc: "Hello" }
66
>a : Symbol(a, Decl(index.ts, 1, 5))
7-
>ABC : Symbol(ABC)
7+
>ABC : Symbol(ABC, Decl(index.d.ts, 0, 0))
88
>abc : Symbol(abc, Decl(index.ts, 1, 16))
99

1010
// This should fail because libdom has been replaced
1111
// by the module above ^
1212
window.localStorage
13-
>window.localStorage : Symbol(localStorage, Decl(lib.dom.d.ts, --, --), Decl(lib.dom.d.ts, --, --))
14-
>window : Symbol(window, Decl(lib.dom.d.ts, --, --))
15-
>localStorage : Symbol(localStorage, Decl(lib.dom.d.ts, --, --), Decl(lib.dom.d.ts, --, --))
13+
14+
=== /somepath/node_modules/@typescript/lib-dom/index.d.ts ===
15+
interface ABC { abc: string }
16+
>ABC : Symbol(ABC, Decl(index.d.ts, 0, 0))
17+
>abc : Symbol(abc, Decl(index.d.ts, 0, 15))
1618

Lines changed: 5 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,8 @@
11
--- old.libTypeScriptOverrideSimpleConfig.symbols
22
+++ new.libTypeScriptOverrideSimpleConfig.symbols
3-
@@= skipped -3, +3 lines =@@
4-
/// <reference lib="dom" />
5-
const a: ABC = { abc: "Hello" }
6-
>a : Symbol(a, Decl(index.ts, 1, 5))
7-
->ABC : Symbol(ABC, Decl(index.d.ts, 0, 0))
8-
+>ABC : Symbol(ABC)
9-
>abc : Symbol(abc, Decl(index.ts, 1, 16))
10-
11-
// This should fail because libdom has been replaced
12-
// by the module above ^
13-
window.localStorage
14-
-
15-
-=== /somepath/node_modules/@typescript/lib-dom/index.d.ts ===
16-
-interface ABC { abc: string }
17-
->ABC : Symbol(ABC, Decl(index.d.ts, 0, 0))
3+
@@= skipped -13, +13 lines =@@
4+
=== /somepath/node_modules/@typescript/lib-dom/index.d.ts ===
5+
interface ABC { abc: string }
6+
>ABC : Symbol(ABC, Decl(index.d.ts, 0, 0))
187
->abc : Symbol(ABC.abc, Decl(index.d.ts, 0, 15))
19-
+>window.localStorage : Symbol(localStorage, Decl(lib.dom.d.ts, --, --), Decl(lib.dom.d.ts, --, --))
20-
+>window : Symbol(window, Decl(lib.dom.d.ts, --, --))
21-
+>localStorage : Symbol(localStorage, Decl(lib.dom.d.ts, --, --), Decl(lib.dom.d.ts, --, --))
8+
+>abc : Symbol(abc, Decl(index.d.ts, 0, 15))

testdata/baselines/reference/submodule/compiler/libTypeScriptOverrideSimpleConfig.types

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,11 @@ const a: ABC = { abc: "Hello" }
1111
// This should fail because libdom has been replaced
1212
// by the module above ^
1313
window.localStorage
14-
>window.localStorage : Storage
15-
>window : Window & typeof globalThis
16-
>localStorage : Storage
14+
>window.localStorage : any
15+
>window : any
16+
>localStorage : any
17+
18+
=== /somepath/node_modules/@typescript/lib-dom/index.d.ts ===
19+
interface ABC { abc: string }
20+
>abc : string
1721

testdata/baselines/reference/submodule/compiler/libTypeScriptOverrideSimpleConfig.types.diff

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

0 commit comments

Comments
 (0)