mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-02-09 02:30:15 -06:00
Add a related span for suggested declaration locations in error messages.
This commit is contained in:
parent
fd32cb97a4
commit
5afc8fdcef
@ -710,7 +710,7 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
function addRelatedInfo(diagnostic: Diagnostic, ...relatedInformation: DiagnosticRelatedInformation[]) {
|
||||
function addRelatedInfo(diagnostic: Diagnostic, ...relatedInformation: [DiagnosticRelatedInformation, ...DiagnosticRelatedInformation[]]) {
|
||||
if (!diagnostic.relatedInformation) {
|
||||
diagnostic.relatedInformation = [];
|
||||
}
|
||||
@ -1434,11 +1434,18 @@ namespace ts {
|
||||
!checkAndReportErrorForUsingTypeAsNamespace(errorLocation, name, meaning) &&
|
||||
!checkAndReportErrorForUsingTypeAsValue(errorLocation, name, meaning) &&
|
||||
!checkAndReportErrorForUsingNamespaceModuleAsValue(errorLocation, name, meaning)) {
|
||||
let suggestion: string | undefined;
|
||||
let suggestion: Symbol | undefined;
|
||||
if (suggestedNameNotFoundMessage && suggestionCount < maximumSuggestionCount) {
|
||||
suggestion = getSuggestionForNonexistentSymbol(originalLocation, name, meaning);
|
||||
suggestion = getSuggestedSymbolForNonexistentSymbol(originalLocation, name, meaning);
|
||||
if (suggestion) {
|
||||
error(errorLocation, suggestedNameNotFoundMessage, diagnosticName(nameArg!), suggestion);
|
||||
const suggestionName = symbolToString(suggestion);
|
||||
const diagnostic = error(errorLocation, suggestedNameNotFoundMessage, diagnosticName(nameArg!), suggestionName);
|
||||
if (suggestion.valueDeclaration) {
|
||||
addRelatedInfo(
|
||||
diagnostic,
|
||||
createDiagnosticForNode(suggestion.valueDeclaration, Diagnostics._0_is_declared_here, suggestionName)
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!suggestion) {
|
||||
@ -1674,7 +1681,7 @@ namespace ts {
|
||||
|
||||
if (diagnosticMessage) {
|
||||
addRelatedInfo(diagnosticMessage,
|
||||
createDiagnosticForNode(declaration, Diagnostics._0_was_declared_here, declarationName)
|
||||
createDiagnosticForNode(declaration, Diagnostics._0_is_declared_here, declarationName)
|
||||
);
|
||||
}
|
||||
}
|
||||
@ -1866,9 +1873,15 @@ namespace ts {
|
||||
if (!symbol) {
|
||||
const moduleName = getFullyQualifiedName(moduleSymbol);
|
||||
const declarationName = declarationNameToString(name);
|
||||
const suggestion = getSuggestionForNonexistentModule(name, targetSymbol);
|
||||
const suggestion = getSuggestedSymbolForNonexistentModule(name, targetSymbol);
|
||||
if (suggestion !== undefined) {
|
||||
error(name, Diagnostics.Module_0_has_no_exported_member_1_Did_you_mean_2, moduleName, declarationName, suggestion);
|
||||
const suggestionName = symbolToString(suggestion);
|
||||
const diagnostic = error(name, Diagnostics.Module_0_has_no_exported_member_1_Did_you_mean_2, moduleName, declarationName, suggestionName);
|
||||
if (suggestion.valueDeclaration) {
|
||||
addRelatedInfo(diagnostic,
|
||||
createDiagnosticForNode(suggestion.valueDeclaration, Diagnostics._0_is_declared_here, suggestionName)
|
||||
);
|
||||
}
|
||||
}
|
||||
else {
|
||||
error(name, Diagnostics.Module_0_has_no_exported_member_1, moduleName, declarationName);
|
||||
@ -17661,7 +17674,7 @@ namespace ts {
|
||||
|
||||
if (diagnosticMessage) {
|
||||
addRelatedInfo(diagnosticMessage,
|
||||
createDiagnosticForNode(valueDeclaration, Diagnostics._0_was_declared_here, declarationName)
|
||||
createDiagnosticForNode(valueDeclaration, Diagnostics._0_is_declared_here, declarationName)
|
||||
);
|
||||
}
|
||||
}
|
||||
@ -17711,6 +17724,7 @@ namespace ts {
|
||||
|
||||
function reportNonexistentProperty(propNode: Identifier, containingType: Type) {
|
||||
let errorInfo: DiagnosticMessageChain | undefined;
|
||||
let relatedInfo: Diagnostic | undefined;
|
||||
if (containingType.flags & TypeFlags.Union && !(containingType.flags & TypeFlags.Primitive)) {
|
||||
for (const subtype of (containingType as UnionType).types) {
|
||||
if (!getPropertyOfType(subtype, propNode.escapedText)) {
|
||||
@ -17724,30 +17738,34 @@ namespace ts {
|
||||
errorInfo = chainDiagnosticMessages(errorInfo, Diagnostics.Property_0_does_not_exist_on_type_1_Did_you_forget_to_use_await, declarationNameToString(propNode), typeToString(containingType));
|
||||
}
|
||||
else {
|
||||
const suggestion = getSuggestionForNonexistentProperty(propNode, containingType);
|
||||
const suggestion = getSuggestedSymbolForNonexistentProperty(propNode, containingType);
|
||||
if (suggestion !== undefined) {
|
||||
errorInfo = chainDiagnosticMessages(errorInfo, Diagnostics.Property_0_does_not_exist_on_type_1_Did_you_mean_2, declarationNameToString(propNode), typeToString(containingType), suggestion);
|
||||
const suggestedName = symbolName(suggestion);
|
||||
errorInfo = chainDiagnosticMessages(errorInfo, Diagnostics.Property_0_does_not_exist_on_type_1_Did_you_mean_2, declarationNameToString(propNode), typeToString(containingType), suggestedName);
|
||||
relatedInfo = suggestion.valueDeclaration && createDiagnosticForNode(suggestion.valueDeclaration, Diagnostics._0_is_declared_here, suggestedName);
|
||||
}
|
||||
else {
|
||||
const suggestion = getSuggestionForNonexistentProperty(propNode, containingType);
|
||||
if (suggestion !== undefined) {
|
||||
errorInfo = chainDiagnosticMessages(errorInfo, Diagnostics.Property_0_does_not_exist_on_type_1_Did_you_mean_2, declarationNameToString(propNode), typeToString(containingType), suggestion);
|
||||
}
|
||||
else {
|
||||
errorInfo = chainDiagnosticMessages(errorInfo, Diagnostics.Property_0_does_not_exist_on_type_1, declarationNameToString(propNode), typeToString(containingType));
|
||||
}
|
||||
errorInfo = chainDiagnosticMessages(errorInfo, Diagnostics.Property_0_does_not_exist_on_type_1, declarationNameToString(propNode), typeToString(containingType));
|
||||
}
|
||||
}
|
||||
|
||||
diagnostics.add(createDiagnosticForNodeFromMessageChain(propNode, errorInfo));
|
||||
const resultDiagnostic = createDiagnosticForNodeFromMessageChain(propNode, errorInfo);
|
||||
if (relatedInfo) {
|
||||
addRelatedInfo(resultDiagnostic, relatedInfo);
|
||||
}
|
||||
diagnostics.add(resultDiagnostic);
|
||||
}
|
||||
|
||||
function getSuggestedSymbolForNonexistentProperty(name: Identifier | string, containingType: Type): Symbol | undefined {
|
||||
return getSpellingSuggestionForName(isString(name) ? name : idText(name), getPropertiesOfType(containingType), SymbolFlags.Value);
|
||||
}
|
||||
|
||||
function getSuggestionForNonexistentProperty(name: Identifier | string, containingType: Type): string | undefined {
|
||||
const suggestion = getSpellingSuggestionForName(isString(name) ? name : idText(name), getPropertiesOfType(containingType), SymbolFlags.Value);
|
||||
const suggestion = getSuggestedSymbolForNonexistentProperty(name, containingType);
|
||||
return suggestion && symbolName(suggestion);
|
||||
}
|
||||
|
||||
function getSuggestionForNonexistentSymbol(location: Node | undefined, outerName: __String, meaning: SymbolFlags): string | undefined {
|
||||
function getSuggestedSymbolForNonexistentSymbol(location: Node | undefined, outerName: __String, meaning: SymbolFlags): Symbol | undefined {
|
||||
Debug.assert(outerName !== undefined, "outername should always be defined");
|
||||
const result = resolveNameHelper(location, outerName, meaning, /*nameNotFoundMessage*/ undefined, outerName, /*isUse*/ false, /*excludeGlobals*/ false, (symbols, name, meaning) => {
|
||||
Debug.assertEqual(outerName, name, "name should equal outerName");
|
||||
@ -17757,11 +17775,20 @@ namespace ts {
|
||||
// However, resolveNameHelper will continue and call this callback again, so we'll eventually get a correct suggestion.
|
||||
return symbol || getSpellingSuggestionForName(unescapeLeadingUnderscores(name), arrayFrom(symbols.values()), meaning);
|
||||
});
|
||||
return result && symbolName(result);
|
||||
return result;
|
||||
}
|
||||
|
||||
function getSuggestionForNonexistentSymbol(location: Node | undefined, outerName: __String, meaning: SymbolFlags): string | undefined {
|
||||
const symbolResult = getSuggestedSymbolForNonexistentSymbol(location, outerName, meaning);
|
||||
return symbolResult && symbolName(symbolResult)
|
||||
}
|
||||
|
||||
function getSuggestedSymbolForNonexistentModule(name: Identifier, targetModule: Symbol): Symbol | undefined {
|
||||
return targetModule.exports && getSpellingSuggestionForName(idText(name), getExportsOfModuleAsArray(targetModule), SymbolFlags.ModuleMember);
|
||||
}
|
||||
|
||||
function getSuggestionForNonexistentModule(name: Identifier, targetModule: Symbol): string | undefined {
|
||||
const suggestion = targetModule.exports && getSpellingSuggestionForName(idText(name), getExportsOfModuleAsArray(targetModule), SymbolFlags.ModuleMember);
|
||||
const suggestion = getSuggestedSymbolForNonexistentModule(name, targetModule);
|
||||
return suggestion && symbolName(suggestion);
|
||||
}
|
||||
|
||||
|
||||
@ -2401,7 +2401,7 @@
|
||||
"category": "Error",
|
||||
"code": 2727
|
||||
},
|
||||
"'{0}' was declared here.": {
|
||||
"'{0}' is declared here.": {
|
||||
"category": "Error",
|
||||
"code": 2728
|
||||
},
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user