Skip to content

Commit 768f301

Browse files
authored
no-null: Allow Object.create(null, …) (#1432)
1 parent ee9f609 commit 768f301

File tree

2 files changed

+13
-36
lines changed

2 files changed

+13
-36
lines changed

rules/no-null.js

Lines changed: 10 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
'use strict';
22
const {
33
not,
4-
matches,
54
methodCallSelector,
65
callExpressionSelector,
76
} = require('./selectors/index.js');
@@ -15,43 +14,23 @@ const messages = {
1514
[SUGGESTION_REMOVE_MESSAGE_ID]: 'Remove `null`.',
1615
};
1716

18-
const objectCreateSelector = methodCallSelector({
19-
object: 'Object',
20-
method: 'create',
21-
argumentsLength: 1,
22-
});
23-
24-
// `useRef(null)`
25-
// eslint-disable-next-line unicorn/prevent-abbreviations
26-
const useRefSelector = callExpressionSelector({name: 'useRef', argumentsLength: 1});
27-
28-
// `React.useRef(null)`
29-
// eslint-disable-next-line unicorn/prevent-abbreviations
30-
const reactUseRefSelector = methodCallSelector({
31-
object: 'React',
32-
method: 'useRef',
33-
argumentsLength: 1,
34-
});
35-
3617
const selector = [
3718
'Literal',
3819
'[raw="null"]',
39-
not(`${matches([objectCreateSelector, useRefSelector, reactUseRefSelector])} > .arguments`),
20+
not([
21+
// `Object.create(null)`, `Object.create(null, foo)`
22+
`${methodCallSelector({object: 'Object', method: 'create', minimumArguments: 1, maximumArguments: 2})} > .arguments:first-child`,
23+
// `useRef(null)`
24+
`${callExpressionSelector({name: 'useRef', argumentsLength: 1})} > .arguments:first-child`,
25+
// `React.useRef(null)`
26+
`${methodCallSelector({object: 'React', method: 'useRef', argumentsLength: 1})} > .arguments:first-child`,
27+
// `foo.insertBefore(bar, null)`
28+
`${methodCallSelector({method: 'insertBefore', argumentsLength: 2})}[arguments.0.type!="SpreadElement"] > .arguments:nth-child(2)`,
29+
]),
4030
].join('');
4131

4232
const isLooseEqual = node => node.type === 'BinaryExpression' && ['==', '!='].includes(node.operator);
4333
const isStrictEqual = node => node.type === 'BinaryExpression' && ['===', '!=='].includes(node.operator);
44-
const isSecondArgumentOfInsertBefore = node =>
45-
node.parent.type === 'CallExpression' &&
46-
!node.parent.optional &&
47-
node.parent.arguments.length === 2 &&
48-
node.parent.arguments[0].type !== 'SpreadElement' &&
49-
node.parent.arguments[1] === node &&
50-
node.parent.callee.type === 'MemberExpression' &&
51-
!node.parent.callee.computed &&
52-
!node.parent.callee.optional &&
53-
node.parent.callee.property.type === 'Identifier' &&
54-
node.parent.callee.property.name === 'insertBefore';
5534

5635
const create = context => {
5736
const {checkStrictEquality} = {
@@ -66,10 +45,6 @@ const create = context => {
6645
return;
6746
}
6847

69-
if (isSecondArgumentOfInsertBefore(node)) {
70-
return;
71-
}
72-
7348
const problem = {
7449
node,
7550
messageId: ERROR_MESSAGE_ID,

test/no-null.mjs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ test({
5959
valid: [
6060
'let foo',
6161
'Object.create(null)',
62+
'Object.create(null, {foo: {value:1}})',
6263
'let insertedNode = parentNode.insertBefore(newNode, null)',
6364
// Not `null`
6465
'const foo = "null";',
@@ -222,13 +223,14 @@ test({
222223
// `callee.object.type` is not a `Identifier`
223224
invalidTestCase('lib.Object.create(null)'),
224225
// More/Less arguments
225-
invalidTestCase('Object.create(null, "")'),
226226
invalidTestCase('Object.create(...[null])'),
227+
invalidTestCase('Object.create(null, bar, extraArgument)'),
227228
invalidTestCase('foo.insertBefore(null)'),
228229
invalidTestCase('foo.insertBefore(foo, null, bar)'),
229230
invalidTestCase('foo.insertBefore(...[foo], null)'),
230231
// Not in right position
231232
invalidTestCase('foo.insertBefore(null, bar)'),
233+
invalidTestCase('Object.create(bar, null)'),
232234
],
233235
});
234236

0 commit comments

Comments
 (0)