From 0612e180c2bdb3e72b991da8615b1471ca073a6f Mon Sep 17 00:00:00 2001 From: Andrew Branch Date: Wed, 1 Dec 2021 10:47:05 -0800 Subject: [PATCH 1/2] Fix checker initialization crash --- src/compiler/checker.ts | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 2e0f1ef628101..06e991333a8f2 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -2122,7 +2122,7 @@ namespace ts { } } if (!result) { - if (nameNotFoundMessage) { + if (nameNotFoundMessage && produceDiagnostics) { if (!errorLocation || !checkAndReportErrorForMissingPrefix(errorLocation, name, nameArg!) && // TODO: GH#18217 !checkAndReportErrorForExtendingInterface(errorLocation) && @@ -2172,7 +2172,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 @@ -28816,7 +28816,8 @@ namespace ts { return candidateName; } - if (candidate.flags & SymbolFlags.Alias) { + // Don't try to resolve aliases if global types aren't initialized yet + if (globalObjectType && candidate.flags & SymbolFlags.Alias) { const alias = tryResolveAlias(candidate); if (alias && alias.flags & meaning) { return candidateName; From 2064b74c2db202e7d6239a5b5d1f90b1c167a827 Mon Sep 17 00:00:00 2001 From: Andrew Branch Date: Wed, 1 Dec 2021 11:15:43 -0800 Subject: [PATCH 2/2] Move checks to a place that makes more sense --- src/compiler/checker.ts | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 06e991333a8f2..41ac79b901fde 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; @@ -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) { @@ -13657,7 +13659,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; @@ -28718,7 +28720,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 @@ -28816,8 +28818,7 @@ namespace ts { return candidateName; } - // Don't try to resolve aliases if global types aren't initialized yet - if (globalObjectType && candidate.flags & SymbolFlags.Alias) { + if (candidate.flags & SymbolFlags.Alias) { const alias = tryResolveAlias(candidate); if (alias && alias.flags & meaning) { return candidateName;