|
| 1 | +'use strict'; |
| 2 | + |
| 3 | +const {isOpeningParenToken, isClosingParenToken} = require('eslint-utils'); |
| 4 | + |
| 5 | +// Determine whether this node is a decimal integer literal. |
| 6 | +// Copied from https://github.com/eslint/eslint/blob/cc4871369645c3409dc56ded7a555af8a9f63d51/lib/rules/utils/ast-utils.js#L1237 |
| 7 | +const DECIMAL_INTEGER_PATTERN = /^(?:0|0[0-7]*[89]\d*|[1-9](?:_?\d)*)$/u; |
| 8 | +const isDecimalInteger = node => |
| 9 | + node.type === 'Literal' && |
| 10 | + typeof node.value === 'number' && |
| 11 | + DECIMAL_INTEGER_PATTERN.test(node.raw); |
| 12 | + |
| 13 | +/** |
| 14 | +Determine if a constructor function is newed-up with parens. |
| 15 | +
|
| 16 | +@param {Node} node - The `NewExpression` node to be checked. |
| 17 | +@param {SourceCode} sourceCode - The source code object. |
| 18 | +@returns {boolean} True if the constructor is called with parens. |
| 19 | +
|
| 20 | +Copied from https://github.com/eslint/eslint/blob/cc4871369645c3409dc56ded7a555af8a9f63d51/lib/rules/no-extra-parens.js#L252 |
| 21 | +*/ |
| 22 | +function isNewExpressionWithParentheses(node, sourceCode) { |
| 23 | + if (node.arguments.length > 0) { |
| 24 | + return true; |
| 25 | + } |
| 26 | + |
| 27 | + const [penultimateToken, lastToken] = sourceCode.getLastTokens(node, 2); |
| 28 | + // The expression should end with its own parens, for example, `new new Foo()` is not a new expression with parens. |
| 29 | + return isOpeningParenToken(penultimateToken) && |
| 30 | + isClosingParenToken(lastToken) && |
| 31 | + node.callee.range[1] < node.range[1]; |
| 32 | +} |
| 33 | + |
| 34 | +/** |
| 35 | +Check if parentheses should to be added to a `node` when it's used as an `object` of `MemberExpression`. |
| 36 | +
|
| 37 | +@param {Node} node - The AST node to check. |
| 38 | +@param {SourceCode} sourceCode - The source code object. |
| 39 | +@returns {boolean} |
| 40 | +*/ |
| 41 | +function shouldAddParenthesesToMemberExpressionObject(node, sourceCode) { |
| 42 | + switch (node.type) { |
| 43 | + // This is not a full list. Some other nodes like `FunctionDeclaration` don't need parentheses, |
| 44 | + // but it's not possible to be in the place we are checking at this point. |
| 45 | + case 'Identifier': |
| 46 | + case 'MemberExpression': |
| 47 | + case 'CallExpression': |
| 48 | + case 'ChainExpression': |
| 49 | + case 'TemplateLiteral': |
| 50 | + return false; |
| 51 | + case 'NewExpression': |
| 52 | + return !isNewExpressionWithParentheses(node, sourceCode); |
| 53 | + case 'Literal': { |
| 54 | + /* istanbul ignore next */ |
| 55 | + if (isDecimalInteger(node)) { |
| 56 | + return true; |
| 57 | + } |
| 58 | + |
| 59 | + return false; |
| 60 | + } |
| 61 | + |
| 62 | + default: |
| 63 | + return true; |
| 64 | + } |
| 65 | +} |
| 66 | + |
| 67 | +module.exports = shouldAddParenthesesToMemberExpressionObject; |
0 commit comments