From 0388976ff9585f8c8dd451a2c5ede8f9af8303bc Mon Sep 17 00:00:00 2001 From: TX <1428427011@qq.com> Date: Mon, 18 Nov 2024 19:34:05 +0800 Subject: [PATCH 1/2] feat: fix the logic short-circuit bug --- .eslintrc.json | 3 ++- index.ts | 29 +++++++++++++++++------------ test.js | 4 ++-- 3 files changed, 21 insertions(+), 15 deletions(-) diff --git a/.eslintrc.json b/.eslintrc.json index 30a74a3..a662389 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -23,7 +23,8 @@ "@typescript-eslint/no-unused-vars": ["warn", {"argsIgnorePattern": "^_"}], "quotes": ["warn", "single"], "max-len": ["warn", {"code": 100, "tabWidth": 4, "ignoreUrls": true, "ignorePattern": "^import|^export"}], - "newline-per-chained-call": [2, {"ignoreChainWithDepth": 3}] + "newline-per-chained-call": [2, {"ignoreChainWithDepth": 3}], + "no-case-declarations": "off" }, "ignorePatterns": ["**/*.js"] } diff --git a/index.ts b/index.ts index d1f93f0..ae7beeb 100644 --- a/index.ts +++ b/index.ts @@ -150,10 +150,11 @@ function evaluate(_node: jsep.Expression, context: object) { return node.value; case 'LogicalExpression': - if (node.operator === '||') { - return evaluate(node.left, context) || evaluate(node.right, context); - } else if (node.operator === '&&') { - return evaluate(node.left, context) && evaluate(node.right, context); + const leftValue = evaluate(node.left, context); + if (node.operator === '||' && leftValue) { + return leftValue; + } else if (node.operator === '&&' && !leftValue) { + return leftValue; } return binops[node.operator](evaluate(node.left, context), evaluate(node.right, context)); @@ -222,15 +223,19 @@ async function evalAsync(_node: jsep.Expression, context: object) { case 'LogicalExpression': { if (node.operator === '||') { - return ( - (await evalAsync(node.left, context)) || - (await evalAsync(node.right, context)) - ); + const left = await evalAsync(node.left, context); + if (left) { + return left; + } + const right = await evalAsync(node.right, context); + return right; } else if (node.operator === '&&') { - return ( - (await evalAsync(node.left, context)) && - (await evalAsync(node.right, context)) - ); + const left = await evalAsync(node.left, context); + if (!left) { + return left; + } + const right = await evalAsync(node.right, context); + return right; } const [left, right] = await Promise.all([ diff --git a/test.js b/test.js index 93475e4..364fcc8 100644 --- a/test.js +++ b/test.js @@ -62,9 +62,9 @@ const fixtures = [ {expr: '1 >= 2', expected: false }, // logical expression lazy evaluation - {expr: 'true || false', expected: true }, + {expr: 'true || throw()', expected: true }, {expr: 'false || true', expected: true }, - {expr: 'false && true', expected: false }, + {expr: 'false && throw()', expected: false }, {expr: 'true && false', expected: false }, // member expression From a3e659e53ea206f3ce42a002d441cfeba2a87f6c Mon Sep 17 00:00:00 2001 From: TX <76741680+tx2002@users.noreply.github.com> Date: Tue, 19 Nov 2024 10:28:01 +0800 Subject: [PATCH 2/2] fix: apply suggestions from code review Co-authored-by: Zixuan Liu --- index.ts | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/index.ts b/index.ts index ae7beeb..f4e1a97 100644 --- a/index.ts +++ b/index.ts @@ -156,7 +156,7 @@ function evaluate(_node: jsep.Expression, context: object) { } else if (node.operator === '&&' && !leftValue) { return leftValue; } - return binops[node.operator](evaluate(node.left, context), evaluate(node.right, context)); + return binops[node.operator](leftValue, evaluate(node.right, context)); case 'MemberExpression': return evaluateMember(node, context)[1]; @@ -227,15 +227,13 @@ async function evalAsync(_node: jsep.Expression, context: object) { if (left) { return left; } - const right = await evalAsync(node.right, context); - return right; + return await evalAsync(node.right, context); } else if (node.operator === '&&') { const left = await evalAsync(node.left, context); if (!left) { return left; } - const right = await evalAsync(node.right, context); - return right; + return await evalAsync(node.right, context); } const [left, right] = await Promise.all([