feat(44263): add quick fix for misspelled override error (#44266)

This commit is contained in:
Oleksandr T
2021-06-09 01:17:56 +03:00
committed by GitHub
parent 703c1bc69d
commit 591be7bece
10 changed files with 131 additions and 2 deletions

View File

@@ -635,6 +635,7 @@ namespace ts {
getSuggestionForNonexistentSymbol: (location, name, meaning) => getSuggestionForNonexistentSymbol(location, escapeLeadingUnderscores(name), meaning),
getSuggestedSymbolForNonexistentModule,
getSuggestionForNonexistentExport,
getSuggestedSymbolForNonexistentClassMember,
getBaseConstraintOfType,
getDefaultFromTypeParameter: type => type && type.flags & TypeFlags.TypeParameter ? getDefaultFromTypeParameter(type as TypeParameter) : undefined,
resolveName(name, location, meaning, excludeGlobals) {
@@ -27720,6 +27721,10 @@ namespace ts {
}
}
function getSuggestedSymbolForNonexistentClassMember(name: string, baseType: Type): Symbol | undefined {
return getSpellingSuggestionForName(name, arrayFrom(getMembersOfSymbol(baseType.symbol).values()), SymbolFlags.ClassMember);
}
function getSuggestedSymbolForNonexistentProperty(name: Identifier | PrivateIdentifier | string, containingType: Type): Symbol | undefined {
let props = getPropertiesOfType(containingType);
if (typeof name !== "string") {
@@ -27739,7 +27744,7 @@ namespace ts {
: strName === "class" ? find(properties, x => symbolName(x) === "className")
: undefined;
return jsxSpecific ?? getSpellingSuggestionForName(strName, properties, SymbolFlags.Value);
}
}
function getSuggestionForNonexistentProperty(name: Identifier | PrivateIdentifier | string, containingType: Type): string | undefined {
const suggestion = getSuggestedSymbolForNonexistentProperty(name, containingType);
@@ -37346,7 +37351,7 @@ namespace ts {
const baseClassName = typeToString(baseWithThis);
if (prop && !baseProp && hasOverride) {
const suggestion = getSpellingSuggestionForName(symbolName(declaredProp), arrayFrom(getMembersOfSymbol(baseType.symbol).values()), SymbolFlags.ClassMember);
const suggestion = getSuggestedSymbolForNonexistentClassMember(symbolName(declaredProp), baseType);
suggestion ?
error(member, Diagnostics.This_member_cannot_have_an_override_modifier_because_it_is_not_declared_in_the_base_class_0_Did_you_mean_1, baseClassName, symbolToString(suggestion)) :
error(member, Diagnostics.This_member_cannot_have_an_override_modifier_because_it_is_not_declared_in_the_base_class_0, baseClassName);

View File

@@ -4218,6 +4218,7 @@ namespace ts {
/* @internal */ getSuggestedSymbolForNonexistentSymbol(location: Node, name: string, meaning: SymbolFlags): Symbol | undefined;
/* @internal */ getSuggestionForNonexistentSymbol(location: Node, name: string, meaning: SymbolFlags): string | undefined;
/* @internal */ getSuggestedSymbolForNonexistentModule(node: Identifier, target: Symbol): Symbol | undefined;
/* @internal */ getSuggestedSymbolForNonexistentClassMember(name: string, baseType: Type): Symbol | undefined;
/* @internal */ getSuggestionForNonexistentExport(node: Identifier, target: Symbol): string | undefined;
getBaseConstraintOfType(type: Type): Type | undefined;
getDefaultFromTypeParameter(type: Type): Type | undefined;

View File

@@ -7,6 +7,7 @@ namespace ts.codefix {
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,
Diagnostics.This_member_cannot_have_an_override_modifier_because_it_is_not_declared_in_the_base_class_0_Did_you_mean_1.code,
// for JSX class components
Diagnostics.No_overload_matches_this_call.code,
// for JSX FC
@@ -73,6 +74,14 @@ namespace ts.codefix {
const props = checker.getContextualTypeForArgumentAtIndex(tag, 0);
suggestedSymbol = checker.getSuggestedSymbolForNonexistentJSXAttribute(node, props!);
}
else if (hasSyntacticModifier(parent, ModifierFlags.Override) && isClassElement(parent) && parent.name === node) {
const baseDeclaration = findAncestor(node, isClassLike);
const baseTypeNode = baseDeclaration ? getEffectiveBaseTypeNode(baseDeclaration) : undefined;
const baseType = baseTypeNode ? checker.getTypeAtLocation(baseTypeNode) : undefined;
if (baseType) {
suggestedSymbol = checker.getSuggestedSymbolForNonexistentClassMember(getTextOfNode(node), baseType);
}
}
else {
const meaning = getMeaningFromLocation(node);
const name = getTextOfNode(node);