1 | 'use strict';
|
2 | const getDocumentationUrl = require('./utils/get-documentation-url');
|
3 | const methodSelector = require('./utils/method-selector');
|
4 |
|
5 | const ERROR_MESSAGE_ID = 'error';
|
6 | const SUGGESTION_REPLACE_MESSAGE_ID = 'replace';
|
7 | const SUGGESTION_REMOVE_MESSAGE_ID = 'remove';
|
8 |
|
9 | const objectCreateSelector = methodSelector({
|
10 | object: 'Object',
|
11 | name: 'create',
|
12 | length: 1
|
13 | });
|
14 |
|
15 | const selector = [
|
16 | `:not(${objectCreateSelector})`,
|
17 | '>',
|
18 | 'Literal',
|
19 | '[raw="null"]'
|
20 | ].join('');
|
21 |
|
22 | const isLooseEqual = node => node.type === 'BinaryExpression' && ['==', '!='].includes(node.operator);
|
23 | const isStrictEqual = node => node.type === 'BinaryExpression' && ['===', '!=='].includes(node.operator);
|
24 |
|
25 | const create = context => {
|
26 | const {checkStrictEquality} = {
|
27 | checkStrictEquality: false,
|
28 | ...context.options[0]
|
29 | };
|
30 |
|
31 | return {
|
32 | [selector]: node => {
|
33 | const problem = {
|
34 | node,
|
35 | messageId: ERROR_MESSAGE_ID
|
36 | };
|
37 |
|
38 |
|
39 | const {parent = {}} = node;
|
40 |
|
41 | if (!checkStrictEquality && isStrictEqual(parent)) {
|
42 | return;
|
43 | }
|
44 |
|
45 | const fix = fixer => fixer.replaceText(node, 'undefined');
|
46 | const replaceSuggestion = {
|
47 | messageId: SUGGESTION_REPLACE_MESSAGE_ID,
|
48 | fix
|
49 | };
|
50 |
|
51 | if (isLooseEqual(parent)) {
|
52 | problem.fix = fix;
|
53 | } else if (parent.type === 'ReturnStatement' && parent.argument === node) {
|
54 | problem.suggest = [
|
55 | {
|
56 | messageId: SUGGESTION_REMOVE_MESSAGE_ID,
|
57 | fix: fixer => fixer.remove(node)
|
58 | },
|
59 | replaceSuggestion
|
60 | ];
|
61 | } else if (parent.type === 'VariableDeclarator' && parent.init === node && parent.parent.kind !== 'const') {
|
62 | problem.suggest = [
|
63 | {
|
64 | messageId: SUGGESTION_REMOVE_MESSAGE_ID,
|
65 | fix: fixer => fixer.removeRange([parent.id.range[1], node.range[1]])
|
66 | },
|
67 | replaceSuggestion
|
68 | ];
|
69 | } else {
|
70 | problem.suggest = [
|
71 | replaceSuggestion
|
72 | ];
|
73 | }
|
74 |
|
75 | context.report(problem);
|
76 | }
|
77 | };
|
78 | };
|
79 |
|
80 | const schema = [
|
81 | {
|
82 | type: 'object',
|
83 | properties: {
|
84 | checkStrictEquality: {
|
85 | type: 'boolean',
|
86 | default: false
|
87 | }
|
88 | },
|
89 | additionalProperties: false
|
90 | }
|
91 | ];
|
92 |
|
93 | module.exports = {
|
94 | create,
|
95 | meta: {
|
96 | type: 'suggestion',
|
97 | docs: {
|
98 | url: getDocumentationUrl(__filename)
|
99 | },
|
100 | messages: {
|
101 | [ERROR_MESSAGE_ID]: 'Use `undefined` instead of `null`.',
|
102 | [SUGGESTION_REPLACE_MESSAGE_ID]: 'Replace `null` with `undefined`.',
|
103 | [SUGGESTION_REMOVE_MESSAGE_ID]: 'Remove `null`.'
|
104 | },
|
105 | schema,
|
106 | fixable: 'code'
|
107 | }
|
108 | };
|