mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-02-10 06:41:59 -06:00
Merge pull request #8739 from evansb/fix-8738
Fix #8738: Handles Re-assignment of Exported Clause Member
This commit is contained in:
commit
8b7fb8e7e8
@ -2613,11 +2613,21 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
||||
return isSourceFileLevelDeclarationInSystemJsModule(targetDeclaration, /*isExported*/ true);
|
||||
}
|
||||
|
||||
function isNameOfExportedDeclarationInNonES6Module(node: Node): boolean {
|
||||
if (modulekind === ModuleKind.System || node.kind !== SyntaxKind.Identifier || nodeIsSynthesized(node)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return !exportEquals && exportSpecifiers && hasProperty(exportSpecifiers, (<Identifier>node).text);
|
||||
}
|
||||
|
||||
function emitPrefixUnaryExpression(node: PrefixUnaryExpression) {
|
||||
const exportChanged = (node.operator === SyntaxKind.PlusPlusToken || node.operator === SyntaxKind.MinusMinusToken) &&
|
||||
const isPlusPlusOrMinusMinus = (node.operator === SyntaxKind.PlusPlusToken
|
||||
|| node.operator === SyntaxKind.MinusMinusToken);
|
||||
const externalExportChanged = isPlusPlusOrMinusMinus &&
|
||||
isNameOfExportedSourceLevelDeclarationInSystemExternalModule(node.operand);
|
||||
|
||||
if (exportChanged) {
|
||||
if (externalExportChanged) {
|
||||
// emit
|
||||
// ++x
|
||||
// as
|
||||
@ -2626,6 +2636,12 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
||||
emitNodeWithoutSourceMap(node.operand);
|
||||
write(`", `);
|
||||
}
|
||||
const internalExportChanged = isPlusPlusOrMinusMinus &&
|
||||
isNameOfExportedDeclarationInNonES6Module(node.operand);
|
||||
|
||||
if (internalExportChanged) {
|
||||
emitAliasEqual(<Identifier> node.operand);
|
||||
}
|
||||
|
||||
write(tokenToString(node.operator));
|
||||
// In some cases, we need to emit a space between the operator and the operand. One obvious case
|
||||
@ -2651,14 +2667,16 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
||||
}
|
||||
emit(node.operand);
|
||||
|
||||
if (exportChanged) {
|
||||
if (externalExportChanged) {
|
||||
write(")");
|
||||
}
|
||||
}
|
||||
|
||||
function emitPostfixUnaryExpression(node: PostfixUnaryExpression) {
|
||||
const exportChanged = isNameOfExportedSourceLevelDeclarationInSystemExternalModule(node.operand);
|
||||
if (exportChanged) {
|
||||
const externalExportChanged = isNameOfExportedSourceLevelDeclarationInSystemExternalModule(node.operand);
|
||||
const internalExportChanged = isNameOfExportedDeclarationInNonES6Module(node.operand);
|
||||
|
||||
if (externalExportChanged) {
|
||||
// export function returns the value that was passes as the second argument
|
||||
// however for postfix unary expressions result value should be the value before modification.
|
||||
// emit 'x++' as '(export('x', ++x) - 1)' and 'x--' as '(export('x', --x) + 1)'
|
||||
@ -2676,6 +2694,16 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
||||
write(") + 1)");
|
||||
}
|
||||
}
|
||||
else if (internalExportChanged) {
|
||||
emitAliasEqual(<Identifier> node.operand);
|
||||
emit(node.operand);
|
||||
if (node.operator === SyntaxKind.PlusPlusToken) {
|
||||
write(" += 1");
|
||||
}
|
||||
else {
|
||||
write(" -= 1");
|
||||
}
|
||||
}
|
||||
else {
|
||||
emit(node.operand);
|
||||
write(tokenToString(node.operator));
|
||||
@ -2777,24 +2805,50 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
||||
}
|
||||
}
|
||||
|
||||
function emitAliasEqual(name: Identifier): boolean {
|
||||
for (const specifier of exportSpecifiers[name.text]) {
|
||||
emitStart(specifier.name);
|
||||
emitContainingModuleName(specifier);
|
||||
if (languageVersion === ScriptTarget.ES3 && name.text === "default") {
|
||||
write('["default"]');
|
||||
}
|
||||
else {
|
||||
write(".");
|
||||
emitNodeWithCommentsAndWithoutSourcemap(specifier.name);
|
||||
}
|
||||
emitEnd(specifier.name);
|
||||
write(" = ");
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
function emitBinaryExpression(node: BinaryExpression) {
|
||||
if (languageVersion < ScriptTarget.ES6 && node.operatorToken.kind === SyntaxKind.EqualsToken &&
|
||||
(node.left.kind === SyntaxKind.ObjectLiteralExpression || node.left.kind === SyntaxKind.ArrayLiteralExpression)) {
|
||||
emitDestructuring(node, node.parent.kind === SyntaxKind.ExpressionStatement);
|
||||
}
|
||||
else {
|
||||
const exportChanged =
|
||||
node.operatorToken.kind >= SyntaxKind.FirstAssignment &&
|
||||
node.operatorToken.kind <= SyntaxKind.LastAssignment &&
|
||||
const isAssignment = isAssignmentOperator(node.operatorToken.kind);
|
||||
|
||||
const externalExportChanged = isAssignment &&
|
||||
isNameOfExportedSourceLevelDeclarationInSystemExternalModule(node.left);
|
||||
|
||||
if (exportChanged) {
|
||||
if (externalExportChanged) {
|
||||
// emit assignment 'x <op> y' as 'exports("x", x <op> y)'
|
||||
write(`${exportFunctionForFile}("`);
|
||||
emitNodeWithoutSourceMap(node.left);
|
||||
write(`", `);
|
||||
}
|
||||
|
||||
const internalExportChanged = isAssignment &&
|
||||
isNameOfExportedDeclarationInNonES6Module(node.left);
|
||||
|
||||
if (internalExportChanged) {
|
||||
// export { foo }
|
||||
// emit foo = 2 as exports.foo = foo = 2
|
||||
emitAliasEqual(<Identifier>node.left);
|
||||
}
|
||||
|
||||
if (node.operatorToken.kind === SyntaxKind.AsteriskAsteriskToken || node.operatorToken.kind === SyntaxKind.AsteriskAsteriskEqualsToken) {
|
||||
// Downleveled emit exponentiation operator using Math.pow
|
||||
emitExponentiationOperator(node);
|
||||
@ -2815,7 +2869,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
||||
decreaseIndentIf(indentedBeforeOperator, indentedAfterOperator);
|
||||
}
|
||||
|
||||
if (exportChanged) {
|
||||
if (externalExportChanged) {
|
||||
write(")");
|
||||
}
|
||||
}
|
||||
|
||||
@ -0,0 +1,36 @@
|
||||
//// [server.ts]
|
||||
|
||||
var foo = 2;
|
||||
foo = 3;
|
||||
|
||||
var baz = 3;
|
||||
baz = 4;
|
||||
|
||||
var buzz = 10;
|
||||
buzz += 3;
|
||||
|
||||
var bizz = 8;
|
||||
bizz++; // compiles to exports.bizz = bizz += 1
|
||||
bizz--; // similarly
|
||||
++bizz; // compiles to exports.bizz = ++bizz
|
||||
|
||||
export { foo, baz, baz as quux, buzz, bizz };
|
||||
|
||||
|
||||
//// [server.js]
|
||||
"use strict";
|
||||
var foo = 2;
|
||||
exports.foo = foo;
|
||||
exports.foo = foo = 3;
|
||||
var baz = 3;
|
||||
exports.baz = baz;
|
||||
exports.quux = baz;
|
||||
exports.baz = exports.quux = baz = 4;
|
||||
var buzz = 10;
|
||||
exports.buzz = buzz;
|
||||
exports.buzz = buzz += 3;
|
||||
var bizz = 8;
|
||||
exports.bizz = bizz;
|
||||
exports.bizz = bizz += 1; // compiles to exports.bizz = bizz += 1
|
||||
exports.bizz = bizz -= 1; // similarly
|
||||
exports.bizz = ++bizz; // compiles to exports.bizz = ++bizz
|
||||
@ -0,0 +1,40 @@
|
||||
=== tests/cases/compiler/server.ts ===
|
||||
|
||||
var foo = 2;
|
||||
>foo : Symbol(foo, Decl(server.ts, 1, 3))
|
||||
|
||||
foo = 3;
|
||||
>foo : Symbol(foo, Decl(server.ts, 1, 3))
|
||||
|
||||
var baz = 3;
|
||||
>baz : Symbol(baz, Decl(server.ts, 4, 3))
|
||||
|
||||
baz = 4;
|
||||
>baz : Symbol(baz, Decl(server.ts, 4, 3))
|
||||
|
||||
var buzz = 10;
|
||||
>buzz : Symbol(buzz, Decl(server.ts, 7, 3))
|
||||
|
||||
buzz += 3;
|
||||
>buzz : Symbol(buzz, Decl(server.ts, 7, 3))
|
||||
|
||||
var bizz = 8;
|
||||
>bizz : Symbol(bizz, Decl(server.ts, 10, 3))
|
||||
|
||||
bizz++; // compiles to exports.bizz = bizz += 1
|
||||
>bizz : Symbol(bizz, Decl(server.ts, 10, 3))
|
||||
|
||||
bizz--; // similarly
|
||||
>bizz : Symbol(bizz, Decl(server.ts, 10, 3))
|
||||
|
||||
++bizz; // compiles to exports.bizz = ++bizz
|
||||
>bizz : Symbol(bizz, Decl(server.ts, 10, 3))
|
||||
|
||||
export { foo, baz, baz as quux, buzz, bizz };
|
||||
>foo : Symbol(foo, Decl(server.ts, 15, 8))
|
||||
>baz : Symbol(baz, Decl(server.ts, 15, 13))
|
||||
>baz : Symbol(quux, Decl(server.ts, 15, 18))
|
||||
>quux : Symbol(quux, Decl(server.ts, 15, 18))
|
||||
>buzz : Symbol(buzz, Decl(server.ts, 15, 31))
|
||||
>bizz : Symbol(bizz, Decl(server.ts, 15, 37))
|
||||
|
||||
@ -0,0 +1,53 @@
|
||||
=== tests/cases/compiler/server.ts ===
|
||||
|
||||
var foo = 2;
|
||||
>foo : number
|
||||
>2 : number
|
||||
|
||||
foo = 3;
|
||||
>foo = 3 : number
|
||||
>foo : number
|
||||
>3 : number
|
||||
|
||||
var baz = 3;
|
||||
>baz : number
|
||||
>3 : number
|
||||
|
||||
baz = 4;
|
||||
>baz = 4 : number
|
||||
>baz : number
|
||||
>4 : number
|
||||
|
||||
var buzz = 10;
|
||||
>buzz : number
|
||||
>10 : number
|
||||
|
||||
buzz += 3;
|
||||
>buzz += 3 : number
|
||||
>buzz : number
|
||||
>3 : number
|
||||
|
||||
var bizz = 8;
|
||||
>bizz : number
|
||||
>8 : number
|
||||
|
||||
bizz++; // compiles to exports.bizz = bizz += 1
|
||||
>bizz++ : number
|
||||
>bizz : number
|
||||
|
||||
bizz--; // similarly
|
||||
>bizz-- : number
|
||||
>bizz : number
|
||||
|
||||
++bizz; // compiles to exports.bizz = ++bizz
|
||||
>++bizz : number
|
||||
>bizz : number
|
||||
|
||||
export { foo, baz, baz as quux, buzz, bizz };
|
||||
>foo : number
|
||||
>baz : number
|
||||
>baz : number
|
||||
>quux : number
|
||||
>buzz : number
|
||||
>bizz : number
|
||||
|
||||
19
tests/cases/compiler/es6ExportClauseWithAssignmentInEs5.ts
Normal file
19
tests/cases/compiler/es6ExportClauseWithAssignmentInEs5.ts
Normal file
@ -0,0 +1,19 @@
|
||||
// @target: es5
|
||||
// @module: commonjs
|
||||
|
||||
// @filename: server.ts
|
||||
var foo = 2;
|
||||
foo = 3;
|
||||
|
||||
var baz = 3;
|
||||
baz = 4;
|
||||
|
||||
var buzz = 10;
|
||||
buzz += 3;
|
||||
|
||||
var bizz = 8;
|
||||
bizz++; // compiles to exports.bizz = bizz += 1
|
||||
bizz--; // similarly
|
||||
++bizz; // compiles to exports.bizz = ++bizz
|
||||
|
||||
export { foo, baz, baz as quux, buzz, bizz };
|
||||
Loading…
x
Reference in New Issue
Block a user