Skip to content

Commit

Permalink
[Fix] destructuring-assignment: Handle destructuring of useContext …
Browse files Browse the repository at this point in the history
…in SFC
  • Loading branch information
ed-jinyoung-park authored and ljharb committed Sep 16, 2020
1 parent 896fe4b commit a5294d6
Show file tree
Hide file tree
Showing 2 changed files with 61 additions and 3 deletions.
34 changes: 31 additions & 3 deletions lib/rules/destructuring-assignment.js
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@ module.exports = {
const configuration = context.options[0] || DEFAULT_OPTION;
const ignoreClassFields = (context.options[1] && (context.options[1].ignoreClassFields === true)) || false;

// set to save renamed var of useContext
const contextSet = new Set();
/**
* @param {ASTNode} node We expect either an ArrowFunctionExpression,
* FunctionDeclaration, or FunctionExpression
Expand All @@ -61,14 +63,24 @@ module.exports = {
}

function handleSFCUsage(node) {
// props.aProp || context.aProp
const isPropUsed = (node.object.name === 'props' || node.object.name === 'context') && !isAssignmentLHS(node);
// props.aProp
const isPropUsed = node.object.name === 'props' && !isAssignmentLHS(node);
if (isPropUsed && configuration === 'always') {
context.report({
node,
message: `Must use destructuring ${node.object.name} assignment`
});
}

// const foo = useContext(aContext);
// foo.aProp
const isContextUsed = contextSet.has(node.object.name) && !isAssignmentLHS(node);
if (isContextUsed && configuration === 'always') {
context.report({
node,
message: `Must use destructuring ${node.object.name} assignment`
});
}
}

function isInClassProperty(node) {
Expand Down Expand Up @@ -125,13 +137,29 @@ module.exports = {
const SFCComponent = components.get(context.getScope(node).block);

const destructuring = (node.init && node.id && node.id.type === 'ObjectPattern');
const identifier = (node.init && node.id && node.id.type === 'Identifier');
// let {foo} = props;
const destructuringSFC = destructuring && (node.init.name === 'props' || node.init.name === 'context');
const destructuringSFC = destructuring && node.init.name === 'props';
// let {foo} = useContext(aContext);
const destructuringUseContext = destructuring && node.init.callee && node.init.callee.name === 'useContext';
// let foo = useContext(aContext);
const assignUseContext = identifier && node.init.callee && node.init.callee.name === 'useContext';
// let {foo} = this.props;
const destructuringClass = destructuring && node.init.object && node.init.object.type === 'ThisExpression' && (
node.init.property.name === 'props' || node.init.property.name === 'context' || node.init.property.name === 'state'
);

if (SFCComponent && assignUseContext) {
contextSet.add(node.id.name);
}

if (SFCComponent && destructuringUseContext && configuration === 'never') {
context.report({
node,
message: `Must never use destructuring ${node.init.callee.name} assignment`
});
}

if (SFCComponent && destructuringSFC && configuration === 'never') {
context.report({
node,
Expand Down
30 changes: 30 additions & 0 deletions tests/lib/rules/destructuring-assignment.js
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,18 @@ ruleTester.run('destructuring-assignment', rule, {
].join('\n'),
options: ['always', {ignoreClassFields: true}],
parser: parsers.BABEL_ESLINT
}, {
code: `const MyComponent = (props) => {
const {foo} = useContext(aContext);
return <div>{foo}</div>
};`,
options: ['always']
}, {
code: `const MyComponent = (props) => {
const foo = useContext(aContext);
return <div>{foo.test}</div>
};`,
options: ['never']
}],

invalid: [{
Expand Down Expand Up @@ -314,5 +326,23 @@ ruleTester.run('destructuring-assignment', rule, {
errors: [
{message: 'Must never use destructuring state assignment'}
]
}, {
code: `const MyComponent = (props) => {
const foo = useContext(aContext);
return <div>{foo.test}</div>
};`,
options: ['always'],
errors: [
{message: 'Must use destructuring foo assignment'}
]
}, {
code: `const MyComponent = (props) => {
const {foo} = useContext(aContext);
return <div>{foo}</div>
};`,
options: ['never'],
errors: [
{message: 'Must never use destructuring useContext assignment'}
]
}]
});

0 comments on commit a5294d6

Please sign in to comment.