Skip to content

feat(part of 40169): No spelling suggestion/quick fix for namespaces #40211

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Aug 29, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 7 additions & 2 deletions src/compiler/checker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2643,7 +2643,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)
Expand Down Expand Up @@ -3020,7 +3020,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;
}
Expand Down
3 changes: 1 addition & 2 deletions src/compiler/diagnosticMessages.json
Original file line number Diff line number Diff line change
Expand Up @@ -2740,7 +2740,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
},
Expand Down Expand Up @@ -3017,7 +3017,6 @@
"code": 2792
},


"Import declaration '{0}' is using private name '{1}'.": {
"category": "Error",
"code": 4000
Expand Down
8 changes: 7 additions & 1 deletion src/services/codefixes/fixSpelling.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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)!;
Expand Down
4 changes: 2 additions & 2 deletions tests/baselines/reference/exportSpellingSuggestion.errors.txt
Original file line number Diff line number Diff line change
@@ -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) ====
Expand All @@ -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.

Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
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) ====
export function exist() {}
==== 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()
8 changes: 4 additions & 4 deletions tests/baselines/reference/moduleVisibilityTest3.errors.txt
Original file line number Diff line number Diff line change
@@ -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) ====
Expand All @@ -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'?
}

}
Expand Down
31 changes: 31 additions & 0 deletions tests/baselines/reference/moduleVisibilityTest4.errors.txt
Original file line number Diff line number Diff line change
@@ -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'.

25 changes: 25 additions & 0 deletions tests/baselines/reference/moduleVisibilityTest4.js
Original file line number Diff line number Diff line change
@@ -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;
41 changes: 41 additions & 0 deletions tests/baselines/reference/moduleVisibilityTest4.symbols
Original file line number Diff line number Diff line change
@@ -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))

35 changes: 35 additions & 0 deletions tests/baselines/reference/moduleVisibilityTest4.types
Original file line number Diff line number Diff line change
@@ -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

Original file line number Diff line number Diff line change
Expand Up @@ -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) { } }
   ~
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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) { } }
   ~
Expand Down
15 changes: 15 additions & 0 deletions tests/cases/compiler/moduleVisibilityTest4.ts
Original file line number Diff line number Diff line change
@@ -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;
12 changes: 12 additions & 0 deletions tests/cases/fourslash/codeFixSpelling7.ts
Original file line number Diff line number Diff line change
@@ -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"
});
12 changes: 12 additions & 0 deletions tests/cases/fourslash/codeFixSpelling8.ts
Original file line number Diff line number Diff line change
@@ -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"
});
15 changes: 15 additions & 0 deletions tests/cases/fourslash/codeFixSpelling9.ts
Original file line number Diff line number Diff line change
@@ -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"
});