Skip to content

Commit

Permalink
fixup! [New] Symmetric useState hook variable names
Browse files Browse the repository at this point in the history
  • Loading branch information
duncanbeevers committed Dec 23, 2021
1 parent dbde062 commit 0eba9ec
Show file tree
Hide file tree
Showing 2 changed files with 59 additions and 104 deletions.
77 changes: 16 additions & 61 deletions lib/rules/hook-use-state.js
Expand Up @@ -33,71 +33,12 @@ module.exports = {
hasSuggestions: true,
},

create: Components.detect((context, components) => ({
create: Components.detect((context, components, util) => ({
CallExpression(node) {
const isImmediateReturn = node.parent
&& node.parent.type === 'ReturnStatement';

if (isImmediateReturn) {
return;
}

const defaultReactImports = components.getDefaultReactImports();
const namedReactImports = components.getNamedReactImports();
const defaultReactImportSpecifier = defaultReactImports
? defaultReactImports[0]
: undefined;
const defaultReactImportName = defaultReactImportSpecifier
? defaultReactImportSpecifier.local.name
: undefined;
const useStateReactImportSpecifier = namedReactImports
? namedReactImports.find((specifier) => specifier.imported.name === 'useState')
: undefined;
const useStateReactImportName = useStateReactImportSpecifier
? useStateReactImportSpecifier.local.name
: undefined;

const isPotentialReactUseStateCall = (
defaultReactImportName
&& node.callee.type === 'MemberExpression'
&& node.callee.object.type === 'Identifier'
&& node.callee.object.name === defaultReactImportName
&& node.callee.property.type === 'Identifier'
&& node.callee.property.name === 'useState'
);

const isPotentialUseStateCall = (
useStateReactImportName
&& node.callee.type === 'Identifier'
&& node.callee.name === useStateReactImportName
);

const scope = isPotentialReactUseStateCall || isPotentialUseStateCall
? context.getScope()
: undefined;

const reactResolvedDefs = isPotentialReactUseStateCall && scope.references.find(
(reference) => reference.identifier.name === defaultReactImportName
).resolved.defs;
const useStateResolvedDefs = isPotentialUseStateCall && scope.references.find(
(reference) => reference.identifier.name === useStateReactImportName
).resolved.defs;

const ultimateReactResolvedDef = reactResolvedDefs
? reactResolvedDefs[reactResolvedDefs.length - 1]
: undefined;
const ultimateUseStateResolvedDef = useStateResolvedDefs
? useStateResolvedDefs[useStateResolvedDefs.length - 1]
: undefined;

const isReactShadowed = ultimateReactResolvedDef && ultimateReactResolvedDef.type !== 'ImportBinding';
const isUseStateShadowed = ultimateUseStateResolvedDef && ultimateUseStateResolvedDef.type !== 'ImportBinding';

const isReactUseStateCall = isPotentialReactUseStateCall && !isReactShadowed;
const isUseStateCall = isPotentialUseStateCall && !isUseStateShadowed;

// Ignore unless this is a useState() or React.useState() call.
if (!isReactUseStateCall && !isUseStateCall) {
if (isImmediateReturn || !util.isReactHookCall(node, ['useState'])) {
return;
}

Expand Down Expand Up @@ -151,6 +92,20 @@ module.exports = {
},
];

const defaultReactImports = components.getDefaultReactImports();
const defaultReactImportSpecifier = defaultReactImports
? defaultReactImports[0]
: undefined;

const defaultReactImportName = defaultReactImportSpecifier
? defaultReactImportSpecifier.local.name
: undefined;

const namedReactImports = components.getNamedReactImports();
const useStateReactImportSpecifier = namedReactImports
? namedReactImports.find((specifier) => specifier.imported.name === 'useState')
: undefined;

const isSingleGetter = valueVariable && variableNodes.length === 1;
const isUseStateCalledWithSingleArgument = node.arguments.length === 1;
if (isSingleGetter && isUseStateCalledWithSingleArgument) {
Expand Down

0 comments on commit 0eba9ec

Please sign in to comment.