From ba1b2c64fc2d3ec8169a81e9398354bcfb131025 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20=C5=81opaci=C5=84ski?= Date: Sun, 28 Apr 2024 15:21:37 +0200 Subject: [PATCH 1/6] Adjust all rules and utils --- lib/rules/boolean-prop-naming.js | 7 +-- lib/rules/destructuring-assignment.js | 13 ++--- lib/rules/forbid-elements.js | 5 +- lib/rules/forbid-prop-types.js | 10 ++-- lib/rules/function-component-definition.js | 3 +- lib/rules/hook-use-state.js | 48 ++++++++++++------- lib/rules/jsx-closing-bracket-location.js | 11 +++-- lib/rules/jsx-curly-brace-presence.js | 12 +++-- lib/rules/jsx-curly-newline.js | 3 +- lib/rules/jsx-curly-spacing.js | 13 ++--- lib/rules/jsx-equals-spacing.js | 3 +- lib/rules/jsx-fragments.js | 11 +++-- lib/rules/jsx-handler-names.js | 9 +++- lib/rules/jsx-indent-props.js | 6 ++- lib/rules/jsx-indent.js | 22 +++++---- lib/rules/jsx-key.js | 3 +- lib/rules/jsx-max-depth.js | 2 +- lib/rules/jsx-max-props-per-line.js | 5 +- lib/rules/jsx-newline.js | 3 +- lib/rules/jsx-no-bind.js | 3 +- lib/rules/jsx-no-comment-textnodes.js | 3 +- .../jsx-no-constructed-context-values.js | 3 +- lib/rules/jsx-no-leaked-render.js | 3 +- lib/rules/jsx-no-literals.js | 3 +- lib/rules/jsx-no-undef.js | 5 +- lib/rules/jsx-no-useless-fragment.js | 7 ++- lib/rules/jsx-one-expression-per-line.js | 11 +++-- lib/rules/jsx-props-no-multi-spaces.js | 12 +++-- lib/rules/jsx-sort-default-props.js | 14 ++++-- lib/rules/jsx-sort-props.js | 5 +- lib/rules/jsx-space-before-closing.js | 3 +- lib/rules/jsx-tag-spacing.js | 9 ++-- lib/rules/jsx-uses-react.js | 9 ++-- lib/rules/jsx-uses-vars.js | 3 +- lib/rules/jsx-wrap-multilines.js | 7 +-- lib/rules/no-access-state-in-setstate.js | 14 ++++-- lib/rules/no-array-index-key.js | 2 +- lib/rules/no-arrow-function-lifecycle.js | 3 +- lib/rules/no-danger-with-children.js | 12 +++-- lib/rules/no-deprecated.js | 3 +- lib/rules/no-is-mounted.js | 3 +- lib/rules/no-string-refs.js | 7 +-- lib/rules/no-unescaped-entities.js | 5 +- lib/rules/no-unknown-property.js | 3 +- lib/rules/no-unused-state.js | 7 ++- lib/rules/prefer-exact-props.js | 5 +- lib/rules/prefer-stateless-function.js | 5 +- lib/rules/react-in-jsx-scope.js | 2 +- lib/rules/require-optimization.js | 11 +++-- lib/rules/require-render-return.js | 3 +- lib/rules/sort-default-props.js | 14 ++++-- lib/rules/sort-prop-types.js | 9 ++-- lib/rules/state-in-constructor.js | 6 +-- lib/rules/static-property-placement.js | 13 +++-- lib/rules/style-prop-object.js | 4 +- lib/util/Components.js | 31 +++++++----- lib/util/ast.js | 12 +++-- lib/util/componentUtil.js | 19 ++++---- lib/util/defaultProps.js | 13 +++-- lib/util/eslint.js | 27 +++++++++++ lib/util/isCreateElement.js | 2 +- lib/util/isDestructuredFromPragmaImport.js | 5 +- lib/util/jsx.js | 2 +- lib/util/makeNoMethodSetStateRule.js | 3 +- lib/util/pragma.js | 4 +- lib/util/propTypes.js | 14 +++--- lib/util/propTypesSort.js | 5 +- lib/util/usedPropTypes.js | 40 +++++++++++----- lib/util/variable.js | 11 +++-- package.json | 2 +- 70 files changed, 392 insertions(+), 218 deletions(-) create mode 100644 lib/util/eslint.js diff --git a/lib/rules/boolean-prop-naming.js b/lib/rules/boolean-prop-naming.js index 173b154354..670ec3ad10 100644 --- a/lib/rules/boolean-prop-naming.js +++ b/lib/rules/boolean-prop-naming.js @@ -13,6 +13,7 @@ const propsUtil = require('../util/props'); const docsUrl = require('../util/docsUrl'); const propWrapperUtil = require('../util/propWrapper'); const report = require('../util/report'); +const { getSourceCode } = require('../util/eslint'); // ------------------------------------------------------------------------------ // Rule Definition @@ -115,7 +116,7 @@ module.exports = { // we can't get the name of the Flow object key name. So we have // to hack around it for now. if (node.type === 'ObjectTypeProperty') { - return context.getSourceCode().getFirstToken(node).value; + return getSourceCode(context).getFirstToken(node).value; } return node.key.name; @@ -308,7 +309,7 @@ module.exports = { && node.value.type === 'CallExpression' && propWrapperUtil.isPropWrapperFunction( context, - context.getSourceCode().getText(node.value.callee) + getSourceCode(context).getText(node.value.callee) ) ) { checkPropWrapperArguments(node, node.value.arguments); @@ -334,7 +335,7 @@ module.exports = { right.type === 'CallExpression' && propWrapperUtil.isPropWrapperFunction( context, - context.getSourceCode().getText(right.callee) + getSourceCode(context).getText(right.callee) ) ) { checkPropWrapperArguments(component.node, right.arguments); diff --git a/lib/rules/destructuring-assignment.js b/lib/rules/destructuring-assignment.js index e1a98d30a5..777872743a 100644 --- a/lib/rules/destructuring-assignment.js +++ b/lib/rules/destructuring-assignment.js @@ -6,6 +6,7 @@ const Components = require('../util/Components'); const docsUrl = require('../util/docsUrl'); +const { getScope, getSourceCode } = require('../util/eslint'); const isAssignmentLHS = require('../util/ast').isAssignmentLHS; const report = require('../util/report'); @@ -102,7 +103,7 @@ module.exports = { function handleStatelessComponent(node) { const params = evalParams(node.params); - const SFCComponent = components.get(context.getScope(node).block); + const SFCComponent = components.get(getScope(node, context).block); if (!SFCComponent) { return; } @@ -120,7 +121,7 @@ module.exports = { } function handleStatelessComponentExit(node) { - const SFCComponent = components.get(context.getScope(node).block); + const SFCComponent = components.get(getScope(node, context).block); if (SFCComponent) { sfcParams.pop(); } @@ -192,7 +193,7 @@ module.exports = { 'FunctionExpression:exit': handleStatelessComponentExit, MemberExpression(node) { - let scope = context.getScope(node); + let scope = getScope(node, context); let SFCComponent = components.get(scope.block); while (!SFCComponent && scope.upper && scope.upper !== scope) { SFCComponent = components.get(scope.upper.block); @@ -210,7 +211,7 @@ module.exports = { VariableDeclarator(node) { const classComponent = utils.getParentComponent(node); - const SFCComponent = components.get(context.getScope(node).block); + const SFCComponent = components.get(getScope(node, context).block); const destructuring = (node.init && node.id && node.id.type === 'ObjectPattern'); // let {foo} = props; @@ -248,7 +249,7 @@ module.exports = { && destructureInSignature === 'always' && node.init.name === 'props' ) { - const scopeSetProps = context.getScope().set.get('props'); + const scopeSetProps = getScope(node, context).set.get('props'); const propsRefs = scopeSetProps && scopeSetProps.references; if (!propsRefs) { return; @@ -269,7 +270,7 @@ module.exports = { param.typeAnnotation ? param.typeAnnotation.range[0] : param.range[1], ]; return [ - fixer.replaceTextRange(replaceRange, context.getSourceCode().getText(node.id)), + fixer.replaceTextRange(replaceRange, getSourceCode(context).getText(node.id)), fixer.remove(node.parent), ]; }, diff --git a/lib/rules/forbid-elements.js b/lib/rules/forbid-elements.js index c7f978a164..d9f182c2ae 100644 --- a/lib/rules/forbid-elements.js +++ b/lib/rules/forbid-elements.js @@ -7,6 +7,7 @@ const has = require('object.hasown/polyfill')(); const docsUrl = require('../util/docsUrl'); +const { getSourceCode } = require('../util/eslint'); const isCreateElement = require('../util/isCreateElement'); const report = require('../util/report'); @@ -90,7 +91,7 @@ module.exports = { return { JSXOpeningElement(node) { - reportIfForbidden(context.getSourceCode().getText(node.name), node.name); + reportIfForbidden(getSourceCode(context).getText(node.name), node.name); }, CallExpression(node) { @@ -110,7 +111,7 @@ module.exports = { } else if (argType === 'Literal' && /^[a-z][^.]*$/.test(argument.value)) { reportIfForbidden(argument.value, argument); } else if (argType === 'MemberExpression') { - reportIfForbidden(context.getSourceCode().getText(argument), argument); + reportIfForbidden(getSourceCode(context).getText(argument), argument); } }, }; diff --git a/lib/rules/forbid-prop-types.js b/lib/rules/forbid-prop-types.js index 92f0f0f51f..25a77cbc5c 100644 --- a/lib/rules/forbid-prop-types.js +++ b/lib/rules/forbid-prop-types.js @@ -10,6 +10,7 @@ const astUtil = require('../util/ast'); const docsUrl = require('../util/docsUrl'); const propWrapperUtil = require('../util/propWrapper'); const report = require('../util/report'); +const { getSourceCode } = require('../util/eslint'); // ------------------------------------------------------------------------------ // Constants @@ -162,7 +163,7 @@ module.exports = { checkProperties(node.properties); break; case 'Identifier': { - const propTypesObject = variableUtil.findVariableByName(context, node.name); + const propTypesObject = variableUtil.findVariableByName(node, context, node.name); if (propTypesObject && propTypesObject.properties) { checkProperties(propTypesObject.properties); } @@ -171,8 +172,11 @@ module.exports = { case 'CallExpression': { const innerNode = node.arguments && node.arguments[0]; if ( - propWrapperUtil.isPropWrapperFunction(context, context.getSourceCode().getText(node.callee)) - && innerNode + propWrapperUtil.isPropWrapperFunction( + context, + getSourceCode(context).getText(node.callee) + ) && + innerNode ) { checkNode(innerNode); } diff --git a/lib/rules/function-component-definition.js b/lib/rules/function-component-definition.js index 43e3154873..c378c0740f 100644 --- a/lib/rules/function-component-definition.js +++ b/lib/rules/function-component-definition.js @@ -9,6 +9,7 @@ const arrayIncludes = require('array-includes'); const Components = require('../util/Components'); const docsUrl = require('../util/docsUrl'); const reportC = require('../util/report'); +const { getSourceCode } = require('../util/eslint'); // ------------------------------------------------------------------------------ // Rule Definition @@ -181,7 +182,7 @@ module.exports = { ); function getFixer(node, options) { - const sourceCode = context.getSourceCode(); + const sourceCode = getSourceCode(context); const source = sourceCode.getText(); const typeAnnotation = getTypeAnnotation(node, source); diff --git a/lib/rules/hook-use-state.js b/lib/rules/hook-use-state.js index a9deed4fd6..8414b41e57 100644 --- a/lib/rules/hook-use-state.js +++ b/lib/rules/hook-use-state.js @@ -154,24 +154,36 @@ module.exports = { useMemoCode = 'useMemo'; } - suggestions.unshift(Object.assign( - getMessageData('suggestMemo', messages.suggestMemo), - { - fix: (fixer) => [ - // Add useMemo import, if necessary - useStateReactImportSpecifier - && (!useMemoReactImportSpecifier || defaultReactImportName) - && fixer.insertTextAfter(useStateReactImportSpecifier, ', useMemo'), - // Convert single-value destructure to simple assignment - fixer.replaceTextRange(node.parent.id.range, valueVariableName), - // Convert useState call to useMemo + arrow function + dependency array - fixer.replaceTextRange( - node.range, - `${useMemoCode}(() => ${context.getSourceCode().getText(node.arguments[0])}, [])` - ), - ].filter(Boolean), - } - )); + suggestions.unshift( + Object.assign( + getMessageData('suggestMemo', messages.suggestMemo), + { + fix: (fixer) => + [ + // Add useMemo import, if necessary + useStateReactImportSpecifier && + (!useMemoReactImportSpecifier || + defaultReactImportName) && + fixer.insertTextAfter( + useStateReactImportSpecifier, + ', useMemo' + ), + // Convert single-value destructure to simple assignment + fixer.replaceTextRange( + node.parent.id.range, + valueVariableName + ), + // Convert useState call to useMemo + arrow function + dependency array + fixer.replaceTextRange( + node.range, + `${useMemoCode}(() => ${getSourceCode(context).getText( + node.arguments[0] + )}, [])` + ), + ].filter(Boolean), + } + ) + ); } if (isOnlyValueDestructuring) { diff --git a/lib/rules/jsx-closing-bracket-location.js b/lib/rules/jsx-closing-bracket-location.js index 4816fd0068..56da37c814 100644 --- a/lib/rules/jsx-closing-bracket-location.js +++ b/lib/rules/jsx-closing-bracket-location.js @@ -7,6 +7,7 @@ const has = require('object.hasown/polyfill')(); const docsUrl = require('../util/docsUrl'); +const { getSourceCode } = require('../util/eslint'); const report = require('../util/report'); // ------------------------------------------------------------------------------ @@ -170,11 +171,15 @@ module.exports = { let spaces = []; switch (expectedLocation) { case 'props-aligned': - indentation = /^\s*/.exec(context.getSourceCode().lines[tokens.lastProp.firstLine - 1])[0]; + indentation = /^\s*/.exec( + getSourceCode(context).lines[tokens.lastProp.firstLine - 1] + )[0]; break; case 'tag-aligned': case 'line-aligned': - indentation = /^\s*/.exec(context.getSourceCode().lines[tokens.opening.line - 1])[0]; + indentation = /^\s*/.exec( + getSourceCode(context).lines[tokens.opening.line - 1] + )[0]; break; default: indentation = ''; @@ -194,7 +199,7 @@ module.exports = { * prop and start of opening line. */ function getTokensLocations(node) { - const sourceCode = context.getSourceCode(); + const sourceCode = getSourceCode(context); const opening = sourceCode.getFirstToken(node).loc.start; const closing = sourceCode.getLastTokens(node, node.selfClosing ? 2 : 1)[0].loc.start; const tag = sourceCode.getFirstToken(node.name).loc.start; diff --git a/lib/rules/jsx-curly-brace-presence.js b/lib/rules/jsx-curly-brace-presence.js index 3eac3b47ea..7923b09587 100755 --- a/lib/rules/jsx-curly-brace-presence.js +++ b/lib/rules/jsx-curly-brace-presence.js @@ -11,6 +11,7 @@ const arrayIncludes = require('array-includes'); const docsUrl = require('../util/docsUrl'); const jsxUtil = require('../util/jsx'); const report = require('../util/report'); +const { getSourceCode } = require('../util/eslint'); // ------------------------------------------------------------------------------ // Constants @@ -176,7 +177,7 @@ module.exports = { let textToReplace; if (jsxUtil.isJSX(expression)) { - const sourceCode = context.getSourceCode(); + const sourceCode = getSourceCode(context); textToReplace = sourceCode.getText(expression); } else { const expressionType = expression && expression.type; @@ -188,7 +189,7 @@ module.exports = { : expression.raw.slice(1, -1) }"`; } else if (jsxUtil.isJSX(expression)) { - const sourceCode = context.getSourceCode(); + const sourceCode = getSourceCode(context); textToReplace = sourceCode.getText(expression); } else { @@ -207,7 +208,10 @@ module.exports = { node: literalNode, fix(fixer) { if (jsxUtil.isJSX(literalNode)) { - return fixer.replaceText(literalNode, `{${context.getSourceCode().getText(literalNode)}}`); + return fixer.replaceText( + literalNode, + `{${getSourceCode(context).getText(literalNode)}}` + ); } // If a HTML entity name is found, bail out because it can be fixed @@ -251,7 +255,7 @@ module.exports = { const expression = JSXExpressionNode.expression; const expressionType = expression.type; - const sourceCode = context.getSourceCode(); + const sourceCode = getSourceCode(context); // Curly braces containing comments are necessary if (sourceCode.getCommentsInside && sourceCode.getCommentsInside(JSXExpressionNode).length > 0) { return; diff --git a/lib/rules/jsx-curly-newline.js b/lib/rules/jsx-curly-newline.js index 068a7103da..ca33a68ca1 100644 --- a/lib/rules/jsx-curly-newline.js +++ b/lib/rules/jsx-curly-newline.js @@ -5,6 +5,7 @@ 'use strict'; const docsUrl = require('../util/docsUrl'); +const { getSourceCode } = require('../util/eslint'); const report = require('../util/report'); // ------------------------------------------------------------------------------ @@ -77,7 +78,7 @@ module.exports = { }, create(context) { - const sourceCode = context.getSourceCode(); + const sourceCode = getSourceCode(context); const option = getNormalizedOption(context); // ---------------------------------------------------------------------- diff --git a/lib/rules/jsx-curly-spacing.js b/lib/rules/jsx-curly-spacing.js index 094e612c7d..9675dc74af 100644 --- a/lib/rules/jsx-curly-spacing.js +++ b/lib/rules/jsx-curly-spacing.js @@ -13,6 +13,7 @@ const has = require('object.hasown/polyfill')(); const docsUrl = require('../util/docsUrl'); +const { getSourceCode } = require('../util/eslint'); const report = require('../util/report'); // ------------------------------------------------------------------------------ @@ -175,7 +176,7 @@ module.exports = { * @returns {Object|*|{range, text}} */ function fixByTrimmingWhitespace(fixer, fromLoc, toLoc, mode, spacing) { - let replacementText = context.getSourceCode().text.slice(fromLoc, toLoc); + let replacementText = getSourceCode(context).text.slice(fromLoc, toLoc); if (mode === 'start') { replacementText = replacementText.replace(/^\s+/gm, ''); } else { @@ -206,7 +207,7 @@ module.exports = { token: token.value, }, fix(fixer) { - const nextToken = context.getSourceCode().getTokenAfter(token); + const nextToken = getSourceCode(context).getTokenAfter(token); return fixByTrimmingWhitespace(fixer, token.range[1], nextToken.range[0], 'start', spacing); }, }); @@ -227,7 +228,7 @@ module.exports = { token: token.value, }, fix(fixer) { - const previousToken = context.getSourceCode().getTokenBefore(token); + const previousToken = getSourceCode(context).getTokenBefore(token); return fixByTrimmingWhitespace(fixer, previousToken.range[1], token.range[0], 'end', spacing); }, }); @@ -247,7 +248,7 @@ module.exports = { token: token.value, }, fix(fixer) { - const sourceCode = context.getSourceCode(); + const sourceCode = getSourceCode(context); const nextToken = sourceCode.getTokenAfter(token); let nextComment; @@ -284,7 +285,7 @@ module.exports = { token: token.value, }, fix(fixer) { - const sourceCode = context.getSourceCode(); + const sourceCode = getSourceCode(context); const previousToken = sourceCode.getTokenBefore(token); let previousComment; @@ -370,7 +371,7 @@ module.exports = { return; } - const sourceCode = context.getSourceCode(); + const sourceCode = getSourceCode(context); const first = sourceCode.getFirstToken(node); const last = sourceCode.getLastToken(node); let second = sourceCode.getTokenAfter(first, { includeComments: true }); diff --git a/lib/rules/jsx-equals-spacing.js b/lib/rules/jsx-equals-spacing.js index e5eefd2bb5..9da25b2859 100644 --- a/lib/rules/jsx-equals-spacing.js +++ b/lib/rules/jsx-equals-spacing.js @@ -6,6 +6,7 @@ 'use strict'; const docsUrl = require('../util/docsUrl'); +const { getSourceCode } = require('../util/eslint'); const report = require('../util/report'); // ------------------------------------------------------------------------------ @@ -59,7 +60,7 @@ module.exports = { return; } - const sourceCode = context.getSourceCode(); + const sourceCode = getSourceCode(context); const equalToken = sourceCode.getTokenAfter(attrNode.name); const spacedBefore = sourceCode.isSpaceBetweenTokens(attrNode.name, equalToken); const spacedAfter = sourceCode.isSpaceBetweenTokens(equalToken, attrNode.value); diff --git a/lib/rules/jsx-fragments.js b/lib/rules/jsx-fragments.js index 38b4dd8b4b..1b18774172 100644 --- a/lib/rules/jsx-fragments.js +++ b/lib/rules/jsx-fragments.js @@ -11,6 +11,7 @@ const variableUtil = require('../util/variable'); const testReactVersion = require('../util/version').testReactVersion; const docsUrl = require('../util/docsUrl'); const report = require('../util/report'); +const { getSourceCode } = require('../util/eslint'); // ------------------------------------------------------------------------------ // Rule Definition @@ -65,7 +66,7 @@ module.exports = { } function getFixerToLong(jsxFragment) { - const sourceCode = context.getSourceCode(); + const sourceCode = getSourceCode(context); if (!jsxFragment.closingFragment || !jsxFragment.openingFragment) { // the old TS parser crashes here // TODO: FIXME: can we fake these two descriptors? @@ -83,7 +84,7 @@ module.exports = { } function getFixerToShort(jsxElement) { - const sourceCode = context.getSourceCode(); + const sourceCode = getSourceCode(context); return function fix(fixer) { let source = sourceCode.getText(); let lengthDiff; @@ -103,8 +104,8 @@ module.exports = { }; } - function refersToReactFragment(name) { - const variableInit = variableUtil.findVariableByName(context, name); + function refersToReactFragment(node, name) { + const variableInit = variableUtil.findVariableByName(node, context, name); if (!variableInit) { return false; } @@ -185,7 +186,7 @@ module.exports = { const openingEl = node.openingElement; const elName = elementType(openingEl); - if (fragmentNames.has(elName) || refersToReactFragment(elName)) { + if (fragmentNames.has(elName) || refersToReactFragment(node, elName)) { if (reportOnReactVersion(node)) { return; } diff --git a/lib/rules/jsx-handler-names.js b/lib/rules/jsx-handler-names.js index 8ff56fb47a..7652232640 100644 --- a/lib/rules/jsx-handler-names.js +++ b/lib/rules/jsx-handler-names.js @@ -6,6 +6,7 @@ 'use strict'; const docsUrl = require('../util/docsUrl'); +const { getSourceCode } = require('../util/eslint'); const report = require('../util/report'); // ------------------------------------------------------------------------------ @@ -129,8 +130,12 @@ module.exports = { const propKey = typeof node.name === 'object' ? node.name.name : node.name; const expression = node.value.expression; - const propValue = context.getSourceCode() - .getText(checkInlineFunction && isInlineHandler(node) ? expression.body.callee : expression) + const propValue = getSourceCode(context) + .getText( + checkInlineFunction && isInlineHandler(node) + ? expression.body.callee + : expression + ) .replace(/\s*/g, '') .replace(/^this\.|.*::/, ''); diff --git a/lib/rules/jsx-indent-props.js b/lib/rules/jsx-indent-props.js index 0d971ac7ac..aa7dfb4a55 100644 --- a/lib/rules/jsx-indent-props.js +++ b/lib/rules/jsx-indent-props.js @@ -32,6 +32,7 @@ const astUtil = require('../util/ast'); const docsUrl = require('../util/docsUrl'); +const { getSourceCode } = require('../util/eslint'); const reportC = require('../util/report'); // ------------------------------------------------------------------------------ @@ -140,7 +141,10 @@ module.exports = { * @return {Number} Indent */ function getNodeIndent(node) { - let src = context.getSourceCode().getText(node, node.loc.start.column + extraColumnStart); + let src = getSourceCode(context).getText( + node, + node.loc.start.column + extraColumnStart + ); const lines = src.split('\n'); src = lines[0]; diff --git a/lib/rules/jsx-indent.js b/lib/rules/jsx-indent.js index 9a86e6c03a..01a390bdce 100644 --- a/lib/rules/jsx-indent.js +++ b/lib/rules/jsx-indent.js @@ -36,6 +36,7 @@ const astUtil = require('../util/ast'); const docsUrl = require('../util/docsUrl'); const reportC = require('../util/report'); const jsxUtil = require('../util/jsx'); +const { getSourceCode } = require('../util/eslint'); // ------------------------------------------------------------------------------ // Rule Definition @@ -116,7 +117,7 @@ module.exports = { } if (node.type === 'ReturnStatement') { - const raw = context.getSourceCode().getText(node); + const raw = getSourceCode(context).getText(node); const lines = raw.split('\n'); if (lines.length > 1) { return function fix(fixer) { @@ -168,7 +169,10 @@ module.exports = { * @return {Number} Indent */ function getNodeIndent(node, byLastLine, excludeCommas) { - let src = context.getSourceCode().getText(node, node.loc.start.column + extraColumnStart); + let src = getSourceCode(context).getText( + node, + node.loc.start.column + extraColumnStart + ); const lines = src.split('\n'); if (byLastLine) { src = lines[lines.length - 1]; @@ -211,11 +215,11 @@ module.exports = { */ function isAlternateInConditionalExp(node) { return ( - node.parent - && node.parent.parent - && node.parent.parent.type === 'ConditionalExpression' - && node.parent.parent.alternate === node.parent - && context.getSourceCode().getTokenBefore(node).value !== '(' + node.parent && + node.parent.parent && + node.parent.parent.type === 'ConditionalExpression' && + node.parent.parent.alternate === node.parent && + getSourceCode(context).getTokenBefore(node).value !== '(' ); } @@ -334,7 +338,7 @@ module.exports = { } function handleOpeningElement(node) { - const sourceCode = context.getSourceCode(); + const sourceCode = getSourceCode(context); let prevToken = sourceCode.getTokenBefore(node); if (!prevToken) { return; @@ -377,7 +381,7 @@ module.exports = { return; } const nameIndent = getNodeIndent(node.name); - const lastToken = context.getSourceCode().getLastToken(node.value); + const lastToken = getSourceCode(context).getLastToken(node.value); const firstInLine = astUtil.getFirstNodeInLine(context, lastToken); const indent = node.name.loc.start.line === firstInLine.loc.start.line ? 0 : nameIndent; checkNodesIndent(firstInLine, indent); diff --git a/lib/rules/jsx-key.js b/lib/rules/jsx-key.js index 7ea874d0ae..b8d69136f0 100644 --- a/lib/rules/jsx-key.js +++ b/lib/rules/jsx-key.js @@ -12,6 +12,7 @@ const docsUrl = require('../util/docsUrl'); const pragmaUtil = require('../util/pragma'); const report = require('../util/report'); const astUtil = require('../util/ast'); +const { getSourceCode } = require('../util/eslint'); // ------------------------------------------------------------------------------ // Rule Definition @@ -213,7 +214,7 @@ module.exports = { } } else { keys.forEach((attr) => { - const value = context.getSourceCode().getText(attr.value); + const value = getSourceCode(context).getText(attr.value); if (!map[value]) { map[value] = []; } map[value].push(attr); diff --git a/lib/rules/jsx-max-depth.js b/lib/rules/jsx-max-depth.js index 01698264c7..29d17c2ba0 100644 --- a/lib/rules/jsx-max-depth.js +++ b/lib/rules/jsx-max-depth.js @@ -150,7 +150,7 @@ module.exports = { return; } - const variables = variableUtil.variablesInScope(context); + const variables = variableUtil.variablesInScope(node, context); const element = findJSXElementOrFragment(variables, node.expression.name, []); if (element) { diff --git a/lib/rules/jsx-max-props-per-line.js b/lib/rules/jsx-max-props-per-line.js index 95d7942f9a..5c78e2f5c7 100644 --- a/lib/rules/jsx-max-props-per-line.js +++ b/lib/rules/jsx-max-props-per-line.js @@ -6,11 +6,12 @@ 'use strict'; const docsUrl = require('../util/docsUrl'); +const { getSourceCode } = require('../util/eslint'); const report = require('../util/report'); function getPropName(context, propNode) { if (propNode.type === 'JSXSpreadAttribute') { - return context.getSourceCode().getText(propNode.argument); + return getSourceCode(context).getText(propNode.argument); } return propNode.name.name; } @@ -87,7 +88,7 @@ module.exports = { }; function generateFixFunction(line, max) { - const sourceCode = context.getSourceCode(); + const sourceCode = getSourceCode(context); const output = []; const front = line[0].range[0]; const back = line[line.length - 1].range[1]; diff --git a/lib/rules/jsx-newline.js b/lib/rules/jsx-newline.js index 966bf6a34b..304be8d11b 100644 --- a/lib/rules/jsx-newline.js +++ b/lib/rules/jsx-newline.js @@ -7,6 +7,7 @@ 'use strict'; const docsUrl = require('../util/docsUrl'); +const { getSourceCode } = require('../util/eslint'); const report = require('../util/report'); // ------------------------------------------------------------------------------ @@ -71,7 +72,7 @@ module.exports = { }, create(context) { const jsxElementParents = new Set(); - const sourceCode = context.getSourceCode(); + const sourceCode = getSourceCode(context); function isBlockCommentInCurlyBraces(element) { const elementRawValue = sourceCode.getText(element); diff --git a/lib/rules/jsx-no-bind.js b/lib/rules/jsx-no-bind.js index 17e56e2e04..b282f87bea 100644 --- a/lib/rules/jsx-no-bind.js +++ b/lib/rules/jsx-no-bind.js @@ -11,6 +11,7 @@ const propName = require('jsx-ast-utils/propName'); const docsUrl = require('../util/docsUrl'); const jsxUtil = require('../util/jsx'); const report = require('../util/report'); +const { getAncestors } = require('../util/eslint'); // ----------------------------------------------------------------------------- // Rule Definition @@ -123,7 +124,7 @@ module.exports = { } function getBlockStatementAncestors(node) { - return context.getAncestors(node).filter( + return getAncestors(node, context).filter( (ancestor) => ancestor.type === 'BlockStatement' ).reverse(); } diff --git a/lib/rules/jsx-no-comment-textnodes.js b/lib/rules/jsx-no-comment-textnodes.js index 2a90467d3f..1430f3b5ad 100644 --- a/lib/rules/jsx-no-comment-textnodes.js +++ b/lib/rules/jsx-no-comment-textnodes.js @@ -6,6 +6,7 @@ 'use strict'; const docsUrl = require('../util/docsUrl'); +const { getSourceCode } = require('../util/eslint'); const report = require('../util/report'); // ------------------------------------------------------------------------------ @@ -18,7 +19,7 @@ const messages = { function checkText(node, context) { // since babel-eslint has the wrong node.raw, we'll get the source text - const rawValue = context.getSourceCode().getText(node); + const rawValue = getSourceCode(context).getText(node); if (/^\s*\/(\/|\*)/m.test(rawValue)) { // inside component, e.g.
literal
if ( diff --git a/lib/rules/jsx-no-constructed-context-values.js b/lib/rules/jsx-no-constructed-context-values.js index f28c51fd4a..ec52a6568f 100644 --- a/lib/rules/jsx-no-constructed-context-values.js +++ b/lib/rules/jsx-no-constructed-context-values.js @@ -8,6 +8,7 @@ const Components = require('../util/Components'); const docsUrl = require('../util/docsUrl'); +const { getScope } = require('../util/eslint'); const report = require('../util/report'); // ------------------------------------------------------------------------------ @@ -180,7 +181,7 @@ module.exports = { } const valueExpression = valueNode.expression; - const invocationScope = context.getScope(); + const invocationScope = getScope(node, context); // Check if the value prop is a construction const constructInfo = isConstruction(valueExpression, invocationScope); diff --git a/lib/rules/jsx-no-leaked-render.js b/lib/rules/jsx-no-leaked-render.js index a6bf54b72a..2b3d0af2b1 100644 --- a/lib/rules/jsx-no-leaked-render.js +++ b/lib/rules/jsx-no-leaked-render.js @@ -10,6 +10,7 @@ const from = require('es-iterator-helpers/Iterator.from'); const docsUrl = require('../util/docsUrl'); const report = require('../util/report'); +const { getSourceCode } = require('../util/eslint'); const testReactVersion = require('../util/version').testReactVersion; const isParenthesized = require('../util/ast').isParenthesized; @@ -54,7 +55,7 @@ function extractExpressionBetweenLogicalAnds(node) { } function ruleFixer(context, fixStrategy, fixer, reportedNode, leftNode, rightNode) { - const sourceCode = context.getSourceCode(); + const sourceCode = getSourceCode(context); const rightSideText = sourceCode.getText(rightNode); if (fixStrategy === COERCE_STRATEGY) { diff --git a/lib/rules/jsx-no-literals.js b/lib/rules/jsx-no-literals.js index ca4f3a8d46..5003626a9f 100644 --- a/lib/rules/jsx-no-literals.js +++ b/lib/rules/jsx-no-literals.js @@ -11,6 +11,7 @@ const map = require('es-iterator-helpers/Iterator.prototype.map'); const docsUrl = require('../util/docsUrl'); const report = require('../util/report'); +const { getSourceCode } = require('../util/eslint'); // ------------------------------------------------------------------------------ // Rule Definition @@ -149,7 +150,7 @@ module.exports = { report(context, messages[messageId], messageId, { node, data: { - text: context.getSourceCode().getText(node).trim(), + text: getSourceCode(context).getText(node).trim(), }, }); } diff --git a/lib/rules/jsx-no-undef.js b/lib/rules/jsx-no-undef.js index 3a1f4dbc5f..bb45df8f97 100644 --- a/lib/rules/jsx-no-undef.js +++ b/lib/rules/jsx-no-undef.js @@ -6,6 +6,7 @@ 'use strict'; const docsUrl = require('../util/docsUrl'); +const { getScope, getSourceCode } = require('../util/eslint'); const jsxUtil = require('../util/jsx'); const report = require('../util/report'); @@ -50,8 +51,8 @@ module.exports = { * @returns {void} */ function checkIdentifierInJSX(node) { - let scope = context.getScope(); - const sourceCode = context.getSourceCode(); + let scope = getScope(node, context); + const sourceCode = getSourceCode(context); const sourceType = sourceCode.ast.sourceType; const scopeUpperBound = !allowGlobals && sourceType === 'module' ? 'module' : 'global'; let variables = scope.variables; diff --git a/lib/rules/jsx-no-useless-fragment.js b/lib/rules/jsx-no-useless-fragment.js index 303b9719e5..5444ae74e8 100644 --- a/lib/rules/jsx-no-useless-fragment.js +++ b/lib/rules/jsx-no-useless-fragment.js @@ -10,6 +10,7 @@ const pragmaUtil = require('../util/pragma'); const jsxUtil = require('../util/jsx'); const docsUrl = require('../util/docsUrl'); const report = require('../util/report'); +const { getSourceCode } = require('../util/eslint'); function isJSXText(node) { return !!node && (node.type === 'JSXText' || node.type === 'Literal'); @@ -216,7 +217,11 @@ module.exports = { const opener = node.type === 'JSXFragment' ? node.openingFragment : node.openingElement; const closer = node.type === 'JSXFragment' ? node.closingFragment : node.closingElement; - const childrenText = opener.selfClosing ? '' : context.getSourceCode().getText().slice(opener.range[1], closer.range[0]); + const childrenText = opener.selfClosing + ? '' + : getSourceCode(context) + .getText() + .slice(opener.range[1], closer.range[0]); return fixer.replaceText(node, trimLikeReact(childrenText)); }; diff --git a/lib/rules/jsx-one-expression-per-line.js b/lib/rules/jsx-one-expression-per-line.js index f18fa919e1..f9409d1a90 100644 --- a/lib/rules/jsx-one-expression-per-line.js +++ b/lib/rules/jsx-one-expression-per-line.js @@ -6,6 +6,7 @@ 'use strict'; const docsUrl = require('../util/docsUrl'); +const { getSourceCode } = require('../util/eslint'); const jsxUtil = require('../util/jsx'); const report = require('../util/report'); @@ -56,7 +57,9 @@ module.exports = { } function nodeDescriptor(n) { - return n.openingElement ? n.openingElement.name.name : context.getSourceCode().getText(n).replace(/\n/g, ''); + return n.openingElement + ? n.openingElement.name.name + : getSourceCode(context).getText(n).replace(/\n/g, ''); } function handleJSX(node) { @@ -163,20 +166,20 @@ module.exports = { function spaceBetweenPrev() { return ((prevChild.type === 'Literal' || prevChild.type === 'JSXText') && / $/.test(prevChild.raw)) || ((child.type === 'Literal' || child.type === 'JSXText') && /^ /.test(child.raw)) - || context.getSourceCode().isSpaceBetweenTokens(prevChild, child); + || getSourceCode(context).isSpaceBetweenTokens(prevChild, child) } function spaceBetweenNext() { return ((nextChild.type === 'Literal' || nextChild.type === 'JSXText') && /^ /.test(nextChild.raw)) || ((child.type === 'Literal' || child.type === 'JSXText') && / $/.test(child.raw)) - || context.getSourceCode().isSpaceBetweenTokens(child, nextChild); + || getSourceCode(context).isSpaceBetweenTokens(child, nextChild); } if (!prevChild && !nextChild) { return; } - const source = context.getSourceCode().getText(child); + const source = getSourceCode(context).getText(child); const leadingSpace = !!(prevChild && spaceBetweenPrev()); const trailingSpace = !!(nextChild && spaceBetweenNext()); const leadingNewLine = !!prevChild; diff --git a/lib/rules/jsx-props-no-multi-spaces.js b/lib/rules/jsx-props-no-multi-spaces.js index edd122c413..0ca17bd68e 100644 --- a/lib/rules/jsx-props-no-multi-spaces.js +++ b/lib/rules/jsx-props-no-multi-spaces.js @@ -6,6 +6,7 @@ 'use strict'; const docsUrl = require('../util/docsUrl'); +const { getSourceCode } = require('../util/eslint'); const report = require('../util/report'); // ------------------------------------------------------------------------------ @@ -34,12 +35,12 @@ module.exports = { }, create(context) { - const sourceCode = context.getSourceCode(); + const sourceCode = getSourceCode(context); function getPropName(propNode) { switch (propNode.type) { case 'JSXSpreadAttribute': - return context.getSourceCode().getText(propNode.argument); + return sourceCode.getText(propNode.argument); case 'JSXIdentifier': return propNode.name; case 'JSXMemberExpression': @@ -47,7 +48,7 @@ module.exports = { default: return propNode.name ? propNode.name.name - : `${context.getSourceCode().getText(propNode.object)}.${propNode.property.name}`; // needed for typescript-eslint parser + : `${sourceCode.getText(propNode.object)}.${propNode.property.name}`; // needed for typescript-eslint parser } } @@ -82,7 +83,10 @@ module.exports = { return; } - const between = context.getSourceCode().text.slice(prev.range[1], node.range[0]); + const between = getSourceCode(context).text.slice( + prev.range[1], + node.range[0] + ); if (between !== ' ') { report(context, messages.onlyOneSpace, 'onlyOneSpace', { diff --git a/lib/rules/jsx-sort-default-props.js b/lib/rules/jsx-sort-default-props.js index f35e40dc5f..7fcff990eb 100644 --- a/lib/rules/jsx-sort-default-props.js +++ b/lib/rules/jsx-sort-default-props.js @@ -10,6 +10,7 @@ const variableUtil = require('../util/variable'); const docsUrl = require('../util/docsUrl'); const report = require('../util/report'); const log = require('../util/log'); +const { getSourceCode } = require('../util/eslint'); let isWarnedForDeprecation = false; @@ -65,7 +66,7 @@ module.exports = { // (babel-eslint@5 does not expose property name so we have to rely on tokens) } if (node.type === 'ClassProperty') { - const tokens = context.getSourceCode().getFirstTokens(node, 2); + const tokens = getSourceCode(context).getFirstTokens(node, 2); return tokens[1] && tokens[1].type === 'Identifier' ? tokens[1].value : tokens[0].value; } return ''; @@ -82,16 +83,19 @@ module.exports = { } function getKey(node) { - return context.getSourceCode().getText(node.key || node.argument); + return getSourceCode(context).getText(node.key || node.argument); } /** * Find a variable by name in the current scope. + * @param {ASTNode} node The node to look for. * @param {string} name Name of the variable to look for. * @returns {ASTNode|null} Return null if the variable could not be found, ASTNode otherwise. */ - function findVariableByName(name) { - const variable = variableUtil.variablesInScope(context).find((item) => item.name === name); + function findVariableByName(node, name) { + const variable = variableUtil + .variablesInScope(node, context) + .find((item) => item.name === name); if (!variable || !variable.defs[0] || !variable.defs[0].node) { return null; @@ -147,7 +151,7 @@ module.exports = { if (node.type === 'ObjectExpression') { checkSorted(node.properties); } else if (node.type === 'Identifier') { - const propTypesObject = findVariableByName(node.name); + const propTypesObject = findVariableByName(node, node.name); if (propTypesObject && propTypesObject.properties) { checkSorted(propTypesObject.properties); } diff --git a/lib/rules/jsx-sort-props.js b/lib/rules/jsx-sort-props.js index 3ca1724ebe..7a975d9818 100644 --- a/lib/rules/jsx-sort-props.js +++ b/lib/rules/jsx-sort-props.js @@ -12,6 +12,7 @@ const toSorted = require('array.prototype.tosorted'); const docsUrl = require('../util/docsUrl'); const jsxUtil = require('../util/jsx'); const report = require('../util/report'); +const { getSourceCode } = require('../util/eslint'); // ------------------------------------------------------------------------------ // Rule Definition @@ -141,7 +142,7 @@ function contextCompare(a, b, options) { * @return {Array>} */ function getGroupsOfSortableAttributes(attributes, context) { - const sourceCode = context.getSourceCode(); + const sourceCode = getSourceCode(context); const sortableAttributeGroups = []; let groupCount = 0; @@ -212,7 +213,7 @@ function getGroupsOfSortableAttributes(attributes, context) { } function generateFixerFunction(node, context, reservedList) { - const sourceCode = context.getSourceCode(); + const sourceCode = getSourceCode(context); const attributes = node.attributes.slice(0); const configuration = context.options[0] || {}; const ignoreCase = configuration.ignoreCase || false; diff --git a/lib/rules/jsx-space-before-closing.js b/lib/rules/jsx-space-before-closing.js index f1e1e61d96..9fbb13a776 100644 --- a/lib/rules/jsx-space-before-closing.js +++ b/lib/rules/jsx-space-before-closing.js @@ -10,6 +10,7 @@ const getTokenBeforeClosingBracket = require('../util/getTokenBeforeClosingBrack const docsUrl = require('../util/docsUrl'); const log = require('../util/log'); const report = require('../util/report'); +const { getSourceCode } = require('../util/eslint'); let isWarnedForDeprecation = false; @@ -54,7 +55,7 @@ module.exports = { return; } - const sourceCode = context.getSourceCode(); + const sourceCode = getSourceCode(context); const leftToken = getTokenBeforeClosingBracket(node); const closingSlash = sourceCode.getTokenAfter(leftToken); diff --git a/lib/rules/jsx-tag-spacing.js b/lib/rules/jsx-tag-spacing.js index 9cc18e8c37..a0ace6bb0f 100644 --- a/lib/rules/jsx-tag-spacing.js +++ b/lib/rules/jsx-tag-spacing.js @@ -8,6 +8,7 @@ const getTokenBeforeClosingBracket = require('../util/getTokenBeforeClosingBracket'); const docsUrl = require('../util/docsUrl'); const report = require('../util/report'); +const { getSourceCode } = require('../util/eslint'); const messages = { selfCloseSlashNoSpace: 'Whitespace is forbidden between `/` and `>`; write `/>`', @@ -29,7 +30,7 @@ const messages = { // ------------------------------------------------------------------------------ function validateClosingSlash(context, node, option) { - const sourceCode = context.getSourceCode(); + const sourceCode = getSourceCode(context); let adjacent; @@ -97,7 +98,7 @@ function validateClosingSlash(context, node, option) { } function validateBeforeSelfClosing(context, node, option) { - const sourceCode = context.getSourceCode(); + const sourceCode = getSourceCode(context); const leftToken = getTokenBeforeClosingBracket(node); const closingSlash = sourceCode.getTokenAfter(leftToken); @@ -141,7 +142,7 @@ function validateBeforeSelfClosing(context, node, option) { } function validateAfterOpening(context, node, option) { - const sourceCode = context.getSourceCode(); + const sourceCode = getSourceCode(context); const openingToken = sourceCode.getTokenBefore(node.name); if (option === 'allow-multiline') { @@ -182,7 +183,7 @@ function validateAfterOpening(context, node, option) { function validateBeforeClosing(context, node, option) { // Don't enforce this rule for self closing tags if (!node.selfClosing) { - const sourceCode = context.getSourceCode(); + const sourceCode = getSourceCode(context); const leftToken = option === 'proportional-always' ? getTokenBeforeClosingBracket(node) : sourceCode.getLastTokens(node, 2)[0]; diff --git a/lib/rules/jsx-uses-react.js b/lib/rules/jsx-uses-react.js index bf06f508f8..ee5946bcb7 100644 --- a/lib/rules/jsx-uses-react.js +++ b/lib/rules/jsx-uses-react.js @@ -7,6 +7,7 @@ const pragmaUtil = require('../util/pragma'); const docsUrl = require('../util/docsUrl'); +const { markVariableAsUsed } = require('../util/eslint'); // ------------------------------------------------------------------------------ // Rule Definition @@ -29,8 +30,8 @@ module.exports = { const pragma = pragmaUtil.getFromContext(context); const fragment = pragmaUtil.getFragmentFromContext(context); - function handleOpeningElement() { - context.markVariableAsUsed(pragma); + function handleOpeningElement(node) { + markVariableAsUsed(pragma, node, context); } // -------------------------------------------------------------------------- // Public @@ -39,8 +40,8 @@ module.exports = { return { JSXOpeningElement: handleOpeningElement, JSXOpeningFragment: handleOpeningElement, - JSXFragment() { - context.markVariableAsUsed(fragment); + JSXFragment(node) { + markVariableAsUsed(fragment, node, context); }, }; }, diff --git a/lib/rules/jsx-uses-vars.js b/lib/rules/jsx-uses-vars.js index 9ea9ab001e..a3ad2c2abf 100644 --- a/lib/rules/jsx-uses-vars.js +++ b/lib/rules/jsx-uses-vars.js @@ -6,6 +6,7 @@ 'use strict'; const docsUrl = require('../util/docsUrl'); +const { markVariableAsUsed } = require('../util/eslint'); // ------------------------------------------------------------------------------ // Rule Definition @@ -53,7 +54,7 @@ module.exports = { return; } - context.markVariableAsUsed(name); + markVariableAsUsed(name, node, context); }, }; diff --git a/lib/rules/jsx-wrap-multilines.js b/lib/rules/jsx-wrap-multilines.js index 59fa5f294b..4d1cd8c23d 100644 --- a/lib/rules/jsx-wrap-multilines.js +++ b/lib/rules/jsx-wrap-multilines.js @@ -7,6 +7,7 @@ const has = require('object.hasown/polyfill')(); const docsUrl = require('../util/docsUrl'); +const { getSourceCode } = require('../util/eslint'); const jsxUtil = require('../util/jsx'); const reportC = require('../util/report'); const isParenthesized = require('../util/ast').isParenthesized; @@ -93,7 +94,7 @@ module.exports = { } function needsOpeningNewLine(node) { - const previousToken = context.getSourceCode().getTokenBefore(node); + const previousToken = getSourceCode(context).getTokenBefore(node); if (!isParenthesized(context, node)) { return false; @@ -107,7 +108,7 @@ module.exports = { } function needsClosingNewLine(node) { - const nextToken = context.getSourceCode().getTokenAfter(node); + const nextToken = getSourceCode(context).getTokenAfter(node); if (!isParenthesized(context, node)) { return false; @@ -143,7 +144,7 @@ module.exports = { return; } - const sourceCode = context.getSourceCode(); + const sourceCode = getSourceCode(context); const option = getOption(type); if ((option === true || option === 'parens') && !isParenthesized(context, node) && isMultilines(node)) { diff --git a/lib/rules/no-access-state-in-setstate.js b/lib/rules/no-access-state-in-setstate.js index 89d4976077..1696eb2843 100644 --- a/lib/rules/no-access-state-in-setstate.js +++ b/lib/rules/no-access-state-in-setstate.js @@ -8,6 +8,7 @@ const docsUrl = require('../util/docsUrl'); const componentUtil = require('../util/componentUtil'); const report = require('../util/report'); +const { getScope } = require('../util/eslint'); // ------------------------------------------------------------------------------ // Rule Definition @@ -47,8 +48,11 @@ module.exports = { return current.arguments[0] === node; } - function isClassComponent() { - return !!(componentUtil.getParentES6Component(context) || componentUtil.getParentES5Component(context)); + function isClassComponent(node) { + return !!( + componentUtil.getParentES6Component(node, context) || + componentUtil.getParentES5Component(node, context) + ); } // The methods array contains all methods or functions that are using this.state @@ -134,7 +138,7 @@ module.exports = { if (current.type === 'VariableDeclarator') { vars.push({ node, - scope: context.getScope(), + scope: getScope(node, context), variableName: current.id.name, }); break; @@ -158,7 +162,7 @@ module.exports = { while (current.type !== 'Program') { if (isFirstArgumentInSetStateCall(current, node)) { vars - .filter((v) => v.scope === context.getScope() && v.variableName === node.name) + .filter((v) => v.scope === getScope(node, context) && v.variableName === node.name) .forEach((v) => { report(context, messages.useCallback, 'useCallback', { node: v.node, @@ -176,7 +180,7 @@ module.exports = { if (property && property.key && property.key.name === 'state' && isDerivedFromThis) { vars.push({ node: property.key, - scope: context.getScope(), + scope: getScope(node, context), variableName: property.key.name, }); } diff --git a/lib/rules/no-array-index-key.js b/lib/rules/no-array-index-key.js index bc8c91f9ef..1ee946694b 100644 --- a/lib/rules/no-array-index-key.js +++ b/lib/rules/no-array-index-key.js @@ -28,7 +28,7 @@ function isCreateCloneElement(node, context) { } if (node.type === 'Identifier') { - const variable = variableUtil.findVariableByName(context, node.name); + const variable = variableUtil.findVariableByName(node, context, node.name); if (variable && variable.type === 'ImportSpecifier') { return variable.parent.source.value === 'react'; } diff --git a/lib/rules/no-arrow-function-lifecycle.js b/lib/rules/no-arrow-function-lifecycle.js index a1de789b81..d04c74cc7c 100644 --- a/lib/rules/no-arrow-function-lifecycle.js +++ b/lib/rules/no-arrow-function-lifecycle.js @@ -13,6 +13,7 @@ const componentUtil = require('../util/componentUtil'); const docsUrl = require('../util/docsUrl'); const lifecycleMethods = require('../util/lifecycleMethods'); const report = require('../util/report'); +const { getSourceCode } = require('../util/eslint'); function getText(node) { const params = node.value.params.map((p) => p.name); @@ -67,7 +68,7 @@ module.exports = { if (nodeType === 'ArrowFunctionExpression' && isLifecycleMethod) { const body = node.value.body; const isBlockBody = body.type === 'BlockStatement'; - const sourceCode = context.getSourceCode(); + const sourceCode = getSourceCode(context); let nextComment = []; let previousComment = []; diff --git a/lib/rules/no-danger-with-children.js b/lib/rules/no-danger-with-children.js index 17d55930ff..477e81b489 100644 --- a/lib/rules/no-danger-with-children.js +++ b/lib/rules/no-danger-with-children.js @@ -31,8 +31,10 @@ module.exports = { schema: [], // no options }, create(context) { - function findSpreadVariable(name) { - return variableUtil.variablesInScope(context).find((item) => item.name === name); + function findSpreadVariable(node, name) { + return variableUtil + .variablesInScope(node, context) + .find((item) => item.name === name); } /** * Takes a ObjectExpression and returns the value of the prop if it has it @@ -50,7 +52,7 @@ module.exports = { return prop.key.name === propName; } if (prop.type === 'ExperimentalSpreadProperty' || prop.type === 'SpreadElement') { - const variable = findSpreadVariable(prop.argument.name); + const variable = findSpreadVariable(node, prop.argument.name); if (variable && variable.defs.length && variable.defs[0].node.init) { if (seenProps.indexOf(prop.argument.name) > -1) { return false; @@ -73,7 +75,7 @@ module.exports = { const attributes = node.openingElement.attributes; return attributes.find((attribute) => { if (attribute.type === 'JSXSpreadAttribute') { - const variable = findSpreadVariable(attribute.argument.name); + const variable = findSpreadVariable(node, attribute.argument.name); if (variable && variable.defs.length && variable.defs[0].node.init) { return findObjectProp(variable.defs[0].node.init, propName, []); } @@ -127,7 +129,7 @@ module.exports = { let props = node.arguments[1]; if (props.type === 'Identifier') { - const variable = variableUtil.variablesInScope(context).find((item) => item.name === props.name); + const variable = variableUtil.variablesInScope(node, context).find((item) => item.name === props.name); if (variable && variable.defs.length && variable.defs[0].node.init) { props = variable.defs[0].node.init; } diff --git a/lib/rules/no-deprecated.js b/lib/rules/no-deprecated.js index d37b55bbfd..612dc62f7e 100644 --- a/lib/rules/no-deprecated.js +++ b/lib/rules/no-deprecated.js @@ -14,6 +14,7 @@ const docsUrl = require('../util/docsUrl'); const pragmaUtil = require('../util/pragma'); const testReactVersion = require('../util/version').testReactVersion; const report = require('../util/report'); +const { getSourceCode } = require('../util/eslint'); // ------------------------------------------------------------------------------ // Constants @@ -217,7 +218,7 @@ module.exports = { return { MemberExpression(node) { - checkDeprecation(node, context.getSourceCode().getText(node)); + checkDeprecation(node, getSourceCode(context).getText(node)); }, ImportDeclaration(node) { diff --git a/lib/rules/no-is-mounted.js b/lib/rules/no-is-mounted.js index c15b6e81a4..f5fe4b5896 100644 --- a/lib/rules/no-is-mounted.js +++ b/lib/rules/no-is-mounted.js @@ -6,6 +6,7 @@ 'use strict'; const docsUrl = require('../util/docsUrl'); +const { getAncestors } = require('../util/eslint'); const report = require('../util/report'); // ------------------------------------------------------------------------------ @@ -40,7 +41,7 @@ module.exports = { if (callee.object.type !== 'ThisExpression' || callee.property.name !== 'isMounted') { return; } - const ancestors = context.getAncestors(callee); + const ancestors = getAncestors(node, context); for (let i = 0, j = ancestors.length; i < j; i++) { if (ancestors[i].type === 'Property' || ancestors[i].type === 'MethodDefinition') { report(context, messages.noIsMounted, 'noIsMounted', { diff --git a/lib/rules/no-string-refs.js b/lib/rules/no-string-refs.js index 466a214579..700b5fc6ad 100644 --- a/lib/rules/no-string-refs.js +++ b/lib/rules/no-string-refs.js @@ -50,9 +50,10 @@ module.exports = { */ function isRefsUsage(node) { return !!( - (componentUtil.getParentES6Component(context) || componentUtil.getParentES5Component(context)) - && node.object.type === 'ThisExpression' - && node.property.name === 'refs' + (componentUtil.getParentES6Component(node, context) || + componentUtil.getParentES5Component(node, context)) && + node.object.type === 'ThisExpression' && + node.property.name === 'refs' ); } diff --git a/lib/rules/no-unescaped-entities.js b/lib/rules/no-unescaped-entities.js index a449ad5206..354008b5d5 100644 --- a/lib/rules/no-unescaped-entities.js +++ b/lib/rules/no-unescaped-entities.js @@ -6,6 +6,7 @@ 'use strict'; const docsUrl = require('../util/docsUrl'); +const { getSourceCode } = require('../util/eslint'); const jsxUtil = require('../util/jsx'); const report = require('../util/report'); @@ -83,9 +84,9 @@ module.exports = { const entities = configuration.forbid || DEFAULTS; // HTML entities are already escaped in node.value (as well as node.raw), - // so pull the raw text from context.getSourceCode() + // so pull the raw text from getSourceCode(context) for (let i = node.loc.start.line; i <= node.loc.end.line; i++) { - let rawLine = context.getSourceCode().lines[i - 1]; + let rawLine = getSourceCode(context).lines[i - 1]; let start = 0; let end = rawLine.length; if (i === node.loc.start.line) { diff --git a/lib/rules/no-unknown-property.js b/lib/rules/no-unknown-property.js index 9491f9c658..a9e7069c50 100644 --- a/lib/rules/no-unknown-property.js +++ b/lib/rules/no-unknown-property.js @@ -7,6 +7,7 @@ const has = require('object.hasown/polyfill')(); const docsUrl = require('../util/docsUrl'); +const { getSourceCode } = require('../util/eslint'); const testReactVersion = require('../util/version').testReactVersion; const report = require('../util/report'); @@ -555,7 +556,7 @@ module.exports = { return { JSXAttribute(node) { const ignoreNames = getIgnoreConfig(); - const actualName = context.getSourceCode().getText(node.name); + const actualName = getSourceCode(context).getText(node.name); if (ignoreNames.indexOf(actualName) >= 0) { return; } diff --git a/lib/rules/no-unused-state.js b/lib/rules/no-unused-state.js index 73a0e52163..69c8ce89dd 100644 --- a/lib/rules/no-unused-state.js +++ b/lib/rules/no-unused-state.js @@ -13,6 +13,7 @@ const docsUrl = require('../util/docsUrl'); const ast = require('../util/ast'); const componentUtil = require('../util/componentUtil'); const report = require('../util/report'); +const { getScope } = require('../util/eslint'); // Descend through all wrapping TypeCastExpressions and return the expression // that was cast. @@ -107,7 +108,7 @@ module.exports = { 'componentDidUpdate', ]; - let scope = context.getScope(); + let scope = getScope(node, context); while (scope) { const parent = scope.block && scope.block.parent; if ( @@ -368,7 +369,9 @@ module.exports = { return; } - const childScope = context.getScope().childScopes.find((x) => x.block === node.value); + const childScope = getScope(node, context).childScopes.find( + (x) => x.block === node.value + ); if (!childScope) { return; } diff --git a/lib/rules/prefer-exact-props.js b/lib/rules/prefer-exact-props.js index 4ad088e9ee..8143782ad7 100644 --- a/lib/rules/prefer-exact-props.js +++ b/lib/rules/prefer-exact-props.js @@ -10,6 +10,7 @@ const propsUtil = require('../util/props'); const propWrapperUtil = require('../util/propWrapper'); const variableUtil = require('../util/variable'); const report = require('../util/report'); +const { getSourceCode } = require('../util/eslint'); // ----------------------------------------------------------------------------- // Rule Definition @@ -36,7 +37,7 @@ module.exports = { create: Components.detect((context, components, utils) => { const typeAliases = {}; const exactWrappers = propWrapperUtil.getExactPropWrapperFunctions(context); - const sourceCode = context.getSourceCode(); + const sourceCode = getSourceCode(context); function getPropTypesErrorMessage() { const formattedWrappers = propWrapperUtil.formatPropWrapperFunctions(exactWrappers); @@ -149,7 +150,7 @@ module.exports = { reportPropTypesError(node); } else if (right.type === 'Identifier') { const identifier = right.name; - const propsDefinition = variableUtil.findVariableByName(context, identifier); + const propsDefinition = variableUtil.findVariableByName(node, context, identifier); if (isNonEmptyObjectExpression(propsDefinition)) { reportPropTypesError(node); } else if (isNonExactPropWrapperFunction(propsDefinition)) { diff --git a/lib/rules/prefer-stateless-function.js b/lib/rules/prefer-stateless-function.js index 07c435747f..25ff7923ba 100644 --- a/lib/rules/prefer-stateless-function.js +++ b/lib/rules/prefer-stateless-function.js @@ -15,6 +15,7 @@ const astUtil = require('../util/ast'); const componentUtil = require('../util/componentUtil'); const docsUrl = require('../util/docsUrl'); const report = require('../util/report'); +const { getScope, getSourceCode } = require('../util/eslint'); // ------------------------------------------------------------------------------ // Rule Definition @@ -332,7 +333,7 @@ module.exports = { // Mark `ref` usage JSXAttribute(node) { - const name = context.getSourceCode().getText(node.name); + const name = getSourceCode(context).getText(node.name); if (name !== 'ref') { return; } @@ -342,7 +343,7 @@ module.exports = { // Mark `render` that do not return some JSX ReturnStatement(node) { let blockNode; - let scope = context.getScope(); + let scope = getScope(node, context); while (scope) { blockNode = scope.block && scope.block.parent; if (blockNode && (blockNode.type === 'MethodDefinition' || blockNode.type === 'Property')) { diff --git a/lib/rules/react-in-jsx-scope.js b/lib/rules/react-in-jsx-scope.js index 1af398deae..9783605384 100644 --- a/lib/rules/react-in-jsx-scope.js +++ b/lib/rules/react-in-jsx-scope.js @@ -37,7 +37,7 @@ module.exports = { const pragma = pragmaUtil.getFromContext(context); function checkIfReactIsInScope(node) { - const variables = variableUtil.variablesInScope(context); + const variables = variableUtil.variablesInScope(node, context); if (variableUtil.findVariable(variables, pragma)) { return; } diff --git a/lib/rules/require-optimization.js b/lib/rules/require-optimization.js index 9d440b19ee..e3edb78296 100644 --- a/lib/rules/require-optimization.js +++ b/lib/rules/require-optimization.js @@ -11,6 +11,7 @@ const Components = require('../util/Components'); const componentUtil = require('../util/componentUtil'); const docsUrl = require('../util/docsUrl'); const report = require('../util/report'); +const { getScope } = require('../util/eslint'); const messages = { noShouldComponentUpdate: 'Component is not optimized. Please add a shouldComponentUpdate method.', @@ -156,9 +157,9 @@ module.exports = { * Checks if we are declaring function in class * @returns {Boolean} True if we are declaring function in class, false if not. */ - function isFunctionInClass() { + function isFunctionInClass(node) { let blockNode; - let scope = context.getScope(); + let scope = getScope(node, context); while (scope) { blockNode = scope.block; if (blockNode && blockNode.type === 'ClassDeclaration') { @@ -173,7 +174,7 @@ module.exports = { return { ArrowFunctionExpression(node) { // Skip if the function is declared in the class - if (isFunctionInClass()) { + if (isFunctionInClass(node)) { return; } // Stateless Functional Components cannot be optimized (yet) @@ -193,7 +194,7 @@ module.exports = { FunctionDeclaration(node) { // Skip if the function is declared in the class - if (isFunctionInClass()) { + if (isFunctionInClass(node)) { return; } // Stateless Functional Components cannot be optimized (yet) @@ -202,7 +203,7 @@ module.exports = { FunctionExpression(node) { // Skip if the function is declared in the class - if (isFunctionInClass()) { + if (isFunctionInClass(node)) { return; } // Stateless Functional Components cannot be optimized (yet) diff --git a/lib/rules/require-render-return.js b/lib/rules/require-render-return.js index d79c9406b7..c2ef52bb84 100644 --- a/lib/rules/require-render-return.js +++ b/lib/rules/require-render-return.js @@ -12,6 +12,7 @@ const astUtil = require('../util/ast'); const componentUtil = require('../util/componentUtil'); const docsUrl = require('../util/docsUrl'); const report = require('../util/report'); +const { getAncestors } = require('../util/eslint'); // ------------------------------------------------------------------------------ // Rule Definition @@ -61,7 +62,7 @@ module.exports = { return { ReturnStatement(node) { - const ancestors = context.getAncestors(node).reverse(); + const ancestors = getAncestors(node, context).reverse(); let depth = 0; ancestors.forEach((ancestor) => { if (/Function(Expression|Declaration)$/.test(ancestor.type)) { diff --git a/lib/rules/sort-default-props.js b/lib/rules/sort-default-props.js index aae419ba18..b0e2f373f1 100644 --- a/lib/rules/sort-default-props.js +++ b/lib/rules/sort-default-props.js @@ -9,6 +9,7 @@ const variableUtil = require('../util/variable'); const docsUrl = require('../util/docsUrl'); const report = require('../util/report'); +const { getSourceCode } = require('../util/eslint'); // ------------------------------------------------------------------------------ // Rule Definition @@ -60,7 +61,7 @@ module.exports = { // (babel-eslint@5 does not expose property name so we have to rely on tokens) } if (node.type === 'ClassProperty') { - const tokens = context.getSourceCode().getFirstTokens(node, 2); + const tokens = getSourceCode(context).getFirstTokens(node, 2); return tokens[1] && tokens[1].type === 'Identifier' ? tokens[1].value : tokens[0].value; } return ''; @@ -77,16 +78,19 @@ module.exports = { } function getKey(node) { - return context.getSourceCode().getText(node.key || node.argument); + return getSourceCode(context).getText(node.key || node.argument); } /** * Find a variable by name in the current scope. + * @param {ASTNode} node The node to look for. * @param {string} name Name of the variable to look for. * @returns {ASTNode|null} Return null if the variable could not be found, ASTNode otherwise. */ - function findVariableByName(name) { - const variable = variableUtil.variablesInScope(context).find((item) => item.name === name); + function findVariableByName(node, name) { + const variable = variableUtil + .variablesInScope(node, context) + .find((item) => item.name === name); if (!variable || !variable.defs[0] || !variable.defs[0].node) { return null; @@ -142,7 +146,7 @@ module.exports = { if (node.type === 'ObjectExpression') { checkSorted(node.properties); } else if (node.type === 'Identifier') { - const propTypesObject = findVariableByName(node.name); + const propTypesObject = findVariableByName(node, node.name); if (propTypesObject && propTypesObject.properties) { checkSorted(propTypesObject.properties); } diff --git a/lib/rules/sort-prop-types.js b/lib/rules/sort-prop-types.js index 8c3574af4a..fb77362cfd 100644 --- a/lib/rules/sort-prop-types.js +++ b/lib/rules/sort-prop-types.js @@ -10,6 +10,7 @@ const docsUrl = require('../util/docsUrl'); const propWrapperUtil = require('../util/propWrapper'); const propTypesSortUtil = require('../util/propTypesSort'); const report = require('../util/report'); +const { getSourceCode } = require('../util/eslint'); // ------------------------------------------------------------------------------ // Rule Definition @@ -23,12 +24,12 @@ const messages = { function getKey(context, node) { if (node.type === 'ObjectTypeProperty') { - return context.getSourceCode().getFirstToken(node).value; + return getSourceCode(context).getFirstToken(node).value; } if (node.key && node.key.value) { return node.key.value; } - return context.getSourceCode().getText(node.key || node.argument); + return getSourceCode(context).getText(node.key || node.argument); } function getValueName(node) { @@ -207,7 +208,7 @@ module.exports = { checkSorted(node.properties); break; case 'Identifier': { - const propTypesObject = variableUtil.findVariableByName(context, node.name); + const propTypesObject = variableUtil.findVariableByName(node, context, node.name); if (propTypesObject && propTypesObject.properties) { checkSorted(propTypesObject.properties); } @@ -260,7 +261,7 @@ module.exports = { if (firstArg.properties) { checkSorted(firstArg.properties); } else if (firstArg.type === 'Identifier') { - const variable = variableUtil.findVariableByName(context, firstArg.name); + const variable = variableUtil.findVariableByName(node, context, firstArg.name); if (variable && variable.properties) { checkSorted(variable.properties); } diff --git a/lib/rules/state-in-constructor.js b/lib/rules/state-in-constructor.js index c518b1713a..07f2a74d97 100644 --- a/lib/rules/state-in-constructor.js +++ b/lib/rules/state-in-constructor.js @@ -44,7 +44,7 @@ module.exports = { option === 'always' && !node.static && node.key.name === 'state' - && componentUtil.getParentES6Component(context) + && componentUtil.getParentES6Component(node, context) ) { report(context, messages.stateInitConstructor, 'stateInitConstructor', { node, @@ -55,8 +55,8 @@ module.exports = { if ( option === 'never' && componentUtil.isStateMemberExpression(node.left) - && astUtil.inConstructor(context) - && componentUtil.getParentES6Component(context) + && astUtil.inConstructor(node, context) + && componentUtil.getParentES6Component(node, context) ) { report(context, messages.stateInitClassProp, 'stateInitClassProp', { node, diff --git a/lib/rules/static-property-placement.js b/lib/rules/static-property-placement.js index efc50da3bd..17013f4d9e 100644 --- a/lib/rules/static-property-placement.js +++ b/lib/rules/static-property-placement.js @@ -12,6 +12,7 @@ const astUtil = require('../util/ast'); const componentUtil = require('../util/componentUtil'); const propsUtil = require('../util/props'); const report = require('../util/report'); +const { getScope } = require('../util/eslint'); // ------------------------------------------------------------------------------ // Positioning Options @@ -99,9 +100,9 @@ module.exports = { * Checks if we are declaring context in class * @returns {Boolean} True if we are declaring context in class, false if not. */ - function isContextInClass() { + function isContextInClass(node) { let blockNode; - let scope = context.getScope(); + let scope = getScope(node, context); while (scope) { blockNode = scope.block; if (blockNode && blockNode.type === 'ClassDeclaration') { @@ -149,7 +150,7 @@ module.exports = { // ---------------------------------------------------------------------- return { 'ClassProperty, PropertyDefinition'(node) { - if (!componentUtil.getParentES6Component(context)) { + if (!componentUtil.getParentES6Component(node, context)) { return; } @@ -178,7 +179,11 @@ module.exports = { MethodDefinition(node) { // If the function is inside a class and is static getter then check if correctly positioned - if (componentUtil.getParentES6Component(context) && node.static && node.kind === 'get') { + if ( + componentUtil.getParentES6Component(node, context) && + node.static && + node.kind === 'get' + ) { // Report error if needed reportNodeIncorrectlyPositioned(node, STATIC_GETTER); } diff --git a/lib/rules/style-prop-object.js b/lib/rules/style-prop-object.js index 4d6684a6f1..65be38c5d0 100644 --- a/lib/rules/style-prop-object.js +++ b/lib/rules/style-prop-object.js @@ -61,7 +61,9 @@ module.exports = { * @param {object} node A Identifier node */ function checkIdentifiers(node) { - const variable = variableUtil.variablesInScope(context).find((item) => item.name === node.name); + const variable = variableUtil + .variablesInScope(node, context) + .find((item) => item.name === node.name); if (!variable || !variable.defs[0] || !variable.defs[0].node.init) { return; diff --git a/lib/util/Components.js b/lib/util/Components.js index a31989702f..78e3b4c9f7 100644 --- a/lib/util/Components.js +++ b/lib/util/Components.js @@ -21,6 +21,7 @@ const usedPropTypesUtil = require('./usedPropTypes'); const defaultPropsUtil = require('./defaultProps'); const isFirstLetterCapitalized = require('./isFirstLetterCapitalized'); const isDestructuredFromPragmaImport = require('./isDestructuredFromPragmaImport'); +const { getScope, getSourceCode } = require('./eslint'); function getId(node) { return node ? `${node.range[0]}:${node.range[1]}` : ''; @@ -282,7 +283,7 @@ function mergeRules(rules) { function componentRule(rule, context) { const pragma = pragmaUtil.getFromContext(context); - const sourceCode = context.getSourceCode(); + const sourceCode = getSourceCode(context); const components = new Components(); const wrapperFunctions = getWrapperFunctions(context, pragma); @@ -291,11 +292,12 @@ function componentRule(rule, context) { /** * Check if variable is destructured from pragma import * + * @param (ASTNode) node The AST node to check * @param {string} variable The variable name to check * @returns {Boolean} True if createElement is destructured from the pragma */ - isDestructuredFromPragmaImport(variable) { - return isDestructuredFromPragmaImport(variable, context); + isDestructuredFromPragmaImport(ASTNode, variable) { + return isDestructuredFromPragmaImport(variable, ASTNode, context); }, isReturningJSX(ASTNode, strict) { @@ -412,7 +414,7 @@ function componentRule(rule, context) { return wrapperFunction.property === node.callee.name && (!wrapperFunction.object // Functions coming from the current pragma need special handling - || (wrapperFunction.object === pragma && this.isDestructuredFromPragmaImport(node.callee.name)) + || (wrapperFunction.object === pragma && this.isDestructuredFromPragmaImport(node, node.callee.name)) ); }); }, @@ -429,11 +431,11 @@ function componentRule(rule, context) { * * @returns {ASTNode} component node, null if we are not in a component */ - getParentComponent() { + getParentComponent(node) { return ( - componentUtil.getParentES6Component(context) - || componentUtil.getParentES5Component(context) - || utils.getParentStatelessComponent() + componentUtil.getParentES6Component(node, context) || + componentUtil.getParentES5Component(node, context) || + utils.getParentStatelessComponent(node) ); }, @@ -612,10 +614,11 @@ function componentRule(rule, context) { /** * Get the parent stateless component node from the current scope * + * @param {ASTNode} node The AST node being checked * @returns {ASTNode} component node, null if we are not in a component */ - getParentStatelessComponent() { - let scope = context.getScope(); + getParentStatelessComponent(node) { + let scope = getScope(node, context); while (scope) { const node = scope.block; const statelessComponent = utils.getStatelessComponent(node); @@ -659,7 +662,7 @@ function componentRule(rule, context) { return null; } let variableInScope; - const variables = variableUtil.variablesInScope(context); + const variables = variableUtil.variablesInScope(node, context); for (i = 0, j = variables.length; i < j; i++) { if (variables[i].name === variableName) { variableInScope = variables[i]; @@ -776,7 +779,9 @@ function componentRule(rule, context) { && node.callee.type === 'Identifier' && node.callee.name.match(USE_HOOK_PREFIX_REGEX); - const scope = (isPotentialReactHookCall || isPotentialHookCall) && context.getScope(); + const scope = + (isPotentialReactHookCall || isPotentialHookCall) && + getScope(node, context); const reactResolvedDefs = isPotentialReactHookCall && scope.references @@ -888,7 +893,7 @@ function componentRule(rule, context) { }, ThisExpression(node) { - const component = utils.getParentStatelessComponent(); + const component = utils.getParentStatelessComponent(node); if (!component || !/Function/.test(component.type) || !node.parent.property) { return; } diff --git a/lib/util/ast.js b/lib/util/ast.js index fd6019a3f2..e45abad271 100644 --- a/lib/util/ast.js +++ b/lib/util/ast.js @@ -5,6 +5,7 @@ 'use strict'; const estraverse = require('estraverse'); +const { getScope, getSourceCode } = require('./eslint'); // const pragmaUtil = require('./pragma'); /** @@ -186,7 +187,7 @@ function getComponentProperties(node) { * @return {ASTNode} the first node in the line */ function getFirstNodeInLine(context, node) { - const sourceCode = context.getSourceCode(); + const sourceCode = getSourceCode(context); let token = node; let lines; do { @@ -252,11 +253,12 @@ function isClass(node) { /** * Check if we are in a class constructor + * @param {ASTNode} node The AST node being checked. * @param {Context} context * @return {boolean} */ -function inConstructor(context) { - let scope = context.getScope(); +function inConstructor(node, context) { + let scope = getScope(node, context); while (scope) { // @ts-ignore if (scope.block && scope.block.parent && scope.block.parent.kind === 'constructor') { @@ -284,7 +286,7 @@ function stripQuotes(string) { */ function getKeyValue(context, node) { if (node.type === 'ObjectTypeProperty') { - const tokens = context.getSourceCode().getFirstTokens(node, 2); + const tokens = getSourceCode(context).getFirstTokens(node, 2); return (tokens[0].value === '+' || tokens[0].value === '-' ? tokens[1].value : stripQuotes(tokens[0].value) @@ -311,7 +313,7 @@ function getKeyValue(context, node) { * @returns {boolean} */ function isParenthesized(context, node) { - const sourceCode = context.getSourceCode(); + const sourceCode = getSourceCode(context); const previousToken = sourceCode.getTokenBefore(node); const nextToken = sourceCode.getTokenAfter(node); diff --git a/lib/util/componentUtil.js b/lib/util/componentUtil.js index 35d54edcc5..aabe452386 100644 --- a/lib/util/componentUtil.js +++ b/lib/util/componentUtil.js @@ -2,6 +2,7 @@ const doctrine = require('doctrine'); const pragmaUtil = require('./pragma'); +const { getScope, getSourceCode } = require('./eslint'); // eslint-disable-next-line valid-jsdoc /** @@ -57,7 +58,7 @@ function isES5Component(node, context) { * @returns {boolean} */ function isExplicitComponent(node, context) { - const sourceCode = context.getSourceCode(); + const sourceCode = getSourceCode(context); let comment; // Sometimes the passed node may not have been parsed yet by eslint, and this function call crashes. // Can be removed when eslint sets "parent" property for all nodes on initial AST traversal: https://github.com/eslint/eslint-scope/issues/27 @@ -115,14 +116,15 @@ function isES6Component(node, context) { /** * Get the parent ES5 component node from the current scope + * @param {ASTNode} node * @param {Context} context * @returns {ASTNode|null} */ -function getParentES5Component(context) { - let scope = context.getScope(); +function getParentES5Component(node, context) { + let scope = getScope(node, context); while (scope) { // @ts-ignore - const node = scope.block && scope.block.parent && scope.block.parent.parent; + node = scope.block && scope.block.parent && scope.block.parent.parent; if (node && isES5Component(node, context)) { return node; } @@ -133,15 +135,16 @@ function getParentES5Component(context) { /** * Get the parent ES6 component node from the current scope + * @param {ASTNode} node * @param {Context} context * @returns {ASTNode | null} */ -function getParentES6Component(context) { - let scope = context.getScope(); +function getParentES6Component(node, context) { + let scope = getScope(node, context); while (scope && scope.type !== 'class') { scope = scope.upper; } - const node = scope && scope.block; + node = scope && scope.block; if (!node || !isES6Component(node, context)) { return null; } @@ -156,7 +159,7 @@ function getParentES6Component(context) { */ function isPureComponent(node, context) { const pragma = getPragma(context); - const sourceCode = context.getSourceCode(); + const sourceCode = getSourceCode(context); if (node.superClass) { return new RegExp(`^(${pragma}\\.)?PureComponent$`).test(sourceCode.getText(node.superClass)); } diff --git a/lib/util/defaultProps.js b/lib/util/defaultProps.js index 44b42454ce..9d51c9b143 100644 --- a/lib/util/defaultProps.js +++ b/lib/util/defaultProps.js @@ -10,11 +10,12 @@ const componentUtil = require('./componentUtil'); const propsUtil = require('./props'); const variableUtil = require('./variable'); const propWrapperUtil = require('./propWrapper'); +const { getSourceCode } = require('./eslint'); const QUOTES_REGEX = /^["']|["']$/g; module.exports = function defaultPropsInstructions(context, components, utils) { - const sourceCode = context.getSourceCode(); + const sourceCode = getSourceCode(context); /** * Try to resolve the node passed in to a variable in the current scope. If the node passed in is not @@ -24,7 +25,7 @@ module.exports = function defaultPropsInstructions(context, components, utils) { */ function resolveNodeValue(node) { if (node.type === 'Identifier') { - return variableUtil.findVariableByName(context, node.name); + return variableUtil.findVariableByName(node, context, node.name); } if ( node.type === 'CallExpression' @@ -172,7 +173,9 @@ module.exports = function defaultPropsInstructions(context, components, utils) { } // find component this propTypes/defaultProps belongs to - const component = components.get(componentUtil.getParentES6Component(context)); + const component = components.get( + componentUtil.getParentES6Component(node, context) + ); if (!component) { return; } @@ -215,7 +218,9 @@ module.exports = function defaultPropsInstructions(context, components, utils) { } // find component this propTypes/defaultProps belongs to - const component = components.get(componentUtil.getParentES6Component(context)); + const component = components.get( + componentUtil.getParentES6Component(node, context) + ); if (!component) { return; } diff --git a/lib/util/eslint.js b/lib/util/eslint.js new file mode 100644 index 0000000000..4f1610df95 --- /dev/null +++ b/lib/util/eslint.js @@ -0,0 +1,27 @@ +function getSourceCode(context) { + return context.sourceCode ?? context.getSourceCode(); +} + +function getScope(node, context) { + const sourceCode = getSourceCode(context); + return sourceCode.getScope ? sourceCode.getScope(node) : context.getScope(); +} + +function getAncestors(node, context) { + const sourceCode = getSourceCode(context); + return sourceCode.getAncestors ? sourceCode.getAncestors(node) : context.getAncestors(); +} + +function markVariableAsUsed(name, node, context) { + const sourceCode = getSourceCode(context); + return sourceCode.markVariableAsUsed + ? sourceCode.markVariableAsUsed(name, node) + : context.markVariableAsUsed(name); +} + +module.exports = { + getSourceCode, + getScope, + getAncestors, + markVariableAsUsed, +}; diff --git a/lib/util/isCreateElement.js b/lib/util/isCreateElement.js index c28dc563fb..2d01c3fdb7 100644 --- a/lib/util/isCreateElement.js +++ b/lib/util/isCreateElement.js @@ -24,7 +24,7 @@ module.exports = function isCreateElement(node, context) { node && node.callee && node.callee.name === 'createElement' - && isDestructuredFromPragmaImport('createElement', context) + && isDestructuredFromPragmaImport('createElement', node, context) ) { return true; } diff --git a/lib/util/isDestructuredFromPragmaImport.js b/lib/util/isDestructuredFromPragmaImport.js index 6f8deb08bc..5f4941f15c 100644 --- a/lib/util/isDestructuredFromPragmaImport.js +++ b/lib/util/isDestructuredFromPragmaImport.js @@ -7,12 +7,13 @@ const variableUtil = require('./variable'); * Check if variable is destructured from pragma import * * @param {string} variable The variable name to check + * @param {ASTNode} node The AST node to check * @param {Context} context eslint context * @returns {Boolean} True if createElement is destructured from the pragma */ -module.exports = function isDestructuredFromPragmaImport(variable, context) { +module.exports = function isDestructuredFromPragmaImport(variable, node, context) { const pragma = pragmaUtil.getFromContext(context); - const variables = variableUtil.variablesInScope(context); + const variables = variableUtil.variablesInScope(node, context); const variableInScope = variableUtil.getVariable(variables, variable); if (variableInScope) { const latestDef = variableUtil.getLatestVariableDefinition(variableInScope); diff --git a/lib/util/jsx.js b/lib/util/jsx.js index 55073bfe1e..5ae02c0d09 100644 --- a/lib/util/jsx.js +++ b/lib/util/jsx.js @@ -121,7 +121,7 @@ function isReturningJSX(ASTnode, context, strict, ignoreNull) { } return false; case 'Identifier': { - const variable = variableUtil.findVariableByName(context, node.name); + const variable = variableUtil.findVariableByName(node, context, node.name); return isJSX(variable); } default: diff --git a/lib/util/makeNoMethodSetStateRule.js b/lib/util/makeNoMethodSetStateRule.js index 1225092802..4b1e8f54df 100644 --- a/lib/util/makeNoMethodSetStateRule.js +++ b/lib/util/makeNoMethodSetStateRule.js @@ -9,6 +9,7 @@ const findLast = require('array.prototype.findlast'); const docsUrl = require('./docsUrl'); const report = require('./report'); +const { getAncestors } = require('./eslint'); const testReactVersion = require('./version').testReactVersion; // ------------------------------------------------------------------------------ @@ -93,7 +94,7 @@ module.exports = function makeNoMethodSetStateRule(methodName, shouldCheckUnsafe ) { return; } - const ancestors = context.getAncestors(callee); + const ancestors = getAncestors(node, context); let depth = 0; findLast(ancestors, (ancestor) => { // ancestors.some((ancestor) => { diff --git a/lib/util/pragma.js b/lib/util/pragma.js index 2bde47fb37..49ed713d2a 100644 --- a/lib/util/pragma.js +++ b/lib/util/pragma.js @@ -5,6 +5,8 @@ 'use strict'; +const { getSourceCode } = require("./eslint"); + const JSX_ANNOTATION_REGEX = /@jsx\s+([^\s]+)/; // Does not check for reserved keywords or unicode characters const JS_IDENTIFIER_REGEX = /^[_$a-zA-Z][_$a-zA-Z0-9]*$/; @@ -48,7 +50,7 @@ function getFragmentFromContext(context) { function getFromContext(context) { let pragma = 'React'; - const sourceCode = context.getSourceCode(); + const sourceCode = getSourceCode(context); const pragmaNode = sourceCode.getAllComments().find((node) => JSX_ANNOTATION_REGEX.test(node.value)); if (pragmaNode) { diff --git a/lib/util/propTypes.js b/lib/util/propTypes.js index a189f871ca..95b4fa7758 100644 --- a/lib/util/propTypes.js +++ b/lib/util/propTypes.js @@ -13,6 +13,7 @@ const testFlowVersion = require('./version').testFlowVersion; const propWrapperUtil = require('./propWrapper'); const astUtil = require('./ast'); const isFirstLetterCapitalized = require('./isFirstLetterCapitalized'); +const { getScope, getSourceCode } = require('./eslint'); /** * Check if node is function type. @@ -368,7 +369,7 @@ module.exports = function propTypesInstructions(context, components, utils) { node && node.type === 'Identifier' ) { - const scope = context.getScope(); + const scope = getScope(node, context); const identVariable = scope.variableScope.variables.find( (variable) => variable.name === node.name ); @@ -578,7 +579,7 @@ module.exports = function propTypesInstructions(context, components, utils) { this.declaredPropTypes = declaredPropTypes; this.foundDeclaredPropertiesList = []; this.referenceNameMap = new Set(); - this.sourceCode = context.getSourceCode(); + this.sourceCode = getSourceCode(context); this.shouldIgnorePropTypes = false; this.visitTSNode(this.propTypes); this.endAndStructDeclaredPropTypes(); @@ -934,7 +935,7 @@ module.exports = function propTypesInstructions(context, components, utils) { break; } case 'Identifier': { - const variablesInScope = variableUtil.variablesInScope(context); + const variablesInScope = variableUtil.variablesInScope(node, context); const firstMatchingVariable = variablesInScope .find((variableInScope) => variableInScope.name === propTypes.name); if (firstMatchingVariable) { @@ -949,9 +950,10 @@ module.exports = function propTypesInstructions(context, components, utils) { if ( propWrapperUtil.isPropWrapperFunction( context, - context.getSourceCode().getText(propTypes.callee) - ) - && propTypes.arguments && propTypes.arguments[0] + getSourceCode(context).getText(propTypes.callee) + ) && + propTypes.arguments && + propTypes.arguments[0] ) { markPropTypesAsDeclared(node, propTypes.arguments[0]); return; diff --git a/lib/util/propTypesSort.js b/lib/util/propTypesSort.js index 505f346a3b..348fdd6968 100644 --- a/lib/util/propTypesSort.js +++ b/lib/util/propTypesSort.js @@ -7,6 +7,7 @@ const toSorted = require('array.prototype.tosorted'); const astUtil = require('./ast'); +const { getSourceCode } = require('./eslint'); /** * Returns the value name of a node. @@ -136,7 +137,7 @@ function fixPropTypesSort( ) { function sortInSource(allNodes, source) { const originalSource = source; - const sourceCode = context.getSourceCode(); + const sourceCode = getSourceCode(context); for (let i = 0; i < allNodes.length; i++) { const node = allNodes[i]; let commentAfter = []; @@ -199,7 +200,7 @@ function fixPropTypesSort( return source; } - const source = sortInSource(declarations, context.getSourceCode().getText()); + const source = sortInSource(declarations, getSourceCode(context).getText()); const rangeStart = commentnodeMap.get(declarations[0]).start; const rangeEnd = commentnodeMap.get(declarations[declarations.length - 1]).end; diff --git a/lib/util/usedPropTypes.js b/lib/util/usedPropTypes.js index 6a0a650333..b556898165 100644 --- a/lib/util/usedPropTypes.js +++ b/lib/util/usedPropTypes.js @@ -10,6 +10,7 @@ const astUtil = require('./ast'); const componentUtil = require('./componentUtil'); const testReactVersion = require('./version').testReactVersion; const ast = require('./ast'); +const { getScope, getSourceCode } = require('./eslint'); // ------------------------------------------------------------------------------ // Constants @@ -79,12 +80,13 @@ function mustBeValidated(component) { /** * Check if we are in a lifecycle method + * @param {ASTNode} node The AST node being checked. * @param {object} context * @param {boolean} checkAsyncSafeLifeCycles * @return {boolean} true if we are in a class constructor, false if not */ -function inLifeCycleMethod(context, checkAsyncSafeLifeCycles) { - let scope = context.getScope(); +function inLifeCycleMethod(node, context, checkAsyncSafeLifeCycles) { + let scope = getScope(node, context); while (scope) { if (scope.block && scope.block.parent && scope.block.parent.key) { const name = scope.block.parent.key.name; @@ -158,11 +160,11 @@ function isSetStateUpdater(node) { && node.parent.arguments[0] === node; } -function isPropArgumentInSetStateUpdater(context, name) { +function isPropArgumentInSetStateUpdater(node, context, name) { if (typeof name !== 'string') { return; } - let scope = context.getScope(); + let scope = getScope(node, context); while (scope) { const unwrappedParentCalleeNode = scope.block && scope.block.parent @@ -185,11 +187,15 @@ function isPropArgumentInSetStateUpdater(context, name) { } /** + * @param (ASTNode) node * @param {Context} context * @returns {boolean} */ -function isInClassComponent(context) { - return !!(componentUtil.getParentES6Component(context) || componentUtil.getParentES5Component(context)); +function isInClassComponent(node, context) { + return !!( + componentUtil.getParentES6Component(node, context) || + componentUtil.getParentES5Component(node, context) + ); } /** @@ -211,7 +217,7 @@ function isThisDotProps(node) { * @returns {Boolean} True if the prop has spread operator, false if not. */ function hasSpreadOperator(context, node) { - const tokens = context.getSourceCode().getTokens(node); + const tokens = getSourceCode(context).getTokens(node); return tokens.length && tokens[0].value === '...'; } @@ -226,20 +232,21 @@ function hasSpreadOperator(context, node) { function isPropTypesUsageByMemberExpression(node, context, utils, checkAsyncSafeLifeCycles) { const unwrappedObjectNode = ast.unwrapTSAsExpression(node.object); - if (isInClassComponent(context)) { + if (isInClassComponent(node, context)) { // this.props.* if (isThisDotProps(unwrappedObjectNode)) { return true; } // props.* or prevProps.* or nextProps.* if ( - isCommonVariableNameForProps(unwrappedObjectNode.name) - && (inLifeCycleMethod(context, checkAsyncSafeLifeCycles) || astUtil.inConstructor(context)) + isCommonVariableNameForProps(unwrappedObjectNode.name) && + (inLifeCycleMethod(node, context, checkAsyncSafeLifeCycles) || + astUtil.inConstructor(node, context)) ) { return true; } // this.setState((_, props) => props.*)) - if (isPropArgumentInSetStateUpdater(context, unwrappedObjectNode.name)) { + if (isPropArgumentInSetStateUpdater(node, context, unwrappedObjectNode.name)) { return true; } return false; @@ -472,7 +479,11 @@ module.exports = function usedPropTypesInstructions(context, components, utils) const unwrappedInitNode = ast.unwrapTSAsExpression(node.init); // let props = this.props - if (isThisDotProps(unwrappedInitNode) && isInClassComponent(context) && node.id.type === 'Identifier') { + if ( + isThisDotProps(unwrappedInitNode) && + isInClassComponent(node, context) && + node.id.type === 'Identifier' + ) { propVariables.set(node.id.name, []); } @@ -508,7 +519,10 @@ module.exports = function usedPropTypesInstructions(context, components, utils) } // let {firstname} = this.props - if (isThisDotProps(unwrappedInitNode) && isInClassComponent(context)) { + if ( + isThisDotProps(unwrappedInitNode) && + isInClassComponent(node, context) + ) { markPropTypesAsUsed(node.id); return; } diff --git a/lib/util/variable.js b/lib/util/variable.js index a93cf18b5e..3704fc1da1 100644 --- a/lib/util/variable.js +++ b/lib/util/variable.js @@ -6,6 +6,7 @@ 'use strict'; const toReversed = require('array.prototype.toreversed'); +const { getScope } = require('./eslint'); /** * Search a particular variable in a list @@ -32,11 +33,12 @@ function getVariable(variables, name) { * * Contain a patch for babel-eslint to avoid https://github.com/babel/babel-eslint/issues/21 * + * @param {ASTNode} node The node to start looking from. * @param {Object} context The current rule context. * @returns {Array} The variables list */ -function variablesInScope(context) { - let scope = context.getScope(); +function variablesInScope(node, context) { + let scope = getScope(node, context); let variables = scope.variables; while (scope.type !== 'global') { @@ -55,12 +57,13 @@ function variablesInScope(context) { /** * Find a variable by name in the current scope. + * @param {ASTNode} node The node to check. Must be an Identifier node. * @param {Object} context The current rule context. * @param {string} name Name of the variable to look for. * @returns {ASTNode|null} Return null if the variable could not be found, ASTNode otherwise. */ -function findVariableByName(context, name) { - const variable = getVariable(variablesInScope(context), name); +function findVariableByName(node, context, name) { + const variable = getVariable(variablesInScope(node, context), name); if (!variable || !variable.defs[0] || !variable.defs[0].node) { return null; diff --git a/package.json b/package.json index 66d7078685..685e65a222 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "eslint-plugin-react", - "version": "7.34.0", + "version": "7.34.1", "author": "Yannick Croissant ", "description": "React specific linting rules for ESLint", "main": "index.js", From 9d4cc14f6821f7954911d968ca1a8793996e95ed Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20=C5=81opaci=C5=84ski?= Date: Sun, 28 Apr 2024 15:37:38 +0200 Subject: [PATCH 2/6] Fix linting issues --- lib/rules/boolean-prop-naming.js | 8 ++-- lib/rules/destructuring-assignment.js | 14 +++---- lib/rules/forbid-elements.js | 6 +-- lib/rules/forbid-prop-types.js | 8 ++-- lib/rules/function-component-definition.js | 4 +- lib/rules/hook-use-state.js | 40 +++++++++---------- lib/rules/jsx-closing-bracket-location.js | 8 ++-- lib/rules/jsx-curly-brace-presence.js | 10 ++--- lib/rules/jsx-curly-newline.js | 4 +- lib/rules/jsx-curly-spacing.js | 14 +++---- lib/rules/jsx-equals-spacing.js | 4 +- lib/rules/jsx-fragments.js | 6 +-- lib/rules/jsx-handler-names.js | 4 +- lib/rules/jsx-indent-props.js | 4 +- lib/rules/jsx-indent.js | 20 +++++----- lib/rules/jsx-key.js | 4 +- lib/rules/jsx-max-props-per-line.js | 6 +-- lib/rules/jsx-newline.js | 4 +- lib/rules/jsx-no-bind.js | 8 ++-- lib/rules/jsx-no-comment-textnodes.js | 4 +- .../jsx-no-constructed-context-values.js | 4 +- lib/rules/jsx-no-leaked-render.js | 4 +- lib/rules/jsx-no-literals.js | 4 +- lib/rules/jsx-no-undef.js | 6 +-- lib/rules/jsx-no-useless-fragment.js | 8 ++-- lib/rules/jsx-one-expression-per-line.js | 10 ++--- lib/rules/jsx-props-no-multi-spaces.js | 6 +-- lib/rules/jsx-sort-default-props.js | 6 +-- lib/rules/jsx-sort-props.js | 6 +-- lib/rules/jsx-space-before-closing.js | 4 +- lib/rules/jsx-tag-spacing.js | 10 ++--- lib/rules/jsx-uses-react.js | 6 +-- lib/rules/jsx-uses-vars.js | 4 +- lib/rules/jsx-wrap-multilines.js | 8 ++-- lib/rules/no-access-state-in-setstate.js | 12 +++--- lib/rules/no-arrow-function-lifecycle.js | 4 +- lib/rules/no-deprecated.js | 4 +- lib/rules/no-is-mounted.js | 4 +- lib/rules/no-string-refs.js | 8 ++-- lib/rules/no-unescaped-entities.js | 6 +-- lib/rules/no-unknown-property.js | 4 +- lib/rules/no-unused-state.js | 6 +-- lib/rules/prefer-exact-props.js | 4 +- lib/rules/prefer-stateless-function.js | 6 +-- lib/rules/require-optimization.js | 5 ++- lib/rules/require-render-return.js | 4 +- lib/rules/sort-default-props.js | 6 +-- lib/rules/sort-prop-types.js | 6 +-- lib/rules/static-property-placement.js | 13 +++--- lib/util/Components.js | 28 +++++-------- lib/util/ast.js | 10 ++--- lib/util/componentUtil.js | 10 ++--- lib/util/defaultProps.js | 4 +- lib/util/eslint.js | 4 +- lib/util/makeNoMethodSetStateRule.js | 4 +- lib/util/pragma.js | 4 +- lib/util/propTypes.js | 14 +++---- lib/util/propTypesSort.js | 6 +-- lib/util/usedPropTypes.js | 30 +++++++------- lib/util/variable.js | 4 +- 60 files changed, 236 insertions(+), 240 deletions(-) diff --git a/lib/rules/boolean-prop-naming.js b/lib/rules/boolean-prop-naming.js index 670ec3ad10..174c9e244a 100644 --- a/lib/rules/boolean-prop-naming.js +++ b/lib/rules/boolean-prop-naming.js @@ -13,7 +13,7 @@ const propsUtil = require('../util/props'); const docsUrl = require('../util/docsUrl'); const propWrapperUtil = require('../util/propWrapper'); const report = require('../util/report'); -const { getSourceCode } = require('../util/eslint'); +const eslintUtil = require('../util/eslint'); // ------------------------------------------------------------------------------ // Rule Definition @@ -116,7 +116,7 @@ module.exports = { // we can't get the name of the Flow object key name. So we have // to hack around it for now. if (node.type === 'ObjectTypeProperty') { - return getSourceCode(context).getFirstToken(node).value; + return eslintUtil.getSourceCode(context).getFirstToken(node).value; } return node.key.name; @@ -309,7 +309,7 @@ module.exports = { && node.value.type === 'CallExpression' && propWrapperUtil.isPropWrapperFunction( context, - getSourceCode(context).getText(node.value.callee) + eslintUtil.getSourceCode(context).getText(node.value.callee) ) ) { checkPropWrapperArguments(node, node.value.arguments); @@ -335,7 +335,7 @@ module.exports = { right.type === 'CallExpression' && propWrapperUtil.isPropWrapperFunction( context, - getSourceCode(context).getText(right.callee) + eslintUtil.getSourceCode(context).getText(right.callee) ) ) { checkPropWrapperArguments(component.node, right.arguments); diff --git a/lib/rules/destructuring-assignment.js b/lib/rules/destructuring-assignment.js index 777872743a..a259031c70 100644 --- a/lib/rules/destructuring-assignment.js +++ b/lib/rules/destructuring-assignment.js @@ -6,7 +6,7 @@ const Components = require('../util/Components'); const docsUrl = require('../util/docsUrl'); -const { getScope, getSourceCode } = require('../util/eslint'); +const eslintUtil = require('../util/eslint'); const isAssignmentLHS = require('../util/ast').isAssignmentLHS; const report = require('../util/report'); @@ -103,7 +103,7 @@ module.exports = { function handleStatelessComponent(node) { const params = evalParams(node.params); - const SFCComponent = components.get(getScope(node, context).block); + const SFCComponent = components.get(eslintUtil.getScope(node, context).block); if (!SFCComponent) { return; } @@ -121,7 +121,7 @@ module.exports = { } function handleStatelessComponentExit(node) { - const SFCComponent = components.get(getScope(node, context).block); + const SFCComponent = components.get(eslintUtil.getScope(node, context).block); if (SFCComponent) { sfcParams.pop(); } @@ -193,7 +193,7 @@ module.exports = { 'FunctionExpression:exit': handleStatelessComponentExit, MemberExpression(node) { - let scope = getScope(node, context); + let scope = eslintUtil.getScope(node, context); let SFCComponent = components.get(scope.block); while (!SFCComponent && scope.upper && scope.upper !== scope) { SFCComponent = components.get(scope.upper.block); @@ -211,7 +211,7 @@ module.exports = { VariableDeclarator(node) { const classComponent = utils.getParentComponent(node); - const SFCComponent = components.get(getScope(node, context).block); + const SFCComponent = components.get(eslintUtil.getScope(node, context).block); const destructuring = (node.init && node.id && node.id.type === 'ObjectPattern'); // let {foo} = props; @@ -249,7 +249,7 @@ module.exports = { && destructureInSignature === 'always' && node.init.name === 'props' ) { - const scopeSetProps = getScope(node, context).set.get('props'); + const scopeSetProps = eslintUtil.getScope(node, context).set.get('props'); const propsRefs = scopeSetProps && scopeSetProps.references; if (!propsRefs) { return; @@ -270,7 +270,7 @@ module.exports = { param.typeAnnotation ? param.typeAnnotation.range[0] : param.range[1], ]; return [ - fixer.replaceTextRange(replaceRange, getSourceCode(context).getText(node.id)), + fixer.replaceTextRange(replaceRange, eslintUtil.getSourceCode(context).getText(node.id)), fixer.remove(node.parent), ]; }, diff --git a/lib/rules/forbid-elements.js b/lib/rules/forbid-elements.js index d9f182c2ae..289e2d0e07 100644 --- a/lib/rules/forbid-elements.js +++ b/lib/rules/forbid-elements.js @@ -7,7 +7,7 @@ const has = require('object.hasown/polyfill')(); const docsUrl = require('../util/docsUrl'); -const { getSourceCode } = require('../util/eslint'); +const eslintUtil = require('../util/eslint'); const isCreateElement = require('../util/isCreateElement'); const report = require('../util/report'); @@ -91,7 +91,7 @@ module.exports = { return { JSXOpeningElement(node) { - reportIfForbidden(getSourceCode(context).getText(node.name), node.name); + reportIfForbidden(eslintUtil.getSourceCode(context).getText(node.name), node.name); }, CallExpression(node) { @@ -111,7 +111,7 @@ module.exports = { } else if (argType === 'Literal' && /^[a-z][^.]*$/.test(argument.value)) { reportIfForbidden(argument.value, argument); } else if (argType === 'MemberExpression') { - reportIfForbidden(getSourceCode(context).getText(argument), argument); + reportIfForbidden(eslintUtil.getSourceCode(context).getText(argument), argument); } }, }; diff --git a/lib/rules/forbid-prop-types.js b/lib/rules/forbid-prop-types.js index 25a77cbc5c..8f874c6363 100644 --- a/lib/rules/forbid-prop-types.js +++ b/lib/rules/forbid-prop-types.js @@ -10,7 +10,7 @@ const astUtil = require('../util/ast'); const docsUrl = require('../util/docsUrl'); const propWrapperUtil = require('../util/propWrapper'); const report = require('../util/report'); -const { getSourceCode } = require('../util/eslint'); +const eslintUtil = require('../util/eslint'); // ------------------------------------------------------------------------------ // Constants @@ -174,9 +174,9 @@ module.exports = { if ( propWrapperUtil.isPropWrapperFunction( context, - getSourceCode(context).getText(node.callee) - ) && - innerNode + eslintUtil.getSourceCode(context).getText(node.callee) + ) + && innerNode ) { checkNode(innerNode); } diff --git a/lib/rules/function-component-definition.js b/lib/rules/function-component-definition.js index c378c0740f..747bd1dc0d 100644 --- a/lib/rules/function-component-definition.js +++ b/lib/rules/function-component-definition.js @@ -9,7 +9,7 @@ const arrayIncludes = require('array-includes'); const Components = require('../util/Components'); const docsUrl = require('../util/docsUrl'); const reportC = require('../util/report'); -const { getSourceCode } = require('../util/eslint'); +const eslintUtil = require('../util/eslint'); // ------------------------------------------------------------------------------ // Rule Definition @@ -182,7 +182,7 @@ module.exports = { ); function getFixer(node, options) { - const sourceCode = getSourceCode(context); + const sourceCode = eslintUtil.getSourceCode(context); const source = sourceCode.getText(); const typeAnnotation = getTypeAnnotation(node, source); diff --git a/lib/rules/hook-use-state.js b/lib/rules/hook-use-state.js index 8414b41e57..61423f3409 100644 --- a/lib/rules/hook-use-state.js +++ b/lib/rules/hook-use-state.js @@ -9,6 +9,7 @@ const Components = require('../util/Components'); const docsUrl = require('../util/docsUrl'); const report = require('../util/report'); const getMessageData = require('../util/message'); +const eslintUtil = require('../util/eslint'); // ------------------------------------------------------------------------------ // Rule Definition @@ -158,29 +159,28 @@ module.exports = { Object.assign( getMessageData('suggestMemo', messages.suggestMemo), { - fix: (fixer) => - [ - // Add useMemo import, if necessary - useStateReactImportSpecifier && - (!useMemoReactImportSpecifier || - defaultReactImportName) && - fixer.insertTextAfter( + fix: (fixer) => [ + // Add useMemo import, if necessary + useStateReactImportSpecifier + && (!useMemoReactImportSpecifier + || defaultReactImportName) + && fixer.insertTextAfter( useStateReactImportSpecifier, ', useMemo' ), - // Convert single-value destructure to simple assignment - fixer.replaceTextRange( - node.parent.id.range, - valueVariableName - ), - // Convert useState call to useMemo + arrow function + dependency array - fixer.replaceTextRange( - node.range, - `${useMemoCode}(() => ${getSourceCode(context).getText( - node.arguments[0] - )}, [])` - ), - ].filter(Boolean), + // Convert single-value destructure to simple assignment + fixer.replaceTextRange( + node.parent.id.range, + valueVariableName + ), + // Convert useState call to useMemo + arrow function + dependency array + fixer.replaceTextRange( + node.range, + `${useMemoCode}(() => ${eslintUtil.getSourceCode(context).getText( + node.arguments[0] + )}, [])` + ), + ].filter(Boolean), } ) ); diff --git a/lib/rules/jsx-closing-bracket-location.js b/lib/rules/jsx-closing-bracket-location.js index 56da37c814..7d817034d0 100644 --- a/lib/rules/jsx-closing-bracket-location.js +++ b/lib/rules/jsx-closing-bracket-location.js @@ -7,7 +7,7 @@ const has = require('object.hasown/polyfill')(); const docsUrl = require('../util/docsUrl'); -const { getSourceCode } = require('../util/eslint'); +const eslintUtil = require('../util/eslint'); const report = require('../util/report'); // ------------------------------------------------------------------------------ @@ -172,13 +172,13 @@ module.exports = { switch (expectedLocation) { case 'props-aligned': indentation = /^\s*/.exec( - getSourceCode(context).lines[tokens.lastProp.firstLine - 1] + eslintUtil.getSourceCode(context).lines[tokens.lastProp.firstLine - 1] )[0]; break; case 'tag-aligned': case 'line-aligned': indentation = /^\s*/.exec( - getSourceCode(context).lines[tokens.opening.line - 1] + eslintUtil.getSourceCode(context).lines[tokens.opening.line - 1] )[0]; break; default: @@ -199,7 +199,7 @@ module.exports = { * prop and start of opening line. */ function getTokensLocations(node) { - const sourceCode = getSourceCode(context); + const sourceCode = eslintUtil.getSourceCode(context); const opening = sourceCode.getFirstToken(node).loc.start; const closing = sourceCode.getLastTokens(node, node.selfClosing ? 2 : 1)[0].loc.start; const tag = sourceCode.getFirstToken(node.name).loc.start; diff --git a/lib/rules/jsx-curly-brace-presence.js b/lib/rules/jsx-curly-brace-presence.js index 7923b09587..9e486a5bef 100755 --- a/lib/rules/jsx-curly-brace-presence.js +++ b/lib/rules/jsx-curly-brace-presence.js @@ -11,7 +11,7 @@ const arrayIncludes = require('array-includes'); const docsUrl = require('../util/docsUrl'); const jsxUtil = require('../util/jsx'); const report = require('../util/report'); -const { getSourceCode } = require('../util/eslint'); +const eslintUtil = require('../util/eslint'); // ------------------------------------------------------------------------------ // Constants @@ -177,7 +177,7 @@ module.exports = { let textToReplace; if (jsxUtil.isJSX(expression)) { - const sourceCode = getSourceCode(context); + const sourceCode = eslintUtil.getSourceCode(context); textToReplace = sourceCode.getText(expression); } else { const expressionType = expression && expression.type; @@ -189,7 +189,7 @@ module.exports = { : expression.raw.slice(1, -1) }"`; } else if (jsxUtil.isJSX(expression)) { - const sourceCode = getSourceCode(context); + const sourceCode = eslintUtil.getSourceCode(context); textToReplace = sourceCode.getText(expression); } else { @@ -210,7 +210,7 @@ module.exports = { if (jsxUtil.isJSX(literalNode)) { return fixer.replaceText( literalNode, - `{${getSourceCode(context).getText(literalNode)}}` + `{${eslintUtil.getSourceCode(context).getText(literalNode)}}` ); } @@ -255,7 +255,7 @@ module.exports = { const expression = JSXExpressionNode.expression; const expressionType = expression.type; - const sourceCode = getSourceCode(context); + const sourceCode = eslintUtil.getSourceCode(context); // Curly braces containing comments are necessary if (sourceCode.getCommentsInside && sourceCode.getCommentsInside(JSXExpressionNode).length > 0) { return; diff --git a/lib/rules/jsx-curly-newline.js b/lib/rules/jsx-curly-newline.js index ca33a68ca1..9d258dd42f 100644 --- a/lib/rules/jsx-curly-newline.js +++ b/lib/rules/jsx-curly-newline.js @@ -5,7 +5,7 @@ 'use strict'; const docsUrl = require('../util/docsUrl'); -const { getSourceCode } = require('../util/eslint'); +const eslintUtil = require('../util/eslint'); const report = require('../util/report'); // ------------------------------------------------------------------------------ @@ -78,7 +78,7 @@ module.exports = { }, create(context) { - const sourceCode = getSourceCode(context); + const sourceCode = eslintUtil.getSourceCode(context); const option = getNormalizedOption(context); // ---------------------------------------------------------------------- diff --git a/lib/rules/jsx-curly-spacing.js b/lib/rules/jsx-curly-spacing.js index 9675dc74af..e92a2b0409 100644 --- a/lib/rules/jsx-curly-spacing.js +++ b/lib/rules/jsx-curly-spacing.js @@ -13,7 +13,7 @@ const has = require('object.hasown/polyfill')(); const docsUrl = require('../util/docsUrl'); -const { getSourceCode } = require('../util/eslint'); +const eslintUtil = require('../util/eslint'); const report = require('../util/report'); // ------------------------------------------------------------------------------ @@ -176,7 +176,7 @@ module.exports = { * @returns {Object|*|{range, text}} */ function fixByTrimmingWhitespace(fixer, fromLoc, toLoc, mode, spacing) { - let replacementText = getSourceCode(context).text.slice(fromLoc, toLoc); + let replacementText = eslintUtil.getSourceCode(context).text.slice(fromLoc, toLoc); if (mode === 'start') { replacementText = replacementText.replace(/^\s+/gm, ''); } else { @@ -207,7 +207,7 @@ module.exports = { token: token.value, }, fix(fixer) { - const nextToken = getSourceCode(context).getTokenAfter(token); + const nextToken = eslintUtil.getSourceCode(context).getTokenAfter(token); return fixByTrimmingWhitespace(fixer, token.range[1], nextToken.range[0], 'start', spacing); }, }); @@ -228,7 +228,7 @@ module.exports = { token: token.value, }, fix(fixer) { - const previousToken = getSourceCode(context).getTokenBefore(token); + const previousToken = eslintUtil.getSourceCode(context).getTokenBefore(token); return fixByTrimmingWhitespace(fixer, previousToken.range[1], token.range[0], 'end', spacing); }, }); @@ -248,7 +248,7 @@ module.exports = { token: token.value, }, fix(fixer) { - const sourceCode = getSourceCode(context); + const sourceCode = eslintUtil.getSourceCode(context); const nextToken = sourceCode.getTokenAfter(token); let nextComment; @@ -285,7 +285,7 @@ module.exports = { token: token.value, }, fix(fixer) { - const sourceCode = getSourceCode(context); + const sourceCode = eslintUtil.getSourceCode(context); const previousToken = sourceCode.getTokenBefore(token); let previousComment; @@ -371,7 +371,7 @@ module.exports = { return; } - const sourceCode = getSourceCode(context); + const sourceCode = eslintUtil.getSourceCode(context); const first = sourceCode.getFirstToken(node); const last = sourceCode.getLastToken(node); let second = sourceCode.getTokenAfter(first, { includeComments: true }); diff --git a/lib/rules/jsx-equals-spacing.js b/lib/rules/jsx-equals-spacing.js index 9da25b2859..6aa24c726a 100644 --- a/lib/rules/jsx-equals-spacing.js +++ b/lib/rules/jsx-equals-spacing.js @@ -6,7 +6,7 @@ 'use strict'; const docsUrl = require('../util/docsUrl'); -const { getSourceCode } = require('../util/eslint'); +const eslintUtil = require('../util/eslint'); const report = require('../util/report'); // ------------------------------------------------------------------------------ @@ -60,7 +60,7 @@ module.exports = { return; } - const sourceCode = getSourceCode(context); + const sourceCode = eslintUtil.getSourceCode(context); const equalToken = sourceCode.getTokenAfter(attrNode.name); const spacedBefore = sourceCode.isSpaceBetweenTokens(attrNode.name, equalToken); const spacedAfter = sourceCode.isSpaceBetweenTokens(equalToken, attrNode.value); diff --git a/lib/rules/jsx-fragments.js b/lib/rules/jsx-fragments.js index 1b18774172..37c7d6cba9 100644 --- a/lib/rules/jsx-fragments.js +++ b/lib/rules/jsx-fragments.js @@ -11,7 +11,7 @@ const variableUtil = require('../util/variable'); const testReactVersion = require('../util/version').testReactVersion; const docsUrl = require('../util/docsUrl'); const report = require('../util/report'); -const { getSourceCode } = require('../util/eslint'); +const eslintUtil = require('../util/eslint'); // ------------------------------------------------------------------------------ // Rule Definition @@ -66,7 +66,7 @@ module.exports = { } function getFixerToLong(jsxFragment) { - const sourceCode = getSourceCode(context); + const sourceCode = eslintUtil.getSourceCode(context); if (!jsxFragment.closingFragment || !jsxFragment.openingFragment) { // the old TS parser crashes here // TODO: FIXME: can we fake these two descriptors? @@ -84,7 +84,7 @@ module.exports = { } function getFixerToShort(jsxElement) { - const sourceCode = getSourceCode(context); + const sourceCode = eslintUtil.getSourceCode(context); return function fix(fixer) { let source = sourceCode.getText(); let lengthDiff; diff --git a/lib/rules/jsx-handler-names.js b/lib/rules/jsx-handler-names.js index 7652232640..1f0beb3425 100644 --- a/lib/rules/jsx-handler-names.js +++ b/lib/rules/jsx-handler-names.js @@ -6,7 +6,7 @@ 'use strict'; const docsUrl = require('../util/docsUrl'); -const { getSourceCode } = require('../util/eslint'); +const eslintUtil = require('../util/eslint'); const report = require('../util/report'); // ------------------------------------------------------------------------------ @@ -130,7 +130,7 @@ module.exports = { const propKey = typeof node.name === 'object' ? node.name.name : node.name; const expression = node.value.expression; - const propValue = getSourceCode(context) + const propValue = eslintUtil.getSourceCode(context) .getText( checkInlineFunction && isInlineHandler(node) ? expression.body.callee diff --git a/lib/rules/jsx-indent-props.js b/lib/rules/jsx-indent-props.js index aa7dfb4a55..9361e600da 100644 --- a/lib/rules/jsx-indent-props.js +++ b/lib/rules/jsx-indent-props.js @@ -32,7 +32,7 @@ const astUtil = require('../util/ast'); const docsUrl = require('../util/docsUrl'); -const { getSourceCode } = require('../util/eslint'); +const eslintUtil = require('../util/eslint'); const reportC = require('../util/report'); // ------------------------------------------------------------------------------ @@ -141,7 +141,7 @@ module.exports = { * @return {Number} Indent */ function getNodeIndent(node) { - let src = getSourceCode(context).getText( + let src = eslintUtil.getSourceCode(context).getText( node, node.loc.start.column + extraColumnStart ); diff --git a/lib/rules/jsx-indent.js b/lib/rules/jsx-indent.js index 01a390bdce..c93d74bd10 100644 --- a/lib/rules/jsx-indent.js +++ b/lib/rules/jsx-indent.js @@ -36,7 +36,7 @@ const astUtil = require('../util/ast'); const docsUrl = require('../util/docsUrl'); const reportC = require('../util/report'); const jsxUtil = require('../util/jsx'); -const { getSourceCode } = require('../util/eslint'); +const eslintUtil = require('../util/eslint'); // ------------------------------------------------------------------------------ // Rule Definition @@ -117,7 +117,7 @@ module.exports = { } if (node.type === 'ReturnStatement') { - const raw = getSourceCode(context).getText(node); + const raw = eslintUtil.getSourceCode(context).getText(node); const lines = raw.split('\n'); if (lines.length > 1) { return function fix(fixer) { @@ -169,7 +169,7 @@ module.exports = { * @return {Number} Indent */ function getNodeIndent(node, byLastLine, excludeCommas) { - let src = getSourceCode(context).getText( + let src = eslintUtil.getSourceCode(context).getText( node, node.loc.start.column + extraColumnStart ); @@ -215,11 +215,11 @@ module.exports = { */ function isAlternateInConditionalExp(node) { return ( - node.parent && - node.parent.parent && - node.parent.parent.type === 'ConditionalExpression' && - node.parent.parent.alternate === node.parent && - getSourceCode(context).getTokenBefore(node).value !== '(' + node.parent + && node.parent.parent + && node.parent.parent.type === 'ConditionalExpression' + && node.parent.parent.alternate === node.parent + && eslintUtil.getSourceCode(context).getTokenBefore(node).value !== '(' ); } @@ -338,7 +338,7 @@ module.exports = { } function handleOpeningElement(node) { - const sourceCode = getSourceCode(context); + const sourceCode = eslintUtil.getSourceCode(context); let prevToken = sourceCode.getTokenBefore(node); if (!prevToken) { return; @@ -381,7 +381,7 @@ module.exports = { return; } const nameIndent = getNodeIndent(node.name); - const lastToken = getSourceCode(context).getLastToken(node.value); + const lastToken = eslintUtil.getSourceCode(context).getLastToken(node.value); const firstInLine = astUtil.getFirstNodeInLine(context, lastToken); const indent = node.name.loc.start.line === firstInLine.loc.start.line ? 0 : nameIndent; checkNodesIndent(firstInLine, indent); diff --git a/lib/rules/jsx-key.js b/lib/rules/jsx-key.js index b8d69136f0..eef99bd273 100644 --- a/lib/rules/jsx-key.js +++ b/lib/rules/jsx-key.js @@ -12,7 +12,7 @@ const docsUrl = require('../util/docsUrl'); const pragmaUtil = require('../util/pragma'); const report = require('../util/report'); const astUtil = require('../util/ast'); -const { getSourceCode } = require('../util/eslint'); +const eslintUtil = require('../util/eslint'); // ------------------------------------------------------------------------------ // Rule Definition @@ -214,7 +214,7 @@ module.exports = { } } else { keys.forEach((attr) => { - const value = getSourceCode(context).getText(attr.value); + const value = eslintUtil.getSourceCode(context).getText(attr.value); if (!map[value]) { map[value] = []; } map[value].push(attr); diff --git a/lib/rules/jsx-max-props-per-line.js b/lib/rules/jsx-max-props-per-line.js index 5c78e2f5c7..54087718bc 100644 --- a/lib/rules/jsx-max-props-per-line.js +++ b/lib/rules/jsx-max-props-per-line.js @@ -6,12 +6,12 @@ 'use strict'; const docsUrl = require('../util/docsUrl'); -const { getSourceCode } = require('../util/eslint'); +const eslintUtil = require('../util/eslint'); const report = require('../util/report'); function getPropName(context, propNode) { if (propNode.type === 'JSXSpreadAttribute') { - return getSourceCode(context).getText(propNode.argument); + return eslintUtil.getSourceCode(context).getText(propNode.argument); } return propNode.name.name; } @@ -88,7 +88,7 @@ module.exports = { }; function generateFixFunction(line, max) { - const sourceCode = getSourceCode(context); + const sourceCode = eslintUtil.getSourceCode(context); const output = []; const front = line[0].range[0]; const back = line[line.length - 1].range[1]; diff --git a/lib/rules/jsx-newline.js b/lib/rules/jsx-newline.js index 304be8d11b..cc3f5b5390 100644 --- a/lib/rules/jsx-newline.js +++ b/lib/rules/jsx-newline.js @@ -7,7 +7,7 @@ 'use strict'; const docsUrl = require('../util/docsUrl'); -const { getSourceCode } = require('../util/eslint'); +const eslintUtil = require('../util/eslint'); const report = require('../util/report'); // ------------------------------------------------------------------------------ @@ -72,7 +72,7 @@ module.exports = { }, create(context) { const jsxElementParents = new Set(); - const sourceCode = getSourceCode(context); + const sourceCode = eslintUtil.getSourceCode(context); function isBlockCommentInCurlyBraces(element) { const elementRawValue = sourceCode.getText(element); diff --git a/lib/rules/jsx-no-bind.js b/lib/rules/jsx-no-bind.js index b282f87bea..784e13ceaa 100644 --- a/lib/rules/jsx-no-bind.js +++ b/lib/rules/jsx-no-bind.js @@ -11,7 +11,7 @@ const propName = require('jsx-ast-utils/propName'); const docsUrl = require('../util/docsUrl'); const jsxUtil = require('../util/jsx'); const report = require('../util/report'); -const { getAncestors } = require('../util/eslint'); +const eslintUtil = require('../util/eslint'); // ----------------------------------------------------------------------------- // Rule Definition @@ -124,9 +124,9 @@ module.exports = { } function getBlockStatementAncestors(node) { - return getAncestors(node, context).filter( - (ancestor) => ancestor.type === 'BlockStatement' - ).reverse(); + return eslintUtil.getAncestors(node, context) + .filter((ancestor) => ancestor.type === 'BlockStatement') + .reverse(); } function reportVariableViolation(node, name, blockStart) { diff --git a/lib/rules/jsx-no-comment-textnodes.js b/lib/rules/jsx-no-comment-textnodes.js index 1430f3b5ad..25de71a3b4 100644 --- a/lib/rules/jsx-no-comment-textnodes.js +++ b/lib/rules/jsx-no-comment-textnodes.js @@ -6,7 +6,7 @@ 'use strict'; const docsUrl = require('../util/docsUrl'); -const { getSourceCode } = require('../util/eslint'); +const eslintUtil = require('../util/eslint'); const report = require('../util/report'); // ------------------------------------------------------------------------------ @@ -19,7 +19,7 @@ const messages = { function checkText(node, context) { // since babel-eslint has the wrong node.raw, we'll get the source text - const rawValue = getSourceCode(context).getText(node); + const rawValue = eslintUtil.getSourceCode(context).getText(node); if (/^\s*\/(\/|\*)/m.test(rawValue)) { // inside component, e.g.
literal
if ( diff --git a/lib/rules/jsx-no-constructed-context-values.js b/lib/rules/jsx-no-constructed-context-values.js index ec52a6568f..7565e0db0b 100644 --- a/lib/rules/jsx-no-constructed-context-values.js +++ b/lib/rules/jsx-no-constructed-context-values.js @@ -8,7 +8,7 @@ const Components = require('../util/Components'); const docsUrl = require('../util/docsUrl'); -const { getScope } = require('../util/eslint'); +const eslintUtil = require('../util/eslint'); const report = require('../util/report'); // ------------------------------------------------------------------------------ @@ -181,7 +181,7 @@ module.exports = { } const valueExpression = valueNode.expression; - const invocationScope = getScope(node, context); + const invocationScope = eslintUtil.getScope(node, context); // Check if the value prop is a construction const constructInfo = isConstruction(valueExpression, invocationScope); diff --git a/lib/rules/jsx-no-leaked-render.js b/lib/rules/jsx-no-leaked-render.js index 2b3d0af2b1..2082ee4681 100644 --- a/lib/rules/jsx-no-leaked-render.js +++ b/lib/rules/jsx-no-leaked-render.js @@ -10,7 +10,7 @@ const from = require('es-iterator-helpers/Iterator.from'); const docsUrl = require('../util/docsUrl'); const report = require('../util/report'); -const { getSourceCode } = require('../util/eslint'); +const eslintUtil = require('../util/eslint'); const testReactVersion = require('../util/version').testReactVersion; const isParenthesized = require('../util/ast').isParenthesized; @@ -55,7 +55,7 @@ function extractExpressionBetweenLogicalAnds(node) { } function ruleFixer(context, fixStrategy, fixer, reportedNode, leftNode, rightNode) { - const sourceCode = getSourceCode(context); + const sourceCode = eslintUtil.getSourceCode(context); const rightSideText = sourceCode.getText(rightNode); if (fixStrategy === COERCE_STRATEGY) { diff --git a/lib/rules/jsx-no-literals.js b/lib/rules/jsx-no-literals.js index 5003626a9f..a704b57319 100644 --- a/lib/rules/jsx-no-literals.js +++ b/lib/rules/jsx-no-literals.js @@ -11,7 +11,7 @@ const map = require('es-iterator-helpers/Iterator.prototype.map'); const docsUrl = require('../util/docsUrl'); const report = require('../util/report'); -const { getSourceCode } = require('../util/eslint'); +const eslintUtil = require('../util/eslint'); // ------------------------------------------------------------------------------ // Rule Definition @@ -150,7 +150,7 @@ module.exports = { report(context, messages[messageId], messageId, { node, data: { - text: getSourceCode(context).getText(node).trim(), + text: eslintUtil.getSourceCode(context).getText(node).trim(), }, }); } diff --git a/lib/rules/jsx-no-undef.js b/lib/rules/jsx-no-undef.js index bb45df8f97..bcb480dd71 100644 --- a/lib/rules/jsx-no-undef.js +++ b/lib/rules/jsx-no-undef.js @@ -6,7 +6,7 @@ 'use strict'; const docsUrl = require('../util/docsUrl'); -const { getScope, getSourceCode } = require('../util/eslint'); +const eslintUtil = require('../util/eslint'); const jsxUtil = require('../util/jsx'); const report = require('../util/report'); @@ -51,8 +51,8 @@ module.exports = { * @returns {void} */ function checkIdentifierInJSX(node) { - let scope = getScope(node, context); - const sourceCode = getSourceCode(context); + let scope = eslintUtil.getScope(node, context); + const sourceCode = eslintUtil.getSourceCode(context); const sourceType = sourceCode.ast.sourceType; const scopeUpperBound = !allowGlobals && sourceType === 'module' ? 'module' : 'global'; let variables = scope.variables; diff --git a/lib/rules/jsx-no-useless-fragment.js b/lib/rules/jsx-no-useless-fragment.js index 5444ae74e8..0d55eb973c 100644 --- a/lib/rules/jsx-no-useless-fragment.js +++ b/lib/rules/jsx-no-useless-fragment.js @@ -10,7 +10,7 @@ const pragmaUtil = require('../util/pragma'); const jsxUtil = require('../util/jsx'); const docsUrl = require('../util/docsUrl'); const report = require('../util/report'); -const { getSourceCode } = require('../util/eslint'); +const eslintUtil = require('../util/eslint'); function isJSXText(node) { return !!node && (node.type === 'JSXText' || node.type === 'Literal'); @@ -219,9 +219,9 @@ module.exports = { const childrenText = opener.selfClosing ? '' - : getSourceCode(context) - .getText() - .slice(opener.range[1], closer.range[0]); + : eslintUtil.getSourceCode(context) + .getText() + .slice(opener.range[1], closer.range[0]); return fixer.replaceText(node, trimLikeReact(childrenText)); }; diff --git a/lib/rules/jsx-one-expression-per-line.js b/lib/rules/jsx-one-expression-per-line.js index f9409d1a90..86fee282ad 100644 --- a/lib/rules/jsx-one-expression-per-line.js +++ b/lib/rules/jsx-one-expression-per-line.js @@ -6,7 +6,7 @@ 'use strict'; const docsUrl = require('../util/docsUrl'); -const { getSourceCode } = require('../util/eslint'); +const eslintUtil = require('../util/eslint'); const jsxUtil = require('../util/jsx'); const report = require('../util/report'); @@ -59,7 +59,7 @@ module.exports = { function nodeDescriptor(n) { return n.openingElement ? n.openingElement.name.name - : getSourceCode(context).getText(n).replace(/\n/g, ''); + : eslintUtil.getSourceCode(context).getText(n).replace(/\n/g, ''); } function handleJSX(node) { @@ -166,20 +166,20 @@ module.exports = { function spaceBetweenPrev() { return ((prevChild.type === 'Literal' || prevChild.type === 'JSXText') && / $/.test(prevChild.raw)) || ((child.type === 'Literal' || child.type === 'JSXText') && /^ /.test(child.raw)) - || getSourceCode(context).isSpaceBetweenTokens(prevChild, child) + || eslintUtil.getSourceCode(context).isSpaceBetweenTokens(prevChild, child); } function spaceBetweenNext() { return ((nextChild.type === 'Literal' || nextChild.type === 'JSXText') && /^ /.test(nextChild.raw)) || ((child.type === 'Literal' || child.type === 'JSXText') && / $/.test(child.raw)) - || getSourceCode(context).isSpaceBetweenTokens(child, nextChild); + || eslintUtil.getSourceCode(context).isSpaceBetweenTokens(child, nextChild); } if (!prevChild && !nextChild) { return; } - const source = getSourceCode(context).getText(child); + const source = eslintUtil.getSourceCode(context).getText(child); const leadingSpace = !!(prevChild && spaceBetweenPrev()); const trailingSpace = !!(nextChild && spaceBetweenNext()); const leadingNewLine = !!prevChild; diff --git a/lib/rules/jsx-props-no-multi-spaces.js b/lib/rules/jsx-props-no-multi-spaces.js index 0ca17bd68e..2eb332f96f 100644 --- a/lib/rules/jsx-props-no-multi-spaces.js +++ b/lib/rules/jsx-props-no-multi-spaces.js @@ -6,7 +6,7 @@ 'use strict'; const docsUrl = require('../util/docsUrl'); -const { getSourceCode } = require('../util/eslint'); +const eslintUtil = require('../util/eslint'); const report = require('../util/report'); // ------------------------------------------------------------------------------ @@ -35,7 +35,7 @@ module.exports = { }, create(context) { - const sourceCode = getSourceCode(context); + const sourceCode = eslintUtil.getSourceCode(context); function getPropName(propNode) { switch (propNode.type) { @@ -83,7 +83,7 @@ module.exports = { return; } - const between = getSourceCode(context).text.slice( + const between = eslintUtil.getSourceCode(context).text.slice( prev.range[1], node.range[0] ); diff --git a/lib/rules/jsx-sort-default-props.js b/lib/rules/jsx-sort-default-props.js index 7fcff990eb..529a0c8b3f 100644 --- a/lib/rules/jsx-sort-default-props.js +++ b/lib/rules/jsx-sort-default-props.js @@ -10,7 +10,7 @@ const variableUtil = require('../util/variable'); const docsUrl = require('../util/docsUrl'); const report = require('../util/report'); const log = require('../util/log'); -const { getSourceCode } = require('../util/eslint'); +const eslintUtil = require('../util/eslint'); let isWarnedForDeprecation = false; @@ -66,7 +66,7 @@ module.exports = { // (babel-eslint@5 does not expose property name so we have to rely on tokens) } if (node.type === 'ClassProperty') { - const tokens = getSourceCode(context).getFirstTokens(node, 2); + const tokens = eslintUtil.getSourceCode(context).getFirstTokens(node, 2); return tokens[1] && tokens[1].type === 'Identifier' ? tokens[1].value : tokens[0].value; } return ''; @@ -83,7 +83,7 @@ module.exports = { } function getKey(node) { - return getSourceCode(context).getText(node.key || node.argument); + return eslintUtil.getSourceCode(context).getText(node.key || node.argument); } /** diff --git a/lib/rules/jsx-sort-props.js b/lib/rules/jsx-sort-props.js index 7a975d9818..b9dcd9e6e1 100644 --- a/lib/rules/jsx-sort-props.js +++ b/lib/rules/jsx-sort-props.js @@ -12,7 +12,7 @@ const toSorted = require('array.prototype.tosorted'); const docsUrl = require('../util/docsUrl'); const jsxUtil = require('../util/jsx'); const report = require('../util/report'); -const { getSourceCode } = require('../util/eslint'); +const eslintUtil = require('../util/eslint'); // ------------------------------------------------------------------------------ // Rule Definition @@ -142,7 +142,7 @@ function contextCompare(a, b, options) { * @return {Array>} */ function getGroupsOfSortableAttributes(attributes, context) { - const sourceCode = getSourceCode(context); + const sourceCode = eslintUtil.getSourceCode(context); const sortableAttributeGroups = []; let groupCount = 0; @@ -213,7 +213,7 @@ function getGroupsOfSortableAttributes(attributes, context) { } function generateFixerFunction(node, context, reservedList) { - const sourceCode = getSourceCode(context); + const sourceCode = eslintUtil.getSourceCode(context); const attributes = node.attributes.slice(0); const configuration = context.options[0] || {}; const ignoreCase = configuration.ignoreCase || false; diff --git a/lib/rules/jsx-space-before-closing.js b/lib/rules/jsx-space-before-closing.js index 9fbb13a776..3e161c27da 100644 --- a/lib/rules/jsx-space-before-closing.js +++ b/lib/rules/jsx-space-before-closing.js @@ -10,7 +10,7 @@ const getTokenBeforeClosingBracket = require('../util/getTokenBeforeClosingBrack const docsUrl = require('../util/docsUrl'); const log = require('../util/log'); const report = require('../util/report'); -const { getSourceCode } = require('../util/eslint'); +const eslintUtil = require('../util/eslint'); let isWarnedForDeprecation = false; @@ -55,7 +55,7 @@ module.exports = { return; } - const sourceCode = getSourceCode(context); + const sourceCode = eslintUtil.getSourceCode(context); const leftToken = getTokenBeforeClosingBracket(node); const closingSlash = sourceCode.getTokenAfter(leftToken); diff --git a/lib/rules/jsx-tag-spacing.js b/lib/rules/jsx-tag-spacing.js index a0ace6bb0f..115909e445 100644 --- a/lib/rules/jsx-tag-spacing.js +++ b/lib/rules/jsx-tag-spacing.js @@ -8,7 +8,7 @@ const getTokenBeforeClosingBracket = require('../util/getTokenBeforeClosingBracket'); const docsUrl = require('../util/docsUrl'); const report = require('../util/report'); -const { getSourceCode } = require('../util/eslint'); +const eslintUtil = require('../util/eslint'); const messages = { selfCloseSlashNoSpace: 'Whitespace is forbidden between `/` and `>`; write `/>`', @@ -30,7 +30,7 @@ const messages = { // ------------------------------------------------------------------------------ function validateClosingSlash(context, node, option) { - const sourceCode = getSourceCode(context); + const sourceCode = eslintUtil.getSourceCode(context); let adjacent; @@ -98,7 +98,7 @@ function validateClosingSlash(context, node, option) { } function validateBeforeSelfClosing(context, node, option) { - const sourceCode = getSourceCode(context); + const sourceCode = eslintUtil.getSourceCode(context); const leftToken = getTokenBeforeClosingBracket(node); const closingSlash = sourceCode.getTokenAfter(leftToken); @@ -142,7 +142,7 @@ function validateBeforeSelfClosing(context, node, option) { } function validateAfterOpening(context, node, option) { - const sourceCode = getSourceCode(context); + const sourceCode = eslintUtil.getSourceCode(context); const openingToken = sourceCode.getTokenBefore(node.name); if (option === 'allow-multiline') { @@ -183,7 +183,7 @@ function validateAfterOpening(context, node, option) { function validateBeforeClosing(context, node, option) { // Don't enforce this rule for self closing tags if (!node.selfClosing) { - const sourceCode = getSourceCode(context); + const sourceCode = eslintUtil.getSourceCode(context); const leftToken = option === 'proportional-always' ? getTokenBeforeClosingBracket(node) : sourceCode.getLastTokens(node, 2)[0]; diff --git a/lib/rules/jsx-uses-react.js b/lib/rules/jsx-uses-react.js index ee5946bcb7..068e2f396f 100644 --- a/lib/rules/jsx-uses-react.js +++ b/lib/rules/jsx-uses-react.js @@ -7,7 +7,7 @@ const pragmaUtil = require('../util/pragma'); const docsUrl = require('../util/docsUrl'); -const { markVariableAsUsed } = require('../util/eslint'); +const eslintUtil = require('../util/eslint'); // ------------------------------------------------------------------------------ // Rule Definition @@ -31,7 +31,7 @@ module.exports = { const fragment = pragmaUtil.getFragmentFromContext(context); function handleOpeningElement(node) { - markVariableAsUsed(pragma, node, context); + eslintUtil.markVariableAsUsed(pragma, node, context); } // -------------------------------------------------------------------------- // Public @@ -41,7 +41,7 @@ module.exports = { JSXOpeningElement: handleOpeningElement, JSXOpeningFragment: handleOpeningElement, JSXFragment(node) { - markVariableAsUsed(fragment, node, context); + eslintUtil.markVariableAsUsed(fragment, node, context); }, }; }, diff --git a/lib/rules/jsx-uses-vars.js b/lib/rules/jsx-uses-vars.js index a3ad2c2abf..cb7b182266 100644 --- a/lib/rules/jsx-uses-vars.js +++ b/lib/rules/jsx-uses-vars.js @@ -6,7 +6,7 @@ 'use strict'; const docsUrl = require('../util/docsUrl'); -const { markVariableAsUsed } = require('../util/eslint'); +const eslintUtil = require('../util/eslint'); // ------------------------------------------------------------------------------ // Rule Definition @@ -54,7 +54,7 @@ module.exports = { return; } - markVariableAsUsed(name, node, context); + eslintUtil.markVariableAsUsed(name, node, context); }, }; diff --git a/lib/rules/jsx-wrap-multilines.js b/lib/rules/jsx-wrap-multilines.js index 4d1cd8c23d..3353c63923 100644 --- a/lib/rules/jsx-wrap-multilines.js +++ b/lib/rules/jsx-wrap-multilines.js @@ -7,7 +7,7 @@ const has = require('object.hasown/polyfill')(); const docsUrl = require('../util/docsUrl'); -const { getSourceCode } = require('../util/eslint'); +const eslintUtil = require('../util/eslint'); const jsxUtil = require('../util/jsx'); const reportC = require('../util/report'); const isParenthesized = require('../util/ast').isParenthesized; @@ -94,7 +94,7 @@ module.exports = { } function needsOpeningNewLine(node) { - const previousToken = getSourceCode(context).getTokenBefore(node); + const previousToken = eslintUtil.getSourceCode(context).getTokenBefore(node); if (!isParenthesized(context, node)) { return false; @@ -108,7 +108,7 @@ module.exports = { } function needsClosingNewLine(node) { - const nextToken = getSourceCode(context).getTokenAfter(node); + const nextToken = eslintUtil.getSourceCode(context).getTokenAfter(node); if (!isParenthesized(context, node)) { return false; @@ -144,7 +144,7 @@ module.exports = { return; } - const sourceCode = getSourceCode(context); + const sourceCode = eslintUtil.getSourceCode(context); const option = getOption(type); if ((option === true || option === 'parens') && !isParenthesized(context, node) && isMultilines(node)) { diff --git a/lib/rules/no-access-state-in-setstate.js b/lib/rules/no-access-state-in-setstate.js index 1696eb2843..80039411bf 100644 --- a/lib/rules/no-access-state-in-setstate.js +++ b/lib/rules/no-access-state-in-setstate.js @@ -8,7 +8,7 @@ const docsUrl = require('../util/docsUrl'); const componentUtil = require('../util/componentUtil'); const report = require('../util/report'); -const { getScope } = require('../util/eslint'); +const eslintUtil = require('../util/eslint'); // ------------------------------------------------------------------------------ // Rule Definition @@ -50,8 +50,8 @@ module.exports = { function isClassComponent(node) { return !!( - componentUtil.getParentES6Component(node, context) || - componentUtil.getParentES5Component(node, context) + componentUtil.getParentES6Component(node, context) + || componentUtil.getParentES5Component(node, context) ); } @@ -138,7 +138,7 @@ module.exports = { if (current.type === 'VariableDeclarator') { vars.push({ node, - scope: getScope(node, context), + scope: eslintUtil.getScope(node, context), variableName: current.id.name, }); break; @@ -162,7 +162,7 @@ module.exports = { while (current.type !== 'Program') { if (isFirstArgumentInSetStateCall(current, node)) { vars - .filter((v) => v.scope === getScope(node, context) && v.variableName === node.name) + .filter((v) => v.scope === eslintUtil.getScope(node, context) && v.variableName === node.name) .forEach((v) => { report(context, messages.useCallback, 'useCallback', { node: v.node, @@ -180,7 +180,7 @@ module.exports = { if (property && property.key && property.key.name === 'state' && isDerivedFromThis) { vars.push({ node: property.key, - scope: getScope(node, context), + scope: eslintUtil.getScope(node, context), variableName: property.key.name, }); } diff --git a/lib/rules/no-arrow-function-lifecycle.js b/lib/rules/no-arrow-function-lifecycle.js index d04c74cc7c..8eda7cea5d 100644 --- a/lib/rules/no-arrow-function-lifecycle.js +++ b/lib/rules/no-arrow-function-lifecycle.js @@ -13,7 +13,7 @@ const componentUtil = require('../util/componentUtil'); const docsUrl = require('../util/docsUrl'); const lifecycleMethods = require('../util/lifecycleMethods'); const report = require('../util/report'); -const { getSourceCode } = require('../util/eslint'); +const eslintUtil = require('../util/eslint'); function getText(node) { const params = node.value.params.map((p) => p.name); @@ -68,7 +68,7 @@ module.exports = { if (nodeType === 'ArrowFunctionExpression' && isLifecycleMethod) { const body = node.value.body; const isBlockBody = body.type === 'BlockStatement'; - const sourceCode = getSourceCode(context); + const sourceCode = eslintUtil.getSourceCode(context); let nextComment = []; let previousComment = []; diff --git a/lib/rules/no-deprecated.js b/lib/rules/no-deprecated.js index 612dc62f7e..3d1d4b7d85 100644 --- a/lib/rules/no-deprecated.js +++ b/lib/rules/no-deprecated.js @@ -14,7 +14,7 @@ const docsUrl = require('../util/docsUrl'); const pragmaUtil = require('../util/pragma'); const testReactVersion = require('../util/version').testReactVersion; const report = require('../util/report'); -const { getSourceCode } = require('../util/eslint'); +const eslintUtil = require('../util/eslint'); // ------------------------------------------------------------------------------ // Constants @@ -218,7 +218,7 @@ module.exports = { return { MemberExpression(node) { - checkDeprecation(node, getSourceCode(context).getText(node)); + checkDeprecation(node, eslintUtil.getSourceCode(context).getText(node)); }, ImportDeclaration(node) { diff --git a/lib/rules/no-is-mounted.js b/lib/rules/no-is-mounted.js index f5fe4b5896..1e13d682df 100644 --- a/lib/rules/no-is-mounted.js +++ b/lib/rules/no-is-mounted.js @@ -6,7 +6,7 @@ 'use strict'; const docsUrl = require('../util/docsUrl'); -const { getAncestors } = require('../util/eslint'); +const eslintUtil = require('../util/eslint'); const report = require('../util/report'); // ------------------------------------------------------------------------------ @@ -41,7 +41,7 @@ module.exports = { if (callee.object.type !== 'ThisExpression' || callee.property.name !== 'isMounted') { return; } - const ancestors = getAncestors(node, context); + const ancestors = eslintUtil.getAncestors(node, context); for (let i = 0, j = ancestors.length; i < j; i++) { if (ancestors[i].type === 'Property' || ancestors[i].type === 'MethodDefinition') { report(context, messages.noIsMounted, 'noIsMounted', { diff --git a/lib/rules/no-string-refs.js b/lib/rules/no-string-refs.js index 700b5fc6ad..dc237fe188 100644 --- a/lib/rules/no-string-refs.js +++ b/lib/rules/no-string-refs.js @@ -50,10 +50,10 @@ module.exports = { */ function isRefsUsage(node) { return !!( - (componentUtil.getParentES6Component(node, context) || - componentUtil.getParentES5Component(node, context)) && - node.object.type === 'ThisExpression' && - node.property.name === 'refs' + (componentUtil.getParentES6Component(node, context) + || componentUtil.getParentES5Component(node, context)) + && node.object.type === 'ThisExpression' + && node.property.name === 'refs' ); } diff --git a/lib/rules/no-unescaped-entities.js b/lib/rules/no-unescaped-entities.js index 354008b5d5..6a94d76e0f 100644 --- a/lib/rules/no-unescaped-entities.js +++ b/lib/rules/no-unescaped-entities.js @@ -6,7 +6,7 @@ 'use strict'; const docsUrl = require('../util/docsUrl'); -const { getSourceCode } = require('../util/eslint'); +const eslintUtil = require('../util/eslint'); const jsxUtil = require('../util/jsx'); const report = require('../util/report'); @@ -84,9 +84,9 @@ module.exports = { const entities = configuration.forbid || DEFAULTS; // HTML entities are already escaped in node.value (as well as node.raw), - // so pull the raw text from getSourceCode(context) + // so pull the raw text from eslintUtil.getSourceCode(context) for (let i = node.loc.start.line; i <= node.loc.end.line; i++) { - let rawLine = getSourceCode(context).lines[i - 1]; + let rawLine = eslintUtil.getSourceCode(context).lines[i - 1]; let start = 0; let end = rawLine.length; if (i === node.loc.start.line) { diff --git a/lib/rules/no-unknown-property.js b/lib/rules/no-unknown-property.js index a9e7069c50..7f3df258a2 100644 --- a/lib/rules/no-unknown-property.js +++ b/lib/rules/no-unknown-property.js @@ -7,7 +7,7 @@ const has = require('object.hasown/polyfill')(); const docsUrl = require('../util/docsUrl'); -const { getSourceCode } = require('../util/eslint'); +const eslintUtil = require('../util/eslint'); const testReactVersion = require('../util/version').testReactVersion; const report = require('../util/report'); @@ -556,7 +556,7 @@ module.exports = { return { JSXAttribute(node) { const ignoreNames = getIgnoreConfig(); - const actualName = getSourceCode(context).getText(node.name); + const actualName = eslintUtil.getSourceCode(context).getText(node.name); if (ignoreNames.indexOf(actualName) >= 0) { return; } diff --git a/lib/rules/no-unused-state.js b/lib/rules/no-unused-state.js index 69c8ce89dd..cf76d6fe13 100644 --- a/lib/rules/no-unused-state.js +++ b/lib/rules/no-unused-state.js @@ -13,7 +13,7 @@ const docsUrl = require('../util/docsUrl'); const ast = require('../util/ast'); const componentUtil = require('../util/componentUtil'); const report = require('../util/report'); -const { getScope } = require('../util/eslint'); +const eslintUtil = require('../util/eslint'); // Descend through all wrapping TypeCastExpressions and return the expression // that was cast. @@ -108,7 +108,7 @@ module.exports = { 'componentDidUpdate', ]; - let scope = getScope(node, context); + let scope = eslintUtil.getScope(node, context); while (scope) { const parent = scope.block && scope.block.parent; if ( @@ -369,7 +369,7 @@ module.exports = { return; } - const childScope = getScope(node, context).childScopes.find( + const childScope = eslintUtil.getScope(node, context).childScopes.find( (x) => x.block === node.value ); if (!childScope) { diff --git a/lib/rules/prefer-exact-props.js b/lib/rules/prefer-exact-props.js index 8143782ad7..641920c639 100644 --- a/lib/rules/prefer-exact-props.js +++ b/lib/rules/prefer-exact-props.js @@ -10,7 +10,7 @@ const propsUtil = require('../util/props'); const propWrapperUtil = require('../util/propWrapper'); const variableUtil = require('../util/variable'); const report = require('../util/report'); -const { getSourceCode } = require('../util/eslint'); +const eslintUtil = require('../util/eslint'); // ----------------------------------------------------------------------------- // Rule Definition @@ -37,7 +37,7 @@ module.exports = { create: Components.detect((context, components, utils) => { const typeAliases = {}; const exactWrappers = propWrapperUtil.getExactPropWrapperFunctions(context); - const sourceCode = getSourceCode(context); + const sourceCode = eslintUtil.getSourceCode(context); function getPropTypesErrorMessage() { const formattedWrappers = propWrapperUtil.formatPropWrapperFunctions(exactWrappers); diff --git a/lib/rules/prefer-stateless-function.js b/lib/rules/prefer-stateless-function.js index 25ff7923ba..127b610168 100644 --- a/lib/rules/prefer-stateless-function.js +++ b/lib/rules/prefer-stateless-function.js @@ -15,7 +15,7 @@ const astUtil = require('../util/ast'); const componentUtil = require('../util/componentUtil'); const docsUrl = require('../util/docsUrl'); const report = require('../util/report'); -const { getScope, getSourceCode } = require('../util/eslint'); +const eslintUtil = require('../util/eslint'); // ------------------------------------------------------------------------------ // Rule Definition @@ -333,7 +333,7 @@ module.exports = { // Mark `ref` usage JSXAttribute(node) { - const name = getSourceCode(context).getText(node.name); + const name = eslintUtil.getSourceCode(context).getText(node.name); if (name !== 'ref') { return; } @@ -343,7 +343,7 @@ module.exports = { // Mark `render` that do not return some JSX ReturnStatement(node) { let blockNode; - let scope = getScope(node, context); + let scope = eslintUtil.getScope(node, context); while (scope) { blockNode = scope.block && scope.block.parent; if (blockNode && (blockNode.type === 'MethodDefinition' || blockNode.type === 'Property')) { diff --git a/lib/rules/require-optimization.js b/lib/rules/require-optimization.js index e3edb78296..bb4bb383fb 100644 --- a/lib/rules/require-optimization.js +++ b/lib/rules/require-optimization.js @@ -11,7 +11,7 @@ const Components = require('../util/Components'); const componentUtil = require('../util/componentUtil'); const docsUrl = require('../util/docsUrl'); const report = require('../util/report'); -const { getScope } = require('../util/eslint'); +const eslintUtil = require('../util/eslint'); const messages = { noShouldComponentUpdate: 'Component is not optimized. Please add a shouldComponentUpdate method.', @@ -155,11 +155,12 @@ module.exports = { /** * Checks if we are declaring function in class + * @param {ASTNode} node The AST node being checked. * @returns {Boolean} True if we are declaring function in class, false if not. */ function isFunctionInClass(node) { let blockNode; - let scope = getScope(node, context); + let scope = eslintUtil.getScope(node, context); while (scope) { blockNode = scope.block; if (blockNode && blockNode.type === 'ClassDeclaration') { diff --git a/lib/rules/require-render-return.js b/lib/rules/require-render-return.js index c2ef52bb84..6305457550 100644 --- a/lib/rules/require-render-return.js +++ b/lib/rules/require-render-return.js @@ -12,7 +12,7 @@ const astUtil = require('../util/ast'); const componentUtil = require('../util/componentUtil'); const docsUrl = require('../util/docsUrl'); const report = require('../util/report'); -const { getAncestors } = require('../util/eslint'); +const eslintUtil = require('../util/eslint'); // ------------------------------------------------------------------------------ // Rule Definition @@ -62,7 +62,7 @@ module.exports = { return { ReturnStatement(node) { - const ancestors = getAncestors(node, context).reverse(); + const ancestors = eslintUtil.getAncestors(node, context).reverse(); let depth = 0; ancestors.forEach((ancestor) => { if (/Function(Expression|Declaration)$/.test(ancestor.type)) { diff --git a/lib/rules/sort-default-props.js b/lib/rules/sort-default-props.js index b0e2f373f1..316404d451 100644 --- a/lib/rules/sort-default-props.js +++ b/lib/rules/sort-default-props.js @@ -9,7 +9,7 @@ const variableUtil = require('../util/variable'); const docsUrl = require('../util/docsUrl'); const report = require('../util/report'); -const { getSourceCode } = require('../util/eslint'); +const eslintUtil = require('../util/eslint'); // ------------------------------------------------------------------------------ // Rule Definition @@ -61,7 +61,7 @@ module.exports = { // (babel-eslint@5 does not expose property name so we have to rely on tokens) } if (node.type === 'ClassProperty') { - const tokens = getSourceCode(context).getFirstTokens(node, 2); + const tokens = eslintUtil.getSourceCode(context).getFirstTokens(node, 2); return tokens[1] && tokens[1].type === 'Identifier' ? tokens[1].value : tokens[0].value; } return ''; @@ -78,7 +78,7 @@ module.exports = { } function getKey(node) { - return getSourceCode(context).getText(node.key || node.argument); + return eslintUtil.getSourceCode(context).getText(node.key || node.argument); } /** diff --git a/lib/rules/sort-prop-types.js b/lib/rules/sort-prop-types.js index fb77362cfd..0400d08dec 100644 --- a/lib/rules/sort-prop-types.js +++ b/lib/rules/sort-prop-types.js @@ -10,7 +10,7 @@ const docsUrl = require('../util/docsUrl'); const propWrapperUtil = require('../util/propWrapper'); const propTypesSortUtil = require('../util/propTypesSort'); const report = require('../util/report'); -const { getSourceCode } = require('../util/eslint'); +const eslintUtil = require('../util/eslint'); // ------------------------------------------------------------------------------ // Rule Definition @@ -24,12 +24,12 @@ const messages = { function getKey(context, node) { if (node.type === 'ObjectTypeProperty') { - return getSourceCode(context).getFirstToken(node).value; + return eslintUtil.getSourceCode(context).getFirstToken(node).value; } if (node.key && node.key.value) { return node.key.value; } - return getSourceCode(context).getText(node.key || node.argument); + return eslintUtil.getSourceCode(context).getText(node.key || node.argument); } function getValueName(node) { diff --git a/lib/rules/static-property-placement.js b/lib/rules/static-property-placement.js index 17013f4d9e..1b63cac38f 100644 --- a/lib/rules/static-property-placement.js +++ b/lib/rules/static-property-placement.js @@ -12,7 +12,7 @@ const astUtil = require('../util/ast'); const componentUtil = require('../util/componentUtil'); const propsUtil = require('../util/props'); const report = require('../util/report'); -const { getScope } = require('../util/eslint'); +const eslintUtil = require('../util/eslint'); // ------------------------------------------------------------------------------ // Positioning Options @@ -98,11 +98,12 @@ module.exports = { /** * Checks if we are declaring context in class + * @param {ASTNode} node The node to check * @returns {Boolean} True if we are declaring context in class, false if not. */ function isContextInClass(node) { let blockNode; - let scope = getScope(node, context); + let scope = eslintUtil.getScope(node, context); while (scope) { blockNode = scope.block; if (blockNode && blockNode.type === 'ClassDeclaration') { @@ -161,7 +162,7 @@ module.exports = { // If definition type is undefined then it must not be a defining expression or if the definition is inside a // class body then skip this node. const right = node.parent.right; - if (!right || right.type === 'undefined' || isContextInClass()) { + if (!right || right.type === 'undefined' || isContextInClass(node)) { return; } @@ -180,9 +181,9 @@ module.exports = { MethodDefinition(node) { // If the function is inside a class and is static getter then check if correctly positioned if ( - componentUtil.getParentES6Component(node, context) && - node.static && - node.kind === 'get' + componentUtil.getParentES6Component(node, context) + && node.static + && node.kind === 'get' ) { // Report error if needed reportNodeIncorrectlyPositioned(node, STATIC_GETTER); diff --git a/lib/util/Components.js b/lib/util/Components.js index 78e3b4c9f7..631dafbdba 100644 --- a/lib/util/Components.js +++ b/lib/util/Components.js @@ -21,7 +21,7 @@ const usedPropTypesUtil = require('./usedPropTypes'); const defaultPropsUtil = require('./defaultProps'); const isFirstLetterCapitalized = require('./isFirstLetterCapitalized'); const isDestructuredFromPragmaImport = require('./isDestructuredFromPragmaImport'); -const { getScope, getSourceCode } = require('./eslint'); +const eslintUtil = require('./eslint'); function getId(node) { return node ? `${node.range[0]}:${node.range[1]}` : ''; @@ -283,19 +283,12 @@ function mergeRules(rules) { function componentRule(rule, context) { const pragma = pragmaUtil.getFromContext(context); - const sourceCode = getSourceCode(context); + const sourceCode = eslintUtil.getSourceCode(context); const components = new Components(); const wrapperFunctions = getWrapperFunctions(context, pragma); // Utilities for component detection const utils = { - /** - * Check if variable is destructured from pragma import - * - * @param (ASTNode) node The AST node to check - * @param {string} variable The variable name to check - * @returns {Boolean} True if createElement is destructured from the pragma - */ isDestructuredFromPragmaImport(ASTNode, variable) { return isDestructuredFromPragmaImport(variable, ASTNode, context); }, @@ -429,13 +422,14 @@ function componentRule(rule, context) { /** * Get the parent component node from the current scope * + * @param {ASTNode} node The AST node being checked * @returns {ASTNode} component node, null if we are not in a component */ getParentComponent(node) { return ( - componentUtil.getParentES6Component(node, context) || - componentUtil.getParentES5Component(node, context) || - utils.getParentStatelessComponent(node) + componentUtil.getParentES6Component(node, context) + || componentUtil.getParentES5Component(node, context) + || utils.getParentStatelessComponent(node) ); }, @@ -618,10 +612,9 @@ function componentRule(rule, context) { * @returns {ASTNode} component node, null if we are not in a component */ getParentStatelessComponent(node) { - let scope = getScope(node, context); + let scope = eslintUtil.getScope(node, context); while (scope) { - const node = scope.block; - const statelessComponent = utils.getStatelessComponent(node); + const statelessComponent = utils.getStatelessComponent(scope.block); if (statelessComponent) { return statelessComponent; } @@ -779,9 +772,8 @@ function componentRule(rule, context) { && node.callee.type === 'Identifier' && node.callee.name.match(USE_HOOK_PREFIX_REGEX); - const scope = - (isPotentialReactHookCall || isPotentialHookCall) && - getScope(node, context); + const scope = (isPotentialReactHookCall || isPotentialHookCall) + && eslintUtil.getScope(node, context); const reactResolvedDefs = isPotentialReactHookCall && scope.references diff --git a/lib/util/ast.js b/lib/util/ast.js index e45abad271..90e94b00f3 100644 --- a/lib/util/ast.js +++ b/lib/util/ast.js @@ -5,7 +5,7 @@ 'use strict'; const estraverse = require('estraverse'); -const { getScope, getSourceCode } = require('./eslint'); +const eslintUtil = require('./eslint'); // const pragmaUtil = require('./pragma'); /** @@ -187,7 +187,7 @@ function getComponentProperties(node) { * @return {ASTNode} the first node in the line */ function getFirstNodeInLine(context, node) { - const sourceCode = getSourceCode(context); + const sourceCode = eslintUtil.getSourceCode(context); let token = node; let lines; do { @@ -258,7 +258,7 @@ function isClass(node) { * @return {boolean} */ function inConstructor(node, context) { - let scope = getScope(node, context); + let scope = eslintUtil.getScope(node, context); while (scope) { // @ts-ignore if (scope.block && scope.block.parent && scope.block.parent.kind === 'constructor') { @@ -286,7 +286,7 @@ function stripQuotes(string) { */ function getKeyValue(context, node) { if (node.type === 'ObjectTypeProperty') { - const tokens = getSourceCode(context).getFirstTokens(node, 2); + const tokens = eslintUtil.getSourceCode(context).getFirstTokens(node, 2); return (tokens[0].value === '+' || tokens[0].value === '-' ? tokens[1].value : stripQuotes(tokens[0].value) @@ -313,7 +313,7 @@ function getKeyValue(context, node) { * @returns {boolean} */ function isParenthesized(context, node) { - const sourceCode = getSourceCode(context); + const sourceCode = eslintUtil.getSourceCode(context); const previousToken = sourceCode.getTokenBefore(node); const nextToken = sourceCode.getTokenAfter(node); diff --git a/lib/util/componentUtil.js b/lib/util/componentUtil.js index aabe452386..c106f5ebfd 100644 --- a/lib/util/componentUtil.js +++ b/lib/util/componentUtil.js @@ -2,7 +2,7 @@ const doctrine = require('doctrine'); const pragmaUtil = require('./pragma'); -const { getScope, getSourceCode } = require('./eslint'); +const eslintUtil = require('./eslint'); // eslint-disable-next-line valid-jsdoc /** @@ -58,7 +58,7 @@ function isES5Component(node, context) { * @returns {boolean} */ function isExplicitComponent(node, context) { - const sourceCode = getSourceCode(context); + const sourceCode = eslintUtil.getSourceCode(context); let comment; // Sometimes the passed node may not have been parsed yet by eslint, and this function call crashes. // Can be removed when eslint sets "parent" property for all nodes on initial AST traversal: https://github.com/eslint/eslint-scope/issues/27 @@ -121,7 +121,7 @@ function isES6Component(node, context) { * @returns {ASTNode|null} */ function getParentES5Component(node, context) { - let scope = getScope(node, context); + let scope = eslintUtil.getScope(node, context); while (scope) { // @ts-ignore node = scope.block && scope.block.parent && scope.block.parent.parent; @@ -140,7 +140,7 @@ function getParentES5Component(node, context) { * @returns {ASTNode | null} */ function getParentES6Component(node, context) { - let scope = getScope(node, context); + let scope = eslintUtil.getScope(node, context); while (scope && scope.type !== 'class') { scope = scope.upper; } @@ -159,7 +159,7 @@ function getParentES6Component(node, context) { */ function isPureComponent(node, context) { const pragma = getPragma(context); - const sourceCode = getSourceCode(context); + const sourceCode = eslintUtil.getSourceCode(context); if (node.superClass) { return new RegExp(`^(${pragma}\\.)?PureComponent$`).test(sourceCode.getText(node.superClass)); } diff --git a/lib/util/defaultProps.js b/lib/util/defaultProps.js index 9d51c9b143..752f9b0671 100644 --- a/lib/util/defaultProps.js +++ b/lib/util/defaultProps.js @@ -10,12 +10,12 @@ const componentUtil = require('./componentUtil'); const propsUtil = require('./props'); const variableUtil = require('./variable'); const propWrapperUtil = require('./propWrapper'); -const { getSourceCode } = require('./eslint'); +const eslintUtil = require('./eslint'); const QUOTES_REGEX = /^["']|["']$/g; module.exports = function defaultPropsInstructions(context, components, utils) { - const sourceCode = getSourceCode(context); + const sourceCode = eslintUtil.getSourceCode(context); /** * Try to resolve the node passed in to a variable in the current scope. If the node passed in is not diff --git a/lib/util/eslint.js b/lib/util/eslint.js index 4f1610df95..f76d8e186d 100644 --- a/lib/util/eslint.js +++ b/lib/util/eslint.js @@ -1,5 +1,7 @@ +'use strict'; + function getSourceCode(context) { - return context.sourceCode ?? context.getSourceCode(); + return context.sourceCode || context.getSourceCode(); } function getScope(node, context) { diff --git a/lib/util/makeNoMethodSetStateRule.js b/lib/util/makeNoMethodSetStateRule.js index 4b1e8f54df..0430b64e03 100644 --- a/lib/util/makeNoMethodSetStateRule.js +++ b/lib/util/makeNoMethodSetStateRule.js @@ -9,7 +9,7 @@ const findLast = require('array.prototype.findlast'); const docsUrl = require('./docsUrl'); const report = require('./report'); -const { getAncestors } = require('./eslint'); +const eslintUtil = require('./eslint'); const testReactVersion = require('./version').testReactVersion; // ------------------------------------------------------------------------------ @@ -94,7 +94,7 @@ module.exports = function makeNoMethodSetStateRule(methodName, shouldCheckUnsafe ) { return; } - const ancestors = getAncestors(node, context); + const ancestors = eslintUtil.getAncestors(node, context); let depth = 0; findLast(ancestors, (ancestor) => { // ancestors.some((ancestor) => { diff --git a/lib/util/pragma.js b/lib/util/pragma.js index 49ed713d2a..d4f89c8e51 100644 --- a/lib/util/pragma.js +++ b/lib/util/pragma.js @@ -5,7 +5,7 @@ 'use strict'; -const { getSourceCode } = require("./eslint"); +const eslintUtil = require('./eslint'); const JSX_ANNOTATION_REGEX = /@jsx\s+([^\s]+)/; // Does not check for reserved keywords or unicode characters @@ -50,7 +50,7 @@ function getFragmentFromContext(context) { function getFromContext(context) { let pragma = 'React'; - const sourceCode = getSourceCode(context); + const sourceCode = eslintUtil.getSourceCode(context); const pragmaNode = sourceCode.getAllComments().find((node) => JSX_ANNOTATION_REGEX.test(node.value)); if (pragmaNode) { diff --git a/lib/util/propTypes.js b/lib/util/propTypes.js index 95b4fa7758..5afe836405 100644 --- a/lib/util/propTypes.js +++ b/lib/util/propTypes.js @@ -13,7 +13,7 @@ const testFlowVersion = require('./version').testFlowVersion; const propWrapperUtil = require('./propWrapper'); const astUtil = require('./ast'); const isFirstLetterCapitalized = require('./isFirstLetterCapitalized'); -const { getScope, getSourceCode } = require('./eslint'); +const eslintUtil = require('./eslint'); /** * Check if node is function type. @@ -369,7 +369,7 @@ module.exports = function propTypesInstructions(context, components, utils) { node && node.type === 'Identifier' ) { - const scope = getScope(node, context); + const scope = eslintUtil.getScope(node, context); const identVariable = scope.variableScope.variables.find( (variable) => variable.name === node.name ); @@ -579,7 +579,7 @@ module.exports = function propTypesInstructions(context, components, utils) { this.declaredPropTypes = declaredPropTypes; this.foundDeclaredPropertiesList = []; this.referenceNameMap = new Set(); - this.sourceCode = getSourceCode(context); + this.sourceCode = eslintUtil.getSourceCode(context); this.shouldIgnorePropTypes = false; this.visitTSNode(this.propTypes); this.endAndStructDeclaredPropTypes(); @@ -950,10 +950,10 @@ module.exports = function propTypesInstructions(context, components, utils) { if ( propWrapperUtil.isPropWrapperFunction( context, - getSourceCode(context).getText(propTypes.callee) - ) && - propTypes.arguments && - propTypes.arguments[0] + eslintUtil.getSourceCode(context).getText(propTypes.callee) + ) + && propTypes.arguments + && propTypes.arguments[0] ) { markPropTypesAsDeclared(node, propTypes.arguments[0]); return; diff --git a/lib/util/propTypesSort.js b/lib/util/propTypesSort.js index 348fdd6968..e2248eef18 100644 --- a/lib/util/propTypesSort.js +++ b/lib/util/propTypesSort.js @@ -7,7 +7,7 @@ const toSorted = require('array.prototype.tosorted'); const astUtil = require('./ast'); -const { getSourceCode } = require('./eslint'); +const eslintUtil = require('./eslint'); /** * Returns the value name of a node. @@ -137,7 +137,7 @@ function fixPropTypesSort( ) { function sortInSource(allNodes, source) { const originalSource = source; - const sourceCode = getSourceCode(context); + const sourceCode = eslintUtil.getSourceCode(context); for (let i = 0; i < allNodes.length; i++) { const node = allNodes[i]; let commentAfter = []; @@ -200,7 +200,7 @@ function fixPropTypesSort( return source; } - const source = sortInSource(declarations, getSourceCode(context).getText()); + const source = sortInSource(declarations, eslintUtil.getSourceCode(context).getText()); const rangeStart = commentnodeMap.get(declarations[0]).start; const rangeEnd = commentnodeMap.get(declarations[declarations.length - 1]).end; diff --git a/lib/util/usedPropTypes.js b/lib/util/usedPropTypes.js index b556898165..1f993cf3b5 100644 --- a/lib/util/usedPropTypes.js +++ b/lib/util/usedPropTypes.js @@ -10,7 +10,7 @@ const astUtil = require('./ast'); const componentUtil = require('./componentUtil'); const testReactVersion = require('./version').testReactVersion; const ast = require('./ast'); -const { getScope, getSourceCode } = require('./eslint'); +const eslintUtil = require('./eslint'); // ------------------------------------------------------------------------------ // Constants @@ -86,7 +86,7 @@ function mustBeValidated(component) { * @return {boolean} true if we are in a class constructor, false if not */ function inLifeCycleMethod(node, context, checkAsyncSafeLifeCycles) { - let scope = getScope(node, context); + let scope = eslintUtil.getScope(node, context); while (scope) { if (scope.block && scope.block.parent && scope.block.parent.key) { const name = scope.block.parent.key.name; @@ -164,7 +164,7 @@ function isPropArgumentInSetStateUpdater(node, context, name) { if (typeof name !== 'string') { return; } - let scope = getScope(node, context); + let scope = eslintUtil.getScope(node, context); while (scope) { const unwrappedParentCalleeNode = scope.block && scope.block.parent @@ -187,14 +187,14 @@ function isPropArgumentInSetStateUpdater(node, context, name) { } /** - * @param (ASTNode) node + * @param {ASTNode} node * @param {Context} context * @returns {boolean} */ function isInClassComponent(node, context) { return !!( - componentUtil.getParentES6Component(node, context) || - componentUtil.getParentES5Component(node, context) + componentUtil.getParentES6Component(node, context) + || componentUtil.getParentES5Component(node, context) ); } @@ -217,7 +217,7 @@ function isThisDotProps(node) { * @returns {Boolean} True if the prop has spread operator, false if not. */ function hasSpreadOperator(context, node) { - const tokens = getSourceCode(context).getTokens(node); + const tokens = eslintUtil.getSourceCode(context).getTokens(node); return tokens.length && tokens[0].value === '...'; } @@ -239,9 +239,9 @@ function isPropTypesUsageByMemberExpression(node, context, utils, checkAsyncSafe } // props.* or prevProps.* or nextProps.* if ( - isCommonVariableNameForProps(unwrappedObjectNode.name) && - (inLifeCycleMethod(node, context, checkAsyncSafeLifeCycles) || - astUtil.inConstructor(node, context)) + isCommonVariableNameForProps(unwrappedObjectNode.name) + && (inLifeCycleMethod(node, context, checkAsyncSafeLifeCycles) + || astUtil.inConstructor(node, context)) ) { return true; } @@ -480,9 +480,9 @@ module.exports = function usedPropTypesInstructions(context, components, utils) // let props = this.props if ( - isThisDotProps(unwrappedInitNode) && - isInClassComponent(node, context) && - node.id.type === 'Identifier' + isThisDotProps(unwrappedInitNode) + && isInClassComponent(node, context) + && node.id.type === 'Identifier' ) { propVariables.set(node.id.name, []); } @@ -520,8 +520,8 @@ module.exports = function usedPropTypesInstructions(context, components, utils) // let {firstname} = this.props if ( - isThisDotProps(unwrappedInitNode) && - isInClassComponent(node, context) + isThisDotProps(unwrappedInitNode) + && isInClassComponent(node, context) ) { markPropTypesAsUsed(node.id); return; diff --git a/lib/util/variable.js b/lib/util/variable.js index 3704fc1da1..d3dfe98d4e 100644 --- a/lib/util/variable.js +++ b/lib/util/variable.js @@ -6,7 +6,7 @@ 'use strict'; const toReversed = require('array.prototype.toreversed'); -const { getScope } = require('./eslint'); +const eslintUtil = require('./eslint'); /** * Search a particular variable in a list @@ -38,7 +38,7 @@ function getVariable(variables, name) { * @returns {Array} The variables list */ function variablesInScope(node, context) { - let scope = getScope(node, context); + let scope = eslintUtil.getScope(node, context); let variables = scope.variables; while (scope.type !== 'global') { From 240d5510b2abbc169503a1314e4b6989bcf1ba37 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20=C5=81opaci=C5=84ski?= Date: Sun, 28 Apr 2024 15:42:06 +0200 Subject: [PATCH 3/6] Add v9 to package.json --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 685e65a222..0ed6bf3874 100644 --- a/package.json +++ b/package.json @@ -57,7 +57,7 @@ "@typescript-eslint/parser": "^2.34.0 || ^3.10.1 || ^4.0.0 || ^5.0.0", "aud": "^2.0.4", "babel-eslint": "^8 || ^9 || ^10.1.0", - "eslint": "^3 || ^4 || ^5 || ^6 || ^7 || ^8", + "eslint": "^3 || ^4 || ^5 || ^6 || ^7 || ^8 | ^9", "eslint-config-airbnb-base": "^15.0.0", "eslint-doc-generator": "^1.7.0", "eslint-plugin-eslint-plugin": "^2.3.0 || ^3.5.3 || ^4.0.1 || ^5.0.5", From fb91d5a5a654a447dd1166c81a3697f646c99fff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20=C5=81opaci=C5=84ski?= Date: Sun, 28 Apr 2024 22:56:13 +0200 Subject: [PATCH 4/6] Adjust some tests to match eslint v9 config --- lib/util/Components.js | 13 +- lib/util/annotations.js | 4 +- lib/util/eslint.js | 8 + lib/util/propTypes.js | 2 +- lib/util/usedPropTypes.js | 2 +- package.json | 6 +- tests/helpers/parsers-old.js | 183 ++++++ tests/helpers/parsers.js | 138 ++-- tests/lib/rules/boolean-prop-naming.js | 10 +- tests/lib/rules/button-has-type.js | 591 +++++++++--------- .../checked-requires-onchange-or-readonly.js | 8 +- .../rules/default-props-match-prop-types.js | 14 +- tests/lib/rules/destructuring-assignment.js | 10 +- tests/lib/rules/display-name.js | 10 +- tests/lib/rules/forbid-component-props.js | 25 +- tests/lib/rules/forbid-dom-props.js | 10 +- tests/lib/rules/forbid-elements.js | 10 +- tests/lib/rules/forbid-foreign-prop-types.js | 10 +- tests/lib/rules/forbid-prop-types.js | 10 +- .../rules/function-component-definition.js | 10 +- tests/lib/rules/hook-use-state.js | 6 +- tests/lib/rules/iframe-missing-sandbox.js | 10 +- tests/lib/rules/jsx-boolean-value.js | 10 +- tests/lib/rules/jsx-child-element-spacing.js | 10 +- .../lib/rules/jsx-closing-bracket-location.js | 10 +- tests/lib/rules/jsx-closing-tag-location.js | 10 +- tests/lib/rules/jsx-curly-brace-presence.js | 22 +- tests/lib/rules/jsx-curly-newline.js | 10 +- tests/lib/rules/jsx-curly-spacing.js | 18 +- tests/lib/rules/jsx-equals-spacing.js | 10 +- tests/lib/rules/jsx-filename-extension.js | 10 +- tests/lib/rules/jsx-first-prop-new-line.js | 10 +- tests/lib/rules/jsx-fragments.js | 11 +- tests/lib/rules/jsx-handler-names.js | 16 +- tests/lib/rules/jsx-indent-props.js | 10 +- tests/lib/rules/jsx-indent.js | 18 +- tests/lib/rules/jsx-key.js | 10 +- tests/lib/rules/jsx-max-depth.js | 10 +- tests/lib/rules/jsx-max-props-per-line.js | 30 +- tests/lib/rules/jsx-newline.js | 10 +- tests/lib/rules/jsx-no-bind.js | 10 +- tests/lib/rules/jsx-no-comment-textnodes.js | 10 +- .../jsx-no-constructed-context-values.js | 10 +- tests/lib/rules/jsx-no-duplicate-props.js | 10 +- tests/lib/rules/jsx-no-leaked-render.js | 18 +- tests/lib/rules/jsx-no-literals.js | 10 +- tests/lib/rules/jsx-no-script-url.js | 10 +- tests/lib/rules/jsx-no-target-blank.js | 10 +- tests/lib/rules/jsx-no-undef.js | 14 +- tests/lib/rules/jsx-no-useless-fragment.js | 11 +- .../lib/rules/jsx-one-expression-per-line.js | 140 ++--- tests/lib/rules/jsx-pascal-case.js | 10 +- tests/lib/rules/jsx-props-no-multi-spaces.js | 10 +- tests/lib/rules/jsx-props-no-spreading.js | 10 +- tests/lib/rules/jsx-sort-default-props.js | 10 +- tests/lib/rules/jsx-sort-props.js | 10 +- tests/lib/rules/jsx-space-before-closing.js | 10 +- tests/lib/rules/jsx-tag-spacing.js | 10 +- tests/lib/rules/jsx-uses-react.js | 10 +- tests/lib/rules/jsx-uses-vars.js | 10 +- tests/lib/rules/jsx-wrap-multilines.js | 20 +- .../lib/rules/no-access-state-in-setstate.js | 44 +- .../lib/rules/no-adjacent-inline-elements.js | 44 +- tests/lib/rules/no-array-index-key.js | 10 +- .../lib/rules/no-arrow-function-lifecycle.js | 10 +- tests/lib/rules/no-children-prop.js | 10 +- tests/lib/rules/no-danger-with-children.js | 10 +- tests/lib/rules/no-danger.js | 10 +- tests/lib/rules/no-deprecated.js | 10 +- tests/lib/rules/no-did-mount-set-state.js | 10 +- tests/lib/rules/no-did-update-set-state.js | 10 +- tests/lib/rules/no-direct-mutation-state.js | 10 +- tests/lib/rules/no-find-dom-node.js | 10 +- tests/lib/rules/no-invalid-html-attribute.js | 10 +- tests/lib/rules/no-is-mounted.js | 10 +- tests/lib/rules/no-multi-comp.js | 12 +- tests/lib/rules/no-namespace.js | 10 +- .../rules/no-object-type-as-default-prop.js | 10 +- .../no-redundant-should-component-update.js | 36 +- tests/lib/rules/no-render-return-value.js | 10 +- tests/lib/rules/no-set-state.js | 10 +- tests/lib/rules/no-string-refs.js | 8 +- tests/lib/rules/no-this-in-sfc.js | 10 +- tests/lib/rules/no-typos.js | 204 +++--- tests/lib/rules/no-unescaped-entities.js | 10 +- tests/lib/rules/no-unknown-property.js | 10 +- tests/lib/rules/no-unsafe.js | 10 +- .../rules/no-unstable-nested-components.js | 10 +- .../no-unused-class-component-methods.js | 10 +- tests/lib/rules/no-unused-prop-types.js | 20 +- tests/lib/rules/no-unused-state.js | 14 +- tests/lib/rules/no-will-update-set-state.js | 10 +- tests/lib/rules/prefer-es6-class.js | 10 +- tests/lib/rules/prefer-exact-props.js | 12 +- tests/lib/rules/prefer-read-only-props.js | 10 +- tests/lib/rules/prefer-stateless-function.js | 12 +- tests/lib/rules/prop-types.js | 10 +- tests/lib/rules/react-in-jsx-scope.js | 13 +- tests/lib/rules/require-default-props.js | 14 +- tests/lib/rules/require-optimization.js | 10 +- tests/lib/rules/require-render-return.js | 10 +- tests/lib/rules/self-closing-comp.js | 10 +- tests/lib/rules/sort-comp.js | 16 +- tests/lib/rules/sort-default-props.js | 10 +- tests/lib/rules/sort-prop-types.js | 10 +- tests/lib/rules/state-in-constructor.js | 8 +- tests/lib/rules/static-property-placement.js | 2 +- tests/lib/rules/style-prop-object.js | 12 +- .../rules/void-dom-elements-no-children.js | 12 +- 109 files changed, 1411 insertions(+), 1070 deletions(-) create mode 100644 tests/helpers/parsers-old.js diff --git a/lib/util/Components.js b/lib/util/Components.js index 631dafbdba..537f519e62 100644 --- a/lib/util/Components.js +++ b/lib/util/Components.js @@ -637,14 +637,15 @@ function componentRule(rule, context) { let componentNode; // Get the component path const componentPath = []; - while (node) { - if (node.property && node.property.type === 'Identifier') { - componentPath.push(node.property.name); + let currentNode = node; + while (currentNode) { + if (currentNode.property && currentNode.property.type === 'Identifier') { + componentPath.push(currentNode.property.name); } - if (node.object && node.object.type === 'Identifier') { - componentPath.push(node.object.name); + if (currentNode.object && currentNode.object.type === 'Identifier') { + componentPath.push(currentNode.object.name); } - node = node.object; + currentNode = currentNode.object; } componentPath.reverse(); const componentName = componentPath.slice(0, componentPath.length - 1).join('.'); diff --git a/lib/util/annotations.js b/lib/util/annotations.js index 60aaef8cd0..63868d1f83 100644 --- a/lib/util/annotations.js +++ b/lib/util/annotations.js @@ -6,6 +6,8 @@ 'use strict'; +const eslintUtil = require('./eslint'); + /** * Checks if we are declaring a `props` argument with a flow type annotation. * @param {ASTNode} node The AST node being checked. @@ -19,7 +21,7 @@ function isAnnotatedFunctionPropsDeclaration(node, context) { const typeNode = node.params[0].type === 'AssignmentPattern' ? node.params[0].left : node.params[0]; - const tokens = context.getFirstTokens(typeNode, 2); + const tokens = eslintUtil.getFirstTokens(typeNode, context, 2); const isAnnotated = typeNode.typeAnnotation; const isDestructuredProps = typeNode.type === 'ObjectPattern'; const isProps = tokens[0].value === 'props' || (tokens[1] && tokens[1].value === 'props'); diff --git a/lib/util/eslint.js b/lib/util/eslint.js index f76d8e186d..0ce8dc58f1 100644 --- a/lib/util/eslint.js +++ b/lib/util/eslint.js @@ -21,9 +21,17 @@ function markVariableAsUsed(name, node, context) { : context.markVariableAsUsed(name); } +function getFirstTokens(node, context, count) { + const sourceCode = getSourceCode(context); + return sourceCode.getFirstTokens + ? sourceCode.getFirstTokens(node, count) + : context.getFirstTokens(node, count); +} + module.exports = { getSourceCode, getScope, getAncestors, markVariableAsUsed, + getFirstTokens, }; diff --git a/lib/util/propTypes.js b/lib/util/propTypes.js index 5afe836405..774e566d92 100644 --- a/lib/util/propTypes.js +++ b/lib/util/propTypes.js @@ -1111,7 +1111,7 @@ module.exports = function propTypesInstructions(context, components, utils) { */ function isAnnotatedClassPropsDeclaration(node) { if (node && (node.type === 'ClassProperty' || node.type === 'PropertyDefinition')) { - const tokens = context.getFirstTokens(node, 2); + const tokens = eslintUtil.getFirstTokens(node, context, 2); if ( node.typeAnnotation && ( tokens[0].value === 'props' diff --git a/lib/util/usedPropTypes.js b/lib/util/usedPropTypes.js index 1f993cf3b5..1e9a4a9cc4 100644 --- a/lib/util/usedPropTypes.js +++ b/lib/util/usedPropTypes.js @@ -369,7 +369,7 @@ module.exports = function usedPropTypesInstructions(context, components, utils) throw new Error(`${node.type} ASTNodes are not handled by markPropTypesAsUsed`); } - const component = components.get(utils.getParentComponent()); + const component = components.get(utils.getParentComponent(node)); const usedPropTypes = (component && component.usedPropTypes) || []; let ignoreUnusedPropTypesValidation = (component && component.ignoreUnusedPropTypesValidation) || false; diff --git a/package.json b/package.json index 0ed6bf3874..7ae788f79c 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "eslint-plugin-react", - "version": "7.34.1", + "version": "7.34.0", "author": "Yannick Croissant ", "description": "React specific linting rules for ESLint", "main": "index.js", @@ -57,7 +57,7 @@ "@typescript-eslint/parser": "^2.34.0 || ^3.10.1 || ^4.0.0 || ^5.0.0", "aud": "^2.0.4", "babel-eslint": "^8 || ^9 || ^10.1.0", - "eslint": "^3 || ^4 || ^5 || ^6 || ^7 || ^8 | ^9", + "eslint": "^3 || ^4 || ^5 || ^6 || ^7 || ^8 || ^9", "eslint-config-airbnb-base": "^15.0.0", "eslint-doc-generator": "^1.7.0", "eslint-plugin-eslint-plugin": "^2.3.0 || ^3.5.3 || ^4.0.1 || ^5.0.5", @@ -78,7 +78,7 @@ "typescript-eslint-parser": "^20.1.1" }, "peerDependencies": { - "eslint": "^3 || ^4 || ^5 || ^6 || ^7 || ^8" + "eslint": "^3 || ^4 || ^5 || ^6 || ^7 || ^8 || ^9" }, "engines": { "node": ">=4" diff --git a/tests/helpers/parsers-old.js b/tests/helpers/parsers-old.js new file mode 100644 index 0000000000..59205a509a --- /dev/null +++ b/tests/helpers/parsers-old.js @@ -0,0 +1,183 @@ +'use strict'; + +const path = require('path'); +const semver = require('semver'); +const entries = require('object.entries'); +const version = require('eslint/package.json').version; +const flatMap = require('array.prototype.flatmap'); +const tsParserVersion = require('@typescript-eslint/parser/package.json').version; + +const disableNewTS = semver.satisfies(tsParserVersion, '>= 4.1') // this rule is not useful on v4.1+ of the TS parser + ? (x) => Object.assign({}, x, { features: [].concat(x.features, 'no-ts-new') }) + : (x) => x; + +function minEcmaVersion(features, parserOptions) { + const minEcmaVersionForFeatures = { + 'class fields': 2022, + 'optional chaining': 2020, + 'nullish coalescing': 2020, + }; + const result = Math.max.apply( + Math, + [].concat( + (parserOptions && parserOptions.ecmaVersion) || [], + flatMap(entries(minEcmaVersionForFeatures), (entry) => { + const f = entry[0]; + const y = entry[1]; + return features.has(f) ? y : []; + }) + ).map((y) => (y > 5 && y < 2015 ? y + 2009 : y)) // normalize editions to years + ); + return Number.isFinite(result) ? result : undefined; +} + +const NODE_MODULES = '../../node_modules'; + +const parsers = { + BABEL_ESLINT: path.join(__dirname, NODE_MODULES, 'babel-eslint'), + '@BABEL_ESLINT': path.join(__dirname, NODE_MODULES, '@babel/eslint-parser'), + TYPESCRIPT_ESLINT: path.join(__dirname, NODE_MODULES, 'typescript-eslint-parser'), + '@TYPESCRIPT_ESLINT': path.join(__dirname, NODE_MODULES, '@typescript-eslint/parser'), + disableNewTS, + skipDueToMultiErrorSorting: semver.satisfies(process.versions.node, '^8 || ^9'), + babelParserOptions: function parserOptions(test, features) { + return Object.assign({}, test.parserOptions, { + requireConfigFile: false, + babelOptions: { + presets: [ + '@babel/preset-react', + ], + plugins: [ + '@babel/plugin-syntax-do-expressions', + '@babel/plugin-syntax-function-bind', + ['@babel/plugin-syntax-decorators', { legacy: true }], + ], + parserOpts: { + allowSuperOutsideMethod: false, + allowReturnOutsideFunction: false, + }, + }, + ecmaFeatures: Object.assign( + {}, + test.parserOptions && test.parserOptions.ecmaFeatures, + { + jsx: true, + modules: true, + legacyDecorators: features.has('decorators'), + } + ), + }); + }, + all: function all(tests) { + const t = flatMap(tests, (test) => { + if (typeof test === 'string') { + test = { code: test }; + } + if ('parser' in test) { + delete test.features; + return test; + } + const features = new Set([].concat(test.features || [])); + delete test.features; + + const es = minEcmaVersion(features, test.parserOptions); + + function addComment(testObject, parser) { + const extras = [].concat( + `features: [${Array.from(features).join(',')}]`, + `parser: ${parser}`, + testObject.parserOptions ? `parserOptions: ${JSON.stringify(testObject.parserOptions)}` : [], + testObject.options ? `options: ${JSON.stringify(testObject.options)}` : [], + testObject.settings ? `settings: ${JSON.stringify(testObject.settings)}` : [] + ); + + const extraComment = `\n// ${extras.join(', ')}`; + + // Augment expected fix code output with extraComment + const nextCode = { code: testObject.code + extraComment }; + const nextOutput = testObject.output && { output: testObject.output + extraComment }; + + // Augment expected suggestion outputs with extraComment + // `errors` may be a number (expected number of errors) or an array of + // error objects. + const nextErrors = testObject.errors + && typeof testObject.errors !== 'number' + && { + errors: testObject.errors.map( + (errorObject) => { + const nextSuggestions = errorObject.suggestions && { + suggestions: errorObject.suggestions.map((suggestion) => Object.assign({}, suggestion, { + output: suggestion.output + extraComment, + })), + }; + + return Object.assign({}, errorObject, nextSuggestions); + } + ), + }; + + return Object.assign( + {}, + testObject, + nextCode, + nextOutput, + nextErrors + ); + } + + const skipBase = (features.has('class fields') && semver.satisfies(version, '< 8')) + || (es >= 2020 && semver.satisfies(version, '< 6')) + || features.has('no-default') + || features.has('bind operator') + || features.has('do expressions') + || features.has('decorators') + || features.has('flow') + || features.has('ts') + || features.has('types') + || (features.has('fragment') && semver.satisfies(version, '< 5')); + + const skipBabel = features.has('no-babel'); + const skipOldBabel = skipBabel + || features.has('no-babel-old') + || features.has('optional chaining') + || semver.satisfies(version, '>= 8'); + const skipNewBabel = skipBabel + || features.has('no-babel-new') + || !semver.satisfies(version, '^7.5.0') // require('@babel/eslint-parser/package.json').peerDependencies.eslint + || features.has('flow') + || features.has('types') + || features.has('ts'); + const skipTS = semver.satisfies(version, '<= 5') // TODO: make these pass on eslint 5 + || features.has('no-ts') + || features.has('flow') + || features.has('jsx namespace') + || features.has('bind operator') + || features.has('do expressions'); + const tsOld = !skipTS && !features.has('no-ts-old'); + const tsNew = !skipTS && !features.has('no-ts-new'); + + return [].concat( + skipBase ? [] : addComment( + Object.assign({}, test, typeof es === 'number' && { + parserOptions: Object.assign({}, test.parserOptions, { ecmaVersion: es }), + }), + 'default' + ), + skipOldBabel ? [] : addComment(Object.assign({}, test, { + parser: parsers.BABEL_ESLINT, + parserOptions: parsers.babelParserOptions(test, features), + }), 'babel-eslint'), + skipNewBabel ? [] : addComment(Object.assign({}, test, { + parser: parsers['@BABEL_ESLINT'], + parserOptions: parsers.babelParserOptions(test, features), + }), '@babel/eslint-parser'), + tsOld ? addComment(Object.assign({}, test, { parser: parsers.TYPESCRIPT_ESLINT }), 'typescript-eslint') : [], + tsNew ? addComment(Object.assign({}, test, { parser: parsers['@TYPESCRIPT_ESLINT'] }), '@typescript-eslint/parser') : [] + ); + }); + + return t; + }, +}; + +module.exports = parsers; diff --git a/tests/helpers/parsers.js b/tests/helpers/parsers.js index 59205a509a..1d66365c7a 100644 --- a/tests/helpers/parsers.js +++ b/tests/helpers/parsers.js @@ -1,17 +1,21 @@ 'use strict'; -const path = require('path'); const semver = require('semver'); const entries = require('object.entries'); const version = require('eslint/package.json').version; const flatMap = require('array.prototype.flatmap'); const tsParserVersion = require('@typescript-eslint/parser/package.json').version; +const oldBabelParser = require('babel-eslint'); +const newBabelParser = require('@babel/eslint-parser'); +const oldTSParser = require('typescript-eslint-parser'); +const newTSParser = require('@typescript-eslint/parser'); + const disableNewTS = semver.satisfies(tsParserVersion, '>= 4.1') // this rule is not useful on v4.1+ of the TS parser ? (x) => Object.assign({}, x, { features: [].concat(x.features, 'no-ts-new') }) : (x) => x; -function minEcmaVersion(features, parserOptions) { +function minEcmaVersion(features, languageOptions) { const minEcmaVersionForFeatures = { 'class fields': 2022, 'optional chaining': 2020, @@ -19,34 +23,32 @@ function minEcmaVersion(features, parserOptions) { }; const result = Math.max.apply( Math, - [].concat( - (parserOptions && parserOptions.ecmaVersion) || [], - flatMap(entries(minEcmaVersionForFeatures), (entry) => { - const f = entry[0]; - const y = entry[1]; - return features.has(f) ? y : []; - }) - ).map((y) => (y > 5 && y < 2015 ? y + 2009 : y)) // normalize editions to years + [] + .concat( + (languageOptions && languageOptions.ecmaVersion) || [], + flatMap(entries(minEcmaVersionForFeatures), (entry) => { + const f = entry[0]; + const y = entry[1]; + return features.has(f) ? y : []; + }) + ) + .map((y) => (y > 5 && y < 2015 ? y + 2009 : y)) ); return Number.isFinite(result) ? result : undefined; } -const NODE_MODULES = '../../node_modules'; - const parsers = { - BABEL_ESLINT: path.join(__dirname, NODE_MODULES, 'babel-eslint'), - '@BABEL_ESLINT': path.join(__dirname, NODE_MODULES, '@babel/eslint-parser'), - TYPESCRIPT_ESLINT: path.join(__dirname, NODE_MODULES, 'typescript-eslint-parser'), - '@TYPESCRIPT_ESLINT': path.join(__dirname, NODE_MODULES, '@typescript-eslint/parser'), + BABEL_ESLINT: oldBabelParser, + '@BABEL_ESLINT': newBabelParser, + TYPESCRIPT_ESLINT: oldTSParser, + '@TYPESCRIPT_ESLINT': newTSParser, disableNewTS, skipDueToMultiErrorSorting: semver.satisfies(process.versions.node, '^8 || ^9'), babelParserOptions: function parserOptions(test, features) { - return Object.assign({}, test.parserOptions, { + return Object.assign({}, (test.languageOptions && test.languageOptions.parserOptions) || {}, { requireConfigFile: false, babelOptions: { - presets: [ - '@babel/preset-react', - ], + presets: ['@babel/preset-react'], plugins: [ '@babel/plugin-syntax-do-expressions', '@babel/plugin-syntax-function-bind', @@ -59,7 +61,7 @@ const parsers = { }, ecmaFeatures: Object.assign( {}, - test.parserOptions && test.parserOptions.ecmaFeatures, + test.languageOptions && test.languageOptions.ecmaFeatures, { jsx: true, modules: true, @@ -80,26 +82,22 @@ const parsers = { const features = new Set([].concat(test.features || [])); delete test.features; - const es = minEcmaVersion(features, test.parserOptions); + const es = minEcmaVersion(features, test.languageOptions); function addComment(testObject, parser) { const extras = [].concat( `features: [${Array.from(features).join(',')}]`, `parser: ${parser}`, - testObject.parserOptions ? `parserOptions: ${JSON.stringify(testObject.parserOptions)}` : [], + testObject.languageOptions ? `languageOptions: ${JSON.stringify(testObject.languageOptions)}` : [], testObject.options ? `options: ${JSON.stringify(testObject.options)}` : [], testObject.settings ? `settings: ${JSON.stringify(testObject.settings)}` : [] ); const extraComment = `\n// ${extras.join(', ')}`; - // Augment expected fix code output with extraComment const nextCode = { code: testObject.code + extraComment }; const nextOutput = testObject.output && { output: testObject.output + extraComment }; - // Augment expected suggestion outputs with extraComment - // `errors` may be a number (expected number of errors) or an array of - // error objects. const nextErrors = testObject.errors && typeof testObject.errors !== 'number' && { @@ -108,21 +106,15 @@ const parsers = { const nextSuggestions = errorObject.suggestions && { suggestions: errorObject.suggestions.map((suggestion) => Object.assign({}, suggestion, { output: suggestion.output + extraComment, - })), + }) + ), }; return Object.assign({}, errorObject, nextSuggestions); - } - ), + }), }; - return Object.assign( - {}, - testObject, - nextCode, - nextOutput, - nextErrors - ); + return Object.assign({}, testObject, nextCode, nextOutput, nextErrors); } const skipBase = (features.has('class fields') && semver.satisfies(version, '< 8')) @@ -157,22 +149,62 @@ const parsers = { const tsNew = !skipTS && !features.has('no-ts-new'); return [].concat( - skipBase ? [] : addComment( - Object.assign({}, test, typeof es === 'number' && { - parserOptions: Object.assign({}, test.parserOptions, { ecmaVersion: es }), - }), - 'default' - ), - skipOldBabel ? [] : addComment(Object.assign({}, test, { - parser: parsers.BABEL_ESLINT, - parserOptions: parsers.babelParserOptions(test, features), - }), 'babel-eslint'), - skipNewBabel ? [] : addComment(Object.assign({}, test, { - parser: parsers['@BABEL_ESLINT'], - parserOptions: parsers.babelParserOptions(test, features), - }), '@babel/eslint-parser'), - tsOld ? addComment(Object.assign({}, test, { parser: parsers.TYPESCRIPT_ESLINT }), 'typescript-eslint') : [], - tsNew ? addComment(Object.assign({}, test, { parser: parsers['@TYPESCRIPT_ESLINT'] }), '@typescript-eslint/parser') : [] + skipBase + ? [] + : addComment( + Object.assign( + {}, + test, + typeof es === 'number' && { + languageOptions: Object.assign({}, test.languageOptions, { + ecmaVersion: es, + }), + } + ), + 'default' + ), + skipOldBabel + ? [] + : addComment( + Object.assign({}, test, { + languageOptions: Object.assign({ + parserOptions: parsers.babelParserOptions(test, features), + parser: parsers.BABEL_ESLINT, + }), + }), + 'babel-eslint' + ), + skipNewBabel + ? [] + : addComment( + Object.assign({}, test, { + languageOptions: Object.assign({ + parserOptions: parsers.babelParserOptions(test, features), + parser: parsers['@BABEL_ESLINT'], + }), + }), + '@babel/eslint-parser' + ), + tsOld + ? addComment( + Object.assign({}, test, { + languageOptions: Object.assign({}, test.languageOptions, { + parser: parsers.TYPESCRIPT_ESLINT, + }), + }), + 'typescript-eslint' + ) + : [], + tsNew + ? addComment( + Object.assign({}, test, { + languageOptions: Object.assign({}, test.languageOptions, { + parser: parsers['@TYPESCRIPT_ESLINT'], + }), + }), + '@typescript-eslint/parser' + ) + : [] ); }); diff --git a/tests/lib/rules/boolean-prop-naming.js b/tests/lib/rules/boolean-prop-naming.js index 2dec7ed70c..3766c396d2 100644 --- a/tests/lib/rules/boolean-prop-naming.js +++ b/tests/lib/rules/boolean-prop-naming.js @@ -14,11 +14,13 @@ const rule = require('../../../lib/rules/boolean-prop-naming'); const parsers = require('../../helpers/parsers'); -const parserOptions = { +const languageOptions = { ecmaVersion: 2018, sourceType: 'module', - ecmaFeatures: { - jsx: true, + parserOptions: { + ecmaFeatures: { + jsx: true, + }, }, }; @@ -26,7 +28,7 @@ const parserOptions = { // Tests // ------------------------------------------------------------------------------ -const ruleTester = new RuleTester({ parserOptions }); +const ruleTester = new RuleTester({ languageOptions }); ruleTester.run('boolean-prop-naming', rule, { valid: parsers.all([ { diff --git a/tests/lib/rules/button-has-type.js b/tests/lib/rules/button-has-type.js index fb16f28aa5..5efcded4ef 100644 --- a/tests/lib/rules/button-has-type.js +++ b/tests/lib/rules/button-has-type.js @@ -14,11 +14,13 @@ const rule = require('../../../lib/rules/button-has-type'); const parsers = require('../../helpers/parsers'); -const parserOptions = { +const languageOptions = { ecmaVersion: 2018, sourceType: 'module', - ecmaFeatures: { - jsx: true, + parserOptions: { + ecmaFeatures: { + jsx: true, + }, }, }; @@ -26,300 +28,301 @@ const parserOptions = { // Tests // ------------------------------------------------------------------------------ -const ruleTester = new RuleTester({ parserOptions }); +const ruleTester = new RuleTester({ languageOptions }); ruleTester.run('button-has-type', rule, { valid: parsers.all([ { code: '' }, - { code: '' }, - { code: '