Skip to content

Commit

Permalink
Fix operator precedence
Browse files Browse the repository at this point in the history
  • Loading branch information
fisker committed May 20, 2020
1 parent d610645 commit c890378
Show file tree
Hide file tree
Showing 2 changed files with 47 additions and 7 deletions.
19 changes: 12 additions & 7 deletions rules/prefer-array-find.js
Expand Up @@ -87,17 +87,22 @@ const destructuringAssignmentSelector = [
// - `ObjectPattern`: `[{foo = baz}] = array.filter(bar)`
const assignmentNeedParenthesize = ({type}) => type === 'ObjectExpression' || type === 'ObjectPattern';

// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Expressions_and_Operators#Operator_precedence
// Higher than `??` and `||`
const hasHigherPrecedence = (node, operator) => (
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Operator_Precedence#Table
const hasLowerPrecedence = (node, operator) => (
(node.type === 'LogicalExpression' && (
node.operator === operator ||
// `??` has lower precedence than `||`
// https://tc39.es/proposal-nullish-coalescing/
(operator === '??' && node.operator === '||')
// https://tc39.es/proposal-nullish-coalescing/ says
// `??` has lower precedence than `||`
// But MDN says
// `??` has higher precedence than `||`
(operator === '||' && node.operator === '??') ||
(operator === '??' && (node.operator === '||' || node.operator === '&&'))
)) ||
node.type === 'ConditionalExpression' ||
// Lower than `assignment`, should already parenthesized
/* istanbul ignore next */
node.type === 'AssignmentExpression' ||
node.type === 'YieldExpression' ||
node.type === 'SequenceExpression'
);

Expand Down Expand Up @@ -128,7 +133,7 @@ const fixDestructuring = (source, node) => {
const defaultValue = element.right;
let defaultValueText = source.getText(defaultValue);

if (isParenthesized(defaultValue, source) || hasHigherPrecedence(defaultValue, operator)) {
if (isParenthesized(defaultValue, source) || hasLowerPrecedence(defaultValue, operator)) {
defaultValueText = `(${defaultValueText})`;
}

Expand Down
35 changes: 35 additions & 0 deletions test/prefer-array-find.js
Expand Up @@ -312,6 +312,24 @@ ruleTester.run('prefer-array-find', rule, {
]
}]
},
// // TODO: enable this test when ESLint support `nullish coalescing operator`
// {
// code: 'const [foo = a ?? b] = array.filter(bar)',
// output: 'const [foo = a ?? b] = array.filter(bar)',
// errors: [{
// messageId: MESSAGE_ID_DESTRUCTURING_DECLARATION,
// suggestions: [
// {
// messageId: MESSAGE_ID_USE_NULLISH_COALESCING_OPERATOR,
// output: 'const foo = array.find(bar) ?? (a ?? b)'
// },
// {
// messageId: MESSAGE_ID_USE_LOGICAL_OR_OPERATOR,
// output: 'const foo = array.find(bar) || (a ?? b)'
// }
// ]
// }]
// },
{
code: 'const [foo = a || b] = array.filter(bar)',
output: 'const [foo = a || b] = array.filter(bar)',
Expand All @@ -328,6 +346,23 @@ ruleTester.run('prefer-array-find', rule, {
}
]
}]
},
{
code: 'const [foo = a && b] = array.filter(bar)',
output: 'const [foo = a && b] = array.filter(bar)',
errors: [{
messageId: MESSAGE_ID_DESTRUCTURING_DECLARATION,
suggestions: [
{
messageId: MESSAGE_ID_USE_NULLISH_COALESCING_OPERATOR,
output: 'const foo = array.find(bar) ?? (a && b)'
},
{
messageId: MESSAGE_ID_USE_LOGICAL_OR_OPERATOR,
output: 'const foo = array.find(bar) || a && b'
}
]
}]
}
]
});
Expand Down

0 comments on commit c890378

Please sign in to comment.