Fix alias of module.exports->exports->IIFE (#27992)

In JS, when you assign `module.exports = exports` and the entire module is
wrapped in an IIFE, the resulting `export=` symbol, after following
aliases, is the module itself. This results in trying to merge the
file's exports with itself inside `getCommonJsExportEquals`, since it
thinks that it has found new exports, possibly in an object literal,
that need to be merged with the file's exports.

For example:

```js
(function() {
exports.a = 1
module.exports = exports
})()
```
This commit is contained in:
Nathan Shively-Sanders 2018-10-19 13:50:38 -07:00 committed by GitHub
parent b64d08a21b
commit e379aeb151
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 68 additions and 2 deletions

View File

@ -2353,11 +2353,16 @@ namespace ts {
function resolveExternalModuleSymbol(moduleSymbol: Symbol, dontResolveAlias?: boolean): Symbol;
function resolveExternalModuleSymbol(moduleSymbol: Symbol | undefined, dontResolveAlias?: boolean): Symbol | undefined;
function resolveExternalModuleSymbol(moduleSymbol: Symbol, dontResolveAlias?: boolean): Symbol {
return moduleSymbol && getMergedSymbol(getCommonJsExportEquals(resolveSymbol(moduleSymbol.exports!.get(InternalSymbolName.ExportEquals), dontResolveAlias), moduleSymbol)) || moduleSymbol;
if (moduleSymbol) {
const exportEquals = resolveSymbol(moduleSymbol.exports!.get(InternalSymbolName.ExportEquals), dontResolveAlias);
const exported = getCommonJsExportEquals(exportEquals, moduleSymbol);
return getMergedSymbol(exported) || moduleSymbol;
}
return undefined!;
}
function getCommonJsExportEquals(exported: Symbol | undefined, moduleSymbol: Symbol): Symbol | undefined {
if (!exported || exported === unknownSymbol || moduleSymbol.exports!.size === 1) {
if (!exported || exported === unknownSymbol || exported === moduleSymbol || moduleSymbol.exports!.size === 1) {
return exported;
}
const merged = cloneSymbol(exported);

View File

@ -0,0 +1,21 @@
=== tests/cases/conformance/salsa/Eloquent.js ===
// bug #27365, crashes from github.com/marijnh/Eloquent-JavaScript
(function() {
exports.bigOak = 1
>exports.bigOak : Symbol(bigOak, Decl(Eloquent.js, 1, 13))
>exports : Symbol(bigOak, Decl(Eloquent.js, 1, 13))
>bigOak : Symbol(bigOak, Decl(Eloquent.js, 1, 13))
exports.everywhere = 2
>exports.everywhere : Symbol(everywhere, Decl(Eloquent.js, 2, 18))
>exports : Symbol(everywhere, Decl(Eloquent.js, 2, 18))
>everywhere : Symbol(everywhere, Decl(Eloquent.js, 2, 18))
module.exports = exports
>module.exports : Symbol("tests/cases/conformance/salsa/Eloquent", Decl(Eloquent.js, 0, 0))
>module : Symbol(export=, Decl(Eloquent.js, 3, 22))
>exports : Symbol(export=, Decl(Eloquent.js, 3, 22))
>exports : Symbol("tests/cases/conformance/salsa/Eloquent", Decl(Eloquent.js, 0, 0))
})()

View File

@ -0,0 +1,30 @@
=== tests/cases/conformance/salsa/Eloquent.js ===
// bug #27365, crashes from github.com/marijnh/Eloquent-JavaScript
(function() {
>(function() {exports.bigOak = 1exports.everywhere = 2module.exports = exports})() : void
>(function() {exports.bigOak = 1exports.everywhere = 2module.exports = exports}) : () => void
>function() {exports.bigOak = 1exports.everywhere = 2module.exports = exports} : () => void
exports.bigOak = 1
>exports.bigOak = 1 : 1
>exports.bigOak : number
>exports : typeof import("tests/cases/conformance/salsa/Eloquent")
>bigOak : number
>1 : 1
exports.everywhere = 2
>exports.everywhere = 2 : 2
>exports.everywhere : number
>exports : typeof import("tests/cases/conformance/salsa/Eloquent")
>everywhere : number
>2 : 2
module.exports = exports
>module.exports = exports : typeof import("tests/cases/conformance/salsa/Eloquent")
>module.exports : typeof import("tests/cases/conformance/salsa/Eloquent")
>module : { "tests/cases/conformance/salsa/Eloquent": typeof import("tests/cases/conformance/salsa/Eloquent"); }
>exports : typeof import("tests/cases/conformance/salsa/Eloquent")
>exports : typeof import("tests/cases/conformance/salsa/Eloquent")
})()

View File

@ -0,0 +1,10 @@
// @noEmit: true
// @allowJs: true
// @checkJs: true
// @Filename: Eloquent.js
// bug #27365, crashes from github.com/marijnh/Eloquent-JavaScript
(function() {
exports.bigOak = 1
exports.everywhere = 2
module.exports = exports
})()