Skip to content

Commit

Permalink
Add and fix tests for new babel eslint parser
Browse files Browse the repository at this point in the history
  • Loading branch information
Pascal Fong Kye committed Aug 26, 2020
1 parent de71e14 commit a4dd52d
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 4 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -7961,6 +7961,11 @@ new ESLintTester({
parserOptions,
}).run('react-hooks', ReactHooksESLintRule, tests);

new ESLintTester({
parser: require.resolve('@babel/eslint-parser'),
parserOptions,
}).run('react-hooks', ReactHooksESLintRule, tests);

new ESLintTester({
parser: require.resolve('@typescript-eslint/parser'),
parserOptions,
Expand Down
41 changes: 37 additions & 4 deletions packages/eslint-plugin-react-hooks/src/ExhaustiveDeps.js
Original file line number Diff line number Diff line change
Expand Up @@ -803,9 +803,10 @@ export default {
let maybeID = declaredDependencyNode;
while (
maybeID.type === 'MemberExpression' ||
maybeID.type === 'OptionalMemberExpression'
maybeID.type === 'OptionalMemberExpression' ||
maybeID.type === 'ChainExpression'
) {
maybeID = maybeID.object;
maybeID = maybeID.object || maybeID.expression.object;
}
const isDeclaredInComponent = !componentScope.through.some(
ref => ref.identifier === maybeID,
Expand Down Expand Up @@ -1599,8 +1600,19 @@ function analyzePropertyChain(node, optionalChains) {
const property = analyzePropertyChain(node.property, null);
const result = `${object}.${property}`;
if (optionalChains) {
// Mark as required.
optionalChains.set(result, false);
// Note: OptionalMemberExpression doesn't necessarily mean this node is optional.
// It just means there is an optional member somewhere inside.
// This particular node might still represent a required member, so check .optional field.
if (node.optional) {
// We only want to consider it optional if *all* usages were optional.
if (!optionalChains.has(result)) {
// Mark as (maybe) optional. If there's a required usage, this will be overridden.
optionalChains.set(result, true);
}
} else {
// Mark as required.
optionalChains.set(result, false);
}
}
return result;
} else if (node.type === 'OptionalMemberExpression' && !node.computed) {
Expand All @@ -1623,6 +1635,27 @@ function analyzePropertyChain(node, optionalChains) {
}
}
return result;
} else if (node.type === 'ChainExpression' && !node.computed) {
const expression = node.expression;
const object = analyzePropertyChain(expression.object, optionalChains);
const property = analyzePropertyChain(expression.property, null);
const result = `${object}.${property}`;
if (optionalChains) {
// Note: OptionalMemberExpression doesn't necessarily mean this node is optional.
// It just means there is an optional member somewhere inside.
// This particular node might still represent a required member, so check .optional field.
if (expression.optional) {
// We only want to consider it optional if *all* usages were optional.
if (!optionalChains.has(result)) {
// Mark as (maybe) optional. If there's a required usage, this will be overridden.
optionalChains.set(result, true);
}
} else {
// Mark as required.
optionalChains.set(result, false);
}
}
return result;
} else {
throw new Error(`Unsupported node type: ${node.type}`);
}
Expand Down

0 comments on commit a4dd52d

Please sign in to comment.