Skip to content

Commit ee304c3

Browse files
author
Andy Hanson
committed
Convert 'installTypesForPackge' refactor to a suggestion
1 parent 24d3035 commit ee304c3

14 files changed

+103
-164
lines changed

src/compiler/checker.ts

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2096,14 +2096,7 @@ namespace ts {
20962096
error(errorNode, diag, moduleReference, resolvedModule.resolvedFileName);
20972097
}
20982098
else if (noImplicitAny && moduleNotFoundError) {
2099-
let errorInfo = resolvedModule.packageId && chainDiagnosticMessages(/*details*/ undefined,
2100-
Diagnostics.Try_npm_install_types_Slash_0_if_it_exists_or_add_a_new_declaration_d_ts_file_containing_declare_module_0,
2101-
getMangledNameForScopedPackage(resolvedModule.packageId.name));
2102-
errorInfo = chainDiagnosticMessages(errorInfo,
2103-
Diagnostics.Could_not_find_a_declaration_file_for_module_0_1_implicitly_has_an_any_type,
2104-
moduleReference,
2105-
resolvedModule.resolvedFileName);
2106-
diagnostics.add(createDiagnosticForNodeFromMessageChain(errorNode, errorInfo));
2099+
diagnostics.add(createDiagnosticForModuleMissingTypes(errorNode, resolvedModule, moduleReference, Diagnostics.Could_not_find_a_declaration_file_for_module_0_1_implicitly_has_an_any_type));
21072100
}
21082101
// Failed imports and untyped modules are both treated in an untyped manner; only difference is whether we give a diagnostic first.
21092102
return undefined;

src/compiler/diagnosticMessages.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3818,6 +3818,10 @@
38183818
"category": "Suggestion",
38193819
"code": 80001
38203820
},
3821+
"Did not find a declaration file for module '{0}'. '{1}' implicitly has an 'any' type.": {
3822+
"category": "Suggestion",
3823+
"code": 80002
3824+
},
38213825

38223826
"Add missing 'super()' call": {
38233827
"category": "Message",

src/compiler/program.ts

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2416,10 +2416,26 @@ namespace ts {
24162416
return options.jsx ? undefined : Diagnostics.Module_0_was_resolved_to_1_but_jsx_is_not_set;
24172417
}
24182418
function needAllowJs() {
2419-
return options.allowJs || !getStrictOptionValue(options, "noImplicitAny") ? undefined : Diagnostics.Could_not_find_a_declaration_file_for_module_0_1_implicitly_has_an_any_type;
2419+
return willAllowImplicitAnyJsModule(options) ? undefined : Diagnostics.Could_not_find_a_declaration_file_for_module_0_1_implicitly_has_an_any_type;
24202420
}
24212421
}
24222422

2423+
export function willAllowImplicitAnyJsModule(options: CompilerOptions): boolean {
2424+
return options.allowJs || !getStrictOptionValue(options, "noImplicitAny");
2425+
}
2426+
2427+
export function createDiagnosticForModuleMissingTypes(errorNode: Node, { packageId, resolvedFileName }: ResolvedModuleFull, moduleReference: string, diag: DiagnosticMessage): Diagnostic {
2428+
const errorInfo = packageId && chainDiagnosticMessages(
2429+
/*details*/ undefined,
2430+
Diagnostics.Try_npm_install_types_Slash_0_if_it_exists_or_add_a_new_declaration_d_ts_file_containing_declare_module_0,
2431+
getMangledNameForScopedPackage(packageId.name));
2432+
return createDiagnosticForNodeFromMessageChain(errorNode, chainDiagnosticMessages(
2433+
errorInfo,
2434+
diag,
2435+
moduleReference,
2436+
resolvedFileName));
2437+
}
2438+
24232439
function checkAllDefined(names: string[]): string[] {
24242440
Debug.assert(names.every(name => name !== undefined), "A name is undefined.", () => JSON.stringify(names));
24252441
return names;

src/harness/fourslash.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -583,7 +583,8 @@ namespace FourSlash {
583583

584584
public verifyNoErrors() {
585585
ts.forEachKey(this.inputFiles, fileName => {
586-
if (!ts.isAnySupportedFileExtension(fileName)) return;
586+
if (!ts.isAnySupportedFileExtension(fileName)
587+
|| !this.getProgram().getCompilerOptions().allowJs && !ts.extensionIsTypeScript(ts.extensionFromPath(fileName))) return;
587588
const errors = this.getDiagnostics(fileName).filter(e => e.category !== ts.DiagnosticCategory.Suggestion);
588589
if (errors.length) {
589590
this.printErrorLog(/*expectErrors*/ false, errors);

src/services/codefixes/fixCannotFindModule.ts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
11
/* @internal */
22
namespace ts.codefix {
33
const fixId = "fixCannotFindModule";
4-
const errorCodes = [Diagnostics.Could_not_find_a_declaration_file_for_module_0_1_implicitly_has_an_any_type.code];
4+
const errorCodes = [
5+
Diagnostics.Could_not_find_a_declaration_file_for_module_0_1_implicitly_has_an_any_type.code,
6+
Diagnostics.Did_not_find_a_declaration_file_for_module_0_1_implicitly_has_an_any_type.code
7+
];
58
registerCodeFix({
69
errorCodes,
710
getCodeActions: context => {
@@ -31,7 +34,7 @@ namespace ts.codefix {
3134
return host.isKnownTypesPackageName(packageName) ? getTypesPackageName(packageName) : undefined;
3235
}
3336

34-
export function tryGetCodeActionForInstallPackageTypes(host: LanguageServiceHost, fileName: string, moduleName: string): CodeAction | undefined {
37+
function tryGetCodeActionForInstallPackageTypes(host: LanguageServiceHost, fileName: string, moduleName: string): CodeAction | undefined {
3538
const packageName = getTypesPackageNameToInstall(host, moduleName);
3639
return packageName === undefined ? undefined : {
3740
description: formatStringFromArgs(getLocaleSpecificMessage(Diagnostics.Install_0), [packageName]),

src/services/refactors/installTypesForPackage.ts

Lines changed: 0 additions & 67 deletions
This file was deleted.
Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
/// <reference path="annotateWithTypeFromJSDoc.ts" />
22
/// <reference path="convertFunctionToEs6Class.ts" />
33
/// <reference path="extractSymbol.ts" />
4-
/// <reference path="installTypesForPackage.ts" />
54
/// <reference path="useDefaultImport.ts" />

src/services/services.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1422,7 +1422,7 @@ namespace ts {
14221422

14231423
function getSuggestionDiagnostics(fileName: string): Diagnostic[] {
14241424
synchronizeHostData();
1425-
return computeSuggestionDiagnostics(getValidSourceFile(fileName));
1425+
return computeSuggestionDiagnostics(getValidSourceFile(fileName), program);
14261426
}
14271427

14281428
function getCompilerOptionsDiagnostics() {
Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,21 @@
11
/* @internal */
22
namespace ts {
3-
export function computeSuggestionDiagnostics(sourceFile: SourceFile): Diagnostic[] {
4-
return sourceFile.commonJsModuleIndicator
5-
? [createDiagnosticForNode(sourceFile.commonJsModuleIndicator, Diagnostics.File_is_a_CommonJS_module_it_may_be_converted_to_an_ES6_module)]
6-
: emptyArray;
3+
export function computeSuggestionDiagnostics(sourceFile: SourceFile, program: Program): Diagnostic[] {
4+
const diags: Diagnostic[] = [];
5+
6+
if (sourceFile.commonJsModuleIndicator) {
7+
diags.push(createDiagnosticForNode(sourceFile.commonJsModuleIndicator, Diagnostics.File_is_a_CommonJS_module_it_may_be_converted_to_an_ES6_module));
8+
}
9+
10+
if (willAllowImplicitAnyJsModule(program.getCompilerOptions())) {
11+
for (const importNode of sourceFile.imports) {
12+
const resolved = getResolvedModule(sourceFile, importNode.text);
13+
if (resolved && resolved.isExternalLibraryImport && !extensionIsTypeScript(resolved.extension)) {
14+
diags.push(createDiagnosticForModuleMissingTypes(importNode, resolved, importNode.text, Diagnostics.Did_not_find_a_declaration_file_for_module_0_1_implicitly_has_an_any_type));
15+
}
16+
}
17+
}
18+
19+
return diags;
720
}
821
}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
/// <reference path='fourslash.ts' />
2+
3+
// @moduleResolution: node
4+
5+
// @Filename: /node_modules/abs/subModule.js
6+
////export const x = 0;
7+
8+
// @Filename: /a.ts
9+
////import * as abs from [|"abs/subModule"|];
10+
11+
test.setTypesRegistry({
12+
"abs": undefined,
13+
});
14+
15+
verify.noErrors();
16+
goTo.file("/a.ts");
17+
verify.getSuggestionDiagnostics([{
18+
message: "Did not find a declaration file for module 'abs/subModule'. '/node_modules/abs/subModule.js' implicitly has an 'any' type.",
19+
code: 80002,
20+
}]);
21+
22+
verify.codeFixAvailable([{
23+
description: "Install '@types/abs'",
24+
commands: [{
25+
type: "install package",
26+
file: "/a.ts",
27+
packageName: "@types/abs",
28+
}],
29+
}]);

0 commit comments

Comments
 (0)