Skip to content

Commit 781bfff

Browse files
vedadeeptaljharb
authored andcommitted
[new] sort-comp: add static-variables grouping
Fixes #2405
1 parent 7ccff10 commit 781bfff

File tree

3 files changed

+197
-3
lines changed

3 files changed

+197
-3
lines changed

docs/rules/sort-comp.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ The default configuration is:
9090
}
9191
}
9292
```
93-
93+
* `static-variables` This group is not specified by default, but can be used to enforce class static variable positioning.
9494
* `static-methods` is a special keyword that refers to static class methods.
9595
* `lifecycle` refers to the `lifecycle` group defined in `groups`.
9696
* `everything-else` is a special group that matches all of the methods that do not match any of the other groups.

lib/rules/sort-comp.js

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -148,8 +148,12 @@ module.exports = {
148148
if (method.typeAnnotation) {
149149
methodGroupIndexes.push(groupIndex);
150150
}
151+
} else if (currentGroup === 'static-variables') {
152+
if (method.staticVariable) {
153+
methodGroupIndexes.push(groupIndex);
154+
}
151155
} else if (currentGroup === 'static-methods') {
152-
if (method.static) {
156+
if (method.staticMethod) {
153157
methodGroupIndexes.push(groupIndex);
154158
}
155159
} else if (currentGroup === 'instance-variables') {
@@ -380,7 +384,13 @@ module.exports = {
380384
name: getPropertyName(node),
381385
getter: node.kind === 'get',
382386
setter: node.kind === 'set',
383-
static: node.static,
387+
staticVariable: node.static &&
388+
node.type === 'ClassProperty' &&
389+
(!node.value || !astUtil.isFunctionLikeExpression(node.value)),
390+
staticMethod: node.static &&
391+
(node.type === 'ClassProperty' || node.type === 'MethodDefinition') &&
392+
node.value &&
393+
(astUtil.isFunctionLikeExpression(node.value)),
384394
instanceVariable: !node.static &&
385395
node.type === 'ClassProperty' &&
386396
(!node.value || !astUtil.isFunctionLikeExpression(node.value)),

tests/lib/rules/sort-comp.js

Lines changed: 184 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -506,6 +506,129 @@ ruleTester.run('sort-comp', rule, {
506506
'everything-else'
507507
]
508508
}]
509+
}, {
510+
code: `
511+
class MyComponent extends React.Component {
512+
static foo;
513+
static getDerivedStateFromProps() {}
514+
515+
render() {
516+
return null;
517+
}
518+
}
519+
`,
520+
parser: parsers.BABEL_ESLINT,
521+
options: [{
522+
order: [
523+
'static-variables',
524+
'static-methods'
525+
]
526+
}]
527+
}, {
528+
code: `
529+
class MyComponent extends React.Component {
530+
static getDerivedStateFromProps() {}
531+
static foo = 'some-str';
532+
533+
render() {
534+
return null;
535+
}
536+
}
537+
`,
538+
parser: parsers.BABEL_ESLINT,
539+
options: [{
540+
order: [
541+
'static-methods',
542+
'static-variables'
543+
]
544+
}]
545+
}, {
546+
code: `
547+
class MyComponent extends React.Component {
548+
foo = {};
549+
static bar = 0;
550+
static getDerivedStateFromProps() {}
551+
552+
render() {
553+
return null;
554+
}
555+
}
556+
`,
557+
parser: parsers.BABEL_ESLINT,
558+
options: [{
559+
order: [
560+
'instance-variables',
561+
'static-variables',
562+
'static-methods'
563+
]
564+
}]
565+
}, {
566+
code: `
567+
class MyComponent extends React.Component {
568+
static bar = 1;
569+
foo = {};
570+
static getDerivedStateFromProps() {}
571+
572+
render() {
573+
return null;
574+
}
575+
}
576+
`,
577+
parser: parsers.BABEL_ESLINT,
578+
options: [{
579+
order: [
580+
'static-variables',
581+
'instance-variables',
582+
'static-methods'
583+
]
584+
}]
585+
}, {
586+
code: `
587+
class MyComponent extends React.Component {
588+
static getDerivedStateFromProps() {}
589+
render() {
590+
return null;
591+
}
592+
static bar;
593+
foo = {};
594+
}
595+
`,
596+
parser: parsers.BABEL_ESLINT,
597+
options: [{
598+
order: [
599+
'static-methods',
600+
'render',
601+
'static-variables',
602+
'instance-variables'
603+
]
604+
}]
605+
}, {
606+
code: `
607+
class MyComponent extends React.Component {
608+
static foo = 1;
609+
bar;
610+
611+
constructor() {
612+
super(props);
613+
614+
this.state = {};
615+
}
616+
617+
render() {
618+
return null;
619+
}
620+
}
621+
`,
622+
parser: parsers.BABEL_ESLINT,
623+
options: [{
624+
order: [
625+
'static-variables',
626+
'instance-variables',
627+
'constructor',
628+
'everything-else',
629+
'render'
630+
]
631+
}]
509632
}],
510633

511634
invalid: [{
@@ -790,5 +913,66 @@ ruleTester.run('sort-comp', rule, {
790913
'render'
791914
]
792915
}]
916+
}, {
917+
code: `
918+
class MyComponent extends React.Component {
919+
static getDerivedStateFromProps() {}
920+
static foo;
921+
922+
render() {
923+
return null;
924+
}
925+
}
926+
`,
927+
errors: [{message: 'getDerivedStateFromProps should be placed after foo'}],
928+
parser: parsers.BABEL_ESLINT,
929+
options: [{
930+
order: [
931+
'static-variables',
932+
'static-methods'
933+
]
934+
}]
935+
}, {
936+
code: `
937+
class MyComponent extends React.Component {
938+
static foo;
939+
bar = 'some-str'
940+
static getDerivedStateFromProps() {}
941+
942+
render() {
943+
return null;
944+
}
945+
}
946+
`,
947+
errors: [{message: 'foo should be placed after bar'}],
948+
parser: parsers.BABEL_ESLINT,
949+
options: [{
950+
order: [
951+
'instance-variables',
952+
'static-variables',
953+
'static-methods'
954+
]
955+
}]
956+
}, {
957+
code: `
958+
class MyComponent extends React.Component {
959+
static getDerivedStateFromProps() {}
960+
static bar;
961+
render() {
962+
return null;
963+
}
964+
foo = {};
965+
}
966+
`,
967+
parser: parsers.BABEL_ESLINT,
968+
errors: [{message: 'bar should be placed after render'}],
969+
options: [{
970+
order: [
971+
'static-methods',
972+
'render',
973+
'static-variables',
974+
'instance-variables'
975+
]
976+
}]
793977
}]
794978
});

0 commit comments

Comments
 (0)