Skip to content

Feat/quick fix for types #42126

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 15 commits into from
Oct 5, 2021
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
34 changes: 23 additions & 11 deletions src/compiler/checker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1764,9 +1764,8 @@ namespace ts {
nameNotFoundMessage: DiagnosticMessage | undefined,
nameArg: __String | Identifier | undefined,
isUse: boolean,
excludeGlobals = false,
issueSuggestions?: boolean): Symbol | undefined {
return resolveNameHelper(location, name, meaning, nameNotFoundMessage, nameArg, isUse, excludeGlobals, getSymbol, issueSuggestions);
excludeGlobals = false): Symbol | undefined {
return resolveNameHelper(location, name, meaning, nameNotFoundMessage, nameArg, isUse, excludeGlobals, getSymbol);
}

function resolveNameHelper(
Expand All @@ -1777,7 +1776,7 @@ namespace ts {
nameArg: __String | Identifier | undefined,
isUse: boolean,
excludeGlobals: boolean,
lookup: typeof getSymbol, issueSuggestions?: boolean): Symbol | undefined {
lookup: typeof getSymbol): Symbol | undefined {
const originalLocation = location; // needed for did-you-mean error reporting, which gathers candidates starting from the original location
let result: Symbol | undefined;
let lastLocation: Node | undefined;
Expand Down Expand Up @@ -2116,7 +2115,7 @@ namespace ts {
!checkAndReportErrorForUsingNamespaceModuleAsValue(errorLocation, name, meaning) &&
!checkAndReportErrorForUsingValueAsType(errorLocation, name, meaning)) {
let suggestion: Symbol | undefined;
if (issueSuggestions && suggestionCount < maximumSuggestionCount) {
if (suggestionCount < maximumSuggestionCount) {
suggestion = getSuggestedSymbolForNonexistentSymbol(originalLocation, name, meaning);
const isGlobalScopeAugmentationDeclaration = suggestion?.valueDeclaration && isAmbientModule(suggestion.valueDeclaration) && isGlobalScopeAugmentation(suggestion.valueDeclaration);
if (isGlobalScopeAugmentationDeclaration) {
Expand All @@ -2125,10 +2124,11 @@ namespace ts {
if (suggestion) {
const suggestionName = symbolToString(suggestion);
const isUncheckedJS = isUncheckedJSSuggestion(originalLocation, suggestion, /*excludeClasses*/ false);
const message = isUncheckedJS ? Diagnostics.Could_not_find_name_0_Did_you_mean_1 : Diagnostics.Cannot_find_name_0_Did_you_mean_1;
const message = meaning === SymbolFlags.Namespace || nameArg && typeof nameArg !== "string" && nodeIsSynthesized(nameArg) ? Diagnostics.Cannot_find_namespace_0_Did_you_mean_1
: isUncheckedJS ? Diagnostics.Could_not_find_name_0_Did_you_mean_1
: Diagnostics.Cannot_find_name_0_Did_you_mean_1;
const diagnostic = createError(errorLocation, message, diagnosticName(nameArg!), suggestionName);
addErrorOrSuggestion(!isUncheckedJS, diagnostic);

if (suggestion.valueDeclaration) {
addRelatedInfo(
diagnostic,
Expand Down Expand Up @@ -3238,7 +3238,7 @@ namespace ts {
if (name.kind === SyntaxKind.Identifier) {
const message = meaning === namespaceMeaning || nodeIsSynthesized(name) ? Diagnostics.Cannot_find_namespace_0 : getCannotFindNameDiagnosticForName(getFirstIdentifier(name));
const symbolFromJSPrototype = isInJSFile(name) && !nodeIsSynthesized(name) ? resolveEntityNameFromAssignmentDeclaration(name, meaning) : undefined;
symbol = getMergedSymbol(resolveName(location || name, name.escapedText, meaning, ignoreErrors || symbolFromJSPrototype ? undefined : message, name, /*isUse*/ true));
symbol = getMergedSymbol(resolveName(location || name, name.escapedText, meaning, ignoreErrors || symbolFromJSPrototype ? undefined : message, name, /*isUse*/ true, false));
if (!symbol) {
return getMergedSymbol(symbolFromJSPrototype);
}
Expand Down Expand Up @@ -22449,8 +22449,7 @@ namespace ts {
getCannotFindNameDiagnosticForName(node),
node,
!isWriteOnlyAccess(node),
/*excludeGlobals*/ false,
/*issueSuggestions*/ true) || unknownSymbol;
/*excludeGlobals*/ false) || unknownSymbol;
}
return links.resolvedSymbol;
}
Expand Down Expand Up @@ -28535,7 +28534,20 @@ namespace ts {
// Sometimes the symbol is found when location is a return type of a function: `typeof x` and `x` is declared in the body of the function
// So the table *contains* `x` but `x` isn't actually in scope.
// However, resolveNameHelper will continue and call this callback again, so we'll eventually get a correct suggestion.
return symbol || getSpellingSuggestionForName(unescapeLeadingUnderscores(name), arrayFrom(symbols.values()), meaning);
if (symbol) return symbol;
let candidates: Symbol[];
if (symbols === globals) {
const primitives = mapDefined(
["string", "number", "boolean", "object", "bigint", "symbol"],
s => symbols.has((s.charAt(0).toUpperCase() + s.slice(1)) as __String)
? createSymbol(SymbolFlags.TypeAlias, s as __String) as Symbol
: undefined);
candidates = primitives.concat(arrayFrom(symbols.values()));
}
else {
candidates = arrayFrom(symbols.values());
}
return getSpellingSuggestionForName(unescapeLeadingUnderscores(name), candidates, meaning);
});
return result;
}
Expand Down
4 changes: 4 additions & 0 deletions src/compiler/diagnosticMessages.json
Original file line number Diff line number Diff line change
Expand Up @@ -3337,6 +3337,10 @@
"category": "Error",
"code": 2822
},
"Cannot find namespace '{0}'. Did you mean '{1}'?": {
"category": "Error",
"code": 2833
},

"Import declaration '{0}' is using private name '{1}'.": {
"category": "Error",
Expand Down
1 change: 1 addition & 0 deletions src/services/codefixes/fixSpelling.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ namespace ts.codefix {
Diagnostics.Property_0_may_not_exist_on_type_1_Did_you_mean_2.code,
Diagnostics.Cannot_find_name_0_Did_you_mean_1.code,
Diagnostics.Could_not_find_name_0_Did_you_mean_1.code,
Diagnostics.Cannot_find_namespace_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._0_has_no_exported_member_named_1_Did_you_mean_2.code,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
tests/cases/compiler/declarationEmitUnknownImport.ts(1,1): error TS2303: Circular definition of import alias 'Foo'.
tests/cases/compiler/declarationEmitUnknownImport.ts(1,14): error TS2304: Cannot find name 'SomeNonExistingName'.
tests/cases/compiler/declarationEmitUnknownImport.ts(1,14): error TS2503: Cannot find namespace 'SomeNonExistingName'.
tests/cases/compiler/declarationEmitUnknownImport.ts(1,14): error TS4000: Import declaration 'Foo' is using private name 'SomeNonExistingName'.


==== tests/cases/compiler/declarationEmitUnknownImport.ts (3 errors) ====
==== tests/cases/compiler/declarationEmitUnknownImport.ts (4 errors) ====
import Foo = SomeNonExistingName
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
!!! error TS2303: Circular definition of import alias 'Foo'.
~~~~~~~~~~~~~~~~~~~
!!! error TS2304: Cannot find name 'SomeNonExistingName'.
~~~~~~~~~~~~~~~~~~~
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
tests/cases/compiler/declarationEmitUnknownImport2.ts(1,1): error TS2303: Circular definition of import alias 'Foo'.
tests/cases/compiler/declarationEmitUnknownImport2.ts(1,12): error TS1005: '=' expected.
tests/cases/compiler/declarationEmitUnknownImport2.ts(1,12): error TS2304: Cannot find name 'From'.
tests/cases/compiler/declarationEmitUnknownImport2.ts(1,12): error TS2503: Cannot find namespace 'From'.
tests/cases/compiler/declarationEmitUnknownImport2.ts(1,12): error TS4000: Import declaration 'Foo' is using private name 'From'.
tests/cases/compiler/declarationEmitUnknownImport2.ts(1,17): error TS1005: ';' expected.


==== tests/cases/compiler/declarationEmitUnknownImport2.ts (5 errors) ====
==== tests/cases/compiler/declarationEmitUnknownImport2.ts (6 errors) ====
import Foo From './Foo'; // Syntax error
~~~~~~~~~~~~~~~
!!! error TS2303: Circular definition of import alias 'Foo'.
~~~~
!!! error TS1005: '=' expected.
~~~~
Expand Down
10 changes: 6 additions & 4 deletions tests/baselines/reference/extendArray.errors.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
tests/cases/compiler/extendArray.ts(7,19): error TS2304: Cannot find name '_element'.
tests/cases/compiler/extendArray.ts(7,32): error TS2304: Cannot find name '_element'.
tests/cases/compiler/extendArray.ts(7,19): error TS2552: Cannot find name '_element'. Did you mean 'Element'?
tests/cases/compiler/extendArray.ts(7,32): error TS2552: Cannot find name '_element'. Did you mean 'Element'?


==== tests/cases/compiler/extendArray.ts (2 errors) ====
Expand All @@ -11,9 +11,11 @@ tests/cases/compiler/extendArray.ts(7,32): error TS2304: Cannot find name '_elem
interface Array {
collect(fn:(e:_element) => _element[]) : any[];
~~~~~~~~
!!! error TS2304: Cannot find name '_element'.
!!! error TS2552: Cannot find name '_element'. Did you mean 'Element'?
!!! related TS2728 /.ts/lib.dom.d.ts:4792:13: 'Element' is declared here.
~~~~~~~~
!!! error TS2304: Cannot find name '_element'.
!!! error TS2552: Cannot find name '_element'. Did you mean 'Element'?
!!! related TS2728 /.ts/lib.dom.d.ts:4792:13: 'Element' is declared here.
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
tests/cases/compiler/importedModuleAddToGlobal.ts(15,23): error TS2503: Cannot find namespace 'b'.
tests/cases/compiler/importedModuleAddToGlobal.ts(15,23): error TS2833: Cannot find namespace 'b'. Did you mean 'B'?


==== tests/cases/compiler/importedModuleAddToGlobal.ts (1 errors) ====
Expand All @@ -18,5 +18,6 @@ tests/cases/compiler/importedModuleAddToGlobal.ts(15,23): error TS2503: Cannot f
import a = A;
function hello(): b.B { return null; }
~
!!! error TS2503: Cannot find namespace 'b'.
!!! error TS2833: Cannot find namespace 'b'. Did you mean 'B'?
!!! related TS2728 tests/cases/compiler/importedModuleAddToGlobal.ts:8:8: 'B' is declared here.
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
tests/cases/conformance/internalModules/moduleDeclarations/invalidInstantiatedModule.ts(2,18): error TS2300: Duplicate identifier 'Point'.
tests/cases/conformance/internalModules/moduleDeclarations/invalidInstantiatedModule.ts(3,16): error TS2300: Duplicate identifier 'Point'.
tests/cases/conformance/internalModules/moduleDeclarations/invalidInstantiatedModule.ts(12,8): error TS2503: Cannot find namespace 'm'.
tests/cases/conformance/internalModules/moduleDeclarations/invalidInstantiatedModule.ts(12,8): error TS2833: Cannot find namespace 'm'. Did you mean 'M'?


==== tests/cases/conformance/internalModules/moduleDeclarations/invalidInstantiatedModule.ts (3 errors) ====
Expand All @@ -21,7 +21,8 @@ tests/cases/conformance/internalModules/moduleDeclarations/invalidInstantiatedMo
var m = M2;
var p: m.Point; // Error
~
!!! error TS2503: Cannot find namespace 'm'.
!!! error TS2833: Cannot find namespace 'm'. Did you mean 'M'?
!!! related TS2728 tests/cases/conformance/internalModules/moduleDeclarations/invalidInstantiatedModule.ts:1:8: 'M' is declared here.



4 changes: 2 additions & 2 deletions tests/baselines/reference/jsdocPropertyTagInvalid.errors.txt
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
/a.js(3,15): error TS2304: Cannot find name 'sting'.
/a.js(3,15): error TS2552: Cannot find name 'sting'. Did you mean 'string'?


==== /a.js (1 errors) ====
/**
* @typedef MyType
* @property {sting} [x]
~~~~~
!!! error TS2304: Cannot find name 'sting'.
!!! error TS2552: Cannot find name 'sting'. Did you mean 'string'?
*/

/** @param {MyType} p */
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
tests/cases/compiler/test.tsx(9,17): error TS2304: Cannot find name 'createElement'.
tests/cases/compiler/test.tsx(9,17): error TS2552: Cannot find name 'createElement'. Did you mean 'frameElement'?


==== tests/cases/compiler/test.tsx (1 errors) ====
Expand All @@ -12,7 +12,8 @@ tests/cases/compiler/test.tsx(9,17): error TS2304: Cannot find name 'createEleme
render() {
return <div />;
~~~
!!! error TS2304: Cannot find name 'createElement'.
!!! error TS2552: Cannot find name 'createElement'. Did you mean 'frameElement'?
!!! related TS2728 /.ts/lib.dom.d.ts:17075:13: 'frameElement' is declared here.
}
}

Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
tests/cases/compiler/test.tsx(9,17): error TS2304: Cannot find name 'MyElement'.
tests/cases/compiler/test.tsx(9,17): error TS2552: Cannot find name 'MyElement'. Did you mean 'Element'?


==== tests/cases/compiler/test.tsx (1 errors) ====
Expand All @@ -12,6 +12,7 @@ tests/cases/compiler/test.tsx(9,17): error TS2304: Cannot find name 'MyElement'.
render(createElement) {
return <div />;
~~~
!!! error TS2304: Cannot find name 'MyElement'.
!!! error TS2552: Cannot find name 'MyElement'. Did you mean 'Element'?
!!! related TS2728 /.ts/lib.dom.d.ts:4792:13: 'Element' is declared here.
}
}
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
tests/cases/conformance/parser/ecmascript5/ErrorRecovery/parserUnfinishedTypeNameBeforeKeyword1.ts(1,8): error TS2503: Cannot find namespace 'TypeModule1'.
tests/cases/conformance/parser/ecmascript5/ErrorRecovery/parserUnfinishedTypeNameBeforeKeyword1.ts(1,8): error TS2833: Cannot find namespace 'TypeModule1'. Did you mean 'TypeModule2'?
tests/cases/conformance/parser/ecmascript5/ErrorRecovery/parserUnfinishedTypeNameBeforeKeyword1.ts(1,20): error TS1003: Identifier expected.


==== tests/cases/conformance/parser/ecmascript5/ErrorRecovery/parserUnfinishedTypeNameBeforeKeyword1.ts (2 errors) ====
var x: TypeModule1.
~~~~~~~~~~~
!!! error TS2503: Cannot find namespace 'TypeModule1'.
!!! error TS2833: Cannot find namespace 'TypeModule1'. Did you mean 'TypeModule2'?

!!! error TS1003: Identifier expected.
module TypeModule2 {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
tests/cases/conformance/parser/ecmascript5/ErrorRecovery/parserUnterminatedGeneric1.ts(2,23): error TS2304: Cannot find name 'IPromise'.
tests/cases/conformance/parser/ecmascript5/ErrorRecovery/parserUnterminatedGeneric1.ts(2,45): error TS2304: Cannot find name 'IPromise'.
tests/cases/conformance/parser/ecmascript5/ErrorRecovery/parserUnterminatedGeneric1.ts(2,23): error TS2552: Cannot find name 'IPromise'. Did you mean 'Promise'?
tests/cases/conformance/parser/ecmascript5/ErrorRecovery/parserUnterminatedGeneric1.ts(2,45): error TS2552: Cannot find name 'IPromise'. Did you mean 'Promise'?
tests/cases/conformance/parser/ecmascript5/ErrorRecovery/parserUnterminatedGeneric1.ts(2,54): error TS1005: '>' expected.


==== tests/cases/conformance/parser/ecmascript5/ErrorRecovery/parserUnterminatedGeneric1.ts (3 errors) ====
interface IQService {
all(promises: IPromise < any > []): IPromise<
~~~~~~~~
!!! error TS2304: Cannot find name 'IPromise'.
!!! error TS2552: Cannot find name 'IPromise'. Did you mean 'Promise'?
~~~~~~~~
!!! error TS2304: Cannot find name 'IPromise'.
!!! error TS2552: Cannot find name 'IPromise'. Did you mean 'Promise'?

!!! error TS1005: '>' expected.
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ tests/cases/conformance/parser/ecmascript5/ErrorRecovery/parserUnterminatedGener
tests/cases/conformance/parser/ecmascript5/ErrorRecovery/parserUnterminatedGeneric2.ts(4,37): error TS2693: 'any' only refers to a type, but is being used as a value here.
tests/cases/conformance/parser/ecmascript5/ErrorRecovery/parserUnterminatedGeneric2.ts(4,41): error TS1005: ';' expected.
tests/cases/conformance/parser/ecmascript5/ErrorRecovery/parserUnterminatedGeneric2.ts(4,43): error TS2693: 'any' only refers to a type, but is being used as a value here.
tests/cases/conformance/parser/ecmascript5/ErrorRecovery/parserUnterminatedGeneric2.ts(8,23): error TS2304: Cannot find name 'IPromise'.
tests/cases/conformance/parser/ecmascript5/ErrorRecovery/parserUnterminatedGeneric2.ts(8,45): error TS2304: Cannot find name 'IPromise'.
tests/cases/conformance/parser/ecmascript5/ErrorRecovery/parserUnterminatedGeneric2.ts(8,23): error TS2552: Cannot find name 'IPromise'. Did you mean 'Promise'?
tests/cases/conformance/parser/ecmascript5/ErrorRecovery/parserUnterminatedGeneric2.ts(8,45): error TS2552: Cannot find name 'IPromise'. Did you mean 'Promise'?
tests/cases/conformance/parser/ecmascript5/ErrorRecovery/parserUnterminatedGeneric2.ts(8,54): error TS1005: '>' expected.


Expand Down Expand Up @@ -49,8 +49,8 @@ tests/cases/conformance/parser/ecmascript5/ErrorRecovery/parserUnterminatedGener
interface IQService {
all(promises: IPromise < any > []): IPromise<
~~~~~~~~
!!! error TS2304: Cannot find name 'IPromise'.
!!! error TS2552: Cannot find name 'IPromise'. Did you mean 'Promise'?
~~~~~~~~
!!! error TS2304: Cannot find name 'IPromise'.
!!! error TS2552: Cannot find name 'IPromise'. Did you mean 'Promise'?

!!! error TS1005: '>' expected.
5 changes: 3 additions & 2 deletions tests/baselines/reference/primaryExpressionMods.errors.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
tests/cases/compiler/primaryExpressionMods.ts(7,8): error TS2709: Cannot use namespace 'M' as a type.
tests/cases/compiler/primaryExpressionMods.ts(11,8): error TS2503: Cannot find namespace 'm'.
tests/cases/compiler/primaryExpressionMods.ts(11,8): error TS2833: Cannot find namespace 'm'. Did you mean 'M'?


==== tests/cases/compiler/primaryExpressionMods.ts (2 errors) ====
Expand All @@ -17,5 +17,6 @@ tests/cases/compiler/primaryExpressionMods.ts(11,8): error TS2503: Cannot find n
var x2 = m.a; // Same as M.a
var q: m.P; // Error
~
!!! error TS2503: Cannot find namespace 'm'.
!!! error TS2833: Cannot find namespace 'm'. Did you mean 'M'?
!!! related TS2728 tests/cases/compiler/primaryExpressionMods.ts:1:8: 'M' is declared here.

26 changes: 26 additions & 0 deletions tests/cases/fourslash/codeFixSpellingCaseSensitive4.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
/// <reference path='fourslash.ts' />

//// declare let a: numbers;
//// declare let b: Numbers;
//// declare let c: objects;
//// declare let d: Objects;
//// declare let e: RegEx;
//// namespace yadda {
//// export type Thing = string;
//// }
//// let f: yaddas.Thing;

verify.codeFixAll({
fixId: "fixSpelling",
fixAllDescription: "Fix all detected spelling errors",
newFileContent:
`declare let a: number;
declare let b: Number;
declare let c: object;
declare let d: Object;
declare let e: RegExp;
namespace yadda {
export type Thing = string;
}
let f: yadda.Thing;`,
});