Skip to content
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

Spelling correction #15507

Merged
merged 13 commits into from
May 9, 2017
Merged
202 changes: 153 additions & 49 deletions src/compiler/checker.ts

Large diffs are not rendered by default.

13 changes: 12 additions & 1 deletion src/compiler/diagnosticMessages.json
Original file line number Diff line number Diff line change
Expand Up @@ -1843,6 +1843,14 @@
"category": "Error",
"code": 2550
},
"Property '{0}' does not exist on type '{1}'. Did you mean '{2}'?": {
"category": "Error",
"code": 2551
},
"Cannot find name '{0}'. Did you mean '{1}'?": {
"category": "Error",
"code": 2552
},
"JSX element attributes type '{0}' may not be a union type.": {
"category": "Error",
"code": 2600
Expand Down Expand Up @@ -3532,7 +3540,10 @@
"category": "Message",
"code": 90021
},

"Change spelling to '{0}'.": {
"category": "Message",
"code": 90022
},

"Octal literal types must use ES2015 syntax. Use the syntax '{0}'.": {
"category": "Error",
Expand Down
2 changes: 2 additions & 0 deletions src/compiler/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2545,6 +2545,8 @@ namespace ts {

tryGetMemberInModuleExports(memberName: string, moduleSymbol: Symbol): Symbol | undefined;
getApparentType(type: Type): Type;
getSuggestionForNonexistentProperty(node: Identifier, containingType: Type): string | undefined;
getSuggestionForNonexistentSymbol(location: Node, name: string, meaning: SymbolFlags): string;

/* @internal */ tryFindAmbientModuleWithoutAugmentations(moduleName: string): Symbol;

Expand Down
23 changes: 23 additions & 0 deletions src/compiler/utilities.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4629,4 +4629,27 @@ namespace ts {
export function unescapeIdentifier(identifier: string): string {
return identifier.length >= 3 && identifier.charCodeAt(0) === CharacterCodes._ && identifier.charCodeAt(1) === CharacterCodes._ && identifier.charCodeAt(2) === CharacterCodes._ ? identifier.substr(1) : identifier;
}

export function levenshtein(s1: string, s2: string): number {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Did you intend for levenshtein to be in the public TypeScript API? This file has two top-level ts namespaces, the first marked with /* @internal */ and the second without the marker. This code is in the second namespace currently.

let previous: number[] = new Array(s2.length + 1);
let current: number[] = new Array(s2.length + 1);
for (let i = 0; i < s2.length + 1; i++) {
previous[i] = i;
current[i] = -1;
}
for (let i = 1; i < s1.length + 1; i++) {
current[0] = i;
for (let j = 1; j < s2.length + 1; j++) {
current[j] = Math.min(
previous[j] + 1,
current[j - 1] + 1,
previous[j - 1] + (s1[i - 1] === s2[j - 1] ? 0 : 2));
}
// shift current back to previous, and then reuse previous' array
const tmp = previous;
previous = current;
current = tmp;
}
return previous[previous.length - 1];
}
}
5 changes: 3 additions & 2 deletions src/services/codefixes/fixAddMissingMember.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
/* @internal */
namespace ts.codefix {
registerCodeFix({
errorCodes: [Diagnostics.Property_0_does_not_exist_on_type_1.code],
errorCodes: [Diagnostics.Property_0_does_not_exist_on_type_1.code,
Diagnostics.Property_0_does_not_exist_on_type_1_Did_you_mean_2.code],
getCodeActions: getActionsForAddMissingMember
});

Expand Down Expand Up @@ -135,4 +136,4 @@ namespace ts.codefix {
return actions;
}
}
}
}
53 changes: 53 additions & 0 deletions src/services/codefixes/fixSpelling.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
/* @internal */
namespace ts.codefix {
registerCodeFix({
errorCodes: [Diagnostics.Property_0_does_not_exist_on_type_1_Did_you_mean_2.code,
Diagnostics.Cannot_find_name_0_Did_you_mean_1.code],
getCodeActions: getActionsForCorrectSpelling
});

function getActionsForCorrectSpelling(context: CodeFixContext): CodeAction[] | undefined {
const sourceFile = context.sourceFile;

// This is the identifier of the misspelled word. eg:
// this.speling = 1;
// ^^^^^^^
const node = getTokenAtPosition(sourceFile, context.span.start);
const checker = context.program.getTypeChecker();
let suggestion: string;
if (node.kind === SyntaxKind.Identifier && isPropertyAccessExpression(node.parent)) {
const containingType = checker.getTypeAtLocation(node.parent.expression);
suggestion = checker.getSuggestionForNonexistentProperty(node as Identifier, containingType);
}
else {
const meaning = getMeaningFromLocation(node);
suggestion = checker.getSuggestionForNonexistentSymbol(node, getTextOfNode(node), convertSemanticMeaningToSymbolFlags(meaning));
}
if (suggestion) {
return [{
description: formatStringFromArgs(getLocaleSpecificMessage(Diagnostics.Change_spelling_to_0), [suggestion]),
changes: [{
fileName: sourceFile.fileName,
textChanges: [{
span: { start: node.getStart(), length: node.getWidth() },
newText: suggestion
}],
}],
}];
}
}

function convertSemanticMeaningToSymbolFlags(meaning: SemanticMeaning): SymbolFlags {
let flags = 0;
if (meaning & SemanticMeaning.Namespace) {
flags |= SymbolFlags.Namespace;
}
if (meaning & SemanticMeaning.Type) {
flags |= SymbolFlags.Type;
}
if (meaning & SemanticMeaning.Value) {
flags |= SymbolFlags.Value;
}
return flags;
}
}
1 change: 1 addition & 0 deletions src/services/codefixes/fixes.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
/// <reference path="fixClassIncorrectlyImplementsInterface.ts" />
/// <reference path="fixAddMissingMember.ts" />
/// <reference path="fixSpelling.ts" />
/// <reference path="fixClassDoesntImplementInheritedAbstractMember.ts" />
/// <reference path="fixClassSuperMustPrecedeThisAccess.ts" />
/// <reference path="fixConstructorForDerivedNeedSuperCall.ts" />
Expand Down
1 change: 1 addition & 0 deletions src/services/codefixes/importFixes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,7 @@ namespace ts.codefix {
registerCodeFix({
errorCodes: [
Diagnostics.Cannot_find_name_0.code,
Diagnostics.Cannot_find_name_0_Did_you_mean_1.code,
Diagnostics.Cannot_find_namespace_0.code,
Diagnostics._0_refers_to_a_UMD_global_but_the_current_file_is_a_module_Consider_adding_an_import_instead.code
],
Expand Down
3 changes: 2 additions & 1 deletion src/services/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@
"formatting/tokenRange.ts",
"codeFixProvider.ts",
"codefixes/fixAddMissingMember.ts",
"codefixes/fixSpelling.ts",
"codefixes/fixExtendsInterfaceBecomesImplements.ts",
"codefixes/fixClassIncorrectlyImplementsInterface.ts",
"codefixes/fixClassDoesntImplementInheritedAbstractMember.ts",
Expand All @@ -94,4 +95,4 @@
"codefixes/unusedIdentifierFixes.ts",
"codefixes/disableJsDiagnostics.ts"
]
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
tests/cases/conformance/internalModules/exportDeclarations/ModuleWithExportedAndNonExportedFunctions.ts(28,13): error TS2339: Property 'fn2' does not exist on type 'typeof A'.
tests/cases/conformance/internalModules/exportDeclarations/ModuleWithExportedAndNonExportedFunctions.ts(29,14): error TS2339: Property 'fng2' does not exist on type 'typeof A'.
tests/cases/conformance/internalModules/exportDeclarations/ModuleWithExportedAndNonExportedFunctions.ts(28,13): error TS2551: Property 'fn2' does not exist on type 'typeof A'. Did you mean 'fng'?
tests/cases/conformance/internalModules/exportDeclarations/ModuleWithExportedAndNonExportedFunctions.ts(29,14): error TS2551: Property 'fng2' does not exist on type 'typeof A'. Did you mean 'fng'?


==== tests/cases/conformance/internalModules/exportDeclarations/ModuleWithExportedAndNonExportedFunctions.ts (2 errors) ====
Expand Down Expand Up @@ -32,7 +32,7 @@ tests/cases/conformance/internalModules/exportDeclarations/ModuleWithExportedAnd
// these should be errors since the functions are not exported
var fn2 = A.fn2;
~~~
!!! error TS2339: Property 'fn2' does not exist on type 'typeof A'.
!!! error TS2551: Property 'fn2' does not exist on type 'typeof A'. Did you mean 'fng'?
var fng2 = A.fng2;
~~~~
!!! error TS2339: Property 'fng2' does not exist on type 'typeof A'.
!!! error TS2551: Property 'fng2' does not exist on type 'typeof A'. Did you mean 'fng'?
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
tests/cases/conformance/es6/variableDeclarations/VariableDeclaration11_es6.ts(2,1): error TS1212: Identifier expected. 'let' is a reserved word in strict mode.
tests/cases/conformance/es6/variableDeclarations/VariableDeclaration11_es6.ts(2,1): error TS2304: Cannot find name 'let'.
tests/cases/conformance/es6/variableDeclarations/VariableDeclaration11_es6.ts(2,1): error TS2552: Cannot find name 'let'. Did you mean 'Set'?


==== tests/cases/conformance/es6/variableDeclarations/VariableDeclaration11_es6.ts (2 errors) ====
Expand All @@ -8,4 +8,4 @@ tests/cases/conformance/es6/variableDeclarations/VariableDeclaration11_es6.ts(2,
~~~
!!! error TS1212: Identifier expected. 'let' is a reserved word in strict mode.
~~~
!!! error TS2304: Cannot find name 'let'.
!!! error TS2552: Cannot find name 'let'. Did you mean 'Set'?
4 changes: 2 additions & 2 deletions tests/baselines/reference/VariableDeclaration6_es6.errors.txt
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
tests/cases/conformance/es6/variableDeclarations/VariableDeclaration6_es6.ts(1,1): error TS2304: Cannot find name 'let'.
tests/cases/conformance/es6/variableDeclarations/VariableDeclaration6_es6.ts(1,1): error TS2552: Cannot find name 'let'. Did you mean 'Set'?


==== tests/cases/conformance/es6/variableDeclarations/VariableDeclaration6_es6.ts (1 errors) ====
let
~~~
!!! error TS2304: Cannot find name 'let'.
!!! error TS2552: Cannot find name 'let'. Did you mean 'Set'?
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
tests/cases/compiler/anonymousClassExpression2.ts(13,18): error TS2339: Property 'methodA' does not exist on type 'B'.
tests/cases/compiler/anonymousClassExpression2.ts(13,18): error TS2551: Property 'methodA' does not exist on type 'B'. Did you mean 'methodB'?


==== tests/cases/compiler/anonymousClassExpression2.ts (1 errors) ====
Expand All @@ -16,7 +16,7 @@ tests/cases/compiler/anonymousClassExpression2.ts(13,18): error TS2339: Property
methodB() {
this.methodA; // error
~~~~~~~
!!! error TS2339: Property 'methodA' does not exist on type 'B'.
!!! error TS2551: Property 'methodA' does not exist on type 'B'. Did you mean 'methodB'?
this.methodB; // ok
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
tests/cases/compiler/assignmentRestElementWithErrorSourceType.ts(2,5): error TS2304: Cannot find name 'c'.
tests/cases/compiler/assignmentRestElementWithErrorSourceType.ts(2,10): error TS2304: Cannot find name 'tupel'.
tests/cases/compiler/assignmentRestElementWithErrorSourceType.ts(2,10): error TS2552: Cannot find name 'tupel'. Did you mean 'tuple'?


==== tests/cases/compiler/assignmentRestElementWithErrorSourceType.ts (2 errors) ====
Expand All @@ -8,4 +8,4 @@ tests/cases/compiler/assignmentRestElementWithErrorSourceType.ts(2,10): error TS
~
!!! error TS2304: Cannot find name 'c'.
~~~~~
!!! error TS2304: Cannot find name 'tupel'.
!!! error TS2552: Cannot find name 'tupel'. Did you mean 'tuple'?
20 changes: 10 additions & 10 deletions tests/baselines/reference/autoLift2.errors.txt
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
tests/cases/compiler/autoLift2.ts(5,14): error TS2339: Property 'foo' does not exist on type 'A'.
tests/cases/compiler/autoLift2.ts(5,17): error TS1005: ';' expected.
tests/cases/compiler/autoLift2.ts(5,19): error TS2304: Cannot find name 'any'.
tests/cases/compiler/autoLift2.ts(6,14): error TS2339: Property 'bar' does not exist on type 'A'.
tests/cases/compiler/autoLift2.ts(5,19): error TS2552: Cannot find name 'any'. Did you mean 'NaN'?
tests/cases/compiler/autoLift2.ts(6,14): error TS2551: Property 'bar' does not exist on type 'A'. Did you mean 'baz'?
tests/cases/compiler/autoLift2.ts(6,17): error TS1005: ';' expected.
tests/cases/compiler/autoLift2.ts(6,19): error TS2304: Cannot find name 'any'.
tests/cases/compiler/autoLift2.ts(6,19): error TS2552: Cannot find name 'any'. Did you mean 'NaN'?
tests/cases/compiler/autoLift2.ts(12,11): error TS2339: Property 'foo' does not exist on type 'A'.
tests/cases/compiler/autoLift2.ts(14,11): error TS2339: Property 'bar' does not exist on type 'A'.
tests/cases/compiler/autoLift2.ts(14,11): error TS2551: Property 'bar' does not exist on type 'A'. Did you mean 'baz'?
tests/cases/compiler/autoLift2.ts(16,33): error TS2339: Property 'foo' does not exist on type 'A'.
tests/cases/compiler/autoLift2.ts(18,33): error TS2339: Property 'bar' does not exist on type 'A'.
tests/cases/compiler/autoLift2.ts(18,33): error TS2551: Property 'bar' does not exist on type 'A'. Did you mean 'baz'?


==== tests/cases/compiler/autoLift2.ts (10 errors) ====
Expand All @@ -21,14 +21,14 @@ tests/cases/compiler/autoLift2.ts(18,33): error TS2339: Property 'bar' does not
~
!!! error TS1005: ';' expected.
~~~
!!! error TS2304: Cannot find name 'any'.
!!! error TS2552: Cannot find name 'any'. Did you mean 'NaN'?
this.bar: any;
~~~
!!! error TS2339: Property 'bar' does not exist on type 'A'.
!!! error TS2551: Property 'bar' does not exist on type 'A'. Did you mean 'baz'?
~
!!! error TS1005: ';' expected.
~~~
!!! error TS2304: Cannot find name 'any'.
!!! error TS2552: Cannot find name 'any'. Did you mean 'NaN'?
}


Expand All @@ -40,15 +40,15 @@ tests/cases/compiler/autoLift2.ts(18,33): error TS2339: Property 'bar' does not

this.bar = "bar";
~~~
!!! error TS2339: Property 'bar' does not exist on type 'A'.
!!! error TS2551: Property 'bar' does not exist on type 'A'. Did you mean 'baz'?

[1, 2].forEach((p) => this.foo);
~~~
!!! error TS2339: Property 'foo' does not exist on type 'A'.

[1, 2].forEach((p) => this.bar);
~~~
!!! error TS2339: Property 'bar' does not exist on type 'A'.
!!! error TS2551: Property 'bar' does not exist on type 'A'. Did you mean 'baz'?

}

Expand Down
4 changes: 2 additions & 2 deletions tests/baselines/reference/badArrayIndex.errors.txt
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
tests/cases/compiler/badArrayIndex.ts(1,15): error TS2304: Cannot find name 'number'.
tests/cases/compiler/badArrayIndex.ts(1,15): error TS2552: Cannot find name 'number'. Did you mean 'Number'?
tests/cases/compiler/badArrayIndex.ts(1,22): error TS1109: Expression expected.


==== tests/cases/compiler/badArrayIndex.ts (2 errors) ====
var results = number[];
~~~~~~
!!! error TS2304: Cannot find name 'number'.
!!! error TS2552: Cannot find name 'number'. Did you mean 'Number'?
~
!!! error TS1109: Expression expected.
4 changes: 2 additions & 2 deletions tests/baselines/reference/baseCheck.errors.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
tests/cases/compiler/baseCheck.ts(9,18): error TS2304: Cannot find name 'loc'.
tests/cases/compiler/baseCheck.ts(9,18): error TS2552: Cannot find name 'loc'. Did you mean 'ELoc'?
tests/cases/compiler/baseCheck.ts(17,53): error TS2346: Supplied parameters do not match any signature of call target.
tests/cases/compiler/baseCheck.ts(17,59): error TS17009: 'super' must be called before accessing 'this' in the constructor of a derived class.
tests/cases/compiler/baseCheck.ts(18,62): error TS17009: 'super' must be called before accessing 'this' in the constructor of a derived class.
Expand All @@ -20,7 +20,7 @@ tests/cases/compiler/baseCheck.ts(26,9): error TS2304: Cannot find name 'x'.
constructor(x: number) {
super(0, loc);
~~~
!!! error TS2304: Cannot find name 'loc'.
!!! error TS2552: Cannot find name 'loc'. Did you mean 'ELoc'?
}

m() {
Expand Down
8 changes: 4 additions & 4 deletions tests/baselines/reference/bases.errors.txt
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
tests/cases/compiler/bases.ts(7,14): error TS2339: Property 'y' does not exist on type 'B'.
tests/cases/compiler/bases.ts(7,15): error TS1005: ';' expected.
tests/cases/compiler/bases.ts(7,17): error TS2304: Cannot find name 'any'.
tests/cases/compiler/bases.ts(7,17): error TS2552: Cannot find name 'any'. Did you mean 'NaN'?
tests/cases/compiler/bases.ts(11,7): error TS2420: Class 'C' incorrectly implements interface 'I'.
Property 'x' is missing in type 'C'.
tests/cases/compiler/bases.ts(12,5): error TS2377: Constructors for derived classes must contain a 'super' call.
tests/cases/compiler/bases.ts(13,9): error TS17009: 'super' must be called before accessing 'this' in the constructor of a derived class.
tests/cases/compiler/bases.ts(13,14): error TS2339: Property 'x' does not exist on type 'C'.
tests/cases/compiler/bases.ts(13,15): error TS1005: ';' expected.
tests/cases/compiler/bases.ts(13,17): error TS2304: Cannot find name 'any'.
tests/cases/compiler/bases.ts(13,17): error TS2552: Cannot find name 'any'. Did you mean 'NaN'?
tests/cases/compiler/bases.ts(17,9): error TS2339: Property 'x' does not exist on type 'C'.
tests/cases/compiler/bases.ts(18,9): error TS2339: Property 'y' does not exist on type 'C'.

Expand All @@ -25,7 +25,7 @@ tests/cases/compiler/bases.ts(18,9): error TS2339: Property 'y' does not exist o
~
!!! error TS1005: ';' expected.
~~~
!!! error TS2304: Cannot find name 'any'.
!!! error TS2552: Cannot find name 'any'. Did you mean 'NaN'?
}
}

Expand All @@ -44,7 +44,7 @@ tests/cases/compiler/bases.ts(18,9): error TS2339: Property 'y' does not exist o
~
!!! error TS1005: ';' expected.
~~~
!!! error TS2304: Cannot find name 'any'.
!!! error TS2552: Cannot find name 'any'. Did you mean 'NaN'?
}
~~~~~
!!! error TS2377: Constructors for derived classes must contain a 'super' call.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
tests/cases/compiler/breakInIterationOrSwitchStatement4.ts(1,15): error TS2304: Cannot find name 'something'.
tests/cases/compiler/breakInIterationOrSwitchStatement4.ts(1,15): error TS2552: Cannot find name 'something'. Did you mean 'String'?


==== tests/cases/compiler/breakInIterationOrSwitchStatement4.ts (1 errors) ====
for (var i in something) {
~~~~~~~~~
!!! error TS2304: Cannot find name 'something'.
!!! error TS2552: Cannot find name 'something'. Did you mean 'String'?
break;
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
tests/cases/compiler/cannotInvokeNewOnIndexExpression.ts(1,23): error TS2304: Cannot find name 'any'.
tests/cases/compiler/cannotInvokeNewOnIndexExpression.ts(1,23): error TS2552: Cannot find name 'any'. Did you mean 'NaN'?


==== tests/cases/compiler/cannotInvokeNewOnIndexExpression.ts (1 errors) ====
var test: any[] = new any[1];
~~~
!!! error TS2304: Cannot find name 'any'.
!!! error TS2552: Cannot find name 'any'. Did you mean 'NaN'?
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
tests/cases/conformance/jsx/file.tsx(24,28): error TS2339: Property 'NAme' does not exist on type 'IUser'.
tests/cases/conformance/jsx/file.tsx(24,28): error TS2551: Property 'NAme' does not exist on type 'IUser'. Did you mean 'Name'?
tests/cases/conformance/jsx/file.tsx(32,9): error TS2322: Type '{ children: ((user: IUser) => Element)[]; }' is not assignable to type 'IntrinsicAttributes & IntrinsicClassAttributes<FetchUser> & IFetchUserProps & { children?: ReactNode; }'.
Type '{ children: ((user: IUser) => Element)[]; }' is not assignable to type 'IFetchUserProps'.
Types of property 'children' are incompatible.
Expand Down Expand Up @@ -32,7 +32,7 @@ tests/cases/conformance/jsx/file.tsx(32,9): error TS2322: Type '{ children: ((us
{ user => (
<h1>{ user.NAme }</h1>
~~~~
!!! error TS2339: Property 'NAme' does not exist on type 'IUser'.
!!! error TS2551: Property 'NAme' does not exist on type 'IUser'. Did you mean 'Name'?
) }
</FetchUser>
);
Expand Down
Loading