@@ -145,9 +145,7 @@ function expressionNeedsParenthesis(state, node, parentNode, isRightHand) {
145145
146146function formatExpression ( state , node , parentNode , isRightHand ) {
147147 /*
148- Writes into `state` a left-hand or right-hand expression `node`
149- from a binary expression applying the provided `operator`.
150- The `isRightHand` parameter should be `true` if the `node` is a right-hand argument.
148+ Writes into `state` the provided `node`, adding parenthesis around if the provided `parentNode` needs it. If `node` is a right-hand argument, the provided `isRightHand` parameter should be `true`.
151149 */
152150 const { generator } = state
153151 if ( expressionNeedsParenthesis ( state , node , parentNode , isRightHand ) ) {
@@ -505,7 +503,21 @@ export const GENERATOR = {
505503 state . write ( 'class ' + ( node . id ? `${ node . id . name } ` : '' ) , node )
506504 if ( node . superClass ) {
507505 state . write ( 'extends ' )
508- this [ node . superClass . type ] ( node . superClass , state )
506+ const { superClass } = node
507+ const { type } = superClass
508+ const precedence = state . expressionsPrecedence [ type ]
509+ if (
510+ ( type [ 0 ] !== 'C' || type [ 1 ] !== 'l' || type [ 5 ] !== 'E' ) &&
511+ ( precedence === NEEDS_PARENTHESES ||
512+ precedence < state . expressionsPrecedence . ClassExpression )
513+ ) {
514+ // Not a ClassExpression that needs parentheses
515+ state . write ( '(' )
516+ this [ node . superClass . type ] ( superClass , state )
517+ state . write ( ')' )
518+ } else {
519+ this [ superClass . type ] ( superClass , state )
520+ }
509521 state . write ( ' ' )
510522 }
511523 this . ClassBody ( node . body , state )
@@ -514,7 +526,7 @@ export const GENERATOR = {
514526 state . write ( 'import ' )
515527 const { specifiers } = node
516528 const { length } = specifiers
517- // NOTE : Once babili is fixed, put this after condition
529+ // TODO : Once babili is fixed, put this after condition
518530 // https://github.com/babel/babili/issues/430
519531 let i = 0
520532 if ( length > 0 ) {
@@ -830,22 +842,21 @@ export const GENERATOR = {
830842 argument : { type } ,
831843 } = node
832844 state . write ( operator )
845+ const needsParentheses = expressionNeedsParenthesis ( state , argument , node )
833846 if (
834- operator . length > 1 ||
835- ( type [ 0 ] === 'U' &&
836- ( type [ 1 ] === 'n' || type [ 1 ] === 'p' ) &&
837- argument . prefix &&
838- argument . operator [ 0 ] === operator &&
839- ( operator === '+' || operator === '-' ) )
847+ ! needsParentheses &&
848+ ( operator . length > 1 ||
849+ ( type [ 0 ] === 'U' &&
850+ ( type [ 1 ] === 'n' || type [ 1 ] === 'p' ) &&
851+ argument . prefix &&
852+ argument . operator [ 0 ] === operator &&
853+ ( operator === '+' || operator === '-' ) ) )
840854 ) {
841855 // Large operator or argument is UnaryExpression or UpdateExpression node
842856 state . write ( ' ' )
843857 }
844- if (
845- state . expressionsPrecedence [ type ] <
846- state . expressionsPrecedence . UnaryExpression
847- ) {
848- state . write ( '(' )
858+ if ( needsParentheses ) {
859+ state . write ( operator . length > 1 ? ' (' : '(' )
849860 this [ type ] ( argument , state )
850861 state . write ( ')' )
851862 } else {
@@ -892,15 +903,17 @@ export const GENERATOR = {
892903 } ) ,
893904 LogicalExpression : BinaryExpression ,
894905 ConditionalExpression ( node , state ) {
906+ const { test } = node
907+ const precedence = state . expressionsPrecedence [ test . type ]
895908 if (
896- state . expressionsPrecedence [ node . test . type ] >
897- state . expressionsPrecedence . ConditionalExpression
909+ precedence === NEEDS_PARENTHESES ||
910+ precedence <= state . expressionsPrecedence . ConditionalExpression
898911 ) {
899- this [ node . test . type ] ( node . test , state )
900- } else {
901912 state . write ( '(' )
902- this [ node . test . type ] ( node . test , state )
913+ this [ test . type ] ( test , state )
903914 state . write ( ')' )
915+ } else {
916+ this [ test . type ] ( test , state )
904917 }
905918 state . write ( ' ? ' )
906919 this [ node . consequent . type ] ( node . consequent , state )
@@ -909,9 +922,10 @@ export const GENERATOR = {
909922 } ,
910923 NewExpression ( node , state ) {
911924 state . write ( 'new ' )
925+ const precedence = state . expressionsPrecedence [ node . callee . type ]
912926 if (
913- state . expressionsPrecedence [ node . callee . type ] <
914- state . expressionsPrecedence . CallExpression ||
927+ precedence === NEEDS_PARENTHESES ||
928+ precedence < state . expressionsPrecedence . CallExpression ||
915929 hasCallExpression ( node . callee )
916930 ) {
917931 state . write ( '(' )
@@ -923,9 +937,10 @@ export const GENERATOR = {
923937 formatSequence ( state , node [ 'arguments' ] )
924938 } ,
925939 CallExpression ( node , state ) {
940+ const precedence = state . expressionsPrecedence [ node . callee . type ]
926941 if (
927- state . expressionsPrecedence [ node . callee . type ] <
928- state . expressionsPrecedence . CallExpression
942+ precedence === NEEDS_PARENTHESES ||
943+ precedence < state . expressionsPrecedence . CallExpression
929944 ) {
930945 state . write ( '(' )
931946 this [ node . callee . type ] ( node . callee , state )
@@ -942,9 +957,10 @@ export const GENERATOR = {
942957 this [ node . expression . type ] ( node . expression , state )
943958 } ,
944959 MemberExpression ( node , state ) {
960+ const precedence = state . expressionsPrecedence [ node . object . type ]
945961 if (
946- state . expressionsPrecedence [ node . object . type ] <
947- state . expressionsPrecedence . MemberExpression
962+ precedence === NEEDS_PARENTHESES ||
963+ precedence < state . expressionsPrecedence . MemberExpression
948964 ) {
949965 state . write ( '(' )
950966 this [ node . object . type ] ( node . object , state )
0 commit comments