mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-05-30 22:32:33 -05:00
fix: correct name length criterion for spelling fixes (#49575)
Co-authored-by: Jake Bailey <5341706+jakebailey@users.noreply.github.com>
This commit is contained in:
@@ -1874,7 +1874,7 @@ m2: ${(this.mapper2 as unknown as DebugTypeMapper).__debugToString().split("\n")
|
||||
let result: Symbol | undefined;
|
||||
let lastLocation: Node | undefined;
|
||||
let lastSelfReferenceLocation: Node | undefined;
|
||||
let propertyWithInvalidInitializer: Node | undefined;
|
||||
let propertyWithInvalidInitializer: PropertyDeclaration | undefined;
|
||||
let associatedDeclarationForContainingInitializerOrBindingName: ParameterDeclaration | BindingElement | undefined;
|
||||
let withinDeferredContext = false;
|
||||
const errorLocation = location;
|
||||
@@ -2008,6 +2008,7 @@ m2: ${(this.mapper2 as unknown as DebugTypeMapper).__debugToString().split("\n")
|
||||
if (ctor && ctor.locals) {
|
||||
if (lookup(ctor.locals, name, meaning & SymbolFlags.Value)) {
|
||||
// Remember the property node, it will be used later to report appropriate error
|
||||
Debug.assertNode(location, isPropertyDeclaration);
|
||||
propertyWithInvalidInitializer = location;
|
||||
}
|
||||
}
|
||||
@@ -2204,11 +2205,31 @@ m2: ${(this.mapper2 as unknown as DebugTypeMapper).__debugToString().split("\n")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// The invalid initializer error is needed in two situation:
|
||||
// 1. When result is undefined, after checking for a missing "this."
|
||||
// 2. When result is defined
|
||||
function checkAndReportErrorForInvalidInitializer() {
|
||||
if (propertyWithInvalidInitializer && !(getEmitScriptTarget(compilerOptions) === ScriptTarget.ESNext && useDefineForClassFields)) {
|
||||
// We have a match, but the reference occurred within a property initializer and the identifier also binds
|
||||
// to a local variable in the constructor where the code will be emitted. Note that this is actually allowed
|
||||
// with ESNext+useDefineForClassFields because the scope semantics are different.
|
||||
error(errorLocation,
|
||||
errorLocation && propertyWithInvalidInitializer.type && textRangeContainsPositionInclusive(propertyWithInvalidInitializer.type, errorLocation.pos)
|
||||
? Diagnostics.Type_of_instance_member_variable_0_cannot_reference_identifier_1_declared_in_the_constructor
|
||||
: Diagnostics.Initializer_of_instance_member_variable_0_cannot_reference_identifier_1_declared_in_the_constructor,
|
||||
declarationNameToString(propertyWithInvalidInitializer.name), diagnosticName(nameArg!));
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!result) {
|
||||
if (nameNotFoundMessage) {
|
||||
addLazyDiagnostic(() => {
|
||||
if (!errorLocation ||
|
||||
!checkAndReportErrorForMissingPrefix(errorLocation, name, nameArg!) && // TODO: GH#18217
|
||||
!checkAndReportErrorForInvalidInitializer() &&
|
||||
!checkAndReportErrorForExtendingInterface(errorLocation) &&
|
||||
!checkAndReportErrorForUsingTypeAsNamespace(errorLocation, name, meaning) &&
|
||||
!checkAndReportErrorForExportingPrimitiveType(errorLocation, name) &&
|
||||
@@ -2216,7 +2237,16 @@ m2: ${(this.mapper2 as unknown as DebugTypeMapper).__debugToString().split("\n")
|
||||
!checkAndReportErrorForUsingNamespaceModuleAsValue(errorLocation, name, meaning) &&
|
||||
!checkAndReportErrorForUsingValueAsType(errorLocation, name, meaning)) {
|
||||
let suggestion: Symbol | undefined;
|
||||
if (getSpellingSuggestions && suggestionCount < maximumSuggestionCount) {
|
||||
let suggestedLib: string | undefined;
|
||||
// Report missing lib first
|
||||
if (nameArg) {
|
||||
suggestedLib = getSuggestedLibForNonExistentName(nameArg);
|
||||
if (suggestedLib) {
|
||||
error(errorLocation, nameNotFoundMessage, diagnosticName(nameArg), suggestedLib);
|
||||
}
|
||||
}
|
||||
// then spelling suggestions
|
||||
if (!suggestedLib && getSpellingSuggestions && suggestionCount < maximumSuggestionCount) {
|
||||
suggestion = getSuggestedSymbolForNonexistentSymbol(originalLocation, name, meaning);
|
||||
const isGlobalScopeAugmentationDeclaration = suggestion?.valueDeclaration && isAmbientModule(suggestion.valueDeclaration) && isGlobalScopeAugmentation(suggestion.valueDeclaration);
|
||||
if (isGlobalScopeAugmentationDeclaration) {
|
||||
@@ -2238,16 +2268,9 @@ m2: ${(this.mapper2 as unknown as DebugTypeMapper).__debugToString().split("\n")
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!suggestion) {
|
||||
if (nameArg) {
|
||||
const lib = getSuggestedLibForNonExistentName(nameArg);
|
||||
if (lib) {
|
||||
error(errorLocation, nameNotFoundMessage, diagnosticName(nameArg), lib);
|
||||
}
|
||||
else {
|
||||
error(errorLocation, nameNotFoundMessage, diagnosticName(nameArg));
|
||||
}
|
||||
}
|
||||
// And then fall back to unspecified "not found"
|
||||
if (!suggestion && !suggestedLib && nameArg) {
|
||||
error(errorLocation, nameNotFoundMessage, diagnosticName(nameArg));
|
||||
}
|
||||
suggestionCount++;
|
||||
}
|
||||
@@ -2255,14 +2278,7 @@ m2: ${(this.mapper2 as unknown as DebugTypeMapper).__debugToString().split("\n")
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
if (propertyWithInvalidInitializer && !(getEmitScriptTarget(compilerOptions) === ScriptTarget.ESNext && useDefineForClassFields)) {
|
||||
// We have a match, but the reference occurred within a property initializer and the identifier also binds
|
||||
// to a local variable in the constructor where the code will be emitted. Note that this is actually allowed
|
||||
// with ESNext+useDefineForClassFields because the scope semantics are different.
|
||||
const propertyName = (propertyWithInvalidInitializer as PropertyDeclaration).name;
|
||||
error(errorLocation, Diagnostics.Initializer_of_instance_member_variable_0_cannot_reference_identifier_1_declared_in_the_constructor,
|
||||
declarationNameToString(propertyName), diagnosticName(nameArg!));
|
||||
else if (checkAndReportErrorForInvalidInitializer()) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
|
||||
@@ -2105,7 +2105,7 @@ namespace ts {
|
||||
* and 1 insertion/deletion at 3 characters)
|
||||
*/
|
||||
export function getSpellingSuggestion<T>(name: string, candidates: T[], getName: (candidate: T) => string | undefined): T | undefined {
|
||||
const maximumLengthDifference = Math.min(2, Math.floor(name.length * 0.34));
|
||||
const maximumLengthDifference = Math.max(2, Math.floor(name.length * 0.34));
|
||||
let bestDistance = Math.floor(name.length * 0.4) + 1; // If the best result is worse than this, don't bother.
|
||||
let bestCandidate: T | undefined;
|
||||
for (const candidate of candidates) {
|
||||
|
||||
@@ -3507,6 +3507,10 @@
|
||||
"category": "Error",
|
||||
"code": 2843
|
||||
},
|
||||
"Type of instance member variable '{0}' cannot reference identifier '{1}' declared in the constructor.": {
|
||||
"category": "Error",
|
||||
"code": 2844
|
||||
},
|
||||
|
||||
"Import declaration '{0}' is using private name '{1}'.": {
|
||||
"category": "Error",
|
||||
|
||||
Reference in New Issue
Block a user