feat(part of 40169): add spelling suggestion/quick fix for module/namespace exported members (#40211)

This commit is contained in:
Alexander T
2020-08-29 11:01:06 +03:00
committed by GitHub
parent b78c722199
commit 01362a3ac1
16 changed files with 211 additions and 15 deletions

View File

@@ -2678,7 +2678,7 @@ namespace ts {
const suggestion = getSuggestedSymbolForNonexistentModule(name, targetSymbol);
if (suggestion !== undefined) {
const suggestionName = symbolToString(suggestion);
const diagnostic = error(name, Diagnostics.Module_0_has_no_exported_member_1_Did_you_mean_2, moduleName, declarationName, suggestionName);
const diagnostic = error(name, Diagnostics._0_has_no_exported_member_named_1_Did_you_mean_2, moduleName, declarationName, suggestionName);
if (suggestion.valueDeclaration) {
addRelatedInfo(diagnostic,
createDiagnosticForNode(suggestion.valueDeclaration, Diagnostics._0_is_declared_here, suggestionName)
@@ -3057,7 +3057,12 @@ namespace ts {
symbol = getMergedSymbol(getSymbol(getExportsOfSymbol(namespace), right.escapedText, meaning));
if (!symbol) {
if (!ignoreErrors) {
error(right, Diagnostics.Namespace_0_has_no_exported_member_1, getFullyQualifiedName(namespace), declarationNameToString(right));
const namespaceName = getFullyQualifiedName(namespace);
const declarationName = declarationNameToString(right);
const suggestion = getSuggestedSymbolForNonexistentModule(right, namespace);
suggestion ?
error(right, Diagnostics._0_has_no_exported_member_named_1_Did_you_mean_2, namespaceName, declarationName, symbolToString(suggestion)) :
error(right, Diagnostics.Namespace_0_has_no_exported_member_1, namespaceName, declarationName);
}
return undefined;
}

View File

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

View File

@@ -6,7 +6,7 @@ namespace ts.codefix {
Diagnostics.Cannot_find_name_0_Did_you_mean_1.code,
Diagnostics.Cannot_find_name_0_Did_you_mean_the_instance_member_this_0.code,
Diagnostics.Cannot_find_name_0_Did_you_mean_the_static_member_1_0.code,
Diagnostics.Module_0_has_no_exported_member_1_Did_you_mean_2.code,
Diagnostics._0_has_no_exported_member_named_1_Did_you_mean_2.code,
// for JSX class components
Diagnostics.No_overload_matches_this_call.code,
// for JSX FC
@@ -53,6 +53,12 @@ namespace ts.codefix {
}
suggestedSymbol = checker.getSuggestedSymbolForNonexistentProperty(node, containingType);
}
else if (isQualifiedName(parent) && parent.right === node) {
const symbol = checker.getSymbolAtLocation(parent.left);
if (symbol && symbol.flags & SymbolFlags.Module) {
suggestedSymbol = checker.getSuggestedSymbolForNonexistentModule(parent.right, symbol);
}
}
else if (isImportSpecifier(parent) && parent.name === node) {
Debug.assertNode(node, isIdentifier, "Expected an identifier for spelling (import)");
const importDeclaration = findAncestor(node, isImportDeclaration)!;

View File

@@ -1,4 +1,4 @@
tests/cases/conformance/es6/modules/b.ts(1,10): error TS2724: Module '"./a"' has no exported member 'assertNevar'. Did you mean 'assertNever'?
tests/cases/conformance/es6/modules/b.ts(1,10): error TS2724: '"./a"' has no exported member named 'assertNevar'. Did you mean 'assertNever'?
==== tests/cases/conformance/es6/modules/a.ts (0 errors) ====
@@ -9,6 +9,6 @@ tests/cases/conformance/es6/modules/b.ts(1,10): error TS2724: Module '"./a"' has
==== tests/cases/conformance/es6/modules/b.ts (1 errors) ====
import { assertNevar } from "./a";
~~~~~~~~~~~
!!! error TS2724: Module '"./a"' has no exported member 'assertNevar'. Did you mean 'assertNever'?
!!! error TS2724: '"./a"' has no exported member named 'assertNevar'. Did you mean 'assertNever'?
!!! related TS2728 tests/cases/conformance/es6/modules/a.ts:1:17: 'assertNever' is declared here.

View File

@@ -1,4 +1,4 @@
C:/foo/bar/Baz/src/sample.ts(1,10): error TS2724: Module '"./utils.js"' has no exported member 'exit'. Did you mean 'exist'?
C:/foo/bar/Baz/src/sample.ts(1,10): error TS2724: '"./utils.js"' has no exported member named 'exit'. Did you mean 'exist'?
==== C:/foo/bar/Baz/src/utils.ts (0 errors) ====
@@ -6,7 +6,7 @@ C:/foo/bar/Baz/src/sample.ts(1,10): error TS2724: Module '"./utils.js"' has no e
==== C:/foo/bar/Baz/src/sample.ts (1 errors) ====
import { exit } from "./utils.js";
~~~~
!!! error TS2724: Module '"./utils.js"' has no exported member 'exit'. Did you mean 'exist'?
!!! error TS2724: '"./utils.js"' has no exported member named 'exit'. Did you mean 'exist'?
!!! related TS2728 C:/foo/bar/Baz/src/utils.ts:1:17: 'exist' is declared here.
exit()

View File

@@ -1,6 +1,6 @@
tests/cases/compiler/moduleVisibilityTest3.ts(20,22): error TS2709: Cannot use namespace 'modes' as a type.
tests/cases/compiler/moduleVisibilityTest3.ts(20,39): error TS2694: Namespace '_modes' has no exported member 'Mode'.
tests/cases/compiler/moduleVisibilityTest3.ts(21,22): error TS2694: Namespace '_modes' has no exported member 'Mode'.
tests/cases/compiler/moduleVisibilityTest3.ts(20,39): error TS2724: '_modes' has no exported member named 'Mode'. Did you mean 'IMode'?
tests/cases/compiler/moduleVisibilityTest3.ts(21,22): error TS2724: '_modes' has no exported member named 'Mode'. Did you mean 'IMode'?
==== tests/cases/compiler/moduleVisibilityTest3.ts (3 errors) ====
@@ -27,10 +27,10 @@ tests/cases/compiler/moduleVisibilityTest3.ts(21,22): error TS2694: Namespace '_
~~~~~
!!! error TS2709: Cannot use namespace 'modes' as a type.
~~~~
!!! error TS2694: Namespace '_modes' has no exported member 'Mode'.
!!! error TS2724: '_modes' has no exported member named 'Mode'. Did you mean 'IMode'?
var x:modes.Mode;
~~~~
!!! error TS2694: Namespace '_modes' has no exported member 'Mode'.
!!! error TS2724: '_modes' has no exported member named 'Mode'. Did you mean 'IMode'?
}
}

View File

@@ -0,0 +1,31 @@
tests/cases/compiler/moduleVisibilityTest4.ts(9,11): error TS2724: 'M' has no exported member named 'num'. Did you mean 'nums'?
tests/cases/compiler/moduleVisibilityTest4.ts(11,11): error TS2694: Namespace 'M' has no exported member 'bar'.
tests/cases/compiler/moduleVisibilityTest4.ts(13,11): error TS2724: 'N' has no exported member named 'num'. Did you mean 'nums'?
tests/cases/compiler/moduleVisibilityTest4.ts(15,11): error TS2694: Namespace 'N' has no exported member 'bar'.
==== tests/cases/compiler/moduleVisibilityTest4.ts (4 errors) ====
module M {
export type nums = number;
}
namespace N {
export type nums = number;
}
let a1: M.num;
~~~
!!! error TS2724: 'M' has no exported member named 'num'. Did you mean 'nums'?
let b1: M.nums;
let c1: M.bar;
~~~
!!! error TS2694: Namespace 'M' has no exported member 'bar'.
let a2: N.num;
~~~
!!! error TS2724: 'N' has no exported member named 'num'. Did you mean 'nums'?
let b2: N.nums;
let c2: N.bar;
~~~
!!! error TS2694: Namespace 'N' has no exported member 'bar'.

View File

@@ -0,0 +1,25 @@
//// [moduleVisibilityTest4.ts]
module M {
export type nums = number;
}
namespace N {
export type nums = number;
}
let a1: M.num;
let b1: M.nums;
let c1: M.bar;
let a2: N.num;
let b2: N.nums;
let c2: N.bar;
//// [moduleVisibilityTest4.js]
var a1;
var b1;
var c1;
var a2;
var b2;
var c2;

View File

@@ -0,0 +1,41 @@
=== tests/cases/compiler/moduleVisibilityTest4.ts ===
module M {
>M : Symbol(M, Decl(moduleVisibilityTest4.ts, 0, 0))
export type nums = number;
>nums : Symbol(nums, Decl(moduleVisibilityTest4.ts, 0, 10))
}
namespace N {
>N : Symbol(N, Decl(moduleVisibilityTest4.ts, 2, 1))
export type nums = number;
>nums : Symbol(nums, Decl(moduleVisibilityTest4.ts, 4, 13))
}
let a1: M.num;
>a1 : Symbol(a1, Decl(moduleVisibilityTest4.ts, 8, 3))
>M : Symbol(M, Decl(moduleVisibilityTest4.ts, 0, 0))
let b1: M.nums;
>b1 : Symbol(b1, Decl(moduleVisibilityTest4.ts, 9, 3))
>M : Symbol(M, Decl(moduleVisibilityTest4.ts, 0, 0))
>nums : Symbol(M.nums, Decl(moduleVisibilityTest4.ts, 0, 10))
let c1: M.bar;
>c1 : Symbol(c1, Decl(moduleVisibilityTest4.ts, 10, 3))
>M : Symbol(M, Decl(moduleVisibilityTest4.ts, 0, 0))
let a2: N.num;
>a2 : Symbol(a2, Decl(moduleVisibilityTest4.ts, 12, 3))
>N : Symbol(N, Decl(moduleVisibilityTest4.ts, 2, 1))
let b2: N.nums;
>b2 : Symbol(b2, Decl(moduleVisibilityTest4.ts, 13, 3))
>N : Symbol(N, Decl(moduleVisibilityTest4.ts, 2, 1))
>nums : Symbol(N.nums, Decl(moduleVisibilityTest4.ts, 4, 13))
let c2: N.bar;
>c2 : Symbol(c2, Decl(moduleVisibilityTest4.ts, 14, 3))
>N : Symbol(N, Decl(moduleVisibilityTest4.ts, 2, 1))

View File

@@ -0,0 +1,35 @@
=== tests/cases/compiler/moduleVisibilityTest4.ts ===
module M {
export type nums = number;
>nums : number
}
namespace N {
export type nums = number;
>nums : number
}
let a1: M.num;
>a1 : any
>M : any
let b1: M.nums;
>b1 : number
>M : any
let c1: M.bar;
>c1 : any
>M : any
let a2: N.num;
>a2 : any
>N : any
let b2: N.nums;
>b2 : number
>N : any
let c2: N.bar;
>c2 : any
>N : any

View File

@@ -34,7 +34,7 @@ Output::
[12:00:31 AM] Starting compilation in watch mode...
a/b/project/src/main2.ts:1:114 - error TS2694: Namespace 'Common.SomeComponent.DynamicMenu' has no exported member 'z'.
a/b/project/src/main2.ts:1:114 - error TS2724: 'Common.SomeComponent.DynamicMenu' has no exported member named 'z'. Did you mean 'Z'?
1 namespace main.file4 { import DynamicMenu = Common.SomeComponent.DynamicMenu; export function foo(a: DynamicMenu.z) { } }
   ~

View File

@@ -34,7 +34,7 @@ Output::
[12:00:31 AM] Starting compilation in watch mode...
a/b/project/src/main2.ts:1:114 - error TS2694: Namespace 'Common.SomeComponent.DynamicMenu' has no exported member 'z'.
a/b/project/src/main2.ts:1:114 - error TS2724: 'Common.SomeComponent.DynamicMenu' has no exported member named 'z'. Did you mean 'Z'?
1 namespace main.file4 { import DynamicMenu = Common.SomeComponent.DynamicMenu; export function foo(a: DynamicMenu.z) { } }
   ~

View File

@@ -0,0 +1,15 @@
module M {
export type nums = number;
}
namespace N {
export type nums = number;
}
let a1: M.num;
let b1: M.nums;
let c1: M.bar;
let a2: N.num;
let b2: N.nums;
let c2: N.bar;

View File

@@ -0,0 +1,12 @@
/// <reference path='fourslash.ts' />
////namespace Foo {
//// export type nums = number;
////}
////let x: Foo.[|num|];
verify.codeFix({
index: 0,
description: [ts.Diagnostics.Change_spelling_to_0.message, "nums"],
newRangeContent: "nums"
});

View File

@@ -0,0 +1,12 @@
/// <reference path='fourslash.ts' />
////module Foo {
//// export type nums = number;
////}
////let x: Foo.[|num|];
verify.codeFix({
index: 0,
description: [ts.Diagnostics.Change_spelling_to_0.message, "nums"],
newRangeContent: "nums"
});

View File

@@ -0,0 +1,15 @@
/// <reference path='fourslash.ts' />
// @filename: a.ts
////module Foo {
//// export type nums = number;
////}
// @filename: b.ts
////let x: Foo.[|num|];
goTo.file("b.ts");
verify.codeFix({
index: 0,
description: [ts.Diagnostics.Change_spelling_to_0.message, "nums"],
newRangeContent: "nums"
});