Skip to content

Commit 08a5366

Browse files
authored
Merge branch 'master' into ignore-non-proptypes-objects
2 parents 2433116 + 9139830 commit 08a5366

File tree

6 files changed

+108
-6
lines changed

6 files changed

+108
-6
lines changed

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,12 +15,16 @@ This change log adheres to standards from [Keep a CHANGELOG](https://keepachange
1515
* [`jsx-key`]: avoid a crash from optional chaining from [#3320][] ([#3327][] @ljharb)
1616
* [`jsx-key`]: avoid a crash on a non-array node.body from [#3320][] ([#3328][] @ljharb)
1717
* [`display-name`]: fix false positive for assignment of function returning null ([#3331][] @apbarrero)
18+
* [`display-name`]: fix identifying `_` as a capital letter ([#3335][] @apbarrero)
1819

1920
### Changed
2021
* [Refactor] [`jsx-indent-props`]: improved readability of the checkNodesIndent function ([#3315][] @caroline223)
2122
* [Tests] [`jsx-indent`], [`jsx-one-expression-per-line`]: add passing test cases ([#3314][] @ROSSROSALES)
2223
* [Refactor] `boolean-prop-naming`, `jsx-indent`: avoid assigning to arguments ([#3316][] @caroline223)
24+
* [Docs] `sort-comp`: add class component examples ([#3339][] @maurer2)
2325

26+
[#3339]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3339
27+
[#3335]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3335
2428
[#3331]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3331
2529
[#3328]: https://github.com/jsx-eslint/eslint-plugin-react/issues/3328
2630
[#3327]: https://github.com/jsx-eslint/eslint-plugin-react/issues/3327

docs/rules/sort-comp.md

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,15 @@ var Hello = createReactClass({
2424
});
2525
```
2626

27+
```jsx
28+
class Hello extends React.Component {
29+
render() {
30+
return <div>Hello</div>;
31+
}
32+
static displayName = 'Hello';
33+
}
34+
```
35+
2736
Examples of **correct** code for this rule:
2837

2938
```jsx
@@ -35,6 +44,15 @@ var Hello = createReactClass({
3544
});
3645
```
3746

47+
```jsx
48+
class Hello extends React.Component {
49+
static displayName = 'Hello';
50+
render() {
51+
return <div>Hello</div>;
52+
}
53+
}
54+
```
55+
3856
## Rule Options
3957

4058
This rule can take one argument to customize the components organisation.
@@ -128,6 +146,16 @@ var Hello = createReactClass({
128146
});
129147
```
130148

149+
```jsx
150+
class Hello extends React.Component {
151+
render() {
152+
return <div>Hello</div>;
153+
}
154+
onClick = this.onClick.bind(this);
155+
onClick() {}
156+
}
157+
```
158+
131159
Examples of **correct** code for this rule, with the above configuration:
132160

133161
```jsx
@@ -139,6 +167,16 @@ var Hello = createReactClass({
139167
});
140168
```
141169

170+
```jsx
171+
class Hello extends React.Component {
172+
onClick = this.onClick.bind(this);
173+
onClick() {}
174+
render() {
175+
return <div>Hello</div>;
176+
}
177+
}
178+
```
179+
142180
If you want to split your `render` method into smaller ones and keep them just before render:
143181

144182
```js
@@ -170,6 +208,17 @@ var Hello = createReactClass({
170208
});
171209
```
172210

211+
```jsx
212+
class Hello extends React.Component {
213+
renderButton = () => {}
214+
onClick = this.onClick.bind(this);
215+
onClick() {}
216+
render() {
217+
return <div>Hello</div>;
218+
}
219+
}
220+
```
221+
173222
Examples of **correct** code for this rule, with the above configuration:
174223

175224
```jsx
@@ -182,6 +231,17 @@ var Hello = createReactClass({
182231
});
183232
```
184233

234+
```jsx
235+
class Hello extends React.Component {
236+
onClick = this.onClick.bind(this);
237+
onClick() {}
238+
renderButton = () => {}
239+
render() {
240+
return <div>Hello</div>;
241+
}
242+
}
243+
```
244+
185245
If you want to flow annotations to be at the top:
186246

187247
```js

lib/util/isFirstLetterCapitalized.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
* @returns {Boolean} True if first letter is capitalized.
77
*/
88
function isFirstLetterCapitalized(word) {
9-
if (!word) {
9+
if (!word || word.charAt(0) === '_') {
1010
return false;
1111
}
1212
const firstLetter = word.charAt(0);

tests/helpers/parsers.js

Lines changed: 23 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
const path = require('path');
44
const semver = require('semver');
5+
const entries = require('object.entries');
56
const version = require('eslint/package.json').version;
67
const flatMap = require('array.prototype.flatmap');
78
const tsParserVersion = require('@typescript-eslint/parser/package.json').version;
@@ -10,6 +11,25 @@ const disableNewTS = semver.satisfies(tsParserVersion, '>= 4.1') // this rule is
1011
? (x) => Object.assign({}, x, { features: [].concat(x.features, 'no-ts-new') })
1112
: (x) => x;
1213

14+
function minEcmaVersion(features, parserOptions) {
15+
const minEcmaVersionForFeatures = {
16+
'class fields': 2022,
17+
'optional chaining': 2020,
18+
};
19+
const result = Math.max.apply(
20+
Math,
21+
[].concat(
22+
(parserOptions && parserOptions.ecmaVersion) || [],
23+
flatMap(entries(minEcmaVersionForFeatures), (entry) => {
24+
const f = entry[0];
25+
const y = entry[1];
26+
return features.has(f) ? y : [];
27+
})
28+
).map((y) => (y > 5 && y < 2015 ? y + 2009 : y)) // normalize editions to years
29+
);
30+
return Number.isFinite(result) ? result : undefined;
31+
}
32+
1333
const NODE_MODULES = '../../node_modules';
1434

1535
const parsers = {
@@ -58,7 +78,7 @@ const parsers = {
5878
const features = new Set([].concat(test.features || []));
5979
delete test.features;
6080

61-
const es = features.has('class fields') ? 2022 : (features.has('optional chaining') ? 2020 : (test.parserOptions && test.parserOptions.ecmaVersion) || undefined); // eslint-disable-line no-nested-ternary
81+
const es = minEcmaVersion(features, test.parserOptions);
6282

6383
function addComment(testObject, parser) {
6484
const extras = [].concat(
@@ -133,10 +153,8 @@ const parsers = {
133153

134154
return [].concat(
135155
skipBase ? [] : addComment(
136-
Object.assign({}, test, typeof es !== 'undefined' && {
137-
parserOptions: Object.assign({}, test.parserOptions, {
138-
ecmaVersion: Math.max((test.parserOptions && test.parserOptions.ecmaVersion) || 0, es),
139-
}),
156+
Object.assign({}, test, typeof es === 'number' && {
157+
parserOptions: Object.assign({}, test.parserOptions, { ecmaVersion: es }),
140158
}),
141159
'default'
142160
),

tests/lib/rules/display-name.js

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -597,6 +597,24 @@ ruleTester.run('display-name', rule, {
597597
return f(a);
598598
};`,
599599
},
600+
{
601+
// issue #3334
602+
code: `
603+
obj._property = (a) => {
604+
if (a == null) return null;
605+
return f(a);
606+
};
607+
`,
608+
},
609+
{
610+
// issue #3334
611+
code: `
612+
_variable = (a) => {
613+
if (a == null) return null;
614+
return f(a);
615+
};
616+
`,
617+
},
600618
{
601619
// issue #3303
602620
code: `

tests/util/isFirstLetterCapitalized.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@ describe('isFirstLetterCapitalized', () => {
1414
it('should return false for uncapitalized string', () => {
1515
assert.equal(isFirstLetterCapitalized('isCapitalized'), false);
1616
assert.equal(isFirstLetterCapitalized('lowercase'), false);
17+
assert.equal(isFirstLetterCapitalized('_startsWithUnderscore'), false);
18+
assert.equal(isFirstLetterCapitalized('_StartsWithUnderscore'), false);
1719
});
1820

1921
it('should return true for capitalized string', () => {

0 commit comments

Comments
 (0)