Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 5ce32cc

Browse filesBrowse files
committed
factor out helpers + cleanup startsWith and friends
1 parent f2e5fa5 commit 5ce32cc
Copy full SHA for 5ce32cc

4 files changed

+31-22Lines changed: 31 additions & 22 deletions

File tree

Expand file treeCollapse file tree
Open diff view settings
Filter options
Expand file treeCollapse file tree
Open diff view settings
Collapse file

‎src/compiler/core.ts‎

Copy file name to clipboardExpand all lines: src/compiler/core.ts
+9-4Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1730,13 +1730,18 @@ namespace ts {
17301730

17311731
/* @internal */
17321732
export function startsWith(str: string, prefix: string): boolean {
1733-
return str.lastIndexOf(prefix, 0) === 0;
1733+
return str.indexOf(prefix) === 0;
1734+
}
1735+
1736+
/* @internal */
1737+
export function removePrefix(str: string, prefix: string | undefined): string {
1738+
return startsWith(str, prefix) ? str.substr(prefix.length) : str;
17341739
}
17351740

17361741
/* @internal */
17371742
export function endsWith(str: string, suffix: string): boolean {
17381743
const expectedPos = str.length - suffix.length;
1739-
return expectedPos >= 0 && str.indexOf(suffix, expectedPos) === expectedPos;
1744+
return expectedPos >= 0 && str.lastIndexOf(suffix, expectedPos) === expectedPos;
17401745
}
17411746

17421747
export function hasExtension(fileName: string): boolean {
@@ -1747,7 +1752,7 @@ namespace ts {
17471752
return path.length > extension.length && endsWith(path, extension);
17481753
}
17491754

1750-
export function fileExtensionIsAny(path: string, extensions: string[]): boolean {
1755+
export function fileExtensionIsOneOf(path: string, extensions: string[]): boolean {
17511756
for (const extension of extensions) {
17521757
if (fileExtensionIs(path, extension)) {
17531758
return true;
@@ -1947,7 +1952,7 @@ namespace ts {
19471952
for (const current of files) {
19481953
const name = combinePaths(path, current);
19491954
const absoluteName = combinePaths(absolutePath, current);
1950-
if (extensions && !fileExtensionIsAny(name, extensions)) continue;
1955+
if (extensions && !fileExtensionIsOneOf(name, extensions)) continue;
19511956
if (excludeRegex && excludeRegex.test(absoluteName)) continue;
19521957
if (!includeFileRegexes) {
19531958
results[0].push(name);
Collapse file

‎src/compiler/moduleNameResolver.ts‎

Copy file name to clipboardExpand all lines: src/compiler/moduleNameResolver.ts
+14-1Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -958,10 +958,13 @@ namespace ts {
958958
}
959959
}
960960

961+
/** Double underscores are used in DefinitelyTyped to delimit scoped packages. */
962+
const mangledScopedPackageSeparator = "__";
963+
961964
/** For a scoped package, we must look in `@types/foo__bar` instead of `@types/@foo/bar`. */
962965
function mangleScopedPackage(moduleName: string, state: ModuleResolutionState): string {
963966
if (startsWith(moduleName, "@")) {
964-
const replaceSlash = moduleName.replace(ts.directorySeparator, "__");
967+
const replaceSlash = moduleName.replace(ts.directorySeparator, mangledScopedPackageSeparator);
965968
if (replaceSlash !== moduleName) {
966969
const mangled = replaceSlash.slice(1); // Take off the "@"
967970
if (state.traceEnabled) {
@@ -973,6 +976,16 @@ namespace ts {
973976
return moduleName;
974977
}
975978

979+
export function getPackageNameFromAtTypesDirectory(mangledName: string): string {
980+
const withoutAtTypePrefix = removePrefix(mangledName, "@types/");
981+
if (withoutAtTypePrefix !== mangledName) {
982+
return withoutAtTypePrefix.indexOf("__") !== -1 ?
983+
"@" + withoutAtTypePrefix.replace(mangledScopedPackageSeparator, ts.directorySeparator) :
984+
withoutAtTypePrefix;
985+
}
986+
return mangledName;
987+
}
988+
976989
function tryFindNonRelativeModuleNameInCache(cache: PerModuleNameCache | undefined, moduleName: string, containingDirectory: string, traceEnabled: boolean, host: ModuleResolutionHost): SearchResult<Resolved> {
977990
const result = cache && cache.get(containingDirectory);
978991
if (result) {
Collapse file

‎src/services/codefixes/importFixes.ts‎

Copy file name to clipboardExpand all lines: src/services/codefixes/importFixes.ts
+2-8Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -501,14 +501,6 @@ namespace ts.codefix {
501501
relativeFileName = getRelativePath(moduleFileName, sourceDirectory);
502502
}
503503

504-
if (startsWith(relativeFileName, "@types/")) {
505-
relativeFileName = relativeFileName.substr(/*"@types".length*/ 7);
506-
if (relativeFileName.indexOf("__") !== -1) {
507-
// Double underscores are used in DefinitelyTyped to delimit scoped packages.
508-
relativeFileName = "@" + relativeFileName.replace("__", "/");
509-
}
510-
}
511-
512504
relativeFileName = removeFileExtension(relativeFileName);
513505
if (endsWith(relativeFileName, "/index")) {
514506
relativeFileName = getDirectoryPath(relativeFileName);
@@ -530,6 +522,8 @@ namespace ts.codefix {
530522
catch (e) { }
531523
}
532524

525+
relativeFileName = getPackageNameFromAtTypesDirectory(relativeFileName);
526+
533527
return relativeFileName;
534528
}
535529
}
Collapse file

‎src/services/pathCompletions.ts‎

Copy file name to clipboardExpand all lines: src/services/pathCompletions.ts
+6-9Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -245,41 +245,38 @@ namespace ts.Completions.PathCompletions {
245245

246246
// Get modules that the type checker picked up
247247
const ambientModules = map(typeChecker.getAmbientModules(), sym => stripQuotes(sym.name));
248-
let nonRelativeModules = filter(ambientModules, moduleName => startsWith(moduleName, fragment));
248+
let nonRelativeModuleNames = filter(ambientModules, moduleName => startsWith(moduleName, fragment));
249249

250250
// Nested modules of the form "module-name/sub" need to be adjusted to only return the string
251251
// after the last '/' that appears in the fragment because that's where the replacement span
252252
// starts
253253
if (isNestedModule) {
254254
const moduleNameWithSeperator = ensureTrailingDirectorySeparator(moduleNameFragment);
255-
nonRelativeModules = map(nonRelativeModules, moduleName => {
256-
if (startsWith(fragment, moduleNameWithSeperator)) {
257-
return moduleName.substr(moduleNameWithSeperator.length);
258-
}
259-
return moduleName;
255+
nonRelativeModuleNames = map(nonRelativeModuleNames, nonRelativeModuleName => {
256+
return removePrefix(nonRelativeModuleName, moduleNameWithSeperator);
260257
});
261258
}
262259

263260

264261
if (!options.moduleResolution || options.moduleResolution === ModuleResolutionKind.NodeJs) {
265262
for (const visibleModule of enumerateNodeModulesVisibleToScript(host, scriptPath)) {
266263
if (!isNestedModule) {
267-
nonRelativeModules.push(visibleModule.moduleName);
264+
nonRelativeModuleNames.push(visibleModule.moduleName);
268265
}
269266
else if (startsWith(visibleModule.moduleName, moduleNameFragment)) {
270267
const nestedFiles = tryReadDirectory(host, visibleModule.moduleDir, supportedTypeScriptExtensions, /*exclude*/ undefined, /*include*/ ["./*"]);
271268
if (nestedFiles) {
272269
for (let f of nestedFiles) {
273270
f = normalizePath(f);
274271
const nestedModule = removeFileExtension(getBaseFileName(f));
275-
nonRelativeModules.push(nestedModule);
272+
nonRelativeModuleNames.push(nestedModule);
276273
}
277274
}
278275
}
279276
}
280277
}
281278

282-
return deduplicate(nonRelativeModules);
279+
return deduplicate(nonRelativeModuleNames);
283280
}
284281

285282
export function getTripleSlashReferenceCompletion(sourceFile: SourceFile, position: number, compilerOptions: CompilerOptions, host: LanguageServiceHost): CompletionInfo {

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.