Skip to content

Commit 4fce495

Browse files
committed
chore: resolve review
1 parent d33256c commit 4fce495

File tree

6 files changed

+28
-21
lines changed

6 files changed

+28
-21
lines changed

src/compiler/checker.ts

Lines changed: 21 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -606,6 +606,7 @@ namespace ts {
606606
getAllPossiblePropertiesOfTypes,
607607
getSuggestedSymbolForNonexistentProperty,
608608
getSuggestionForNonexistentProperty,
609+
getSuggestedSymbolForNonexistentJSXAttribute,
609610
getSuggestedSymbolForNonexistentSymbol: (location, name, meaning) => getSuggestedSymbolForNonexistentSymbol(location, escapeLeadingUnderscores(name), meaning),
610611
getSuggestionForNonexistentSymbol: (location, name, meaning) => getSuggestionForNonexistentSymbol(location, escapeLeadingUnderscores(name), meaning),
611612
getSuggestedSymbolForNonexistentModule,
@@ -24852,7 +24853,7 @@ namespace ts {
2485224853
relatedInfo = createDiagnosticForNode(propNode, Diagnostics.Did_you_forget_to_use_await);
2485324854
}
2485424855
else {
24855-
const suggestion = getSuggestedSymbolForNonexistentProperty(propNode, containingType, /*isJsxAttr*/ false);
24856+
const suggestion = getSuggestedSymbolForNonexistentProperty(propNode, containingType);
2485624857
if (suggestion !== undefined) {
2485724858
const suggestedName = symbolName(suggestion);
2485824859
errorInfo = chainDiagnosticMessages(errorInfo, Diagnostics.Property_0_does_not_exist_on_type_1_Did_you_mean_2, declarationNameToString(propNode), typeToString(containingType), suggestedName);
@@ -24875,12 +24876,24 @@ namespace ts {
2487524876
return prop !== undefined && prop.valueDeclaration && hasSyntacticModifier(prop.valueDeclaration, ModifierFlags.Static);
2487624877
}
2487724878

24878-
function getSuggestedSymbolForNonexistentProperty(name: Identifier | PrivateIdentifier | string, containingType: Type, isJsxAttr: boolean): Symbol | undefined {
24879-
return getSpellingSuggestionForName(isString(name) ? name : idText(name), getPropertiesOfType(containingType), SymbolFlags.Value, isJsxAttr);
24879+
function getSuggestedSymbolForNonexistentProperty(name: Identifier | PrivateIdentifier | string, containingType: Type): Symbol | undefined {
24880+
return getSpellingSuggestionForName(isString(name) ? name : idText(name), getPropertiesOfType(containingType), SymbolFlags.Value);
2488024881
}
2488124882

24883+
function getSuggestedSymbolForNonexistentJSXAttribute(name: Identifier | PrivateIdentifier | string, containingType: Type): Symbol | undefined {
24884+
const strName = isString(name) ? name : idText(name);
24885+
const properties = getPropertiesOfType(containingType);
24886+
const defaultSuggestion = () => getSpellingSuggestionForName(strName, properties, SymbolFlags.Value);
24887+
const getCandidate = (expectedName: string) => properties.find(x => symbolName(x) === expectedName);
24888+
switch (strName) {
24889+
case "for": return getCandidate("htmlFor") || defaultSuggestion();
24890+
case "class": return getCandidate("className") || defaultSuggestion();
24891+
}
24892+
return defaultSuggestion();
24893+
}
24894+
2488224895
function getSuggestionForNonexistentProperty(name: Identifier | PrivateIdentifier | string, containingType: Type, isJsxAttr: boolean): string | undefined {
24883-
const suggestion = getSuggestedSymbolForNonexistentProperty(name, containingType, isJsxAttr);
24896+
const suggestion = (isJsxAttr ? getSuggestedSymbolForNonexistentJSXAttribute : getSuggestedSymbolForNonexistentProperty)(name, containingType);
2488424897
return suggestion && symbolName(suggestion);
2488524898
}
2488624899

@@ -24892,7 +24905,7 @@ namespace ts {
2489224905
// 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
2489324906
// So the table *contains* `x` but `x` isn't actually in scope.
2489424907
// However, resolveNameHelper will continue and call this callback again, so we'll eventually get a correct suggestion.
24895-
return symbol || getSpellingSuggestionForName(unescapeLeadingUnderscores(name), arrayFrom(symbols.values()), meaning, /*isJsxAttr*/ false);
24908+
return symbol || getSpellingSuggestionForName(unescapeLeadingUnderscores(name), arrayFrom(symbols.values()), meaning);
2489624909
});
2489724910
return result;
2489824911
}
@@ -24903,7 +24916,7 @@ namespace ts {
2490324916
}
2490424917

2490524918
function getSuggestedSymbolForNonexistentModule(name: Identifier, targetModule: Symbol): Symbol | undefined {
24906-
return targetModule.exports && getSpellingSuggestionForName(idText(name), getExportsOfModuleAsArray(targetModule), SymbolFlags.ModuleMember, /*isJsxAttr*/ false);
24919+
return targetModule.exports && getSpellingSuggestionForName(idText(name), getExportsOfModuleAsArray(targetModule), SymbolFlags.ModuleMember);
2490724920
}
2490824921

2490924922
function getSuggestionForNonexistentExport(name: Identifier, targetModule: Symbol): string | undefined {
@@ -24953,8 +24966,8 @@ namespace ts {
2495324966
* (0.4 allows 1 substitution/transposition for every 5 characters,
2495424967
* and 1 insertion/deletion at 3 characters)
2495524968
*/
24956-
function getSpellingSuggestionForName(name: string, symbols: Symbol[], meaning: SymbolFlags, isJsxAttr: boolean): Symbol | undefined {
24957-
return getSpellingSuggestion(name, symbols, getCandidateName, isJsxAttr);
24969+
function getSpellingSuggestionForName(name: string, symbols: Symbol[], meaning: SymbolFlags): Symbol | undefined {
24970+
return getSpellingSuggestion(name, symbols, getCandidateName);
2495824971
function getCandidateName(candidate: Symbol) {
2495924972
const candidateName = symbolName(candidate);
2496024973
if (startsWith(candidateName, "\"")) {

src/compiler/commandLineParser.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1194,7 +1194,7 @@ namespace ts {
11941194
createDiagnostics: (message: DiagnosticMessage, arg0: string, arg1?: string) => Diagnostic,
11951195
unknownOptionErrorText?: string
11961196
) {
1197-
const possibleOption = getSpellingSuggestion(unknownOption, diagnostics.optionDeclarations, getOptionName, /*isJsxAttr*/ false);
1197+
const possibleOption = getSpellingSuggestion(unknownOption, diagnostics.optionDeclarations, getOptionName);
11981198
return possibleOption ?
11991199
createDiagnostics(diagnostics.unknownDidYouMeanDiagnostic, unknownOptionErrorText || unknownOption, possibleOption.name) :
12001200
createDiagnostics(diagnostics.unknownOptionDiagnostic, unknownOptionErrorText || unknownOption);

src/compiler/core.ts

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1817,21 +1817,14 @@ namespace ts {
18171817
* (0.4 allows 1 substitution/transposition for every 5 characters,
18181818
* and 1 insertion/deletion at 3 characters)
18191819
*/
1820-
export function getSpellingSuggestion<T>(name: string, candidates: T[], getName: (candidate: T) => string | undefined, isJsxAttr: boolean): T | undefined {
1820+
export function getSpellingSuggestion<T>(name: string, candidates: T[], getName: (candidate: T) => string | undefined): T | undefined {
18211821
const maximumLengthDifference = Math.min(2, Math.floor(name.length * 0.34));
18221822
let bestDistance = Math.floor(name.length * 0.4) + 1; // If the best result isn't better than this, don't bother.
18231823
let bestCandidate: T | undefined;
18241824
let justCheckExactMatches = false;
18251825
const nameLowerCase = name.toLowerCase();
18261826
for (const candidate of candidates) {
18271827
const candidateName = getName(candidate);
1828-
if (isJsxAttr) {
1829-
const htmlFor = name === "for" && candidateName === "htmlFor";
1830-
const className = name === "class" && candidateName === "className";
1831-
if (htmlFor || className) {
1832-
return candidate;
1833-
}
1834-
}
18351828
if (candidateName !== undefined && Math.abs(candidateName.length - nameLowerCase.length) <= maximumLengthDifference) {
18361829
const candidateNameLowerCase = candidateName.toLowerCase();
18371830
if (candidateNameLowerCase === nameLowerCase) {

src/compiler/program.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2784,7 +2784,7 @@ namespace ts {
27842784
}
27852785
else {
27862786
const unqualifiedLibName = removeSuffix(removePrefix(libName, "lib."), ".d.ts");
2787-
const suggestion = getSpellingSuggestion(unqualifiedLibName, libs, identity, /*isJsxAttr*/ false);
2787+
const suggestion = getSpellingSuggestion(unqualifiedLibName, libs, identity);
27882788
const message = suggestion ? Diagnostics.Cannot_find_lib_definition_for_0_Did_you_mean_1 : Diagnostics.Cannot_find_lib_definition_for_0;
27892789
fileProcessingDiagnostics.add(createFileDiagnostic(
27902790
file,

src/compiler/types.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4009,7 +4009,8 @@ namespace ts {
40094009
*/
40104010
/* @internal */ tryGetMemberInModuleExportsAndProperties(memberName: string, moduleSymbol: Symbol): Symbol | undefined;
40114011
getApparentType(type: Type): Type;
4012-
/* @internal */ getSuggestedSymbolForNonexistentProperty(name: Identifier | PrivateIdentifier | string, containingType: Type, isJsxAttr: boolean): Symbol | undefined;
4012+
/* @internal */ getSuggestedSymbolForNonexistentProperty(name: Identifier | PrivateIdentifier | string, containingType: Type): Symbol | undefined;
4013+
/* @internal */ getSuggestedSymbolForNonexistentJSXAttribute(name: Identifier | string, containingType: Type): Symbol | undefined;
40134014
/* @internal */ getSuggestionForNonexistentProperty(name: Identifier | PrivateIdentifier | string, containingType: Type, isJsxAttr: boolean): string | undefined;
40144015
/* @internal */ getSuggestedSymbolForNonexistentSymbol(location: Node, name: string, meaning: SymbolFlags): Symbol | undefined;
40154016
/* @internal */ getSuggestionForNonexistentSymbol(location: Node, name: string, meaning: SymbolFlags): string | undefined;

src/services/codefixes/fixSpelling.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ namespace ts.codefix {
5151
if (parent.flags & NodeFlags.OptionalChain) {
5252
containingType = checker.getNonNullableType(containingType);
5353
}
54-
suggestedSymbol = checker.getSuggestedSymbolForNonexistentProperty(node, containingType, /*isJsxAttr*/ false);
54+
suggestedSymbol = checker.getSuggestedSymbolForNonexistentProperty(node, containingType);
5555
}
5656
else if (isImportSpecifier(parent) && parent.name === node) {
5757
Debug.assertNode(node, isIdentifier, "Expected an identifier for spelling (import)");
@@ -65,7 +65,7 @@ namespace ts.codefix {
6565
Debug.assertNode(node, isIdentifier, "Expected an identifier for JSX attribute");
6666
const tag = findAncestor(node, isJsxOpeningLikeElement)!;
6767
const props = checker.getContextualTypeForArgumentAtIndex(tag, 0);
68-
suggestedSymbol = checker.getSuggestedSymbolForNonexistentProperty(node, props!, /** isJsxAttr */ true);
68+
suggestedSymbol = checker.getSuggestedSymbolForNonexistentJSXAttribute(node, props!);
6969
}
7070
else {
7171
const meaning = getMeaningFromLocation(node);

0 commit comments

Comments
 (0)