From 166c0a9867f369f6c3706f5051edcdab3b50a2a7 Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Mon, 21 Mar 2022 20:29:13 +0000 Subject: [PATCH] Perform up-front checks to avoid relying on info set by the binder. --- src/compiler/checker.ts | 23 ++++++++++++++++------- 1 file changed, 16 insertions(+), 7 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 56fc415f13b..b545ddee007 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -42864,14 +42864,27 @@ namespace ts { // Initialize global symbol table let augmentations: (readonly (StringLiteral | Identifier)[])[] | undefined; for (const file of host.getSourceFiles()) { - if (file.redirectInfo) { + const mustBeBoundUpFront = + // Globals must be bound up-front. + // (With the global symbol scope, now our checker has some hope.) + !isExternalModule(file) || + // JavaScript files *can* augment the global scope. + // (To know whether they will today, we have to bind them anyway.) + isInJSFile(file) || + // Module augmentations make the current and affected file global. + // (If you add an augmentation, we'll be sure to make you patien(t)!) + file.moduleAugmentations.length || + // Since binding sometimes takes a while, we'll check the top statements in `file`. + // (Using outdated UMD references? No worries, we respect slow preferences!) + find(file.statements, isNamespaceExportDeclaration); + if (mustBeBoundUpFront) { bindSourceFile(file, compilerOptions); + } + if (file.redirectInfo) { continue; } if (!isExternalOrCommonJsModule(file)) { - bindSourceFile(file, compilerOptions); - // It is an error for a non-external-module (i.e. script) to declare its own `globalThis`. // We can't use `builtinGlobals` for this due to synthetic expando-namespace generation in JS files. const fileGlobalThisSymbol = file.locals!.get("globalThis" as __String); @@ -42883,19 +42896,15 @@ namespace ts { mergeSymbolTable(globals, file.locals!); } if (file.jsGlobalAugmentations) { - bindSourceFile(file, compilerOptions); mergeSymbolTable(globals, file.jsGlobalAugmentations); } if (file.patternAmbientModules && file.patternAmbientModules.length) { - bindSourceFile(file, compilerOptions); patternAmbientModules = concatenate(patternAmbientModules, file.patternAmbientModules); } if (file.moduleAugmentations.length) { - bindSourceFile(file, compilerOptions); (augmentations ||= []).push(file.moduleAugmentations); } if (file.symbol && file.symbol.globalExports) { - bindSourceFile(file, compilerOptions); // Merge in UMD exports with first-in-wins semantics (see #9771) const source = file.symbol.globalExports; source.forEach((sourceSymbol, id) => {