/
prefer-node-remove.js
91 lines (72 loc) · 1.71 KB
/
prefer-node-remove.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
87
88
89
90
91
'use strict';
const getDocumentationUrl = require('./utils/get-documentation-url');
const isValueUsed = require('./utils/is-value-used');
const getMethodName = callee => {
const {property} = callee;
if (property.type === 'Identifier') {
return property.name;
}
return null;
};
const getCallerName = callee => {
const {object} = callee;
if (object.type === 'Identifier') {
return object.name;
}
if (object.type === 'MemberExpression') {
const {property} = object;
if (property.type === 'Identifier') {
return property.name;
}
}
return null;
};
const getArgumentName = arguments_ => {
const [identifier] = arguments_;
if (identifier.type === 'ThisExpression') {
return 'this';
}
if (identifier.type === 'Identifier') {
return identifier.name;
}
return null;
};
const create = context => {
return {
CallExpression(node) {
const {callee} = node;
if (node.arguments.length === 0 ||
callee.type !== 'MemberExpression' ||
callee.computed
) {
return;
}
const methodName = getMethodName(callee);
const callerName = getCallerName(callee);
if (methodName === 'removeChild' && (
callerName === 'parentNode' ||
callerName === 'parentElement'
)) {
const argumentName = getArgumentName(node.arguments);
if (argumentName) {
const fix = isValueUsed(node) ? undefined : fixer => fixer.replaceText(node, `${argumentName}.remove()`);
context.report({
node,
message: `Prefer \`${argumentName}.remove()\` over \`${callerName}.removeChild(${argumentName})\`.`,
fix
});
}
}
}
};
};
module.exports = {
create,
meta: {
type: 'suggestion',
docs: {
url: getDocumentationUrl(__filename)
},
fixable: 'code'
}
};