Skip to content

Commit 4af2dcd

Browse files
committed
Consume exceptions when checking for import completions
1 parent f16edf9 commit 4af2dcd

1 file changed

Lines changed: 72 additions & 32 deletions

File tree

src/services/completions.ts

Lines changed: 72 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -335,10 +335,11 @@ namespace ts.Completions {
335335
const baseDirectory = getDirectoryPath(absolutePath);
336336
const ignoreCase = !(host.useCaseSensitiveFileNames && host.useCaseSensitiveFileNames());
337337

338-
if (directoryProbablyExists(baseDirectory, host)) {
339-
if (host.readDirectory) {
340-
// Enumerate the available files if possible
341-
const files = host.readDirectory(baseDirectory, extensions, /*exclude*/undefined, /*include*/["./*"]);
338+
if (tryDirectoryExists(host, baseDirectory)) {
339+
// Enumerate the available files if possible
340+
const files = tryReadDirectory(host, baseDirectory, extensions, /*exclude*/undefined, /*include*/["./*"]);
341+
342+
if (files) {
342343
const foundFiles = createMap<boolean>();
343344
for (let filePath of files) {
344345
filePath = normalizePath(filePath);
@@ -359,8 +360,9 @@ namespace ts.Completions {
359360
}
360361

361362
// If possible, get folder completion as well
362-
if (host.getDirectories) {
363-
const directories = host.getDirectories(baseDirectory);
363+
const directories = tryGetDirectories(host, baseDirectory);
364+
365+
if (directories) {
364366
for (const directory of directories) {
365367
const directoryName = getBaseFileName(normalizePath(directory));
366368

@@ -449,22 +451,24 @@ namespace ts.Completions {
449451
// doesn't support. For now, this is safer but slower
450452
const includeGlob = normalizedSuffix ? "**/*" : "./*";
451453

452-
const matches = host.readDirectory(baseDirectory, fileExtensions, undefined, [includeGlob]);
453-
const result: string[] = [];
454+
const matches = tryReadDirectory(host, baseDirectory, fileExtensions, undefined, [includeGlob]);
455+
if (matches) {
456+
const result: string[] = [];
454457

455-
// Trim away prefix and suffix
456-
for (const match of matches) {
457-
const normalizedMatch = normalizePath(match);
458-
if (!endsWith(normalizedMatch, normalizedSuffix) || !startsWith(normalizedMatch, completePrefix)) {
459-
continue;
460-
}
458+
// Trim away prefix and suffix
459+
for (const match of matches) {
460+
const normalizedMatch = normalizePath(match);
461+
if (!endsWith(normalizedMatch, normalizedSuffix) || !startsWith(normalizedMatch, completePrefix)) {
462+
continue;
463+
}
461464

462-
const start = completePrefix.length;
463-
const length = normalizedMatch.length - start - normalizedSuffix.length;
465+
const start = completePrefix.length;
466+
const length = normalizedMatch.length - start - normalizedSuffix.length;
464467

465-
result.push(removeFileExtension(normalizedMatch.substr(start, length)));
468+
result.push(removeFileExtension(normalizedMatch.substr(start, length)));
469+
}
470+
return result;
466471
}
467-
return result;
468472
}
469473
}
470474

@@ -499,13 +503,14 @@ namespace ts.Completions {
499503
if (!isNestedModule) {
500504
nonRelativeModules.push(visibleModule.moduleName);
501505
}
502-
else if (host.readDirectory && startsWith(visibleModule.moduleName, moduleNameFragment)) {
503-
const nestedFiles = host.readDirectory(visibleModule.moduleDir, supportedTypeScriptExtensions, /*exclude*/undefined, /*include*/["./*"]);
504-
505-
for (let f of nestedFiles) {
506-
f = normalizePath(f);
507-
const nestedModule = removeFileExtension(getBaseFileName(f));
508-
nonRelativeModules.push(nestedModule);
506+
else if (startsWith(visibleModule.moduleName, moduleNameFragment)) {
507+
const nestedFiles = tryReadDirectory(host, visibleModule.moduleDir, supportedTypeScriptExtensions, /*exclude*/undefined, /*include*/["./*"]);
508+
if (nestedFiles) {
509+
for (let f of nestedFiles) {
510+
f = normalizePath(f);
511+
const nestedModule = removeFileExtension(getBaseFileName(f));
512+
nonRelativeModules.push(nestedModule);
513+
}
509514
}
510515
}
511516
}
@@ -588,10 +593,13 @@ namespace ts.Completions {
588593
}
589594

590595
function getCompletionEntriesFromDirectories(host: LanguageServiceHost, options: CompilerOptions, directory: string, span: TextSpan, result: CompletionEntry[]) {
591-
if (host.getDirectories && directoryProbablyExists(directory, host)) {
592-
for (let typeDirectory of host.getDirectories(directory)) {
593-
typeDirectory = normalizePath(typeDirectory);
594-
result.push(createCompletionEntryForModule(getBaseFileName(typeDirectory), ScriptElementKind.externalModuleName, span));
596+
if (host.getDirectories && tryDirectoryExists(host, directory)) {
597+
const directories = tryGetDirectories(host, directory);
598+
if (directories) {
599+
for (let typeDirectory of directories) {
600+
typeDirectory = normalizePath(typeDirectory);
601+
result.push(createCompletionEntryForModule(getBaseFileName(typeDirectory), ScriptElementKind.externalModuleName, span));
602+
}
595603
}
596604
}
597605
}
@@ -600,7 +608,7 @@ namespace ts.Completions {
600608
const paths: string[] = [];
601609
let currentConfigPath: string;
602610
while (true) {
603-
currentConfigPath = findConfigFile(currentDir, (f) => host.fileExists(f), "package.json");
611+
currentConfigPath = findConfigFile(currentDir, (f) => tryFileExists(host, f), "package.json");
604612
if (currentConfigPath) {
605613
paths.push(currentConfigPath);
606614

@@ -652,8 +660,8 @@ namespace ts.Completions {
652660

653661
function tryReadingPackageJson(filePath: string) {
654662
try {
655-
const fileText = host.readFile(filePath);
656-
return JSON.parse(fileText);
663+
const fileText = tryReadFile(host, filePath);
664+
return fileText ? JSON.parse(fileText) : undefined;
657665
}
658666
catch (e) {
659667
return undefined;
@@ -1660,4 +1668,36 @@ namespace ts.Completions {
16601668
}
16611669

16621670
const nodeModulesDependencyKeys = ["dependencies", "devDependencies", "peerDependencies", "optionalDependencies"];
1671+
1672+
function tryGetDirectories(host: LanguageServiceHost, directoryName: string): string[] {
1673+
return tryIOAndConsumeErrors(host, host.getDirectories, directoryName);
1674+
}
1675+
1676+
function tryReadDirectory(host: LanguageServiceHost, path: string, extensions?: string[], exclude?: string[], include?: string[]): string[] {
1677+
return tryIOAndConsumeErrors(host, host.readDirectory, path, extensions, exclude, include);
1678+
}
1679+
1680+
function tryReadFile(host: LanguageServiceHost, path: string): string {
1681+
return tryIOAndConsumeErrors(host, host.readFile, path);
1682+
}
1683+
1684+
function tryFileExists(host: LanguageServiceHost, path: string): boolean {
1685+
return tryIOAndConsumeErrors(host, host.fileExists, path);
1686+
}
1687+
1688+
function tryDirectoryExists(host: LanguageServiceHost, path: string): boolean {
1689+
try {
1690+
return directoryProbablyExists(path, host);
1691+
}
1692+
catch (e) {}
1693+
return undefined;
1694+
}
1695+
1696+
function tryIOAndConsumeErrors<T>(host: LanguageServiceHost, toApply: (...a: any[]) => T, ...args: any[]) {
1697+
try {
1698+
return toApply && toApply.apply(host, args);
1699+
}
1700+
catch (e) {}
1701+
return undefined;
1702+
}
16631703
}

0 commit comments

Comments
 (0)