From c847de9fd9306b5478bccddbc428988614bad340 Mon Sep 17 00:00:00 2001 From: yqiaoxu Date: Sun, 24 Jul 2022 22:46:54 +0800 Subject: [PATCH 1/2] fix: no-non-null-asserted-optional-chain infinite loop problem --- .../src/rules/no-non-null-asserted-optional-chain.ts | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/packages/eslint-plugin/src/rules/no-non-null-asserted-optional-chain.ts b/packages/eslint-plugin/src/rules/no-non-null-asserted-optional-chain.ts index 9e1b3c94656e..a00aa1e92d4a 100644 --- a/packages/eslint-plugin/src/rules/no-non-null-asserted-optional-chain.ts +++ b/packages/eslint-plugin/src/rules/no-non-null-asserted-optional-chain.ts @@ -104,12 +104,13 @@ export default util.createRule({ const node = child.parent as TSESTree.TSNonNullExpression; let current = child; - while (current) { + let isRight = true; + while (current && isRight) { switch (current.type) { case AST_NODE_TYPES.MemberExpression: if (current.optional) { // found an optional chain! stop traversing - break; + isRight = false; } current = current.object; @@ -118,7 +119,7 @@ export default util.createRule({ case AST_NODE_TYPES.CallExpression: if (current.optional) { // found an optional chain! stop traversing - break; + isRight = false; } current = current.callee; From ac7ccb4ae2535e144661ca260349cff786da35cb Mon Sep 17 00:00:00 2001 From: yqiaoxu Date: Fri, 19 Aug 2022 10:04:20 +0800 Subject: [PATCH 2/2] fix: code modified to a cleaner way --- .../no-non-null-asserted-optional-chain.ts | 50 +++++++++++-------- 1 file changed, 28 insertions(+), 22 deletions(-) diff --git a/packages/eslint-plugin/src/rules/no-non-null-asserted-optional-chain.ts b/packages/eslint-plugin/src/rules/no-non-null-asserted-optional-chain.ts index a00aa1e92d4a..41fa2f8e1503 100644 --- a/packages/eslint-plugin/src/rules/no-non-null-asserted-optional-chain.ts +++ b/packages/eslint-plugin/src/rules/no-non-null-asserted-optional-chain.ts @@ -102,33 +102,39 @@ export default util.createRule({ ].join(', ')](child: TSESTree.Node): void { // selector guarantees this assertion const node = child.parent as TSESTree.TSNonNullExpression; + const hasOptionalChain = ((): boolean => { + let current = child; + while (current) { + switch (current.type) { + case AST_NODE_TYPES.MemberExpression: + if (current.optional) { + // found an optional chain! stop traversing + return true; + } - let current = child; - let isRight = true; - while (current && isRight) { - switch (current.type) { - case AST_NODE_TYPES.MemberExpression: - if (current.optional) { - // found an optional chain! stop traversing - isRight = false; - } + current = current.object; + continue; - current = current.object; - continue; + case AST_NODE_TYPES.CallExpression: + if (current.optional) { + // found an optional chain! stop traversing + return true; + } - case AST_NODE_TYPES.CallExpression: - if (current.optional) { - // found an optional chain! stop traversing - isRight = false; - } + current = current.callee; + continue; - current = current.callee; - continue; - - default: - // something that's not a ChainElement, which means this is not an optional chain we want to check - return; + default: + // something that's not a ChainElement, which means this is not an optional chain we want to check + return false; + } } + + return true; + })(); + + if (!hasOptionalChain) { + return; } context.report({