Skip to content

Commit a4bf6b9

Browse files
committed
Merge branch 'master' of https://github.com/y-hsgw/eslint-plugin-react into feature/add-jsdoc-annotations
2 parents b392497 + 51d342b commit a4bf6b9

File tree

105 files changed

+1221
-599
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

105 files changed

+1221
-599
lines changed

.eslintrc

Lines changed: 74 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -1,82 +1,82 @@
11
{
2-
"root": true,
3-
"extends": ["airbnb-base", "plugin:eslint-plugin/recommended"],
4-
"plugins": ["eslint-plugin"],
5-
"env": {
6-
"es6": true,
7-
"node": true
8-
},
9-
"parserOptions": {
10-
"ecmaVersion": 6,
11-
"ecmaFeatures": {
12-
"jsx": true
13-
},
14-
"sourceType": "script",
15-
},
16-
"ignorePatterns": [
17-
"coverage/",
18-
".nyc_output/",
19-
],
20-
"rules": {
21-
"comma-dangle": [2, "always-multiline"],
22-
"object-shorthand": [2, "always", {
23-
"ignoreConstructors": false,
24-
"avoidQuotes": false, // this is the override vs airbnb
25-
}],
26-
"max-len": [2, 120, {
27-
"ignoreStrings": true,
28-
"ignoreTemplateLiterals": true,
29-
"ignoreComments": true,
30-
}],
31-
"consistent-return": 0,
2+
"root": true,
3+
"extends": ["airbnb-base", "plugin:eslint-plugin/recommended"],
4+
"plugins": ["eslint-plugin"],
5+
"env": {
6+
"es6": true,
7+
"node": true
8+
},
9+
"parserOptions": {
10+
"ecmaVersion": 6,
11+
"ecmaFeatures": {
12+
"jsx": true
13+
},
14+
"sourceType": "script",
15+
},
16+
"ignorePatterns": [
17+
"coverage/",
18+
".nyc_output/",
19+
],
20+
"rules": {
21+
"comma-dangle": [2, "always-multiline"],
22+
"object-shorthand": [2, "always", {
23+
"ignoreConstructors": false,
24+
"avoidQuotes": false, // this is the override vs airbnb
25+
}],
26+
"max-len": [2, 140, {
27+
"ignoreStrings": true,
28+
"ignoreTemplateLiterals": true,
29+
"ignoreComments": true,
30+
}],
31+
"consistent-return": 0,
3232

33-
"prefer-destructuring": [2, { "array": false, "object": false }, { "enforceForRenamedProperties": false }],
34-
"prefer-object-spread": 0, // until node 8 is required
35-
"prefer-rest-params": 0, // until node 6 is required
36-
"prefer-spread": 0, // until node 6 is required
37-
"function-call-argument-newline": 1, // TODO: enable
38-
"function-paren-newline": 0,
39-
"no-plusplus": [2, {"allowForLoopAfterthoughts": true}],
40-
"no-param-reassign": 1,
41-
"no-restricted-syntax": [2, {
42-
"selector": "ObjectPattern",
43-
"message": "Object destructuring is not compatible with Node v4"
44-
}],
45-
"strict": [2, "safe"],
46-
"valid-jsdoc": [2, {
47-
"requireReturn": false,
48-
"requireParamDescription": false,
49-
"requireReturnDescription": false,
50-
}],
33+
"prefer-destructuring": [2, { "array": false, "object": false }, { "enforceForRenamedProperties": false }],
34+
"prefer-object-spread": 0, // until node 8 is required
35+
"prefer-rest-params": 0, // until node 6 is required
36+
"prefer-spread": 0, // until node 6 is required
37+
"function-call-argument-newline": 1, // TODO: enable
38+
"function-paren-newline": 0,
39+
"no-plusplus": [2, {"allowForLoopAfterthoughts": true}],
40+
"no-param-reassign": 1,
41+
"no-restricted-syntax": [2, {
42+
"selector": "ObjectPattern",
43+
"message": "Object destructuring is not compatible with Node v4"
44+
}],
45+
"strict": [2, "safe"],
46+
"valid-jsdoc": [2, {
47+
"requireReturn": false,
48+
"requireParamDescription": false,
49+
"requireReturnDescription": false,
50+
}],
5151

52-
"eslint-plugin/consistent-output": 0,
53-
"eslint-plugin/require-meta-docs-description": [2, { "pattern": "^(Enforce|Require|Disallow)" }],
54-
"eslint-plugin/require-meta-schema": 0,
55-
"eslint-plugin/require-meta-type": 0
52+
"eslint-plugin/consistent-output": 0,
53+
"eslint-plugin/require-meta-docs-description": [2, { "pattern": "^(Enforce|Require|Disallow)" }],
54+
"eslint-plugin/require-meta-schema": 0,
55+
"eslint-plugin/require-meta-type": 0
56+
},
57+
"overrides": [
58+
{
59+
"files": "tests/**",
60+
"rules": {
61+
"no-template-curly-in-string": 1,
62+
},
5663
},
57-
"overrides": [
58-
{
59-
"files": "tests/**",
60-
"rules": {
61-
"no-template-curly-in-string": 1,
62-
},
64+
{
65+
"files": "markdown.config.js",
66+
"rules": {
67+
"no-console": 0,
6368
},
64-
{
65-
"files": "markdown.config.js",
66-
"rules": {
67-
"no-console": 0,
68-
},
69+
},
70+
{
71+
"files": ".github/workflows/*.js",
72+
"parserOptions": {
73+
"ecmaVersion": 2019,
6974
},
70-
{
71-
"files": ".github/workflows/*.js",
72-
"parserOptions": {
73-
"ecmaVersion": 2019,
74-
},
75-
"rules": {
76-
"camelcase": 0,
77-
"no-console": 0,
78-
"no-restricted-syntax": 0,
79-
},
75+
"rules": {
76+
"camelcase": 0,
77+
"no-console": 0,
78+
"no-restricted-syntax": 0,
8079
},
81-
],
80+
},
81+
],
8282
}

CHANGELOG.md

Lines changed: 41 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,46 @@ This change log adheres to standards from [Keep a CHANGELOG](https://keepachange
55

66
## Unreleased
77

8+
### Fixed
9+
10+
* [`prop-types`]: fix `className` missing in prop validation false negative ([#3749] @akulsr0)
11+
12+
[#3749]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3749
13+
14+
## [7.34.3] - 2024.06.18
15+
16+
### Fixed
17+
* [`prop-types`]: null-check rootNode before calling getScope ([#3762][] @crnhrv)
18+
* [`boolean-prop-naming`]: avoid a crash with a spread prop ([#3733][] @ljharb)
19+
* [`jsx-boolean-value`]: `assumeUndefinedIsFalse` with `never` must not allow explicit `true` value ([#3757][] @6uliver)
20+
* [`no-object-type-as-default-prop`]: enable rule for components with many parameters ([#3768][] @JulienR1)
21+
* [`jsx-key`]: incorrect behavior for checkKeyMustBeforeSpread with map callbacks ([#3769][] @akulsr0)
22+
23+
[7.34.3]: https://github.com/jsx-eslint/eslint-plugin-react/compare/v7.34.2...v7.34.3
24+
[#3769]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3769
25+
[#3768]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3768
26+
[#3762]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3762
27+
[#3757]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3757
28+
[#3733]: https://github.com/jsx-eslint/eslint-plugin-react/issues/3733
29+
30+
## [7.34.2] - 2024.05.24
31+
32+
### Fixed
33+
* [`boolean-prop-naming`]: avoid a crash with a non-TSTypeReference type ([#3718][] @developer-bandi)
34+
* [`jsx-no-leaked-render`]: invalid report if left side is boolean ([#3746][] @akulsr0)
35+
* [`jsx-closing-bracket-location`]: message shows `{{details}}` when there are no details ([#3759][] @mdjermanovic)
36+
* [`no-invalid-html-attribute`]: ensure error messages are correct ([#3759][] @mdjermanovic, @ljharb)
37+
38+
### Changed
39+
* [Refactor] create various eslint utils to fix eslint deprecations ([#3759][] @mdjermanovic, @ljharb)
40+
41+
[7.34.2]: https://github.com/jsx-eslint/eslint-plugin-react/compare/v7.34.1...v7.34.2
42+
[#3759]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3759
43+
[#3746]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3746
44+
[#3718]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3718
45+
46+
## [7.34.1] - 2024.03.15
47+
848
### Fixed
949
* [`jsx-no-leaked-render`]: prevent wrongly adding parens ([#3700][] @developer-bandi)
1050
* [`boolean-prop-naming`]: detect TS interfaces ([#3701][] @developer-bandi)
@@ -13,12 +53,11 @@ This change log adheres to standards from [Keep a CHANGELOG](https://keepachange
1353
* [`no-unknown-property`]: support `popover`, `popovertarget`, `popovertargetaction` attributes ([#3707][] @ljharb)
1454
* [`no-unknown-property`]: only match `data-*` attributes containing `-` ([#3713][] @silverwind)
1555
* [`checked-requires-onchange-or-readonly`]: correct options that were behaving opposite ([#3715][] @jaesoekjjang)
16-
* [`boolean-prop-naming`]: avoid a crash with a non-TSTypeReference type ([#3718][] @developer-bandi)
1756

1857
### Changed
1958
* [`boolean-prop-naming`]: improve error message (@ljharb)
2059

21-
[#3718]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3718
60+
[7.34.1]: https://github.com/jsx-eslint/eslint-plugin-react/compare/v7.34.0...v7.34.1
2261
[#3715]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3715
2362
[#3713]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3713
2463
[#3707]: https://github.com/jsx-eslint/eslint-plugin-react/issues/3707

lib/rules/boolean-prop-naming.js

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,10 @@ const propsUtil = require('../util/props');
1313
const docsUrl = require('../util/docsUrl');
1414
const propWrapperUtil = require('../util/propWrapper');
1515
const report = require('../util/report');
16+
const eslintUtil = require('../util/eslint');
17+
18+
const getSourceCode = eslintUtil.getSourceCode;
19+
const getText = eslintUtil.getText;
1620

1721
// ------------------------------------------------------------------------------
1822
// Rule Definition
@@ -115,7 +119,7 @@ module.exports = {
115119
// we can't get the name of the Flow object key name. So we have
116120
// to hack around it for now.
117121
if (node.type === 'ObjectTypeProperty') {
118-
return context.getSourceCode().getFirstToken(node).value;
122+
return getSourceCode(context).getFirstToken(node).value;
119123
}
120124

121125
return node.key.name;
@@ -308,7 +312,7 @@ module.exports = {
308312
&& node.value.type === 'CallExpression'
309313
&& propWrapperUtil.isPropWrapperFunction(
310314
context,
311-
context.getSourceCode().getText(node.value.callee)
315+
getText(context, node.value.callee)
312316
)
313317
) {
314318
checkPropWrapperArguments(node, node.value.arguments);
@@ -334,7 +338,7 @@ module.exports = {
334338
right.type === 'CallExpression'
335339
&& propWrapperUtil.isPropWrapperFunction(
336340
context,
337-
context.getSourceCode().getText(right.callee)
341+
getText(context, right.callee)
338342
)
339343
) {
340344
checkPropWrapperArguments(component.node, right.arguments);
@@ -395,7 +399,7 @@ module.exports = {
395399
}
396400

397401
if (propType) {
398-
[].concat(propType).forEach((prop) => {
402+
[].concat(propType).filter(Boolean).forEach((prop) => {
399403
validatePropNaming(
400404
component.node,
401405
prop.properties || prop.members || prop.body

lib/rules/button-has-type.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -136,7 +136,7 @@ module.exports = {
136136
checkValue(node, propValue);
137137
},
138138
CallExpression(node) {
139-
if (!isCreateElement(node, context) || node.arguments.length < 1) {
139+
if (!isCreateElement(context, node) || node.arguments.length < 1) {
140140
return;
141141
}
142142

lib/rules/checked-requires-onchange-or-readonly.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,7 @@ module.exports = {
116116
checkAttributesAndReport(node, propSet);
117117
},
118118
CallExpression(node) {
119-
if (!isCreateElement(node, context)) {
119+
if (!isCreateElement(context, node)) {
120120
return;
121121
}
122122

lib/rules/destructuring-assignment.js

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,13 @@
66

77
const Components = require('../util/Components');
88
const docsUrl = require('../util/docsUrl');
9+
const eslintUtil = require('../util/eslint');
910
const isAssignmentLHS = require('../util/ast').isAssignmentLHS;
1011
const report = require('../util/report');
1112

13+
const getScope = eslintUtil.getScope;
14+
const getText = eslintUtil.getText;
15+
1216
const DEFAULT_OPTION = 'always';
1317

1418
function createSFCParams() {
@@ -102,7 +106,7 @@ module.exports = {
102106
function handleStatelessComponent(node) {
103107
const params = evalParams(node.params);
104108

105-
const SFCComponent = components.get(context.getScope(node).block);
109+
const SFCComponent = components.get(getScope(context, node).block);
106110
if (!SFCComponent) {
107111
return;
108112
}
@@ -120,7 +124,7 @@ module.exports = {
120124
}
121125

122126
function handleStatelessComponentExit(node) {
123-
const SFCComponent = components.get(context.getScope(node).block);
127+
const SFCComponent = components.get(getScope(context, node).block);
124128
if (SFCComponent) {
125129
sfcParams.pop();
126130
}
@@ -192,7 +196,7 @@ module.exports = {
192196
'FunctionExpression:exit': handleStatelessComponentExit,
193197

194198
MemberExpression(node) {
195-
let scope = context.getScope(node);
199+
let scope = getScope(context, node);
196200
let SFCComponent = components.get(scope.block);
197201
while (!SFCComponent && scope.upper && scope.upper !== scope) {
198202
SFCComponent = components.get(scope.upper.block);
@@ -210,7 +214,7 @@ module.exports = {
210214

211215
VariableDeclarator(node) {
212216
const classComponent = utils.getParentComponent(node);
213-
const SFCComponent = components.get(context.getScope(node).block);
217+
const SFCComponent = components.get(getScope(context, node).block);
214218

215219
const destructuring = (node.init && node.id && node.id.type === 'ObjectPattern');
216220
// let {foo} = props;
@@ -248,7 +252,7 @@ module.exports = {
248252
&& destructureInSignature === 'always'
249253
&& node.init.name === 'props'
250254
) {
251-
const scopeSetProps = context.getScope().set.get('props');
255+
const scopeSetProps = getScope(context, node).set.get('props');
252256
const propsRefs = scopeSetProps && scopeSetProps.references;
253257
if (!propsRefs) {
254258
return;
@@ -269,7 +273,7 @@ module.exports = {
269273
param.typeAnnotation ? param.typeAnnotation.range[0] : param.range[1],
270274
];
271275
return [
272-
fixer.replaceTextRange(replaceRange, context.getSourceCode().getText(node.id)),
276+
fixer.replaceTextRange(replaceRange, getText(context, node.id)),
273277
fixer.remove(node.parent),
274278
];
275279
},

lib/rules/forbid-elements.js

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,9 @@
55

66
'use strict';
77

8-
const has = require('object.hasown/polyfill')();
8+
const has = require('hasown');
99
const docsUrl = require('../util/docsUrl');
10+
const getText = require('../util/eslint').getText;
1011
const isCreateElement = require('../util/isCreateElement');
1112
const report = require('../util/report');
1213

@@ -60,6 +61,7 @@ module.exports = {
6061
const configuration = context.options[0] || {};
6162
const forbidConfiguration = configuration.forbid || [];
6263

64+
/** @type {Record<string, { element: string, message?: string }>} */
6365
const indexedForbidConfigs = {};
6466

6567
forbidConfiguration.forEach((item) => {
@@ -91,11 +93,11 @@ module.exports = {
9193

9294
return {
9395
JSXOpeningElement(node) {
94-
reportIfForbidden(context.getSourceCode().getText(node.name), node.name);
96+
reportIfForbidden(getText(context, node.name), node.name);
9597
},
9698

9799
CallExpression(node) {
98-
if (!isCreateElement(node, context)) {
100+
if (!isCreateElement(context, node)) {
99101
return;
100102
}
101103

@@ -109,7 +111,7 @@ module.exports = {
109111
} else if (argument.type === 'Literal' && /^[a-z][^.]*$/.test(String(argument.value))) {
110112
reportIfForbidden(argument.value, argument);
111113
} else if (argument.type === 'MemberExpression') {
112-
reportIfForbidden(context.getSourceCode().getText(argument), argument);
114+
reportIfForbidden(getText(context, argument), argument);
113115
}
114116
},
115117
};

0 commit comments

Comments
 (0)