Upgrade to ESLint 9
This commit is contained in:
@ -6,7 +6,6 @@
|
||||
*/
|
||||
|
||||
/* global BigInt */
|
||||
/* eslint-disable no-for-of-loops/no-for-of-loops */
|
||||
import type { Rule, Scope } from 'eslint';
|
||||
import type {
|
||||
CallExpression,
|
||||
@ -16,6 +15,7 @@ import type {
|
||||
Identifier,
|
||||
BaseFunction,
|
||||
} from 'estree';
|
||||
|
||||
import { __EXPERIMENTAL__ } from './index';
|
||||
|
||||
/**
|
||||
@ -24,10 +24,7 @@ import { __EXPERIMENTAL__ } from './index';
|
||||
*/
|
||||
|
||||
function isHookName(s: string) {
|
||||
if (__EXPERIMENTAL__) {
|
||||
return s === 'use' || /^use[A-Z0-9]/.test(s);
|
||||
}
|
||||
return /^use[A-Z0-9]/.test(s);
|
||||
return s === 'use' || /^use[\dA-Z]/.test(s);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -94,10 +91,8 @@ function isMemoCallback(node: Rule.Node) {
|
||||
function isInsideComponentOrHook(node: Rule.Node) {
|
||||
while (node) {
|
||||
const functionName = getFunctionName(node);
|
||||
if (functionName) {
|
||||
if (isComponentName(functionName) || isHook(functionName)) {
|
||||
return true;
|
||||
}
|
||||
if (functionName && (isComponentName(functionName) || isHook(functionName))) {
|
||||
return true;
|
||||
}
|
||||
if (isForwardRefCallback(node) || isMemoCallback(node)) {
|
||||
return true;
|
||||
@ -115,10 +110,7 @@ function isUseEffectEventIdentifier(node: Node) {
|
||||
}
|
||||
|
||||
function isUseIdentifier(node: Node) {
|
||||
if (__EXPERIMENTAL__) {
|
||||
return node.type === 'Identifier' && node.name === 'use';
|
||||
}
|
||||
return false;
|
||||
return isReactFunction(node as Expression, 'use');
|
||||
}
|
||||
|
||||
const rule: Rule.RuleModule = {
|
||||
@ -161,6 +153,22 @@ const rule: Rule.RuleModule = {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* SourceCode#getText that also works down to ESLint 3.0.0
|
||||
*/
|
||||
const getSource =
|
||||
typeof context.getSource === 'function'
|
||||
? (node: Node) => context.getSource(node)
|
||||
: (node: Node) => context.sourceCode.getText(node);
|
||||
|
||||
/**
|
||||
* SourceCode#getScope that also works down to ESLint 3.0.0
|
||||
*/
|
||||
const getScope =
|
||||
typeof context.getScope === 'function'
|
||||
? () => context.getScope()
|
||||
: (node: Node) => context.sourceCode.getScope(node);
|
||||
|
||||
return {
|
||||
// Maintain code segment path stack as we traverse.
|
||||
onCodePathSegmentStart: segment => codePathSegmentStack.push(segment),
|
||||
@ -479,7 +487,7 @@ const rule: Rule.RuleModule = {
|
||||
context.report({
|
||||
node: hook,
|
||||
message:
|
||||
`React Hook "${context.getSource(hook)}" may be executed ` +
|
||||
`React Hook "${getSource(hook)}" may be executed ` +
|
||||
'more than once. Possibly because it is called in a loop. ' +
|
||||
'React Hooks must be called in the exact same order in ' +
|
||||
'every component render.',
|
||||
@ -498,7 +506,7 @@ const rule: Rule.RuleModule = {
|
||||
context.report({
|
||||
node: hook,
|
||||
message:
|
||||
`React Hook "${context.getSource(hook)}" cannot be ` +
|
||||
`React Hook "${getSource(hook)}" cannot be ` +
|
||||
'called in an async function.',
|
||||
});
|
||||
}
|
||||
@ -513,7 +521,7 @@ const rule: Rule.RuleModule = {
|
||||
!isUseIdentifier(hook) // `use(...)` can be called conditionally.
|
||||
) {
|
||||
const message =
|
||||
`React Hook "${context.getSource(hook)}" is called ` +
|
||||
`React Hook "${getSource(hook)}" is called ` +
|
||||
'conditionally. React Hooks must be called in the exact ' +
|
||||
'same order in every component render.' +
|
||||
(possiblyHasEarlyReturn
|
||||
@ -530,15 +538,15 @@ const rule: Rule.RuleModule = {
|
||||
) {
|
||||
// Custom message for hooks inside a class
|
||||
const message =
|
||||
`React Hook "${context.getSource(hook)}" cannot be called ` +
|
||||
`React Hook "${getSource(hook)}" cannot be called ` +
|
||||
'in a class component. React Hooks must be called in a ' +
|
||||
'React function component or a custom React Hook function.';
|
||||
context.report({ node: hook, message });
|
||||
} else if (codePathFunctionName) {
|
||||
// Custom message if we found an invalid function name.
|
||||
const message =
|
||||
`React Hook "${context.getSource(hook)}" is called in ` +
|
||||
`function "${context.getSource(codePathFunctionName)}" ` +
|
||||
`React Hook "${getSource(hook)}" is called in ` +
|
||||
`function "${getSource(codePathFunctionName)}" ` +
|
||||
'that is neither a React function component nor a custom ' +
|
||||
'React Hook function.' +
|
||||
' React component names must start with an uppercase letter.' +
|
||||
@ -547,7 +555,7 @@ const rule: Rule.RuleModule = {
|
||||
} else if (codePathNode.type === 'Program') {
|
||||
// These are dangerous if you have inline requires enabled.
|
||||
const message =
|
||||
`React Hook "${context.getSource(hook)}" cannot be called ` +
|
||||
`React Hook "${getSource(hook)}" cannot be called ` +
|
||||
'at the top level. React Hooks must be called in a ' +
|
||||
'React function component or a custom React Hook function.';
|
||||
context.report({ node: hook, message });
|
||||
@ -560,7 +568,7 @@ const rule: Rule.RuleModule = {
|
||||
// `use(...)` can be called in callbacks.
|
||||
if (isSomewhereInsideComponentOrHook && !isUseIdentifier(hook)) {
|
||||
const message =
|
||||
`React Hook "${context.getSource(hook)}" cannot be called ` +
|
||||
`React Hook "${getSource(hook)}" cannot be called ` +
|
||||
'inside a callback. React Hooks must be called in a ' +
|
||||
'React function component or a custom React Hook function.';
|
||||
context.report({ node: hook, message });
|
||||
@ -612,7 +620,7 @@ const rule: Rule.RuleModule = {
|
||||
context.report({
|
||||
node,
|
||||
message:
|
||||
`\`${context.getSource(
|
||||
`\`${getSource(
|
||||
node,
|
||||
)}\` is a function created with React Hook "useEffectEvent", and can only be called from ` +
|
||||
'the same component. They cannot be assigned to variables or passed down.',
|
||||
@ -629,14 +637,14 @@ const rule: Rule.RuleModule = {
|
||||
FunctionDeclaration(node) {
|
||||
// function MyComponent() { const onClick = useEffectEvent(...) }
|
||||
if (isInsideComponentOrHook(node)) {
|
||||
recordAllUseEffectEventFunctions(context.getScope());
|
||||
recordAllUseEffectEventFunctions(getScope(node));
|
||||
}
|
||||
},
|
||||
|
||||
ArrowFunctionExpression(node) {
|
||||
// const MyComponent = () => { const onClick = useEffectEvent(...) }
|
||||
if (isInsideComponentOrHook(node)) {
|
||||
recordAllUseEffectEventFunctions(context.getScope());
|
||||
recordAllUseEffectEventFunctions(getScope(node));
|
||||
}
|
||||
},
|
||||
};
|
||||
|
Reference in New Issue
Block a user