diff --git a/lib/tsc.js b/lib/tsc.js index 2e0c0282eac..cdf999a64f0 100644 --- a/lib/tsc.js +++ b/lib/tsc.js @@ -24625,7 +24625,8 @@ var ts; } } else { - return "\"" + ts.getResolvedExternalModuleName(context.tracker.moduleResolverHost, file_3, ts.getSourceFileOfNode(ts.getOriginalNode(context.enclosingDeclaration))) + "\""; + var contextFile = ts.getSourceFileOfNode(ts.getOriginalNode(context.enclosingDeclaration)); + return "\"" + (file_3.moduleName || ts.moduleSpecifiers.getModuleSpecifiers(symbol, compilerOptions, contextFile, context.tracker.moduleResolverHost, context.tracker.moduleResolverHost.getSourceFiles(), { importModuleSpecifierPreference: "non-relative" })[0]) + "\""; } } var declaration = symbol.declarations[0]; @@ -63716,20 +63717,8 @@ var ts; return oldProgram.structureIsReused = 2; } function getEmitHost(writeFileCallback) { - return { - getPrependNodes: getPrependNodes, - getCanonicalFileName: getCanonicalFileName, - getCommonSourceDirectory: program.getCommonSourceDirectory, - getCompilerOptions: program.getCompilerOptions, - getCurrentDirectory: function () { return currentDirectory; }, - getNewLine: function () { return host.getNewLine(); }, - getSourceFile: program.getSourceFile, - getSourceFileByPath: program.getSourceFileByPath, - getSourceFiles: program.getSourceFiles, - isSourceFileFromExternalLibrary: isSourceFileFromExternalLibrary, - writeFile: writeFileCallback || (function (fileName, data, writeByteOrderMark, onError, sourceFiles) { return host.writeFile(fileName, data, writeByteOrderMark, onError, sourceFiles); }), - isEmitBlocked: isEmitBlocked, - }; + return __assign({ getPrependNodes: getPrependNodes, + getCanonicalFileName: getCanonicalFileName, getCommonSourceDirectory: program.getCommonSourceDirectory, getCompilerOptions: program.getCompilerOptions, getCurrentDirectory: function () { return currentDirectory; }, getNewLine: function () { return host.getNewLine(); }, getSourceFile: program.getSourceFile, getSourceFileByPath: program.getSourceFileByPath, getSourceFiles: program.getSourceFiles, isSourceFileFromExternalLibrary: isSourceFileFromExternalLibrary, writeFile: writeFileCallback || (function (fileName, data, writeByteOrderMark, onError, sourceFiles) { return host.writeFile(fileName, data, writeByteOrderMark, onError, sourceFiles); }), isEmitBlocked: isEmitBlocked, readFile: function (f) { return host.readFile(f); }, fileExists: function (f) { return host.fileExists(f); } }, (host.directoryExists ? { directoryExists: function (f) { return host.directoryExists(f); } } : {})); } function getProjectReferences() { if (!resolvedProjectReferences) @@ -66003,6 +65992,312 @@ var ts; ts.createResolutionCache = createResolutionCache; })(ts || (ts = {})); var ts; +(function (ts) { + var moduleSpecifiers; + (function (moduleSpecifiers) { + function getModuleSpecifier(compilerOptions, fromSourceFile, fromSourceFileName, toFileName, host, preferences) { + if (preferences === void 0) { preferences = {}; } + var info = getInfo(compilerOptions, fromSourceFile, fromSourceFileName, host); + return getGlobalModuleSpecifier(toFileName, info, host, compilerOptions) || + ts.first(getLocalModuleSpecifiers(toFileName, info, compilerOptions, preferences)); + } + moduleSpecifiers.getModuleSpecifier = getModuleSpecifier; + function getModuleSpecifiers(moduleSymbol, compilerOptions, importingSourceFile, host, files, preferences) { + var ambient = tryGetModuleNameFromAmbientModule(moduleSymbol); + if (ambient) + return [[ambient]]; + var info = getInfo(compilerOptions, importingSourceFile, importingSourceFile.path, host); + if (!files) { + return ts.Debug.fail("Files list must be present to resolve symlinks in specifier resolution"); + } + var modulePaths = getAllModulePaths(files, ts.getSourceFileOfNode(moduleSymbol.valueDeclaration), info.getCanonicalFileName, host); + var global = ts.mapDefined(modulePaths, function (moduleFileName) { return getGlobalModuleSpecifier(moduleFileName, info, host, compilerOptions); }); + return global.length ? global.map(function (g) { return [g]; }) : modulePaths.map(function (moduleFileName) { + return getLocalModuleSpecifiers(moduleFileName, info, compilerOptions, preferences); + }); + } + moduleSpecifiers.getModuleSpecifiers = getModuleSpecifiers; + function getInfo(compilerOptions, importingSourceFile, importingSourceFileName, host) { + var moduleResolutionKind = ts.getEmitModuleResolutionKind(compilerOptions); + var addJsExtension = usesJsExtensionOnImports(importingSourceFile); + var getCanonicalFileName = ts.createGetCanonicalFileName(host.useCaseSensitiveFileNames ? host.useCaseSensitiveFileNames() : true); + var sourceDirectory = ts.getDirectoryPath(importingSourceFileName); + return { moduleResolutionKind: moduleResolutionKind, addJsExtension: addJsExtension, getCanonicalFileName: getCanonicalFileName, sourceDirectory: sourceDirectory }; + } + function getGlobalModuleSpecifier(moduleFileName, _a, host, compilerOptions) { + var addJsExtension = _a.addJsExtension, getCanonicalFileName = _a.getCanonicalFileName, sourceDirectory = _a.sourceDirectory; + return tryGetModuleNameFromTypeRoots(compilerOptions, host, getCanonicalFileName, moduleFileName, addJsExtension) + || tryGetModuleNameAsNodeModule(compilerOptions, moduleFileName, host, getCanonicalFileName, sourceDirectory) + || compilerOptions.rootDirs && tryGetModuleNameFromRootDirs(compilerOptions.rootDirs, moduleFileName, sourceDirectory, getCanonicalFileName); + } + function getLocalModuleSpecifiers(moduleFileName, _a, compilerOptions, preferences) { + var moduleResolutionKind = _a.moduleResolutionKind, addJsExtension = _a.addJsExtension, getCanonicalFileName = _a.getCanonicalFileName, sourceDirectory = _a.sourceDirectory; + var baseUrl = compilerOptions.baseUrl, paths = compilerOptions.paths; + var relativePath = removeExtensionAndIndexPostFix(ts.ensurePathIsNonModuleName(ts.getRelativePathFromDirectory(sourceDirectory, moduleFileName, getCanonicalFileName)), moduleResolutionKind, addJsExtension); + if (!baseUrl || preferences.importModuleSpecifierPreference === "relative") { + return [relativePath]; + } + var relativeToBaseUrl = getRelativePathIfInDirectory(moduleFileName, baseUrl, getCanonicalFileName); + if (!relativeToBaseUrl) { + return [relativePath]; + } + var importRelativeToBaseUrl = removeExtensionAndIndexPostFix(relativeToBaseUrl, moduleResolutionKind, addJsExtension); + if (paths) { + var fromPaths = tryGetModuleNameFromPaths(ts.removeFileExtension(relativeToBaseUrl), importRelativeToBaseUrl, paths); + if (fromPaths) { + return [fromPaths]; + } + } + if (preferences.importModuleSpecifierPreference === "non-relative") { + return [importRelativeToBaseUrl]; + } + if (preferences.importModuleSpecifierPreference !== undefined) + ts.Debug.assertNever(preferences.importModuleSpecifierPreference); + if (isPathRelativeToParent(relativeToBaseUrl)) { + return [relativePath]; + } + var pathFromSourceToBaseUrl = ts.ensurePathIsNonModuleName(ts.getRelativePathFromDirectory(sourceDirectory, baseUrl, getCanonicalFileName)); + var relativeFirst = getRelativePathNParents(relativePath) < getRelativePathNParents(pathFromSourceToBaseUrl); + return relativeFirst ? [relativePath, importRelativeToBaseUrl] : [importRelativeToBaseUrl, relativePath]; + } + function usesJsExtensionOnImports(_a) { + var imports = _a.imports; + return ts.firstDefined(imports, function (_a) { + var text = _a.text; + return ts.pathIsRelative(text) ? ts.fileExtensionIs(text, ".js") : undefined; + }) || false; + } + function discoverProbableSymlinks(files) { + var symlinks = ts.mapDefined(files, function (sf) { + return sf.resolvedModules && ts.firstDefinedIterator(sf.resolvedModules.values(), function (res) { + return res && res.originalPath && res.resolvedFileName !== res.originalPath ? [res.resolvedFileName, res.originalPath] : undefined; + }); + }); + var result = ts.createMap(); + if (symlinks) { + for (var _i = 0, symlinks_1 = symlinks; _i < symlinks_1.length; _i++) { + var _a = symlinks_1[_i], resolvedPath = _a[0], originalPath = _a[1]; + var resolvedParts = ts.getPathComponents(resolvedPath); + var originalParts = ts.getPathComponents(originalPath); + while (resolvedParts[resolvedParts.length - 1] === originalParts[originalParts.length - 1]) { + resolvedParts.pop(); + originalParts.pop(); + } + result.set(ts.getPathFromPathComponents(originalParts), ts.getPathFromPathComponents(resolvedParts)); + } + } + return result; + } + function getAllModulePathsUsingIndirectSymlinks(files, target, getCanonicalFileName, host) { + var links = discoverProbableSymlinks(files); + var paths = ts.arrayFrom(links.keys()); + var options; + for (var _i = 0, paths_2 = paths; _i < paths_2.length; _i++) { + var path = paths_2[_i]; + var resolved = links.get(path); + if (ts.startsWith(target, resolved + "/")) { + var relative = ts.getRelativePathFromDirectory(resolved, target, getCanonicalFileName); + var option = ts.resolvePath(path, relative); + if (!host.fileExists || host.fileExists(option)) { + if (!options) + options = []; + options.push(option); + } + } + } + var resolvedtarget = host.getCurrentDirectory ? ts.resolvePath(host.getCurrentDirectory(), target) : target; + if (options) { + options.push(resolvedtarget); + return options; + } + return [resolvedtarget]; + } + function getAllModulePaths(files, _a, getCanonicalFileName, host) { + var fileName = _a.fileName; + var symlinks = ts.mapDefined(files, function (sf) { + return sf.resolvedModules && ts.firstDefinedIterator(sf.resolvedModules.values(), function (res) { + return res && res.resolvedFileName === fileName ? res.originalPath : undefined; + }); + }); + return symlinks.length === 0 ? getAllModulePathsUsingIndirectSymlinks(files, fileName, getCanonicalFileName, host) : symlinks; + } + function getRelativePathNParents(relativePath) { + var components = ts.getPathComponents(relativePath); + if (components[0] || components.length === 1) + return 0; + for (var i = 1; i < components.length; i++) { + if (components[i] !== "..") + return i - 1; + } + return components.length - 1; + } + function tryGetModuleNameFromAmbientModule(moduleSymbol) { + var decl = moduleSymbol.valueDeclaration; + if (ts.isModuleDeclaration(decl) && ts.isStringLiteral(decl.name)) { + return decl.name.text; + } + } + function tryGetModuleNameFromPaths(relativeToBaseUrlWithIndex, relativeToBaseUrl, paths) { + for (var key in paths) { + for (var _i = 0, _a = paths[key]; _i < _a.length; _i++) { + var patternText_1 = _a[_i]; + var pattern = ts.removeFileExtension(ts.normalizePath(patternText_1)); + var indexOfStar = pattern.indexOf("*"); + if (indexOfStar === 0 && pattern.length === 1) { + continue; + } + else if (indexOfStar !== -1) { + var prefix = pattern.substr(0, indexOfStar); + var suffix = pattern.substr(indexOfStar + 1); + if (relativeToBaseUrl.length >= prefix.length + suffix.length && + ts.startsWith(relativeToBaseUrl, prefix) && + ts.endsWith(relativeToBaseUrl, suffix)) { + var matchedStar = relativeToBaseUrl.substr(prefix.length, relativeToBaseUrl.length - suffix.length); + return key.replace("*", matchedStar); + } + } + else if (pattern === relativeToBaseUrl || pattern === relativeToBaseUrlWithIndex) { + return key; + } + } + } + } + function tryGetModuleNameFromRootDirs(rootDirs, moduleFileName, sourceDirectory, getCanonicalFileName) { + var normalizedTargetPath = getPathRelativeToRootDirs(moduleFileName, rootDirs, getCanonicalFileName); + if (normalizedTargetPath === undefined) { + return undefined; + } + var normalizedSourcePath = getPathRelativeToRootDirs(sourceDirectory, rootDirs, getCanonicalFileName); + var relativePath = normalizedSourcePath !== undefined ? ts.ensurePathIsNonModuleName(ts.getRelativePathFromDirectory(normalizedSourcePath, normalizedTargetPath, getCanonicalFileName)) : normalizedTargetPath; + return ts.removeFileExtension(relativePath); + } + function tryGetModuleNameFromTypeRoots(options, host, getCanonicalFileName, moduleFileName, addJsExtension) { + var roots = ts.getEffectiveTypeRoots(options, host); + return ts.firstDefined(roots, function (unNormalizedTypeRoot) { + var typeRoot = ts.toPath(unNormalizedTypeRoot, undefined, getCanonicalFileName); + if (ts.startsWith(moduleFileName, typeRoot)) { + return removeExtensionAndIndexPostFix(moduleFileName.substring(typeRoot.length + 1), ts.ModuleResolutionKind.NodeJs, addJsExtension); + } + }); + } + function tryGetModuleNameAsNodeModule(options, moduleFileName, host, getCanonicalFileName, sourceDirectory) { + if (ts.getEmitModuleResolutionKind(options) !== ts.ModuleResolutionKind.NodeJs) { + return undefined; + } + var parts = getNodeModulePathParts(moduleFileName); + if (!parts) { + return undefined; + } + var moduleSpecifier = getDirectoryOrExtensionlessFileName(moduleFileName); + moduleSpecifier = getNodeResolvablePath(moduleSpecifier); + return ts.getPackageNameFromAtTypesDirectory(moduleSpecifier); + function getDirectoryOrExtensionlessFileName(path) { + var packageRootPath = path.substring(0, parts.packageRootIndex); + var packageJsonPath = ts.combinePaths(packageRootPath, "package.json"); + if (host.fileExists(packageJsonPath)) { + var packageJsonContent = JSON.parse(host.readFile(packageJsonPath)); + if (packageJsonContent) { + var mainFileRelative = packageJsonContent.typings || packageJsonContent.types || packageJsonContent.main; + if (mainFileRelative) { + var mainExportFile = ts.toPath(mainFileRelative, packageRootPath, getCanonicalFileName); + if (mainExportFile === getCanonicalFileName(path)) { + return packageRootPath; + } + } + } + } + var fullModulePathWithoutExtension = ts.removeFileExtension(path); + if (getCanonicalFileName(fullModulePathWithoutExtension.substring(parts.fileNameIndex)) === "/index" && !tryGetAnyFileFromPath(host, fullModulePathWithoutExtension.substring(0, parts.fileNameIndex))) { + return fullModulePathWithoutExtension.substring(0, parts.fileNameIndex); + } + return fullModulePathWithoutExtension; + } + function getNodeResolvablePath(path) { + var basePath = path.substring(0, parts.topLevelNodeModulesIndex); + if (sourceDirectory.indexOf(basePath) === 0) { + return path.substring(parts.topLevelPackageNameIndex + 1); + } + else { + return ts.ensurePathIsNonModuleName(ts.getRelativePathFromDirectory(sourceDirectory, path, getCanonicalFileName)); + } + } + } + function tryGetAnyFileFromPath(host, path) { + var extensions = ts.getSupportedExtensions({ allowJs: true }, [{ extension: "node", isMixedContent: false }, { extension: "json", isMixedContent: false, scriptKind: 6 }]); + for (var _i = 0, extensions_3 = extensions; _i < extensions_3.length; _i++) { + var e = extensions_3[_i]; + var fullPath = path + e; + if (host.fileExists(fullPath)) { + return fullPath; + } + } + } + function getNodeModulePathParts(fullPath) { + var topLevelNodeModulesIndex = 0; + var topLevelPackageNameIndex = 0; + var packageRootIndex = 0; + var fileNameIndex = 0; + var partStart = 0; + var partEnd = 0; + var state = 0; + while (partEnd >= 0) { + partStart = partEnd; + partEnd = fullPath.indexOf("/", partStart + 1); + switch (state) { + case 0: + if (fullPath.indexOf("/node_modules/", partStart) === partStart) { + topLevelNodeModulesIndex = partStart; + topLevelPackageNameIndex = partEnd; + state = 1; + } + break; + case 1: + case 2: + if (state === 1 && fullPath.charAt(partStart + 1) === "@") { + state = 2; + } + else { + packageRootIndex = partEnd; + state = 3; + } + break; + case 3: + if (fullPath.indexOf("/node_modules/", partStart) === partStart) { + state = 1; + } + else { + state = 3; + } + break; + } + } + fileNameIndex = partStart; + return state > 1 ? { topLevelNodeModulesIndex: topLevelNodeModulesIndex, topLevelPackageNameIndex: topLevelPackageNameIndex, packageRootIndex: packageRootIndex, fileNameIndex: fileNameIndex } : undefined; + } + function getPathRelativeToRootDirs(path, rootDirs, getCanonicalFileName) { + return ts.firstDefined(rootDirs, function (rootDir) { + var relativePath = getRelativePathIfInDirectory(path, rootDir, getCanonicalFileName); + return isPathRelativeToParent(relativePath) ? undefined : relativePath; + }); + } + function removeExtensionAndIndexPostFix(fileName, moduleResolutionKind, addJsExtension) { + var noExtension = ts.removeFileExtension(fileName); + return addJsExtension + ? noExtension + ".js" + : moduleResolutionKind === ts.ModuleResolutionKind.NodeJs + ? ts.removeSuffix(noExtension, "/index") + : noExtension; + } + function getRelativePathIfInDirectory(path, directoryPath, getCanonicalFileName) { + var relativePath = ts.getRelativePathToDirectoryOrUrl(directoryPath, path, directoryPath, getCanonicalFileName, false); + return ts.isRootedDiskPath(relativePath) ? undefined : relativePath; + } + function isPathRelativeToParent(path) { + return ts.startsWith(path, ".."); + } + })(moduleSpecifiers = ts.moduleSpecifiers || (ts.moduleSpecifiers = {})); +})(ts || (ts = {})); +var ts; (function (ts) { var sysFormatDiagnosticsHost = ts.sys ? { getCurrentDirectory: function () { return ts.sys.getCurrentDirectory(); }, @@ -66145,11 +66440,11 @@ var ts; watchFile: system.watchFile ? (function (path, callback, pollingInterval) { return system.watchFile(path, callback, pollingInterval); }) : function () { return noopFileWatcher; }, watchDirectory: system.watchDirectory ? (function (path, callback, recursive) { return system.watchDirectory(path, callback, recursive); }) : function () { return noopFileWatcher; }, setTimeout: system.setTimeout ? (function (callback, ms) { - var _a; var args = []; for (var _i = 2; _i < arguments.length; _i++) { args[_i - 2] = arguments[_i]; } + var _a; return (_a = system.setTimeout).call.apply(_a, [system, callback, ms].concat(args)); }) : ts.noop, clearTimeout: system.clearTimeout ? (function (timeoutId) { return system.clearTimeout(timeoutId); }) : ts.noop, diff --git a/lib/tsserver.js b/lib/tsserver.js index c5ad1c8d993..4d0bf0fc571 100644 --- a/lib/tsserver.js +++ b/lib/tsserver.js @@ -26067,7 +26067,8 @@ var ts; } } else { - return "\"" + ts.getResolvedExternalModuleName(context.tracker.moduleResolverHost, file, ts.getSourceFileOfNode(ts.getOriginalNode(context.enclosingDeclaration))) + "\""; + var contextFile = ts.getSourceFileOfNode(ts.getOriginalNode(context.enclosingDeclaration)); + return "\"" + (file.moduleName || ts.moduleSpecifiers.getModuleSpecifiers(symbol, compilerOptions, contextFile, context.tracker.moduleResolverHost, context.tracker.moduleResolverHost.getSourceFiles(), { importModuleSpecifierPreference: "non-relative" })[0]) + "\""; } } var declaration = symbol.declarations[0]; @@ -65365,20 +65366,8 @@ var ts; return oldProgram.structureIsReused = 2; } function getEmitHost(writeFileCallback) { - return { - getPrependNodes: getPrependNodes, - getCanonicalFileName: getCanonicalFileName, - getCommonSourceDirectory: program.getCommonSourceDirectory, - getCompilerOptions: program.getCompilerOptions, - getCurrentDirectory: function () { return currentDirectory; }, - getNewLine: function () { return host.getNewLine(); }, - getSourceFile: program.getSourceFile, - getSourceFileByPath: program.getSourceFileByPath, - getSourceFiles: program.getSourceFiles, - isSourceFileFromExternalLibrary: isSourceFileFromExternalLibrary, - writeFile: writeFileCallback || (function (fileName, data, writeByteOrderMark, onError, sourceFiles) { return host.writeFile(fileName, data, writeByteOrderMark, onError, sourceFiles); }), - isEmitBlocked: isEmitBlocked, - }; + return __assign({ getPrependNodes: getPrependNodes, + getCanonicalFileName: getCanonicalFileName, getCommonSourceDirectory: program.getCommonSourceDirectory, getCompilerOptions: program.getCompilerOptions, getCurrentDirectory: function () { return currentDirectory; }, getNewLine: function () { return host.getNewLine(); }, getSourceFile: program.getSourceFile, getSourceFileByPath: program.getSourceFileByPath, getSourceFiles: program.getSourceFiles, isSourceFileFromExternalLibrary: isSourceFileFromExternalLibrary, writeFile: writeFileCallback || (function (fileName, data, writeByteOrderMark, onError, sourceFiles) { return host.writeFile(fileName, data, writeByteOrderMark, onError, sourceFiles); }), isEmitBlocked: isEmitBlocked, readFile: function (f) { return host.readFile(f); }, fileExists: function (f) { return host.fileExists(f); } }, (host.directoryExists ? { directoryExists: function (f) { return host.directoryExists(f); } } : {})); } function getProjectReferences() { if (!resolvedProjectReferences) @@ -67652,6 +67641,319 @@ var ts; ts.createResolutionCache = createResolutionCache; })(ts || (ts = {})); var ts; +(function (ts) { + var moduleSpecifiers; + (function (moduleSpecifiers) { + function getModuleSpecifier(compilerOptions, fromSourceFile, fromSourceFileName, toFileName, host, preferences) { + if (preferences === void 0) { preferences = {}; } + var info = getInfo(compilerOptions, fromSourceFile, fromSourceFileName, host); + return getGlobalModuleSpecifier(toFileName, info, host, compilerOptions) || + ts.first(getLocalModuleSpecifiers(toFileName, info, compilerOptions, preferences)); + } + moduleSpecifiers.getModuleSpecifier = getModuleSpecifier; + function getModuleSpecifiers(moduleSymbol, compilerOptions, importingSourceFile, host, files, preferences) { + var ambient = tryGetModuleNameFromAmbientModule(moduleSymbol); + if (ambient) + return [[ambient]]; + var info = getInfo(compilerOptions, importingSourceFile, importingSourceFile.path, host); + if (!files) { + return ts.Debug.fail("Files list must be present to resolve symlinks in specifier resolution"); + } + var modulePaths = getAllModulePaths(files, ts.getSourceFileOfNode(moduleSymbol.valueDeclaration), info.getCanonicalFileName, host); + var global = ts.mapDefined(modulePaths, function (moduleFileName) { return getGlobalModuleSpecifier(moduleFileName, info, host, compilerOptions); }); + return global.length ? global.map(function (g) { return [g]; }) : modulePaths.map(function (moduleFileName) { + return getLocalModuleSpecifiers(moduleFileName, info, compilerOptions, preferences); + }); + } + moduleSpecifiers.getModuleSpecifiers = getModuleSpecifiers; + function getInfo(compilerOptions, importingSourceFile, importingSourceFileName, host) { + var moduleResolutionKind = ts.getEmitModuleResolutionKind(compilerOptions); + var addJsExtension = usesJsExtensionOnImports(importingSourceFile); + var getCanonicalFileName = ts.createGetCanonicalFileName(host.useCaseSensitiveFileNames ? host.useCaseSensitiveFileNames() : true); + var sourceDirectory = ts.getDirectoryPath(importingSourceFileName); + return { moduleResolutionKind: moduleResolutionKind, addJsExtension: addJsExtension, getCanonicalFileName: getCanonicalFileName, sourceDirectory: sourceDirectory }; + } + function getGlobalModuleSpecifier(moduleFileName, _a, host, compilerOptions) { + var addJsExtension = _a.addJsExtension, getCanonicalFileName = _a.getCanonicalFileName, sourceDirectory = _a.sourceDirectory; + return tryGetModuleNameFromTypeRoots(compilerOptions, host, getCanonicalFileName, moduleFileName, addJsExtension) + || tryGetModuleNameAsNodeModule(compilerOptions, moduleFileName, host, getCanonicalFileName, sourceDirectory) + || compilerOptions.rootDirs && tryGetModuleNameFromRootDirs(compilerOptions.rootDirs, moduleFileName, sourceDirectory, getCanonicalFileName); + } + function getLocalModuleSpecifiers(moduleFileName, _a, compilerOptions, preferences) { + var moduleResolutionKind = _a.moduleResolutionKind, addJsExtension = _a.addJsExtension, getCanonicalFileName = _a.getCanonicalFileName, sourceDirectory = _a.sourceDirectory; + var baseUrl = compilerOptions.baseUrl, paths = compilerOptions.paths; + var relativePath = removeExtensionAndIndexPostFix(ts.ensurePathIsNonModuleName(ts.getRelativePathFromDirectory(sourceDirectory, moduleFileName, getCanonicalFileName)), moduleResolutionKind, addJsExtension); + if (!baseUrl || preferences.importModuleSpecifierPreference === "relative") { + return [relativePath]; + } + var relativeToBaseUrl = getRelativePathIfInDirectory(moduleFileName, baseUrl, getCanonicalFileName); + if (!relativeToBaseUrl) { + return [relativePath]; + } + var importRelativeToBaseUrl = removeExtensionAndIndexPostFix(relativeToBaseUrl, moduleResolutionKind, addJsExtension); + if (paths) { + var fromPaths = tryGetModuleNameFromPaths(ts.removeFileExtension(relativeToBaseUrl), importRelativeToBaseUrl, paths); + if (fromPaths) { + return [fromPaths]; + } + } + if (preferences.importModuleSpecifierPreference === "non-relative") { + return [importRelativeToBaseUrl]; + } + if (preferences.importModuleSpecifierPreference !== undefined) + ts.Debug.assertNever(preferences.importModuleSpecifierPreference); + if (isPathRelativeToParent(relativeToBaseUrl)) { + return [relativePath]; + } + var pathFromSourceToBaseUrl = ts.ensurePathIsNonModuleName(ts.getRelativePathFromDirectory(sourceDirectory, baseUrl, getCanonicalFileName)); + var relativeFirst = getRelativePathNParents(relativePath) < getRelativePathNParents(pathFromSourceToBaseUrl); + return relativeFirst ? [relativePath, importRelativeToBaseUrl] : [importRelativeToBaseUrl, relativePath]; + } + function usesJsExtensionOnImports(_a) { + var imports = _a.imports; + return ts.firstDefined(imports, function (_a) { + var text = _a.text; + return ts.pathIsRelative(text) ? ts.fileExtensionIs(text, ".js") : undefined; + }) || false; + } + function discoverProbableSymlinks(files) { + var symlinks = ts.mapDefined(files, function (sf) { + return sf.resolvedModules && ts.firstDefinedIterator(sf.resolvedModules.values(), function (res) { + return res && res.originalPath && res.resolvedFileName !== res.originalPath ? [res.resolvedFileName, res.originalPath] : undefined; + }); + }); + var result = ts.createMap(); + if (symlinks) { + for (var _i = 0, symlinks_1 = symlinks; _i < symlinks_1.length; _i++) { + var _a = symlinks_1[_i], resolvedPath = _a[0], originalPath = _a[1]; + var resolvedParts = ts.getPathComponents(resolvedPath); + var originalParts = ts.getPathComponents(originalPath); + while (resolvedParts[resolvedParts.length - 1] === originalParts[originalParts.length - 1]) { + resolvedParts.pop(); + originalParts.pop(); + } + result.set(ts.getPathFromPathComponents(originalParts), ts.getPathFromPathComponents(resolvedParts)); + } + } + return result; + } + function getAllModulePathsUsingIndirectSymlinks(files, target, getCanonicalFileName, host) { + var links = discoverProbableSymlinks(files); + var paths = ts.arrayFrom(links.keys()); + var options; + for (var _i = 0, paths_2 = paths; _i < paths_2.length; _i++) { + var path = paths_2[_i]; + var resolved = links.get(path); + if (ts.startsWith(target, resolved + "/")) { + var relative = ts.getRelativePathFromDirectory(resolved, target, getCanonicalFileName); + var option = ts.resolvePath(path, relative); + if (!host.fileExists || host.fileExists(option)) { + if (!options) + options = []; + options.push(option); + } + } + } + var resolvedtarget = host.getCurrentDirectory ? ts.resolvePath(host.getCurrentDirectory(), target) : target; + if (options) { + options.push(resolvedtarget); + return options; + } + return [resolvedtarget]; + } + function getAllModulePaths(files, _a, getCanonicalFileName, host) { + var fileName = _a.fileName; + var symlinks = ts.mapDefined(files, function (sf) { + return sf.resolvedModules && ts.firstDefinedIterator(sf.resolvedModules.values(), function (res) { + return res && res.resolvedFileName === fileName ? res.originalPath : undefined; + }); + }); + return symlinks.length === 0 ? getAllModulePathsUsingIndirectSymlinks(files, fileName, getCanonicalFileName, host) : symlinks; + } + function getRelativePathNParents(relativePath) { + var components = ts.getPathComponents(relativePath); + if (components[0] || components.length === 1) + return 0; + for (var i = 1; i < components.length; i++) { + if (components[i] !== "..") + return i - 1; + } + return components.length - 1; + } + function tryGetModuleNameFromAmbientModule(moduleSymbol) { + var decl = moduleSymbol.valueDeclaration; + if (ts.isModuleDeclaration(decl) && ts.isStringLiteral(decl.name)) { + return decl.name.text; + } + } + function tryGetModuleNameFromPaths(relativeToBaseUrlWithIndex, relativeToBaseUrl, paths) { + for (var key in paths) { + for (var _i = 0, _a = paths[key]; _i < _a.length; _i++) { + var patternText_1 = _a[_i]; + var pattern = ts.removeFileExtension(ts.normalizePath(patternText_1)); + var indexOfStar = pattern.indexOf("*"); + if (indexOfStar === 0 && pattern.length === 1) { + continue; + } + else if (indexOfStar !== -1) { + var prefix = pattern.substr(0, indexOfStar); + var suffix = pattern.substr(indexOfStar + 1); + if (relativeToBaseUrl.length >= prefix.length + suffix.length && + ts.startsWith(relativeToBaseUrl, prefix) && + ts.endsWith(relativeToBaseUrl, suffix)) { + var matchedStar = relativeToBaseUrl.substr(prefix.length, relativeToBaseUrl.length - suffix.length); + return key.replace("*", matchedStar); + } + } + else if (pattern === relativeToBaseUrl || pattern === relativeToBaseUrlWithIndex) { + return key; + } + } + } + } + function tryGetModuleNameFromRootDirs(rootDirs, moduleFileName, sourceDirectory, getCanonicalFileName) { + var normalizedTargetPath = getPathRelativeToRootDirs(moduleFileName, rootDirs, getCanonicalFileName); + if (normalizedTargetPath === undefined) { + return undefined; + } + var normalizedSourcePath = getPathRelativeToRootDirs(sourceDirectory, rootDirs, getCanonicalFileName); + var relativePath = normalizedSourcePath !== undefined ? ts.ensurePathIsNonModuleName(ts.getRelativePathFromDirectory(normalizedSourcePath, normalizedTargetPath, getCanonicalFileName)) : normalizedTargetPath; + return ts.removeFileExtension(relativePath); + } + function tryGetModuleNameFromTypeRoots(options, host, getCanonicalFileName, moduleFileName, addJsExtension) { + var roots = ts.getEffectiveTypeRoots(options, host); + return ts.firstDefined(roots, function (unNormalizedTypeRoot) { + var typeRoot = ts.toPath(unNormalizedTypeRoot, undefined, getCanonicalFileName); + if (ts.startsWith(moduleFileName, typeRoot)) { + return removeExtensionAndIndexPostFix(moduleFileName.substring(typeRoot.length + 1), ts.ModuleResolutionKind.NodeJs, addJsExtension); + } + }); + } + function tryGetModuleNameAsNodeModule(options, moduleFileName, host, getCanonicalFileName, sourceDirectory) { + if (ts.getEmitModuleResolutionKind(options) !== ts.ModuleResolutionKind.NodeJs) { + return undefined; + } + var parts = getNodeModulePathParts(moduleFileName); + if (!parts) { + return undefined; + } + var moduleSpecifier = getDirectoryOrExtensionlessFileName(moduleFileName); + moduleSpecifier = getNodeResolvablePath(moduleSpecifier); + return ts.getPackageNameFromAtTypesDirectory(moduleSpecifier); + function getDirectoryOrExtensionlessFileName(path) { + var packageRootPath = path.substring(0, parts.packageRootIndex); + var packageJsonPath = ts.combinePaths(packageRootPath, "package.json"); + if (host.fileExists(packageJsonPath)) { + var packageJsonContent = JSON.parse(host.readFile(packageJsonPath)); + if (packageJsonContent) { + var mainFileRelative = packageJsonContent.typings || packageJsonContent.types || packageJsonContent.main; + if (mainFileRelative) { + var mainExportFile = ts.toPath(mainFileRelative, packageRootPath, getCanonicalFileName); + if (mainExportFile === getCanonicalFileName(path)) { + return packageRootPath; + } + } + } + } + var fullModulePathWithoutExtension = ts.removeFileExtension(path); + if (getCanonicalFileName(fullModulePathWithoutExtension.substring(parts.fileNameIndex)) === "/index" && !tryGetAnyFileFromPath(host, fullModulePathWithoutExtension.substring(0, parts.fileNameIndex))) { + return fullModulePathWithoutExtension.substring(0, parts.fileNameIndex); + } + return fullModulePathWithoutExtension; + } + function getNodeResolvablePath(path) { + var basePath = path.substring(0, parts.topLevelNodeModulesIndex); + if (sourceDirectory.indexOf(basePath) === 0) { + return path.substring(parts.topLevelPackageNameIndex + 1); + } + else { + return ts.ensurePathIsNonModuleName(ts.getRelativePathFromDirectory(sourceDirectory, path, getCanonicalFileName)); + } + } + } + function tryGetAnyFileFromPath(host, path) { + var extensions = ts.getSupportedExtensions({ allowJs: true }, [{ extension: "node", isMixedContent: false }, { extension: "json", isMixedContent: false, scriptKind: 6 }]); + for (var _i = 0, extensions_3 = extensions; _i < extensions_3.length; _i++) { + var e = extensions_3[_i]; + var fullPath = path + e; + if (host.fileExists(fullPath)) { + return fullPath; + } + } + } + function getNodeModulePathParts(fullPath) { + var topLevelNodeModulesIndex = 0; + var topLevelPackageNameIndex = 0; + var packageRootIndex = 0; + var fileNameIndex = 0; + var States; + (function (States) { + States[States["BeforeNodeModules"] = 0] = "BeforeNodeModules"; + States[States["NodeModules"] = 1] = "NodeModules"; + States[States["Scope"] = 2] = "Scope"; + States[States["PackageContent"] = 3] = "PackageContent"; + })(States || (States = {})); + var partStart = 0; + var partEnd = 0; + var state = 0; + while (partEnd >= 0) { + partStart = partEnd; + partEnd = fullPath.indexOf("/", partStart + 1); + switch (state) { + case 0: + if (fullPath.indexOf("/node_modules/", partStart) === partStart) { + topLevelNodeModulesIndex = partStart; + topLevelPackageNameIndex = partEnd; + state = 1; + } + break; + case 1: + case 2: + if (state === 1 && fullPath.charAt(partStart + 1) === "@") { + state = 2; + } + else { + packageRootIndex = partEnd; + state = 3; + } + break; + case 3: + if (fullPath.indexOf("/node_modules/", partStart) === partStart) { + state = 1; + } + else { + state = 3; + } + break; + } + } + fileNameIndex = partStart; + return state > 1 ? { topLevelNodeModulesIndex: topLevelNodeModulesIndex, topLevelPackageNameIndex: topLevelPackageNameIndex, packageRootIndex: packageRootIndex, fileNameIndex: fileNameIndex } : undefined; + } + function getPathRelativeToRootDirs(path, rootDirs, getCanonicalFileName) { + return ts.firstDefined(rootDirs, function (rootDir) { + var relativePath = getRelativePathIfInDirectory(path, rootDir, getCanonicalFileName); + return isPathRelativeToParent(relativePath) ? undefined : relativePath; + }); + } + function removeExtensionAndIndexPostFix(fileName, moduleResolutionKind, addJsExtension) { + var noExtension = ts.removeFileExtension(fileName); + return addJsExtension + ? noExtension + ".js" + : moduleResolutionKind === ts.ModuleResolutionKind.NodeJs + ? ts.removeSuffix(noExtension, "/index") + : noExtension; + } + function getRelativePathIfInDirectory(path, directoryPath, getCanonicalFileName) { + var relativePath = ts.getRelativePathToDirectoryOrUrl(directoryPath, path, directoryPath, getCanonicalFileName, false); + return ts.isRootedDiskPath(relativePath) ? undefined : relativePath; + } + function isPathRelativeToParent(path) { + return ts.startsWith(path, ".."); + } + })(moduleSpecifiers = ts.moduleSpecifiers || (ts.moduleSpecifiers = {})); +})(ts || (ts = {})); +var ts; (function (ts) { var sysFormatDiagnosticsHost = ts.sys ? { getCurrentDirectory: function () { return ts.sys.getCurrentDirectory(); }, @@ -76674,7 +76976,7 @@ var ts; var toImport = oldFromNew !== undefined ? getSourceFileToImportFromResolved(ts.resolveModuleName(importLiteral.text, oldImportFromPath, program.getCompilerOptions(), host), oldToNew, program) : getSourceFileToImport(importLiteral, sourceFile, program, host, oldToNew); - return toImport === undefined ? undefined : ts.moduleSpecifiers.getModuleSpecifier(program, sourceFile, newImportFromPath, toImport, host, preferences); + return toImport === undefined ? undefined : ts.moduleSpecifiers.getModuleSpecifier(program.getCompilerOptions(), sourceFile, newImportFromPath, toImport, host, preferences); }); }; for (var _i = 0, _a = program.getSourceFiles(); _i < _a.length; _i++) { @@ -79555,7 +79857,7 @@ var ts; ts.Debug.assert(indexOfOpenerToken >= 0 && children.length > indexOfOpenerToken + 1); return children[indexOfOpenerToken + 1]; } - var signatureHelpNodeBuilderFlags = 8192 | 3112960; + var signatureHelpNodeBuilderFlags = 8192 | 3112960 | 16384; function createSignatureHelpItems(candidates, resolvedSignature, argumentListInfo, typeChecker) { var argumentCount = argumentListInfo.argumentCount, applicableSpan = argumentListInfo.argumentsSpan, invocation = argumentListInfo.invocation, argumentIndex = argumentListInfo.argumentIndex; var isTypeParameterList = argumentListInfo.kind === 0; @@ -84454,7 +84756,7 @@ var ts; function getNewImportInfos(program, sourceFile, moduleSymbols, host, preferences) { var choicesForEachExportingModule = ts.flatMap(moduleSymbols, function (_a) { var moduleSymbol = _a.moduleSymbol, importKind = _a.importKind; - var modulePathsGroups = ts.moduleSpecifiers.getModuleSpecifiers(moduleSymbol, program, sourceFile, host, preferences); + var modulePathsGroups = ts.moduleSpecifiers.getModuleSpecifiers(moduleSymbol, program.getCompilerOptions(), sourceFile, host, program.getSourceFiles(), preferences); return modulePathsGroups.map(function (group) { return group.map(function (moduleSpecifier) { return ({ moduleSpecifier: moduleSpecifier, importKind: importKind }); }); }); }); return ts.flatten(choicesForEachExportingModule.sort(function (a, b) { return ts.first(a).moduleSpecifier.length - ts.first(b).moduleSpecifier.length; })); @@ -86620,262 +86922,6 @@ var ts; })(codefix = ts.codefix || (ts.codefix = {})); })(ts || (ts = {})); var ts; -(function (ts) { - var moduleSpecifiers; - (function (moduleSpecifiers) { - function getModuleSpecifier(program, fromSourceFile, fromSourceFileName, toFileName, host, preferences) { - var info = getInfo(program.getCompilerOptions(), fromSourceFile, fromSourceFileName, host); - var compilerOptions = program.getCompilerOptions(); - return getGlobalModuleSpecifier(toFileName, info, host, compilerOptions) || - ts.first(getLocalModuleSpecifiers(toFileName, info, compilerOptions, preferences)); - } - moduleSpecifiers.getModuleSpecifier = getModuleSpecifier; - function getModuleSpecifiers(moduleSymbol, program, importingSourceFile, host, preferences) { - var ambient = tryGetModuleNameFromAmbientModule(moduleSymbol); - if (ambient) - return [[ambient]]; - var compilerOptions = program.getCompilerOptions(); - var info = getInfo(compilerOptions, importingSourceFile, importingSourceFile.fileName, host); - var modulePaths = getAllModulePaths(program, moduleSymbol.valueDeclaration.getSourceFile()); - var global = ts.mapDefined(modulePaths, function (moduleFileName) { return getGlobalModuleSpecifier(moduleFileName, info, host, compilerOptions); }); - return global.length ? global.map(function (g) { return [g]; }) : modulePaths.map(function (moduleFileName) { - return getLocalModuleSpecifiers(moduleFileName, info, compilerOptions, preferences); - }); - } - moduleSpecifiers.getModuleSpecifiers = getModuleSpecifiers; - function getInfo(compilerOptions, importingSourceFile, importingSourceFileName, host) { - var moduleResolutionKind = ts.getEmitModuleResolutionKind(compilerOptions); - var addJsExtension = usesJsExtensionOnImports(importingSourceFile); - var getCanonicalFileName = ts.hostGetCanonicalFileName(host); - var sourceDirectory = ts.getDirectoryPath(importingSourceFileName); - return { moduleResolutionKind: moduleResolutionKind, addJsExtension: addJsExtension, getCanonicalFileName: getCanonicalFileName, sourceDirectory: sourceDirectory }; - } - function getGlobalModuleSpecifier(moduleFileName, _a, host, compilerOptions) { - var addJsExtension = _a.addJsExtension, getCanonicalFileName = _a.getCanonicalFileName, sourceDirectory = _a.sourceDirectory; - return tryGetModuleNameFromTypeRoots(compilerOptions, host, getCanonicalFileName, moduleFileName, addJsExtension) - || tryGetModuleNameAsNodeModule(compilerOptions, moduleFileName, host, getCanonicalFileName, sourceDirectory) - || compilerOptions.rootDirs && tryGetModuleNameFromRootDirs(compilerOptions.rootDirs, moduleFileName, sourceDirectory, getCanonicalFileName); - } - function getLocalModuleSpecifiers(moduleFileName, _a, compilerOptions, preferences) { - var moduleResolutionKind = _a.moduleResolutionKind, addJsExtension = _a.addJsExtension, getCanonicalFileName = _a.getCanonicalFileName, sourceDirectory = _a.sourceDirectory; - var baseUrl = compilerOptions.baseUrl, paths = compilerOptions.paths; - var relativePath = removeExtensionAndIndexPostFix(ts.ensurePathIsNonModuleName(ts.getRelativePathFromDirectory(sourceDirectory, moduleFileName, getCanonicalFileName)), moduleResolutionKind, addJsExtension); - if (!baseUrl || preferences.importModuleSpecifierPreference === "relative") { - return [relativePath]; - } - var relativeToBaseUrl = getRelativePathIfInDirectory(moduleFileName, baseUrl, getCanonicalFileName); - if (!relativeToBaseUrl) { - return [relativePath]; - } - var importRelativeToBaseUrl = removeExtensionAndIndexPostFix(relativeToBaseUrl, moduleResolutionKind, addJsExtension); - if (paths) { - var fromPaths = tryGetModuleNameFromPaths(ts.removeFileExtension(relativeToBaseUrl), importRelativeToBaseUrl, paths); - if (fromPaths) { - return [fromPaths]; - } - } - if (preferences.importModuleSpecifierPreference === "non-relative") { - return [importRelativeToBaseUrl]; - } - if (preferences.importModuleSpecifierPreference !== undefined) - ts.Debug.assertNever(preferences.importModuleSpecifierPreference); - if (isPathRelativeToParent(relativeToBaseUrl)) { - return [relativePath]; - } - var pathFromSourceToBaseUrl = ts.ensurePathIsNonModuleName(ts.getRelativePathFromDirectory(sourceDirectory, baseUrl, getCanonicalFileName)); - var relativeFirst = getRelativePathNParents(relativePath) < getRelativePathNParents(pathFromSourceToBaseUrl); - return relativeFirst ? [relativePath, importRelativeToBaseUrl] : [importRelativeToBaseUrl, relativePath]; - } - function usesJsExtensionOnImports(_a) { - var imports = _a.imports; - return ts.firstDefined(imports, function (_a) { - var text = _a.text; - return ts.pathIsRelative(text) ? ts.fileExtensionIs(text, ".js") : undefined; - }) || false; - } - function getAllModulePaths(program, _a) { - var fileName = _a.fileName; - var symlinks = ts.mapDefined(program.getSourceFiles(), function (sf) { - return sf.resolvedModules && ts.firstDefinedIterator(sf.resolvedModules.values(), function (res) { - return res && res.resolvedFileName === fileName ? res.originalPath : undefined; - }); - }); - return symlinks.length === 0 ? [fileName] : symlinks; - } - function getRelativePathNParents(relativePath) { - var components = ts.getPathComponents(relativePath); - if (components[0] || components.length === 1) - return 0; - for (var i = 1; i < components.length; i++) { - if (components[i] !== "..") - return i - 1; - } - return components.length - 1; - } - function tryGetModuleNameFromAmbientModule(moduleSymbol) { - var decl = moduleSymbol.valueDeclaration; - if (ts.isModuleDeclaration(decl) && ts.isStringLiteral(decl.name)) { - return decl.name.text; - } - } - function tryGetModuleNameFromPaths(relativeToBaseUrlWithIndex, relativeToBaseUrl, paths) { - for (var key in paths) { - for (var _i = 0, _a = paths[key]; _i < _a.length; _i++) { - var patternText_1 = _a[_i]; - var pattern = ts.removeFileExtension(ts.normalizePath(patternText_1)); - var indexOfStar = pattern.indexOf("*"); - if (indexOfStar === 0 && pattern.length === 1) { - continue; - } - else if (indexOfStar !== -1) { - var prefix = pattern.substr(0, indexOfStar); - var suffix = pattern.substr(indexOfStar + 1); - if (relativeToBaseUrl.length >= prefix.length + suffix.length && - ts.startsWith(relativeToBaseUrl, prefix) && - ts.endsWith(relativeToBaseUrl, suffix)) { - var matchedStar = relativeToBaseUrl.substr(prefix.length, relativeToBaseUrl.length - suffix.length); - return key.replace("*", matchedStar); - } - } - else if (pattern === relativeToBaseUrl || pattern === relativeToBaseUrlWithIndex) { - return key; - } - } - } - } - function tryGetModuleNameFromRootDirs(rootDirs, moduleFileName, sourceDirectory, getCanonicalFileName) { - var normalizedTargetPath = getPathRelativeToRootDirs(moduleFileName, rootDirs, getCanonicalFileName); - if (normalizedTargetPath === undefined) { - return undefined; - } - var normalizedSourcePath = getPathRelativeToRootDirs(sourceDirectory, rootDirs, getCanonicalFileName); - var relativePath = normalizedSourcePath !== undefined ? ts.ensurePathIsNonModuleName(ts.getRelativePathFromDirectory(normalizedSourcePath, normalizedTargetPath, getCanonicalFileName)) : normalizedTargetPath; - return ts.removeFileExtension(relativePath); - } - function tryGetModuleNameFromTypeRoots(options, host, getCanonicalFileName, moduleFileName, addJsExtension) { - var roots = ts.getEffectiveTypeRoots(options, host); - return ts.firstDefined(roots, function (unNormalizedTypeRoot) { - var typeRoot = ts.toPath(unNormalizedTypeRoot, undefined, getCanonicalFileName); - if (ts.startsWith(moduleFileName, typeRoot)) { - return removeExtensionAndIndexPostFix(moduleFileName.substring(typeRoot.length + 1), ts.ModuleResolutionKind.NodeJs, addJsExtension); - } - }); - } - function tryGetModuleNameAsNodeModule(options, moduleFileName, host, getCanonicalFileName, sourceDirectory) { - if (ts.getEmitModuleResolutionKind(options) !== ts.ModuleResolutionKind.NodeJs) { - return undefined; - } - var parts = getNodeModulePathParts(moduleFileName); - if (!parts) { - return undefined; - } - var moduleSpecifier = getDirectoryOrExtensionlessFileName(moduleFileName); - moduleSpecifier = getNodeResolvablePath(moduleSpecifier); - return ts.getPackageNameFromAtTypesDirectory(moduleSpecifier); - function getDirectoryOrExtensionlessFileName(path) { - var packageRootPath = path.substring(0, parts.packageRootIndex); - var packageJsonPath = ts.combinePaths(packageRootPath, "package.json"); - if (host.fileExists(packageJsonPath)) { - var packageJsonContent = JSON.parse(host.readFile(packageJsonPath)); - if (packageJsonContent) { - var mainFileRelative = packageJsonContent.typings || packageJsonContent.types || packageJsonContent.main; - if (mainFileRelative) { - var mainExportFile = ts.toPath(mainFileRelative, packageRootPath, getCanonicalFileName); - if (mainExportFile === getCanonicalFileName(path)) { - return packageRootPath; - } - } - } - } - var fullModulePathWithoutExtension = ts.removeFileExtension(path); - if (getCanonicalFileName(fullModulePathWithoutExtension.substring(parts.fileNameIndex)) === "/index") { - return fullModulePathWithoutExtension.substring(0, parts.fileNameIndex); - } - return fullModulePathWithoutExtension; - } - function getNodeResolvablePath(path) { - var basePath = path.substring(0, parts.topLevelNodeModulesIndex); - if (sourceDirectory.indexOf(basePath) === 0) { - return path.substring(parts.topLevelPackageNameIndex + 1); - } - else { - return ts.ensurePathIsNonModuleName(ts.getRelativePathFromDirectory(sourceDirectory, path, getCanonicalFileName)); - } - } - } - function getNodeModulePathParts(fullPath) { - var topLevelNodeModulesIndex = 0; - var topLevelPackageNameIndex = 0; - var packageRootIndex = 0; - var fileNameIndex = 0; - var States; - (function (States) { - States[States["BeforeNodeModules"] = 0] = "BeforeNodeModules"; - States[States["NodeModules"] = 1] = "NodeModules"; - States[States["Scope"] = 2] = "Scope"; - States[States["PackageContent"] = 3] = "PackageContent"; - })(States || (States = {})); - var partStart = 0; - var partEnd = 0; - var state = 0; - while (partEnd >= 0) { - partStart = partEnd; - partEnd = fullPath.indexOf("/", partStart + 1); - switch (state) { - case 0: - if (fullPath.indexOf("/node_modules/", partStart) === partStart) { - topLevelNodeModulesIndex = partStart; - topLevelPackageNameIndex = partEnd; - state = 1; - } - break; - case 1: - case 2: - if (state === 1 && fullPath.charAt(partStart + 1) === "@") { - state = 2; - } - else { - packageRootIndex = partEnd; - state = 3; - } - break; - case 3: - if (fullPath.indexOf("/node_modules/", partStart) === partStart) { - state = 1; - } - else { - state = 3; - } - break; - } - } - fileNameIndex = partStart; - return state > 1 ? { topLevelNodeModulesIndex: topLevelNodeModulesIndex, topLevelPackageNameIndex: topLevelPackageNameIndex, packageRootIndex: packageRootIndex, fileNameIndex: fileNameIndex } : undefined; - } - function getPathRelativeToRootDirs(path, rootDirs, getCanonicalFileName) { - return ts.firstDefined(rootDirs, function (rootDir) { - var relativePath = getRelativePathIfInDirectory(path, rootDir, getCanonicalFileName); - return isPathRelativeToParent(relativePath) ? undefined : relativePath; - }); - } - function removeExtensionAndIndexPostFix(fileName, moduleResolutionKind, addJsExtension) { - var noExtension = ts.removeFileExtension(fileName); - return addJsExtension - ? noExtension + ".js" - : moduleResolutionKind === ts.ModuleResolutionKind.NodeJs - ? ts.removeSuffix(noExtension, "/index") - : noExtension; - } - function getRelativePathIfInDirectory(path, directoryPath, getCanonicalFileName) { - var relativePath = ts.getRelativePathToDirectoryOrUrl(directoryPath, path, directoryPath, getCanonicalFileName, false); - return ts.isRootedDiskPath(relativePath) ? undefined : relativePath; - } - function isPathRelativeToParent(path) { - return ts.startsWith(path, ".."); - } - })(moduleSpecifiers = ts.moduleSpecifiers || (ts.moduleSpecifiers = {})); -})(ts || (ts = {})); -var ts; (function (ts) { var codefix; (function (codefix) { @@ -89089,7 +89135,7 @@ var ts; getGeneratedPosition: getGeneratedPosition }; function getGeneratedPosition(loc) { - var maps = getGeneratedOrderedMappings(); + var maps = getSourceOrderedMappings(); if (!ts.length(maps)) return loc; var targetIndex = ts.binarySearch(maps, { sourcePath: loc.fileName, sourcePosition: loc.position }, ts.identity, compareProcessedPositionSourcePositions); @@ -89102,7 +89148,7 @@ var ts; return { fileName: ts.toPath(map.file, sourceRoot, host.getCanonicalFileName), position: maps[targetIndex].emittedPosition }; } function getOriginalPosition(loc) { - var maps = getSourceOrderedMappings(); + var maps = getGeneratedOrderedMappings(); if (!ts.length(maps)) return loc; var targetIndex = ts.binarySearch(maps, { emittedPosition: loc.position }, ts.identity, compareProcessedPositionEmittedPositions); diff --git a/lib/tsserverlibrary.d.ts b/lib/tsserverlibrary.d.ts index cee46538461..d1db7480e57 100644 --- a/lib/tsserverlibrary.d.ts +++ b/lib/tsserverlibrary.d.ts @@ -2876,6 +2876,10 @@ declare namespace ts { omitTrailingSemicolon?: boolean; noEmitHelpers?: boolean; } + interface GetEffectiveTypeRootsHost { + directoryExists?(directoryName: string): boolean; + getCurrentDirectory?(): string; + } /** @deprecated See comment on SymbolWriter */ interface SymbolTracker { trackSymbol?(symbol: Symbol, enclosingDeclaration?: Node, meaning?: SymbolFlags): void; @@ -3463,10 +3467,6 @@ declare namespace ts { function updateSourceFile(sourceFile: SourceFile, newText: string, textChangeRange: TextChangeRange, aggressiveChecks?: boolean): SourceFile; } declare namespace ts { - interface GetEffectiveTypeRootsHost { - directoryExists?(directoryName: string): boolean; - getCurrentDirectory?(): string; - } function getEffectiveTypeRoots(options: CompilerOptions, host: GetEffectiveTypeRootsHost): string[] | undefined; /** * @param {string | undefined} containingFile - file that contains type reference directive, can be undefined if containing file is unknown. diff --git a/lib/tsserverlibrary.js b/lib/tsserverlibrary.js index 4ea0f4f7fdc..aa0992f731b 100644 --- a/lib/tsserverlibrary.js +++ b/lib/tsserverlibrary.js @@ -30235,7 +30235,8 @@ var ts; // ambient module, just use declaration/symbol name (fallthrough) } else { - return "\"" + ts.getResolvedExternalModuleName(context.tracker.moduleResolverHost, file_3, ts.getSourceFileOfNode(ts.getOriginalNode(context.enclosingDeclaration))) + "\""; + var contextFile = ts.getSourceFileOfNode(ts.getOriginalNode(context.enclosingDeclaration)); + return "\"" + (file_3.moduleName || ts.moduleSpecifiers.getModuleSpecifiers(symbol, compilerOptions, contextFile, context.tracker.moduleResolverHost, context.tracker.moduleResolverHost.getSourceFiles(), { importModuleSpecifierPreference: "non-relative" })[0]) + "\""; } } var declaration = symbol.declarations[0]; @@ -78966,20 +78967,8 @@ var ts; return oldProgram.structureIsReused = 2 /* Completely */; } function getEmitHost(writeFileCallback) { - return { - getPrependNodes: getPrependNodes, - getCanonicalFileName: getCanonicalFileName, - getCommonSourceDirectory: program.getCommonSourceDirectory, - getCompilerOptions: program.getCompilerOptions, - getCurrentDirectory: function () { return currentDirectory; }, - getNewLine: function () { return host.getNewLine(); }, - getSourceFile: program.getSourceFile, - getSourceFileByPath: program.getSourceFileByPath, - getSourceFiles: program.getSourceFiles, - isSourceFileFromExternalLibrary: isSourceFileFromExternalLibrary, - writeFile: writeFileCallback || (function (fileName, data, writeByteOrderMark, onError, sourceFiles) { return host.writeFile(fileName, data, writeByteOrderMark, onError, sourceFiles); }), - isEmitBlocked: isEmitBlocked, - }; + return __assign({ getPrependNodes: getPrependNodes, + getCanonicalFileName: getCanonicalFileName, getCommonSourceDirectory: program.getCommonSourceDirectory, getCompilerOptions: program.getCompilerOptions, getCurrentDirectory: function () { return currentDirectory; }, getNewLine: function () { return host.getNewLine(); }, getSourceFile: program.getSourceFile, getSourceFileByPath: program.getSourceFileByPath, getSourceFiles: program.getSourceFiles, isSourceFileFromExternalLibrary: isSourceFileFromExternalLibrary, writeFile: writeFileCallback || (function (fileName, data, writeByteOrderMark, onError, sourceFiles) { return host.writeFile(fileName, data, writeByteOrderMark, onError, sourceFiles); }), isEmitBlocked: isEmitBlocked, readFile: function (f) { return host.readFile(f); }, fileExists: function (f) { return host.fileExists(f); } }, (host.directoryExists ? { directoryExists: function (f) { return host.directoryExists(f); } } : {})); } function getProjectReferences() { if (!resolvedProjectReferences) @@ -81639,6 +81628,370 @@ var ts; } ts.createResolutionCache = createResolutionCache; })(ts || (ts = {})); +// Used by importFixes to synthesize import module specifiers. +/* @internal */ +var ts; +(function (ts) { + var moduleSpecifiers; + (function (moduleSpecifiers) { + // Note: fromSourceFile is just for usesJsExtensionOnImports + function getModuleSpecifier(compilerOptions, fromSourceFile, fromSourceFileName, toFileName, host, preferences) { + if (preferences === void 0) { preferences = {}; } + var info = getInfo(compilerOptions, fromSourceFile, fromSourceFileName, host); + return getGlobalModuleSpecifier(toFileName, info, host, compilerOptions) || + ts.first(getLocalModuleSpecifiers(toFileName, info, compilerOptions, preferences)); + } + moduleSpecifiers.getModuleSpecifier = getModuleSpecifier; + // For each symlink/original for a module, returns a list of ways to import that file. + function getModuleSpecifiers(moduleSymbol, compilerOptions, importingSourceFile, host, files, preferences) { + var ambient = tryGetModuleNameFromAmbientModule(moduleSymbol); + if (ambient) + return [[ambient]]; + var info = getInfo(compilerOptions, importingSourceFile, importingSourceFile.path, host); + if (!files) { + return ts.Debug.fail("Files list must be present to resolve symlinks in specifier resolution"); + } + var modulePaths = getAllModulePaths(files, ts.getSourceFileOfNode(moduleSymbol.valueDeclaration), info.getCanonicalFileName, host); + var global = ts.mapDefined(modulePaths, function (moduleFileName) { return getGlobalModuleSpecifier(moduleFileName, info, host, compilerOptions); }); + return global.length ? global.map(function (g) { return [g]; }) : modulePaths.map(function (moduleFileName) { + return getLocalModuleSpecifiers(moduleFileName, info, compilerOptions, preferences); + }); + } + moduleSpecifiers.getModuleSpecifiers = getModuleSpecifiers; + // importingSourceFileName is separate because getEditsForFileRename may need to specify an updated path + function getInfo(compilerOptions, importingSourceFile, importingSourceFileName, host) { + var moduleResolutionKind = ts.getEmitModuleResolutionKind(compilerOptions); + var addJsExtension = usesJsExtensionOnImports(importingSourceFile); + var getCanonicalFileName = ts.createGetCanonicalFileName(host.useCaseSensitiveFileNames ? host.useCaseSensitiveFileNames() : true); + var sourceDirectory = ts.getDirectoryPath(importingSourceFileName); + return { moduleResolutionKind: moduleResolutionKind, addJsExtension: addJsExtension, getCanonicalFileName: getCanonicalFileName, sourceDirectory: sourceDirectory }; + } + function getGlobalModuleSpecifier(moduleFileName, _a, host, compilerOptions) { + var addJsExtension = _a.addJsExtension, getCanonicalFileName = _a.getCanonicalFileName, sourceDirectory = _a.sourceDirectory; + return tryGetModuleNameFromTypeRoots(compilerOptions, host, getCanonicalFileName, moduleFileName, addJsExtension) + || tryGetModuleNameAsNodeModule(compilerOptions, moduleFileName, host, getCanonicalFileName, sourceDirectory) + || compilerOptions.rootDirs && tryGetModuleNameFromRootDirs(compilerOptions.rootDirs, moduleFileName, sourceDirectory, getCanonicalFileName); + } + function getLocalModuleSpecifiers(moduleFileName, _a, compilerOptions, preferences) { + var moduleResolutionKind = _a.moduleResolutionKind, addJsExtension = _a.addJsExtension, getCanonicalFileName = _a.getCanonicalFileName, sourceDirectory = _a.sourceDirectory; + var baseUrl = compilerOptions.baseUrl, paths = compilerOptions.paths; + var relativePath = removeExtensionAndIndexPostFix(ts.ensurePathIsNonModuleName(ts.getRelativePathFromDirectory(sourceDirectory, moduleFileName, getCanonicalFileName)), moduleResolutionKind, addJsExtension); + if (!baseUrl || preferences.importModuleSpecifierPreference === "relative") { + return [relativePath]; + } + var relativeToBaseUrl = getRelativePathIfInDirectory(moduleFileName, baseUrl, getCanonicalFileName); + if (!relativeToBaseUrl) { + return [relativePath]; + } + var importRelativeToBaseUrl = removeExtensionAndIndexPostFix(relativeToBaseUrl, moduleResolutionKind, addJsExtension); + if (paths) { + var fromPaths = tryGetModuleNameFromPaths(ts.removeFileExtension(relativeToBaseUrl), importRelativeToBaseUrl, paths); + if (fromPaths) { + return [fromPaths]; + } + } + if (preferences.importModuleSpecifierPreference === "non-relative") { + return [importRelativeToBaseUrl]; + } + if (preferences.importModuleSpecifierPreference !== undefined) + ts.Debug.assertNever(preferences.importModuleSpecifierPreference); + if (isPathRelativeToParent(relativeToBaseUrl)) { + return [relativePath]; + } + /* + Prefer a relative import over a baseUrl import if it doesn't traverse up to baseUrl. + + Suppose we have: + baseUrl = /base + sourceDirectory = /base/a/b + moduleFileName = /base/foo/bar + Then: + relativePath = ../../foo/bar + getRelativePathNParents(relativePath) = 2 + pathFromSourceToBaseUrl = ../../ + getRelativePathNParents(pathFromSourceToBaseUrl) = 2 + 2 < 2 = false + In this case we should prefer using the baseUrl path "/a/b" instead of the relative path "../../foo/bar". + + Suppose we have: + baseUrl = /base + sourceDirectory = /base/foo/a + moduleFileName = /base/foo/bar + Then: + relativePath = ../a + getRelativePathNParents(relativePath) = 1 + pathFromSourceToBaseUrl = ../../ + getRelativePathNParents(pathFromSourceToBaseUrl) = 2 + 1 < 2 = true + In this case we should prefer using the relative path "../a" instead of the baseUrl path "foo/a". + */ + var pathFromSourceToBaseUrl = ts.ensurePathIsNonModuleName(ts.getRelativePathFromDirectory(sourceDirectory, baseUrl, getCanonicalFileName)); + var relativeFirst = getRelativePathNParents(relativePath) < getRelativePathNParents(pathFromSourceToBaseUrl); + return relativeFirst ? [relativePath, importRelativeToBaseUrl] : [importRelativeToBaseUrl, relativePath]; + } + function usesJsExtensionOnImports(_a) { + var imports = _a.imports; + return ts.firstDefined(imports, function (_a) { + var text = _a.text; + return ts.pathIsRelative(text) ? ts.fileExtensionIs(text, ".js" /* Js */) : undefined; + }) || false; + } + function discoverProbableSymlinks(files) { + var symlinks = ts.mapDefined(files, function (sf) { + return sf.resolvedModules && ts.firstDefinedIterator(sf.resolvedModules.values(), function (res) { + return res && res.originalPath && res.resolvedFileName !== res.originalPath ? [res.resolvedFileName, res.originalPath] : undefined; + }); + }); + var result = ts.createMap(); + if (symlinks) { + for (var _i = 0, symlinks_1 = symlinks; _i < symlinks_1.length; _i++) { + var _a = symlinks_1[_i], resolvedPath = _a[0], originalPath = _a[1]; + var resolvedParts = ts.getPathComponents(resolvedPath); + var originalParts = ts.getPathComponents(originalPath); + while (resolvedParts[resolvedParts.length - 1] === originalParts[originalParts.length - 1]) { + resolvedParts.pop(); + originalParts.pop(); + } + result.set(ts.getPathFromPathComponents(originalParts), ts.getPathFromPathComponents(resolvedParts)); + } + } + return result; + } + function getAllModulePathsUsingIndirectSymlinks(files, target, getCanonicalFileName, host) { + var links = discoverProbableSymlinks(files); + var paths = ts.arrayFrom(links.keys()); + var options; + for (var _i = 0, paths_2 = paths; _i < paths_2.length; _i++) { + var path = paths_2[_i]; + var resolved = links.get(path); + if (ts.startsWith(target, resolved + "/")) { + var relative = ts.getRelativePathFromDirectory(resolved, target, getCanonicalFileName); + var option = ts.resolvePath(path, relative); + if (!host.fileExists || host.fileExists(option)) { + if (!options) + options = []; + options.push(option); + } + } + } + var resolvedtarget = host.getCurrentDirectory ? ts.resolvePath(host.getCurrentDirectory(), target) : target; + if (options) { + options.push(resolvedtarget); // Since these are speculative, we also include the original resolved name as a possibility + return options; + } + return [resolvedtarget]; + } + /** + * Looks for a existing imports that use symlinks to this module. + * Only if no symlink is available, the real path will be used. + */ + function getAllModulePaths(files, _a, getCanonicalFileName, host) { + var fileName = _a.fileName; + var symlinks = ts.mapDefined(files, function (sf) { + return sf.resolvedModules && ts.firstDefinedIterator(sf.resolvedModules.values(), function (res) { + return res && res.resolvedFileName === fileName ? res.originalPath : undefined; + }); + }); + return symlinks.length === 0 ? getAllModulePathsUsingIndirectSymlinks(files, fileName, getCanonicalFileName, host) : symlinks; + } + function getRelativePathNParents(relativePath) { + var components = ts.getPathComponents(relativePath); + if (components[0] || components.length === 1) + return 0; + for (var i = 1; i < components.length; i++) { + if (components[i] !== "..") + return i - 1; + } + return components.length - 1; + } + function tryGetModuleNameFromAmbientModule(moduleSymbol) { + var decl = moduleSymbol.valueDeclaration; + if (ts.isModuleDeclaration(decl) && ts.isStringLiteral(decl.name)) { + return decl.name.text; + } + } + function tryGetModuleNameFromPaths(relativeToBaseUrlWithIndex, relativeToBaseUrl, paths) { + for (var key in paths) { + for (var _i = 0, _a = paths[key]; _i < _a.length; _i++) { + var patternText_1 = _a[_i]; + var pattern = ts.removeFileExtension(ts.normalizePath(patternText_1)); + var indexOfStar = pattern.indexOf("*"); + if (indexOfStar === 0 && pattern.length === 1) { + continue; + } + else if (indexOfStar !== -1) { + var prefix = pattern.substr(0, indexOfStar); + var suffix = pattern.substr(indexOfStar + 1); + if (relativeToBaseUrl.length >= prefix.length + suffix.length && + ts.startsWith(relativeToBaseUrl, prefix) && + ts.endsWith(relativeToBaseUrl, suffix)) { + var matchedStar = relativeToBaseUrl.substr(prefix.length, relativeToBaseUrl.length - suffix.length); + return key.replace("*", matchedStar); + } + } + else if (pattern === relativeToBaseUrl || pattern === relativeToBaseUrlWithIndex) { + return key; + } + } + } + } + function tryGetModuleNameFromRootDirs(rootDirs, moduleFileName, sourceDirectory, getCanonicalFileName) { + var normalizedTargetPath = getPathRelativeToRootDirs(moduleFileName, rootDirs, getCanonicalFileName); + if (normalizedTargetPath === undefined) { + return undefined; + } + var normalizedSourcePath = getPathRelativeToRootDirs(sourceDirectory, rootDirs, getCanonicalFileName); + var relativePath = normalizedSourcePath !== undefined ? ts.ensurePathIsNonModuleName(ts.getRelativePathFromDirectory(normalizedSourcePath, normalizedTargetPath, getCanonicalFileName)) : normalizedTargetPath; + return ts.removeFileExtension(relativePath); + } + function tryGetModuleNameFromTypeRoots(options, host, getCanonicalFileName, moduleFileName, addJsExtension) { + var roots = ts.getEffectiveTypeRoots(options, host); + return ts.firstDefined(roots, function (unNormalizedTypeRoot) { + var typeRoot = ts.toPath(unNormalizedTypeRoot, /*basePath*/ undefined, getCanonicalFileName); + if (ts.startsWith(moduleFileName, typeRoot)) { + // For a type definition, we can strip `/index` even with classic resolution. + return removeExtensionAndIndexPostFix(moduleFileName.substring(typeRoot.length + 1), ts.ModuleResolutionKind.NodeJs, addJsExtension); + } + }); + } + function tryGetModuleNameAsNodeModule(options, moduleFileName, host, getCanonicalFileName, sourceDirectory) { + if (ts.getEmitModuleResolutionKind(options) !== ts.ModuleResolutionKind.NodeJs) { + // nothing to do here + return undefined; + } + var parts = getNodeModulePathParts(moduleFileName); + if (!parts) { + return undefined; + } + // Simplify the full file path to something that can be resolved by Node. + // If the module could be imported by a directory name, use that directory's name + var moduleSpecifier = getDirectoryOrExtensionlessFileName(moduleFileName); + // Get a path that's relative to node_modules or the importing file's path + moduleSpecifier = getNodeResolvablePath(moduleSpecifier); + // If the module was found in @types, get the actual Node package name + return ts.getPackageNameFromAtTypesDirectory(moduleSpecifier); + function getDirectoryOrExtensionlessFileName(path) { + // If the file is the main module, it can be imported by the package name + var packageRootPath = path.substring(0, parts.packageRootIndex); + var packageJsonPath = ts.combinePaths(packageRootPath, "package.json"); + if (host.fileExists(packageJsonPath)) { + var packageJsonContent = JSON.parse(host.readFile(packageJsonPath)); + if (packageJsonContent) { + var mainFileRelative = packageJsonContent.typings || packageJsonContent.types || packageJsonContent.main; + if (mainFileRelative) { + var mainExportFile = ts.toPath(mainFileRelative, packageRootPath, getCanonicalFileName); + if (mainExportFile === getCanonicalFileName(path)) { + return packageRootPath; + } + } + } + } + // We still have a file name - remove the extension + var fullModulePathWithoutExtension = ts.removeFileExtension(path); + // If the file is /index, it can be imported by its directory name + // IFF there is not _also_ a file by the same name + if (getCanonicalFileName(fullModulePathWithoutExtension.substring(parts.fileNameIndex)) === "/index" && !tryGetAnyFileFromPath(host, fullModulePathWithoutExtension.substring(0, parts.fileNameIndex))) { + return fullModulePathWithoutExtension.substring(0, parts.fileNameIndex); + } + return fullModulePathWithoutExtension; + } + function getNodeResolvablePath(path) { + var basePath = path.substring(0, parts.topLevelNodeModulesIndex); + if (sourceDirectory.indexOf(basePath) === 0) { + // if node_modules folder is in this folder or any of its parent folders, no need to keep it. + return path.substring(parts.topLevelPackageNameIndex + 1); + } + else { + return ts.ensurePathIsNonModuleName(ts.getRelativePathFromDirectory(sourceDirectory, path, getCanonicalFileName)); + } + } + } + function tryGetAnyFileFromPath(host, path) { + // We check all js, `node` and `json` extensions in addition to TS, since node module resolution would also choose those over the directory + var extensions = ts.getSupportedExtensions({ allowJs: true }, [{ extension: "node", isMixedContent: false }, { extension: "json", isMixedContent: false, scriptKind: 6 /* JSON */ }]); + for (var _i = 0, extensions_3 = extensions; _i < extensions_3.length; _i++) { + var e = extensions_3[_i]; + var fullPath = path + e; + if (host.fileExists(fullPath)) { // TODO: GH#18217 + return fullPath; + } + } + } + function getNodeModulePathParts(fullPath) { + // 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: ^ ^ ^ ^ + var topLevelNodeModulesIndex = 0; + var topLevelPackageNameIndex = 0; + var packageRootIndex = 0; + var fileNameIndex = 0; + var States; + (function (States) { + States[States["BeforeNodeModules"] = 0] = "BeforeNodeModules"; + States[States["NodeModules"] = 1] = "NodeModules"; + States[States["Scope"] = 2] = "Scope"; + States[States["PackageContent"] = 3] = "PackageContent"; + })(States || (States = {})); + var partStart = 0; + var partEnd = 0; + var state = 0 /* BeforeNodeModules */; + while (partEnd >= 0) { + partStart = partEnd; + partEnd = fullPath.indexOf("/", partStart + 1); + switch (state) { + case 0 /* BeforeNodeModules */: + if (fullPath.indexOf("/node_modules/", partStart) === partStart) { + topLevelNodeModulesIndex = partStart; + topLevelPackageNameIndex = partEnd; + state = 1 /* NodeModules */; + } + break; + case 1 /* NodeModules */: + case 2 /* Scope */: + if (state === 1 /* NodeModules */ && fullPath.charAt(partStart + 1) === "@") { + state = 2 /* Scope */; + } + else { + packageRootIndex = partEnd; + state = 3 /* PackageContent */; + } + break; + case 3 /* PackageContent */: + if (fullPath.indexOf("/node_modules/", partStart) === partStart) { + state = 1 /* NodeModules */; + } + else { + state = 3 /* PackageContent */; + } + break; + } + } + fileNameIndex = partStart; + return state > 1 /* NodeModules */ ? { topLevelNodeModulesIndex: topLevelNodeModulesIndex, topLevelPackageNameIndex: topLevelPackageNameIndex, packageRootIndex: packageRootIndex, fileNameIndex: fileNameIndex } : undefined; + } + function getPathRelativeToRootDirs(path, rootDirs, getCanonicalFileName) { + return ts.firstDefined(rootDirs, function (rootDir) { + var relativePath = getRelativePathIfInDirectory(path, rootDir, getCanonicalFileName); + return isPathRelativeToParent(relativePath) ? undefined : relativePath; + }); + } + function removeExtensionAndIndexPostFix(fileName, moduleResolutionKind, addJsExtension) { + var noExtension = ts.removeFileExtension(fileName); + return addJsExtension + ? noExtension + ".js" + : moduleResolutionKind === ts.ModuleResolutionKind.NodeJs + ? ts.removeSuffix(noExtension, "/index") + : noExtension; + } + function getRelativePathIfInDirectory(path, directoryPath, getCanonicalFileName) { + var relativePath = ts.getRelativePathToDirectoryOrUrl(directoryPath, path, directoryPath, getCanonicalFileName, /*isAbsolutePathAnUrl*/ false); + return ts.isRootedDiskPath(relativePath) ? undefined : relativePath; + } + function isPathRelativeToParent(path) { + return ts.startsWith(path, ".."); + } + })(moduleSpecifiers = ts.moduleSpecifiers || (ts.moduleSpecifiers = {})); +})(ts || (ts = {})); /*@internal*/ var ts; (function (ts) { @@ -92141,7 +92494,7 @@ var ts; // TODO:GH#18217 ? getSourceFileToImportFromResolved(ts.resolveModuleName(importLiteral.text, oldImportFromPath, program.getCompilerOptions(), host), oldToNew, program) : getSourceFileToImport(importLiteral, sourceFile, program, host, oldToNew); - return toImport === undefined ? undefined : ts.moduleSpecifiers.getModuleSpecifier(program, sourceFile, newImportFromPath, toImport, host, preferences); + return toImport === undefined ? undefined : ts.moduleSpecifiers.getModuleSpecifier(program.getCompilerOptions(), sourceFile, newImportFromPath, toImport, host, preferences); }); }; for (var _i = 0, _a = program.getSourceFiles(); _i < _a.length; _i++) { @@ -95616,7 +95969,7 @@ var ts; ts.Debug.assert(indexOfOpenerToken >= 0 && children.length > indexOfOpenerToken + 1); return children[indexOfOpenerToken + 1]; } - var signatureHelpNodeBuilderFlags = 8192 /* OmitParameterModifiers */ | 3112960 /* IgnoreErrors */; + var signatureHelpNodeBuilderFlags = 8192 /* OmitParameterModifiers */ | 3112960 /* IgnoreErrors */ | 16384 /* UseAliasDefinedOutsideCurrentScope */; function createSignatureHelpItems(candidates, resolvedSignature, argumentListInfo, typeChecker) { var argumentCount = argumentListInfo.argumentCount, applicableSpan = argumentListInfo.argumentsSpan, invocation = argumentListInfo.invocation, argumentIndex = argumentListInfo.argumentIndex; var isTypeParameterList = argumentListInfo.kind === 0 /* TypeArguments */; @@ -101216,7 +101569,7 @@ var ts; function getNewImportInfos(program, sourceFile, moduleSymbols, host, preferences) { var choicesForEachExportingModule = ts.flatMap(moduleSymbols, function (_a) { var moduleSymbol = _a.moduleSymbol, importKind = _a.importKind; - var modulePathsGroups = ts.moduleSpecifiers.getModuleSpecifiers(moduleSymbol, program, sourceFile, host, preferences); + var modulePathsGroups = ts.moduleSpecifiers.getModuleSpecifiers(moduleSymbol, program.getCompilerOptions(), sourceFile, host, program.getSourceFiles(), preferences); return modulePathsGroups.map(function (group) { return group.map(function (moduleSpecifier) { return ({ moduleSpecifier: moduleSpecifier, importKind: importKind }); }); }); }); // Sort to keep the shortest paths first, but keep [relativePath, importRelativeToBaseUrl] groups together @@ -103580,311 +103933,6 @@ var ts; } })(codefix = ts.codefix || (ts.codefix = {})); })(ts || (ts = {})); -// Used by importFixes to synthesize import module specifiers. -/* @internal */ -var ts; -(function (ts) { - var moduleSpecifiers; - (function (moduleSpecifiers) { - // Note: fromSourceFile is just for usesJsExtensionOnImports - function getModuleSpecifier(program, fromSourceFile, fromSourceFileName, toFileName, host, preferences) { - var info = getInfo(program.getCompilerOptions(), fromSourceFile, fromSourceFileName, host); - var compilerOptions = program.getCompilerOptions(); - return getGlobalModuleSpecifier(toFileName, info, host, compilerOptions) || - ts.first(getLocalModuleSpecifiers(toFileName, info, compilerOptions, preferences)); - } - moduleSpecifiers.getModuleSpecifier = getModuleSpecifier; - // For each symlink/original for a module, returns a list of ways to import that file. - function getModuleSpecifiers(moduleSymbol, program, importingSourceFile, host, preferences) { - var ambient = tryGetModuleNameFromAmbientModule(moduleSymbol); - if (ambient) - return [[ambient]]; - var compilerOptions = program.getCompilerOptions(); - var info = getInfo(compilerOptions, importingSourceFile, importingSourceFile.fileName, host); - var modulePaths = getAllModulePaths(program, moduleSymbol.valueDeclaration.getSourceFile()); - var global = ts.mapDefined(modulePaths, function (moduleFileName) { return getGlobalModuleSpecifier(moduleFileName, info, host, compilerOptions); }); - return global.length ? global.map(function (g) { return [g]; }) : modulePaths.map(function (moduleFileName) { - return getLocalModuleSpecifiers(moduleFileName, info, compilerOptions, preferences); - }); - } - moduleSpecifiers.getModuleSpecifiers = getModuleSpecifiers; - // importingSourceFileName is separate because getEditsForFileRename may need to specify an updated path - function getInfo(compilerOptions, importingSourceFile, importingSourceFileName, host) { - var moduleResolutionKind = ts.getEmitModuleResolutionKind(compilerOptions); - var addJsExtension = usesJsExtensionOnImports(importingSourceFile); - var getCanonicalFileName = ts.hostGetCanonicalFileName(host); - var sourceDirectory = ts.getDirectoryPath(importingSourceFileName); - return { moduleResolutionKind: moduleResolutionKind, addJsExtension: addJsExtension, getCanonicalFileName: getCanonicalFileName, sourceDirectory: sourceDirectory }; - } - function getGlobalModuleSpecifier(moduleFileName, _a, host, compilerOptions) { - var addJsExtension = _a.addJsExtension, getCanonicalFileName = _a.getCanonicalFileName, sourceDirectory = _a.sourceDirectory; - return tryGetModuleNameFromTypeRoots(compilerOptions, host, getCanonicalFileName, moduleFileName, addJsExtension) - || tryGetModuleNameAsNodeModule(compilerOptions, moduleFileName, host, getCanonicalFileName, sourceDirectory) - || compilerOptions.rootDirs && tryGetModuleNameFromRootDirs(compilerOptions.rootDirs, moduleFileName, sourceDirectory, getCanonicalFileName); - } - function getLocalModuleSpecifiers(moduleFileName, _a, compilerOptions, preferences) { - var moduleResolutionKind = _a.moduleResolutionKind, addJsExtension = _a.addJsExtension, getCanonicalFileName = _a.getCanonicalFileName, sourceDirectory = _a.sourceDirectory; - var baseUrl = compilerOptions.baseUrl, paths = compilerOptions.paths; - var relativePath = removeExtensionAndIndexPostFix(ts.ensurePathIsNonModuleName(ts.getRelativePathFromDirectory(sourceDirectory, moduleFileName, getCanonicalFileName)), moduleResolutionKind, addJsExtension); - if (!baseUrl || preferences.importModuleSpecifierPreference === "relative") { - return [relativePath]; - } - var relativeToBaseUrl = getRelativePathIfInDirectory(moduleFileName, baseUrl, getCanonicalFileName); - if (!relativeToBaseUrl) { - return [relativePath]; - } - var importRelativeToBaseUrl = removeExtensionAndIndexPostFix(relativeToBaseUrl, moduleResolutionKind, addJsExtension); - if (paths) { - var fromPaths = tryGetModuleNameFromPaths(ts.removeFileExtension(relativeToBaseUrl), importRelativeToBaseUrl, paths); - if (fromPaths) { - return [fromPaths]; - } - } - if (preferences.importModuleSpecifierPreference === "non-relative") { - return [importRelativeToBaseUrl]; - } - if (preferences.importModuleSpecifierPreference !== undefined) - ts.Debug.assertNever(preferences.importModuleSpecifierPreference); - if (isPathRelativeToParent(relativeToBaseUrl)) { - return [relativePath]; - } - /* - Prefer a relative import over a baseUrl import if it doesn't traverse up to baseUrl. - - Suppose we have: - baseUrl = /base - sourceDirectory = /base/a/b - moduleFileName = /base/foo/bar - Then: - relativePath = ../../foo/bar - getRelativePathNParents(relativePath) = 2 - pathFromSourceToBaseUrl = ../../ - getRelativePathNParents(pathFromSourceToBaseUrl) = 2 - 2 < 2 = false - In this case we should prefer using the baseUrl path "/a/b" instead of the relative path "../../foo/bar". - - Suppose we have: - baseUrl = /base - sourceDirectory = /base/foo/a - moduleFileName = /base/foo/bar - Then: - relativePath = ../a - getRelativePathNParents(relativePath) = 1 - pathFromSourceToBaseUrl = ../../ - getRelativePathNParents(pathFromSourceToBaseUrl) = 2 - 1 < 2 = true - In this case we should prefer using the relative path "../a" instead of the baseUrl path "foo/a". - */ - var pathFromSourceToBaseUrl = ts.ensurePathIsNonModuleName(ts.getRelativePathFromDirectory(sourceDirectory, baseUrl, getCanonicalFileName)); - var relativeFirst = getRelativePathNParents(relativePath) < getRelativePathNParents(pathFromSourceToBaseUrl); - return relativeFirst ? [relativePath, importRelativeToBaseUrl] : [importRelativeToBaseUrl, relativePath]; - } - function usesJsExtensionOnImports(_a) { - var imports = _a.imports; - return ts.firstDefined(imports, function (_a) { - var text = _a.text; - return ts.pathIsRelative(text) ? ts.fileExtensionIs(text, ".js" /* Js */) : undefined; - }) || false; - } - /** - * Looks for a existing imports that use symlinks to this module. - * Only if no symlink is available, the real path will be used. - */ - function getAllModulePaths(program, _a) { - var fileName = _a.fileName; - var symlinks = ts.mapDefined(program.getSourceFiles(), function (sf) { - return sf.resolvedModules && ts.firstDefinedIterator(sf.resolvedModules.values(), function (res) { - return res && res.resolvedFileName === fileName ? res.originalPath : undefined; - }); - }); - return symlinks.length === 0 ? [fileName] : symlinks; - } - function getRelativePathNParents(relativePath) { - var components = ts.getPathComponents(relativePath); - if (components[0] || components.length === 1) - return 0; - for (var i = 1; i < components.length; i++) { - if (components[i] !== "..") - return i - 1; - } - return components.length - 1; - } - function tryGetModuleNameFromAmbientModule(moduleSymbol) { - var decl = moduleSymbol.valueDeclaration; - if (ts.isModuleDeclaration(decl) && ts.isStringLiteral(decl.name)) { - return decl.name.text; - } - } - function tryGetModuleNameFromPaths(relativeToBaseUrlWithIndex, relativeToBaseUrl, paths) { - for (var key in paths) { - for (var _i = 0, _a = paths[key]; _i < _a.length; _i++) { - var patternText_1 = _a[_i]; - var pattern = ts.removeFileExtension(ts.normalizePath(patternText_1)); - var indexOfStar = pattern.indexOf("*"); - if (indexOfStar === 0 && pattern.length === 1) { - continue; - } - else if (indexOfStar !== -1) { - var prefix = pattern.substr(0, indexOfStar); - var suffix = pattern.substr(indexOfStar + 1); - if (relativeToBaseUrl.length >= prefix.length + suffix.length && - ts.startsWith(relativeToBaseUrl, prefix) && - ts.endsWith(relativeToBaseUrl, suffix)) { - var matchedStar = relativeToBaseUrl.substr(prefix.length, relativeToBaseUrl.length - suffix.length); - return key.replace("*", matchedStar); - } - } - else if (pattern === relativeToBaseUrl || pattern === relativeToBaseUrlWithIndex) { - return key; - } - } - } - } - function tryGetModuleNameFromRootDirs(rootDirs, moduleFileName, sourceDirectory, getCanonicalFileName) { - var normalizedTargetPath = getPathRelativeToRootDirs(moduleFileName, rootDirs, getCanonicalFileName); - if (normalizedTargetPath === undefined) { - return undefined; - } - var normalizedSourcePath = getPathRelativeToRootDirs(sourceDirectory, rootDirs, getCanonicalFileName); - var relativePath = normalizedSourcePath !== undefined ? ts.ensurePathIsNonModuleName(ts.getRelativePathFromDirectory(normalizedSourcePath, normalizedTargetPath, getCanonicalFileName)) : normalizedTargetPath; - return ts.removeFileExtension(relativePath); - } - function tryGetModuleNameFromTypeRoots(options, host, getCanonicalFileName, moduleFileName, addJsExtension) { - var roots = ts.getEffectiveTypeRoots(options, host); - return ts.firstDefined(roots, function (unNormalizedTypeRoot) { - var typeRoot = ts.toPath(unNormalizedTypeRoot, /*basePath*/ undefined, getCanonicalFileName); - if (ts.startsWith(moduleFileName, typeRoot)) { - // For a type definition, we can strip `/index` even with classic resolution. - return removeExtensionAndIndexPostFix(moduleFileName.substring(typeRoot.length + 1), ts.ModuleResolutionKind.NodeJs, addJsExtension); - } - }); - } - function tryGetModuleNameAsNodeModule(options, moduleFileName, host, getCanonicalFileName, sourceDirectory) { - if (ts.getEmitModuleResolutionKind(options) !== ts.ModuleResolutionKind.NodeJs) { - // nothing to do here - return undefined; - } - var parts = getNodeModulePathParts(moduleFileName); - if (!parts) { - return undefined; - } - // Simplify the full file path to something that can be resolved by Node. - // If the module could be imported by a directory name, use that directory's name - var moduleSpecifier = getDirectoryOrExtensionlessFileName(moduleFileName); - // Get a path that's relative to node_modules or the importing file's path - moduleSpecifier = getNodeResolvablePath(moduleSpecifier); - // If the module was found in @types, get the actual Node package name - return ts.getPackageNameFromAtTypesDirectory(moduleSpecifier); - function getDirectoryOrExtensionlessFileName(path) { - // If the file is the main module, it can be imported by the package name - var packageRootPath = path.substring(0, parts.packageRootIndex); - var packageJsonPath = ts.combinePaths(packageRootPath, "package.json"); - if (host.fileExists(packageJsonPath)) { - var packageJsonContent = JSON.parse(host.readFile(packageJsonPath)); - if (packageJsonContent) { - var mainFileRelative = packageJsonContent.typings || packageJsonContent.types || packageJsonContent.main; - if (mainFileRelative) { - var mainExportFile = ts.toPath(mainFileRelative, packageRootPath, getCanonicalFileName); - if (mainExportFile === getCanonicalFileName(path)) { - return packageRootPath; - } - } - } - } - // We still have a file name - remove the extension - var fullModulePathWithoutExtension = ts.removeFileExtension(path); - // If the file is /index, it can be imported by its directory name - if (getCanonicalFileName(fullModulePathWithoutExtension.substring(parts.fileNameIndex)) === "/index") { - return fullModulePathWithoutExtension.substring(0, parts.fileNameIndex); - } - return fullModulePathWithoutExtension; - } - function getNodeResolvablePath(path) { - var basePath = path.substring(0, parts.topLevelNodeModulesIndex); - if (sourceDirectory.indexOf(basePath) === 0) { - // if node_modules folder is in this folder or any of its parent folders, no need to keep it. - return path.substring(parts.topLevelPackageNameIndex + 1); - } - else { - return ts.ensurePathIsNonModuleName(ts.getRelativePathFromDirectory(sourceDirectory, path, getCanonicalFileName)); - } - } - } - function getNodeModulePathParts(fullPath) { - // 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: ^ ^ ^ ^ - var topLevelNodeModulesIndex = 0; - var topLevelPackageNameIndex = 0; - var packageRootIndex = 0; - var fileNameIndex = 0; - var States; - (function (States) { - States[States["BeforeNodeModules"] = 0] = "BeforeNodeModules"; - States[States["NodeModules"] = 1] = "NodeModules"; - States[States["Scope"] = 2] = "Scope"; - States[States["PackageContent"] = 3] = "PackageContent"; - })(States || (States = {})); - var partStart = 0; - var partEnd = 0; - var state = 0 /* BeforeNodeModules */; - while (partEnd >= 0) { - partStart = partEnd; - partEnd = fullPath.indexOf("/", partStart + 1); - switch (state) { - case 0 /* BeforeNodeModules */: - if (fullPath.indexOf("/node_modules/", partStart) === partStart) { - topLevelNodeModulesIndex = partStart; - topLevelPackageNameIndex = partEnd; - state = 1 /* NodeModules */; - } - break; - case 1 /* NodeModules */: - case 2 /* Scope */: - if (state === 1 /* NodeModules */ && fullPath.charAt(partStart + 1) === "@") { - state = 2 /* Scope */; - } - else { - packageRootIndex = partEnd; - state = 3 /* PackageContent */; - } - break; - case 3 /* PackageContent */: - if (fullPath.indexOf("/node_modules/", partStart) === partStart) { - state = 1 /* NodeModules */; - } - else { - state = 3 /* PackageContent */; - } - break; - } - } - fileNameIndex = partStart; - return state > 1 /* NodeModules */ ? { topLevelNodeModulesIndex: topLevelNodeModulesIndex, topLevelPackageNameIndex: topLevelPackageNameIndex, packageRootIndex: packageRootIndex, fileNameIndex: fileNameIndex } : undefined; - } - function getPathRelativeToRootDirs(path, rootDirs, getCanonicalFileName) { - return ts.firstDefined(rootDirs, function (rootDir) { - var relativePath = getRelativePathIfInDirectory(path, rootDir, getCanonicalFileName); - return isPathRelativeToParent(relativePath) ? undefined : relativePath; - }); - } - function removeExtensionAndIndexPostFix(fileName, moduleResolutionKind, addJsExtension) { - var noExtension = ts.removeFileExtension(fileName); - return addJsExtension - ? noExtension + ".js" - : moduleResolutionKind === ts.ModuleResolutionKind.NodeJs - ? ts.removeSuffix(noExtension, "/index") - : noExtension; - } - function getRelativePathIfInDirectory(path, directoryPath, getCanonicalFileName) { - var relativePath = ts.getRelativePathToDirectoryOrUrl(directoryPath, path, directoryPath, getCanonicalFileName, /*isAbsolutePathAnUrl*/ false); - return ts.isRootedDiskPath(relativePath) ? undefined : relativePath; - } - function isPathRelativeToParent(path) { - return ts.startsWith(path, ".."); - } - })(moduleSpecifiers = ts.moduleSpecifiers || (ts.moduleSpecifiers = {})); -})(ts || (ts = {})); /* @internal */ var ts; (function (ts) { @@ -106362,7 +106410,7 @@ var ts; getGeneratedPosition: getGeneratedPosition }; function getGeneratedPosition(loc) { - var maps = getGeneratedOrderedMappings(); + var maps = getSourceOrderedMappings(); if (!ts.length(maps)) return loc; var targetIndex = ts.binarySearch(maps, { sourcePath: loc.fileName, sourcePosition: loc.position }, ts.identity, compareProcessedPositionSourcePositions); @@ -106376,7 +106424,7 @@ var ts; return { fileName: ts.toPath(map.file, sourceRoot, host.getCanonicalFileName), position: maps[targetIndex].emittedPosition }; // Closest pos } function getOriginalPosition(loc) { - var maps = getSourceOrderedMappings(); + var maps = getGeneratedOrderedMappings(); if (!ts.length(maps)) return loc; var targetIndex = ts.binarySearch(maps, { emittedPosition: loc.position }, ts.identity, compareProcessedPositionEmittedPositions); diff --git a/lib/typescript.d.ts b/lib/typescript.d.ts index 8685c813ffc..433a59b9404 100644 --- a/lib/typescript.d.ts +++ b/lib/typescript.d.ts @@ -2876,6 +2876,10 @@ declare namespace ts { omitTrailingSemicolon?: boolean; noEmitHelpers?: boolean; } + interface GetEffectiveTypeRootsHost { + directoryExists?(directoryName: string): boolean; + getCurrentDirectory?(): string; + } /** @deprecated See comment on SymbolWriter */ interface SymbolTracker { trackSymbol?(symbol: Symbol, enclosingDeclaration?: Node, meaning?: SymbolFlags): void; @@ -3463,10 +3467,6 @@ declare namespace ts { function updateSourceFile(sourceFile: SourceFile, newText: string, textChangeRange: TextChangeRange, aggressiveChecks?: boolean): SourceFile; } declare namespace ts { - interface GetEffectiveTypeRootsHost { - directoryExists?(directoryName: string): boolean; - getCurrentDirectory?(): string; - } function getEffectiveTypeRoots(options: CompilerOptions, host: GetEffectiveTypeRootsHost): string[] | undefined; /** * @param {string | undefined} containingFile - file that contains type reference directive, can be undefined if containing file is unknown. diff --git a/lib/typescript.js b/lib/typescript.js index 78fc16846f8..550c05d5713 100644 --- a/lib/typescript.js +++ b/lib/typescript.js @@ -30235,7 +30235,8 @@ var ts; // ambient module, just use declaration/symbol name (fallthrough) } else { - return "\"" + ts.getResolvedExternalModuleName(context.tracker.moduleResolverHost, file_3, ts.getSourceFileOfNode(ts.getOriginalNode(context.enclosingDeclaration))) + "\""; + var contextFile = ts.getSourceFileOfNode(ts.getOriginalNode(context.enclosingDeclaration)); + return "\"" + (file_3.moduleName || ts.moduleSpecifiers.getModuleSpecifiers(symbol, compilerOptions, contextFile, context.tracker.moduleResolverHost, context.tracker.moduleResolverHost.getSourceFiles(), { importModuleSpecifierPreference: "non-relative" })[0]) + "\""; } } var declaration = symbol.declarations[0]; @@ -78966,20 +78967,8 @@ var ts; return oldProgram.structureIsReused = 2 /* Completely */; } function getEmitHost(writeFileCallback) { - return { - getPrependNodes: getPrependNodes, - getCanonicalFileName: getCanonicalFileName, - getCommonSourceDirectory: program.getCommonSourceDirectory, - getCompilerOptions: program.getCompilerOptions, - getCurrentDirectory: function () { return currentDirectory; }, - getNewLine: function () { return host.getNewLine(); }, - getSourceFile: program.getSourceFile, - getSourceFileByPath: program.getSourceFileByPath, - getSourceFiles: program.getSourceFiles, - isSourceFileFromExternalLibrary: isSourceFileFromExternalLibrary, - writeFile: writeFileCallback || (function (fileName, data, writeByteOrderMark, onError, sourceFiles) { return host.writeFile(fileName, data, writeByteOrderMark, onError, sourceFiles); }), - isEmitBlocked: isEmitBlocked, - }; + return __assign({ getPrependNodes: getPrependNodes, + getCanonicalFileName: getCanonicalFileName, getCommonSourceDirectory: program.getCommonSourceDirectory, getCompilerOptions: program.getCompilerOptions, getCurrentDirectory: function () { return currentDirectory; }, getNewLine: function () { return host.getNewLine(); }, getSourceFile: program.getSourceFile, getSourceFileByPath: program.getSourceFileByPath, getSourceFiles: program.getSourceFiles, isSourceFileFromExternalLibrary: isSourceFileFromExternalLibrary, writeFile: writeFileCallback || (function (fileName, data, writeByteOrderMark, onError, sourceFiles) { return host.writeFile(fileName, data, writeByteOrderMark, onError, sourceFiles); }), isEmitBlocked: isEmitBlocked, readFile: function (f) { return host.readFile(f); }, fileExists: function (f) { return host.fileExists(f); } }, (host.directoryExists ? { directoryExists: function (f) { return host.directoryExists(f); } } : {})); } function getProjectReferences() { if (!resolvedProjectReferences) @@ -81639,6 +81628,370 @@ var ts; } ts.createResolutionCache = createResolutionCache; })(ts || (ts = {})); +// Used by importFixes to synthesize import module specifiers. +/* @internal */ +var ts; +(function (ts) { + var moduleSpecifiers; + (function (moduleSpecifiers) { + // Note: fromSourceFile is just for usesJsExtensionOnImports + function getModuleSpecifier(compilerOptions, fromSourceFile, fromSourceFileName, toFileName, host, preferences) { + if (preferences === void 0) { preferences = {}; } + var info = getInfo(compilerOptions, fromSourceFile, fromSourceFileName, host); + return getGlobalModuleSpecifier(toFileName, info, host, compilerOptions) || + ts.first(getLocalModuleSpecifiers(toFileName, info, compilerOptions, preferences)); + } + moduleSpecifiers.getModuleSpecifier = getModuleSpecifier; + // For each symlink/original for a module, returns a list of ways to import that file. + function getModuleSpecifiers(moduleSymbol, compilerOptions, importingSourceFile, host, files, preferences) { + var ambient = tryGetModuleNameFromAmbientModule(moduleSymbol); + if (ambient) + return [[ambient]]; + var info = getInfo(compilerOptions, importingSourceFile, importingSourceFile.path, host); + if (!files) { + return ts.Debug.fail("Files list must be present to resolve symlinks in specifier resolution"); + } + var modulePaths = getAllModulePaths(files, ts.getSourceFileOfNode(moduleSymbol.valueDeclaration), info.getCanonicalFileName, host); + var global = ts.mapDefined(modulePaths, function (moduleFileName) { return getGlobalModuleSpecifier(moduleFileName, info, host, compilerOptions); }); + return global.length ? global.map(function (g) { return [g]; }) : modulePaths.map(function (moduleFileName) { + return getLocalModuleSpecifiers(moduleFileName, info, compilerOptions, preferences); + }); + } + moduleSpecifiers.getModuleSpecifiers = getModuleSpecifiers; + // importingSourceFileName is separate because getEditsForFileRename may need to specify an updated path + function getInfo(compilerOptions, importingSourceFile, importingSourceFileName, host) { + var moduleResolutionKind = ts.getEmitModuleResolutionKind(compilerOptions); + var addJsExtension = usesJsExtensionOnImports(importingSourceFile); + var getCanonicalFileName = ts.createGetCanonicalFileName(host.useCaseSensitiveFileNames ? host.useCaseSensitiveFileNames() : true); + var sourceDirectory = ts.getDirectoryPath(importingSourceFileName); + return { moduleResolutionKind: moduleResolutionKind, addJsExtension: addJsExtension, getCanonicalFileName: getCanonicalFileName, sourceDirectory: sourceDirectory }; + } + function getGlobalModuleSpecifier(moduleFileName, _a, host, compilerOptions) { + var addJsExtension = _a.addJsExtension, getCanonicalFileName = _a.getCanonicalFileName, sourceDirectory = _a.sourceDirectory; + return tryGetModuleNameFromTypeRoots(compilerOptions, host, getCanonicalFileName, moduleFileName, addJsExtension) + || tryGetModuleNameAsNodeModule(compilerOptions, moduleFileName, host, getCanonicalFileName, sourceDirectory) + || compilerOptions.rootDirs && tryGetModuleNameFromRootDirs(compilerOptions.rootDirs, moduleFileName, sourceDirectory, getCanonicalFileName); + } + function getLocalModuleSpecifiers(moduleFileName, _a, compilerOptions, preferences) { + var moduleResolutionKind = _a.moduleResolutionKind, addJsExtension = _a.addJsExtension, getCanonicalFileName = _a.getCanonicalFileName, sourceDirectory = _a.sourceDirectory; + var baseUrl = compilerOptions.baseUrl, paths = compilerOptions.paths; + var relativePath = removeExtensionAndIndexPostFix(ts.ensurePathIsNonModuleName(ts.getRelativePathFromDirectory(sourceDirectory, moduleFileName, getCanonicalFileName)), moduleResolutionKind, addJsExtension); + if (!baseUrl || preferences.importModuleSpecifierPreference === "relative") { + return [relativePath]; + } + var relativeToBaseUrl = getRelativePathIfInDirectory(moduleFileName, baseUrl, getCanonicalFileName); + if (!relativeToBaseUrl) { + return [relativePath]; + } + var importRelativeToBaseUrl = removeExtensionAndIndexPostFix(relativeToBaseUrl, moduleResolutionKind, addJsExtension); + if (paths) { + var fromPaths = tryGetModuleNameFromPaths(ts.removeFileExtension(relativeToBaseUrl), importRelativeToBaseUrl, paths); + if (fromPaths) { + return [fromPaths]; + } + } + if (preferences.importModuleSpecifierPreference === "non-relative") { + return [importRelativeToBaseUrl]; + } + if (preferences.importModuleSpecifierPreference !== undefined) + ts.Debug.assertNever(preferences.importModuleSpecifierPreference); + if (isPathRelativeToParent(relativeToBaseUrl)) { + return [relativePath]; + } + /* + Prefer a relative import over a baseUrl import if it doesn't traverse up to baseUrl. + + Suppose we have: + baseUrl = /base + sourceDirectory = /base/a/b + moduleFileName = /base/foo/bar + Then: + relativePath = ../../foo/bar + getRelativePathNParents(relativePath) = 2 + pathFromSourceToBaseUrl = ../../ + getRelativePathNParents(pathFromSourceToBaseUrl) = 2 + 2 < 2 = false + In this case we should prefer using the baseUrl path "/a/b" instead of the relative path "../../foo/bar". + + Suppose we have: + baseUrl = /base + sourceDirectory = /base/foo/a + moduleFileName = /base/foo/bar + Then: + relativePath = ../a + getRelativePathNParents(relativePath) = 1 + pathFromSourceToBaseUrl = ../../ + getRelativePathNParents(pathFromSourceToBaseUrl) = 2 + 1 < 2 = true + In this case we should prefer using the relative path "../a" instead of the baseUrl path "foo/a". + */ + var pathFromSourceToBaseUrl = ts.ensurePathIsNonModuleName(ts.getRelativePathFromDirectory(sourceDirectory, baseUrl, getCanonicalFileName)); + var relativeFirst = getRelativePathNParents(relativePath) < getRelativePathNParents(pathFromSourceToBaseUrl); + return relativeFirst ? [relativePath, importRelativeToBaseUrl] : [importRelativeToBaseUrl, relativePath]; + } + function usesJsExtensionOnImports(_a) { + var imports = _a.imports; + return ts.firstDefined(imports, function (_a) { + var text = _a.text; + return ts.pathIsRelative(text) ? ts.fileExtensionIs(text, ".js" /* Js */) : undefined; + }) || false; + } + function discoverProbableSymlinks(files) { + var symlinks = ts.mapDefined(files, function (sf) { + return sf.resolvedModules && ts.firstDefinedIterator(sf.resolvedModules.values(), function (res) { + return res && res.originalPath && res.resolvedFileName !== res.originalPath ? [res.resolvedFileName, res.originalPath] : undefined; + }); + }); + var result = ts.createMap(); + if (symlinks) { + for (var _i = 0, symlinks_1 = symlinks; _i < symlinks_1.length; _i++) { + var _a = symlinks_1[_i], resolvedPath = _a[0], originalPath = _a[1]; + var resolvedParts = ts.getPathComponents(resolvedPath); + var originalParts = ts.getPathComponents(originalPath); + while (resolvedParts[resolvedParts.length - 1] === originalParts[originalParts.length - 1]) { + resolvedParts.pop(); + originalParts.pop(); + } + result.set(ts.getPathFromPathComponents(originalParts), ts.getPathFromPathComponents(resolvedParts)); + } + } + return result; + } + function getAllModulePathsUsingIndirectSymlinks(files, target, getCanonicalFileName, host) { + var links = discoverProbableSymlinks(files); + var paths = ts.arrayFrom(links.keys()); + var options; + for (var _i = 0, paths_2 = paths; _i < paths_2.length; _i++) { + var path = paths_2[_i]; + var resolved = links.get(path); + if (ts.startsWith(target, resolved + "/")) { + var relative = ts.getRelativePathFromDirectory(resolved, target, getCanonicalFileName); + var option = ts.resolvePath(path, relative); + if (!host.fileExists || host.fileExists(option)) { + if (!options) + options = []; + options.push(option); + } + } + } + var resolvedtarget = host.getCurrentDirectory ? ts.resolvePath(host.getCurrentDirectory(), target) : target; + if (options) { + options.push(resolvedtarget); // Since these are speculative, we also include the original resolved name as a possibility + return options; + } + return [resolvedtarget]; + } + /** + * Looks for a existing imports that use symlinks to this module. + * Only if no symlink is available, the real path will be used. + */ + function getAllModulePaths(files, _a, getCanonicalFileName, host) { + var fileName = _a.fileName; + var symlinks = ts.mapDefined(files, function (sf) { + return sf.resolvedModules && ts.firstDefinedIterator(sf.resolvedModules.values(), function (res) { + return res && res.resolvedFileName === fileName ? res.originalPath : undefined; + }); + }); + return symlinks.length === 0 ? getAllModulePathsUsingIndirectSymlinks(files, fileName, getCanonicalFileName, host) : symlinks; + } + function getRelativePathNParents(relativePath) { + var components = ts.getPathComponents(relativePath); + if (components[0] || components.length === 1) + return 0; + for (var i = 1; i < components.length; i++) { + if (components[i] !== "..") + return i - 1; + } + return components.length - 1; + } + function tryGetModuleNameFromAmbientModule(moduleSymbol) { + var decl = moduleSymbol.valueDeclaration; + if (ts.isModuleDeclaration(decl) && ts.isStringLiteral(decl.name)) { + return decl.name.text; + } + } + function tryGetModuleNameFromPaths(relativeToBaseUrlWithIndex, relativeToBaseUrl, paths) { + for (var key in paths) { + for (var _i = 0, _a = paths[key]; _i < _a.length; _i++) { + var patternText_1 = _a[_i]; + var pattern = ts.removeFileExtension(ts.normalizePath(patternText_1)); + var indexOfStar = pattern.indexOf("*"); + if (indexOfStar === 0 && pattern.length === 1) { + continue; + } + else if (indexOfStar !== -1) { + var prefix = pattern.substr(0, indexOfStar); + var suffix = pattern.substr(indexOfStar + 1); + if (relativeToBaseUrl.length >= prefix.length + suffix.length && + ts.startsWith(relativeToBaseUrl, prefix) && + ts.endsWith(relativeToBaseUrl, suffix)) { + var matchedStar = relativeToBaseUrl.substr(prefix.length, relativeToBaseUrl.length - suffix.length); + return key.replace("*", matchedStar); + } + } + else if (pattern === relativeToBaseUrl || pattern === relativeToBaseUrlWithIndex) { + return key; + } + } + } + } + function tryGetModuleNameFromRootDirs(rootDirs, moduleFileName, sourceDirectory, getCanonicalFileName) { + var normalizedTargetPath = getPathRelativeToRootDirs(moduleFileName, rootDirs, getCanonicalFileName); + if (normalizedTargetPath === undefined) { + return undefined; + } + var normalizedSourcePath = getPathRelativeToRootDirs(sourceDirectory, rootDirs, getCanonicalFileName); + var relativePath = normalizedSourcePath !== undefined ? ts.ensurePathIsNonModuleName(ts.getRelativePathFromDirectory(normalizedSourcePath, normalizedTargetPath, getCanonicalFileName)) : normalizedTargetPath; + return ts.removeFileExtension(relativePath); + } + function tryGetModuleNameFromTypeRoots(options, host, getCanonicalFileName, moduleFileName, addJsExtension) { + var roots = ts.getEffectiveTypeRoots(options, host); + return ts.firstDefined(roots, function (unNormalizedTypeRoot) { + var typeRoot = ts.toPath(unNormalizedTypeRoot, /*basePath*/ undefined, getCanonicalFileName); + if (ts.startsWith(moduleFileName, typeRoot)) { + // For a type definition, we can strip `/index` even with classic resolution. + return removeExtensionAndIndexPostFix(moduleFileName.substring(typeRoot.length + 1), ts.ModuleResolutionKind.NodeJs, addJsExtension); + } + }); + } + function tryGetModuleNameAsNodeModule(options, moduleFileName, host, getCanonicalFileName, sourceDirectory) { + if (ts.getEmitModuleResolutionKind(options) !== ts.ModuleResolutionKind.NodeJs) { + // nothing to do here + return undefined; + } + var parts = getNodeModulePathParts(moduleFileName); + if (!parts) { + return undefined; + } + // Simplify the full file path to something that can be resolved by Node. + // If the module could be imported by a directory name, use that directory's name + var moduleSpecifier = getDirectoryOrExtensionlessFileName(moduleFileName); + // Get a path that's relative to node_modules or the importing file's path + moduleSpecifier = getNodeResolvablePath(moduleSpecifier); + // If the module was found in @types, get the actual Node package name + return ts.getPackageNameFromAtTypesDirectory(moduleSpecifier); + function getDirectoryOrExtensionlessFileName(path) { + // If the file is the main module, it can be imported by the package name + var packageRootPath = path.substring(0, parts.packageRootIndex); + var packageJsonPath = ts.combinePaths(packageRootPath, "package.json"); + if (host.fileExists(packageJsonPath)) { + var packageJsonContent = JSON.parse(host.readFile(packageJsonPath)); + if (packageJsonContent) { + var mainFileRelative = packageJsonContent.typings || packageJsonContent.types || packageJsonContent.main; + if (mainFileRelative) { + var mainExportFile = ts.toPath(mainFileRelative, packageRootPath, getCanonicalFileName); + if (mainExportFile === getCanonicalFileName(path)) { + return packageRootPath; + } + } + } + } + // We still have a file name - remove the extension + var fullModulePathWithoutExtension = ts.removeFileExtension(path); + // If the file is /index, it can be imported by its directory name + // IFF there is not _also_ a file by the same name + if (getCanonicalFileName(fullModulePathWithoutExtension.substring(parts.fileNameIndex)) === "/index" && !tryGetAnyFileFromPath(host, fullModulePathWithoutExtension.substring(0, parts.fileNameIndex))) { + return fullModulePathWithoutExtension.substring(0, parts.fileNameIndex); + } + return fullModulePathWithoutExtension; + } + function getNodeResolvablePath(path) { + var basePath = path.substring(0, parts.topLevelNodeModulesIndex); + if (sourceDirectory.indexOf(basePath) === 0) { + // if node_modules folder is in this folder or any of its parent folders, no need to keep it. + return path.substring(parts.topLevelPackageNameIndex + 1); + } + else { + return ts.ensurePathIsNonModuleName(ts.getRelativePathFromDirectory(sourceDirectory, path, getCanonicalFileName)); + } + } + } + function tryGetAnyFileFromPath(host, path) { + // We check all js, `node` and `json` extensions in addition to TS, since node module resolution would also choose those over the directory + var extensions = ts.getSupportedExtensions({ allowJs: true }, [{ extension: "node", isMixedContent: false }, { extension: "json", isMixedContent: false, scriptKind: 6 /* JSON */ }]); + for (var _i = 0, extensions_3 = extensions; _i < extensions_3.length; _i++) { + var e = extensions_3[_i]; + var fullPath = path + e; + if (host.fileExists(fullPath)) { // TODO: GH#18217 + return fullPath; + } + } + } + function getNodeModulePathParts(fullPath) { + // 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: ^ ^ ^ ^ + var topLevelNodeModulesIndex = 0; + var topLevelPackageNameIndex = 0; + var packageRootIndex = 0; + var fileNameIndex = 0; + var States; + (function (States) { + States[States["BeforeNodeModules"] = 0] = "BeforeNodeModules"; + States[States["NodeModules"] = 1] = "NodeModules"; + States[States["Scope"] = 2] = "Scope"; + States[States["PackageContent"] = 3] = "PackageContent"; + })(States || (States = {})); + var partStart = 0; + var partEnd = 0; + var state = 0 /* BeforeNodeModules */; + while (partEnd >= 0) { + partStart = partEnd; + partEnd = fullPath.indexOf("/", partStart + 1); + switch (state) { + case 0 /* BeforeNodeModules */: + if (fullPath.indexOf("/node_modules/", partStart) === partStart) { + topLevelNodeModulesIndex = partStart; + topLevelPackageNameIndex = partEnd; + state = 1 /* NodeModules */; + } + break; + case 1 /* NodeModules */: + case 2 /* Scope */: + if (state === 1 /* NodeModules */ && fullPath.charAt(partStart + 1) === "@") { + state = 2 /* Scope */; + } + else { + packageRootIndex = partEnd; + state = 3 /* PackageContent */; + } + break; + case 3 /* PackageContent */: + if (fullPath.indexOf("/node_modules/", partStart) === partStart) { + state = 1 /* NodeModules */; + } + else { + state = 3 /* PackageContent */; + } + break; + } + } + fileNameIndex = partStart; + return state > 1 /* NodeModules */ ? { topLevelNodeModulesIndex: topLevelNodeModulesIndex, topLevelPackageNameIndex: topLevelPackageNameIndex, packageRootIndex: packageRootIndex, fileNameIndex: fileNameIndex } : undefined; + } + function getPathRelativeToRootDirs(path, rootDirs, getCanonicalFileName) { + return ts.firstDefined(rootDirs, function (rootDir) { + var relativePath = getRelativePathIfInDirectory(path, rootDir, getCanonicalFileName); + return isPathRelativeToParent(relativePath) ? undefined : relativePath; + }); + } + function removeExtensionAndIndexPostFix(fileName, moduleResolutionKind, addJsExtension) { + var noExtension = ts.removeFileExtension(fileName); + return addJsExtension + ? noExtension + ".js" + : moduleResolutionKind === ts.ModuleResolutionKind.NodeJs + ? ts.removeSuffix(noExtension, "/index") + : noExtension; + } + function getRelativePathIfInDirectory(path, directoryPath, getCanonicalFileName) { + var relativePath = ts.getRelativePathToDirectoryOrUrl(directoryPath, path, directoryPath, getCanonicalFileName, /*isAbsolutePathAnUrl*/ false); + return ts.isRootedDiskPath(relativePath) ? undefined : relativePath; + } + function isPathRelativeToParent(path) { + return ts.startsWith(path, ".."); + } + })(moduleSpecifiers = ts.moduleSpecifiers || (ts.moduleSpecifiers = {})); +})(ts || (ts = {})); /*@internal*/ var ts; (function (ts) { @@ -92141,7 +92494,7 @@ var ts; // TODO:GH#18217 ? getSourceFileToImportFromResolved(ts.resolveModuleName(importLiteral.text, oldImportFromPath, program.getCompilerOptions(), host), oldToNew, program) : getSourceFileToImport(importLiteral, sourceFile, program, host, oldToNew); - return toImport === undefined ? undefined : ts.moduleSpecifiers.getModuleSpecifier(program, sourceFile, newImportFromPath, toImport, host, preferences); + return toImport === undefined ? undefined : ts.moduleSpecifiers.getModuleSpecifier(program.getCompilerOptions(), sourceFile, newImportFromPath, toImport, host, preferences); }); }; for (var _i = 0, _a = program.getSourceFiles(); _i < _a.length; _i++) { @@ -95616,7 +95969,7 @@ var ts; ts.Debug.assert(indexOfOpenerToken >= 0 && children.length > indexOfOpenerToken + 1); return children[indexOfOpenerToken + 1]; } - var signatureHelpNodeBuilderFlags = 8192 /* OmitParameterModifiers */ | 3112960 /* IgnoreErrors */; + var signatureHelpNodeBuilderFlags = 8192 /* OmitParameterModifiers */ | 3112960 /* IgnoreErrors */ | 16384 /* UseAliasDefinedOutsideCurrentScope */; function createSignatureHelpItems(candidates, resolvedSignature, argumentListInfo, typeChecker) { var argumentCount = argumentListInfo.argumentCount, applicableSpan = argumentListInfo.argumentsSpan, invocation = argumentListInfo.invocation, argumentIndex = argumentListInfo.argumentIndex; var isTypeParameterList = argumentListInfo.kind === 0 /* TypeArguments */; @@ -101216,7 +101569,7 @@ var ts; function getNewImportInfos(program, sourceFile, moduleSymbols, host, preferences) { var choicesForEachExportingModule = ts.flatMap(moduleSymbols, function (_a) { var moduleSymbol = _a.moduleSymbol, importKind = _a.importKind; - var modulePathsGroups = ts.moduleSpecifiers.getModuleSpecifiers(moduleSymbol, program, sourceFile, host, preferences); + var modulePathsGroups = ts.moduleSpecifiers.getModuleSpecifiers(moduleSymbol, program.getCompilerOptions(), sourceFile, host, program.getSourceFiles(), preferences); return modulePathsGroups.map(function (group) { return group.map(function (moduleSpecifier) { return ({ moduleSpecifier: moduleSpecifier, importKind: importKind }); }); }); }); // Sort to keep the shortest paths first, but keep [relativePath, importRelativeToBaseUrl] groups together @@ -103580,311 +103933,6 @@ var ts; } })(codefix = ts.codefix || (ts.codefix = {})); })(ts || (ts = {})); -// Used by importFixes to synthesize import module specifiers. -/* @internal */ -var ts; -(function (ts) { - var moduleSpecifiers; - (function (moduleSpecifiers) { - // Note: fromSourceFile is just for usesJsExtensionOnImports - function getModuleSpecifier(program, fromSourceFile, fromSourceFileName, toFileName, host, preferences) { - var info = getInfo(program.getCompilerOptions(), fromSourceFile, fromSourceFileName, host); - var compilerOptions = program.getCompilerOptions(); - return getGlobalModuleSpecifier(toFileName, info, host, compilerOptions) || - ts.first(getLocalModuleSpecifiers(toFileName, info, compilerOptions, preferences)); - } - moduleSpecifiers.getModuleSpecifier = getModuleSpecifier; - // For each symlink/original for a module, returns a list of ways to import that file. - function getModuleSpecifiers(moduleSymbol, program, importingSourceFile, host, preferences) { - var ambient = tryGetModuleNameFromAmbientModule(moduleSymbol); - if (ambient) - return [[ambient]]; - var compilerOptions = program.getCompilerOptions(); - var info = getInfo(compilerOptions, importingSourceFile, importingSourceFile.fileName, host); - var modulePaths = getAllModulePaths(program, moduleSymbol.valueDeclaration.getSourceFile()); - var global = ts.mapDefined(modulePaths, function (moduleFileName) { return getGlobalModuleSpecifier(moduleFileName, info, host, compilerOptions); }); - return global.length ? global.map(function (g) { return [g]; }) : modulePaths.map(function (moduleFileName) { - return getLocalModuleSpecifiers(moduleFileName, info, compilerOptions, preferences); - }); - } - moduleSpecifiers.getModuleSpecifiers = getModuleSpecifiers; - // importingSourceFileName is separate because getEditsForFileRename may need to specify an updated path - function getInfo(compilerOptions, importingSourceFile, importingSourceFileName, host) { - var moduleResolutionKind = ts.getEmitModuleResolutionKind(compilerOptions); - var addJsExtension = usesJsExtensionOnImports(importingSourceFile); - var getCanonicalFileName = ts.hostGetCanonicalFileName(host); - var sourceDirectory = ts.getDirectoryPath(importingSourceFileName); - return { moduleResolutionKind: moduleResolutionKind, addJsExtension: addJsExtension, getCanonicalFileName: getCanonicalFileName, sourceDirectory: sourceDirectory }; - } - function getGlobalModuleSpecifier(moduleFileName, _a, host, compilerOptions) { - var addJsExtension = _a.addJsExtension, getCanonicalFileName = _a.getCanonicalFileName, sourceDirectory = _a.sourceDirectory; - return tryGetModuleNameFromTypeRoots(compilerOptions, host, getCanonicalFileName, moduleFileName, addJsExtension) - || tryGetModuleNameAsNodeModule(compilerOptions, moduleFileName, host, getCanonicalFileName, sourceDirectory) - || compilerOptions.rootDirs && tryGetModuleNameFromRootDirs(compilerOptions.rootDirs, moduleFileName, sourceDirectory, getCanonicalFileName); - } - function getLocalModuleSpecifiers(moduleFileName, _a, compilerOptions, preferences) { - var moduleResolutionKind = _a.moduleResolutionKind, addJsExtension = _a.addJsExtension, getCanonicalFileName = _a.getCanonicalFileName, sourceDirectory = _a.sourceDirectory; - var baseUrl = compilerOptions.baseUrl, paths = compilerOptions.paths; - var relativePath = removeExtensionAndIndexPostFix(ts.ensurePathIsNonModuleName(ts.getRelativePathFromDirectory(sourceDirectory, moduleFileName, getCanonicalFileName)), moduleResolutionKind, addJsExtension); - if (!baseUrl || preferences.importModuleSpecifierPreference === "relative") { - return [relativePath]; - } - var relativeToBaseUrl = getRelativePathIfInDirectory(moduleFileName, baseUrl, getCanonicalFileName); - if (!relativeToBaseUrl) { - return [relativePath]; - } - var importRelativeToBaseUrl = removeExtensionAndIndexPostFix(relativeToBaseUrl, moduleResolutionKind, addJsExtension); - if (paths) { - var fromPaths = tryGetModuleNameFromPaths(ts.removeFileExtension(relativeToBaseUrl), importRelativeToBaseUrl, paths); - if (fromPaths) { - return [fromPaths]; - } - } - if (preferences.importModuleSpecifierPreference === "non-relative") { - return [importRelativeToBaseUrl]; - } - if (preferences.importModuleSpecifierPreference !== undefined) - ts.Debug.assertNever(preferences.importModuleSpecifierPreference); - if (isPathRelativeToParent(relativeToBaseUrl)) { - return [relativePath]; - } - /* - Prefer a relative import over a baseUrl import if it doesn't traverse up to baseUrl. - - Suppose we have: - baseUrl = /base - sourceDirectory = /base/a/b - moduleFileName = /base/foo/bar - Then: - relativePath = ../../foo/bar - getRelativePathNParents(relativePath) = 2 - pathFromSourceToBaseUrl = ../../ - getRelativePathNParents(pathFromSourceToBaseUrl) = 2 - 2 < 2 = false - In this case we should prefer using the baseUrl path "/a/b" instead of the relative path "../../foo/bar". - - Suppose we have: - baseUrl = /base - sourceDirectory = /base/foo/a - moduleFileName = /base/foo/bar - Then: - relativePath = ../a - getRelativePathNParents(relativePath) = 1 - pathFromSourceToBaseUrl = ../../ - getRelativePathNParents(pathFromSourceToBaseUrl) = 2 - 1 < 2 = true - In this case we should prefer using the relative path "../a" instead of the baseUrl path "foo/a". - */ - var pathFromSourceToBaseUrl = ts.ensurePathIsNonModuleName(ts.getRelativePathFromDirectory(sourceDirectory, baseUrl, getCanonicalFileName)); - var relativeFirst = getRelativePathNParents(relativePath) < getRelativePathNParents(pathFromSourceToBaseUrl); - return relativeFirst ? [relativePath, importRelativeToBaseUrl] : [importRelativeToBaseUrl, relativePath]; - } - function usesJsExtensionOnImports(_a) { - var imports = _a.imports; - return ts.firstDefined(imports, function (_a) { - var text = _a.text; - return ts.pathIsRelative(text) ? ts.fileExtensionIs(text, ".js" /* Js */) : undefined; - }) || false; - } - /** - * Looks for a existing imports that use symlinks to this module. - * Only if no symlink is available, the real path will be used. - */ - function getAllModulePaths(program, _a) { - var fileName = _a.fileName; - var symlinks = ts.mapDefined(program.getSourceFiles(), function (sf) { - return sf.resolvedModules && ts.firstDefinedIterator(sf.resolvedModules.values(), function (res) { - return res && res.resolvedFileName === fileName ? res.originalPath : undefined; - }); - }); - return symlinks.length === 0 ? [fileName] : symlinks; - } - function getRelativePathNParents(relativePath) { - var components = ts.getPathComponents(relativePath); - if (components[0] || components.length === 1) - return 0; - for (var i = 1; i < components.length; i++) { - if (components[i] !== "..") - return i - 1; - } - return components.length - 1; - } - function tryGetModuleNameFromAmbientModule(moduleSymbol) { - var decl = moduleSymbol.valueDeclaration; - if (ts.isModuleDeclaration(decl) && ts.isStringLiteral(decl.name)) { - return decl.name.text; - } - } - function tryGetModuleNameFromPaths(relativeToBaseUrlWithIndex, relativeToBaseUrl, paths) { - for (var key in paths) { - for (var _i = 0, _a = paths[key]; _i < _a.length; _i++) { - var patternText_1 = _a[_i]; - var pattern = ts.removeFileExtension(ts.normalizePath(patternText_1)); - var indexOfStar = pattern.indexOf("*"); - if (indexOfStar === 0 && pattern.length === 1) { - continue; - } - else if (indexOfStar !== -1) { - var prefix = pattern.substr(0, indexOfStar); - var suffix = pattern.substr(indexOfStar + 1); - if (relativeToBaseUrl.length >= prefix.length + suffix.length && - ts.startsWith(relativeToBaseUrl, prefix) && - ts.endsWith(relativeToBaseUrl, suffix)) { - var matchedStar = relativeToBaseUrl.substr(prefix.length, relativeToBaseUrl.length - suffix.length); - return key.replace("*", matchedStar); - } - } - else if (pattern === relativeToBaseUrl || pattern === relativeToBaseUrlWithIndex) { - return key; - } - } - } - } - function tryGetModuleNameFromRootDirs(rootDirs, moduleFileName, sourceDirectory, getCanonicalFileName) { - var normalizedTargetPath = getPathRelativeToRootDirs(moduleFileName, rootDirs, getCanonicalFileName); - if (normalizedTargetPath === undefined) { - return undefined; - } - var normalizedSourcePath = getPathRelativeToRootDirs(sourceDirectory, rootDirs, getCanonicalFileName); - var relativePath = normalizedSourcePath !== undefined ? ts.ensurePathIsNonModuleName(ts.getRelativePathFromDirectory(normalizedSourcePath, normalizedTargetPath, getCanonicalFileName)) : normalizedTargetPath; - return ts.removeFileExtension(relativePath); - } - function tryGetModuleNameFromTypeRoots(options, host, getCanonicalFileName, moduleFileName, addJsExtension) { - var roots = ts.getEffectiveTypeRoots(options, host); - return ts.firstDefined(roots, function (unNormalizedTypeRoot) { - var typeRoot = ts.toPath(unNormalizedTypeRoot, /*basePath*/ undefined, getCanonicalFileName); - if (ts.startsWith(moduleFileName, typeRoot)) { - // For a type definition, we can strip `/index` even with classic resolution. - return removeExtensionAndIndexPostFix(moduleFileName.substring(typeRoot.length + 1), ts.ModuleResolutionKind.NodeJs, addJsExtension); - } - }); - } - function tryGetModuleNameAsNodeModule(options, moduleFileName, host, getCanonicalFileName, sourceDirectory) { - if (ts.getEmitModuleResolutionKind(options) !== ts.ModuleResolutionKind.NodeJs) { - // nothing to do here - return undefined; - } - var parts = getNodeModulePathParts(moduleFileName); - if (!parts) { - return undefined; - } - // Simplify the full file path to something that can be resolved by Node. - // If the module could be imported by a directory name, use that directory's name - var moduleSpecifier = getDirectoryOrExtensionlessFileName(moduleFileName); - // Get a path that's relative to node_modules or the importing file's path - moduleSpecifier = getNodeResolvablePath(moduleSpecifier); - // If the module was found in @types, get the actual Node package name - return ts.getPackageNameFromAtTypesDirectory(moduleSpecifier); - function getDirectoryOrExtensionlessFileName(path) { - // If the file is the main module, it can be imported by the package name - var packageRootPath = path.substring(0, parts.packageRootIndex); - var packageJsonPath = ts.combinePaths(packageRootPath, "package.json"); - if (host.fileExists(packageJsonPath)) { - var packageJsonContent = JSON.parse(host.readFile(packageJsonPath)); - if (packageJsonContent) { - var mainFileRelative = packageJsonContent.typings || packageJsonContent.types || packageJsonContent.main; - if (mainFileRelative) { - var mainExportFile = ts.toPath(mainFileRelative, packageRootPath, getCanonicalFileName); - if (mainExportFile === getCanonicalFileName(path)) { - return packageRootPath; - } - } - } - } - // We still have a file name - remove the extension - var fullModulePathWithoutExtension = ts.removeFileExtension(path); - // If the file is /index, it can be imported by its directory name - if (getCanonicalFileName(fullModulePathWithoutExtension.substring(parts.fileNameIndex)) === "/index") { - return fullModulePathWithoutExtension.substring(0, parts.fileNameIndex); - } - return fullModulePathWithoutExtension; - } - function getNodeResolvablePath(path) { - var basePath = path.substring(0, parts.topLevelNodeModulesIndex); - if (sourceDirectory.indexOf(basePath) === 0) { - // if node_modules folder is in this folder or any of its parent folders, no need to keep it. - return path.substring(parts.topLevelPackageNameIndex + 1); - } - else { - return ts.ensurePathIsNonModuleName(ts.getRelativePathFromDirectory(sourceDirectory, path, getCanonicalFileName)); - } - } - } - function getNodeModulePathParts(fullPath) { - // 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: ^ ^ ^ ^ - var topLevelNodeModulesIndex = 0; - var topLevelPackageNameIndex = 0; - var packageRootIndex = 0; - var fileNameIndex = 0; - var States; - (function (States) { - States[States["BeforeNodeModules"] = 0] = "BeforeNodeModules"; - States[States["NodeModules"] = 1] = "NodeModules"; - States[States["Scope"] = 2] = "Scope"; - States[States["PackageContent"] = 3] = "PackageContent"; - })(States || (States = {})); - var partStart = 0; - var partEnd = 0; - var state = 0 /* BeforeNodeModules */; - while (partEnd >= 0) { - partStart = partEnd; - partEnd = fullPath.indexOf("/", partStart + 1); - switch (state) { - case 0 /* BeforeNodeModules */: - if (fullPath.indexOf("/node_modules/", partStart) === partStart) { - topLevelNodeModulesIndex = partStart; - topLevelPackageNameIndex = partEnd; - state = 1 /* NodeModules */; - } - break; - case 1 /* NodeModules */: - case 2 /* Scope */: - if (state === 1 /* NodeModules */ && fullPath.charAt(partStart + 1) === "@") { - state = 2 /* Scope */; - } - else { - packageRootIndex = partEnd; - state = 3 /* PackageContent */; - } - break; - case 3 /* PackageContent */: - if (fullPath.indexOf("/node_modules/", partStart) === partStart) { - state = 1 /* NodeModules */; - } - else { - state = 3 /* PackageContent */; - } - break; - } - } - fileNameIndex = partStart; - return state > 1 /* NodeModules */ ? { topLevelNodeModulesIndex: topLevelNodeModulesIndex, topLevelPackageNameIndex: topLevelPackageNameIndex, packageRootIndex: packageRootIndex, fileNameIndex: fileNameIndex } : undefined; - } - function getPathRelativeToRootDirs(path, rootDirs, getCanonicalFileName) { - return ts.firstDefined(rootDirs, function (rootDir) { - var relativePath = getRelativePathIfInDirectory(path, rootDir, getCanonicalFileName); - return isPathRelativeToParent(relativePath) ? undefined : relativePath; - }); - } - function removeExtensionAndIndexPostFix(fileName, moduleResolutionKind, addJsExtension) { - var noExtension = ts.removeFileExtension(fileName); - return addJsExtension - ? noExtension + ".js" - : moduleResolutionKind === ts.ModuleResolutionKind.NodeJs - ? ts.removeSuffix(noExtension, "/index") - : noExtension; - } - function getRelativePathIfInDirectory(path, directoryPath, getCanonicalFileName) { - var relativePath = ts.getRelativePathToDirectoryOrUrl(directoryPath, path, directoryPath, getCanonicalFileName, /*isAbsolutePathAnUrl*/ false); - return ts.isRootedDiskPath(relativePath) ? undefined : relativePath; - } - function isPathRelativeToParent(path) { - return ts.startsWith(path, ".."); - } - })(moduleSpecifiers = ts.moduleSpecifiers || (ts.moduleSpecifiers = {})); -})(ts || (ts = {})); /* @internal */ var ts; (function (ts) { @@ -106362,7 +106410,7 @@ var ts; getGeneratedPosition: getGeneratedPosition }; function getGeneratedPosition(loc) { - var maps = getGeneratedOrderedMappings(); + var maps = getSourceOrderedMappings(); if (!ts.length(maps)) return loc; var targetIndex = ts.binarySearch(maps, { sourcePath: loc.fileName, sourcePosition: loc.position }, ts.identity, compareProcessedPositionSourcePositions); @@ -106376,7 +106424,7 @@ var ts; return { fileName: ts.toPath(map.file, sourceRoot, host.getCanonicalFileName), position: maps[targetIndex].emittedPosition }; // Closest pos } function getOriginalPosition(loc) { - var maps = getSourceOrderedMappings(); + var maps = getGeneratedOrderedMappings(); if (!ts.length(maps)) return loc; var targetIndex = ts.binarySearch(maps, { emittedPosition: loc.position }, ts.identity, compareProcessedPositionEmittedPositions); diff --git a/lib/typescriptServices.d.ts b/lib/typescriptServices.d.ts index de424afca90..6ca694bb3dc 100644 --- a/lib/typescriptServices.d.ts +++ b/lib/typescriptServices.d.ts @@ -2876,6 +2876,10 @@ declare namespace ts { omitTrailingSemicolon?: boolean; noEmitHelpers?: boolean; } + interface GetEffectiveTypeRootsHost { + directoryExists?(directoryName: string): boolean; + getCurrentDirectory?(): string; + } /** @deprecated See comment on SymbolWriter */ interface SymbolTracker { trackSymbol?(symbol: Symbol, enclosingDeclaration?: Node, meaning?: SymbolFlags): void; @@ -3463,10 +3467,6 @@ declare namespace ts { function updateSourceFile(sourceFile: SourceFile, newText: string, textChangeRange: TextChangeRange, aggressiveChecks?: boolean): SourceFile; } declare namespace ts { - interface GetEffectiveTypeRootsHost { - directoryExists?(directoryName: string): boolean; - getCurrentDirectory?(): string; - } function getEffectiveTypeRoots(options: CompilerOptions, host: GetEffectiveTypeRootsHost): string[] | undefined; /** * @param {string | undefined} containingFile - file that contains type reference directive, can be undefined if containing file is unknown. diff --git a/lib/typescriptServices.js b/lib/typescriptServices.js index 78fc16846f8..550c05d5713 100644 --- a/lib/typescriptServices.js +++ b/lib/typescriptServices.js @@ -30235,7 +30235,8 @@ var ts; // ambient module, just use declaration/symbol name (fallthrough) } else { - return "\"" + ts.getResolvedExternalModuleName(context.tracker.moduleResolverHost, file_3, ts.getSourceFileOfNode(ts.getOriginalNode(context.enclosingDeclaration))) + "\""; + var contextFile = ts.getSourceFileOfNode(ts.getOriginalNode(context.enclosingDeclaration)); + return "\"" + (file_3.moduleName || ts.moduleSpecifiers.getModuleSpecifiers(symbol, compilerOptions, contextFile, context.tracker.moduleResolverHost, context.tracker.moduleResolverHost.getSourceFiles(), { importModuleSpecifierPreference: "non-relative" })[0]) + "\""; } } var declaration = symbol.declarations[0]; @@ -78966,20 +78967,8 @@ var ts; return oldProgram.structureIsReused = 2 /* Completely */; } function getEmitHost(writeFileCallback) { - return { - getPrependNodes: getPrependNodes, - getCanonicalFileName: getCanonicalFileName, - getCommonSourceDirectory: program.getCommonSourceDirectory, - getCompilerOptions: program.getCompilerOptions, - getCurrentDirectory: function () { return currentDirectory; }, - getNewLine: function () { return host.getNewLine(); }, - getSourceFile: program.getSourceFile, - getSourceFileByPath: program.getSourceFileByPath, - getSourceFiles: program.getSourceFiles, - isSourceFileFromExternalLibrary: isSourceFileFromExternalLibrary, - writeFile: writeFileCallback || (function (fileName, data, writeByteOrderMark, onError, sourceFiles) { return host.writeFile(fileName, data, writeByteOrderMark, onError, sourceFiles); }), - isEmitBlocked: isEmitBlocked, - }; + return __assign({ getPrependNodes: getPrependNodes, + getCanonicalFileName: getCanonicalFileName, getCommonSourceDirectory: program.getCommonSourceDirectory, getCompilerOptions: program.getCompilerOptions, getCurrentDirectory: function () { return currentDirectory; }, getNewLine: function () { return host.getNewLine(); }, getSourceFile: program.getSourceFile, getSourceFileByPath: program.getSourceFileByPath, getSourceFiles: program.getSourceFiles, isSourceFileFromExternalLibrary: isSourceFileFromExternalLibrary, writeFile: writeFileCallback || (function (fileName, data, writeByteOrderMark, onError, sourceFiles) { return host.writeFile(fileName, data, writeByteOrderMark, onError, sourceFiles); }), isEmitBlocked: isEmitBlocked, readFile: function (f) { return host.readFile(f); }, fileExists: function (f) { return host.fileExists(f); } }, (host.directoryExists ? { directoryExists: function (f) { return host.directoryExists(f); } } : {})); } function getProjectReferences() { if (!resolvedProjectReferences) @@ -81639,6 +81628,370 @@ var ts; } ts.createResolutionCache = createResolutionCache; })(ts || (ts = {})); +// Used by importFixes to synthesize import module specifiers. +/* @internal */ +var ts; +(function (ts) { + var moduleSpecifiers; + (function (moduleSpecifiers) { + // Note: fromSourceFile is just for usesJsExtensionOnImports + function getModuleSpecifier(compilerOptions, fromSourceFile, fromSourceFileName, toFileName, host, preferences) { + if (preferences === void 0) { preferences = {}; } + var info = getInfo(compilerOptions, fromSourceFile, fromSourceFileName, host); + return getGlobalModuleSpecifier(toFileName, info, host, compilerOptions) || + ts.first(getLocalModuleSpecifiers(toFileName, info, compilerOptions, preferences)); + } + moduleSpecifiers.getModuleSpecifier = getModuleSpecifier; + // For each symlink/original for a module, returns a list of ways to import that file. + function getModuleSpecifiers(moduleSymbol, compilerOptions, importingSourceFile, host, files, preferences) { + var ambient = tryGetModuleNameFromAmbientModule(moduleSymbol); + if (ambient) + return [[ambient]]; + var info = getInfo(compilerOptions, importingSourceFile, importingSourceFile.path, host); + if (!files) { + return ts.Debug.fail("Files list must be present to resolve symlinks in specifier resolution"); + } + var modulePaths = getAllModulePaths(files, ts.getSourceFileOfNode(moduleSymbol.valueDeclaration), info.getCanonicalFileName, host); + var global = ts.mapDefined(modulePaths, function (moduleFileName) { return getGlobalModuleSpecifier(moduleFileName, info, host, compilerOptions); }); + return global.length ? global.map(function (g) { return [g]; }) : modulePaths.map(function (moduleFileName) { + return getLocalModuleSpecifiers(moduleFileName, info, compilerOptions, preferences); + }); + } + moduleSpecifiers.getModuleSpecifiers = getModuleSpecifiers; + // importingSourceFileName is separate because getEditsForFileRename may need to specify an updated path + function getInfo(compilerOptions, importingSourceFile, importingSourceFileName, host) { + var moduleResolutionKind = ts.getEmitModuleResolutionKind(compilerOptions); + var addJsExtension = usesJsExtensionOnImports(importingSourceFile); + var getCanonicalFileName = ts.createGetCanonicalFileName(host.useCaseSensitiveFileNames ? host.useCaseSensitiveFileNames() : true); + var sourceDirectory = ts.getDirectoryPath(importingSourceFileName); + return { moduleResolutionKind: moduleResolutionKind, addJsExtension: addJsExtension, getCanonicalFileName: getCanonicalFileName, sourceDirectory: sourceDirectory }; + } + function getGlobalModuleSpecifier(moduleFileName, _a, host, compilerOptions) { + var addJsExtension = _a.addJsExtension, getCanonicalFileName = _a.getCanonicalFileName, sourceDirectory = _a.sourceDirectory; + return tryGetModuleNameFromTypeRoots(compilerOptions, host, getCanonicalFileName, moduleFileName, addJsExtension) + || tryGetModuleNameAsNodeModule(compilerOptions, moduleFileName, host, getCanonicalFileName, sourceDirectory) + || compilerOptions.rootDirs && tryGetModuleNameFromRootDirs(compilerOptions.rootDirs, moduleFileName, sourceDirectory, getCanonicalFileName); + } + function getLocalModuleSpecifiers(moduleFileName, _a, compilerOptions, preferences) { + var moduleResolutionKind = _a.moduleResolutionKind, addJsExtension = _a.addJsExtension, getCanonicalFileName = _a.getCanonicalFileName, sourceDirectory = _a.sourceDirectory; + var baseUrl = compilerOptions.baseUrl, paths = compilerOptions.paths; + var relativePath = removeExtensionAndIndexPostFix(ts.ensurePathIsNonModuleName(ts.getRelativePathFromDirectory(sourceDirectory, moduleFileName, getCanonicalFileName)), moduleResolutionKind, addJsExtension); + if (!baseUrl || preferences.importModuleSpecifierPreference === "relative") { + return [relativePath]; + } + var relativeToBaseUrl = getRelativePathIfInDirectory(moduleFileName, baseUrl, getCanonicalFileName); + if (!relativeToBaseUrl) { + return [relativePath]; + } + var importRelativeToBaseUrl = removeExtensionAndIndexPostFix(relativeToBaseUrl, moduleResolutionKind, addJsExtension); + if (paths) { + var fromPaths = tryGetModuleNameFromPaths(ts.removeFileExtension(relativeToBaseUrl), importRelativeToBaseUrl, paths); + if (fromPaths) { + return [fromPaths]; + } + } + if (preferences.importModuleSpecifierPreference === "non-relative") { + return [importRelativeToBaseUrl]; + } + if (preferences.importModuleSpecifierPreference !== undefined) + ts.Debug.assertNever(preferences.importModuleSpecifierPreference); + if (isPathRelativeToParent(relativeToBaseUrl)) { + return [relativePath]; + } + /* + Prefer a relative import over a baseUrl import if it doesn't traverse up to baseUrl. + + Suppose we have: + baseUrl = /base + sourceDirectory = /base/a/b + moduleFileName = /base/foo/bar + Then: + relativePath = ../../foo/bar + getRelativePathNParents(relativePath) = 2 + pathFromSourceToBaseUrl = ../../ + getRelativePathNParents(pathFromSourceToBaseUrl) = 2 + 2 < 2 = false + In this case we should prefer using the baseUrl path "/a/b" instead of the relative path "../../foo/bar". + + Suppose we have: + baseUrl = /base + sourceDirectory = /base/foo/a + moduleFileName = /base/foo/bar + Then: + relativePath = ../a + getRelativePathNParents(relativePath) = 1 + pathFromSourceToBaseUrl = ../../ + getRelativePathNParents(pathFromSourceToBaseUrl) = 2 + 1 < 2 = true + In this case we should prefer using the relative path "../a" instead of the baseUrl path "foo/a". + */ + var pathFromSourceToBaseUrl = ts.ensurePathIsNonModuleName(ts.getRelativePathFromDirectory(sourceDirectory, baseUrl, getCanonicalFileName)); + var relativeFirst = getRelativePathNParents(relativePath) < getRelativePathNParents(pathFromSourceToBaseUrl); + return relativeFirst ? [relativePath, importRelativeToBaseUrl] : [importRelativeToBaseUrl, relativePath]; + } + function usesJsExtensionOnImports(_a) { + var imports = _a.imports; + return ts.firstDefined(imports, function (_a) { + var text = _a.text; + return ts.pathIsRelative(text) ? ts.fileExtensionIs(text, ".js" /* Js */) : undefined; + }) || false; + } + function discoverProbableSymlinks(files) { + var symlinks = ts.mapDefined(files, function (sf) { + return sf.resolvedModules && ts.firstDefinedIterator(sf.resolvedModules.values(), function (res) { + return res && res.originalPath && res.resolvedFileName !== res.originalPath ? [res.resolvedFileName, res.originalPath] : undefined; + }); + }); + var result = ts.createMap(); + if (symlinks) { + for (var _i = 0, symlinks_1 = symlinks; _i < symlinks_1.length; _i++) { + var _a = symlinks_1[_i], resolvedPath = _a[0], originalPath = _a[1]; + var resolvedParts = ts.getPathComponents(resolvedPath); + var originalParts = ts.getPathComponents(originalPath); + while (resolvedParts[resolvedParts.length - 1] === originalParts[originalParts.length - 1]) { + resolvedParts.pop(); + originalParts.pop(); + } + result.set(ts.getPathFromPathComponents(originalParts), ts.getPathFromPathComponents(resolvedParts)); + } + } + return result; + } + function getAllModulePathsUsingIndirectSymlinks(files, target, getCanonicalFileName, host) { + var links = discoverProbableSymlinks(files); + var paths = ts.arrayFrom(links.keys()); + var options; + for (var _i = 0, paths_2 = paths; _i < paths_2.length; _i++) { + var path = paths_2[_i]; + var resolved = links.get(path); + if (ts.startsWith(target, resolved + "/")) { + var relative = ts.getRelativePathFromDirectory(resolved, target, getCanonicalFileName); + var option = ts.resolvePath(path, relative); + if (!host.fileExists || host.fileExists(option)) { + if (!options) + options = []; + options.push(option); + } + } + } + var resolvedtarget = host.getCurrentDirectory ? ts.resolvePath(host.getCurrentDirectory(), target) : target; + if (options) { + options.push(resolvedtarget); // Since these are speculative, we also include the original resolved name as a possibility + return options; + } + return [resolvedtarget]; + } + /** + * Looks for a existing imports that use symlinks to this module. + * Only if no symlink is available, the real path will be used. + */ + function getAllModulePaths(files, _a, getCanonicalFileName, host) { + var fileName = _a.fileName; + var symlinks = ts.mapDefined(files, function (sf) { + return sf.resolvedModules && ts.firstDefinedIterator(sf.resolvedModules.values(), function (res) { + return res && res.resolvedFileName === fileName ? res.originalPath : undefined; + }); + }); + return symlinks.length === 0 ? getAllModulePathsUsingIndirectSymlinks(files, fileName, getCanonicalFileName, host) : symlinks; + } + function getRelativePathNParents(relativePath) { + var components = ts.getPathComponents(relativePath); + if (components[0] || components.length === 1) + return 0; + for (var i = 1; i < components.length; i++) { + if (components[i] !== "..") + return i - 1; + } + return components.length - 1; + } + function tryGetModuleNameFromAmbientModule(moduleSymbol) { + var decl = moduleSymbol.valueDeclaration; + if (ts.isModuleDeclaration(decl) && ts.isStringLiteral(decl.name)) { + return decl.name.text; + } + } + function tryGetModuleNameFromPaths(relativeToBaseUrlWithIndex, relativeToBaseUrl, paths) { + for (var key in paths) { + for (var _i = 0, _a = paths[key]; _i < _a.length; _i++) { + var patternText_1 = _a[_i]; + var pattern = ts.removeFileExtension(ts.normalizePath(patternText_1)); + var indexOfStar = pattern.indexOf("*"); + if (indexOfStar === 0 && pattern.length === 1) { + continue; + } + else if (indexOfStar !== -1) { + var prefix = pattern.substr(0, indexOfStar); + var suffix = pattern.substr(indexOfStar + 1); + if (relativeToBaseUrl.length >= prefix.length + suffix.length && + ts.startsWith(relativeToBaseUrl, prefix) && + ts.endsWith(relativeToBaseUrl, suffix)) { + var matchedStar = relativeToBaseUrl.substr(prefix.length, relativeToBaseUrl.length - suffix.length); + return key.replace("*", matchedStar); + } + } + else if (pattern === relativeToBaseUrl || pattern === relativeToBaseUrlWithIndex) { + return key; + } + } + } + } + function tryGetModuleNameFromRootDirs(rootDirs, moduleFileName, sourceDirectory, getCanonicalFileName) { + var normalizedTargetPath = getPathRelativeToRootDirs(moduleFileName, rootDirs, getCanonicalFileName); + if (normalizedTargetPath === undefined) { + return undefined; + } + var normalizedSourcePath = getPathRelativeToRootDirs(sourceDirectory, rootDirs, getCanonicalFileName); + var relativePath = normalizedSourcePath !== undefined ? ts.ensurePathIsNonModuleName(ts.getRelativePathFromDirectory(normalizedSourcePath, normalizedTargetPath, getCanonicalFileName)) : normalizedTargetPath; + return ts.removeFileExtension(relativePath); + } + function tryGetModuleNameFromTypeRoots(options, host, getCanonicalFileName, moduleFileName, addJsExtension) { + var roots = ts.getEffectiveTypeRoots(options, host); + return ts.firstDefined(roots, function (unNormalizedTypeRoot) { + var typeRoot = ts.toPath(unNormalizedTypeRoot, /*basePath*/ undefined, getCanonicalFileName); + if (ts.startsWith(moduleFileName, typeRoot)) { + // For a type definition, we can strip `/index` even with classic resolution. + return removeExtensionAndIndexPostFix(moduleFileName.substring(typeRoot.length + 1), ts.ModuleResolutionKind.NodeJs, addJsExtension); + } + }); + } + function tryGetModuleNameAsNodeModule(options, moduleFileName, host, getCanonicalFileName, sourceDirectory) { + if (ts.getEmitModuleResolutionKind(options) !== ts.ModuleResolutionKind.NodeJs) { + // nothing to do here + return undefined; + } + var parts = getNodeModulePathParts(moduleFileName); + if (!parts) { + return undefined; + } + // Simplify the full file path to something that can be resolved by Node. + // If the module could be imported by a directory name, use that directory's name + var moduleSpecifier = getDirectoryOrExtensionlessFileName(moduleFileName); + // Get a path that's relative to node_modules or the importing file's path + moduleSpecifier = getNodeResolvablePath(moduleSpecifier); + // If the module was found in @types, get the actual Node package name + return ts.getPackageNameFromAtTypesDirectory(moduleSpecifier); + function getDirectoryOrExtensionlessFileName(path) { + // If the file is the main module, it can be imported by the package name + var packageRootPath = path.substring(0, parts.packageRootIndex); + var packageJsonPath = ts.combinePaths(packageRootPath, "package.json"); + if (host.fileExists(packageJsonPath)) { + var packageJsonContent = JSON.parse(host.readFile(packageJsonPath)); + if (packageJsonContent) { + var mainFileRelative = packageJsonContent.typings || packageJsonContent.types || packageJsonContent.main; + if (mainFileRelative) { + var mainExportFile = ts.toPath(mainFileRelative, packageRootPath, getCanonicalFileName); + if (mainExportFile === getCanonicalFileName(path)) { + return packageRootPath; + } + } + } + } + // We still have a file name - remove the extension + var fullModulePathWithoutExtension = ts.removeFileExtension(path); + // If the file is /index, it can be imported by its directory name + // IFF there is not _also_ a file by the same name + if (getCanonicalFileName(fullModulePathWithoutExtension.substring(parts.fileNameIndex)) === "/index" && !tryGetAnyFileFromPath(host, fullModulePathWithoutExtension.substring(0, parts.fileNameIndex))) { + return fullModulePathWithoutExtension.substring(0, parts.fileNameIndex); + } + return fullModulePathWithoutExtension; + } + function getNodeResolvablePath(path) { + var basePath = path.substring(0, parts.topLevelNodeModulesIndex); + if (sourceDirectory.indexOf(basePath) === 0) { + // if node_modules folder is in this folder or any of its parent folders, no need to keep it. + return path.substring(parts.topLevelPackageNameIndex + 1); + } + else { + return ts.ensurePathIsNonModuleName(ts.getRelativePathFromDirectory(sourceDirectory, path, getCanonicalFileName)); + } + } + } + function tryGetAnyFileFromPath(host, path) { + // We check all js, `node` and `json` extensions in addition to TS, since node module resolution would also choose those over the directory + var extensions = ts.getSupportedExtensions({ allowJs: true }, [{ extension: "node", isMixedContent: false }, { extension: "json", isMixedContent: false, scriptKind: 6 /* JSON */ }]); + for (var _i = 0, extensions_3 = extensions; _i < extensions_3.length; _i++) { + var e = extensions_3[_i]; + var fullPath = path + e; + if (host.fileExists(fullPath)) { // TODO: GH#18217 + return fullPath; + } + } + } + function getNodeModulePathParts(fullPath) { + // 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: ^ ^ ^ ^ + var topLevelNodeModulesIndex = 0; + var topLevelPackageNameIndex = 0; + var packageRootIndex = 0; + var fileNameIndex = 0; + var States; + (function (States) { + States[States["BeforeNodeModules"] = 0] = "BeforeNodeModules"; + States[States["NodeModules"] = 1] = "NodeModules"; + States[States["Scope"] = 2] = "Scope"; + States[States["PackageContent"] = 3] = "PackageContent"; + })(States || (States = {})); + var partStart = 0; + var partEnd = 0; + var state = 0 /* BeforeNodeModules */; + while (partEnd >= 0) { + partStart = partEnd; + partEnd = fullPath.indexOf("/", partStart + 1); + switch (state) { + case 0 /* BeforeNodeModules */: + if (fullPath.indexOf("/node_modules/", partStart) === partStart) { + topLevelNodeModulesIndex = partStart; + topLevelPackageNameIndex = partEnd; + state = 1 /* NodeModules */; + } + break; + case 1 /* NodeModules */: + case 2 /* Scope */: + if (state === 1 /* NodeModules */ && fullPath.charAt(partStart + 1) === "@") { + state = 2 /* Scope */; + } + else { + packageRootIndex = partEnd; + state = 3 /* PackageContent */; + } + break; + case 3 /* PackageContent */: + if (fullPath.indexOf("/node_modules/", partStart) === partStart) { + state = 1 /* NodeModules */; + } + else { + state = 3 /* PackageContent */; + } + break; + } + } + fileNameIndex = partStart; + return state > 1 /* NodeModules */ ? { topLevelNodeModulesIndex: topLevelNodeModulesIndex, topLevelPackageNameIndex: topLevelPackageNameIndex, packageRootIndex: packageRootIndex, fileNameIndex: fileNameIndex } : undefined; + } + function getPathRelativeToRootDirs(path, rootDirs, getCanonicalFileName) { + return ts.firstDefined(rootDirs, function (rootDir) { + var relativePath = getRelativePathIfInDirectory(path, rootDir, getCanonicalFileName); + return isPathRelativeToParent(relativePath) ? undefined : relativePath; + }); + } + function removeExtensionAndIndexPostFix(fileName, moduleResolutionKind, addJsExtension) { + var noExtension = ts.removeFileExtension(fileName); + return addJsExtension + ? noExtension + ".js" + : moduleResolutionKind === ts.ModuleResolutionKind.NodeJs + ? ts.removeSuffix(noExtension, "/index") + : noExtension; + } + function getRelativePathIfInDirectory(path, directoryPath, getCanonicalFileName) { + var relativePath = ts.getRelativePathToDirectoryOrUrl(directoryPath, path, directoryPath, getCanonicalFileName, /*isAbsolutePathAnUrl*/ false); + return ts.isRootedDiskPath(relativePath) ? undefined : relativePath; + } + function isPathRelativeToParent(path) { + return ts.startsWith(path, ".."); + } + })(moduleSpecifiers = ts.moduleSpecifiers || (ts.moduleSpecifiers = {})); +})(ts || (ts = {})); /*@internal*/ var ts; (function (ts) { @@ -92141,7 +92494,7 @@ var ts; // TODO:GH#18217 ? getSourceFileToImportFromResolved(ts.resolveModuleName(importLiteral.text, oldImportFromPath, program.getCompilerOptions(), host), oldToNew, program) : getSourceFileToImport(importLiteral, sourceFile, program, host, oldToNew); - return toImport === undefined ? undefined : ts.moduleSpecifiers.getModuleSpecifier(program, sourceFile, newImportFromPath, toImport, host, preferences); + return toImport === undefined ? undefined : ts.moduleSpecifiers.getModuleSpecifier(program.getCompilerOptions(), sourceFile, newImportFromPath, toImport, host, preferences); }); }; for (var _i = 0, _a = program.getSourceFiles(); _i < _a.length; _i++) { @@ -95616,7 +95969,7 @@ var ts; ts.Debug.assert(indexOfOpenerToken >= 0 && children.length > indexOfOpenerToken + 1); return children[indexOfOpenerToken + 1]; } - var signatureHelpNodeBuilderFlags = 8192 /* OmitParameterModifiers */ | 3112960 /* IgnoreErrors */; + var signatureHelpNodeBuilderFlags = 8192 /* OmitParameterModifiers */ | 3112960 /* IgnoreErrors */ | 16384 /* UseAliasDefinedOutsideCurrentScope */; function createSignatureHelpItems(candidates, resolvedSignature, argumentListInfo, typeChecker) { var argumentCount = argumentListInfo.argumentCount, applicableSpan = argumentListInfo.argumentsSpan, invocation = argumentListInfo.invocation, argumentIndex = argumentListInfo.argumentIndex; var isTypeParameterList = argumentListInfo.kind === 0 /* TypeArguments */; @@ -101216,7 +101569,7 @@ var ts; function getNewImportInfos(program, sourceFile, moduleSymbols, host, preferences) { var choicesForEachExportingModule = ts.flatMap(moduleSymbols, function (_a) { var moduleSymbol = _a.moduleSymbol, importKind = _a.importKind; - var modulePathsGroups = ts.moduleSpecifiers.getModuleSpecifiers(moduleSymbol, program, sourceFile, host, preferences); + var modulePathsGroups = ts.moduleSpecifiers.getModuleSpecifiers(moduleSymbol, program.getCompilerOptions(), sourceFile, host, program.getSourceFiles(), preferences); return modulePathsGroups.map(function (group) { return group.map(function (moduleSpecifier) { return ({ moduleSpecifier: moduleSpecifier, importKind: importKind }); }); }); }); // Sort to keep the shortest paths first, but keep [relativePath, importRelativeToBaseUrl] groups together @@ -103580,311 +103933,6 @@ var ts; } })(codefix = ts.codefix || (ts.codefix = {})); })(ts || (ts = {})); -// Used by importFixes to synthesize import module specifiers. -/* @internal */ -var ts; -(function (ts) { - var moduleSpecifiers; - (function (moduleSpecifiers) { - // Note: fromSourceFile is just for usesJsExtensionOnImports - function getModuleSpecifier(program, fromSourceFile, fromSourceFileName, toFileName, host, preferences) { - var info = getInfo(program.getCompilerOptions(), fromSourceFile, fromSourceFileName, host); - var compilerOptions = program.getCompilerOptions(); - return getGlobalModuleSpecifier(toFileName, info, host, compilerOptions) || - ts.first(getLocalModuleSpecifiers(toFileName, info, compilerOptions, preferences)); - } - moduleSpecifiers.getModuleSpecifier = getModuleSpecifier; - // For each symlink/original for a module, returns a list of ways to import that file. - function getModuleSpecifiers(moduleSymbol, program, importingSourceFile, host, preferences) { - var ambient = tryGetModuleNameFromAmbientModule(moduleSymbol); - if (ambient) - return [[ambient]]; - var compilerOptions = program.getCompilerOptions(); - var info = getInfo(compilerOptions, importingSourceFile, importingSourceFile.fileName, host); - var modulePaths = getAllModulePaths(program, moduleSymbol.valueDeclaration.getSourceFile()); - var global = ts.mapDefined(modulePaths, function (moduleFileName) { return getGlobalModuleSpecifier(moduleFileName, info, host, compilerOptions); }); - return global.length ? global.map(function (g) { return [g]; }) : modulePaths.map(function (moduleFileName) { - return getLocalModuleSpecifiers(moduleFileName, info, compilerOptions, preferences); - }); - } - moduleSpecifiers.getModuleSpecifiers = getModuleSpecifiers; - // importingSourceFileName is separate because getEditsForFileRename may need to specify an updated path - function getInfo(compilerOptions, importingSourceFile, importingSourceFileName, host) { - var moduleResolutionKind = ts.getEmitModuleResolutionKind(compilerOptions); - var addJsExtension = usesJsExtensionOnImports(importingSourceFile); - var getCanonicalFileName = ts.hostGetCanonicalFileName(host); - var sourceDirectory = ts.getDirectoryPath(importingSourceFileName); - return { moduleResolutionKind: moduleResolutionKind, addJsExtension: addJsExtension, getCanonicalFileName: getCanonicalFileName, sourceDirectory: sourceDirectory }; - } - function getGlobalModuleSpecifier(moduleFileName, _a, host, compilerOptions) { - var addJsExtension = _a.addJsExtension, getCanonicalFileName = _a.getCanonicalFileName, sourceDirectory = _a.sourceDirectory; - return tryGetModuleNameFromTypeRoots(compilerOptions, host, getCanonicalFileName, moduleFileName, addJsExtension) - || tryGetModuleNameAsNodeModule(compilerOptions, moduleFileName, host, getCanonicalFileName, sourceDirectory) - || compilerOptions.rootDirs && tryGetModuleNameFromRootDirs(compilerOptions.rootDirs, moduleFileName, sourceDirectory, getCanonicalFileName); - } - function getLocalModuleSpecifiers(moduleFileName, _a, compilerOptions, preferences) { - var moduleResolutionKind = _a.moduleResolutionKind, addJsExtension = _a.addJsExtension, getCanonicalFileName = _a.getCanonicalFileName, sourceDirectory = _a.sourceDirectory; - var baseUrl = compilerOptions.baseUrl, paths = compilerOptions.paths; - var relativePath = removeExtensionAndIndexPostFix(ts.ensurePathIsNonModuleName(ts.getRelativePathFromDirectory(sourceDirectory, moduleFileName, getCanonicalFileName)), moduleResolutionKind, addJsExtension); - if (!baseUrl || preferences.importModuleSpecifierPreference === "relative") { - return [relativePath]; - } - var relativeToBaseUrl = getRelativePathIfInDirectory(moduleFileName, baseUrl, getCanonicalFileName); - if (!relativeToBaseUrl) { - return [relativePath]; - } - var importRelativeToBaseUrl = removeExtensionAndIndexPostFix(relativeToBaseUrl, moduleResolutionKind, addJsExtension); - if (paths) { - var fromPaths = tryGetModuleNameFromPaths(ts.removeFileExtension(relativeToBaseUrl), importRelativeToBaseUrl, paths); - if (fromPaths) { - return [fromPaths]; - } - } - if (preferences.importModuleSpecifierPreference === "non-relative") { - return [importRelativeToBaseUrl]; - } - if (preferences.importModuleSpecifierPreference !== undefined) - ts.Debug.assertNever(preferences.importModuleSpecifierPreference); - if (isPathRelativeToParent(relativeToBaseUrl)) { - return [relativePath]; - } - /* - Prefer a relative import over a baseUrl import if it doesn't traverse up to baseUrl. - - Suppose we have: - baseUrl = /base - sourceDirectory = /base/a/b - moduleFileName = /base/foo/bar - Then: - relativePath = ../../foo/bar - getRelativePathNParents(relativePath) = 2 - pathFromSourceToBaseUrl = ../../ - getRelativePathNParents(pathFromSourceToBaseUrl) = 2 - 2 < 2 = false - In this case we should prefer using the baseUrl path "/a/b" instead of the relative path "../../foo/bar". - - Suppose we have: - baseUrl = /base - sourceDirectory = /base/foo/a - moduleFileName = /base/foo/bar - Then: - relativePath = ../a - getRelativePathNParents(relativePath) = 1 - pathFromSourceToBaseUrl = ../../ - getRelativePathNParents(pathFromSourceToBaseUrl) = 2 - 1 < 2 = true - In this case we should prefer using the relative path "../a" instead of the baseUrl path "foo/a". - */ - var pathFromSourceToBaseUrl = ts.ensurePathIsNonModuleName(ts.getRelativePathFromDirectory(sourceDirectory, baseUrl, getCanonicalFileName)); - var relativeFirst = getRelativePathNParents(relativePath) < getRelativePathNParents(pathFromSourceToBaseUrl); - return relativeFirst ? [relativePath, importRelativeToBaseUrl] : [importRelativeToBaseUrl, relativePath]; - } - function usesJsExtensionOnImports(_a) { - var imports = _a.imports; - return ts.firstDefined(imports, function (_a) { - var text = _a.text; - return ts.pathIsRelative(text) ? ts.fileExtensionIs(text, ".js" /* Js */) : undefined; - }) || false; - } - /** - * Looks for a existing imports that use symlinks to this module. - * Only if no symlink is available, the real path will be used. - */ - function getAllModulePaths(program, _a) { - var fileName = _a.fileName; - var symlinks = ts.mapDefined(program.getSourceFiles(), function (sf) { - return sf.resolvedModules && ts.firstDefinedIterator(sf.resolvedModules.values(), function (res) { - return res && res.resolvedFileName === fileName ? res.originalPath : undefined; - }); - }); - return symlinks.length === 0 ? [fileName] : symlinks; - } - function getRelativePathNParents(relativePath) { - var components = ts.getPathComponents(relativePath); - if (components[0] || components.length === 1) - return 0; - for (var i = 1; i < components.length; i++) { - if (components[i] !== "..") - return i - 1; - } - return components.length - 1; - } - function tryGetModuleNameFromAmbientModule(moduleSymbol) { - var decl = moduleSymbol.valueDeclaration; - if (ts.isModuleDeclaration(decl) && ts.isStringLiteral(decl.name)) { - return decl.name.text; - } - } - function tryGetModuleNameFromPaths(relativeToBaseUrlWithIndex, relativeToBaseUrl, paths) { - for (var key in paths) { - for (var _i = 0, _a = paths[key]; _i < _a.length; _i++) { - var patternText_1 = _a[_i]; - var pattern = ts.removeFileExtension(ts.normalizePath(patternText_1)); - var indexOfStar = pattern.indexOf("*"); - if (indexOfStar === 0 && pattern.length === 1) { - continue; - } - else if (indexOfStar !== -1) { - var prefix = pattern.substr(0, indexOfStar); - var suffix = pattern.substr(indexOfStar + 1); - if (relativeToBaseUrl.length >= prefix.length + suffix.length && - ts.startsWith(relativeToBaseUrl, prefix) && - ts.endsWith(relativeToBaseUrl, suffix)) { - var matchedStar = relativeToBaseUrl.substr(prefix.length, relativeToBaseUrl.length - suffix.length); - return key.replace("*", matchedStar); - } - } - else if (pattern === relativeToBaseUrl || pattern === relativeToBaseUrlWithIndex) { - return key; - } - } - } - } - function tryGetModuleNameFromRootDirs(rootDirs, moduleFileName, sourceDirectory, getCanonicalFileName) { - var normalizedTargetPath = getPathRelativeToRootDirs(moduleFileName, rootDirs, getCanonicalFileName); - if (normalizedTargetPath === undefined) { - return undefined; - } - var normalizedSourcePath = getPathRelativeToRootDirs(sourceDirectory, rootDirs, getCanonicalFileName); - var relativePath = normalizedSourcePath !== undefined ? ts.ensurePathIsNonModuleName(ts.getRelativePathFromDirectory(normalizedSourcePath, normalizedTargetPath, getCanonicalFileName)) : normalizedTargetPath; - return ts.removeFileExtension(relativePath); - } - function tryGetModuleNameFromTypeRoots(options, host, getCanonicalFileName, moduleFileName, addJsExtension) { - var roots = ts.getEffectiveTypeRoots(options, host); - return ts.firstDefined(roots, function (unNormalizedTypeRoot) { - var typeRoot = ts.toPath(unNormalizedTypeRoot, /*basePath*/ undefined, getCanonicalFileName); - if (ts.startsWith(moduleFileName, typeRoot)) { - // For a type definition, we can strip `/index` even with classic resolution. - return removeExtensionAndIndexPostFix(moduleFileName.substring(typeRoot.length + 1), ts.ModuleResolutionKind.NodeJs, addJsExtension); - } - }); - } - function tryGetModuleNameAsNodeModule(options, moduleFileName, host, getCanonicalFileName, sourceDirectory) { - if (ts.getEmitModuleResolutionKind(options) !== ts.ModuleResolutionKind.NodeJs) { - // nothing to do here - return undefined; - } - var parts = getNodeModulePathParts(moduleFileName); - if (!parts) { - return undefined; - } - // Simplify the full file path to something that can be resolved by Node. - // If the module could be imported by a directory name, use that directory's name - var moduleSpecifier = getDirectoryOrExtensionlessFileName(moduleFileName); - // Get a path that's relative to node_modules or the importing file's path - moduleSpecifier = getNodeResolvablePath(moduleSpecifier); - // If the module was found in @types, get the actual Node package name - return ts.getPackageNameFromAtTypesDirectory(moduleSpecifier); - function getDirectoryOrExtensionlessFileName(path) { - // If the file is the main module, it can be imported by the package name - var packageRootPath = path.substring(0, parts.packageRootIndex); - var packageJsonPath = ts.combinePaths(packageRootPath, "package.json"); - if (host.fileExists(packageJsonPath)) { - var packageJsonContent = JSON.parse(host.readFile(packageJsonPath)); - if (packageJsonContent) { - var mainFileRelative = packageJsonContent.typings || packageJsonContent.types || packageJsonContent.main; - if (mainFileRelative) { - var mainExportFile = ts.toPath(mainFileRelative, packageRootPath, getCanonicalFileName); - if (mainExportFile === getCanonicalFileName(path)) { - return packageRootPath; - } - } - } - } - // We still have a file name - remove the extension - var fullModulePathWithoutExtension = ts.removeFileExtension(path); - // If the file is /index, it can be imported by its directory name - if (getCanonicalFileName(fullModulePathWithoutExtension.substring(parts.fileNameIndex)) === "/index") { - return fullModulePathWithoutExtension.substring(0, parts.fileNameIndex); - } - return fullModulePathWithoutExtension; - } - function getNodeResolvablePath(path) { - var basePath = path.substring(0, parts.topLevelNodeModulesIndex); - if (sourceDirectory.indexOf(basePath) === 0) { - // if node_modules folder is in this folder or any of its parent folders, no need to keep it. - return path.substring(parts.topLevelPackageNameIndex + 1); - } - else { - return ts.ensurePathIsNonModuleName(ts.getRelativePathFromDirectory(sourceDirectory, path, getCanonicalFileName)); - } - } - } - function getNodeModulePathParts(fullPath) { - // 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: ^ ^ ^ ^ - var topLevelNodeModulesIndex = 0; - var topLevelPackageNameIndex = 0; - var packageRootIndex = 0; - var fileNameIndex = 0; - var States; - (function (States) { - States[States["BeforeNodeModules"] = 0] = "BeforeNodeModules"; - States[States["NodeModules"] = 1] = "NodeModules"; - States[States["Scope"] = 2] = "Scope"; - States[States["PackageContent"] = 3] = "PackageContent"; - })(States || (States = {})); - var partStart = 0; - var partEnd = 0; - var state = 0 /* BeforeNodeModules */; - while (partEnd >= 0) { - partStart = partEnd; - partEnd = fullPath.indexOf("/", partStart + 1); - switch (state) { - case 0 /* BeforeNodeModules */: - if (fullPath.indexOf("/node_modules/", partStart) === partStart) { - topLevelNodeModulesIndex = partStart; - topLevelPackageNameIndex = partEnd; - state = 1 /* NodeModules */; - } - break; - case 1 /* NodeModules */: - case 2 /* Scope */: - if (state === 1 /* NodeModules */ && fullPath.charAt(partStart + 1) === "@") { - state = 2 /* Scope */; - } - else { - packageRootIndex = partEnd; - state = 3 /* PackageContent */; - } - break; - case 3 /* PackageContent */: - if (fullPath.indexOf("/node_modules/", partStart) === partStart) { - state = 1 /* NodeModules */; - } - else { - state = 3 /* PackageContent */; - } - break; - } - } - fileNameIndex = partStart; - return state > 1 /* NodeModules */ ? { topLevelNodeModulesIndex: topLevelNodeModulesIndex, topLevelPackageNameIndex: topLevelPackageNameIndex, packageRootIndex: packageRootIndex, fileNameIndex: fileNameIndex } : undefined; - } - function getPathRelativeToRootDirs(path, rootDirs, getCanonicalFileName) { - return ts.firstDefined(rootDirs, function (rootDir) { - var relativePath = getRelativePathIfInDirectory(path, rootDir, getCanonicalFileName); - return isPathRelativeToParent(relativePath) ? undefined : relativePath; - }); - } - function removeExtensionAndIndexPostFix(fileName, moduleResolutionKind, addJsExtension) { - var noExtension = ts.removeFileExtension(fileName); - return addJsExtension - ? noExtension + ".js" - : moduleResolutionKind === ts.ModuleResolutionKind.NodeJs - ? ts.removeSuffix(noExtension, "/index") - : noExtension; - } - function getRelativePathIfInDirectory(path, directoryPath, getCanonicalFileName) { - var relativePath = ts.getRelativePathToDirectoryOrUrl(directoryPath, path, directoryPath, getCanonicalFileName, /*isAbsolutePathAnUrl*/ false); - return ts.isRootedDiskPath(relativePath) ? undefined : relativePath; - } - function isPathRelativeToParent(path) { - return ts.startsWith(path, ".."); - } - })(moduleSpecifiers = ts.moduleSpecifiers || (ts.moduleSpecifiers = {})); -})(ts || (ts = {})); /* @internal */ var ts; (function (ts) { @@ -106362,7 +106410,7 @@ var ts; getGeneratedPosition: getGeneratedPosition }; function getGeneratedPosition(loc) { - var maps = getGeneratedOrderedMappings(); + var maps = getSourceOrderedMappings(); if (!ts.length(maps)) return loc; var targetIndex = ts.binarySearch(maps, { sourcePath: loc.fileName, sourcePosition: loc.position }, ts.identity, compareProcessedPositionSourcePositions); @@ -106376,7 +106424,7 @@ var ts; return { fileName: ts.toPath(map.file, sourceRoot, host.getCanonicalFileName), position: maps[targetIndex].emittedPosition }; // Closest pos } function getOriginalPosition(loc) { - var maps = getSourceOrderedMappings(); + var maps = getGeneratedOrderedMappings(); if (!ts.length(maps)) return loc; var targetIndex = ts.binarySearch(maps, { emittedPosition: loc.position }, ts.identity, compareProcessedPositionEmittedPositions);