From 5e9dbeac26a5479156676075984d98213c46c888 Mon Sep 17 00:00:00 2001 From: Andrew Branch Date: Fri, 3 Dec 2021 18:16:07 +0000 Subject: [PATCH] Cherry-pick PR #46973 into release-4.5 Component commits: 0612e180c2 Fix checker initialization crash 2064b74c2d Move checks to a place that makes more sense --- src/compiler/checker.ts | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index b6e35f7d6c8e4..6726e5a455032 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -1781,8 +1781,9 @@ namespace ts { nameNotFoundMessage: DiagnosticMessage | undefined, nameArg: __String | Identifier | undefined, isUse: boolean, - excludeGlobals = false): Symbol | undefined { - return resolveNameHelper(location, name, meaning, nameNotFoundMessage, nameArg, isUse, excludeGlobals, getSymbol); + excludeGlobals = false, + getSpellingSuggstions = true): Symbol | undefined { + return resolveNameHelper(location, name, meaning, nameNotFoundMessage, nameArg, isUse, excludeGlobals, getSpellingSuggstions, getSymbol); } function resolveNameHelper( @@ -1793,6 +1794,7 @@ namespace ts { nameArg: __String | Identifier | undefined, isUse: boolean, excludeGlobals: boolean, + getSpellingSuggestions: boolean, lookup: typeof getSymbol): Symbol | undefined { const originalLocation = location; // needed for did-you-mean error reporting, which gathers candidates starting from the original location let result: Symbol | undefined; @@ -2122,7 +2124,7 @@ namespace ts { } } if (!result) { - if (nameNotFoundMessage) { + if (nameNotFoundMessage && produceDiagnostics) { if (!errorLocation || !checkAndReportErrorForMissingPrefix(errorLocation, name, nameArg!) && // TODO: GH#18217 !checkAndReportErrorForExtendingInterface(errorLocation) && @@ -2132,7 +2134,7 @@ namespace ts { !checkAndReportErrorForUsingNamespaceModuleAsValue(errorLocation, name, meaning) && !checkAndReportErrorForUsingValueAsType(errorLocation, name, meaning)) { let suggestion: Symbol | undefined; - if (suggestionCount < maximumSuggestionCount) { + if (getSpellingSuggestions && suggestionCount < maximumSuggestionCount) { suggestion = getSuggestedSymbolForNonexistentSymbol(originalLocation, name, meaning); const isGlobalScopeAugmentationDeclaration = suggestion?.valueDeclaration && isAmbientModule(suggestion.valueDeclaration) && isGlobalScopeAugmentation(suggestion.valueDeclaration); if (isGlobalScopeAugmentationDeclaration) { @@ -2172,7 +2174,7 @@ namespace ts { } // Perform extra checks only if error reporting was requested - if (nameNotFoundMessage) { + if (nameNotFoundMessage && produceDiagnostics) { 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 @@ -13638,7 +13640,7 @@ namespace ts { function getGlobalSymbol(name: __String, meaning: SymbolFlags, diagnostic: DiagnosticMessage | undefined): Symbol | undefined { // Don't track references for global symbols anyway, so value if `isReference` is arbitrary - return resolveName(undefined, name, meaning, diagnostic, name, /*isUse*/ false); + return resolveName(undefined, name, meaning, diagnostic, name, /*isUse*/ false, /*excludeGlobals*/ false, /*getSpellingSuggestions*/ false); } function getGlobalType(name: __String, arity: 0, reportErrors: true): ObjectType; @@ -28620,7 +28622,7 @@ namespace ts { 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) => { + const result = resolveNameHelper(location, outerName, meaning, /*nameNotFoundMessage*/ undefined, outerName, /*isUse*/ false, /*excludeGlobals*/ false, /*getSpellingSuggestions*/ true, (symbols, name, meaning) => { Debug.assertEqual(outerName, name, "name should equal outerName"); const symbol = getSymbol(symbols, name, meaning); // 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