From 881fc14329f1b30f4e94c341f336c32dd287364f Mon Sep 17 00:00:00 2001 From: Brian Ng Date: Mon, 27 Nov 2017 12:08:35 -0600 Subject: [PATCH] Add handling parens for extends clause in generator (#6897) --- .../babel-generator/src/node/parentheses.js | 23 ++++++++++-- .../parentheses/class-extends/actual.js | 22 ++++++++++++ .../parentheses/class-extends/expected.js | 35 +++++++++++++++++++ 3 files changed, 77 insertions(+), 3 deletions(-) create mode 100644 packages/babel-generator/test/fixtures/parentheses/class-extends/actual.js create mode 100644 packages/babel-generator/test/fixtures/parentheses/class-extends/expected.js diff --git a/packages/babel-generator/src/node/parentheses.js b/packages/babel-generator/src/node/parentheses.js index e57efbf977..9c1322881c 100644 --- a/packages/babel-generator/src/node/parentheses.js +++ b/packages/babel-generator/src/node/parentheses.js @@ -27,6 +27,10 @@ const PRECEDENCE = { "**": 10, }; +const isClassExtendsClause = (node: Object, parent: Object): boolean => + (t.isClassDeclaration(parent) || t.isClassExpression(parent)) && + parent.superClass === node; + export function NullableTypeAnnotation(node: Object, parent: Object): boolean { return t.isArrayTypeAnnotation(parent); } @@ -35,7 +39,10 @@ export { NullableTypeAnnotation as FunctionTypeAnnotation }; export function UpdateExpression(node: Object, parent: Object): boolean { // (foo++).test() - return t.isMemberExpression(parent) && parent.object === node; + return ( + (t.isMemberExpression(parent) && parent.object === node) || + isClassExtendsClause(node, parent) + ); } export function ObjectExpression( @@ -62,6 +69,10 @@ export function Binary(node: Object, parent: Object): boolean { return parent.left === node; } + if (isClassExtendsClause(node, parent)) { + return true; + } + if ( ((t.isCallExpression(parent) || t.isNewExpression(parent)) && parent.callee === node) || @@ -151,7 +162,8 @@ export function YieldExpression(node: Object, parent: Object): boolean { t.isCallExpression(parent) || t.isMemberExpression(parent) || t.isNewExpression(parent) || - (t.isConditionalExpression(parent) && node === parent.test) + (t.isConditionalExpression(parent) && node === parent.test) || + isClassExtendsClause(node, parent) ); } @@ -170,7 +182,8 @@ export function UnaryLike(node: Object, parent: Object): boolean { t.isMemberExpression(parent, { object: node }) || t.isCallExpression(parent, { callee: node }) || t.isNewExpression(parent, { callee: node }) || - t.isBinaryExpression(parent, { operator: "**", left: node }) + t.isBinaryExpression(parent, { operator: "**", left: node }) || + isClassExtendsClause(node, parent) ); } @@ -210,6 +223,10 @@ export function AssignmentExpression(node: Object): boolean { } } +export function NewExpression(node: Object, parent: Object): boolean { + return isClassExtendsClause(node, parent); +} + // Walk up the print stack to determine if our node can come first // in statement. function isFirstInStatement( diff --git a/packages/babel-generator/test/fixtures/parentheses/class-extends/actual.js b/packages/babel-generator/test/fixtures/parentheses/class-extends/actual.js new file mode 100644 index 0000000000..308200e8d2 --- /dev/null +++ b/packages/babel-generator/test/fixtures/parentheses/class-extends/actual.js @@ -0,0 +1,22 @@ +class A extends (() => {}) {} +class A extends (B = C) {} +class A extends (B || C) {} +class A extends (B + C) {} +class A extends B() {} +class A extends class {} {} +class A extends (B ? C : D) {} +class A extends (new B()) {} +class A extends (B, C) {} +class A extends ({}) {} +class A extends B.C {} +class A extends function() {} {} +class A extends (void B) {} +class A extends (++B) {} + +async function f() { + class A extends (await C) {} +} + +function* f() { + class A extends (yield 1) {} +} diff --git a/packages/babel-generator/test/fixtures/parentheses/class-extends/expected.js b/packages/babel-generator/test/fixtures/parentheses/class-extends/expected.js new file mode 100644 index 0000000000..6885e6094e --- /dev/null +++ b/packages/babel-generator/test/fixtures/parentheses/class-extends/expected.js @@ -0,0 +1,35 @@ +class A extends (() => {}) {} + +class A extends (B = C) {} + +class A extends (B || C) {} + +class A extends (B + C) {} + +class A extends B() {} + +class A extends class {} {} + +class A extends (B ? C : D) {} + +class A extends (new B()) {} + +class A extends (B, C) {} + +class A extends {} {} + +class A extends B.C {} + +class A extends function () {} {} + +class A extends (void B) {} + +class A extends (++B) {} + +async function f() { + class A extends (await C) {} +} + +function* f() { + class A extends (yield 1) {} +}