Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix checker initialization crash #46973

Merged
merged 2 commits into from Dec 3, 2021
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
16 changes: 9 additions & 7 deletions src/compiler/checker.ts
Expand Up @@ -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 {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm obviously very late to this PR but is this argument ironically named? 😛

return resolveNameHelper(location, name, meaning, nameNotFoundMessage, nameArg, isUse, excludeGlobals, getSpellingSuggstions, getSymbol);
}

function resolveNameHelper(
Expand All @@ -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;
Expand Down Expand Up @@ -2122,7 +2124,7 @@ namespace ts {
}
}
if (!result) {
if (nameNotFoundMessage) {
if (nameNotFoundMessage && produceDiagnostics) {
if (!errorLocation ||
!checkAndReportErrorForMissingPrefix(errorLocation, name, nameArg!) && // TODO: GH#18217
!checkAndReportErrorForExtendingInterface(errorLocation) &&
Expand All @@ -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) {
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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
Expand Down