Skip to content

Commit 6d3cfec

Browse files
authored
Merge branch 'master' into akul/no-render-return-undefined
2 parents 8aec646 + 014ee05 commit 6d3cfec

File tree

92 files changed

+940
-503
lines changed

Some content is hidden

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

92 files changed

+940
-503
lines changed

.eslintrc

+79-79
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, 120, {
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
56-
},
57-
"overrides": [
58-
{
59-
"files": "tests/**",
60-
"rules": {
61-
"no-template-curly-in-string": 1,
62-
},
63-
},
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,
74-
},
75-
"rules": {
76-
"camelcase": 0,
77-
"no-console": 0,
78-
"no-restricted-syntax": 0,
79-
},
80-
},
81-
],
82-
}
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+
},
63+
},
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,
74+
},
75+
"rules": {
76+
"camelcase": 0,
77+
"no-console": 0,
78+
"no-restricted-syntax": 0,
79+
},
80+
},
81+
],
82+
}

CHANGELOG.md

+5
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,12 @@ This change log adheres to standards from [Keep a CHANGELOG](https://keepachange
77

88
### Fixed
99
* [`boolean-prop-naming`]: avoid a crash with a non-TSTypeReference type ([#3718][] @developer-bandi)
10+
* [`jsx-no-leaked-render`]: invalid report if left side is boolean ([#3746][] @akulsr0)
11+
* [`jsx-closing-bracket-location`]: message shows `{{details}}` when there are no details ([#3759][] @mdjermanovic)
12+
* [`no-invalid-html-attribute`]: ensure error messages are correct ([#3759][] @mdjermanovic, @ljharb)
1013

14+
[#3759]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3759
15+
[#3746]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3746
1116
[#3718]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3718
1217

1318
## [7.34.1] - 2024.03.15

lib/rules/boolean-prop-naming.js

+7-3
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);

lib/rules/button-has-type.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -135,7 +135,7 @@ module.exports = {
135135
checkValue(node, propValue);
136136
},
137137
CallExpression(node) {
138-
if (!isCreateElement(node, context) || node.arguments.length < 1) {
138+
if (!isCreateElement(context, node) || node.arguments.length < 1) {
139139
return;
140140
}
141141

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

+1-1
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,7 @@ module.exports = {
115115
checkAttributesAndReport(node, propSet);
116116
},
117117
CallExpression(node) {
118-
if (!isCreateElement(node, context)) {
118+
if (!isCreateElement(context, node)) {
119119
return;
120120
}
121121

lib/rules/destructuring-assignment.js

+10-6
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

+4-3
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77

88
const has = require('object.hasown/polyfill')();
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

@@ -90,11 +91,11 @@ module.exports = {
9091

9192
return {
9293
JSXOpeningElement(node) {
93-
reportIfForbidden(context.getSourceCode().getText(node.name), node.name);
94+
reportIfForbidden(getText(context, node.name), node.name);
9495
},
9596

9697
CallExpression(node) {
97-
if (!isCreateElement(node, context)) {
98+
if (!isCreateElement(context, node)) {
9899
return;
99100
}
100101

@@ -110,7 +111,7 @@ module.exports = {
110111
} else if (argType === 'Literal' && /^[a-z][^.]*$/.test(argument.value)) {
111112
reportIfForbidden(argument.value, argument);
112113
} else if (argType === 'MemberExpression') {
113-
reportIfForbidden(context.getSourceCode().getText(argument), argument);
114+
reportIfForbidden(getText(context, argument), argument);
114115
}
115116
},
116117
};

lib/rules/forbid-prop-types.js

+3-2
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ const astUtil = require('../util/ast');
1010
const docsUrl = require('../util/docsUrl');
1111
const propWrapperUtil = require('../util/propWrapper');
1212
const report = require('../util/report');
13+
const getText = require('../util/eslint').getText;
1314

1415
// ------------------------------------------------------------------------------
1516
// Constants
@@ -162,7 +163,7 @@ module.exports = {
162163
checkProperties(node.properties);
163164
break;
164165
case 'Identifier': {
165-
const propTypesObject = variableUtil.findVariableByName(context, node.name);
166+
const propTypesObject = variableUtil.findVariableByName(context, node, node.name);
166167
if (propTypesObject && propTypesObject.properties) {
167168
checkProperties(propTypesObject.properties);
168169
}
@@ -171,7 +172,7 @@ module.exports = {
171172
case 'CallExpression': {
172173
const innerNode = node.arguments && node.arguments[0];
173174
if (
174-
propWrapperUtil.isPropWrapperFunction(context, context.getSourceCode().getText(node.callee))
175+
propWrapperUtil.isPropWrapperFunction(context, getText(context, node.callee))
175176
&& innerNode
176177
) {
177178
checkNode(innerNode);

lib/rules/function-component-definition.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ const arrayIncludes = require('array-includes');
99
const Components = require('../util/Components');
1010
const docsUrl = require('../util/docsUrl');
1111
const reportC = require('../util/report');
12+
const getText = require('../util/eslint').getText;
1213

1314
// ------------------------------------------------------------------------------
1415
// Rule Definition
@@ -181,8 +182,7 @@ module.exports = {
181182
);
182183

183184
function getFixer(node, options) {
184-
const sourceCode = context.getSourceCode();
185-
const source = sourceCode.getText();
185+
const source = getText(context);
186186

187187
const typeAnnotation = getTypeAnnotation(node, source);
188188

lib/rules/hook-use-state.js

+4-3
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ const Components = require('../util/Components');
99
const docsUrl = require('../util/docsUrl');
1010
const report = require('../util/report');
1111
const getMessageData = require('../util/message');
12+
const getText = require('../util/eslint').getText;
1213

1314
// ------------------------------------------------------------------------------
1415
// Rule Definition
@@ -160,14 +161,14 @@ module.exports = {
160161
fix: (fixer) => [
161162
// Add useMemo import, if necessary
162163
useStateReactImportSpecifier
163-
&& (!useMemoReactImportSpecifier || defaultReactImportName)
164-
&& fixer.insertTextAfter(useStateReactImportSpecifier, ', useMemo'),
164+
&& (!useMemoReactImportSpecifier || defaultReactImportName)
165+
&& fixer.insertTextAfter(useStateReactImportSpecifier, ', useMemo'),
165166
// Convert single-value destructure to simple assignment
166167
fixer.replaceTextRange(node.parent.id.range, valueVariableName),
167168
// Convert useState call to useMemo + arrow function + dependency array
168169
fixer.replaceTextRange(
169170
node.range,
170-
`${useMemoCode}(() => ${context.getSourceCode().getText(node.arguments[0])}, [])`
171+
`${useMemoCode}(() => ${getText(context, node.arguments[0])}, [])`
171172
),
172173
].filter(Boolean),
173174
}

0 commit comments

Comments
 (0)