UNPKG

eslint-plugin-stylistic-compat

Version:

Compatibility version of @stylistic/eslint-plugin for Node.js >= 12 and ESLint v8

259 lines (255 loc) 12.3 kB
'use strict'; var _someInstanceProperty = require('@babel/runtime-corejs3/core-js/instance/some'); var _trimInstanceProperty = require('@babel/runtime-corejs3/core-js/instance/trim'); var _sliceInstanceProperty = require('@babel/runtime-corejs3/core-js/instance/slice'); var utils = require('../utils.js'); require('@babel/runtime-corejs3/core-js/object/from-entries'); require('@babel/runtime-corejs3/core-js/instance/map'); require('@babel/runtime-corejs3/core-js/instance/filter'); require('@babel/runtime-corejs3/core-js/object/entries'); require('@babel/runtime-corejs3/core-js/set'); require('@babel/runtime-corejs3/core-js/instance/flags'); require('@babel/runtime-corejs3/core-js/instance/includes'); require('@babel/runtime-corejs3/core-js/instance/starts-with'); require('../vendor.js'); require('@babel/runtime-corejs3/core-js/object/assign'); require('@babel/runtime-corejs3/core-js/object/create'); require('@babel/runtime-corejs3/core-js/object/freeze'); require('@babel/runtime-corejs3/core-js/array/is-array'); require('@babel/runtime-corejs3/core-js/instance/last-index-of'); require('@babel/runtime-corejs3/core-js/object/define-properties'); require('@babel/runtime-corejs3/core-js/object/keys'); require('@babel/runtime-corejs3/core-js/instance/index-of'); require('@babel/runtime-corejs3/core-js/instance/at'); require('@babel/runtime-corejs3/core-js/symbol'); require('@babel/runtime-corejs3/core-js/symbol/iterator'); require('@babel/runtime-corejs3/core-js/parse-int'); require('@babel/runtime-corejs3/core-js/parse-float'); require('@babel/runtime-corejs3/core-js/weak-map'); require('@babel/runtime-corejs3/core-js/object/define-property'); require('@babel/runtime-corejs3/core-js/global-this'); require('@babel/runtime-corejs3/core-js/instance/for-each'); require('@babel/runtime-corejs3/core-js/array/from'); require('eslint/use-at-your-own-risk'); require('eslint'); require('@babel/runtime-corejs3/core-js/object/get-own-property-descriptor'); require('@babel/runtime-corejs3/core-js/map'); require('@babel/runtime-corejs3/core-js/instance/find'); require('@babel/runtime-corejs3/core-js/instance/every'); require('@babel/runtime-corejs3/core-js/instance/sort'); require('@babel/runtime-corejs3/core-js/array/of'); require('@babel/runtime-corejs3/core-js/instance/concat'); require('@babel/runtime-corejs3/core-js/instance/entries'); require('@babel/runtime-corejs3/core-js/instance/find-index'); require('@babel/runtime-corejs3/core-js/instance/flat'); require('@babel/runtime-corejs3/core-js/instance/keys'); require('@babel/runtime-corejs3/core-js/instance/values'); require('@babel/runtime-corejs3/core-js/object/get-own-property-names'); require('@babel/runtime-corejs3/core-js/number/is-finite'); require('@babel/runtime-corejs3/core-js/number/is-nan'); require('@babel/runtime-corejs3/core-js/number/parse-float'); require('@babel/runtime-corejs3/core-js/number/parse-int'); require('@babel/runtime-corejs3/core-js/object/is'); require('@babel/runtime-corejs3/core-js/object/is-extensible'); require('@babel/runtime-corejs3/core-js/object/is-frozen'); require('@babel/runtime-corejs3/core-js/object/is-sealed'); require('@babel/runtime-corejs3/core-js/object/values'); require('@babel/runtime-corejs3/core-js/string/from-code-point'); require('@babel/runtime-corejs3/core-js/string/raw'); require('@babel/runtime-corejs3/core-js/instance/code-point-at'); require('@babel/runtime-corejs3/core-js/instance/ends-with'); require('@babel/runtime-corejs3/core-js/instance/pad-end'); require('@babel/runtime-corejs3/core-js/instance/pad-start'); require('@babel/runtime-corejs3/core-js/instance/trim-end'); require('@babel/runtime-corejs3/core-js/instance/trim-left'); require('@babel/runtime-corejs3/core-js/instance/trim-right'); require('@babel/runtime-corejs3/core-js/instance/trim-start'); require('@babel/runtime-corejs3/core-js/symbol/for'); require('@babel/runtime-corejs3/core-js/symbol/key-for'); require('@babel/runtime-corejs3/core-js/object/prevent-extensions'); require('@babel/runtime-corejs3/core-js/object/seal'); require('@babel/runtime-corejs3/core-js/object/get-prototype-of'); require('@babel/runtime-corejs3/core-js/symbol/replace'); require('@babel/runtime-corejs3/core-js/instance/bind'); require('@babel/runtime-corejs3/core-js/instance/splice'); require('@babel/runtime-corejs3/core-js/instance/repeat'); require('@babel/runtime-corejs3/core-js/instance/reduce'); require('@babel/runtime-corejs3/core-js/instance/reverse'); var functionParenNewline = utils.createRule({ name: "function-paren-newline", package: "js", meta: { type: "layout", docs: { description: "Enforce consistent line breaks inside function parentheses" }, fixable: "whitespace", schema: [{ oneOf: [{ type: "string", enum: ["always", "never", "consistent", "multiline", "multiline-arguments"] }, { type: "object", properties: { minItems: { type: "integer", minimum: 0 } }, additionalProperties: false }] }], messages: { expectedBefore: "Expected newline before ')'.", expectedAfter: "Expected newline after '('.", expectedBetween: "Expected newline between arguments/params.", unexpectedBefore: "Unexpected newline before ')'.", unexpectedAfter: "Unexpected newline after '('." } }, create(context) { const sourceCode = context.sourceCode; const rawOption = context.options[0] || "multiline"; const multilineOption = rawOption === "multiline"; const multilineArgumentsOption = rawOption === "multiline-arguments"; const consistentOption = rawOption === "consistent"; let minItems; if (typeof rawOption === "object") minItems = rawOption.minItems;else if (rawOption === "always") minItems = 0;else if (rawOption === "never") minItems = Infinity; function shouldHaveNewlines(elements, hasLeftNewline) { if (multilineArgumentsOption && elements.length === 1) return hasLeftNewline; if (multilineOption || multilineArgumentsOption) return _someInstanceProperty(elements).call(elements, (element, index) => index !== elements.length - 1 && element.loc.end.line !== elements[index + 1].loc.start.line); if (consistentOption) return hasLeftNewline; return minItems == null || elements.length >= minItems; } function validateParens(parens, elements) { const leftParen = parens.leftParen; const rightParen = parens.rightParen; const tokenAfterLeftParen = sourceCode.getTokenAfter(leftParen); const tokenBeforeRightParen = sourceCode.getTokenBefore(rightParen); const hasLeftNewline = !utils.isTokenOnSameLine(leftParen, tokenAfterLeftParen); const hasRightNewline = !utils.isTokenOnSameLine(tokenBeforeRightParen, rightParen); const needsNewlines = shouldHaveNewlines(elements, hasLeftNewline); if (hasLeftNewline && !needsNewlines) { context.report({ node: leftParen, messageId: "unexpectedAfter", fix(fixer) { var _context, _context2; return _trimInstanceProperty(_context = _sliceInstanceProperty(_context2 = sourceCode.getText()).call(_context2, leftParen.range[1], tokenAfterLeftParen.range[0])).call(_context) ? null : fixer.removeRange([leftParen.range[1], tokenAfterLeftParen.range[0]]); } }); } else if (!hasLeftNewline && needsNewlines) { context.report({ node: leftParen, messageId: "expectedAfter", fix: fixer => fixer.insertTextAfter(leftParen, "\n") }); } if (hasRightNewline && !needsNewlines) { context.report({ node: rightParen, messageId: "unexpectedBefore", fix(fixer) { var _context3, _context4; return _trimInstanceProperty(_context3 = _sliceInstanceProperty(_context4 = sourceCode.getText()).call(_context4, tokenBeforeRightParen.range[1], rightParen.range[0])).call(_context3) ? null : fixer.removeRange([tokenBeforeRightParen.range[1], rightParen.range[0]]); } }); } else if (!hasRightNewline && needsNewlines) { context.report({ node: rightParen, messageId: "expectedBefore", fix: fixer => fixer.insertTextBefore(rightParen, "\n") }); } } function validateArguments(parens, elements) { const leftParen = parens.leftParen; const tokenAfterLeftParen = sourceCode.getTokenAfter(leftParen); const hasLeftNewline = !utils.isTokenOnSameLine(leftParen, tokenAfterLeftParen); const needsNewlines = shouldHaveNewlines(elements, hasLeftNewline); for (let i = 0; i <= elements.length - 2; i++) { const currentElement = elements[i]; const nextElement = elements[i + 1]; const hasNewLine = currentElement.loc.end.line !== nextElement.loc.start.line; if (!hasNewLine && needsNewlines) { context.report({ node: currentElement, messageId: "expectedBetween", fix: fixer => fixer.insertTextBefore(nextElement, "\n") }); } } } function getParenTokens(node) { const isOpeningParenTokenOutsideTypeParameter = () => { let typeParameterOpeningLevel = 0; return token => { if (token.type === "Punctuator" && token.value === "<") typeParameterOpeningLevel += 1; if (token.type === "Punctuator" && token.value === ">") typeParameterOpeningLevel -= 1; return typeParameterOpeningLevel !== 0 ? false : utils.isOpeningParenToken(token); }; }; switch (node.type) { case "NewExpression": if (!node.arguments.length && !(utils.isOpeningParenToken(sourceCode.getLastToken(node, { skip: 1 })) && utils.isClosingParenToken(sourceCode.getLastToken(node)) && node.callee.range[1] < node.range[1])) { return null; } // falls through case "CallExpression": return { leftParen: sourceCode.getTokenAfter(node.callee, isOpeningParenTokenOutsideTypeParameter()), rightParen: sourceCode.getLastToken(node) }; case "FunctionDeclaration": case "FunctionExpression": { const leftParen = sourceCode.getFirstToken(node, isOpeningParenTokenOutsideTypeParameter()); const rightParen = node.params.length ? sourceCode.getTokenAfter(node.params[node.params.length - 1], utils.isClosingParenToken) : sourceCode.getTokenAfter(leftParen); return { leftParen, rightParen }; } case "ArrowFunctionExpression": { const firstToken = sourceCode.getFirstToken(node, { skip: node.async ? 1 : 0 }); if (!utils.isOpeningParenToken(firstToken)) { return null; } const rightParen = node.params.length ? sourceCode.getTokenAfter(node.params[node.params.length - 1], utils.isClosingParenToken) : sourceCode.getTokenAfter(firstToken); return { leftParen: firstToken, rightParen }; } case "ImportExpression": { const leftParen = sourceCode.getFirstToken(node, 1); const rightParen = sourceCode.getLastToken(node); return { leftParen, rightParen }; } default: throw new TypeError(`unexpected node with type ${node.type}`); } } return { [["ArrowFunctionExpression", "CallExpression", "FunctionDeclaration", "FunctionExpression", "ImportExpression", "NewExpression"].join(", ")](node) { const parens = getParenTokens(node); let params; if (node.type === "ImportExpression") params = [node.source, ...(node.options ? [node.options] : [])];else if (utils.isFunction(node)) params = node.params;else params = node.arguments; if (parens) { validateParens(parens, params); if (multilineArgumentsOption) validateArguments(parens, params); } } }; } }); module.exports = functionParenNewline;