-
-
Notifications
You must be signed in to change notification settings - Fork 2.8k
/
prefer-function-component.js
86 lines (76 loc) · 2.28 KB
/
prefer-function-component.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
/**
* @fileoverview Enforce function components over class components
* @author Tate Thurston
*/
'use strict';
const docsUrl = require('../util/docsUrl');
const Components = require('../util/Components');
const ast = require('../util/ast');
const COMPONENT_SHOULD_BE_FUNCTION = 'componentShouldBeFunction';
const ALLOW_COMPONENT_DID_CATCH = 'allowComponentDidCatch';
const COMPONENT_DID_CATCH = 'componentDidCatch';
module.exports = {
meta: {
docs: {
description: 'Enforce components are written as function components',
category: 'Stylistic Issues',
recommended: false,
suggestion: false,
url: docsUrl('prefer-function-component')
},
fixable: false,
type: 'problem',
messages: {
[COMPONENT_SHOULD_BE_FUNCTION]:
'Class component should be written as a function'
},
schema: [
{
type: 'object',
properties: {
[ALLOW_COMPONENT_DID_CATCH]: {
default: true,
type: 'boolean'
}
},
additionalProperties: false
}
]
},
create: Components.detect((context, components, utils) => {
const allowComponentDidCatchOption = context.options[0] && context.options[0].allowComponentDidCatch;
const allowComponentDidCatch = allowComponentDidCatchOption !== false;
function shouldPreferFunction(node) {
if (!allowComponentDidCatch) {
return true;
}
const properties = ast
.getComponentProperties(node)
.map(ast.getPropertyName);
return !properties.includes(COMPONENT_DID_CATCH);
}
const detect = (guard) => (node) => {
if (guard(node) && shouldPreferFunction(node)) {
components.set(node, {
[COMPONENT_SHOULD_BE_FUNCTION]: true
});
}
};
return {
ObjectExpression: detect(utils.isES5Component),
ClassDeclaration: detect(utils.isES6Component),
ClassExpression: detect(utils.isES6Component),
'Program:exit'() {
const list = components.list();
Object.values(list).forEach((component) => {
if (component[COMPONENT_SHOULD_BE_FUNCTION]) {
context.report({
node: component.node,
messageId: COMPONENT_SHOULD_BE_FUNCTION
});
}
});
}
};
})
};