|
1 | 1 | import {getFunctionHeadLocation, getFunctionNameWithKind} from '@eslint-community/eslint-utils'; |
2 | | -import {getReferences, isNodeMatches} from './utils/index.js'; |
| 2 | +import {getReferences, isNodeContainsLexicalThis, isNodeMatches} from './utils/index.js'; |
3 | 3 | import {functionTypes} from './ast/index.js'; |
4 | 4 |
|
5 | 5 | const MESSAGE_ID = 'consistent-function-scoping'; |
@@ -94,10 +94,11 @@ const isReactHook = scope => |
94 | 94 | scope.block?.parent?.callee |
95 | 95 | && isNodeMatches(scope.block.parent.callee, reactHooks); |
96 | 96 |
|
97 | | -const isArrowFunctionWithThis = scope => |
98 | | - scope.type === 'function' |
99 | | - && scope.block?.type === 'ArrowFunctionExpression' |
100 | | - && (scope.thisFound || scope.childScopes.some(scope => isArrowFunctionWithThis(scope))); |
| 97 | +const isArrowFunctionNodeWithThis = (node, visitorKeys) => |
| 98 | + node.type === 'ArrowFunctionExpression' |
| 99 | + // We avoid `scope.thisFound` because parser scope metadata differs; AST lexical checks are consistent. |
| 100 | + // Include both params and body, because parameter defaults can reference lexical `this`. |
| 101 | + && isNodeContainsLexicalThis(node, visitorKeys); |
101 | 102 |
|
102 | 103 | const iifeFunctionTypes = new Set([ |
103 | 104 | 'FunctionExpression', |
@@ -145,10 +146,13 @@ function handleNestedArrowFunctions(parentNode, node) { |
145 | 146 | return parentNode; |
146 | 147 | } |
147 | 148 |
|
148 | | -function checkNode(node, scopeManager) { |
| 149 | +function checkNode(node, scopeManager, sourceCode) { |
149 | 150 | const scope = scopeManager.acquire(node); |
150 | 151 |
|
151 | | - if (!scope || isArrowFunctionWithThis(scope)) { |
| 152 | + if ( |
| 153 | + !scope |
| 154 | + || isArrowFunctionNodeWithThis(node, sourceCode.visitorKeys) |
| 155 | + ) { |
152 | 156 | return true; |
153 | 157 | } |
154 | 158 |
|
@@ -220,7 +224,7 @@ const create = context => { |
220 | 224 | return; |
221 | 225 | } |
222 | 226 |
|
223 | | - if (checkNode(node, scopeManager)) { |
| 227 | + if (checkNode(node, scopeManager, sourceCode)) { |
224 | 228 | return; |
225 | 229 | } |
226 | 230 |
|
|
0 commit comments