Skip to content

Commit d4051a5

Browse files
committed
apply suggestions
1 parent c01a622 commit d4051a5

File tree

3 files changed

+62
-62
lines changed

3 files changed

+62
-62
lines changed

__tests__/always-return.js

Lines changed: 28 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -105,18 +105,15 @@ ruleTester.run('always-return', rule, {
105105
.finally(() => console.error('end'))`,
106106
options: [{ ignoreLastCallback: true }],
107107
},
108-
`hey.then(x => { window[x] = x })`,
109-
`hey.then(x => { window.a = x })`,
110-
`hey.then(x => { window.a.n = x })`,
111-
`hey.then(x => { window[12] = x })`,
112-
`hey.then(x => { window['12']["test"] = x })`,
113-
{
114-
code: `hey.then(x => { globalThis[x] = x })`,
115-
options: [{ ignoreAssignmentVariable: ['globalThis'] }],
116-
},
117-
{
118-
code: `hey.then(x => { globalThis.a.x = x })`,
119-
options: [{ ignoreAssignmentVariable: ['globalThis'] }],
108+
`hey.then(x => { globalThis = x })`,
109+
`hey.then(x => { globalThis[a] = x })`,
110+
`hey.then(x => { globalThis.a = x })`,
111+
`hey.then(x => { globalThis.a.n = x })`,
112+
`hey.then(x => { globalThis[12] = x })`,
113+
`hey.then(x => { globalThis['12']["test"] = x })`,
114+
{
115+
code: `hey.then(x => { window['x'] = x })`,
116+
options: [{ ignoreAssignmentVariable: ['window'] }],
120117
},
121118
],
122119

@@ -249,7 +246,25 @@ ruleTester.run('always-return', rule, {
249246
errors: [{ message }],
250247
},
251248
{
252-
code: `hey.then(x => { windows[x] = x })`,
249+
code: `hey.then(x => { invalid = x })`,
250+
errors: [{ message }],
251+
},
252+
{
253+
code: `hey.then(x => { invalid['x'] = x })`,
254+
errors: [{ message }],
255+
},
256+
{
257+
code: `hey.then(x => { windo['x'] = x })`,
258+
options: [{ ignoreAssignmentVariable: ['window'] }],
259+
errors: [{ message }],
260+
},
261+
{
262+
code: `hey.then(x => { windows['x'] = x })`,
263+
options: [{ ignoreAssignmentVariable: ['window'] }],
264+
errors: [{ message }],
265+
},
266+
{
267+
code: `hey.then(x => { x() })`,
253268
options: [{ ignoreAssignmentVariable: ['window'] }],
254269
errors: [{ message }],
255270
},

docs/rules/always-return.md

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -98,33 +98,37 @@ function foo() {
9898
You can pass an `{ ignoreAssignmentVariable: [] }` as an option to this rule
9999
with a list of variable names so that the last `then()` callback in a promise
100100
chain does not warn if it does an assignment to a global variable. Default is
101-
`["window"]`.
101+
`["globalThis"]`.
102102

103103
```js
104-
/* eslint promise/always-return: ["error", { ignoreAssignmentVariable: ["window", "globalThis"] }] */
104+
/* eslint promise/always-return: ["error", { ignoreAssignmentVariable: ["globalThis"] }] */
105105

106106
// OK
107107
promise.then((x) => {
108-
window.x = x
108+
globalThis = x
109109
})
110110

111-
// OK
112111
promise.then((x) => {
113-
window.x.y = x
112+
globalThis.x = x
114113
})
115114

116115
// OK
117116
promise.then((x) => {
118-
globalThis.x = x
117+
globalThis.x.y = x
119118
})
120119

121-
// OK
120+
// NG
121+
promise.then((x) => {
122+
anyOtherVariable = x
123+
})
124+
125+
// NG
122126
promise.then((x) => {
123-
globalThis.modules.x = x
127+
anyOtherVariable.x = x
124128
})
125129

126130
// NG
127131
promise.then((x) => {
128-
let a = x
132+
x()
129133
})
130134
```

rules/always-return.js

Lines changed: 21 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -125,37 +125,22 @@ function peek(arr) {
125125
}
126126

127127
/**
128-
* Gets the full object name for a MemberExpression or Identifier
129-
* @param {import('estree').MemberExpression | import('estree').Identifier} node
130-
* @returns {string}
128+
* Gets the root object name for a MemberExpression or Identifier.
129+
* @param {Node} node
130+
* @returns {string | undefined}
131131
*/
132-
function getFullObjectName(node) {
132+
function getRootObjectName(node) {
133133
if (node.type === 'Identifier') {
134134
return node.name
135135
}
136-
const objectName = getFullObjectName(node.object)
137-
const propertyName = node.property.name
138-
return `${objectName}${node.computed ? '[' : '.'}${propertyName}${node.computed ? ']' : ''}`
139-
}
140-
141-
/**
142-
* Checks if the given name starts with an ignored variable
143-
* @param {string} name
144-
* @param {string[]} ignoredVars
145-
* @returns {boolean}
146-
*/
147-
function startsWithIgnoredVar(name, ignoredVars) {
148-
return ignoredVars.some(
149-
(ignoredVar) =>
150-
name === ignoredVar ||
151-
(name.startsWith(ignoredVar) &&
152-
(name.charAt(ignoredVar.length) === '.' ||
153-
name.charAt(ignoredVar.length) === '[')),
154-
)
136+
// istanbul ignore else (fallback)
137+
if (node.type === 'MemberExpression') {
138+
return getRootObjectName(node.object)
139+
}
155140
}
156141

157142
/**
158-
* Checks if the node is an assignment to an ignored variable
143+
* Checks if the node is an assignment to an ignored variable. Use getRootObjectName to get the variable name.
159144
* @param {Node} node
160145
* @param {string[]} ignoredVars
161146
* @returns {boolean}
@@ -165,14 +150,8 @@ function isIgnoredAssignment(node, ignoredVars) {
165150
const expr = node.expression
166151
if (expr.type !== 'AssignmentExpression') return false
167152
const left = expr.left
168-
// istanbul ignore else
169-
if (left.type === 'MemberExpression') {
170-
const fullName = getFullObjectName(left.object)
171-
return startsWithIgnoredVar(fullName, ignoredVars)
172-
}
173-
// istanbul ignore next
174-
// fallback
175-
return false
153+
const rootName = getRootObjectName(left)
154+
return ignoredVars.includes(rootName)
176155
}
177156

178157
module.exports = {
@@ -210,8 +189,9 @@ module.exports = {
210189
const options = context.options[0] || {}
211190
const ignoreLastCallback = !!options.ignoreLastCallback
212191
const ignoreAssignmentVariable = options.ignoreAssignmentVariable || [
213-
'window',
192+
'globalThis',
214193
]
194+
215195
/**
216196
* @typedef {object} FuncInfo
217197
* @property {string[]} branchIDStack This is a stack representing the currently
@@ -306,13 +286,14 @@ module.exports = {
306286
return
307287
}
308288

309-
if (ignoreAssignmentVariable.length && isLastCallback(node)) {
310-
// istanbul ignore else
311-
if (node.body?.type === 'BlockStatement') {
312-
for (const statement of node.body.body) {
313-
if (isIgnoredAssignment(statement, ignoreAssignmentVariable)) {
314-
return
315-
}
289+
if (
290+
ignoreAssignmentVariable.length &&
291+
isLastCallback(node) &&
292+
node.body?.type === 'BlockStatement'
293+
) {
294+
for (const statement of node.body.body) {
295+
if (isIgnoredAssignment(statement, ignoreAssignmentVariable)) {
296+
return
316297
}
317298
}
318299
}

0 commit comments

Comments
 (0)