+1
-1
| { | ||
| "name": "esrap", | ||
| "version": "2.2.11", | ||
| "version": "2.2.12", | ||
| "description": "Parse in reverse", | ||
@@ -5,0 +5,0 @@ "repository": { |
+75
-134
@@ -514,19 +514,7 @@ /** @import { TSESTree } from '@typescript-eslint/types' */ | ||
| // } | ||
| if (needs_parens(node.left, node, false)) { | ||
| context.write('('); | ||
| context.visit(node.left); | ||
| context.write(')'); | ||
| } else { | ||
| context.visit(node.left); | ||
| } | ||
| maybe_wrap(context, node.left, operand_needs_wrap(node.left, node, false)); | ||
| context.write(` ${node.operator} `); | ||
| if (needs_parens(node.right, node, true)) { | ||
| context.write('('); | ||
| context.visit(node.right); | ||
| context.write(')'); | ||
| } else { | ||
| context.visit(node.right); | ||
| } | ||
| maybe_wrap(context, node.right, operand_needs_wrap(node.right, node, true)); | ||
| }, | ||
@@ -579,14 +567,8 @@ | ||
| const needs_parens = | ||
| const wrap = | ||
| node.callee.type === 'ChainExpression' || | ||
| EXPRESSIONS_PRECEDENCE[node.callee.type] < EXPRESSIONS_PRECEDENCE.CallExpression || | ||
| (node.type === 'NewExpression' && has_call_expression(node.callee)); | ||
| maybe_wrap(context, node.callee, wrap); | ||
| if (needs_parens) { | ||
| context.write('('); | ||
| context.visit(node.callee); | ||
| context.write(')'); | ||
| } else { | ||
| context.visit(node.callee); | ||
| } | ||
| if (/** @type {TSESTree.CallExpression} */ (node).optional) { | ||
@@ -931,3 +913,2 @@ context.write('?.'); | ||
| context.write('('); | ||
| sequence( | ||
@@ -959,3 +940,2 @@ context, | ||
| context.write('('); | ||
| sequence( | ||
@@ -971,4 +951,5 @@ context, | ||
| ); | ||
| context.write(')'); | ||
| context.write(') => '); | ||
| context.write(' => '); | ||
@@ -1019,9 +1000,3 @@ // @ts-expect-error `acorn-typescript` and `@typescript-eslint/types` have slightly different type definitions | ||
| if (arrow_concise_body_needs_wrap(node.body)) { | ||
| context.write('('); | ||
| context.visit(node.body); | ||
| context.write(')'); | ||
| } else { | ||
| context.visit(node.body); | ||
| } | ||
| maybe_wrap(context, node.body, arrow_concise_body_needs_wrap(node.body)); | ||
| }, | ||
@@ -1085,9 +1060,5 @@ | ||
| ConditionalExpression(node, context) { | ||
| if (EXPRESSIONS_PRECEDENCE[node.test.type] > EXPRESSIONS_PRECEDENCE.ConditionalExpression) { | ||
| context.visit(node.test); | ||
| } else { | ||
| context.write('('); | ||
| context.visit(node.test); | ||
| context.write(')'); | ||
| } | ||
| const wrap = | ||
| EXPRESSIONS_PRECEDENCE[node.test.type] <= EXPRESSIONS_PRECEDENCE.ConditionalExpression; | ||
| maybe_wrap(context, node.test, wrap); | ||
@@ -1250,16 +1221,9 @@ const consequent = context.new(); | ||
| ExpressionStatement(node, context) { | ||
| if ( | ||
| // wrap when a leading `{`/`function` would otherwise be parsed as a block/declaration | ||
| const wrap = | ||
| node.expression.type === 'ObjectExpression' || | ||
| (node.expression.type === 'AssignmentExpression' && | ||
| node.expression.left.type === 'ObjectPattern') || | ||
| node.expression.type === 'FunctionExpression' | ||
| ) { | ||
| // is an AssignmentExpression to an ObjectPattern | ||
| context.write('('); | ||
| context.visit(node.expression); | ||
| context.write(');'); | ||
| return; | ||
| } | ||
| context.visit(node.expression); | ||
| node.expression.type === 'FunctionExpression'; | ||
| maybe_wrap(context, node.expression, wrap); | ||
| context.write(';'); | ||
@@ -1300,2 +1264,3 @@ }, | ||
| if (node.optional) context.write('?'); | ||
| if (node.typeAnnotation) context.visit(node.typeAnnotation); | ||
@@ -1448,9 +1413,6 @@ }, | ||
| MemberExpression(node, context) { | ||
| if (EXPRESSIONS_PRECEDENCE[node.object.type] < EXPRESSIONS_PRECEDENCE.MemberExpression) { | ||
| context.write('('); | ||
| context.visit(node.object); | ||
| context.write(')'); | ||
| } else { | ||
| context.visit(node.object); | ||
| } | ||
| const wrap = | ||
| node.object.type === 'ChainExpression' || | ||
| EXPRESSIONS_PRECEDENCE[node.object.type] < EXPRESSIONS_PRECEDENCE.MemberExpression; | ||
| maybe_wrap(context, node.object, wrap); | ||
@@ -1496,5 +1458,3 @@ if (node.computed) { | ||
| ParenthesizedExpression(node, context) { | ||
| context.write('('); | ||
| context.visit(node.expression); | ||
| context.write(')'); | ||
| maybe_wrap(context, node.expression, true); | ||
| }, | ||
@@ -1648,3 +1608,3 @@ | ||
| TaggedTemplateExpression(node, context) { | ||
| context.visit(node.tag); | ||
| maybe_wrap(context, node.tag, node.tag.type === 'ChainExpression'); | ||
| context.visit(node.quasi); | ||
@@ -1722,11 +1682,15 @@ }, | ||
| context.write(' '); | ||
| } else if ( | ||
| (node.operator === '+' || node.operator === '-') && | ||
| ((node.argument.type === 'UnaryExpression' && node.argument.operator === node.operator) || | ||
| (node.argument.type === 'UpdateExpression' && | ||
| node.argument.prefix && | ||
| node.argument.operator[0] === node.operator)) | ||
| ) { | ||
| context.write(' '); | ||
| } | ||
| if (EXPRESSIONS_PRECEDENCE[node.argument.type] < EXPRESSIONS_PRECEDENCE.UnaryExpression) { | ||
| context.write('('); | ||
| context.visit(node.argument); | ||
| context.write(')'); | ||
| } else { | ||
| context.visit(node.argument); | ||
| } | ||
| const wrap = | ||
| EXPRESSIONS_PRECEDENCE[node.argument.type] < EXPRESSIONS_PRECEDENCE.UnaryExpression; | ||
| maybe_wrap(context, node.argument, wrap); | ||
| }, | ||
@@ -1967,9 +1931,5 @@ | ||
| context.write('>'); | ||
| if (EXPRESSIONS_PRECEDENCE[node.expression.type] < EXPRESSIONS_PRECEDENCE.TSTypeAssertion) { | ||
| context.write('('); | ||
| context.visit(node.expression); | ||
| context.write(')'); | ||
| } else { | ||
| context.visit(node.expression); | ||
| } | ||
| const wrap = | ||
| EXPRESSIONS_PRECEDENCE[node.expression.type] < EXPRESSIONS_PRECEDENCE.TSTypeAssertion; | ||
| maybe_wrap(context, node.expression, wrap); | ||
| }, | ||
@@ -2093,3 +2053,2 @@ | ||
| context.write('('); | ||
| sequence( | ||
@@ -2208,12 +2167,5 @@ context, | ||
| if (node.expression) { | ||
| const needs_parens = | ||
| const wrap = | ||
| EXPRESSIONS_PRECEDENCE[node.expression.type] < EXPRESSIONS_PRECEDENCE.TSAsExpression; | ||
| if (needs_parens) { | ||
| context.write('('); | ||
| context.visit(node.expression); | ||
| context.write(')'); | ||
| } else { | ||
| context.visit(node.expression); | ||
| } | ||
| maybe_wrap(context, node.expression, wrap); | ||
| } | ||
@@ -2264,11 +2216,5 @@ context.write(' as '); | ||
| // operator expressions can't take a postfix `!` directly: `(0 as number)!`, `(await x)!` | ||
| if ( | ||
| EXPRESSIONS_PRECEDENCE[node.expression.type] < EXPRESSIONS_PRECEDENCE.TSNonNullExpression | ||
| ) { | ||
| context.write('('); | ||
| context.visit(node.expression); | ||
| context.write(')'); | ||
| } else { | ||
| context.visit(node.expression); | ||
| } | ||
| const wrap = | ||
| EXPRESSIONS_PRECEDENCE[node.expression.type] < EXPRESSIONS_PRECEDENCE.TSNonNullExpression; | ||
| maybe_wrap(context, node.expression, wrap); | ||
| context.write('!'); | ||
@@ -2307,5 +2253,3 @@ }, | ||
| TSParenthesizedType(node, context) { | ||
| context.write('('); | ||
| context.visit(node.typeAnnotation); | ||
| context.write(')'); | ||
| maybe_wrap(context, node.typeAnnotation, true); | ||
| }, | ||
@@ -2315,13 +2259,6 @@ | ||
| if (node.expression) { | ||
| const needs_parens = | ||
| const wrap = | ||
| EXPRESSIONS_PRECEDENCE[node.expression.type] < | ||
| EXPRESSIONS_PRECEDENCE.TSSatisfiesExpression; | ||
| if (needs_parens) { | ||
| context.write('('); | ||
| context.visit(node.expression); | ||
| context.write(')'); | ||
| } else { | ||
| context.visit(node.expression); | ||
| } | ||
| maybe_wrap(context, node.expression, wrap); | ||
| } | ||
@@ -2386,3 +2323,3 @@ context.write(' satisfies '); | ||
| */ | ||
| function needs_parens(node, parent, is_right) { | ||
| function operand_needs_wrap(node, parent, is_right) { | ||
| if (node.type === 'PrivateIdentifier') return false; | ||
@@ -2406,23 +2343,17 @@ | ||
| // `**` can't take a unary/await left operand: `-2 ** 2`, `await x ** 2` are syntax errors | ||
| const unary_base_of_pow = | ||
| !is_right && | ||
| parent.operator === '**' && | ||
| (node.type === 'UnaryExpression' || node.type === 'AwaitExpression'); | ||
| if (unary_base_of_pow) return true; | ||
| const precedence = EXPRESSIONS_PRECEDENCE[node.type]; | ||
| const parent_precedence = EXPRESSIONS_PRECEDENCE[parent.type]; | ||
| if (precedence !== parent_precedence) return precedence < parent_precedence; | ||
| if (precedence !== parent_precedence) { | ||
| // Different node types | ||
| return ( | ||
| (!is_right && precedence === 15 && parent_precedence === 14 && parent.operator === '**') || | ||
| precedence < parent_precedence | ||
| ); | ||
| } | ||
| const operator = /** @type {TSESTree.BinaryExpression} */ (node).operator; | ||
| if (precedence !== 12 && precedence !== 14) { | ||
| // Not a `LogicalExpression` or `BinaryExpression` | ||
| return false; | ||
| } | ||
| if ( | ||
| /** @type {TSESTree.BinaryExpression} */ (node).operator === '**' && | ||
| parent.operator === '**' | ||
| ) { | ||
| // Exponentiation operator has right-to-left associativity | ||
| if (operator === '**' && parent.operator === '**') { | ||
| // exponentiation is right-associative | ||
| return !is_right; | ||
@@ -2432,15 +2363,24 @@ } | ||
| if (is_right) { | ||
| // Parenthesis are used if both operators have the same precedence | ||
| return ( | ||
| OPERATOR_PRECEDENCE[/** @type {TSESTree.BinaryExpression} */ (node).operator] <= | ||
| OPERATOR_PRECEDENCE[parent.operator] | ||
| ); | ||
| // parentheses are needed when both operators have the same precedence | ||
| return OPERATOR_PRECEDENCE[operator] <= OPERATOR_PRECEDENCE[parent.operator]; | ||
| } | ||
| return ( | ||
| OPERATOR_PRECEDENCE[/** @type {TSESTree.BinaryExpression} */ (node).operator] < | ||
| OPERATOR_PRECEDENCE[parent.operator] | ||
| ); | ||
| return OPERATOR_PRECEDENCE[operator] < OPERATOR_PRECEDENCE[parent.operator]; | ||
| } | ||
| /** | ||
| * @param {Context} context | ||
| * @param {TSESTree.Node} node | ||
| * @param {boolean} wrap | ||
| */ | ||
| function maybe_wrap(context, node, wrap) { | ||
| if (wrap) { | ||
| context.write('('); | ||
| context.visit(node); | ||
| context.write(')'); | ||
| } else { | ||
| context.visit(node); | ||
| } | ||
| } | ||
| /** @param {TSESTree.Node} node */ | ||
@@ -2457,2 +2397,3 @@ function has_call_expression(node) { | ||
| } | ||
| return false; | ||
| } | ||
@@ -2459,0 +2400,0 @@ |
88534
-0.52%2612
-1.99%