diff --git a/rules/no-unused-expressions.js b/rules/no-unused-expressions.js index 94628cb..eb1955a 100644 --- a/rules/no-unused-expressions.js +++ b/rules/no-unused-expressions.js @@ -42,8 +42,22 @@ function isInDoStatement(node) { return false; } +/** + * @param {ASTNode} node - any node + * @returns {boolean} whether the given node is an optional call expression, + * see https://github.com/tc39/proposal-optional-chaining + */ +function isOptionalCallExpression(node) { + return ( + !!node && + node.type === 'ExpressionStatement' && + node.expression.type === 'OptionalCallExpression' + ); +} + module.exports = ruleComposer.filterReports( rule, - (problem, metadata) => !isInDoStatement(problem.node) + (problem, metadata) => + !isInDoStatement(problem.node) && !isOptionalCallExpression(problem.node) ); diff --git a/tests/rules/no-unused-expressions.js b/tests/rules/no-unused-expressions.js index a8156ec..8ecbf68 100644 --- a/tests/rules/no-unused-expressions.js +++ b/tests/rules/no-unused-expressions.js @@ -74,12 +74,13 @@ ruleTester.run("no-unused-expressions", rule, { }, // Babel-specific test cases. - "let a = do { if (foo) { foo.bar } }", - "let a = do { foo }", - "let a = do { let b = 2; foo; }", - "let a = do { (foo + 1) }", - "let a = do { if (foo) { if (foo.bar) { foo.bar } } }", - "let a = do { if (foo) { if (foo.bar) { foo.bar } else if (foo.baz) { foo.baz } } }", + "let a = do { if (foo) { foo.bar; } }", + "let a = do { foo; }", + "let a = do { let b = 2; foo; }", + "let a = do { (foo + 1); }", + "let a = do { if (foo) { if (foo.bar) { foo.bar; } } }", + "let a = do { if (foo) { if (foo.bar) { foo.bar; } else if (foo.baz) { foo.baz; } } }", + "foo.bar?.();", ], invalid: [ @@ -136,7 +137,7 @@ ruleTester.run("no-unused-expressions", rule, { }, // Babel-specific test cases. - { code: "let a = do { foo; let b = 2; }", errors: [{ message: "Expected an assignment or function call and instead saw an expression.", type: "ExpressionStatement" }] }, + { code: "let a = do { foo; let b = 2; }", errors: [{ message: "Expected an assignment or function call and instead saw an expression.", type: "ExpressionStatement" }] }, { code: "let a = do { if (foo) { foo.bar } else { a; bar.foo } }", errors: [{ message: "Expected an assignment or function call and instead saw an expression.", type: "ExpressionStatement" }] }, ]