Skip to content

Commit 64e1673

Browse files
committed
wip
1 parent fd15f29 commit 64e1673

File tree

8 files changed

+230
-88
lines changed

8 files changed

+230
-88
lines changed

internal/compiler/emitHost.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import (
99
"github.com/microsoft/typescript-go/internal/modulespecifiers"
1010
"github.com/microsoft/typescript-go/internal/outputpaths"
1111
"github.com/microsoft/typescript-go/internal/printer"
12+
"github.com/microsoft/typescript-go/internal/symlinks"
1213
"github.com/microsoft/typescript-go/internal/transformers/declarations"
1314
"github.com/microsoft/typescript-go/internal/tsoptions"
1415
"github.com/microsoft/typescript-go/internal/tspath"
@@ -126,3 +127,7 @@ func (host *emitHost) GetEmitResolver() printer.EmitResolver {
126127
func (host *emitHost) IsSourceFileFromExternalLibrary(file *ast.SourceFile) bool {
127128
return host.program.IsSourceFileFromExternalLibrary(file)
128129
}
130+
131+
func (host *emitHost) GetSymlinkCache() *symlinks.KnownSymlinks {
132+
return host.program.GetSymlinkCache();
133+
}

internal/compiler/knownsymlinks.go

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

internal/compiler/program.go

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ import (
2323
"github.com/microsoft/typescript-go/internal/printer"
2424
"github.com/microsoft/typescript-go/internal/scanner"
2525
"github.com/microsoft/typescript-go/internal/sourcemap"
26+
"github.com/microsoft/typescript-go/internal/symlinks"
2627
"github.com/microsoft/typescript-go/internal/tsoptions"
2728
"github.com/microsoft/typescript-go/internal/tspath"
2829
)
@@ -66,6 +67,7 @@ type Program struct {
6667
// Cached unresolved imports for ATA
6768
unresolvedImportsOnce sync.Once
6869
unresolvedImports *collections.Set[string]
70+
knownSymlinks *symlinks.KnownSymlinks
6971
}
7072

7173
// FileExists implements checker.Program.
@@ -1624,6 +1626,43 @@ func (p *Program) SourceFileMayBeEmitted(sourceFile *ast.SourceFile, forceDtsEmi
16241626
return sourceFileMayBeEmitted(sourceFile, p, forceDtsEmit)
16251627
}
16261628

1629+
func (p *Program) GetSymlinkCache() *symlinks.KnownSymlinks {
1630+
// if p.Host().GetSymlinkCache() != nil {
1631+
// return p.Host().GetSymlinkCache()
1632+
// }
1633+
if p.knownSymlinks == nil {
1634+
p.knownSymlinks = symlinks.NewKnownSymlink(p.GetCurrentDirectory(), p.UseCaseSensitiveFileNames())
1635+
}
1636+
if p.files != nil && !p.knownSymlinks.HasProcessedResolutions {
1637+
p.knownSymlinks.SetSymlinksFromResolutions(p.ForEachResolvedModule, p.ForEachResolvedTypeReferenceDirective)
1638+
}
1639+
return p.knownSymlinks
1640+
}
1641+
1642+
func (p *Program) ForEachResolvedModule(callback func(resolution *module.ResolvedModule, moduleName string, mode core.ResolutionMode, filePath tspath.Path), file *ast.SourceFile) {
1643+
forEachResolution(p.resolvedModules, callback, file)
1644+
}
1645+
1646+
func (p *Program) ForEachResolvedTypeReferenceDirective(callback func(resolution *module.ResolvedTypeReferenceDirective, moduleName string, mode core.ResolutionMode, filePath tspath.Path), file *ast.SourceFile) {
1647+
forEachResolution(p.typeResolutionsInFile, callback, file)
1648+
}
1649+
1650+
func forEachResolution[T any](resolutionCache map[tspath.Path]module.ModeAwareCache[T], callback func(resolution T, moduleName string, mode core.ResolutionMode, filePath tspath.Path), file *ast.SourceFile) {
1651+
if file != nil {
1652+
if resolutions, ok := resolutionCache[file.Path()]; ok {
1653+
for key, resolution := range resolutions {
1654+
callback(resolution, key.Name, key.Mode, file.Path())
1655+
}
1656+
}
1657+
} else {
1658+
for filePath, resolutions := range resolutionCache {
1659+
for key, resolution := range resolutions {
1660+
callback(resolution, key.Name, key.Mode, filePath)
1661+
}
1662+
}
1663+
}
1664+
}
1665+
16271666
var plainJSErrors = collections.NewSetFromItems(
16281667
// binder errors
16291668
diagnostics.Cannot_redeclare_block_scoped_variable_0.Code(),

internal/compiler/projectreferencedtsfakinghost.go

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import (
77
"github.com/microsoft/typescript-go/internal/collections"
88
"github.com/microsoft/typescript-go/internal/core"
99
"github.com/microsoft/typescript-go/internal/module"
10+
"github.com/microsoft/typescript-go/internal/symlinks"
1011
"github.com/microsoft/typescript-go/internal/tspath"
1112
"github.com/microsoft/typescript-go/internal/vfs"
1213
"github.com/microsoft/typescript-go/internal/vfs/cachedvfs"
@@ -26,7 +27,7 @@ func newProjectReferenceDtsFakingHost(loader *fileLoader) module.ResolutionHost
2627
fs: cachedvfs.From(&projectReferenceDtsFakingVfs{
2728
projectReferenceFileMapper: loader.projectReferenceFileMapper,
2829
dtsDirectories: loader.dtsDirectories,
29-
knownSymlinks: knownSymlinks{},
30+
knownSymlinks: symlinks.KnownSymlinks{},
3031
}),
3132
}
3233
return host
@@ -45,7 +46,7 @@ func (h *projectReferenceDtsFakingHost) GetCurrentDirectory() string {
4546
type projectReferenceDtsFakingVfs struct {
4647
projectReferenceFileMapper *projectReferenceFileMapper
4748
dtsDirectories collections.Set[tspath.Path]
48-
knownSymlinks knownSymlinks
49+
knownSymlinks symlinks.KnownSymlinks
4950
}
5051

5152
var _ vfs.FS = (*projectReferenceDtsFakingVfs)(nil)
@@ -150,7 +151,7 @@ func (fs *projectReferenceDtsFakingVfs) handleDirectoryCouldBeSymlink(directory
150151
// not symlinked
151152
return
152153
}
153-
fs.knownSymlinks.SetDirectory(directory, directoryPath, &knownDirectoryLink{
154+
fs.knownSymlinks.SetDirectory(directory, directoryPath, &symlinks.KnownDirectoryLink{
154155
Real: tspath.EnsureTrailingDirectorySeparator(realDirectory),
155156
RealPath: realPath,
156157
})
@@ -181,7 +182,7 @@ func (fs *projectReferenceDtsFakingVfs) fileOrDirectoryExistsUsingSource(fileOrD
181182

182183
// If it contains node_modules check if its one of the symlinked path we know of
183184
var exists bool
184-
knownDirectoryLinks.Range(func(directoryPath tspath.Path, knownDirectoryLink *knownDirectoryLink) bool {
185+
knownDirectoryLinks.Range(func(directoryPath tspath.Path, knownDirectoryLink *symlinks.KnownDirectoryLink) bool {
185186
relative, hasPrefix := strings.CutPrefix(string(fileOrDirectoryPath), string(directoryPath))
186187
if !hasPrefix {
187188
return true

internal/modulespecifiers/specifiers.go

Lines changed: 44 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -280,36 +280,50 @@ func GetEachFileNameOfModule(
280280
}
281281
}
282282

283-
// !!! TODO: Symlink directory handling
284-
// const symlinkedDirectories = host.getSymlinkCache?.().getSymlinkedDirectoriesByRealpath();
285-
// const fullImportedFileName = getNormalizedAbsolutePath(importedFileName, cwd);
286-
// const result = symlinkedDirectories && forEachAncestorDirectoryStoppingAtGlobalCache(
287-
// host,
288-
// getDirectoryPath(fullImportedFileName),
289-
// realPathDirectory => {
290-
// const symlinkDirectories = symlinkedDirectories.get(ensureTrailingDirectorySeparator(toPath(realPathDirectory, cwd, getCanonicalFileName)));
291-
// if (!symlinkDirectories) return undefined; // Continue to ancestor directory
292-
293-
// // Don't want to a package to globally import from itself (importNameCodeFix_symlink_own_package.ts)
294-
// if (startsWithDirectory(importingFileName, realPathDirectory, getCanonicalFileName)) {
295-
// return false; // Stop search, each ancestor directory will also hit this condition
296-
// }
297-
298-
// return forEach(targets, target => {
299-
// if (!startsWithDirectory(target, realPathDirectory, getCanonicalFileName)) {
300-
// return;
301-
// }
302-
303-
// const relative = getRelativePathFromDirectory(realPathDirectory, target, getCanonicalFileName);
304-
// for (const symlinkDirectory of symlinkDirectories) {
305-
// const option = resolvePath(symlinkDirectory, relative);
306-
// const result = cb(option, target === referenceRedirect);
307-
// shouldFilterIgnoredPaths = true; // We found a non-ignored path in symlinks, so we can reject ignored-path realpaths
308-
// if (result) return result;
309-
// }
310-
// });
311-
// },
312-
// );
283+
symlinkedDirectories := host.GetSymlinkCache().DirectoriesByRealpath()
284+
fullImportedFileName := tspath.GetNormalizedAbsolutePath(importedFileName, cwd)
285+
if symlinkedDirectories != nil {
286+
tspath.ForEachAncestorDirectoryStoppingAtGlobalCache(
287+
host.GetGlobalTypingsCacheLocation(),
288+
tspath.GetDirectoryPath(fullImportedFileName),
289+
func(realPathDirectory string) (bool, bool) {
290+
symlinkDirectories := symlinkedDirectories.Get(tspath.ToPath(realPathDirectory, cwd, host.UseCaseSensitiveFileNames()).EnsureTrailingDirectorySeparator())
291+
if symlinkDirectories == nil {
292+
return false, false
293+
} // Continue to ancestor directory
294+
295+
// Don't want to a package to globally import from itself (importNameCodeFix_symlink_own_package.ts)
296+
if tspath.StartsWithDirectory(importingFileName, realPathDirectory, host.UseCaseSensitiveFileNames()) {
297+
return false, true // Stop search, each ancestor directory will also hit this condition
298+
}
299+
300+
for _, target := range targets {
301+
if !tspath.StartsWithDirectory(target, realPathDirectory, host.UseCaseSensitiveFileNames()) {
302+
continue
303+
}
304+
305+
relative := tspath.GetRelativePathFromDirectory(
306+
realPathDirectory,
307+
target,
308+
tspath.ComparePathsOptions{
309+
UseCaseSensitiveFileNames: host.UseCaseSensitiveFileNames(),
310+
CurrentDirectory: cwd,
311+
})
312+
for _, symlinkDirectory := range symlinkDirectories {
313+
option := tspath.ResolvePath(symlinkDirectory, relative)
314+
results = append(results, ModulePath{
315+
FileName: option,
316+
IsInNodeModules: ContainsNodeModules(option),
317+
IsRedirect: target == referenceRedirect,
318+
})
319+
shouldFilterIgnoredPaths = true // We found a non-ignored path in symlinks, so we can reject ignored-path realpaths
320+
}
321+
}
322+
323+
return false, false
324+
},
325+
)
326+
}
313327

314328
if preferSymlinks {
315329
for _, p := range targets {

internal/modulespecifiers/types.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import (
55
"github.com/microsoft/typescript-go/internal/core"
66
"github.com/microsoft/typescript-go/internal/module"
77
"github.com/microsoft/typescript-go/internal/packagejson"
8+
"github.com/microsoft/typescript-go/internal/symlinks"
89
"github.com/microsoft/typescript-go/internal/tsoptions"
910
"github.com/microsoft/typescript-go/internal/tspath"
1011
)
@@ -45,7 +46,7 @@ type PackageJsonInfo interface {
4546

4647
type ModuleSpecifierGenerationHost interface {
4748
// GetModuleResolutionCache() any // !!! TODO: adapt new resolution cache model
48-
// GetSymlinkCache() any // !!! TODO: adapt new resolution cache model
49+
GetSymlinkCache() *symlinks.KnownSymlinks
4950
// GetFileIncludeReasons() any // !!! TODO: adapt new resolution cache model
5051
CommonSourceDirectory() string
5152
GetGlobalTypingsCacheLocation() string

0 commit comments

Comments
 (0)