Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[pull] master from jsx-eslint:master #30

Merged
merged 4 commits into from
Jul 24, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 1 addition & 2 deletions lib/rules/jsx-no-literals.js
Original file line number Diff line number Diff line change
Expand Up @@ -74,8 +74,7 @@ module.exports = {
const config = Object.assign({}, defaults, context.options[0] || {});
config.allowedStrings = new Set(map(iterFrom(config.allowedStrings), trimIfString));

function defaultMessageId() {
const ancestorIsJSXElement = arguments.length >= 1 && arguments[0];
function defaultMessageId(ancestorIsJSXElement) {
if (config.noAttributeStrings && !ancestorIsJSXElement) {
return 'noStringsInAttributes';
}
Expand Down
13 changes: 5 additions & 8 deletions lib/rules/jsx-sort-props.js
Original file line number Diff line number Diff line change
Expand Up @@ -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 propTypesSortUtil = require('../util/propTypesSort');
const eslintUtil = require('../util/eslint');

const getText = eslintUtil.getText;
Expand All @@ -21,10 +22,6 @@ const getSourceCode = eslintUtil.getSourceCode;
// Rule Definition
// ------------------------------------------------------------------------------

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

function isMultilineProp(node) {
return node.loc.start.line !== node.loc.end.line;
}
Expand Down Expand Up @@ -85,8 +82,8 @@ function contextCompare(a, b, options) {
}

if (options.callbacksLast) {
const aIsCallback = isCallbackPropName(aProp);
const bIsCallback = isCallbackPropName(bProp);
const aIsCallback = propTypesSortUtil.isCallbackPropName(aProp);
const bIsCallback = propTypesSortUtil.isCallbackPropName(bProp);
if (aIsCallback && !bIsCallback) {
return 1;
}
Expand Down Expand Up @@ -425,8 +422,8 @@ module.exports = {
let currentPropName = propName(decl);
const previousValue = memo.value;
const currentValue = decl.value;
const previousIsCallback = isCallbackPropName(previousPropName);
const currentIsCallback = isCallbackPropName(currentPropName);
const previousIsCallback = propTypesSortUtil.isCallbackPropName(previousPropName);
const currentIsCallback = propTypesSortUtil.isCallbackPropName(currentPropName);

if (ignoreCase) {
previousPropName = previousPropName.toLowerCase();
Expand Down
2 changes: 1 addition & 1 deletion lib/rules/no-direct-mutation-state.js
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ module.exports = {
* @returns {Boolean} True if the component is valid, false if not.
*/
function isValid(component) {
return Boolean(component && !component.mutateSetState);
return !!component && !component.mutateSetState;
}

/**
Expand Down
26 changes: 12 additions & 14 deletions lib/rules/no-invalid-html-attribute.js
Original file line number Diff line number Diff line change
Expand Up @@ -289,7 +289,7 @@ function checkLiteralValueNode(context, attributeName, node, parentNode, parentN
}

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

Expand Down Expand Up @@ -329,15 +329,13 @@ function checkLiteralValueNode(context, attributeName, node, parentNode, parentN
suggest,
});
}
}
});

const allowedPairsForAttribute = VALID_PAIR_VALUES.get(attributeName);
if (allowedPairsForAttribute) {
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');
const firstValue = attributes[0];
const secondValue = attributes[1];
Expand All @@ -357,12 +355,12 @@ function checkLiteralValueNode(context, attributeName, node, parentNode, parentN
});
}
}
}
}
});
});
}

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

if (whitespacePart.range[0] === (node.range[0] + 1) || whitespacePart.range[1] === (node.range[1] - 1)) {
Expand All @@ -386,7 +384,7 @@ function checkLiteralValueNode(context, attributeName, node, parentNode, parentN
}],
});
}
}
});
}

const DEFAULT_ATTRIBUTES = ['rel'];
Expand Down Expand Up @@ -579,9 +577,9 @@ function checkCreateProps(context, node, attribute) {
}

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

// eslint-disable-next-line no-continue
continue;
Expand Down Expand Up @@ -646,9 +644,9 @@ module.exports = {

const attributes = new Set(context.options[0] || DEFAULT_ATTRIBUTES);

for (const attribute of attributes) {
attributes.forEach((attribute) => {
checkCreateProps(context, node, attribute);
}
});
},
};
},
Expand Down
2 changes: 1 addition & 1 deletion lib/rules/no-set-state.js
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ module.exports = {
* @returns {Boolean} True if the component is valid, false if not.
*/
function isValid(component) {
return Boolean(component && !component.useSetState);
return !!component && !component.useSetState;
}

/**
Expand Down
5 changes: 1 addition & 4 deletions lib/rules/no-unused-prop-types.js
Original file line number Diff line number Diff line change
Expand Up @@ -77,10 +77,7 @@ module.exports = {
* @returns {Boolean} True if the component must be validated, false if not.
*/
function mustBeValidated(component) {
return Boolean(
component
&& !component.ignoreUnusedPropTypesValidation
);
return !!component && !component.ignoreUnusedPropTypesValidation;
}

/**
Expand Down
12 changes: 6 additions & 6 deletions lib/rules/no-unused-state.js
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,7 @@ module.exports = {
// Records used state fields and new aliases for an ObjectPattern which
// destructures `this.state`.
function handleStateDestructuring(node) {
for (const prop of node.properties) {
node.properties.forEach((prop) => {
if (prop.type === 'Property') {
addUsedStateField(prop.key);
} else if (
Expand All @@ -183,7 +183,7 @@ module.exports = {
) {
classInfo.aliases.add(getName(prop.argument));
}
}
});
}

// Used to record used state fields and new aliases for both
Expand All @@ -201,7 +201,7 @@ module.exports = {
if (isStateReference(unwrappedRight)) {
handleStateDestructuring(left);
} else if (isThisExpression(unwrappedRight) && classInfo.aliases) {
for (const prop of left.properties) {
left.properties.forEach((prop) => {
if (prop.type === 'Property' && getName(prop.key) === 'state') {
const name = getName(prop.value);
if (name) {
Expand All @@ -210,7 +210,7 @@ module.exports = {
handleStateDestructuring(prop.value);
}
}
}
});
}
break;
default:
Expand All @@ -220,7 +220,7 @@ module.exports = {

function reportUnusedFields() {
// Report all unused state fields.
for (const node of classInfo.stateFields) {
classInfo.stateFields.forEach((node) => {
const name = getName(node.key);
if (!classInfo.usedStateFields.has(name)) {
report(context, messages.unusedStateField, 'unusedStateField', {
Expand All @@ -230,7 +230,7 @@ module.exports = {
},
});
}
}
});
}

function handleES6ComponentEnter(node) {
Expand Down
9 changes: 3 additions & 6 deletions lib/rules/require-optimization.js
Original file line number Diff line number Diff line change
Expand Up @@ -104,10 +104,7 @@ module.exports = {
* @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';
}

/**
Expand All @@ -126,8 +123,8 @@ module.exports = {
}
}

return Boolean(
node
return (
!!node
&& node.key.name === 'mixins'
&& hasPR
);
Expand Down
36 changes: 7 additions & 29 deletions lib/rules/sort-prop-types.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,28 +35,6 @@ function getKey(context, node) {
return getText(context, node.key || node.argument);
}

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} */
module.exports = {
meta: {
Expand Down Expand Up @@ -145,14 +123,14 @@ module.exports = {

let prevPropName = getKey(context, prev);
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();
}

if (requiredFirst) {
Expand Down Expand Up @@ -260,7 +238,7 @@ module.exports = {

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

Expand Down
2 changes: 1 addition & 1 deletion lib/util/propTypes.js
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,7 @@ module.exports = function propTypesInstructions(context, components, utils) {
ObjectTypeAnnotation(annotation, parentName, seen) {
let containsUnresolvedObjectTypeSpread = false;
let containsSpread = false;
const containsIndexers = Boolean(annotation.indexers && annotation.indexers.length);
const containsIndexers = !!annotation.indexers && annotation.indexers.length > 0;
const shapeTypeDefinition = {
type: 'shape',
children: {},
Expand Down
10 changes: 8 additions & 2 deletions lib/util/propTypesSort.js
Original file line number Diff line number Diff line change
Expand Up @@ -49,8 +49,11 @@ function isCallbackPropName(propName) {
* @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'
);
}

Expand Down Expand Up @@ -220,4 +223,7 @@ function fixPropTypesSort(

module.exports = {
fixPropTypesSort,
isCallbackPropName,
isRequiredProp,
isShapeProp,
};
6 changes: 3 additions & 3 deletions tests/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ describe('all rule files should be exported by the plugin', () => {
describe('deprecated rules', () => {
it('marks all deprecated rules as deprecated', () => {
ruleFiles.forEach((ruleName) => {
const inDeprecatedRules = Boolean(plugin.deprecatedRules[ruleName]);
const inDeprecatedRules = !!plugin.deprecatedRules[ruleName];
const isDeprecated = plugin.rules[ruleName].meta.deprecated;
if (inDeprecatedRules) {
assert(isDeprecated, `${ruleName} metadata should mark it as deprecated`);
Expand Down Expand Up @@ -77,7 +77,7 @@ describe('configurations', () => {
});

ruleFiles.forEach((ruleName) => {
const inDeprecatedRules = Boolean(plugin.deprecatedRules[ruleName]);
const inDeprecatedRules = !!plugin.deprecatedRules[ruleName];
const inConfig = typeof plugin.configs[configName].rules[`react/${ruleName}`] !== 'undefined';
assert(inDeprecatedRules ^ inConfig); // eslint-disable-line no-bitwise
});
Expand All @@ -91,7 +91,7 @@ describe('configurations', () => {
assert.ok(ruleName.startsWith('react/'));
assert.equal(plugin.configs[configName].rules[ruleName], 0);

const inDeprecatedRules = Boolean(plugin.deprecatedRules[ruleName]);
const inDeprecatedRules = !!plugin.deprecatedRules[ruleName];
const inConfig = typeof plugin.configs[configName].rules[ruleName] !== 'undefined';
assert(inDeprecatedRules ^ inConfig); // eslint-disable-line no-bitwise
});
Expand Down
Loading