Socket
Socket
Sign inDemoInstall

eslint-plugin-react

Package Overview
Dependencies
Maintainers
0
Versions
210
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

eslint-plugin-react - npm Package Compare versions

Comparing version 7.35.0 to 7.35.1

53

lib/rules/boolean-prop-naming.js

@@ -13,2 +13,3 @@ /**

const propsUtil = require('../util/props');
const astUtil = require('../util/ast');
const docsUrl = require('../util/docsUrl');

@@ -22,2 +23,14 @@ const propWrapperUtil = require('../util/propWrapper');

/**
* Checks if prop is nested
* @param {Object} prop Property object, single prop type declaration
* @returns {boolean}
*/
function nestedPropTypes(prop) {
return (
prop.type === 'Property'
&& astUtil.isCallExpression(prop.value)
);
}
// ------------------------------------------------------------------------------

@@ -133,3 +146,3 @@ // Rule Definition

* @param {Object} prop Property object, single prop type declaration
* @returns {Boolean}
* @returns {boolean}
*/

@@ -147,3 +160,3 @@ function flowCheck(prop) {

* @param {Object} prop Property object, single prop type declaration
* @returns {Boolean}
* @returns {boolean}
*/

@@ -170,14 +183,2 @@ function regularCheck(prop) {

/**
* Checks if prop is nested
* @param {Object} prop Property object, single prop type declaration
* @returns {Boolean}
*/
function nestedPropTypes(prop) {
return (
prop.type === 'Property'
&& prop.value.type === 'CallExpression'
);
}
/**
* Runs recursive check on all proptypes

@@ -188,11 +189,13 @@ * @param {Array} proptypes A list of Property object (for each proptype defined)

function runCheck(proptypes, addInvalidProp) {
(proptypes || []).forEach((prop) => {
if (config.validateNested && nestedPropTypes(prop)) {
runCheck(prop.value.arguments[0].properties, addInvalidProp);
return;
}
if (flowCheck(prop) || regularCheck(prop) || tsCheck(prop)) {
addInvalidProp(prop);
}
});
if (proptypes) {
proptypes.forEach((prop) => {
if (config.validateNested && nestedPropTypes(prop)) {
runCheck(prop.value.arguments[0].properties, addInvalidProp);
return;
}
if (flowCheck(prop) || regularCheck(prop) || tsCheck(prop)) {
addInvalidProp(prop);
}
});
}
}

@@ -318,3 +321,3 @@

node.value
&& node.value.type === 'CallExpression'
&& astUtil.isCallExpression(node.value)
&& propWrapperUtil.isPropWrapperFunction(

@@ -345,3 +348,3 @@ context,

if (
right.type === 'CallExpression'
astUtil.isCallExpression(right)
&& propWrapperUtil.isPropWrapperFunction(

@@ -348,0 +351,0 @@ context,

@@ -76,8 +76,9 @@ /**

* @param {ASTNode} node The AST node being checked.
* @returns {Boolean} True if React.forwardRef is nested inside React.memo, false if not.
* @returns {boolean} True if React.forwardRef is nested inside React.memo, false if not.
*/
function isNestedMemo(node) {
const argumentIsCallExpression = node.arguments && node.arguments[0] && node.arguments[0].type === 'CallExpression';
return node.type === 'CallExpression' && argumentIsCallExpression && utils.isPragmaComponentWrapper(node);
return astUtil.isCallExpression(node)
&& node.arguments
&& astUtil.isCallExpression(node.arguments[0])
&& utils.isPragmaComponentWrapper(node);
}

@@ -115,3 +116,3 @@

* @param {ASTNode} node The AST node being checked.
* @returns {Boolean} True if component has a name, false if not.
* @returns {boolean} True if component has a name, false if not.
*/

@@ -203,3 +204,3 @@ function hasTranspilerName(node) {

}
markDisplayNameAsDeclared(component.node.type === 'TSAsExpression' ? component.node.expression : component.node);
markDisplayNameAsDeclared(astUtil.unwrapTSAsExpression(component.node));
},

@@ -206,0 +207,0 @@

@@ -137,3 +137,3 @@ /**

}
if (value.type === 'CallExpression') {
if (astUtil.isCallExpression(value)) {
if (!isPropTypesPackage(value.callee)) {

@@ -162,25 +162,21 @@ return;

function checkNode(node) {
switch (node && node.type) {
case 'ObjectExpression':
checkProperties(node.properties);
break;
case 'Identifier': {
const propTypesObject = variableUtil.findVariableByName(context, node, node.name);
if (propTypesObject && propTypesObject.properties) {
checkProperties(propTypesObject.properties);
}
break;
if (!node) {
return;
}
if (node.type === 'ObjectExpression') {
checkProperties(node.properties);
} else if (node.type === 'Identifier') {
const propTypesObject = variableUtil.findVariableByName(context, node, node.name);
if (propTypesObject && propTypesObject.properties) {
checkProperties(propTypesObject.properties);
}
case 'CallExpression': {
const innerNode = node.arguments && node.arguments[0];
if (
propWrapperUtil.isPropWrapperFunction(context, getText(context, node.callee))
} else if (astUtil.isCallExpression(node)) {
const innerNode = node.arguments && node.arguments[0];
if (
propWrapperUtil.isPropWrapperFunction(context, getText(context, node.callee))
&& innerNode
) {
checkNode(innerNode);
}
break;
) {
checkNode(innerNode);
}
default:
break;
}

@@ -187,0 +183,0 @@ }

@@ -103,3 +103,3 @@ /**

* @param {Object} tokens Locations of the opening bracket, closing bracket and last prop
* @return {String} Expected location for the closing bracket
* @return {string} Expected location for the closing bracket
*/

@@ -125,3 +125,3 @@ function getExpectedLocation(tokens) {

* @param {Object} tokens Locations of the opening bracket, closing bracket and last prop
* @param {String} expectedLocation Expected location for the closing bracket
* @param {string} expectedLocation Expected location for the closing bracket
* @return {?Number} The correct column for the closing bracket, or null

@@ -145,4 +145,4 @@ */

* @param {Object} tokens Locations of the opening bracket, closing bracket and last prop
* @param {String} expectedLocation Expected location for the closing bracket
* @return {Boolean} True if the closing bracket is correctly located, false if not
* @param {string} expectedLocation Expected location for the closing bracket
* @return {boolean} True if the closing bracket is correctly located, false if not
*/

@@ -169,5 +169,5 @@ function hasCorrectLocation(tokens, expectedLocation) {

* @param {Object} tokens Locations of the opening bracket, closing bracket and last prop
* @param {String} expectedLocation Expected location for the closing bracket
* @param {Number} [correctColumn] Expected column for the closing bracket. Default to 0
* @return {String} The characters used for indentation
* @param {string} expectedLocation Expected location for the closing bracket
* @param {number} [correctColumn] Expected column for the closing bracket. Default to 0
* @return {string} The characters used for indentation
*/

@@ -242,3 +242,3 @@ function getIndentation(tokens, expectedLocation, correctColumn) {

* @param {ASTNode} node The AST node being checked.
* @returns {String} Unique ID (based on its range)
* @returns {string} Unique ID (based on its range)
*/

@@ -245,0 +245,0 @@ function getOpeningElementId(node) {

@@ -34,2 +34,104 @@ /**

const HTML_ENTITY_REGEX = () => /&[A-Za-z\d#]+;/g;
function containsLineTerminators(rawStringValue) {
return /[\n\r\u2028\u2029]/.test(rawStringValue);
}
function containsBackslash(rawStringValue) {
return arrayIncludes(rawStringValue, '\\');
}
function containsHTMLEntity(rawStringValue) {
return HTML_ENTITY_REGEX().test(rawStringValue);
}
function containsOnlyHtmlEntities(rawStringValue) {
return rawStringValue.replace(HTML_ENTITY_REGEX(), '').trim() === '';
}
function containsDisallowedJSXTextChars(rawStringValue) {
return /[{<>}]/.test(rawStringValue);
}
function containsQuoteCharacters(value) {
return /['"]/.test(value);
}
function containsMultilineComment(value) {
return /\/\*/.test(value);
}
function escapeDoubleQuotes(rawStringValue) {
return rawStringValue.replace(/\\"/g, '"').replace(/"/g, '\\"');
}
function escapeBackslashes(rawStringValue) {
return rawStringValue.replace(/\\/g, '\\\\');
}
function needToEscapeCharacterForJSX(raw, node) {
return (
containsBackslash(raw)
|| containsHTMLEntity(raw)
|| (node.parent.type !== 'JSXAttribute' && containsDisallowedJSXTextChars(raw))
);
}
function containsWhitespaceExpression(child) {
if (child.type === 'JSXExpressionContainer') {
const value = child.expression.value;
return value ? jsxUtil.isWhiteSpaces(value) : false;
}
return false;
}
function isLineBreak(text) {
return containsLineTerminators(text) && text.trim() === '';
}
function wrapNonHTMLEntities(text) {
const HTML_ENTITY = '<HTML_ENTITY>';
const withCurlyBraces = text.split(HTML_ENTITY_REGEX()).map((word) => (
word === '' ? '' : `{${JSON.stringify(word)}}`
)).join(HTML_ENTITY);
const htmlEntities = text.match(HTML_ENTITY_REGEX());
return htmlEntities.reduce((acc, htmlEntity) => (
acc.replace(HTML_ENTITY, htmlEntity)
), withCurlyBraces);
}
function wrapWithCurlyBraces(rawText) {
if (!containsLineTerminators(rawText)) {
return `{${JSON.stringify(rawText)}}`;
}
return rawText.split('\n').map((line) => {
if (line.trim() === '') {
return line;
}
const firstCharIndex = line.search(/[^\s]/);
const leftWhitespace = line.slice(0, firstCharIndex);
const text = line.slice(firstCharIndex);
if (containsHTMLEntity(line)) {
return `${leftWhitespace}${wrapNonHTMLEntities(text)}`;
}
return `${leftWhitespace}{${JSON.stringify(text)}}`;
}).join('\n');
}
function isWhiteSpaceLiteral(node) {
return node.type && node.type === 'Literal' && node.value && jsxUtil.isWhiteSpaces(node.value);
}
function isStringWithTrailingWhiteSpaces(value) {
return /^\s|\s$/.test(value);
}
function isLiteralWithTrailingWhiteSpaces(node) {
return node.type && node.type === 'Literal' && node.value && isStringWithTrailingWhiteSpaces(node.value);
}
// ------------------------------------------------------------------------------

@@ -78,3 +180,2 @@ // Rule Definition

create(context) {
const HTML_ENTITY_REGEX = () => /&[A-Za-z\d#]+;/g;
const ruleOptions = context.options[0];

@@ -85,90 +186,2 @@ const userConfig = typeof ruleOptions === 'string'

function containsLineTerminators(rawStringValue) {
return /[\n\r\u2028\u2029]/.test(rawStringValue);
}
function containsBackslash(rawStringValue) {
return arrayIncludes(rawStringValue, '\\');
}
function containsHTMLEntity(rawStringValue) {
return HTML_ENTITY_REGEX().test(rawStringValue);
}
function containsOnlyHtmlEntities(rawStringValue) {
return rawStringValue.replace(HTML_ENTITY_REGEX(), '').trim() === '';
}
function containsDisallowedJSXTextChars(rawStringValue) {
return /[{<>}]/.test(rawStringValue);
}
function containsQuoteCharacters(value) {
return /['"]/.test(value);
}
function containsMultilineComment(value) {
return /\/\*/.test(value);
}
function escapeDoubleQuotes(rawStringValue) {
return rawStringValue.replace(/\\"/g, '"').replace(/"/g, '\\"');
}
function escapeBackslashes(rawStringValue) {
return rawStringValue.replace(/\\/g, '\\\\');
}
function needToEscapeCharacterForJSX(raw, node) {
return (
containsBackslash(raw)
|| containsHTMLEntity(raw)
|| (node.parent.type !== 'JSXAttribute' && containsDisallowedJSXTextChars(raw))
);
}
function containsWhitespaceExpression(child) {
if (child.type === 'JSXExpressionContainer') {
const value = child.expression.value;
return value ? jsxUtil.isWhiteSpaces(value) : false;
}
return false;
}
function isLineBreak(text) {
return containsLineTerminators(text) && text.trim() === '';
}
function wrapNonHTMLEntities(text) {
const HTML_ENTITY = '<HTML_ENTITY>';
const withCurlyBraces = text.split(HTML_ENTITY_REGEX()).map((word) => (
word === '' ? '' : `{${JSON.stringify(word)}}`
)).join(HTML_ENTITY);
const htmlEntities = text.match(HTML_ENTITY_REGEX());
return htmlEntities.reduce((acc, htmlEntity) => (
acc.replace(HTML_ENTITY, htmlEntity)
), withCurlyBraces);
}
function wrapWithCurlyBraces(rawText) {
if (!containsLineTerminators(rawText)) {
return `{${JSON.stringify(rawText)}}`;
}
return rawText.split('\n').map((line) => {
if (line.trim() === '') {
return line;
}
const firstCharIndex = line.search(/[^\s]/);
const leftWhitespace = line.slice(0, firstCharIndex);
const text = line.slice(firstCharIndex);
if (containsHTMLEntity(line)) {
return `${leftWhitespace}${wrapNonHTMLEntities(text)}`;
}
return `${leftWhitespace}{${JSON.stringify(text)}}`;
}).join('\n');
}
/**

@@ -239,14 +252,2 @@ * Report and fix an unnecessary curly brace violation on a node

function isWhiteSpaceLiteral(node) {
return node.type && node.type === 'Literal' && node.value && jsxUtil.isWhiteSpaces(node.value);
}
function isStringWithTrailingWhiteSpaces(value) {
return /^\s|\s$/.test(value);
}
function isLiteralWithTrailingWhiteSpaces(node) {
return node.type && node.type === 'Literal' && node.value && isStringWithTrailingWhiteSpaces(node.value);
}
// Bail out if there is any character that needs to be escaped in JSX

@@ -275,3 +276,3 @@ // because escaping decreases readability and the original code may be more

jsxUtil.isJSX(JSXExpressionNode.parent)
|| !containsQuoteCharacters(expression.value)
|| (!containsQuoteCharacters(expression.value) || typeof expression.value === 'string')
)

@@ -278,0 +279,0 @@ ) {

@@ -119,4 +119,4 @@ /**

* @param {ASTNode} node Node violating the indent rule
* @param {Number} needed Expected indentation character count
* @param {Number} gotten Indentation character count in the actual node/code
* @param {number} needed Expected indentation character count
* @param {number} gotten Indentation character count in the actual node/code
*/

@@ -145,3 +145,3 @@ function report(node, needed, gotten) {

* @param {ASTNode} node Node to examine
* @return {Number} Indent
* @return {number} Indent
*/

@@ -178,3 +178,3 @@ function getNodeIndent(node) {

* @param {ASTNode[]} nodes list of node objects
* @param {Number} indent needed indent
* @param {number} indent needed indent
*/

@@ -181,0 +181,0 @@ function checkNodesIndent(nodes, indent) {

@@ -108,3 +108,3 @@ /**

* @param {ASTNode} node Node violating the indent rule
* @param {Number} needed Expected indentation character count
* @param {number} needed Expected indentation character count
* @returns {Function} function to be executed by the fixer

@@ -150,4 +150,4 @@ * @private

* @param {ASTNode} node Node violating the indent rule
* @param {Number} needed Expected indentation character count
* @param {Number} gotten Indentation character count in the actual node/code
* @param {number} needed Expected indentation character count
* @param {number} gotten Indentation character count in the actual node/code
* @param {Object} [loc] Error line and column location

@@ -173,5 +173,5 @@ */

* @param {ASTNode} node Node to examine
* @param {Boolean} [byLastLine] get indent of node's last line
* @param {Boolean} [excludeCommas] skip comma on start of line
* @return {Number} Indent
* @param {boolean} [byLastLine] get indent of node's last line
* @param {boolean} [excludeCommas] skip comma on start of line
* @return {number} Indent
*/

@@ -203,3 +203,3 @@ function getNodeIndent(node, byLastLine, excludeCommas) {

* @param {ASTNode} node The node to check
* @return {Boolean} true if its the case, false if not
* @return {boolean} true if its the case, false if not
*/

@@ -219,3 +219,3 @@ function isRightInLogicalExp(node) {

* @param {ASTNode} node The node to check
* @return {Boolean} true if its the case, false if not
* @return {boolean} true if its the case, false if not
*/

@@ -235,3 +235,3 @@ function isAlternateInConditionalExp(node) {

* @param {ASTNode} node The node to check
* @return {Boolean} true if its the case, false if not
* @return {boolean} true if its the case, false if not
*/

@@ -307,4 +307,4 @@ function isSecondOrSubsequentExpWithinDoExp(node) {

* @param {ASTNode} node The node to check
* @param {Number} indent needed indent
* @param {Boolean} [excludeCommas] skip comma on start of line
* @param {number} indent needed indent
* @param {boolean} [excludeCommas] skip comma on start of line
*/

@@ -328,3 +328,3 @@ function checkNodesIndent(node, indent, excludeCommas) {

* @param {ASTNode} node The node to check
* @param {Number} indent needed indent
* @param {number} indent needed indent
*/

@@ -331,0 +331,0 @@ function checkLiteralNodeIndent(node, indent) {

@@ -12,2 +12,3 @@ /**

const docsUrl = require('../util/docsUrl');
const astUtil = require('../util/ast');
const jsxUtil = require('../util/jsx');

@@ -87,6 +88,5 @@ const report = require('../util/report');

function getNodeViolationType(node) {
const nodeType = node.type;
if (
!configuration.allowBind
&& nodeType === 'CallExpression'
&& astUtil.isCallExpression(node)
&& node.callee.type === 'MemberExpression'

@@ -98,3 +98,3 @@ && node.callee.property.type === 'Identifier'

}
if (nodeType === 'ConditionalExpression') {
if (node.type === 'ConditionalExpression') {
return getNodeViolationType(node.test)

@@ -104,3 +104,3 @@ || getNodeViolationType(node.consequent)

}
if (!configuration.allowArrowFunctions && nodeType === 'ArrowFunctionExpression') {
if (!configuration.allowArrowFunctions && node.type === 'ArrowFunctionExpression') {
return 'arrowFunc';

@@ -110,7 +110,7 @@ }

!configuration.allowFunctions
&& (nodeType === 'FunctionExpression' || nodeType === 'FunctionDeclaration')
&& (node.type === 'FunctionExpression' || node.type === 'FunctionDeclaration')
) {
return 'func';
}
if (!configuration.allowBind && nodeType === 'BindExpression') {
if (!configuration.allowBind && node.type === 'BindExpression') {
return 'bindExpression';

@@ -117,0 +117,0 @@ }

@@ -77,4 +77,3 @@ /**

function defaultMessageId() {
const ancestorIsJSXElement = arguments.length >= 1 && arguments[0];
function defaultMessageId(ancestorIsJSXElement) {
if (config.noAttributeStrings && !ancestorIsJSXElement) {

@@ -81,0 +80,0 @@ return 'noStringsInAttributes';

@@ -73,3 +73,3 @@ /**

* @param {ASTNode} targetValue The AST node being checked.
* @returns {String | String[] | null} The string value, or null if not a string.
* @returns {string | string[] | null} The string value, or null if not a string.
*/

@@ -76,0 +76,0 @@ function getStringFromValue(value, targetValue) {

@@ -10,2 +10,3 @@ /**

const pragmaUtil = require('../util/pragma');
const astUtil = require('../util/ast');
const jsxUtil = require('../util/jsx');

@@ -79,4 +80,3 @@ const docsUrl = require('../util/docsUrl');

&& node.type === 'JSXExpressionContainer'
&& node.expression
&& node.expression.type === 'CallExpression';
&& astUtil.isCallExpression(node.expression);
}

@@ -83,0 +83,0 @@

@@ -60,3 +60,3 @@ /**

* @param {Object} node - Property.
* @returns {String} Property name.
* @returns {string} Property name.
*/

@@ -82,3 +82,3 @@ function getPropertyName(node) {

* @param {ASTNode} node The node to check. Must be an Identifier node.
* @returns {Boolean} `true` if the node is a defaultProps declaration, `false` if not
* @returns {boolean} `true` if the node is a defaultProps declaration, `false` if not
*/

@@ -85,0 +85,0 @@ function isDefaultPropsDeclaration(node) {

@@ -15,2 +15,3 @@ /**

const report = require('../util/report');
const propTypesSortUtil = require('../util/propTypesSort');
const eslintUtil = require('../util/eslint');

@@ -25,6 +26,2 @@

function isCallbackPropName(name) {
return /^on[A-Z]/.test(name);
}
function isMultilineProp(node) {

@@ -90,4 +87,4 @@ return node.loc.start.line !== node.loc.end.line;

if (options.callbacksLast) {
const aIsCallback = isCallbackPropName(aProp);
const bIsCallback = isCallbackPropName(bProp);
const aIsCallback = propTypesSortUtil.isCallbackPropName(aProp);
const bIsCallback = propTypesSortUtil.isCallbackPropName(bProp);
if (aIsCallback && !bIsCallback) {

@@ -285,4 +282,4 @@ return 1;

* @param {Object} context The context of the rule
* @param {Boolean|Array<String>} reservedFirst The `reservedFirst` option
* @return {Function|undefined} If an error is detected, a function to generate the error message, otherwise, `undefined`
* @param {boolean | string[]} reservedFirst The `reservedFirst` option
* @return {Function | undefined} If an error is detected, a function to generate the error message, otherwise, `undefined`
*/

@@ -432,4 +429,4 @@ // eslint-disable-next-line consistent-return

const currentValue = decl.value;
const previousIsCallback = isCallbackPropName(previousPropName);
const currentIsCallback = isCallbackPropName(currentPropName);
const previousIsCallback = propTypesSortUtil.isCallbackPropName(previousPropName);
const currentIsCallback = propTypesSortUtil.isCallbackPropName(currentPropName);

@@ -436,0 +433,0 @@ if (ignoreCase) {

@@ -9,2 +9,3 @@ /**

const docsUrl = require('../util/docsUrl');
const astUtil = require('../util/ast');
const componentUtil = require('../util/componentUtil');

@@ -36,3 +37,3 @@ const report = require('../util/report');

function isSetStateCall(node) {
return node.type === 'CallExpression'
return astUtil.isCallExpression(node)
&& node.callee.property

@@ -39,0 +40,0 @@ && node.callee.property.name === 'setState'

@@ -11,2 +11,3 @@ /**

const report = require('../util/report');
const astUtil = require('../util/ast');

@@ -66,3 +67,3 @@ // ------------------------------------------------------------------------------

}
if (node.type === 'CallExpression' && inlineNames.indexOf(node.arguments[0].value) > -1) {
if (astUtil.isCallExpression(node) && inlineNames.indexOf(node.arguments[0].value) > -1) {
return true;

@@ -69,0 +70,0 @@ }

@@ -192,10 +192,11 @@ /**

if (node.type === 'CallExpression'
&& node.callee
&& node.callee.type === 'MemberExpression'
&& node.callee.object
&& isArrayIndex(node.callee.object)
&& node.callee.property
&& node.callee.property.type === 'Identifier'
&& node.callee.property.name === 'toString'
if (
astUtil.isCallExpression(node)
&& node.callee
&& node.callee.type === 'MemberExpression'
&& node.callee.object
&& isArrayIndex(node.callee.object)
&& node.callee.property
&& node.callee.property.type === 'Identifier'
&& node.callee.property.name === 'toString'
) {

@@ -209,9 +210,10 @@ // key={bar.toString()}

if (node.type === 'CallExpression'
&& node.callee
&& node.callee.type === 'Identifier'
&& node.callee.name === 'String'
&& Array.isArray(node.arguments)
&& node.arguments.length > 0
&& isArrayIndex(node.arguments[0])
if (
astUtil.isCallExpression(node)
&& node.callee
&& node.callee.type === 'Identifier'
&& node.callee.name === 'String'
&& Array.isArray(node.arguments)
&& node.arguments.length > 0
&& isArrayIndex(node.arguments[0])
) {

@@ -218,0 +220,0 @@ // key={String(bar)}

@@ -20,3 +20,3 @@ /**

* @param {Context} context - The AST node being checked.
* @returns {Boolean} - True if node is a createElement call with a props
* @returns {boolean} - True if node is a createElement call with a props
* object literal, False if not.

@@ -23,0 +23,0 @@ */

@@ -88,3 +88,3 @@ /**

* @param {ASTNode} node The AST node being checked
* @returns {Boolean} True if node is a line break, false if not
* @returns {boolean} True if node is a line break, false if not
*/

@@ -91,0 +91,0 @@ function isLineBreak(node) {

@@ -32,3 +32,3 @@ /**

* Checks if a JSX attribute is dangerous.
* @param {String} name - Name of the attribute to check.
* @param {string} name - Name of the attribute to check.
* @returns {boolean} Whether or not the attribute is dangerous.

@@ -35,0 +35,0 @@ */

@@ -41,6 +41,6 @@ /**

* @param {Object} component The component to process
* @returns {Boolean} True if the component is valid, false if not.
* @returns {boolean} True if the component is valid, false if not.
*/
function isValid(component) {
return Boolean(component && !component.mutateSetState);
return !!component && !component.mutateSetState;
}

@@ -77,3 +77,3 @@

* @param {?Object} component The component to process
* @returns {Boolean} True if we should skip assignment checks.
* @returns {boolean} True if we should skip assignment checks.
*/

@@ -80,0 +80,0 @@ function shouldIgnoreComponent(component) {

@@ -38,4 +38,7 @@ /**

const isfindDOMNode = (callee.name === 'findDOMNode')
|| (callee.property && callee.property.name === 'findDOMNode');
const isfindDOMNode = callee.name === 'findDOMNode' || (
callee.property
&& callee.property.name === 'findDOMNode'
);
if (!isfindDOMNode) {

@@ -42,0 +45,0 @@ return;

@@ -292,3 +292,3 @@ /**

const singleAttributeParts = splitIntoRangedParts(node, /(\S+)/g);
for (const singlePart of singleAttributeParts) {
singleAttributeParts.forEach((singlePart) => {
const allowedTags = VALID_VALUES.get(attributeName).get(singlePart.value);

@@ -333,3 +333,3 @@ const reportingValue = singlePart.reportingValue;

}
}
});

@@ -339,6 +339,4 @@ const allowedPairsForAttribute = VALID_PAIR_VALUES.get(attributeName);

const pairAttributeParts = splitIntoRangedParts(node, /(?=(\b\S+\s*\S+))/g);
for (const pairPart of pairAttributeParts) {
for (const allowedPair of allowedPairsForAttribute) {
const pairing = allowedPair[0];
const siblings = allowedPair[1];
pairAttributeParts.forEach((pairPart) => {
allowedPairsForAttribute.forEach((siblings, pairing) => {
const attributes = pairPart.reportingValue.split('\u0020');

@@ -363,8 +361,8 @@ const firstValue = attributes[0];

}
}
}
});
});
}
const whitespaceParts = splitIntoRangedParts(node, /(\s+)/g);
for (const whitespacePart of whitespaceParts) {
whitespaceParts.forEach((whitespacePart) => {
const data = { attributeName };

@@ -393,3 +391,3 @@

}
}
});
}

@@ -587,5 +585,5 @@

if (prop.value.type === 'ArrayExpression') {
for (const value of prop.value.elements) {
prop.value.elements.forEach((value) => {
checkPropValidValue(context, node, value, attribute);
}
});

@@ -655,5 +653,5 @@ // eslint-disable-next-line no-continue

for (const attribute of attributes) {
attributes.forEach((attribute) => {
checkCreateProps(context, node, attribute);
}
});
},

@@ -660,0 +658,0 @@ };

@@ -53,3 +53,3 @@ /**

* @param {Object} component The component being checked.
* @returns {Boolean} True if the component is ignored, false if not.
* @returns {boolean} True if the component is ignored, false if not.
*/

@@ -56,0 +56,0 @@ function isIgnored(component) {

@@ -12,2 +12,3 @@ /**

const docsUrl = require('../util/docsUrl');
const astUtil = require('../util/ast');
const report = require('../util/report');

@@ -59,3 +60,3 @@

} else if (
propDefaultValueType === 'CallExpression'
astUtil.isCallExpression(propDefaultValue.right)
&& propDefaultValue.right.callee.type === 'Identifier'

@@ -62,0 +63,0 @@ && propDefaultValue.right.callee.name === 'Symbol'

@@ -39,3 +39,3 @@ /**

* @param {ASTNode} node The AST node being checked.
* @returns {Boolean} Whether or not the property exists.
* @returns {boolean} Whether or not the property exists.
*/

@@ -53,3 +53,3 @@ function hasShouldComponentUpdate(node) {

* @param {ASTNode} node The AST node being checked.
* @return {String} The name of the node
* @return {string} The name of the node
*/

@@ -56,0 +56,0 @@ function getNodeName(node) {

@@ -41,6 +41,6 @@ /**

* @param {Object} component The component to process
* @returns {Boolean} True if the component is valid, false if not.
* @returns {boolean} True if the component is valid, false if not.
*/
function isValid(component) {
return Boolean(component && !component.useSetState);
return !!component && !component.useSetState;
}

@@ -53,5 +53,4 @@

function reportSetStateUsages(component) {
let setStateUsage;
for (let i = 0, j = component.setStateUsages.length; i < j; i++) {
setStateUsage = component.setStateUsages[i];
const setStateUsage = component.setStateUsages[i];
report(context, messages.noSetState, 'noSetState', {

@@ -58,0 +57,0 @@ node: setStateUsage,

@@ -49,3 +49,3 @@ /**

* @param {ASTNode} node The AST node being checked.
* @returns {Boolean} True if we are using refs, false if not.
* @returns {boolean} True if we are using refs, false if not.
*/

@@ -63,10 +63,8 @@ function isRefsUsage(node) {

* @param {ASTNode} node The AST node being checked.
* @returns {Boolean} True if we are using a ref attribute, false if not.
* @returns {boolean} True if we are using a ref attribute, false if not.
*/
function isRefAttribute(node) {
return !!(
node.type === 'JSXAttribute'
&& node.name
&& node.name.name === 'ref'
);
return node.type === 'JSXAttribute'
&& !!node.name
&& node.name.name === 'ref';
}

@@ -77,10 +75,8 @@

* @param {ASTNode} node The AST node being checked.
* @returns {Boolean} True if the node contains a string value, false if not.
* @returns {boolean} True if the node contains a string value, false if not.
*/
function containsStringLiteral(node) {
return !!(
node.value
return !!node.value
&& node.value.type === 'Literal'
&& typeof node.value.value === 'string'
);
&& typeof node.value.value === 'string';
}

@@ -91,12 +87,10 @@

* @param {ASTNode} node The AST node being checked.
* @returns {Boolean} True if the node contains a string value within a jsx expression, false if not.
* @returns {boolean} True if the node contains a string value within a jsx expression, false if not.
*/
function containsStringExpressionContainer(node) {
return !!(
node.value
return !!node.value
&& node.value.type === 'JSXExpressionContainer'
&& node.value.expression
&& ((node.value.expression.type === 'Literal' && typeof node.value.expression.value === 'string')
|| (node.value.expression.type === 'TemplateLiteral' && detectTemplateLiterals))
);
|| (node.value.expression.type === 'TemplateLiteral' && detectTemplateLiterals));
}

@@ -112,2 +106,3 @@

},
JSXAttribute(node) {

@@ -114,0 +109,0 @@ if (

@@ -10,2 +10,3 @@ /**

const docsUrl = require('../util/docsUrl');
const astUtil = require('../util/ast');
const componentUtil = require('../util/componentUtil');

@@ -113,7 +114,7 @@ const report = require('../util/report');

checkValidPropType(node.property);
} else if (node.object.type === 'CallExpression') {
} else if (astUtil.isCallExpression(node.object)) {
checkValidPropTypeQualifier(node.property);
checkValidCallExpression(node.object);
}
} else if (node.type === 'CallExpression') {
} else if (astUtil.isCallExpression(node)) {
checkValidCallExpression(node);

@@ -199,3 +200,4 @@ }

const propTypesSpecifier = node.specifiers.find((specifier) => (
specifier.imported && specifier.imported.name === 'PropTypes'
specifier.imported
&& specifier.imported.name === 'PropTypes'
));

@@ -202,0 +204,0 @@ if (propTypesSpecifier) {

@@ -418,4 +418,4 @@ /**

*
* @param {String} name - Attribute name to be normalized
* @returns {String} Result
* @param {string} name - Attribute name to be normalized
* @returns {string} Result
*/

@@ -432,3 +432,3 @@ function normalizeAttributeCase(name) {

*
* @param {String} name - Attribute name to be tested
* @param {string} name - Attribute name to be tested
* @returns {boolean} Result

@@ -443,3 +443,3 @@ */

*
* @param {String} name
* @param {string} name
* @returns {boolean} Result

@@ -455,4 +455,4 @@ */

*
* @param {String} name - Attribute name to be tested
* @returns {Boolean} Result
* @param {string} name - Attribute name to be tested
* @returns {boolean} Result
*/

@@ -467,6 +467,10 @@

* @param {JSXAttribute} node - JSXAttribute being tested.
* @returns {String|null} tag name
* @returns {string | null} tag name
*/
function getTagName(node) {
if (node && node.parent && node.parent.name && node.parent.name) {
if (
node
&& node.parent
&& node.parent.name
) {
return node.parent.name.name;

@@ -481,3 +485,3 @@ }

* @param {JSXAttribute} node - JSXAttribute being tested.
* @returns {Boolean} result
* @returns {boolean} result
*/

@@ -494,5 +498,5 @@ function tagNameHasDot(node) {

* Get the standard name of the attribute.
* @param {String} name - Name of the attribute.
* @param {String} context - eslint context
* @returns {String | undefined} The standard name of the attribute, or undefined if no standard name was found.
* @param {string} name - Name of the attribute.
* @param {string} context - eslint context
* @returns {string | undefined} The standard name of the attribute, or undefined if no standard name was found.
*/

@@ -602,3 +606,5 @@ function getStandardName(name, context) {

// Some attributes are allowed on some tags only
const allowedTags = has(ATTRIBUTE_TAGS_MAP, name) ? ATTRIBUTE_TAGS_MAP[/** @type {keyof ATTRIBUTE_TAGS_MAP} */ (name)] : null;
const allowedTags = has(ATTRIBUTE_TAGS_MAP, name)
? ATTRIBUTE_TAGS_MAP[/** @type {keyof ATTRIBUTE_TAGS_MAP} */ (name)]
: null;
if (tagName && allowedTags) {

@@ -605,0 +611,0 @@ // Scenario 1A: Allowed attribute found where not supposed to, report it

@@ -60,14 +60,11 @@ /**

newMethod: 'componentDidMount',
details:
'See https://reactjs.org/blog/2018/03/27/update-on-async-rendering.html.',
details: 'See https://reactjs.org/blog/2018/03/27/update-on-async-rendering.html.',
},
UNSAFE_componentWillReceiveProps: {
newMethod: 'getDerivedStateFromProps',
details:
'See https://reactjs.org/blog/2018/03/27/update-on-async-rendering.html.',
details: 'See https://reactjs.org/blog/2018/03/27/update-on-async-rendering.html.',
},
UNSAFE_componentWillUpdate: {
newMethod: 'componentDidUpdate',
details:
'See https://reactjs.org/blog/2018/03/27/update-on-async-rendering.html.',
details: 'See https://reactjs.org/blog/2018/03/27/update-on-async-rendering.html.',
},

@@ -74,0 +71,0 @@ };

@@ -10,2 +10,3 @@ /**

const docsUrl = require('../util/docsUrl');
const astUtil = require('../util/ast');
const isCreateElement = require('../util/isCreateElement');

@@ -27,4 +28,4 @@ const report = require('../util/report');

* Generate error message with given parent component name
* @param {String} parentName Name of the parent component, if known
* @returns {String} Error message with parent component name
* @param {string} parentName Name of the parent component, if known
* @returns {string} Error message with parent component name
*/

@@ -37,7 +38,7 @@ function generateErrorMessageWithParentName(parentName) {

* Check whether given text starts with `render`. Comparison is case-sensitive.
* @param {String} text Text to validate
* @returns {Boolean}
* @param {string} text Text to validate
* @returns {boolean}
*/
function startsWithRender(text) {
return (text || '').startsWith('render');
return typeof text === 'string' && text.startsWith('render');
}

@@ -68,8 +69,7 @@

* @param {Context} context eslint context
* @returns {Boolean} True if node is a `createElement` call, false if not
* @returns {boolean} True if node is a `createElement` call, false if not
*/
function isCreateElementMatcher(node, context) {
return (
node
&& node.type === 'CallExpression'
astUtil.isCallExpression(node)
&& isCreateElement(context, node)

@@ -82,3 +82,3 @@ );

* @param {ASTNode} node The AST node
* @returns {Boolean} True if node is a `ObjectExpression`, false if not
* @returns {boolean} True if node is a `ObjectExpression`, false if not
*/

@@ -92,3 +92,3 @@ function isObjectExpressionMatcher(node) {

* @param {ASTNode} node The AST node
* @returns {Boolean} True if node is a `JSXExpressionContainer`, false if not
* @returns {boolean} True if node is a `JSXExpressionContainer`, false if not
*/

@@ -102,3 +102,3 @@ function isJSXExpressionContainerMatcher(node) {

* @param {ASTNode} node The AST node
* @returns {Boolean} True if node is a `JSXAttribute` of `JSXExpressionContainer`, false if not
* @returns {boolean} True if node is a `JSXAttribute` of `JSXExpressionContainer`, false if not
*/

@@ -117,3 +117,3 @@ function isJSXAttributeOfExpressionContainerMatcher(node) {

* @param {ASTNode} node The AST node
* @returns {Boolean} True if node is a `Property`, false if not
* @returns {boolean} True if node is a `Property`, false if not
*/

@@ -129,11 +129,2 @@ function isPropertyOfObjectExpressionMatcher(node) {

/**
* Matcher used to check whether given node is a `CallExpression`
* @param {ASTNode} node The AST node
* @returns {Boolean} True if node is a `CallExpression`, false if not
*/
function isCallExpressionMatcher(node) {
return node && node.type === 'CallExpression';
}
/**
* Check whether given node or its parent is directly inside `map` call

@@ -144,3 +135,3 @@ * ```jsx

* @param {ASTNode} node The AST node
* @returns {Boolean} True if node is directly inside `map` call, false if not
* @returns {boolean} True if node is directly inside `map` call, false if not
*/

@@ -160,3 +151,3 @@ function isMapCall(node) {

* @param {Context} context eslint context
* @returns {Boolean} True if node is a `ReturnStatement` of a React hook, false if not
* @returns {boolean} True if node is a `ReturnStatement` of a React hook, false if not
*/

@@ -172,3 +163,3 @@ function isReturnStatementOfHook(node, context) {

const callExpression = getClosestMatchingParent(node, context, isCallExpressionMatcher);
const callExpression = getClosestMatchingParent(node, context, astUtil.isCallExpression);
return (

@@ -189,3 +180,3 @@ callExpression

* @param {Context} context eslint context
* @returns {Boolean} True if component is declared inside a render prop, false if not
* @returns {boolean} True if component is declared inside a render prop, false if not
*/

@@ -247,3 +238,3 @@ function isComponentInRenderProp(node, context) {

* @param {ASTNode} node The AST node
* @returns {Boolean} True if component is declared inside a render property, false if not
* @returns {boolean} True if component is declared inside a render property, false if not
*/

@@ -264,3 +255,3 @@ function isDirectValueOfRenderProperty(node) {

* @param {ASTNode} node The AST node of the component
* @returns {String} Name of the component, if any
* @returns {string} Name of the component, if any
*/

@@ -321,3 +312,3 @@ function resolveComponentName(node) {

* @param {ASTNode} node The AST node being checked
* @returns {Boolean} True if node is inside class component's render block, false if not
* @returns {boolean} True if node is inside class component's render block, false if not
*/

@@ -350,3 +341,3 @@ function isInsideRenderMethod(node) {

* @param {ASTNode} node The AST node being checked
* @returns {Boolean} True if given node a function component declared inside class component, false if not
* @returns {boolean} True if given node a function component declared inside class component, false if not
*/

@@ -374,3 +365,3 @@ function isFunctionComponentInsideClassComponent(node) {

* @param {ASTNode} node The AST node
* @returns {Boolean} True if node is declare inside `createElement` call's props, false if not
* @returns {boolean} True if node is declare inside `createElement` call's props, false if not
*/

@@ -398,3 +389,3 @@ function isComponentInsideCreateElementsProp(node) {

* @param {ASTNode} node The AST node being checked
* @returns {Boolean} True if node is a component declared inside prop, false if not
* @returns {boolean} True if node is a component declared inside prop, false if not
*/

@@ -421,3 +412,3 @@ function isComponentInProp(node) {

* @param {ASTNode} node The AST node being checked
* @returns {Boolean} True if node is a stateless component returning non-JSX, false if not
* @returns {boolean} True if node is a stateless component returning non-JSX, false if not
*/

@@ -424,0 +415,0 @@ function isStatelessComponentReturningNull(node) {

@@ -17,2 +17,11 @@ /**

/**
* Checks if the component must be validated
* @param {Object} component The component to process
* @returns {boolean} True if the component must be validated, false if not.
*/
function mustBeValidated(component) {
return !!component && !component.ignoreUnusedPropTypesValidation;
}
// ------------------------------------------------------------------------------

@@ -68,4 +77,4 @@ // Rule Definition

* Checks if the prop is ignored
* @param {String} name Name of the prop to check.
* @returns {Boolean} True if the prop is ignored, false if not.
* @param {string} name Name of the prop to check.
* @returns {boolean} True if the prop is ignored, false if not.
*/

@@ -77,18 +86,6 @@ function isIgnored(name) {

/**
* Checks if the component must be validated
* @param {Object} component The component to process
* @returns {Boolean} True if the component must be validated, false if not.
*/
function mustBeValidated(component) {
return Boolean(
component
&& !component.ignoreUnusedPropTypesValidation
);
}
/**
* Checks if a prop is used
* @param {ASTNode} node The AST node being checked.
* @param {Object} prop Declared prop object
* @returns {Boolean} True if the prop is used, false if not.
* @returns {boolean} True if the prop is used, false if not.
*/

@@ -95,0 +92,0 @@ function isPropUsed(node, prop) {

@@ -13,3 +13,3 @@ /**

const docsUrl = require('../util/docsUrl');
const ast = require('../util/ast');
const astUtil = require('../util/ast');
const componentUtil = require('../util/componentUtil');

@@ -48,3 +48,3 @@ const report = require('../util/report');

function isThisExpression(node) {
return ast.unwrapTSAsExpression(uncast(node)).type === 'ThisExpression';
return astUtil.unwrapTSAsExpression(uncast(node)).type === 'ThisExpression';
}

@@ -70,3 +70,3 @@

function isSetStateCall(node) {
const unwrappedCalleeNode = ast.unwrapTSAsExpression(node.callee);
const unwrappedCalleeNode = astUtil.unwrapTSAsExpression(node.callee);

@@ -180,3 +180,3 @@ return (

function handleStateDestructuring(node) {
for (const prop of node.properties) {
node.properties.forEach((prop) => {
if (prop.type === 'Property') {

@@ -190,3 +190,3 @@ addUsedStateField(prop.key);

}
}
});
}

@@ -197,3 +197,3 @@

function handleAssignment(left, right) {
const unwrappedRight = ast.unwrapTSAsExpression(right);
const unwrappedRight = astUtil.unwrapTSAsExpression(right);

@@ -210,3 +210,3 @@ switch (left.type) {

} else if (isThisExpression(unwrappedRight) && classInfo.aliases) {
for (const prop of left.properties) {
left.properties.forEach((prop) => {
if (prop.type === 'Property' && getName(prop.key) === 'state') {

@@ -220,3 +220,3 @@ const name = getName(prop.value);

}
}
});
}

@@ -231,3 +231,3 @@ break;

// Report all unused state fields.
for (const node of classInfo.stateFields) {
classInfo.stateFields.forEach((node) => {
const name = getName(node.key);

@@ -242,3 +242,3 @@ if (!classInfo.usedStateFields.has(name)) {

}
}
});
}

@@ -305,4 +305,4 @@

const unwrappedNode = ast.unwrapTSAsExpression(node);
const unwrappedArgumentNode = ast.unwrapTSAsExpression(unwrappedNode.arguments[0]);
const unwrappedNode = astUtil.unwrapTSAsExpression(node);
const unwrappedArgumentNode = astUtil.unwrapTSAsExpression(unwrappedNode.arguments[0]);

@@ -322,3 +322,3 @@ // If we're looking at a `this.setState({})` invocation, record all the

) {
const unwrappedBodyNode = ast.unwrapTSAsExpression(unwrappedArgumentNode.body);
const unwrappedBodyNode = astUtil.unwrapTSAsExpression(unwrappedArgumentNode.body);

@@ -345,3 +345,3 @@ if (unwrappedBodyNode.type === 'ObjectExpression') {

// expression, record all the fields of that object as state fields.
const unwrappedValueNode = ast.unwrapTSAsExpression(node.value);
const unwrappedValueNode = astUtil.unwrapTSAsExpression(node.value);

@@ -468,4 +468,4 @@ const name = getName(node.key);

const unwrappedLeft = ast.unwrapTSAsExpression(node.left);
const unwrappedRight = ast.unwrapTSAsExpression(node.right);
const unwrappedLeft = astUtil.unwrapTSAsExpression(node.left);
const unwrappedRight = astUtil.unwrapTSAsExpression(node.right);

@@ -510,3 +510,3 @@ // Check for assignments like `this.state = {}`

}
if (isStateReference(ast.unwrapTSAsExpression(node.object))) {
if (isStateReference(astUtil.unwrapTSAsExpression(node.object))) {
// If we see this.state[foo] access, give up.

@@ -520,3 +520,3 @@ if (node.computed && node.property.type !== 'Literal') {

// If we see a `this.state` access in a CallExpression, give up.
} else if (isStateReference(node) && node.parent.type === 'CallExpression') {
} else if (isStateReference(node) && astUtil.isCallExpression(node.parent)) {
classInfo = null;

@@ -523,0 +523,0 @@ }

@@ -9,2 +9,3 @@ /**

const docsUrl = require('../util/docsUrl');
const astUtil = require('../util/ast');
const propsUtil = require('../util/props');

@@ -85,4 +86,3 @@ const propWrapperUtil = require('../util/propWrapper');

return (
node
&& node.type === 'CallExpression'
astUtil.isCallExpression(node)
&& !propWrapperUtil.isExactPropWrapperFunction(context, getText(context, node.callee))

@@ -89,0 +89,0 @@ );

@@ -73,3 +73,3 @@ /**

&& body[0].type === 'ExpressionStatement'
&& body[0].expression.type === 'CallExpression'
&& astUtil.isCallExpression(body[0].expression)
&& body[0].expression.callee.type === 'Super'

@@ -195,3 +195,3 @@ );

* @param {ASTNode} node The AST node being checked.
* @returns {Boolean} True if the node has at least one other property, false if not.
* @returns {boolean} True if the node has at least one other property, false if not.
*/

@@ -359,3 +359,5 @@ function hasOtherProperties(node) {

}
const isRender = blockNode && blockNode.key && blockNode.key.name === 'render';
const isRender = blockNode
&& blockNode.key
&& blockNode.key.name === 'render';
const allowNull = testReactVersion(context, '>= 15.0.0'); // Stateless components can return null since React 15

@@ -362,0 +364,0 @@ const isReturningJSX = utils.isReturningJSX(node, !allowNull);

@@ -67,4 +67,4 @@ /**

* Checks if the prop is ignored
* @param {String} name Name of the prop to check.
* @returns {Boolean} True if the prop is ignored, false if not.
* @param {string} name Name of the prop to check.
* @returns {boolean} True if the prop is ignored, false if not.
*/

@@ -93,3 +93,3 @@ function isIgnored(name) {

* @param {Object} declaredPropTypes Description of propTypes declared in the current component
* @param {String[]} keyList Dot separated name of the prop to check.
* @param {string[]} keyList Dot separated name of the prop to check.
* @returns {boolean} True if the prop is declared, false if not.

@@ -153,4 +153,4 @@ */

* @param {ASTNode} node The AST node being checked.
* @param {String[]} names List of names of the prop to check.
* @returns {Boolean} True if the prop is declared, false if not.
* @param {string[]} names List of names of the prop to check.
* @returns {boolean} True if the prop is declared, false if not.
*/

@@ -196,3 +196,3 @@ function isDeclaredInComponent(node, names) {

* @param {Array} list The all components to process
* @returns {Boolean} True if the component is nested False if not.
* @returns {boolean} True if the component is nested False if not.
*/

@@ -199,0 +199,0 @@ function checkNestedComponent(component, list) {

@@ -53,3 +53,3 @@ /**

* @param {ASTNode} node The AST node being checked.
* @returns {Boolean} True if node is decorated with a PureRenderMixin, false if not.
* @returns {boolean} True if node is decorated with a PureRenderMixin, false if not.
*/

@@ -81,3 +81,3 @@ function hasPureRenderDecorator(node) {

* @param {ASTNode} node The AST node being checked.
* @returns {Boolean} True if node is decorated name with a custom decorated, false if not.
* @returns {boolean} True if node is decorated name with a custom decorated, false if not.
*/

@@ -90,5 +90,6 @@ function hasCustomDecorator(node) {

for (let j = 0, l = node.decorators.length; j < l; j++) {
const expression = node.decorators[j].expression;
if (
node.decorators[j].expression
&& node.decorators[j].expression.name === allowDecorators[i]
expression
&& expression.name === allowDecorators[i]
) {

@@ -107,9 +108,6 @@ return true;

* @param {ASTNode} node The AST node being checked.
* @returns {Boolean} True if we are declaring a shouldComponentUpdate method, false if not.
* @returns {boolean} True if we are declaring a shouldComponentUpdate method, false if not.
*/
function isSCUDeclared(node) {
return Boolean(
node
&& node.name === 'shouldComponentUpdate'
);
return !!node && node.name === 'shouldComponentUpdate';
}

@@ -120,3 +118,3 @@

* @param {ASTNode} node The AST node being checked.
* @returns {Boolean} True if we are declaring a PureRenderMixin method, false if not.
* @returns {boolean} True if we are declaring a PureRenderMixin method, false if not.
*/

@@ -134,4 +132,4 @@ function isPureRenderDeclared(node) {

return Boolean(
node
return (
!!node
&& node.key.name === 'mixins'

@@ -138,0 +136,0 @@ && hasPR

@@ -12,2 +12,27 @@ /**

const optionDefaults = { component: true, html: true };
function isComponent(node) {
return (
node.name
&& (node.name.type === 'JSXIdentifier' || node.name.type === 'JSXMemberExpression')
&& !jsxUtil.isDOMComponent(node)
);
}
function childrenIsEmpty(node) {
return node.parent.children.length === 0;
}
function childrenIsMultilineSpaces(node) {
const childrens = node.parent.children;
return (
childrens.length === 1
&& (childrens[0].type === 'Literal' || childrens[0].type === 'JSXText')
&& childrens[0].value.indexOf('\n') !== -1
&& childrens[0].value.replace(/(?!\xA0)\s/g, '') === ''
);
}
// ------------------------------------------------------------------------------

@@ -17,4 +42,2 @@ // Rule Definition

const optionDefaults = { component: true, html: true };
const messages = {

@@ -54,25 +77,2 @@ notSelfClosing: 'Empty components are self-closing',

create(context) {
function isComponent(node) {
return (
node.name
&& (node.name.type === 'JSXIdentifier' || node.name.type === 'JSXMemberExpression')
&& !jsxUtil.isDOMComponent(node)
);
}
function childrenIsEmpty(node) {
return node.parent.children.length === 0;
}
function childrenIsMultilineSpaces(node) {
const childrens = node.parent.children;
return (
childrens.length === 1
&& (childrens[0].type === 'Literal' || childrens[0].type === 'JSXText')
&& childrens[0].value.indexOf('\n') !== -1
&& childrens[0].value.replace(/(?!\xA0)\s/g, '') === ''
);
}
function isShouldBeSelfClosed(node) {

@@ -79,0 +79,0 @@ const configuration = Object.assign({}, optionDefaults, context.options[0]);

@@ -237,3 +237,3 @@ /**

* @param {Object} node - Property.
* @returns {String} Property name.
* @returns {string} Property name.
*/

@@ -240,0 +240,0 @@ function getPropertyName(node) {

@@ -55,3 +55,3 @@ /**

* @param {Object} node - Property.
* @returns {String} Property name.
* @returns {string} Property name.
*/

@@ -77,3 +77,3 @@ function getPropertyName(node) {

* @param {ASTNode} node The node to check. Must be an Identifier node.
* @returns {Boolean} `true` if the node is a defaultProps declaration, `false` if not
* @returns {boolean} `true` if the node is a defaultProps declaration, `false` if not
*/

@@ -80,0 +80,0 @@ function isDefaultPropsDeclaration(node) {

@@ -7,2 +7,3 @@ /**

const astUtil = require('../util/ast');
const variableUtil = require('../util/variable');

@@ -39,24 +40,2 @@ const propsUtil = require('../util/props');

function getValueName(node) {
return node.type === 'Property' && node.value.property && node.value.property.name;
}
function isCallbackPropName(propName) {
return /^on[A-Z]/.test(propName);
}
function isRequiredProp(node) {
return getValueName(node) === 'isRequired';
}
function isShapeProp(node) {
return Boolean(
node && node.callee && node.callee.property && node.callee.property.name === 'shape'
);
}
function toLowerCase(item) {
return String(item).toLowerCase();
}
/** @type {import('eslint').Rule.RuleModule} */

@@ -150,10 +129,10 @@ module.exports = {

let currentPropName = getKey(context, curr);
const previousIsRequired = isRequiredProp(prev);
const currentIsRequired = isRequiredProp(curr);
const previousIsCallback = isCallbackPropName(prevPropName);
const currentIsCallback = isCallbackPropName(currentPropName);
const previousIsRequired = propTypesSortUtil.isRequiredProp(prev);
const currentIsRequired = propTypesSortUtil.isRequiredProp(curr);
const previousIsCallback = propTypesSortUtil.isCallbackPropName(prevPropName);
const currentIsCallback = propTypesSortUtil.isCallbackPropName(currentPropName);
if (ignoreCase) {
prevPropName = toLowerCase(prevPropName);
currentPropName = toLowerCase(currentPropName);
prevPropName = String(prevPropName).toLowerCase();
currentPropName = String(currentPropName).toLowerCase();
}

@@ -213,22 +192,18 @@

function checkNode(node) {
switch (node && node.type) {
case 'ObjectExpression':
checkSorted(node.properties);
break;
case 'Identifier': {
const propTypesObject = variableUtil.findVariableByName(context, node, node.name);
if (propTypesObject && propTypesObject.properties) {
checkSorted(propTypesObject.properties);
}
break;
if (!node) {
return;
}
if (node.type === 'ObjectExpression') {
checkSorted(node.properties);
} else if (node.type === 'Identifier') {
const propTypesObject = variableUtil.findVariableByName(context, node, node.name);
if (propTypesObject && propTypesObject.properties) {
checkSorted(propTypesObject.properties);
}
case 'CallExpression': {
const innerNode = node.arguments && node.arguments[0];
if (propWrapperUtil.isPropWrapperFunction(context, node.callee.name) && innerNode) {
checkNode(innerNode);
}
break;
} else if (astUtil.isCallExpression(node)) {
const innerNode = node.arguments && node.arguments[0];
if (propWrapperUtil.isPropWrapperFunction(context, node.callee.name) && innerNode) {
checkNode(innerNode);
}
default:
break;
}

@@ -267,3 +242,3 @@ }

CallExpression(node) {
if (!sortShapeProp || !isShapeProp(node) || !(node.arguments && node.arguments[0])) {
if (!sortShapeProp || !propTypesSortUtil.isShapeProp(node) || !(node.arguments && node.arguments[0])) {
return;

@@ -270,0 +245,0 @@ }

@@ -102,3 +102,3 @@ /**

* @param {ASTNode} node
* @returns {Boolean} True if we are declaring context in class, false if not.
* @returns {boolean} True if we are declaring context in class, false if not.
*/

@@ -105,0 +105,0 @@ function isContextInClass(node) {

@@ -15,3 +15,3 @@ /**

* @param {Object} context
* @returns {Boolean} True if the node is a type annotated props declaration, false if not.
* @returns {boolean} True if the node is a type annotated props declaration, false if not.
*/

@@ -18,0 +18,0 @@ function isAnnotatedFunctionPropsDeclaration(node, context) {

@@ -95,3 +95,3 @@ /**

/* TODO: properly warn on React.forwardRefs having typo properties
if (nodeType === 'CallExpression') {
if (astUtil.isCallExpression(ASTNode)) {
const callee = ASTNode.callee;

@@ -152,3 +152,7 @@ const pragma = pragmaUtil.getFromContext(context);

function getPropertyNameNode(node) {
if (node.key || ['MethodDefinition', 'Property'].indexOf(node.type) !== -1) {
if (
node.key
|| node.type === 'MethodDefinition'
|| node.type === 'Property'
) {
return node.key;

@@ -165,3 +169,3 @@ }

* @param {Object} node - Property.
* @returns {String} Property name.
* @returns {string} Property name.
*/

@@ -216,3 +220,3 @@ function getPropertyName(node) {

* @param {ASTNode} node The node to check
* @return {Boolean} true if it's the first node in its line
* @return {boolean} true if it's the first node in its line
*/

@@ -229,3 +233,3 @@ function isNodeFirstInLine(context, node) {

* @param {ASTNode} node The node to check
* @return {Boolean} true if it's a function-like expression
* @return {boolean} true if it's a function-like expression
*/

@@ -239,3 +243,3 @@ function isFunctionLikeExpression(node) {

* @param {ASTNode} node The node to check
* @return {Boolean} true if it's a function
* @return {boolean} true if it's a function
*/

@@ -249,3 +253,3 @@ function isFunction(node) {

* @param {ASTNode} node The node to check
* @return {Boolean} true if it's a function-like
* @return {boolean} true if it's a function-like
*/

@@ -259,3 +263,3 @@ function isFunctionLike(node) {

* @param {ASTNode} node The node to check
* @return {Boolean} true if it's a class
* @return {boolean} true if it's a class
*/

@@ -340,3 +344,3 @@ function isClass(node) {

* @param {ASTNode} node The AST node being checked.
* @returns {Boolean}
* @returns {boolean}
*/

@@ -351,3 +355,16 @@ function isAssignmentLHS(node) {

function isTSAsExpression(node) {
return node && node.type === 'TSAsExpression';
}
/**
* Matcher used to check whether given node is a `CallExpression`
* @param {ASTNode} node The AST node
* @returns {boolean} True if node is a `CallExpression`, false if not
*/
function isCallExpression(node) {
return node && node.type === 'CallExpression';
}
/**
* Extracts the expression node that is wrapped inside a TS type assertion

@@ -359,4 +376,3 @@ *

function unwrapTSAsExpression(node) {
if (node && node.type === 'TSAsExpression') return node.expression;
return node;
return isTSAsExpression(node) ? node.expression : node;
}

@@ -366,114 +382,114 @@

if (!node) return false;
const nodeType = node.type;
return nodeType === 'TSTypeReference';
return node.type === 'TSTypeReference';
}
function isTSTypeAnnotation(node) {
if (!node) return false;
const nodeType = node.type;
return nodeType === 'TSTypeAnnotation';
if (!node) { return false; }
return node.type === 'TSTypeAnnotation';
}
function isTSTypeLiteral(node) {
if (!node) return false;
const nodeType = node.type;
return nodeType === 'TSTypeLiteral';
if (!node) { return false; }
return node.type === 'TSTypeLiteral';
}
function isTSIntersectionType(node) {
if (!node) return false;
const nodeType = node.type;
return nodeType === 'TSIntersectionType';
if (!node) { return false; }
return node.type === 'TSIntersectionType';
}
function isTSInterfaceHeritage(node) {
if (!node) return false;
const nodeType = node.type;
return nodeType === 'TSInterfaceHeritage';
if (!node) { return false; }
return node.type === 'TSInterfaceHeritage';
}
function isTSInterfaceDeclaration(node) {
if (!node) return false;
let nodeType = node.type;
if (node.type === 'ExportNamedDeclaration' && node.declaration) {
nodeType = node.declaration.type;
}
return nodeType === 'TSInterfaceDeclaration';
if (!node) { return false; }
return (node.type === 'ExportNamedDeclaration' && node.declaration
? node.declaration.type
: node.type
) === 'TSInterfaceDeclaration';
}
function isTSTypeDeclaration(node) {
if (!node) return false;
let nodeType = node.type;
let nodeKind = node.kind;
if (node.type === 'ExportNamedDeclaration' && node.declaration) {
nodeType = node.declaration.type;
nodeKind = node.declaration.kind;
}
return nodeType === 'VariableDeclaration' && nodeKind === 'type';
if (!node) { return false; }
const nodeToCheck = node.type === 'ExportNamedDeclaration' && node.declaration
? node.declaration
: node;
return nodeToCheck.type === 'VariableDeclaration' && nodeToCheck.kind === 'type';
}
function isTSTypeAliasDeclaration(node) {
if (!node) return false;
let nodeType = node.type;
if (!node) { return false; }
if (node.type === 'ExportNamedDeclaration' && node.declaration) {
nodeType = node.declaration.type;
return nodeType === 'TSTypeAliasDeclaration' && node.exportKind === 'type';
return node.declaration.type === 'TSTypeAliasDeclaration' && node.exportKind === 'type';
}
return nodeType === 'TSTypeAliasDeclaration';
return node.type === 'TSTypeAliasDeclaration';
}
function isTSParenthesizedType(node) {
if (!node) return false;
const nodeType = node.type;
return nodeType === 'TSTypeAliasDeclaration';
if (!node) { return false; }
return node.type === 'TSTypeAliasDeclaration';
}
function isTSFunctionType(node) {
if (!node) return false;
const nodeType = node.type;
return nodeType === 'TSFunctionType';
if (!node) { return false; }
return node.type === 'TSFunctionType';
}
function isTSTypeQuery(node) {
if (!node) return false;
const nodeType = node.type;
return nodeType === 'TSTypeQuery';
if (!node) { return false; }
return node.type === 'TSTypeQuery';
}
function isTSTypeParameterInstantiation(node) {
if (!node) return false;
const nodeType = node.type;
return nodeType === 'TSTypeParameterInstantiation';
if (!node) { return false; }
return node.type === 'TSTypeParameterInstantiation';
}
module.exports = {
traverse,
findReturnStatement,
getComponentProperties,
getFirstNodeInLine,
getKeyValue,
getPropertyName,
getPropertyNameNode,
getComponentProperties,
getKeyValue,
isParenthesized,
inConstructor,
isAssignmentLHS,
isCallExpression,
isClass,
isFunction,
isFunctionLike,
isFunctionLikeExpression,
isFunctionLike,
inConstructor,
isNodeFirstInLine,
unwrapTSAsExpression,
traverseReturns,
isTSTypeReference,
isParenthesized,
isTSAsExpression,
isTSFunctionType,
isTSInterfaceDeclaration,
isTSInterfaceHeritage,
isTSIntersectionType,
isTSParenthesizedType,
isTSTypeAliasDeclaration,
isTSTypeAnnotation,
isTSTypeDeclaration,
isTSTypeLiteral,
isTSIntersectionType,
isTSInterfaceHeritage,
isTSInterfaceDeclaration,
isTSTypeAliasDeclaration,
isTSParenthesizedType,
isTSFunctionType,
isTSTypeParameterInstantiation,
isTSTypeQuery,
isTSTypeParameterInstantiation,
isTSTypeDeclaration,
isTSTypeReference,
traverse,
traverseReturns,
unwrapTSAsExpression,
};

@@ -73,3 +73,3 @@ /**

* @param {ASTNode} node The AST node being added.
* @param {Number} confidence Confidence in the component detection (0=banned, 1=maybe, 2=yes)
* @param {number} confidence Confidence in the component detection (0=banned, 1=maybe, 2=yes)
* @returns {Object} Added component object

@@ -187,3 +187,3 @@ */

*
* @returns {Number} Components list length
* @returns {number} Components list length
*/

@@ -308,16 +308,16 @@ length() {

/**
* @param {ASTNode} ASTNode
* @param {ASTNode} node
* @param {boolean=} strict
* @returns {boolean}
*/
isReturningJSX(ASTNode, strict) {
return jsxUtil.isReturningJSX(context, ASTNode, strict, true);
isReturningJSX(node, strict) {
return jsxUtil.isReturningJSX(context, node, strict, true);
},
isReturningJSXOrNull(ASTNode, strict) {
return jsxUtil.isReturningJSX(context, ASTNode, strict);
isReturningJSXOrNull(node, strict) {
return jsxUtil.isReturningJSX(context, node, strict);
},
isReturningOnlyNull(ASTNode) {
return jsxUtil.isReturningOnlyNull(ASTNode, context);
isReturningOnlyNull(node) {
return jsxUtil.isReturningOnlyNull(node, context);
},

@@ -413,3 +413,3 @@

isPragmaComponentWrapper(node) {
if (!node || node.type !== 'CallExpression') {
if (!astUtil.isCallExpression(node)) {
return false;

@@ -574,3 +574,9 @@ }

// for case abc = { [someobject.somekey]: props => { ... return not-jsx } }
if (node.parent && node.parent.key && node.parent.key.type === 'MemberExpression' && !utils.isReturningJSX(node) && !utils.isReturningOnlyNull(node)) {
if (
node.parent
&& node.parent.key
&& node.parent.key.type === 'MemberExpression'
&& !utils.isReturningJSX(node)
&& !utils.isReturningOnlyNull(node)
) {
return undefined;

@@ -585,3 +591,6 @@ }

) {
if (isFirstLetterCapitalized(node.parent.key.name) && utils.isReturningJSX(node)) {
if (
isFirstLetterCapitalized(node.parent.key.name)
&& utils.isReturningJSX(node)
) {
return node;

@@ -650,3 +659,3 @@ }

* @param {ASTNode} node The AST node being checked (must be a MemberExpression).
* @returns {ASTNode} component node, null if we cannot find the component
* @returns {ASTNode | null} component node, null if we cannot find the component
*/

@@ -761,6 +770,6 @@ getRelatedComponent(node) {

* @param {('useCallback'|'useContext'|'useDebugValue'|'useEffect'|'useImperativeHandle'|'useLayoutEffect'|'useMemo'|'useReducer'|'useRef'|'useState')[]} [expectedHookNames] React hook names to which search is limited.
* @returns {Boolean} True if the node is a call to a React hook
* @returns {boolean} True if the node is a call to a React hook
*/
isReactHookCall(node, expectedHookNames) {
if (node.type !== 'CallExpression') {
if (!astUtil.isCallExpression(node)) {
return false;

@@ -809,4 +818,10 @@ }

const hookResolvedDefs = potentialHookReference && potentialHookReference.resolved.defs;
const localHookName = (isPotentialReactHookCall && node.callee.property.name)
|| (isPotentialHookCall && potentialHookReference && node.callee.name);
const localHookName = (
isPotentialReactHookCall
&& node.callee.property.name
) || (
isPotentialHookCall
&& potentialHookReference
&& node.callee.name
);
const isHookShadowed = isPotentialHookCall

@@ -888,7 +903,7 @@ && hookResolvedDefs

node = utils.getStatelessComponent(node);
if (!node) {
const cNode = utils.getStatelessComponent(node);
if (!cNode) {
return;
}
components.add(node, 2);
components.add(cNode, 2);
},

@@ -895,0 +910,0 @@

@@ -177,3 +177,5 @@ 'use strict';

function isStateMemberExpression(node) {
return node.type === 'MemberExpression' && node.object.type === 'ThisExpression' && node.property.name === 'state';
return node.type === 'MemberExpression'
&& node.object.type === 'ThisExpression'
&& node.property.name === 'state';
}

@@ -180,0 +182,0 @@

@@ -29,3 +29,3 @@ /**

if (
node.type === 'CallExpression'
astUtil.isCallExpression(node)
&& propWrapperUtil.isPropWrapperFunction(context, node.callee.name)

@@ -32,0 +32,0 @@ && node.arguments && node.arguments[0]

@@ -5,3 +5,3 @@ 'use strict';

* Logs out a message if there is no format option set.
* @param {String} message - Message to log.
* @param {string} message - Message to log.
*/

@@ -8,0 +8,0 @@ function error(message) {

'use strict';
const astUtil = require('./ast');
/**
* Checks if the node is a React.createContext call
* @param {ASTNode} node - The AST node being checked.
* @returns {Boolean} - True if node is a React.createContext call, false if not.
* @returns {boolean} - True if node is a React.createContext call, false if not.
*/

@@ -11,17 +13,18 @@ module.exports = function isCreateContext(node) {

node.init
&& node.init.type === 'CallExpression'
&& node.init.callee
&& node.init.callee.name === 'createContext'
) {
return true;
}
if (
astUtil.isCallExpression(node.init)
&& node.init.callee.name === 'createContext'
) {
return true;
}
if (
node.init
&& node.init.callee
&& node.init.callee.type === 'MemberExpression'
&& node.init.callee.property
&& node.init.callee.property.name === 'createContext'
) {
return true;
if (
node.init.callee.type === 'MemberExpression'
&& node.init.callee.property
&& node.init.callee.property.name === 'createContext'
) {
return true;
}
}

@@ -33,20 +36,18 @@

&& node.expression.operator === '='
&& node.expression.right.type === 'CallExpression'
&& astUtil.isCallExpression(node.expression.right)
&& node.expression.right.callee
&& node.expression.right.callee.name === 'createContext'
) {
return true;
}
const right = node.expression.right;
if (
node.expression
&& node.expression.type === 'AssignmentExpression'
&& node.expression.operator === '='
&& node.expression.right.type === 'CallExpression'
&& node.expression.right.callee
&& node.expression.right.callee.type === 'MemberExpression'
&& node.expression.right.callee.property
&& node.expression.right.callee.property.name === 'createContext'
) {
return true;
if (right.callee.name === 'createContext') {
return true;
}
if (
right.callee.type === 'MemberExpression'
&& right.callee.property
&& right.callee.property.name === 'createContext'
) {
return true;
}
}

@@ -53,0 +54,0 @@

@@ -13,5 +13,8 @@ 'use strict';

module.exports = function isCreateElement(context, node) {
if (!node.callee) {
return false;
}
if (
node.callee
&& node.callee.type === 'MemberExpression'
node.callee.type === 'MemberExpression'
&& node.callee.property.name === 'createElement'

@@ -25,5 +28,3 @@ && node.callee.object

if (
node
&& node.callee
&& node.callee.name === 'createElement'
node.callee.name === 'createElement'
&& isDestructuredFromPragmaImport(context, node, 'createElement')

@@ -30,0 +31,0 @@ ) {

'use strict';
const astUtil = require('./ast');
const pragmaUtil = require('./pragma');

@@ -25,4 +26,4 @@ const variableUtil = require('./variable');

latestDef.node.init.type === 'MemberExpression'
&& latestDef.node.init.object.type === 'Identifier'
&& latestDef.node.init.object.name === pragma
&& latestDef.node.init.object.type === 'Identifier'
&& latestDef.node.init.object.name === pragma
) {

@@ -34,3 +35,3 @@ return true;

latestDef.node.init.type === 'Identifier'
&& latestDef.node.init.name === pragma
&& latestDef.node.init.name === pragma
) {

@@ -44,3 +45,3 @@ return true;

// get "require('react')" from: "{variable} = require('react')"
if (latestDef.node.init.type === 'CallExpression') {
if (astUtil.isCallExpression(latestDef.node.init)) {
requireExpression = latestDef.node.init;

@@ -51,4 +52,4 @@ }

!requireExpression
&& latestDef.node.init.type === 'MemberExpression'
&& latestDef.node.init.object.type === 'CallExpression'
&& latestDef.node.init.type === 'MemberExpression'
&& astUtil.isCallExpression(latestDef.node.init.object)
) {

@@ -61,6 +62,6 @@ requireExpression = latestDef.node.init.object;

requireExpression
&& requireExpression.callee
&& requireExpression.callee.name === 'require'
&& requireExpression.arguments[0]
&& requireExpression.arguments[0].value === pragma.toLocaleLowerCase()
&& requireExpression.callee
&& requireExpression.callee.name === 'require'
&& requireExpression.arguments[0]
&& requireExpression.arguments[0].value === pragma.toLocaleLowerCase()
) {

@@ -76,4 +77,4 @@ return true;

latestDef.parent
&& latestDef.parent.type === 'ImportDeclaration'
&& latestDef.parent.source.value === pragma.toLocaleLowerCase()
&& latestDef.parent.type === 'ImportDeclaration'
&& latestDef.parent.source.value === pragma.toLocaleLowerCase()
) {

@@ -80,0 +81,0 @@ return true;

@@ -5,6 +5,6 @@ 'use strict';

* Check if the first letter of a string is capitalized.
* @param {String} word String to check
* @returns {Boolean} True if first letter is capitalized.
* @param {string} word String to check
* @returns {boolean} True if first letter is capitalized.
*/
function isFirstLetterCapitalized(word) {
module.exports = function isFirstLetterCapitalized(word) {
if (!word) {

@@ -15,4 +15,2 @@ return false;

return firstLetter.toUpperCase() === firstLetter;
}
module.exports = isFirstLetterCapitalized;
};

@@ -79,3 +79,3 @@ /**

* Check if value has only whitespaces
* @param {string} value
* @param {unknown} value
* @returns {boolean}

@@ -92,5 +92,5 @@ */

* @param {ASTNode} ASTnode The AST node being checked
* @param {Boolean} [strict] If true, in a ternary condition the node must return JSX in both cases
* @param {Boolean} [ignoreNull] If true, null return values will be ignored
* @returns {Boolean} True if the node is returning JSX or null, false if not
* @param {boolean} [strict] If true, in a ternary condition the node must return JSX in both cases
* @param {boolean} [ignoreNull] If true, null return values will be ignored
* @returns {boolean} True if the node is returning JSX or null, false if not
*/

@@ -150,3 +150,3 @@ function isReturningJSX(context, ASTnode, strict, ignoreNull) {

* @param {Context} context The context of `ASTNode`.
* @returns {Boolean} True if the node is returning only null values
* @returns {boolean} True if the node is returning only null values
*/

@@ -153,0 +153,0 @@ function isReturningOnlyNull(ASTnode, context) {

@@ -5,3 +5,3 @@ 'use strict';

* Logs out a message if there is no format option set.
* @param {String} message - Message to log.
* @param {string} message - Message to log.
*/

@@ -8,0 +8,0 @@ function log(message) {

@@ -12,3 +12,3 @@ /**

* @param {ASTNode} node The node to check. Must be an Identifier node.
* @returns {Boolean} `true` if the node is a propTypes declaration, `false` if not
* @returns {boolean} `true` if the node is a propTypes declaration, `false` if not
*/

@@ -28,3 +28,3 @@ function isPropTypesDeclaration(node) {

* @param {ASTNode} node The node to check.
* @returns {Boolean} `true` if the node is a contextTypes declaration, `false` if not
* @returns {boolean} `true` if the node is a contextTypes declaration, `false` if not
*/

@@ -44,3 +44,3 @@ function isContextTypesDeclaration(node) {

* @param {ASTNode} node The node to check.
* @returns {Boolean} `true` if the node is a contextType declaration, `false` if not
* @returns {boolean} `true` if the node is a contextType declaration, `false` if not
*/

@@ -54,3 +54,3 @@ function isContextTypeDeclaration(node) {

* @param {ASTNode} node The node to check.
* @returns {Boolean} `true` if the node is a childContextTypes declaration, `false` if not
* @returns {boolean} `true` if the node is a childContextTypes declaration, `false` if not
*/

@@ -64,3 +64,3 @@ function isChildContextTypesDeclaration(node) {

* @param {ASTNode} node The node to check. Must be an Identifier node.
* @returns {Boolean} `true` if the node is a defaultProps declaration, `false` if not
* @returns {boolean} `true` if the node is a defaultProps declaration, `false` if not
*/

@@ -75,3 +75,3 @@ function isDefaultPropsDeclaration(node) {

* @param {ASTNode} node The AST node being checked.
* @returns {Boolean} True if we are declaring a display name, false if not.
* @returns {boolean} True if we are declaring a display name, false if not.
*/

@@ -95,6 +95,7 @@ function isDisplayNameDeclaration(node) {

* @param {ASTNode} propTypeExpression node to check. Must be a `PropTypes` MemberExpression.
* @returns {Boolean} `true` if this PropType is required, `false` if not.
* @returns {boolean} `true` if this PropType is required, `false` if not.
*/
function isRequiredPropType(propTypeExpression) {
return propTypeExpression.type === 'MemberExpression' && propTypeExpression.property.name === 'isRequired';
return propTypeExpression.type === 'MemberExpression'
&& propTypeExpression.property.name === 'isRequired';
}

@@ -101,0 +102,0 @@

@@ -26,3 +26,3 @@ /**

* @param {ASTNode} node
* @returns {Boolean}
* @returns {boolean}
*/

@@ -41,3 +41,3 @@ function isFunctionType(node) {

* @param {ASTNode} node the AST node being checked.
* @returns {Boolean} True if the node is a class with generic prop types, false if not.
* @returns {boolean} True if the node is a class with generic prop types, false if not.
*/

@@ -81,4 +81,4 @@ function isSuperTypeParameterPropsDeclaration(node) {

*
* @param {ASTNode} node the AST node being checked.
* @returns {Boolean} True if the node has a ClassBody ancestor, false if not.
* @param {ASTNode} node the AST node being checked.
* @returns {boolean} True if the node has a ClassBody ancestor, false if not.
*/

@@ -158,4 +158,4 @@ function isInsideClassBody(node) {

* Checks if prop should be validated by plugin-react-proptypes
* @param {String} validator Name of validator to check.
* @returns {Boolean} True if validator should be checked by custom validator.
* @param {string} validator Name of validator to check.
* @returns {boolean} True if validator should be checked by custom validator.
*/

@@ -179,3 +179,3 @@ function hasCustomValidator(validator) {

let containsSpread = false;
const containsIndexers = Boolean(annotation.indexers && annotation.indexers.length);
const containsIndexers = !!annotation.indexers && annotation.indexers.length > 0;
const shapeTypeDefinition = {

@@ -275,3 +275,3 @@ type: 'shape',

* @param {ASTNode} annotation Type annotation for the props class property.
* @param {String} parentName
* @param {string} parentName
* @param {Set<ASTNode>} [seen]

@@ -305,3 +305,3 @@ * @return {Object} The representation of the declaration, empty object means

* @param {Object} declaredPropTypes
* @returns {Boolean} True if propTypes should be ignored (e.g. when a type can't be resolved, when it is imported)
* @returns {boolean} True if propTypes should be ignored (e.g. when a type can't be resolved, when it is imported)
*/

@@ -344,3 +344,3 @@ function declarePropTypesForObjectTypeAnnotation(propTypes, declaredPropTypes) {

* @param {Object} declaredPropTypes
* @returns {Boolean} True if propTypes should be ignored (e.g. when a type can't be resolved, when it is imported)
* @returns {boolean} True if propTypes should be ignored (e.g. when a type can't be resolved, when it is imported)
*/

@@ -438,3 +438,2 @@ function declarePropTypesForIntersectionTypeAnnotation(propTypes, declaredPropTypes) {

&& value.property
&& value.property.name
&& value.property.name === 'isRequired'

@@ -459,4 +458,3 @@ ) {

if (
value
&& value.type === 'CallExpression'
astUtil.isCallExpression(value)
&& value.callee

@@ -510,3 +508,3 @@ && value.callee.property

!argument.elements
|| !argument.elements.length
|| argument.elements.length === 0
) {

@@ -590,4 +588,8 @@ // Invalid proptype or cannot analyse statically

return (
(node.id && node.id.name === typeName)
|| (node.declaration && node.declaration.id && node.declaration.id.name === typeName)
node.id
&& node.id.name === typeName
) || (
node.declaration
&& node.declaration.id
&& node.declaration.id.name === typeName
);

@@ -710,3 +712,11 @@ }

candidateTypes,
(type) => type.declarations || (type.declaration && type.declaration.declarations) || type.declaration);
(type) => (
type.declarations
|| (
type.declaration
&& type.declaration.declarations
)
|| type.declaration
)
);

@@ -799,3 +809,3 @@ // we tried to find either an interface or a type with the TypeReference name

iterateProperties(context, res.properties, (key, value, propNode) => {
if (propNode && propNode.argument && propNode.argument.type === 'CallExpression') {
if (propNode && astUtil.isCallExpression(propNode.argument)) {
const propNodeTypeParams = propNode.argument.typeParameters;

@@ -1152,3 +1162,3 @@ if (propNodeTypeParams) {

* @param {ASTNode} node The AST node being checked.
* @returns {Boolean} True if the node is a type annotated props declaration, false if not.
* @returns {boolean} True if the node is a type annotated props declaration, false if not.
*/

@@ -1155,0 +1165,0 @@ function isAnnotatedClassPropsDeclaration(node) {

@@ -19,6 +19,8 @@ /**

* @param {ASTNode} node the node to check.
* @returns {String} The name of the node.
* @returns {string} The name of the node.
*/
function getValueName(node) {
return node.type === 'Property' && node.value.property && node.value.property.name;
return node.type === 'Property'
&& node.value.property
&& node.value.property.name;
}

@@ -30,3 +32,3 @@

* @param {ASTNode} node the prop to check.
* @returns {Boolean} true if the prop is required.
* @returns {boolean} true if the prop is required.
*/

@@ -40,4 +42,4 @@ function isRequiredProp(node) {

*
* @param {String} propName the name of the proptype to check.
* @returns {Boolean} true if the proptype is a callback.
* @param {string} propName the name of the proptype to check.
* @returns {boolean} true if the proptype is a callback.
*/

@@ -52,7 +54,10 @@ function isCallbackPropName(propName) {

* @param {ASTNode} node the prop to check.
* @returns {Boolean} true if the prop is PropTypes.shape.
* @returns {boolean} true if the prop is PropTypes.shape.
*/
function isShapeProp(node) {
return Boolean(
node && node.callee && node.callee.property && node.callee.property.name === 'shape'
return !!(
node
&& node.callee
&& node.callee.property
&& node.callee.property.name === 'shape'
);

@@ -68,3 +73,5 @@ }

function getShapeProperties(node) {
return node.arguments && node.arguments[0] && node.arguments[0].properties;
return node.arguments
&& node.arguments[0]
&& node.arguments[0].properties;
}

@@ -78,7 +85,7 @@

* @param {Context} context The context of the two nodes.
* @param {Boolean=} ignoreCase whether or not to ignore case when comparing the two elements.
* @param {Boolean=} requiredFirst whether or not to sort required elements first.
* @param {Boolean=} callbacksLast whether or not to sort callbacks after everything else.
* @param {Boolean=} noSortAlphabetically whether or not to disable alphabetical sorting of the elements.
* @returns {Number} the sort order of the two elements.
* @param {boolean=} ignoreCase whether or not to ignore case when comparing the two elements.
* @param {boolean=} requiredFirst whether or not to sort required elements first.
* @param {boolean=} callbacksLast whether or not to sort callbacks after everything else.
* @param {boolean=} noSortAlphabetically whether or not to disable alphabetical sorting of the elements.
* @returns {number} the sort order of the two elements.
*/

@@ -130,8 +137,8 @@ function sorter(a, b, context, ignoreCase, requiredFirst, callbacksLast, noSortAlphabetically) {

* @param {Array} declarations The context of the two nodes.
* @param {Boolean=} ignoreCase whether or not to ignore case when comparing the two elements.
* @param {Boolean=} requiredFirst whether or not to sort required elements first.
* @param {Boolean=} callbacksLast whether or not to sort callbacks after everything else.
* @param {Boolean=} noSortAlphabetically whether or not to disable alphabetical sorting of the elements.
* @param {Boolean=} sortShapeProp whether or not to sort propTypes defined in PropTypes.shape.
* @param {Boolean=} checkTypes whether or not sorting of prop type definitions are checked.
* @param {boolean=} ignoreCase whether or not to ignore case when comparing the two elements.
* @param {boolean=} requiredFirst whether or not to sort required elements first.
* @param {boolean=} callbacksLast whether or not to sort callbacks after everything else.
* @param {boolean=} noSortAlphabetically whether or not to disable alphabetical sorting of the elements.
* @param {boolean=} sortShapeProp whether or not to sort propTypes defined in PropTypes.shape.
* @param {boolean=} checkTypes whether or not sorting of prop type definitions are checked.
* @returns {Object|*|{range, text}} the sort order of the two elements.

@@ -230,2 +237,5 @@ */

fixPropTypesSort,
isCallbackPropName,
isRequiredProp,
isShapeProp,
};

@@ -69,3 +69,3 @@ /**

* @param {string} name The AST node being checked.
* @returns {Boolean} True if the prop name matches
* @returns {boolean} True if the prop name matches
*/

@@ -79,3 +79,3 @@ function isCommonVariableNameForProps(name) {

* @param {Object} component The component to process
* @returns {Boolean} True if the component must be validated, false if not.
* @returns {boolean} True if the component must be validated, false if not.
*/

@@ -115,16 +115,23 @@ function mustBeValidated(component) {

* @param {boolean} checkAsyncSafeLifeCycles
* @return {Boolean} True if the node is a lifecycle method
* @return {boolean} True if the node is a lifecycle method
*/
function isNodeALifeCycleMethod(node, checkAsyncSafeLifeCycles) {
const nodeKeyName = (node.key || /** @type {ASTNode} */ ({})).name;
if (node.key) {
if (node.kind === 'constructor') {
return true;
}
if (node.kind === 'constructor') {
return true;
const nodeKeyName = node.key.name;
if (typeof nodeKeyName !== 'string') {
return false;
}
if (LIFE_CYCLE_METHODS.indexOf(nodeKeyName) >= 0) {
return true;
}
if (checkAsyncSafeLifeCycles && ASYNC_SAFE_LIFE_CYCLE_METHODS.indexOf(nodeKeyName) >= 0) {
return true;
}
}
if (LIFE_CYCLE_METHODS.indexOf(nodeKeyName) >= 0) {
return true;
}
if (checkAsyncSafeLifeCycles && ASYNC_SAFE_LIFE_CYCLE_METHODS.indexOf(nodeKeyName) >= 0) {
return true;
}

@@ -139,6 +146,9 @@ return false;

* @param {boolean} checkAsyncSafeLifeCycles
* @return {Boolean} True if the node is inside a lifecycle method
* @return {boolean} True if the node is inside a lifecycle method
*/
function isInLifeCycleMethod(node, checkAsyncSafeLifeCycles) {
if ((node.type === 'MethodDefinition' || node.type === 'Property') && isNodeALifeCycleMethod(node, checkAsyncSafeLifeCycles)) {
if (
(node.type === 'MethodDefinition' || node.type === 'Property')
&& isNodeALifeCycleMethod(node, checkAsyncSafeLifeCycles)
) {
return true;

@@ -160,3 +170,3 @@ }

function isSetStateUpdater(node) {
const unwrappedParentCalleeNode = node.parent && node.parent.type === 'CallExpression'
const unwrappedParentCalleeNode = astUtil.isCallExpression(node.parent)
&& ast.unwrapTSAsExpression(node.parent.callee);

@@ -178,4 +188,3 @@

const unwrappedParentCalleeNode = scope.block
&& scope.block.parent
&& scope.block.parent.type === 'CallExpression'
&& astUtil.isCallExpression(scope.block.parent)
&& ast.unwrapTSAsExpression(scope.block.parent.callee);

@@ -223,3 +232,3 @@ if (

* @param {ASTNode} node The AST node being marked.
* @returns {Boolean} True if the prop has spread operator, false if not.
* @returns {boolean} True if the prop has spread operator, false if not.
*/

@@ -226,0 +235,0 @@ function hasSpreadOperator(context, node) {

@@ -14,3 +14,3 @@ /**

* @param {string} name The name of the variable to search.
* @returns {Boolean} True if the variable was found, false if not.
* @returns {boolean} True if the variable was found, false if not.
*/

@@ -17,0 +17,0 @@ function findVariable(variables, name) {

{
"name": "eslint-plugin-react",
"version": "7.35.0",
"version": "7.35.1",
"author": "Yannick Croissant <yannick.croissant+npm@gmail.com>",

@@ -16,3 +16,3 @@ "description": "React specific linting rules for ESLint",

"test": "npm run unit-test",
"posttest": "aud --production",
"posttest": "npx npm@'>= 10.2' audit --production",
"type-check": "tsc",

@@ -49,4 +49,4 @@ "unit-test": "istanbul cover node_modules/mocha/bin/_mocha tests/lib/**/*.js tests/util/**/*.js tests/index.js tests/flat-config.js",

"devDependencies": {
"@babel/core": "^7.24.9",
"@babel/eslint-parser": "^7.24.8",
"@babel/core": "^7.25.2",
"@babel/eslint-parser": "^7.25.1",
"@babel/plugin-syntax-decorators": "^7.24.7",

@@ -60,3 +60,2 @@ "@babel/plugin-syntax-do-expressions": "^7.24.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",

@@ -63,0 +62,0 @@ "eslint": "^3 || ^4 || ^5 || ^6 || ^7 || ^8 || ^9.7",

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc