Skip to content

Commit f6684be

Browse files
fix: correct name length criterion for spelling fixes (#49575)
Co-authored-by: Jake Bailey <5341706+jakebailey@users.noreply.github.com>
1 parent 59238db commit f6684be

32 files changed

+245
-95
lines changed

src/compiler/checker.ts

Lines changed: 36 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1874,7 +1874,7 @@ m2: ${(this.mapper2 as unknown as DebugTypeMapper).__debugToString().split("\n")
18741874
let result: Symbol | undefined;
18751875
let lastLocation: Node | undefined;
18761876
let lastSelfReferenceLocation: Node | undefined;
1877-
let propertyWithInvalidInitializer: Node | undefined;
1877+
let propertyWithInvalidInitializer: PropertyDeclaration | undefined;
18781878
let associatedDeclarationForContainingInitializerOrBindingName: ParameterDeclaration | BindingElement | undefined;
18791879
let withinDeferredContext = false;
18801880
const errorLocation = location;
@@ -2008,6 +2008,7 @@ m2: ${(this.mapper2 as unknown as DebugTypeMapper).__debugToString().split("\n")
20082008
if (ctor && ctor.locals) {
20092009
if (lookup(ctor.locals, name, meaning & SymbolFlags.Value)) {
20102010
// Remember the property node, it will be used later to report appropriate error
2011+
Debug.assertNode(location, isPropertyDeclaration);
20112012
propertyWithInvalidInitializer = location;
20122013
}
20132014
}
@@ -2204,19 +2205,48 @@ m2: ${(this.mapper2 as unknown as DebugTypeMapper).__debugToString().split("\n")
22042205
}
22052206
}
22062207
}
2208+
2209+
// The invalid initializer error is needed in two situation:
2210+
// 1. When result is undefined, after checking for a missing "this."
2211+
// 2. When result is defined
2212+
function checkAndReportErrorForInvalidInitializer() {
2213+
if (propertyWithInvalidInitializer && !(getEmitScriptTarget(compilerOptions) === ScriptTarget.ESNext && useDefineForClassFields)) {
2214+
// We have a match, but the reference occurred within a property initializer and the identifier also binds
2215+
// to a local variable in the constructor where the code will be emitted. Note that this is actually allowed
2216+
// with ESNext+useDefineForClassFields because the scope semantics are different.
2217+
error(errorLocation,
2218+
errorLocation && propertyWithInvalidInitializer.type && textRangeContainsPositionInclusive(propertyWithInvalidInitializer.type, errorLocation.pos)
2219+
? Diagnostics.Type_of_instance_member_variable_0_cannot_reference_identifier_1_declared_in_the_constructor
2220+
: Diagnostics.Initializer_of_instance_member_variable_0_cannot_reference_identifier_1_declared_in_the_constructor,
2221+
declarationNameToString(propertyWithInvalidInitializer.name), diagnosticName(nameArg!));
2222+
return true;
2223+
}
2224+
return false;
2225+
}
2226+
22072227
if (!result) {
22082228
if (nameNotFoundMessage) {
22092229
addLazyDiagnostic(() => {
22102230
if (!errorLocation ||
22112231
!checkAndReportErrorForMissingPrefix(errorLocation, name, nameArg!) && // TODO: GH#18217
2232+
!checkAndReportErrorForInvalidInitializer() &&
22122233
!checkAndReportErrorForExtendingInterface(errorLocation) &&
22132234
!checkAndReportErrorForUsingTypeAsNamespace(errorLocation, name, meaning) &&
22142235
!checkAndReportErrorForExportingPrimitiveType(errorLocation, name) &&
22152236
!checkAndReportErrorForUsingTypeAsValue(errorLocation, name, meaning) &&
22162237
!checkAndReportErrorForUsingNamespaceModuleAsValue(errorLocation, name, meaning) &&
22172238
!checkAndReportErrorForUsingValueAsType(errorLocation, name, meaning)) {
22182239
let suggestion: Symbol | undefined;
2219-
if (getSpellingSuggestions && suggestionCount < maximumSuggestionCount) {
2240+
let suggestedLib: string | undefined;
2241+
// Report missing lib first
2242+
if (nameArg) {
2243+
suggestedLib = getSuggestedLibForNonExistentName(nameArg);
2244+
if (suggestedLib) {
2245+
error(errorLocation, nameNotFoundMessage, diagnosticName(nameArg), suggestedLib);
2246+
}
2247+
}
2248+
// then spelling suggestions
2249+
if (!suggestedLib && getSpellingSuggestions && suggestionCount < maximumSuggestionCount) {
22202250
suggestion = getSuggestedSymbolForNonexistentSymbol(originalLocation, name, meaning);
22212251
const isGlobalScopeAugmentationDeclaration = suggestion?.valueDeclaration && isAmbientModule(suggestion.valueDeclaration) && isGlobalScopeAugmentation(suggestion.valueDeclaration);
22222252
if (isGlobalScopeAugmentationDeclaration) {
@@ -2238,31 +2268,17 @@ m2: ${(this.mapper2 as unknown as DebugTypeMapper).__debugToString().split("\n")
22382268
}
22392269
}
22402270
}
2241-
if (!suggestion) {
2242-
if (nameArg) {
2243-
const lib = getSuggestedLibForNonExistentName(nameArg);
2244-
if (lib) {
2245-
error(errorLocation, nameNotFoundMessage, diagnosticName(nameArg), lib);
2246-
}
2247-
else {
2248-
error(errorLocation, nameNotFoundMessage, diagnosticName(nameArg));
2249-
}
2250-
}
2271+
// And then fall back to unspecified "not found"
2272+
if (!suggestion && !suggestedLib && nameArg) {
2273+
error(errorLocation, nameNotFoundMessage, diagnosticName(nameArg));
22512274
}
22522275
suggestionCount++;
22532276
}
22542277
});
22552278
}
22562279
return undefined;
22572280
}
2258-
2259-
if (propertyWithInvalidInitializer && !(getEmitScriptTarget(compilerOptions) === ScriptTarget.ESNext && useDefineForClassFields)) {
2260-
// We have a match, but the reference occurred within a property initializer and the identifier also binds
2261-
// to a local variable in the constructor where the code will be emitted. Note that this is actually allowed
2262-
// with ESNext+useDefineForClassFields because the scope semantics are different.
2263-
const propertyName = (propertyWithInvalidInitializer as PropertyDeclaration).name;
2264-
error(errorLocation, Diagnostics.Initializer_of_instance_member_variable_0_cannot_reference_identifier_1_declared_in_the_constructor,
2265-
declarationNameToString(propertyName), diagnosticName(nameArg!));
2281+
else if (checkAndReportErrorForInvalidInitializer()) {
22662282
return undefined;
22672283
}
22682284

src/compiler/core.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2105,7 +2105,7 @@ namespace ts {
21052105
* and 1 insertion/deletion at 3 characters)
21062106
*/
21072107
export function getSpellingSuggestion<T>(name: string, candidates: T[], getName: (candidate: T) => string | undefined): T | undefined {
2108-
const maximumLengthDifference = Math.min(2, Math.floor(name.length * 0.34));
2108+
const maximumLengthDifference = Math.max(2, Math.floor(name.length * 0.34));
21092109
let bestDistance = Math.floor(name.length * 0.4) + 1; // If the best result is worse than this, don't bother.
21102110
let bestCandidate: T | undefined;
21112111
for (const candidate of candidates) {

src/compiler/diagnosticMessages.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3507,6 +3507,10 @@
35073507
"category": "Error",
35083508
"code": 2843
35093509
},
3510+
"Type of instance member variable '{0}' cannot reference identifier '{1}' declared in the constructor.": {
3511+
"category": "Error",
3512+
"code": 2844
3513+
},
35103514

35113515
"Import declaration '{0}' is using private name '{1}'.": {
35123516
"category": "Error",

tests/baselines/reference/DateTimeFormatAndNumberFormatES2021.errors.txt

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
tests/cases/compiler/DateTimeFormatAndNumberFormatES2021.ts(1,29): error TS2339: Property 'formatRange' does not exist on type 'NumberFormat'.
22
tests/cases/compiler/DateTimeFormatAndNumberFormatES2021.ts(4,25): error TS2339: Property 'formatRange' does not exist on type 'NumberFormat'.
3-
tests/cases/compiler/DateTimeFormatAndNumberFormatES2021.ts(5,25): error TS2339: Property 'formatRangeToParts' does not exist on type 'NumberFormat'.
3+
tests/cases/compiler/DateTimeFormatAndNumberFormatES2021.ts(5,25): error TS2551: Property 'formatRangeToParts' does not exist on type 'NumberFormat'. Did you mean 'formatToParts'?
44

55

66
==== tests/cases/compiler/DateTimeFormatAndNumberFormatES2021.ts (3 errors) ====
@@ -14,6 +14,7 @@ tests/cases/compiler/DateTimeFormatAndNumberFormatES2021.ts(5,25): error TS2339:
1414
!!! error TS2339: Property 'formatRange' does not exist on type 'NumberFormat'.
1515
new Intl.NumberFormat().formatRangeToParts
1616
~~~~~~~~~~~~~~~~~~
17-
!!! error TS2339: Property 'formatRangeToParts' does not exist on type 'NumberFormat'.
17+
!!! error TS2551: Property 'formatRangeToParts' does not exist on type 'NumberFormat'. Did you mean 'formatToParts'?
18+
!!! related TS2728 /.ts/lib.es2018.intl.d.ts:71:9: 'formatToParts' is declared here.
1819
new Intl.DateTimeFormat().formatRange
1920
new Intl.DateTimeFormat().formatRangeToParts
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
1-
tests/cases/conformance/async/es2017/asyncArrowFunction/asyncArrowFunction10_es2017.ts(3,11): error TS2304: Cannot find name 'await'.
1+
tests/cases/conformance/async/es2017/asyncArrowFunction/asyncArrowFunction10_es2017.ts(3,11): error TS2552: Cannot find name 'await'. Did you mean 'Awaited'?
22

33

44
==== tests/cases/conformance/async/es2017/asyncArrowFunction/asyncArrowFunction10_es2017.ts (1 errors) ====
55
var foo = async (): Promise<void> => {
66
// Legal to use 'await' in a type context.
77
var v: await;
88
~~~~~
9-
!!! error TS2304: Cannot find name 'await'.
9+
!!! error TS2552: Cannot find name 'await'. Did you mean 'Awaited'?
1010
}
1111

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
1-
tests/cases/conformance/async/es5/asyncArrowFunction/asyncArrowFunction10_es5.ts(3,11): error TS2304: Cannot find name 'await'.
1+
tests/cases/conformance/async/es5/asyncArrowFunction/asyncArrowFunction10_es5.ts(3,11): error TS2552: Cannot find name 'await'. Did you mean 'Awaited'?
22

33

44
==== tests/cases/conformance/async/es5/asyncArrowFunction/asyncArrowFunction10_es5.ts (1 errors) ====
55
var foo = async (): Promise<void> => {
66
// Legal to use 'await' in a type context.
77
var v: await;
88
~~~~~
9-
!!! error TS2304: Cannot find name 'await'.
9+
!!! error TS2552: Cannot find name 'await'. Did you mean 'Awaited'?
1010
}
1111

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
1-
tests/cases/conformance/async/es6/asyncArrowFunction/asyncArrowFunction10_es6.ts(3,11): error TS2304: Cannot find name 'await'.
1+
tests/cases/conformance/async/es6/asyncArrowFunction/asyncArrowFunction10_es6.ts(3,11): error TS2552: Cannot find name 'await'. Did you mean 'Awaited'?
22

33

44
==== tests/cases/conformance/async/es6/asyncArrowFunction/asyncArrowFunction10_es6.ts (1 errors) ====
55
var foo = async (): Promise<void> => {
66
// Legal to use 'await' in a type context.
77
var v: await;
88
~~~~~
9-
!!! error TS2304: Cannot find name 'await'.
9+
!!! error TS2552: Cannot find name 'await'. Did you mean 'Awaited'?
1010
}
1111

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
1-
tests/cases/conformance/async/es2017/functionDeclarations/asyncFunctionDeclaration13_es2017.ts(3,11): error TS2304: Cannot find name 'await'.
1+
tests/cases/conformance/async/es2017/functionDeclarations/asyncFunctionDeclaration13_es2017.ts(3,11): error TS2552: Cannot find name 'await'. Did you mean 'Awaited'?
22

33

44
==== tests/cases/conformance/async/es2017/functionDeclarations/asyncFunctionDeclaration13_es2017.ts (1 errors) ====
55
async function foo(): Promise<void> {
66
// Legal to use 'await' in a type context.
77
var v: await;
88
~~~~~
9-
!!! error TS2304: Cannot find name 'await'.
9+
!!! error TS2552: Cannot find name 'await'. Did you mean 'Awaited'?
1010
}
1111

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
1-
tests/cases/conformance/async/es5/functionDeclarations/asyncFunctionDeclaration13_es5.ts(3,11): error TS2304: Cannot find name 'await'.
1+
tests/cases/conformance/async/es5/functionDeclarations/asyncFunctionDeclaration13_es5.ts(3,11): error TS2552: Cannot find name 'await'. Did you mean 'Awaited'?
22

33

44
==== tests/cases/conformance/async/es5/functionDeclarations/asyncFunctionDeclaration13_es5.ts (1 errors) ====
55
async function foo(): Promise<void> {
66
// Legal to use 'await' in a type context.
77
var v: await;
88
~~~~~
9-
!!! error TS2304: Cannot find name 'await'.
9+
!!! error TS2552: Cannot find name 'await'. Did you mean 'Awaited'?
1010
}
1111

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
1-
tests/cases/conformance/async/es6/functionDeclarations/asyncFunctionDeclaration13_es6.ts(3,11): error TS2304: Cannot find name 'await'.
1+
tests/cases/conformance/async/es6/functionDeclarations/asyncFunctionDeclaration13_es6.ts(3,11): error TS2552: Cannot find name 'await'. Did you mean 'Awaited'?
22

33

44
==== tests/cases/conformance/async/es6/functionDeclarations/asyncFunctionDeclaration13_es6.ts (1 errors) ====
55
async function foo(): Promise<void> {
66
// Legal to use 'await' in a type context.
77
var v: await;
88
~~~~~
9-
!!! error TS2304: Cannot find name 'await'.
9+
!!! error TS2552: Cannot find name 'await'. Did you mean 'Awaited'?
1010
}
1111

tests/baselines/reference/bigintWithoutLib.errors.txt

Lines changed: 8 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -11,13 +11,13 @@ tests/cases/compiler/bigintWithoutLib.ts(13,38): error TS2554: Expected 0 argume
1111
tests/cases/compiler/bigintWithoutLib.ts(14,38): error TS2554: Expected 0 arguments, but got 2.
1212
tests/cases/compiler/bigintWithoutLib.ts(15,38): error TS2554: Expected 0 arguments, but got 2.
1313
tests/cases/compiler/bigintWithoutLib.ts(18,18): error TS2583: Cannot find name 'BigInt64Array'. Do you need to change your target library? Try changing the 'lib' compiler option to 'es2020' or later.
14-
tests/cases/compiler/bigintWithoutLib.ts(18,38): error TS2552: Cannot find name 'BigInt64Array'. Did you mean 'bigIntArray'?
15-
tests/cases/compiler/bigintWithoutLib.ts(19,19): error TS2552: Cannot find name 'BigInt64Array'. Did you mean 'bigIntArray'?
16-
tests/cases/compiler/bigintWithoutLib.ts(20,19): error TS2552: Cannot find name 'BigInt64Array'. Did you mean 'bigIntArray'?
14+
tests/cases/compiler/bigintWithoutLib.ts(18,38): error TS2583: Cannot find name 'BigInt64Array'. Do you need to change your target library? Try changing the 'lib' compiler option to 'es2020' or later.
15+
tests/cases/compiler/bigintWithoutLib.ts(19,19): error TS2583: Cannot find name 'BigInt64Array'. Do you need to change your target library? Try changing the 'lib' compiler option to 'es2020' or later.
16+
tests/cases/compiler/bigintWithoutLib.ts(20,19): error TS2583: Cannot find name 'BigInt64Array'. Do you need to change your target library? Try changing the 'lib' compiler option to 'es2020' or later.
1717
tests/cases/compiler/bigintWithoutLib.ts(20,34): error TS2737: BigInt literals are not available when targeting lower than ES2020.
1818
tests/cases/compiler/bigintWithoutLib.ts(20,38): error TS2737: BigInt literals are not available when targeting lower than ES2020.
1919
tests/cases/compiler/bigintWithoutLib.ts(20,42): error TS2737: BigInt literals are not available when targeting lower than ES2020.
20-
tests/cases/compiler/bigintWithoutLib.ts(21,19): error TS2552: Cannot find name 'BigInt64Array'. Did you mean 'bigIntArray'?
20+
tests/cases/compiler/bigintWithoutLib.ts(21,19): error TS2583: Cannot find name 'BigInt64Array'. Do you need to change your target library? Try changing the 'lib' compiler option to 'es2020' or later.
2121
tests/cases/compiler/bigintWithoutLib.ts(22,19): error TS2583: Cannot find name 'BigInt64Array'. Do you need to change your target library? Try changing the 'lib' compiler option to 'es2020' or later.
2222
tests/cases/compiler/bigintWithoutLib.ts(23,19): error TS2583: Cannot find name 'BigInt64Array'. Do you need to change your target library? Try changing the 'lib' compiler option to 'es2020' or later.
2323
tests/cases/compiler/bigintWithoutLib.ts(24,19): error TS2583: Cannot find name 'BigInt64Array'. Do you need to change your target library? Try changing the 'lib' compiler option to 'es2020' or later.
@@ -97,16 +97,13 @@ tests/cases/compiler/bigintWithoutLib.ts(56,36): error TS2345: Argument of type
9797
~~~~~~~~~~~~~
9898
!!! error TS2583: Cannot find name 'BigInt64Array'. Do you need to change your target library? Try changing the 'lib' compiler option to 'es2020' or later.
9999
~~~~~~~~~~~~~
100-
!!! error TS2552: Cannot find name 'BigInt64Array'. Did you mean 'bigIntArray'?
101-
!!! related TS2728 tests/cases/compiler/bigintWithoutLib.ts:18:5: 'bigIntArray' is declared here.
100+
!!! error TS2583: Cannot find name 'BigInt64Array'. Do you need to change your target library? Try changing the 'lib' compiler option to 'es2020' or later.
102101
bigIntArray = new BigInt64Array(10);
103102
~~~~~~~~~~~~~
104-
!!! error TS2552: Cannot find name 'BigInt64Array'. Did you mean 'bigIntArray'?
105-
!!! related TS2728 tests/cases/compiler/bigintWithoutLib.ts:18:5: 'bigIntArray' is declared here.
103+
!!! error TS2583: Cannot find name 'BigInt64Array'. Do you need to change your target library? Try changing the 'lib' compiler option to 'es2020' or later.
106104
bigIntArray = new BigInt64Array([1n, 2n, 3n]);
107105
~~~~~~~~~~~~~
108-
!!! error TS2552: Cannot find name 'BigInt64Array'. Did you mean 'bigIntArray'?
109-
!!! related TS2728 tests/cases/compiler/bigintWithoutLib.ts:18:5: 'bigIntArray' is declared here.
106+
!!! error TS2583: Cannot find name 'BigInt64Array'. Do you need to change your target library? Try changing the 'lib' compiler option to 'es2020' or later.
110107
~~
111108
!!! error TS2737: BigInt literals are not available when targeting lower than ES2020.
112109
~~
@@ -115,8 +112,7 @@ tests/cases/compiler/bigintWithoutLib.ts(56,36): error TS2345: Argument of type
115112
!!! error TS2737: BigInt literals are not available when targeting lower than ES2020.
116113
bigIntArray = new BigInt64Array([1, 2, 3]);
117114
~~~~~~~~~~~~~
118-
!!! error TS2552: Cannot find name 'BigInt64Array'. Did you mean 'bigIntArray'?
119-
!!! related TS2728 tests/cases/compiler/bigintWithoutLib.ts:18:5: 'bigIntArray' is declared here.
115+
!!! error TS2583: Cannot find name 'BigInt64Array'. Do you need to change your target library? Try changing the 'lib' compiler option to 'es2020' or later.
120116
bigIntArray = new BigInt64Array(new ArrayBuffer(80));
121117
~~~~~~~~~~~~~
122118
!!! error TS2583: Cannot find name 'BigInt64Array'. Do you need to change your target library? Try changing the 'lib' compiler option to 'es2020' or later.

0 commit comments

Comments
 (0)