add spelling suggestion support for module import (#22283)

This commit is contained in:
Wenlu Wang 2018-03-03 02:24:55 +08:00 committed by Nathan Shively-Sanders
parent dd27288e5a
commit b15157356a
7 changed files with 92 additions and 1 deletions

View file

@ -1857,7 +1857,15 @@ namespace ts {
combineValueAndTypeSymbols(symbolFromVariable, symbolFromModule) :
symbolFromModule || symbolFromVariable;
if (!symbol) {
error(name, Diagnostics.Module_0_has_no_exported_member_1, getFullyQualifiedName(moduleSymbol), declarationNameToString(name));
const moduleName = getFullyQualifiedName(moduleSymbol);
const declarationName = declarationNameToString(name);
const suggestion = getSuggestionForNonexistentModule(name, targetSymbol);
if (suggestion !== undefined) {
error(name, Diagnostics.Module_0_has_no_exported_member_1_Did_you_mean_2, moduleName, declarationName, suggestion);
}
else {
error(name, Diagnostics.Module_0_has_no_exported_member_1, moduleName, declarationName);
}
}
return symbol;
}
@ -16218,6 +16226,11 @@ namespace ts {
return result && symbolName(result);
}
function getSuggestionForNonexistentModule(name: Identifier, targetModule: Symbol): string | undefined {
const suggestion = targetModule.exports && getSpellingSuggestionForName(idText(name), getExportsOfModuleAsArray(targetModule), SymbolFlags.ModuleMember);
return suggestion && symbolName(suggestion);
}
/**
* Given a name and a list of symbols whose names are *not* equal to the name, return a spelling suggestion if there is one that is close enough.
* Names less than length 3 only check for case-insensitive equality, not levenshtein distance.

View file

@ -2317,6 +2317,10 @@
"category": "Error",
"code": 2723
},
"Module '{0}' has no exported member '{1}'. Did you mean '{2}'?": {
"category": "Error",
"code": 2724
},
"Import declaration '{0}' is using private name '{1}'.": {
"category": "Error",
"code": 4000

View file

@ -0,0 +1,13 @@
tests/cases/conformance/es6/modules/b.ts(1,10): error TS2724: Module '"tests/cases/conformance/es6/modules/a"' has no exported member 'assertNevar'. Did you mean 'assertNever'?
==== tests/cases/conformance/es6/modules/a.ts (0 errors) ====
export function assertNever(x: never, msg: string) {
throw new Error("Unexpected " + msg);
}
==== tests/cases/conformance/es6/modules/b.ts (1 errors) ====
import { assertNevar } from "./a";
~~~~~~~~~~~
!!! error TS2724: Module '"tests/cases/conformance/es6/modules/a"' has no exported member 'assertNevar'. Did you mean 'assertNever'?

View file

@ -0,0 +1,21 @@
//// [tests/cases/conformance/es6/modules/exportSpellingSuggestion.ts] ////
//// [a.ts]
export function assertNever(x: never, msg: string) {
throw new Error("Unexpected " + msg);
}
//// [b.ts]
import { assertNevar } from "./a";
//// [a.js]
"use strict";
exports.__esModule = true;
function assertNever(x, msg) {
throw new Error("Unexpected " + msg);
}
exports.assertNever = assertNever;
//// [b.js]
"use strict";
exports.__esModule = true;

View file

@ -0,0 +1,15 @@
=== tests/cases/conformance/es6/modules/a.ts ===
export function assertNever(x: never, msg: string) {
>assertNever : Symbol(assertNever, Decl(a.ts, 0, 0))
>x : Symbol(x, Decl(a.ts, 0, 28))
>msg : Symbol(msg, Decl(a.ts, 0, 37))
throw new Error("Unexpected " + msg);
>Error : Symbol(Error, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --))
>msg : Symbol(msg, Decl(a.ts, 0, 37))
}
=== tests/cases/conformance/es6/modules/b.ts ===
import { assertNevar } from "./a";
>assertNevar : Symbol(assertNevar, Decl(b.ts, 0, 8))

View file

@ -0,0 +1,18 @@
=== tests/cases/conformance/es6/modules/a.ts ===
export function assertNever(x: never, msg: string) {
>assertNever : (x: never, msg: string) => void
>x : never
>msg : string
throw new Error("Unexpected " + msg);
>new Error("Unexpected " + msg) : Error
>Error : ErrorConstructor
>"Unexpected " + msg : string
>"Unexpected " : "Unexpected "
>msg : string
}
=== tests/cases/conformance/es6/modules/b.ts ===
import { assertNevar } from "./a";
>assertNevar : any

View file

@ -0,0 +1,7 @@
// @filename: a.ts
export function assertNever(x: never, msg: string) {
throw new Error("Unexpected " + msg);
}
// @filename: b.ts
import { assertNevar } from "./a";