From 29f9493d87db7b326f650a6b9249fd7162f7e7b7 Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders <293473+sandersn@users.noreply.github.com> Date: Tue, 15 Oct 2019 14:05:39 -0700 Subject: [PATCH] Fix crash when exporting+aliasing globalThis inside `declare global` (#34408) * global module:Fix crash when exporting+aliasing globalThis * Fix another globalThis crash find-all-refs assumed that an export inside a `declare x` was always an ambient module, but it is not -- `declare global` does not allow `export`, so find-all-refs shouldn't return any refs for this error case. --- src/compiler/checker.ts | 2 +- src/services/findAllReferences.ts | 6 ++++-- .../globalThisGlobalExportAsGlobal.errors.txt | 14 ++++++++++++++ .../reference/globalThisGlobalExportAsGlobal.js | 8 ++++++++ .../globalThisGlobalExportAsGlobal.symbols | 10 ++++++++++ .../reference/globalThisGlobalExportAsGlobal.types | 10 ++++++++++ .../es2019/globalThisGlobalExportAsGlobal.ts | 4 ++++ .../documentHighlightsInvalidGlobalThis.ts | 9 +++++++++ 8 files changed, 60 insertions(+), 3 deletions(-) create mode 100644 tests/baselines/reference/globalThisGlobalExportAsGlobal.errors.txt create mode 100644 tests/baselines/reference/globalThisGlobalExportAsGlobal.js create mode 100644 tests/baselines/reference/globalThisGlobalExportAsGlobal.symbols create mode 100644 tests/baselines/reference/globalThisGlobalExportAsGlobal.types create mode 100644 tests/cases/conformance/es2019/globalThisGlobalExportAsGlobal.ts create mode 100644 tests/cases/fourslash/documentHighlightsInvalidGlobalThis.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index ec63501af75..3162f2bb765 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -32454,7 +32454,7 @@ namespace ts { // find immediate value referenced by exported name (SymbolFlags.Alias is set so we don't chase down aliases) const symbol = resolveName(exportedName, exportedName.escapedText, SymbolFlags.Value | SymbolFlags.Type | SymbolFlags.Namespace | SymbolFlags.Alias, /*nameNotFoundMessage*/ undefined, /*nameArg*/ undefined, /*isUse*/ true); - if (symbol && (symbol === undefinedSymbol || isGlobalSourceFile(getDeclarationContainer(symbol.declarations[0])))) { + if (symbol && (symbol === undefinedSymbol || symbol === globalThisSymbol || isGlobalSourceFile(getDeclarationContainer(symbol.declarations[0])))) { error(exportedName, Diagnostics.Cannot_export_0_Only_local_declarations_can_be_exported_from_a_module, idText(exportedName)); } else { diff --git a/src/services/findAllReferences.ts b/src/services/findAllReferences.ts index 2db77a146f2..bd0e63561da 100644 --- a/src/services/findAllReferences.ts +++ b/src/services/findAllReferences.ts @@ -1395,8 +1395,10 @@ namespace ts.FindAllReferences.Core { || exportSpecifier.name.originalKeywordKind === SyntaxKind.DefaultKeyword; const exportKind = isDefaultExport ? ExportKind.Default : ExportKind.Named; const exportSymbol = Debug.assertDefined(exportSpecifier.symbol); - const exportInfo = Debug.assertDefined(getExportInfo(exportSymbol, exportKind, state.checker)); - searchForImportsOfExport(referenceLocation, exportSymbol, exportInfo, state); + const exportInfo = getExportInfo(exportSymbol, exportKind, state.checker); + if (exportInfo) { + searchForImportsOfExport(referenceLocation, exportSymbol, exportInfo, state); + } } // At `export { x } from "foo"`, also search for the imported symbol `"foo".x`. diff --git a/tests/baselines/reference/globalThisGlobalExportAsGlobal.errors.txt b/tests/baselines/reference/globalThisGlobalExportAsGlobal.errors.txt new file mode 100644 index 00000000000..3b9d75e466e --- /dev/null +++ b/tests/baselines/reference/globalThisGlobalExportAsGlobal.errors.txt @@ -0,0 +1,14 @@ +tests/cases/conformance/es2019/globalThisGlobalExportAsGlobal.ts(2,9): error TS2669: Augmentations for the global scope can only be directly nested in external modules or ambient module declarations. +tests/cases/conformance/es2019/globalThisGlobalExportAsGlobal.ts(3,14): error TS2661: Cannot export 'globalThis'. Only local declarations can be exported from a module. + + +==== tests/cases/conformance/es2019/globalThisGlobalExportAsGlobal.ts (2 errors) ==== + // https://github.com/microsoft/TypeScript/issues/33754 + declare global { + ~~~~~~ +!!! error TS2669: Augmentations for the global scope can only be directly nested in external modules or ambient module declarations. + export { globalThis as global } + ~~~~~~~~~~ +!!! error TS2661: Cannot export 'globalThis'. Only local declarations can be exported from a module. + } + \ No newline at end of file diff --git a/tests/baselines/reference/globalThisGlobalExportAsGlobal.js b/tests/baselines/reference/globalThisGlobalExportAsGlobal.js new file mode 100644 index 00000000000..4df230e1151 --- /dev/null +++ b/tests/baselines/reference/globalThisGlobalExportAsGlobal.js @@ -0,0 +1,8 @@ +//// [globalThisGlobalExportAsGlobal.ts] +// https://github.com/microsoft/TypeScript/issues/33754 +declare global { + export { globalThis as global } +} + + +//// [globalThisGlobalExportAsGlobal.js] diff --git a/tests/baselines/reference/globalThisGlobalExportAsGlobal.symbols b/tests/baselines/reference/globalThisGlobalExportAsGlobal.symbols new file mode 100644 index 00000000000..49ac97e912a --- /dev/null +++ b/tests/baselines/reference/globalThisGlobalExportAsGlobal.symbols @@ -0,0 +1,10 @@ +=== tests/cases/conformance/es2019/globalThisGlobalExportAsGlobal.ts === +// https://github.com/microsoft/TypeScript/issues/33754 +declare global { +>global : Symbol(global, Decl(globalThisGlobalExportAsGlobal.ts, 0, 0)) + + export { globalThis as global } +>globalThis : Symbol(globalThis) +>global : Symbol(global, Decl(globalThisGlobalExportAsGlobal.ts, 2, 12)) +} + diff --git a/tests/baselines/reference/globalThisGlobalExportAsGlobal.types b/tests/baselines/reference/globalThisGlobalExportAsGlobal.types new file mode 100644 index 00000000000..68867496daf --- /dev/null +++ b/tests/baselines/reference/globalThisGlobalExportAsGlobal.types @@ -0,0 +1,10 @@ +=== tests/cases/conformance/es2019/globalThisGlobalExportAsGlobal.ts === +// https://github.com/microsoft/TypeScript/issues/33754 +declare global { +>global : typeof global + + export { globalThis as global } +>globalThis : typeof globalThis +>global : typeof globalThis +} + diff --git a/tests/cases/conformance/es2019/globalThisGlobalExportAsGlobal.ts b/tests/cases/conformance/es2019/globalThisGlobalExportAsGlobal.ts new file mode 100644 index 00000000000..b5f6c8927bf --- /dev/null +++ b/tests/cases/conformance/es2019/globalThisGlobalExportAsGlobal.ts @@ -0,0 +1,4 @@ +// https://github.com/microsoft/TypeScript/issues/33754 +declare global { + export { globalThis as global } +} diff --git a/tests/cases/fourslash/documentHighlightsInvalidGlobalThis.ts b/tests/cases/fourslash/documentHighlightsInvalidGlobalThis.ts new file mode 100644 index 00000000000..b9c8008e132 --- /dev/null +++ b/tests/cases/fourslash/documentHighlightsInvalidGlobalThis.ts @@ -0,0 +1,9 @@ +/// + +////declare global { +//// export { globalThis as [|global|] } +////} + +for (const r of test.ranges()) { + verify.documentHighlightsOf(r, [r]); +}