remove unused packages
This commit is contained in:
parent
fb86a3f969
commit
4712bb4e56
@ -1,13 +0,0 @@
|
|||||||
package modulespecifiers
|
|
||||||
|
|
||||||
import (
|
|
||||||
"strings"
|
|
||||||
)
|
|
||||||
|
|
||||||
func CountPathComponents(path string) int {
|
|
||||||
initial := 0
|
|
||||||
if strings.HasPrefix(path, "./") {
|
|
||||||
initial = 2
|
|
||||||
}
|
|
||||||
return strings.Count(path[initial:], "/")
|
|
||||||
}
|
|
||||||
@ -1,233 +0,0 @@
|
|||||||
package modulespecifiers
|
|
||||||
|
|
||||||
import (
|
|
||||||
"strings"
|
|
||||||
|
|
||||||
"efprojects.com/kitten-ipc/kitcom/internal/tsgo/ast"
|
|
||||||
"efprojects.com/kitten-ipc/kitcom/internal/tsgo/core"
|
|
||||||
"efprojects.com/kitten-ipc/kitcom/internal/tsgo/debug"
|
|
||||||
"efprojects.com/kitten-ipc/kitcom/internal/tsgo/tspath"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Program errors validate that `noEmit` or `emitDeclarationOnly` is also set,
|
|
||||||
// so this function doesn't check them to avoid propagating errors.
|
|
||||||
func shouldAllowImportingTsExtension(compilerOptions *core.CompilerOptions, fromFileName string) bool {
|
|
||||||
return compilerOptions.GetAllowImportingTsExtensions() || len(fromFileName) > 0 && tspath.IsDeclarationFileName(fromFileName)
|
|
||||||
}
|
|
||||||
|
|
||||||
func usesExtensionsOnImports(file SourceFileForSpecifierGeneration) bool {
|
|
||||||
for _, ref := range file.Imports() {
|
|
||||||
text := ref.Text()
|
|
||||||
if tspath.PathIsRelative(text) && !tspath.FileExtensionIsOneOf(text, tspath.ExtensionsNotSupportingExtensionlessResolution) {
|
|
||||||
return tspath.HasTSFileExtension(text) || tspath.HasJSFileExtension(text)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
func inferPreference(
|
|
||||||
resolutionMode core.ResolutionMode,
|
|
||||||
sourceFile SourceFileForSpecifierGeneration,
|
|
||||||
moduleResolutionIsNodeNext bool,
|
|
||||||
) ModuleSpecifierEnding {
|
|
||||||
usesJsExtensions := false
|
|
||||||
var specifiers []*ast.LiteralLikeNode
|
|
||||||
if sourceFile != nil && len(sourceFile.Imports()) > 0 {
|
|
||||||
specifiers = sourceFile.Imports()
|
|
||||||
} else if sourceFile != nil && sourceFile.IsJS() {
|
|
||||||
// !!! TODO: JS support
|
|
||||||
// specifiers = core.Map(getRequiresAtTopOfFile(sourceFile), func(d *ast.Node) *ast.Node { return d.arguments[0] })
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, specifier := range specifiers {
|
|
||||||
path := specifier.Text()
|
|
||||||
if tspath.PathIsRelative(path) {
|
|
||||||
// !!! TODO: proper resolutionMode support
|
|
||||||
if moduleResolutionIsNodeNext && resolutionMode == core.ResolutionModeCommonJS /* && getModeForUsageLocation(sourceFile!, specifier, compilerOptions) === ModuleKind.ESNext */ {
|
|
||||||
// We're trying to decide a preference for a CommonJS module specifier, but looking at an ESM import.
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
if tspath.FileExtensionIsOneOf(path, tspath.ExtensionsNotSupportingExtensionlessResolution) {
|
|
||||||
// These extensions are not optional, so do not indicate a preference.
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
if tspath.HasTSFileExtension(path) {
|
|
||||||
return ModuleSpecifierEndingTsExtension
|
|
||||||
}
|
|
||||||
if tspath.HasJSFileExtension(path) {
|
|
||||||
usesJsExtensions = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if usesJsExtensions {
|
|
||||||
return ModuleSpecifierEndingJsExtension
|
|
||||||
}
|
|
||||||
return ModuleSpecifierEndingMinimal
|
|
||||||
}
|
|
||||||
|
|
||||||
func getModuleSpecifierEndingPreference(
|
|
||||||
pref ImportModuleSpecifierEndingPreference,
|
|
||||||
resolutionMode core.ResolutionMode,
|
|
||||||
compilerOptions *core.CompilerOptions,
|
|
||||||
sourceFile SourceFileForSpecifierGeneration,
|
|
||||||
) ModuleSpecifierEnding {
|
|
||||||
moduleResolution := compilerOptions.GetModuleResolutionKind()
|
|
||||||
moduleResolutionIsNodeNext := core.ModuleResolutionKindNode16 <= moduleResolution && moduleResolution <= core.ModuleResolutionKindNodeNext
|
|
||||||
|
|
||||||
if pref == ImportModuleSpecifierEndingPreferenceJs || resolutionMode == core.ResolutionModeESM && moduleResolutionIsNodeNext {
|
|
||||||
// Extensions are explicitly requested or required. Now choose between .js and .ts.
|
|
||||||
if !shouldAllowImportingTsExtension(compilerOptions, "") {
|
|
||||||
return ModuleSpecifierEndingJsExtension
|
|
||||||
}
|
|
||||||
// `allowImportingTsExtensions` is a strong signal, so use .ts unless the file
|
|
||||||
// already uses .js extensions and no .ts extensions.
|
|
||||||
if inferPreference(resolutionMode, sourceFile, moduleResolutionIsNodeNext) != ModuleSpecifierEndingJsExtension {
|
|
||||||
return ModuleSpecifierEndingTsExtension
|
|
||||||
}
|
|
||||||
return ModuleSpecifierEndingJsExtension
|
|
||||||
}
|
|
||||||
|
|
||||||
if pref == ImportModuleSpecifierEndingPreferenceMinimal {
|
|
||||||
return ModuleSpecifierEndingMinimal
|
|
||||||
}
|
|
||||||
|
|
||||||
if pref == ImportModuleSpecifierEndingPreferenceIndex {
|
|
||||||
return ModuleSpecifierEndingIndex
|
|
||||||
}
|
|
||||||
|
|
||||||
// No preference was specified.
|
|
||||||
// Look at imports and/or requires to guess whether .js, .ts, or extensionless imports are preferred.
|
|
||||||
// N.B. that `Index` detection is not supported since it would require file system probing to do
|
|
||||||
// accurately, and more importantly, literally nobody wants `Index` and its existence is a mystery.
|
|
||||||
if !shouldAllowImportingTsExtension(compilerOptions, "") {
|
|
||||||
// If .ts imports are not valid, we only need to see one .js import to go with that.
|
|
||||||
if sourceFile != nil && usesExtensionsOnImports(sourceFile) {
|
|
||||||
return ModuleSpecifierEndingJsExtension
|
|
||||||
}
|
|
||||||
return ModuleSpecifierEndingMinimal
|
|
||||||
}
|
|
||||||
|
|
||||||
return inferPreference(resolutionMode, sourceFile, moduleResolutionIsNodeNext)
|
|
||||||
}
|
|
||||||
|
|
||||||
func getPreferredEnding(
|
|
||||||
prefs UserPreferences,
|
|
||||||
host ModuleSpecifierGenerationHost,
|
|
||||||
compilerOptions *core.CompilerOptions,
|
|
||||||
importingSourceFile SourceFileForSpecifierGeneration,
|
|
||||||
oldImportSpecifier string,
|
|
||||||
resolutionMode core.ResolutionMode,
|
|
||||||
) ModuleSpecifierEnding {
|
|
||||||
if len(oldImportSpecifier) > 0 {
|
|
||||||
if tspath.HasJSFileExtension(oldImportSpecifier) {
|
|
||||||
return ModuleSpecifierEndingJsExtension
|
|
||||||
}
|
|
||||||
if strings.HasSuffix(oldImportSpecifier, "/index") {
|
|
||||||
return ModuleSpecifierEndingIndex
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if resolutionMode == core.ResolutionModeNone {
|
|
||||||
resolutionMode = host.GetDefaultResolutionModeForFile(importingSourceFile)
|
|
||||||
}
|
|
||||||
return getModuleSpecifierEndingPreference(
|
|
||||||
prefs.ImportModuleSpecifierEnding,
|
|
||||||
resolutionMode,
|
|
||||||
compilerOptions,
|
|
||||||
importingSourceFile,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
type ModuleSpecifierPreferences struct {
|
|
||||||
relativePreference RelativePreferenceKind
|
|
||||||
getAllowedEndingsInPreferredOrder func(syntaxImpliedNodeFormat core.ResolutionMode) []ModuleSpecifierEnding
|
|
||||||
excludeRegexes []string
|
|
||||||
}
|
|
||||||
|
|
||||||
func getModuleSpecifierPreferences(
|
|
||||||
prefs UserPreferences,
|
|
||||||
host ModuleSpecifierGenerationHost,
|
|
||||||
compilerOptions *core.CompilerOptions,
|
|
||||||
importingSourceFile SourceFileForSpecifierGeneration,
|
|
||||||
oldImportSpecifier string,
|
|
||||||
) ModuleSpecifierPreferences {
|
|
||||||
excludes := prefs.AutoImportSpecifierExcludeRegexes
|
|
||||||
relativePreference := RelativePreferenceShortest
|
|
||||||
if len(oldImportSpecifier) > 0 {
|
|
||||||
if tspath.IsExternalModuleNameRelative(oldImportSpecifier) {
|
|
||||||
relativePreference = RelativePreferenceRelative
|
|
||||||
} else {
|
|
||||||
relativePreference = RelativePreferenceNonRelative
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
switch prefs.ImportModuleSpecifierPreference {
|
|
||||||
case ImportModuleSpecifierPreferenceRelative:
|
|
||||||
relativePreference = RelativePreferenceRelative
|
|
||||||
case ImportModuleSpecifierPreferenceNonRelative:
|
|
||||||
relativePreference = RelativePreferenceNonRelative
|
|
||||||
case ImportModuleSpecifierPreferenceProjectRelative:
|
|
||||||
relativePreference = RelativePreferenceExternalNonRelative
|
|
||||||
// all others are shortest
|
|
||||||
}
|
|
||||||
}
|
|
||||||
filePreferredEnding := getPreferredEnding(
|
|
||||||
prefs,
|
|
||||||
host,
|
|
||||||
compilerOptions,
|
|
||||||
importingSourceFile,
|
|
||||||
oldImportSpecifier,
|
|
||||||
core.ResolutionModeNone,
|
|
||||||
)
|
|
||||||
|
|
||||||
getAllowedEndingsInPreferredOrder := func(syntaxImpliedNodeFormat core.ResolutionMode) []ModuleSpecifierEnding {
|
|
||||||
preferredEnding := filePreferredEnding
|
|
||||||
resolutionMode := host.GetDefaultResolutionModeForFile(importingSourceFile)
|
|
||||||
if resolutionMode != syntaxImpliedNodeFormat {
|
|
||||||
preferredEnding = getPreferredEnding(
|
|
||||||
prefs,
|
|
||||||
host,
|
|
||||||
compilerOptions,
|
|
||||||
importingSourceFile,
|
|
||||||
oldImportSpecifier,
|
|
||||||
syntaxImpliedNodeFormat,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
moduleResolution := compilerOptions.GetModuleResolutionKind()
|
|
||||||
moduleResolutionIsNodeNext := core.ModuleResolutionKindNode16 <= moduleResolution && moduleResolution <= core.ModuleResolutionKindNodeNext
|
|
||||||
allowImportingTsExtension := shouldAllowImportingTsExtension(compilerOptions, importingSourceFile.FileName())
|
|
||||||
if syntaxImpliedNodeFormat == core.ResolutionModeESM && moduleResolutionIsNodeNext {
|
|
||||||
if allowImportingTsExtension {
|
|
||||||
return []ModuleSpecifierEnding{ModuleSpecifierEndingTsExtension, ModuleSpecifierEndingJsExtension}
|
|
||||||
}
|
|
||||||
return []ModuleSpecifierEnding{ModuleSpecifierEndingJsExtension}
|
|
||||||
}
|
|
||||||
switch preferredEnding {
|
|
||||||
case ModuleSpecifierEndingJsExtension:
|
|
||||||
if allowImportingTsExtension {
|
|
||||||
return []ModuleSpecifierEnding{ModuleSpecifierEndingJsExtension, ModuleSpecifierEndingTsExtension, ModuleSpecifierEndingMinimal, ModuleSpecifierEndingIndex}
|
|
||||||
}
|
|
||||||
return []ModuleSpecifierEnding{ModuleSpecifierEndingJsExtension, ModuleSpecifierEndingMinimal, ModuleSpecifierEndingIndex}
|
|
||||||
case ModuleSpecifierEndingTsExtension:
|
|
||||||
return []ModuleSpecifierEnding{ModuleSpecifierEndingTsExtension, ModuleSpecifierEndingMinimal, ModuleSpecifierEndingJsExtension, ModuleSpecifierEndingIndex}
|
|
||||||
case ModuleSpecifierEndingIndex:
|
|
||||||
if allowImportingTsExtension {
|
|
||||||
return []ModuleSpecifierEnding{ModuleSpecifierEndingIndex, ModuleSpecifierEndingMinimal, ModuleSpecifierEndingTsExtension, ModuleSpecifierEndingJsExtension}
|
|
||||||
}
|
|
||||||
return []ModuleSpecifierEnding{ModuleSpecifierEndingIndex, ModuleSpecifierEndingMinimal, ModuleSpecifierEndingJsExtension}
|
|
||||||
case ModuleSpecifierEndingMinimal:
|
|
||||||
if allowImportingTsExtension {
|
|
||||||
return []ModuleSpecifierEnding{ModuleSpecifierEndingMinimal, ModuleSpecifierEndingIndex, ModuleSpecifierEndingTsExtension, ModuleSpecifierEndingJsExtension}
|
|
||||||
}
|
|
||||||
return []ModuleSpecifierEnding{ModuleSpecifierEndingMinimal, ModuleSpecifierEndingIndex, ModuleSpecifierEndingJsExtension}
|
|
||||||
default:
|
|
||||||
debug.AssertNever(preferredEnding)
|
|
||||||
}
|
|
||||||
return []ModuleSpecifierEnding{ModuleSpecifierEndingMinimal}
|
|
||||||
}
|
|
||||||
|
|
||||||
return ModuleSpecifierPreferences{
|
|
||||||
excludeRegexes: excludes,
|
|
||||||
relativePreference: relativePreference,
|
|
||||||
getAllowedEndingsInPreferredOrder: getAllowedEndingsInPreferredOrder,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
File diff suppressed because it is too large
Load Diff
@ -1,122 +0,0 @@
|
|||||||
package modulespecifiers
|
|
||||||
|
|
||||||
import (
|
|
||||||
"efprojects.com/kitten-ipc/kitcom/internal/tsgo/ast"
|
|
||||||
"efprojects.com/kitten-ipc/kitcom/internal/tsgo/core"
|
|
||||||
"efprojects.com/kitten-ipc/kitcom/internal/tsgo/module"
|
|
||||||
"efprojects.com/kitten-ipc/kitcom/internal/tsgo/packagejson"
|
|
||||||
"efprojects.com/kitten-ipc/kitcom/internal/tsgo/tsoptions"
|
|
||||||
"efprojects.com/kitten-ipc/kitcom/internal/tsgo/tspath"
|
|
||||||
)
|
|
||||||
|
|
||||||
type SourceFileForSpecifierGeneration interface {
|
|
||||||
Path() tspath.Path
|
|
||||||
FileName() string
|
|
||||||
Imports() []*ast.StringLiteralLike
|
|
||||||
IsJS() bool
|
|
||||||
}
|
|
||||||
|
|
||||||
type CheckerShape interface {
|
|
||||||
GetSymbolAtLocation(node *ast.Node) *ast.Symbol
|
|
||||||
GetAliasedSymbol(symbol *ast.Symbol) *ast.Symbol
|
|
||||||
}
|
|
||||||
|
|
||||||
type ResultKind uint8
|
|
||||||
|
|
||||||
const (
|
|
||||||
ResultKindNone ResultKind = iota
|
|
||||||
ResultKindNodeModules
|
|
||||||
ResultKindPaths
|
|
||||||
ResultKindRedirect
|
|
||||||
ResultKindRelative
|
|
||||||
ResultKindAmbient
|
|
||||||
)
|
|
||||||
|
|
||||||
type ModulePath struct {
|
|
||||||
FileName string
|
|
||||||
IsInNodeModules bool
|
|
||||||
IsRedirect bool
|
|
||||||
}
|
|
||||||
|
|
||||||
type PackageJsonInfo interface {
|
|
||||||
GetDirectory() string
|
|
||||||
GetContents() *packagejson.PackageJson
|
|
||||||
}
|
|
||||||
|
|
||||||
type ModuleSpecifierGenerationHost interface {
|
|
||||||
// GetModuleResolutionCache() any // !!! TODO: adapt new resolution cache model
|
|
||||||
// GetSymlinkCache() any // !!! TODO: adapt new resolution cache model
|
|
||||||
// GetFileIncludeReasons() any // !!! TODO: adapt new resolution cache model
|
|
||||||
CommonSourceDirectory() string
|
|
||||||
GetGlobalTypingsCacheLocation() string
|
|
||||||
UseCaseSensitiveFileNames() bool
|
|
||||||
GetCurrentDirectory() string
|
|
||||||
|
|
||||||
GetProjectReferenceFromSource(path tspath.Path) *tsoptions.SourceOutputAndProjectReference
|
|
||||||
GetRedirectTargets(path tspath.Path) []string
|
|
||||||
GetSourceOfProjectReferenceIfOutputIncluded(file ast.HasFileName) string
|
|
||||||
|
|
||||||
FileExists(path string) bool
|
|
||||||
|
|
||||||
GetNearestAncestorDirectoryWithPackageJson(dirname string) string
|
|
||||||
GetPackageJsonInfo(pkgJsonPath string) PackageJsonInfo
|
|
||||||
GetDefaultResolutionModeForFile(file ast.HasFileName) core.ResolutionMode
|
|
||||||
GetResolvedModuleFromModuleSpecifier(file ast.HasFileName, moduleSpecifier *ast.StringLiteralLike) *module.ResolvedModule
|
|
||||||
GetModeForUsageLocation(file ast.HasFileName, moduleSpecifier *ast.StringLiteralLike) core.ResolutionMode
|
|
||||||
}
|
|
||||||
|
|
||||||
type ImportModuleSpecifierPreference string
|
|
||||||
|
|
||||||
const (
|
|
||||||
ImportModuleSpecifierPreferenceNone ImportModuleSpecifierPreference = ""
|
|
||||||
ImportModuleSpecifierPreferenceShortest ImportModuleSpecifierPreference = "shortest"
|
|
||||||
ImportModuleSpecifierPreferenceProjectRelative ImportModuleSpecifierPreference = "project-relative"
|
|
||||||
ImportModuleSpecifierPreferenceRelative ImportModuleSpecifierPreference = "relative"
|
|
||||||
ImportModuleSpecifierPreferenceNonRelative ImportModuleSpecifierPreference = "non-relative"
|
|
||||||
)
|
|
||||||
|
|
||||||
type ImportModuleSpecifierEndingPreference string
|
|
||||||
|
|
||||||
const (
|
|
||||||
ImportModuleSpecifierEndingPreferenceNone ImportModuleSpecifierEndingPreference = ""
|
|
||||||
ImportModuleSpecifierEndingPreferenceAuto ImportModuleSpecifierEndingPreference = "auto"
|
|
||||||
ImportModuleSpecifierEndingPreferenceMinimal ImportModuleSpecifierEndingPreference = "minimal"
|
|
||||||
ImportModuleSpecifierEndingPreferenceIndex ImportModuleSpecifierEndingPreference = "index"
|
|
||||||
ImportModuleSpecifierEndingPreferenceJs ImportModuleSpecifierEndingPreference = "js"
|
|
||||||
)
|
|
||||||
|
|
||||||
type UserPreferences struct {
|
|
||||||
ImportModuleSpecifierPreference ImportModuleSpecifierPreference
|
|
||||||
ImportModuleSpecifierEnding ImportModuleSpecifierEndingPreference
|
|
||||||
AutoImportSpecifierExcludeRegexes []string
|
|
||||||
}
|
|
||||||
|
|
||||||
type ModuleSpecifierOptions struct {
|
|
||||||
OverrideImportMode core.ResolutionMode
|
|
||||||
}
|
|
||||||
|
|
||||||
type RelativePreferenceKind uint8
|
|
||||||
|
|
||||||
const (
|
|
||||||
RelativePreferenceRelative RelativePreferenceKind = iota
|
|
||||||
RelativePreferenceNonRelative
|
|
||||||
RelativePreferenceShortest
|
|
||||||
RelativePreferenceExternalNonRelative
|
|
||||||
)
|
|
||||||
|
|
||||||
type ModuleSpecifierEnding uint8
|
|
||||||
|
|
||||||
const (
|
|
||||||
ModuleSpecifierEndingMinimal ModuleSpecifierEnding = iota
|
|
||||||
ModuleSpecifierEndingIndex
|
|
||||||
ModuleSpecifierEndingJsExtension
|
|
||||||
ModuleSpecifierEndingTsExtension
|
|
||||||
)
|
|
||||||
|
|
||||||
type MatchingMode uint8
|
|
||||||
|
|
||||||
const (
|
|
||||||
MatchingModeExact MatchingMode = iota
|
|
||||||
MatchingModeDirectory
|
|
||||||
MatchingModePattern
|
|
||||||
)
|
|
||||||
@ -1,323 +0,0 @@
|
|||||||
package modulespecifiers
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"slices"
|
|
||||||
"strings"
|
|
||||||
|
|
||||||
"efprojects.com/kitten-ipc/kitcom/internal/tsgo/ast"
|
|
||||||
"efprojects.com/kitten-ipc/kitcom/internal/tsgo/collections"
|
|
||||||
"efprojects.com/kitten-ipc/kitcom/internal/tsgo/core"
|
|
||||||
"efprojects.com/kitten-ipc/kitcom/internal/tsgo/module"
|
|
||||||
"efprojects.com/kitten-ipc/kitcom/internal/tsgo/packagejson"
|
|
||||||
"efprojects.com/kitten-ipc/kitcom/internal/tsgo/semver"
|
|
||||||
"efprojects.com/kitten-ipc/kitcom/internal/tsgo/tsoptions"
|
|
||||||
"efprojects.com/kitten-ipc/kitcom/internal/tsgo/tspath"
|
|
||||||
"github.com/dlclark/regexp2"
|
|
||||||
)
|
|
||||||
|
|
||||||
func isNonGlobalAmbientModule(node *ast.Node) bool {
|
|
||||||
return ast.IsModuleDeclaration(node) && ast.IsStringLiteral(node.Name())
|
|
||||||
}
|
|
||||||
|
|
||||||
func comparePathsByRedirectAndNumberOfDirectorySeparators(a ModulePath, b ModulePath) int {
|
|
||||||
if a.IsRedirect == b.IsRedirect {
|
|
||||||
return strings.Count(a.FileName, "/") - strings.Count(b.FileName, "/")
|
|
||||||
}
|
|
||||||
if a.IsRedirect {
|
|
||||||
return 1
|
|
||||||
}
|
|
||||||
return -1
|
|
||||||
}
|
|
||||||
|
|
||||||
func PathIsBareSpecifier(path string) bool {
|
|
||||||
return !tspath.PathIsAbsolute(path) && !tspath.PathIsRelative(path)
|
|
||||||
}
|
|
||||||
|
|
||||||
func isExcludedByRegex(moduleSpecifier string, excludes []string) bool {
|
|
||||||
for _, pattern := range excludes {
|
|
||||||
compiled, err := regexp2.Compile(pattern, regexp2.None)
|
|
||||||
if err != nil {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
match, _ := compiled.MatchString(moduleSpecifier)
|
|
||||||
if match {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Ensures a path is either absolute (prefixed with `/` or `c:`) or dot-relative (prefixed
|
|
||||||
* with `./` or `../`) so as not to be confused with an unprefixed module name.
|
|
||||||
*
|
|
||||||
* ```ts
|
|
||||||
* ensurePathIsNonModuleName("/path/to/file.ext") === "/path/to/file.ext"
|
|
||||||
* ensurePathIsNonModuleName("./path/to/file.ext") === "./path/to/file.ext"
|
|
||||||
* ensurePathIsNonModuleName("../path/to/file.ext") === "../path/to/file.ext"
|
|
||||||
* ensurePathIsNonModuleName("path/to/file.ext") === "./path/to/file.ext"
|
|
||||||
* ```
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
func ensurePathIsNonModuleName(path string) string {
|
|
||||||
if PathIsBareSpecifier(path) {
|
|
||||||
return "./" + path
|
|
||||||
}
|
|
||||||
return path
|
|
||||||
}
|
|
||||||
|
|
||||||
func getJsExtensionForDeclarationFileExtension(ext string) string {
|
|
||||||
switch ext {
|
|
||||||
case tspath.ExtensionDts:
|
|
||||||
return tspath.ExtensionJs
|
|
||||||
case tspath.ExtensionDmts:
|
|
||||||
return tspath.ExtensionMjs
|
|
||||||
case tspath.ExtensionDcts:
|
|
||||||
return tspath.ExtensionCjs
|
|
||||||
default:
|
|
||||||
// .d.json.ts and the like
|
|
||||||
return ext[len(".d") : len(ext)-len(tspath.ExtensionTs)]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func getJSExtensionForFile(fileName string, options *core.CompilerOptions) string {
|
|
||||||
result := tryGetJSExtensionForFile(fileName, options)
|
|
||||||
if len(result) == 0 {
|
|
||||||
panic(fmt.Sprintf("Extension %s is unsupported:: FileName:: %s", extensionFromPath(fileName), fileName))
|
|
||||||
}
|
|
||||||
return result
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the extension from a path.
|
|
||||||
* Path must have a valid extension.
|
|
||||||
*/
|
|
||||||
func extensionFromPath(path string) string {
|
|
||||||
ext := tspath.TryGetExtensionFromPath(path)
|
|
||||||
if len(ext) == 0 {
|
|
||||||
panic(fmt.Sprintf("File %s has unknown extension.", path))
|
|
||||||
}
|
|
||||||
return ext
|
|
||||||
}
|
|
||||||
|
|
||||||
func tryGetJSExtensionForFile(fileName string, options *core.CompilerOptions) string {
|
|
||||||
ext := tspath.TryGetExtensionFromPath(fileName)
|
|
||||||
switch ext {
|
|
||||||
case tspath.ExtensionTs, tspath.ExtensionDts:
|
|
||||||
return tspath.ExtensionJs
|
|
||||||
case tspath.ExtensionTsx:
|
|
||||||
if options.Jsx == core.JsxEmitPreserve {
|
|
||||||
return tspath.ExtensionJsx
|
|
||||||
}
|
|
||||||
return tspath.ExtensionJs
|
|
||||||
case tspath.ExtensionJs, tspath.ExtensionJsx, tspath.ExtensionJson:
|
|
||||||
return ext
|
|
||||||
case tspath.ExtensionDmts, tspath.ExtensionMts, tspath.ExtensionMjs:
|
|
||||||
return tspath.ExtensionMjs
|
|
||||||
case tspath.ExtensionDcts, tspath.ExtensionCts, tspath.ExtensionCjs:
|
|
||||||
return tspath.ExtensionCjs
|
|
||||||
default:
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func tryGetAnyFileFromPath(host ModuleSpecifierGenerationHost, path string) bool {
|
|
||||||
// !!! TODO: shouldn't this use readdir instead of fileexists for perf?
|
|
||||||
// We check all js, `node` and `json` extensions in addition to TS, since node module resolution would also choose those over the directory
|
|
||||||
extGroups := tsoptions.GetSupportedExtensions(
|
|
||||||
&core.CompilerOptions{
|
|
||||||
AllowJs: core.TSTrue,
|
|
||||||
},
|
|
||||||
[]tsoptions.FileExtensionInfo{
|
|
||||||
{
|
|
||||||
Extension: "node",
|
|
||||||
IsMixedContent: false,
|
|
||||||
ScriptKind: core.ScriptKindExternal,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Extension: "json",
|
|
||||||
IsMixedContent: false,
|
|
||||||
ScriptKind: core.ScriptKindJSON,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
)
|
|
||||||
for _, exts := range extGroups {
|
|
||||||
for _, e := range exts {
|
|
||||||
fullPath := path + e
|
|
||||||
if host.FileExists(tspath.GetNormalizedAbsolutePath(fullPath, host.GetCurrentDirectory())) {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
func getPathsRelativeToRootDirs(path string, rootDirs []string, useCaseSensitiveFileNames bool) []string {
|
|
||||||
var results []string
|
|
||||||
for _, rootDir := range rootDirs {
|
|
||||||
relativePath := getRelativePathIfInSameVolume(path, rootDir, useCaseSensitiveFileNames)
|
|
||||||
if len(relativePath) > 0 && isPathRelativeToParent(relativePath) {
|
|
||||||
results = append(results, relativePath)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return results
|
|
||||||
}
|
|
||||||
|
|
||||||
func isPathRelativeToParent(path string) bool {
|
|
||||||
return strings.HasPrefix(path, "..")
|
|
||||||
}
|
|
||||||
|
|
||||||
func getRelativePathIfInSameVolume(path string, directoryPath string, useCaseSensitiveFileNames bool) string {
|
|
||||||
relativePath := tspath.GetRelativePathToDirectoryOrUrl(directoryPath, path, false, tspath.ComparePathsOptions{
|
|
||||||
UseCaseSensitiveFileNames: useCaseSensitiveFileNames,
|
|
||||||
CurrentDirectory: directoryPath,
|
|
||||||
})
|
|
||||||
if tspath.IsRootedDiskPath(relativePath) {
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
return relativePath
|
|
||||||
}
|
|
||||||
|
|
||||||
func packageJsonPathsAreEqual(a string, b string, options tspath.ComparePathsOptions) bool {
|
|
||||||
if a == b {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
if len(a) == 0 || len(b) == 0 {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
return tspath.ComparePaths(a, b, options) == 0
|
|
||||||
}
|
|
||||||
|
|
||||||
func prefersTsExtension(allowedEndings []ModuleSpecifierEnding) bool {
|
|
||||||
jsPriority := slices.Index(allowedEndings, ModuleSpecifierEndingJsExtension)
|
|
||||||
tsPriority := slices.Index(allowedEndings, ModuleSpecifierEndingTsExtension)
|
|
||||||
if tsPriority > -1 {
|
|
||||||
return tsPriority < jsPriority
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
var typeScriptVersion = semver.MustParse(core.Version()) // TODO: unify with clone inside module resolver?
|
|
||||||
|
|
||||||
func isApplicableVersionedTypesKey(conditions []string, key string) bool {
|
|
||||||
if !slices.Contains(conditions, "types") {
|
|
||||||
return false // only apply versioned types conditions if the types condition is applied
|
|
||||||
}
|
|
||||||
if !strings.HasPrefix(key, "types@") {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
range_, ok := semver.TryParseVersionRange(key[len("types@"):])
|
|
||||||
if !ok {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
return range_.Test(&typeScriptVersion)
|
|
||||||
}
|
|
||||||
|
|
||||||
func replaceFirstStar(s string, replacement string) string {
|
|
||||||
return strings.Replace(s, "*", replacement, 1)
|
|
||||||
}
|
|
||||||
|
|
||||||
type NodeModulePathParts struct {
|
|
||||||
TopLevelNodeModulesIndex int
|
|
||||||
TopLevelPackageNameIndex int
|
|
||||||
PackageRootIndex int
|
|
||||||
FileNameIndex int
|
|
||||||
}
|
|
||||||
|
|
||||||
type nodeModulesPathParseState uint8
|
|
||||||
|
|
||||||
const (
|
|
||||||
nodeModulesPathParseStateBeforeNodeModules nodeModulesPathParseState = iota
|
|
||||||
nodeModulesPathParseStateNodeModules
|
|
||||||
nodeModulesPathParseStateScope
|
|
||||||
nodeModulesPathParseStatePackageContent
|
|
||||||
)
|
|
||||||
|
|
||||||
func GetNodeModulePathParts(fullPath string) *NodeModulePathParts {
|
|
||||||
// If fullPath can't be valid module file within node_modules, returns undefined.
|
|
||||||
// Example of expected pattern: /base/path/node_modules/[@scope/otherpackage/@otherscope/node_modules/]package/[subdirectory/]file.js
|
|
||||||
// Returns indices: ^ ^ ^ ^
|
|
||||||
|
|
||||||
topLevelNodeModulesIndex := 0
|
|
||||||
topLevelPackageNameIndex := 0
|
|
||||||
packageRootIndex := 0
|
|
||||||
fileNameIndex := 0
|
|
||||||
|
|
||||||
partStart := 0
|
|
||||||
partEnd := 0
|
|
||||||
state := nodeModulesPathParseStateBeforeNodeModules
|
|
||||||
|
|
||||||
for partEnd >= 0 {
|
|
||||||
partStart = partEnd
|
|
||||||
partEnd = core.IndexAfter(fullPath, "/", partStart+1)
|
|
||||||
switch state {
|
|
||||||
case nodeModulesPathParseStateBeforeNodeModules:
|
|
||||||
if strings.Index(fullPath[partStart:], "/node_modules/") == 0 {
|
|
||||||
topLevelNodeModulesIndex = partStart
|
|
||||||
topLevelPackageNameIndex = partEnd
|
|
||||||
state = nodeModulesPathParseStateNodeModules
|
|
||||||
}
|
|
||||||
case nodeModulesPathParseStateNodeModules, nodeModulesPathParseStateScope:
|
|
||||||
if state == nodeModulesPathParseStateNodeModules && fullPath[partStart+1] == '@' {
|
|
||||||
state = nodeModulesPathParseStateScope
|
|
||||||
} else {
|
|
||||||
packageRootIndex = partEnd
|
|
||||||
state = nodeModulesPathParseStatePackageContent
|
|
||||||
}
|
|
||||||
case nodeModulesPathParseStatePackageContent:
|
|
||||||
if strings.Index(fullPath[partStart:], "/node_modules/") == 0 {
|
|
||||||
state = nodeModulesPathParseStateNodeModules
|
|
||||||
} else {
|
|
||||||
state = nodeModulesPathParseStatePackageContent
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fileNameIndex = partStart
|
|
||||||
|
|
||||||
if state > nodeModulesPathParseStateNodeModules {
|
|
||||||
return &NodeModulePathParts{
|
|
||||||
TopLevelNodeModulesIndex: topLevelNodeModulesIndex,
|
|
||||||
TopLevelPackageNameIndex: topLevelPackageNameIndex,
|
|
||||||
PackageRootIndex: packageRootIndex,
|
|
||||||
FileNameIndex: fileNameIndex,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func GetNodeModulesPackageName(
|
|
||||||
compilerOptions *core.CompilerOptions,
|
|
||||||
importingSourceFile *ast.SourceFile, // !!! | FutureSourceFile
|
|
||||||
nodeModulesFileName string,
|
|
||||||
host ModuleSpecifierGenerationHost,
|
|
||||||
preferences UserPreferences,
|
|
||||||
options ModuleSpecifierOptions,
|
|
||||||
) string {
|
|
||||||
info := getInfo(importingSourceFile.FileName(), host)
|
|
||||||
modulePaths := getAllModulePaths(info, nodeModulesFileName, host, compilerOptions, preferences, options)
|
|
||||||
for _, modulePath := range modulePaths {
|
|
||||||
if result := tryGetModuleNameAsNodeModule(modulePath, info, importingSourceFile, host, compilerOptions, preferences, true /*packageNameOnly*/, options.OverrideImportMode); len(result) > 0 {
|
|
||||||
return result
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
|
|
||||||
func GetPackageNameFromTypesPackageName(mangledName string) string {
|
|
||||||
withoutAtTypePrefix := strings.TrimPrefix(mangledName, "@types/")
|
|
||||||
if withoutAtTypePrefix != mangledName {
|
|
||||||
return module.UnmangleScopedPackageName(withoutAtTypePrefix)
|
|
||||||
}
|
|
||||||
return mangledName
|
|
||||||
}
|
|
||||||
|
|
||||||
func allKeysStartWithDot(obj *collections.OrderedMap[string, packagejson.ExportsOrImports]) bool {
|
|
||||||
for k := range obj.Keys() {
|
|
||||||
if !strings.HasPrefix(k, ".") {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
Loading…
x
Reference in New Issue
Block a user