Skip to content

Commit

Permalink
Merge pull request #1470 from RDGthree/master
Browse files Browse the repository at this point in the history
Add instance-methods and instance-variables to sort-comp.
  • Loading branch information
ljharb committed Nov 27, 2017
2 parents e632628 + 7efe31a commit c7dd755
Show file tree
Hide file tree
Showing 3 changed files with 117 additions and 1 deletion.
4 changes: 3 additions & 1 deletion docs/rules/sort-comp.md
Original file line number Diff line number Diff line change
Expand Up @@ -89,9 +89,11 @@ The default configuration is:
* `lifecycle` is referring to the `lifecycle` group defined in `groups`.
* `everything-else` is a special group that match all the methods that do not match any of the other groups.
* `render` is referring to the `render` method.
* `type-annotations`. This group is not specified by default, but can be used to enforce flow annotations to be at the top.
* `type-annotations`. This group is not specified by default, but can be used to enforce flow annotations positioning.
* `getters` This group is not specified by default, but can be used to enforce class getters positioning.
* `setters` This group is not specified by default, but can be used to enforce class setters positioning.
* `instance-variables` This group is not specified by default, but can be used to enforce all other instance variables positioning.
* `instance-methods` This group is not specified by default, but can be used to enforce all other instance methods positioning.

You can override this configuration to match your needs.

Expand Down
24 changes: 24 additions & 0 deletions lib/rules/sort-comp.js
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,20 @@ module.exports = {
}
}

if (indexes.length === 0 && method.instanceVariable) {
const annotationIndex = methodsOrder.indexOf('instance-variables');
if (annotationIndex >= 0) {
indexes.push(annotationIndex);
}
}

if (indexes.length === 0 && method.instanceMethod) {
const annotationIndex = methodsOrder.indexOf('instance-methods');
if (annotationIndex >= 0) {
indexes.push(annotationIndex);
}
}

// No matching pattern, return 'everything-else' index
if (indexes.length === 0) {
for (i = 0, j = methodsOrder.length; i < j; i++) {
Expand Down Expand Up @@ -361,6 +375,16 @@ module.exports = {
getter: node.kind === 'get',
setter: node.kind === 'set',
static: node.static,
instanceVariable: !node.static &&
node.type === 'ClassProperty' &&
node.value &&
node.value.type !== 'ArrowFunctionExpression' &&
node.value.type !== 'FunctionExpression',
instanceMethod: !node.static &&
node.type === 'ClassProperty' &&
node.value &&
(node.value.type === 'ArrowFunctionExpression' ||
node.value.type === 'FunctionExpression'),
typeAnnotation: !!node.typeAnnotation && node.value === null
}));

Expand Down
90 changes: 90 additions & 0 deletions tests/lib/rules/sort-comp.js
Original file line number Diff line number Diff line change
Expand Up @@ -310,6 +310,50 @@ ruleTester.run('sort-comp', rule, {
'render'
]
}]
}, {
// Instance methods should be at the top
code: [
'class Hello extends React.Component {',
' foo = () => {}',
' constructor() {}',
' classMethod() {}',
' static bar = () => {}',
' render() {',
' return <div>{this.props.text}</div>;',
' }',
'}'
].join('\n'),
parser: 'babel-eslint',
options: [{
order: [
'instance-methods',
'lifecycle',
'everything-else',
'render'
]
}]
}, {
// Instance variables should be at the top
code: [
'class Hello extends React.Component {',
' foo = \'bar\'',
' constructor() {}',
' state = {}',
' static bar = \'foo\'',
' render() {',
' return <div>{this.props.text}</div>;',
' }',
'}'
].join('\n'),
parser: 'babel-eslint',
options: [{
order: [
'instance-variables',
'lifecycle',
'everything-else',
'render'
]
}]
}],

invalid: [{
Expand Down Expand Up @@ -515,5 +559,51 @@ ruleTester.run('sort-comp', rule, {
'render'
]
}]
}, {
// Instance methods should not be at the top
code: [
'class Hello extends React.Component {',
' constructor() {}',
' static bar = () => {}',
' classMethod() {}',
' foo = function() {}',
' render() {',
' return <div>{this.props.text}</div>;',
' }',
'}'
].join('\n'),
parser: 'babel-eslint',
errors: [{message: 'foo should be placed before constructor'}],
options: [{
order: [
'instance-methods',
'lifecycle',
'everything-else',
'render'
]
}]
}, {
// Instance variables should not be at the top
code: [
'class Hello extends React.Component {',
' constructor() {}',
' state = {}',
' static bar = {}',
' foo = {}',
' render() {',
' return <div>{this.props.text}</div>;',
' }',
'}'
].join('\n'),
parser: 'babel-eslint',
errors: [{message: 'foo should be placed before constructor'}],
options: [{
order: [
'instance-variables',
'lifecycle',
'everything-else',
'render'
]
}]
}]
});

0 comments on commit c7dd755

Please sign in to comment.