Skip to content
Draft
Show file tree
Hide file tree
Changes from all 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
5 changes: 5 additions & 0 deletions internal/compiler/emitHost.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (
"github.com/microsoft/typescript-go/internal/modulespecifiers"
"github.com/microsoft/typescript-go/internal/outputpaths"
"github.com/microsoft/typescript-go/internal/printer"
"github.com/microsoft/typescript-go/internal/symlinks"
"github.com/microsoft/typescript-go/internal/transformers/declarations"
"github.com/microsoft/typescript-go/internal/tsoptions"
"github.com/microsoft/typescript-go/internal/tspath"
Expand Down Expand Up @@ -126,3 +127,7 @@ func (host *emitHost) GetEmitResolver() printer.EmitResolver {
func (host *emitHost) IsSourceFileFromExternalLibrary(file *ast.SourceFile) bool {
return host.program.IsSourceFileFromExternalLibrary(file)
}

func (host *emitHost) GetSymlinkCache() *symlinks.KnownSymlinks {
return host.program.GetSymlinkCache();
}
53 changes: 0 additions & 53 deletions internal/compiler/knownsymlinks.go

This file was deleted.

39 changes: 39 additions & 0 deletions internal/compiler/program.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import (
"github.com/microsoft/typescript-go/internal/printer"
"github.com/microsoft/typescript-go/internal/scanner"
"github.com/microsoft/typescript-go/internal/sourcemap"
"github.com/microsoft/typescript-go/internal/symlinks"
"github.com/microsoft/typescript-go/internal/tsoptions"
"github.com/microsoft/typescript-go/internal/tspath"
)
Expand Down Expand Up @@ -66,6 +67,7 @@ type Program struct {
// Cached unresolved imports for ATA
unresolvedImportsOnce sync.Once
unresolvedImports *collections.Set[string]
knownSymlinks *symlinks.KnownSymlinks
}

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

func (p *Program) GetSymlinkCache() *symlinks.KnownSymlinks {
// if p.Host().GetSymlinkCache() != nil {
// return p.Host().GetSymlinkCache()
// }
if p.knownSymlinks == nil {
p.knownSymlinks = symlinks.NewKnownSymlink(p.GetCurrentDirectory(), p.UseCaseSensitiveFileNames())
}
if p.files != nil && !p.knownSymlinks.HasProcessedResolutions {
p.knownSymlinks.SetSymlinksFromResolutions(p.ForEachResolvedModule, p.ForEachResolvedTypeReferenceDirective)
}
return p.knownSymlinks
}

func (p *Program) ForEachResolvedModule(callback func(resolution *module.ResolvedModule, moduleName string, mode core.ResolutionMode, filePath tspath.Path), file *ast.SourceFile) {
forEachResolution(p.resolvedModules, callback, file)
}

func (p *Program) ForEachResolvedTypeReferenceDirective(callback func(resolution *module.ResolvedTypeReferenceDirective, moduleName string, mode core.ResolutionMode, filePath tspath.Path), file *ast.SourceFile) {
forEachResolution(p.typeResolutionsInFile, callback, file)
}

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) {
if file != nil {
if resolutions, ok := resolutionCache[file.Path()]; ok {
for key, resolution := range resolutions {
callback(resolution, key.Name, key.Mode, file.Path())
}
}
} else {
for filePath, resolutions := range resolutionCache {
for key, resolution := range resolutions {
callback(resolution, key.Name, key.Mode, filePath)
}
}
}
}

var plainJSErrors = collections.NewSetFromItems(
// binder errors
diagnostics.Cannot_redeclare_block_scoped_variable_0.Code(),
Expand Down
9 changes: 5 additions & 4 deletions internal/compiler/projectreferencedtsfakinghost.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"github.com/microsoft/typescript-go/internal/collections"
"github.com/microsoft/typescript-go/internal/core"
"github.com/microsoft/typescript-go/internal/module"
"github.com/microsoft/typescript-go/internal/symlinks"
"github.com/microsoft/typescript-go/internal/tspath"
"github.com/microsoft/typescript-go/internal/vfs"
"github.com/microsoft/typescript-go/internal/vfs/cachedvfs"
Expand All @@ -26,7 +27,7 @@ func newProjectReferenceDtsFakingHost(loader *fileLoader) module.ResolutionHost
fs: cachedvfs.From(&projectReferenceDtsFakingVfs{
projectReferenceFileMapper: loader.projectReferenceFileMapper,
dtsDirectories: loader.dtsDirectories,
knownSymlinks: knownSymlinks{},
knownSymlinks: symlinks.KnownSymlinks{},
}),
}
return host
Expand All @@ -45,7 +46,7 @@ func (h *projectReferenceDtsFakingHost) GetCurrentDirectory() string {
type projectReferenceDtsFakingVfs struct {
projectReferenceFileMapper *projectReferenceFileMapper
dtsDirectories collections.Set[tspath.Path]
knownSymlinks knownSymlinks
knownSymlinks symlinks.KnownSymlinks
}

var _ vfs.FS = (*projectReferenceDtsFakingVfs)(nil)
Expand Down Expand Up @@ -150,7 +151,7 @@ func (fs *projectReferenceDtsFakingVfs) handleDirectoryCouldBeSymlink(directory
// not symlinked
return
}
fs.knownSymlinks.SetDirectory(directory, directoryPath, &knownDirectoryLink{
fs.knownSymlinks.SetDirectory(directory, directoryPath, &symlinks.KnownDirectoryLink{
Real: tspath.EnsureTrailingDirectorySeparator(realDirectory),
RealPath: realPath,
})
Expand Down Expand Up @@ -181,7 +182,7 @@ func (fs *projectReferenceDtsFakingVfs) fileOrDirectoryExistsUsingSource(fileOrD

// If it contains node_modules check if its one of the symlinked path we know of
var exists bool
knownDirectoryLinks.Range(func(directoryPath tspath.Path, knownDirectoryLink *knownDirectoryLink) bool {
knownDirectoryLinks.Range(func(directoryPath tspath.Path, knownDirectoryLink *symlinks.KnownDirectoryLink) bool {
relative, hasPrefix := strings.CutPrefix(string(fileOrDirectoryPath), string(directoryPath))
if !hasPrefix {
return true
Expand Down
3 changes: 2 additions & 1 deletion internal/ls/autoimports.go
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,8 @@ func (e *exportInfoMap) add(
}

moduleName := stringutil.StripQuotes(moduleSymbol.Name)
id := e.exportInfoId + 1
id := e.exportInfoId
e.exportInfoId += 1
target := ch.SkipAlias(symbol)

if flagMatch != nil && !flagMatch(target.Flags) {
Expand Down
74 changes: 44 additions & 30 deletions internal/modulespecifiers/specifiers.go
Original file line number Diff line number Diff line change
Expand Up @@ -280,36 +280,50 @@ func GetEachFileNameOfModule(
}
}

// !!! TODO: Symlink directory handling
// const symlinkedDirectories = host.getSymlinkCache?.().getSymlinkedDirectoriesByRealpath();
// const fullImportedFileName = getNormalizedAbsolutePath(importedFileName, cwd);
// const result = symlinkedDirectories && forEachAncestorDirectoryStoppingAtGlobalCache(
// host,
// getDirectoryPath(fullImportedFileName),
// realPathDirectory => {
// const symlinkDirectories = symlinkedDirectories.get(ensureTrailingDirectorySeparator(toPath(realPathDirectory, cwd, getCanonicalFileName)));
// if (!symlinkDirectories) return undefined; // Continue to ancestor directory

// // Don't want to a package to globally import from itself (importNameCodeFix_symlink_own_package.ts)
// if (startsWithDirectory(importingFileName, realPathDirectory, getCanonicalFileName)) {
// return false; // Stop search, each ancestor directory will also hit this condition
// }

// return forEach(targets, target => {
// if (!startsWithDirectory(target, realPathDirectory, getCanonicalFileName)) {
// return;
// }

// const relative = getRelativePathFromDirectory(realPathDirectory, target, getCanonicalFileName);
// for (const symlinkDirectory of symlinkDirectories) {
// const option = resolvePath(symlinkDirectory, relative);
// const result = cb(option, target === referenceRedirect);
// shouldFilterIgnoredPaths = true; // We found a non-ignored path in symlinks, so we can reject ignored-path realpaths
// if (result) return result;
// }
// });
// },
// );
symlinkedDirectories := host.GetSymlinkCache().DirectoriesByRealpath()
fullImportedFileName := tspath.GetNormalizedAbsolutePath(importedFileName, cwd)
if symlinkedDirectories != nil {
tspath.ForEachAncestorDirectoryStoppingAtGlobalCache(
host.GetGlobalTypingsCacheLocation(),
tspath.GetDirectoryPath(fullImportedFileName),
func(realPathDirectory string) (bool, bool) {
symlinkDirectories := symlinkedDirectories.Get(tspath.ToPath(realPathDirectory, cwd, host.UseCaseSensitiveFileNames()).EnsureTrailingDirectorySeparator())
if symlinkDirectories == nil {
return false, false
} // Continue to ancestor directory

// Don't want to a package to globally import from itself (importNameCodeFix_symlink_own_package.ts)
if tspath.StartsWithDirectory(importingFileName, realPathDirectory, host.UseCaseSensitiveFileNames()) {
return false, true // Stop search, each ancestor directory will also hit this condition
}

for _, target := range targets {
if !tspath.StartsWithDirectory(target, realPathDirectory, host.UseCaseSensitiveFileNames()) {
continue
}

relative := tspath.GetRelativePathFromDirectory(
realPathDirectory,
target,
tspath.ComparePathsOptions{
UseCaseSensitiveFileNames: host.UseCaseSensitiveFileNames(),
CurrentDirectory: cwd,
})
for _, symlinkDirectory := range symlinkDirectories {
option := tspath.ResolvePath(symlinkDirectory, relative)
results = append(results, ModulePath{
FileName: option,
IsInNodeModules: ContainsNodeModules(option),
IsRedirect: target == referenceRedirect,
})
shouldFilterIgnoredPaths = true // We found a non-ignored path in symlinks, so we can reject ignored-path realpaths
}
}

return false, false
},
)
}

if preferSymlinks {
for _, p := range targets {
Expand Down
3 changes: 2 additions & 1 deletion internal/modulespecifiers/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"github.com/microsoft/typescript-go/internal/core"
"github.com/microsoft/typescript-go/internal/module"
"github.com/microsoft/typescript-go/internal/packagejson"
"github.com/microsoft/typescript-go/internal/symlinks"
"github.com/microsoft/typescript-go/internal/tsoptions"
"github.com/microsoft/typescript-go/internal/tspath"
)
Expand Down Expand Up @@ -45,7 +46,7 @@ type PackageJsonInfo interface {

type ModuleSpecifierGenerationHost interface {
// GetModuleResolutionCache() any // !!! TODO: adapt new resolution cache model
// GetSymlinkCache() any // !!! TODO: adapt new resolution cache model
GetSymlinkCache() *symlinks.KnownSymlinks
// GetFileIncludeReasons() any // !!! TODO: adapt new resolution cache model
CommonSourceDirectory() string
GetGlobalTypingsCacheLocation() string
Expand Down
Loading