UNPKG

1.93 kBJavaScriptView Raw
1'use strict';
2const {isParenthesized, hasSideEffect} = require('eslint-utils');
3const getDocumentationUrl = require('./utils/get-documentation-url');
4const methodSelector = require('./utils/method-selector');
5const {notDomNodeSelector} = require('./utils/not-dom-node');
6const needsSemicolon = require('./utils/needs-semicolon');
7const isValueNotUsable = require('./utils/is-value-not-usable');
8
9const selector = [
10 methodSelector({
11 name: 'removeChild',
12 length: 1
13 }),
14 notDomNodeSelector('callee.object'),
15 notDomNodeSelector('arguments.0')
16].join('');
17
18const ERROR_MESSAGE_ID = 'error';
19const SUGGESTION_MESSAGE_ID = 'suggestion';
20
21const create = context => {
22 const sourceCode = context.getSourceCode();
23
24 return {
25 [selector](node) {
26 const parentNode = node.callee.object;
27 const childNode = node.arguments[0];
28
29 const problem = {
30 node,
31 messageId: ERROR_MESSAGE_ID
32 };
33
34 const fix = fixer => {
35 let childNodeText = sourceCode.getText(childNode);
36 if (isParenthesized(childNode, sourceCode) || childNode.type === 'AwaitExpression') {
37 childNodeText = `(${childNodeText})`;
38 }
39
40 if (needsSemicolon(sourceCode.getTokenBefore(node), sourceCode, childNodeText)) {
41 childNodeText = `;${childNodeText}`;
42 }
43
44 return fixer.replaceText(node, `${childNodeText}.remove()`);
45 };
46
47 if (!hasSideEffect(parentNode, sourceCode) && isValueNotUsable(node)) {
48 problem.fix = fix;
49 } else {
50 problem.suggest = [
51 {
52 messageId: SUGGESTION_MESSAGE_ID,
53 fix
54 }
55 ];
56 }
57
58 context.report(problem);
59 }
60 };
61};
62
63module.exports = {
64 create,
65 meta: {
66 type: 'suggestion',
67 docs: {
68 url: getDocumentationUrl(__filename)
69 },
70 fixable: 'code',
71 messages: {
72 [ERROR_MESSAGE_ID]: 'Prefer `childNode.remove()` over `parentNode.removeChild(childNode)`.',
73 [SUGGESTION_MESSAGE_ID]: 'Replace `parentNode.removeChild(childNode)` with `childNode.remove()`.'
74 }
75 }
76};