Parenthesize export assignments if needed (#19590)
* parenthesize export assignments if needed * Add default-specific parenthesization to handle lookahead * New parenthesization logic for export default * Handle commalist and comma cases
This commit is contained in:
parent
a89c055a48
commit
c2aa13dac5
|
@ -1982,7 +1982,7 @@ namespace ts {
|
|||
node.decorators = asNodeArray(decorators);
|
||||
node.modifiers = asNodeArray(modifiers);
|
||||
node.isExportEquals = isExportEquals;
|
||||
node.expression = expression;
|
||||
node.expression = isExportEquals ? parenthesizeBinaryOperand(SyntaxKind.EqualsToken, expression, /*isLeftSideOfBinary*/ false, /*leftOperand*/ undefined) : parenthesizeDefaultExpression(expression);
|
||||
return node;
|
||||
}
|
||||
|
||||
|
@ -3885,6 +3885,27 @@ namespace ts {
|
|||
: e;
|
||||
}
|
||||
|
||||
/**
|
||||
* [Per the spec](https://tc39.github.io/ecma262/#prod-ExportDeclaration), `export default` accepts _AssigmentExpression_ but
|
||||
* has a lookahead restriction for `function`, `async function`, and `class`.
|
||||
*
|
||||
* Basically, that means we need to parenthesize in the following cases:
|
||||
*
|
||||
* - BinaryExpression of CommaToken
|
||||
* - CommaList (synthetic list of multiple comma expressions)
|
||||
* - FunctionExpression
|
||||
* - ClassExpression
|
||||
*/
|
||||
export function parenthesizeDefaultExpression(e: Expression) {
|
||||
const check = skipPartiallyEmittedExpressions(e);
|
||||
return (check.kind === SyntaxKind.ClassExpression ||
|
||||
check.kind === SyntaxKind.FunctionExpression ||
|
||||
check.kind === SyntaxKind.CommaListExpression ||
|
||||
isBinaryExpression(check) && check.operatorToken.kind === SyntaxKind.CommaToken)
|
||||
? createParen(e)
|
||||
: e;
|
||||
}
|
||||
|
||||
/**
|
||||
* Wraps an expression in parentheses if it is needed in order to use the expression
|
||||
* as the expression of a NewExpression node.
|
||||
|
|
72
tests/baselines/reference/exportDefaultParenthesize.js
Normal file
72
tests/baselines/reference/exportDefaultParenthesize.js
Normal file
|
@ -0,0 +1,72 @@
|
|||
//// [tests/cases/compiler/exportDefaultParenthesize.ts] ////
|
||||
|
||||
//// [commalist.ts]
|
||||
export default {
|
||||
['foo'+'']: 42,
|
||||
['foo'+'']: 42,
|
||||
['foo'+'']: 42,
|
||||
['foo'+'']: 42,
|
||||
['foo'+'']: 42,
|
||||
['foo'+'']: 42,
|
||||
['foo'+'']: 42,
|
||||
['foo'+'']: 42,
|
||||
['foo'+'']: 42,
|
||||
['foo'+'']: 42,
|
||||
['foo'+'']: 42,
|
||||
['foo'+'']: 42,
|
||||
['foo'+'']: 42,
|
||||
['foo'+'']: 42,
|
||||
['foo'+'']: 42,
|
||||
['foo'+'']: 42,
|
||||
['foo'+'']: 42,
|
||||
['foo'+'']: 42,
|
||||
['foo'+'']: 42,
|
||||
['foo'+'']: 42,
|
||||
['foo'+'']: 42,
|
||||
['foo'+'']: 42,
|
||||
['foo'+'']: 42,
|
||||
};
|
||||
|
||||
//// [comma.ts]
|
||||
export default {
|
||||
['foo']: 42
|
||||
};
|
||||
|
||||
//// [functionexpression.ts]
|
||||
export default () => 42;
|
||||
|
||||
|
||||
//// [commalist.js]
|
||||
export default (_a = {},
|
||||
_a['foo' + ''] = 42,
|
||||
_a['foo' + ''] = 42,
|
||||
_a['foo' + ''] = 42,
|
||||
_a['foo' + ''] = 42,
|
||||
_a['foo' + ''] = 42,
|
||||
_a['foo' + ''] = 42,
|
||||
_a['foo' + ''] = 42,
|
||||
_a['foo' + ''] = 42,
|
||||
_a['foo' + ''] = 42,
|
||||
_a['foo' + ''] = 42,
|
||||
_a['foo' + ''] = 42,
|
||||
_a['foo' + ''] = 42,
|
||||
_a['foo' + ''] = 42,
|
||||
_a['foo' + ''] = 42,
|
||||
_a['foo' + ''] = 42,
|
||||
_a['foo' + ''] = 42,
|
||||
_a['foo' + ''] = 42,
|
||||
_a['foo' + ''] = 42,
|
||||
_a['foo' + ''] = 42,
|
||||
_a['foo' + ''] = 42,
|
||||
_a['foo' + ''] = 42,
|
||||
_a['foo' + ''] = 42,
|
||||
_a['foo' + ''] = 42,
|
||||
_a);
|
||||
var _a;
|
||||
//// [comma.js]
|
||||
export default (_a = {},
|
||||
_a['foo'] = 42,
|
||||
_a);
|
||||
var _a;
|
||||
//// [functionexpression.js]
|
||||
export default (function () { return 42; });
|
38
tests/baselines/reference/exportDefaultParenthesize.symbols
Normal file
38
tests/baselines/reference/exportDefaultParenthesize.symbols
Normal file
|
@ -0,0 +1,38 @@
|
|||
=== tests/cases/compiler/commalist.ts ===
|
||||
export default {
|
||||
No type information for this code. ['foo'+'']: 42,
|
||||
No type information for this code. ['foo'+'']: 42,
|
||||
No type information for this code. ['foo'+'']: 42,
|
||||
No type information for this code. ['foo'+'']: 42,
|
||||
No type information for this code. ['foo'+'']: 42,
|
||||
No type information for this code. ['foo'+'']: 42,
|
||||
No type information for this code. ['foo'+'']: 42,
|
||||
No type information for this code. ['foo'+'']: 42,
|
||||
No type information for this code. ['foo'+'']: 42,
|
||||
No type information for this code. ['foo'+'']: 42,
|
||||
No type information for this code. ['foo'+'']: 42,
|
||||
No type information for this code. ['foo'+'']: 42,
|
||||
No type information for this code. ['foo'+'']: 42,
|
||||
No type information for this code. ['foo'+'']: 42,
|
||||
No type information for this code. ['foo'+'']: 42,
|
||||
No type information for this code. ['foo'+'']: 42,
|
||||
No type information for this code. ['foo'+'']: 42,
|
||||
No type information for this code. ['foo'+'']: 42,
|
||||
No type information for this code. ['foo'+'']: 42,
|
||||
No type information for this code. ['foo'+'']: 42,
|
||||
No type information for this code. ['foo'+'']: 42,
|
||||
No type information for this code. ['foo'+'']: 42,
|
||||
No type information for this code. ['foo'+'']: 42,
|
||||
No type information for this code.};
|
||||
No type information for this code.
|
||||
No type information for this code.=== tests/cases/compiler/comma.ts ===
|
||||
export default {
|
||||
['foo']: 42
|
||||
>'foo' : Symbol(['foo'], Decl(comma.ts, 0, 16))
|
||||
|
||||
};
|
||||
|
||||
=== tests/cases/compiler/functionexpression.ts ===
|
||||
export default () => 42;
|
||||
No type information for this code.
|
||||
No type information for this code.
|
159
tests/baselines/reference/exportDefaultParenthesize.types
Normal file
159
tests/baselines/reference/exportDefaultParenthesize.types
Normal file
|
@ -0,0 +1,159 @@
|
|||
=== tests/cases/compiler/commalist.ts ===
|
||||
export default {
|
||||
>{ ['foo'+'']: 42, ['foo'+'']: 42, ['foo'+'']: 42, ['foo'+'']: 42, ['foo'+'']: 42, ['foo'+'']: 42, ['foo'+'']: 42, ['foo'+'']: 42, ['foo'+'']: 42, ['foo'+'']: 42, ['foo'+'']: 42, ['foo'+'']: 42, ['foo'+'']: 42, ['foo'+'']: 42, ['foo'+'']: 42, ['foo'+'']: 42, ['foo'+'']: 42, ['foo'+'']: 42, ['foo'+'']: 42, ['foo'+'']: 42, ['foo'+'']: 42, ['foo'+'']: 42, ['foo'+'']: 42,} : { [x: string]: number; }
|
||||
|
||||
['foo'+'']: 42,
|
||||
>'foo'+'' : string
|
||||
>'foo' : "foo"
|
||||
>'' : ""
|
||||
>42 : 42
|
||||
|
||||
['foo'+'']: 42,
|
||||
>'foo'+'' : string
|
||||
>'foo' : "foo"
|
||||
>'' : ""
|
||||
>42 : 42
|
||||
|
||||
['foo'+'']: 42,
|
||||
>'foo'+'' : string
|
||||
>'foo' : "foo"
|
||||
>'' : ""
|
||||
>42 : 42
|
||||
|
||||
['foo'+'']: 42,
|
||||
>'foo'+'' : string
|
||||
>'foo' : "foo"
|
||||
>'' : ""
|
||||
>42 : 42
|
||||
|
||||
['foo'+'']: 42,
|
||||
>'foo'+'' : string
|
||||
>'foo' : "foo"
|
||||
>'' : ""
|
||||
>42 : 42
|
||||
|
||||
['foo'+'']: 42,
|
||||
>'foo'+'' : string
|
||||
>'foo' : "foo"
|
||||
>'' : ""
|
||||
>42 : 42
|
||||
|
||||
['foo'+'']: 42,
|
||||
>'foo'+'' : string
|
||||
>'foo' : "foo"
|
||||
>'' : ""
|
||||
>42 : 42
|
||||
|
||||
['foo'+'']: 42,
|
||||
>'foo'+'' : string
|
||||
>'foo' : "foo"
|
||||
>'' : ""
|
||||
>42 : 42
|
||||
|
||||
['foo'+'']: 42,
|
||||
>'foo'+'' : string
|
||||
>'foo' : "foo"
|
||||
>'' : ""
|
||||
>42 : 42
|
||||
|
||||
['foo'+'']: 42,
|
||||
>'foo'+'' : string
|
||||
>'foo' : "foo"
|
||||
>'' : ""
|
||||
>42 : 42
|
||||
|
||||
['foo'+'']: 42,
|
||||
>'foo'+'' : string
|
||||
>'foo' : "foo"
|
||||
>'' : ""
|
||||
>42 : 42
|
||||
|
||||
['foo'+'']: 42,
|
||||
>'foo'+'' : string
|
||||
>'foo' : "foo"
|
||||
>'' : ""
|
||||
>42 : 42
|
||||
|
||||
['foo'+'']: 42,
|
||||
>'foo'+'' : string
|
||||
>'foo' : "foo"
|
||||
>'' : ""
|
||||
>42 : 42
|
||||
|
||||
['foo'+'']: 42,
|
||||
>'foo'+'' : string
|
||||
>'foo' : "foo"
|
||||
>'' : ""
|
||||
>42 : 42
|
||||
|
||||
['foo'+'']: 42,
|
||||
>'foo'+'' : string
|
||||
>'foo' : "foo"
|
||||
>'' : ""
|
||||
>42 : 42
|
||||
|
||||
['foo'+'']: 42,
|
||||
>'foo'+'' : string
|
||||
>'foo' : "foo"
|
||||
>'' : ""
|
||||
>42 : 42
|
||||
|
||||
['foo'+'']: 42,
|
||||
>'foo'+'' : string
|
||||
>'foo' : "foo"
|
||||
>'' : ""
|
||||
>42 : 42
|
||||
|
||||
['foo'+'']: 42,
|
||||
>'foo'+'' : string
|
||||
>'foo' : "foo"
|
||||
>'' : ""
|
||||
>42 : 42
|
||||
|
||||
['foo'+'']: 42,
|
||||
>'foo'+'' : string
|
||||
>'foo' : "foo"
|
||||
>'' : ""
|
||||
>42 : 42
|
||||
|
||||
['foo'+'']: 42,
|
||||
>'foo'+'' : string
|
||||
>'foo' : "foo"
|
||||
>'' : ""
|
||||
>42 : 42
|
||||
|
||||
['foo'+'']: 42,
|
||||
>'foo'+'' : string
|
||||
>'foo' : "foo"
|
||||
>'' : ""
|
||||
>42 : 42
|
||||
|
||||
['foo'+'']: 42,
|
||||
>'foo'+'' : string
|
||||
>'foo' : "foo"
|
||||
>'' : ""
|
||||
>42 : 42
|
||||
|
||||
['foo'+'']: 42,
|
||||
>'foo'+'' : string
|
||||
>'foo' : "foo"
|
||||
>'' : ""
|
||||
>42 : 42
|
||||
|
||||
};
|
||||
|
||||
=== tests/cases/compiler/comma.ts ===
|
||||
export default {
|
||||
>{ ['foo']: 42} : { ['foo']: number; }
|
||||
|
||||
['foo']: 42
|
||||
>'foo' : "foo"
|
||||
>42 : 42
|
||||
|
||||
};
|
||||
|
||||
=== tests/cases/compiler/functionexpression.ts ===
|
||||
export default () => 42;
|
||||
>() => 42 : () => number
|
||||
>42 : 42
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
//// [classexpr.ts]
|
||||
export default (class Foo {} as any);
|
||||
|
||||
//// [classexpr.js]
|
||||
export default (class Foo {
|
||||
});
|
|
@ -0,0 +1,4 @@
|
|||
=== tests/cases/compiler/classexpr.ts ===
|
||||
export default (class Foo {} as any);
|
||||
>Foo : Symbol(Foo, Decl(classexpr.ts, 0, 16))
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
=== tests/cases/compiler/classexpr.ts ===
|
||||
export default (class Foo {} as any);
|
||||
>(class Foo {} as any) : any
|
||||
>class Foo {} as any : any
|
||||
>class Foo {} : typeof Foo
|
||||
>Foo : typeof Foo
|
||||
|
|
@ -5,5 +5,5 @@ export = { ["hi"]: "there" };
|
|||
define(["require", "exports"], function (require, exports) {
|
||||
"use strict";
|
||||
var _a;
|
||||
return _a = {}, _a["hi"] = "there", _a;
|
||||
return (_a = {}, _a["hi"] = "there", _a);
|
||||
});
|
||||
|
|
|
@ -13,5 +13,5 @@ export = { ["hi"]: "there" };
|
|||
})(function (require, exports) {
|
||||
"use strict";
|
||||
var _a;
|
||||
return _a = {}, _a["hi"] = "there", _a;
|
||||
return (_a = {}, _a["hi"] = "there", _a);
|
||||
});
|
||||
|
|
36
tests/cases/compiler/exportDefaultParenthesize.ts
Normal file
36
tests/cases/compiler/exportDefaultParenthesize.ts
Normal file
|
@ -0,0 +1,36 @@
|
|||
// @target: es5
|
||||
// @module: esnext
|
||||
// @filename: commalist.ts
|
||||
export default {
|
||||
['foo'+'']: 42,
|
||||
['foo'+'']: 42,
|
||||
['foo'+'']: 42,
|
||||
['foo'+'']: 42,
|
||||
['foo'+'']: 42,
|
||||
['foo'+'']: 42,
|
||||
['foo'+'']: 42,
|
||||
['foo'+'']: 42,
|
||||
['foo'+'']: 42,
|
||||
['foo'+'']: 42,
|
||||
['foo'+'']: 42,
|
||||
['foo'+'']: 42,
|
||||
['foo'+'']: 42,
|
||||
['foo'+'']: 42,
|
||||
['foo'+'']: 42,
|
||||
['foo'+'']: 42,
|
||||
['foo'+'']: 42,
|
||||
['foo'+'']: 42,
|
||||
['foo'+'']: 42,
|
||||
['foo'+'']: 42,
|
||||
['foo'+'']: 42,
|
||||
['foo'+'']: 42,
|
||||
['foo'+'']: 42,
|
||||
};
|
||||
|
||||
// @filename: comma.ts
|
||||
export default {
|
||||
['foo']: 42
|
||||
};
|
||||
|
||||
// @filename: functionexpression.ts
|
||||
export default () => 42;
|
4
tests/cases/compiler/exportDefaultParenthesizeES6.ts
Normal file
4
tests/cases/compiler/exportDefaultParenthesizeES6.ts
Normal file
|
@ -0,0 +1,4 @@
|
|||
// @target: es6
|
||||
// @module: esnext
|
||||
// @filename: classexpr.ts
|
||||
export default (class Foo {} as any);
|
Loading…
Reference in a new issue