pve-eslint/eslint/tests/lib/rules/no-extra-parens.js
Dominik Csapak f2a92ac62f import 8.41.0 source
Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
2023-05-24 18:51:55 +02:00

3450 lines
124 KiB
JavaScript

/**
* @fileoverview Disallow parenthesising higher precedence subexpressions.
* @author Michael Ficarra
*/
"use strict";
//------------------------------------------------------------------------------
// Requirements
//------------------------------------------------------------------------------
const rule = require("../../../lib/rules/no-extra-parens"),
{ RuleTester } = require("../../../lib/rule-tester");
//------------------------------------------------------------------------------
// Helpers
//------------------------------------------------------------------------------
/**
* Create error message object for failure cases
* @param {string} code source code
* @param {string} output fixed source code
* @param {string} type node type
* @param {int} line line number
* @param {Object} config rule configuration
* @returns {Object} result object
* @private
*/
function invalid(code, output, type, line, config) {
const result = {
code,
output,
parserOptions: config && config.parserOptions || {},
errors: [
{
messageId: "unexpected",
type
}
],
options: config && config.options || []
};
if (line) {
result.errors[0].line = line;
}
return result;
}
//------------------------------------------------------------------------------
// Tests
//------------------------------------------------------------------------------
const ruleTester = new RuleTester({
parserOptions: {
ecmaVersion: 2022,
ecmaFeatures: {
jsx: true
}
}
});
ruleTester.run("no-extra-parens", rule, {
valid: [
// all precedence boundaries
"foo",
"a = b, c = d",
"a = b ? c : d",
"a = (b, c)",
"a || b ? c = d : e = f",
"(a = b) ? (c, d) : (e, f)",
"a && b || c && d",
"(a ? b : c) || (d ? e : f)",
"a | b && c | d",
"(a || b) && (c || d)",
"a ^ b | c ^ d",
"(a && b) | (c && d)",
"a & b ^ c & d",
"(a | b) ^ (c | d)",
"a == b & c != d",
"(a ^ b) & (c ^ d)",
"a < b === c in d",
"(a & b) !== (c & d)",
"a << b >= c >>> d",
"(a == b) instanceof (c != d)",
"a + b << c - d",
"(a <= b) >> (c > d)",
"a * b + c / d",
"(a << b) - (c >> d)",
"+a % !b",
"(a + b) * (c - d)",
"-void+delete~typeof!a",
"!(a * b); typeof (a / b); +(a % b); delete (a * b); ~(a / b); void (a % b); -(a * b)",
"a(b = c, (d, e))",
"(++a)(b); (c++)(d);",
"new (A())",
"new (foo.Baz().foo)",
"new (foo.baz.bar().foo.baz)",
"new ({}.baz.bar.foo().baz)",
"new (doSomething().baz.bar().foo)",
"new ([][0].baz.foo().bar.foo)",
"new (foo\n.baz\n.bar()\n.foo.baz)",
"new A()()",
"(new A)()",
"(new (Foo || Bar))()",
"(new new foo())()",
"new (new A)()",
"new (new a.b)()",
"new (new new foo())(bar)",
"(new foo).bar",
"(new foo)[bar]",
"(new foo).bar.baz",
"(new foo.bar).baz",
"(new foo).bar()",
"(new foo.bar).baz()",
"new (new foo).bar",
"new (new foo.bar).baz",
"(new new foo()).baz",
"(2 + 3) ** 4",
"2 ** (2 + 3)",
"new (import(source))",
"import((s,t))",
// same precedence
"a, b, c",
"a = b = c",
"a ? b ? c : d : e",
"a ? b : c ? d : e",
"a || b || c",
"a || (b || c)",
"a && b && c",
"a && (b && c)",
"a | b | c",
"a | (b | c)",
"a ^ b ^ c",
"a ^ (b ^ c)",
"a & b & c",
"a & (b & c)",
"a == b == c",
"a == (b == c)",
"a < b < c",
"a < (b < c)",
"a << b << c",
"a << (b << c)",
"a + b + c",
"a + (b + c)",
"a * b * c",
"a * (b * c)",
"!!a; typeof +b; void -c; ~delete d;",
"a(b)",
"a(b)(c)",
"a((b, c))",
"new new A",
"2 ** 3 ** 4",
"(2 ** 3) ** 4",
// constructs that contain expressions
"if(a);",
"with(a){}",
"switch(a){ case 0: break; }",
"function a(){ return b; }",
"var a = () => { return b; }",
"throw a;",
"while(a);",
"do; while(a);",
"for(;;);",
"for(a in b);",
"for(a in b, c);",
"for(a of b);",
"for (a of (b, c));",
"var a = (b, c);",
"[]",
"[a, b]",
"!{a}",
"!{a: 0, b: 1}",
"!{[a]:0}",
"!{[(a, b)]:0}",
"!{a, ...b}",
"const {a} = {}",
"const {a:b} = {}",
"const {a:b=1} = {}",
"const {[a]:b} = {}",
"const {[a]:b=1} = {}",
"const {[(a, b)]:c} = {}",
"const {a, ...b} = {}",
"class foo {}",
"class foo { constructor(){} a(){} get b(){} set b(bar){} get c(){} set d(baz){} static e(){} }",
"class foo { [a](){} get [b](){} set [b](bar){} get [c](){} set [d](baz){} static [e](){} }",
"class foo { [(a,b)](){} }",
"class foo { a(){} [b](){} c(){} [(d,e)](){} }",
"class foo { [(a,b)](){} c(){} [d](){} e(){} }",
"const foo = class { constructor(){} a(){} get b(){} set b(bar){} get c(){} set d(baz){} static e(){} }",
"class foo { x; }",
"class foo { static x; }",
"class foo { x = 1; }",
"class foo { static x = 1; }",
"class foo { #x; }",
"class foo { static #x; }",
"class foo { static #x = 1; }",
"class foo { #x(){} get #y() {} set #y(value) {} static #z(){} static get #q() {} static set #q(value) {} }",
"const foo = class { #x(){} get #y() {} set #y(value) {} static #z(){} static get #q() {} static set #q(value) {} }",
"class foo { [(x, y)]; }",
"class foo { static [(x, y)]; }",
"class foo { [(x, y)] = 1; }",
"class foo { static [(x, y)] = 1; }",
"class foo { x = (y, z); }",
"class foo { static x = (y, z); }",
"class foo { #x = (y, z); }",
"class foo { static #x = (y, z); }",
"class foo { [(1, 2)] = (3, 4) }",
"const foo = class { [(1, 2)] = (3, 4) }",
// ExpressionStatement restricted productions
"({});",
"(function(){});",
"(let[a] = b);",
"(function*(){});",
"(class{});",
// special cases
"(0).a",
"(123).a",
"(08).a",
"(09).a",
"(018).a",
"(012934).a",
"(5_000).a",
"(5_000_00).a",
"(function(){ }())",
"({a: function(){}}.a());",
"({a:0}.a ? b : c)",
// RegExp literal is allowed to have parens (#1589)
"var isA = (/^a$/).test('a');",
"var regex = (/^a$/);",
"function a(){ return (/^a$/); }",
"function a(){ return (/^a$/).test('a'); }",
"var isA = ((/^a$/)).test('a');",
// IIFE is allowed to have parens in any position (#655)
"var foo = (function() { return bar(); }())",
"var o = { foo: (function() { return bar(); }()) };",
"o.foo = (function(){ return bar(); }());",
"(function(){ return bar(); }()), (function(){ return bar(); }())",
// IIFE is allowed to have outer parens (#1004)
"var foo = (function() { return bar(); })()",
"var o = { foo: (function() { return bar(); })() };",
"o.foo = (function(){ return bar(); })();",
"(function(){ return bar(); })(), (function(){ return bar(); })()",
"function foo() { return (function(){}()); }",
// parens are required around yield
"var foo = (function*() { if ((yield foo()) + 1) { return; } }())",
// arrow functions have the precedence of an assignment expression
"(() => 0)()",
"(_ => 0)()",
"_ => 0, _ => 1",
"a = () => b = 0",
"0 ? _ => 0 : _ => 0",
"(_ => 0) || (_ => 0)",
// Object literals as arrow function bodies need parentheses
"x => ({foo: 1})",
// Exponentiation operator `**`
"1 + 2 ** 3",
"1 - 2 ** 3",
"2 ** -3",
"(-2) ** 3",
"(+2) ** 3",
"+ (2 ** 3)",
// https://github.com/eslint/eslint/issues/5789
"a => ({b: c}[d])",
"a => ({b: c}.d())",
"a => ({b: c}.d.e)",
// "functions" enables reports for function nodes only
{ code: "(0)", options: ["functions"] },
{ code: "((0))", options: ["functions"] },
{ code: "a + (b * c)", options: ["functions"] },
{ code: "a + ((b * c))", options: ["functions"] },
{ code: "(a)(b)", options: ["functions"] },
{ code: "((a))(b)", options: ["functions"] },
{ code: "a, (b = c)", options: ["functions"] },
{ code: "a, ((b = c))", options: ["functions"] },
{ code: "for(a in (0));", options: ["functions"] },
{ code: "for(a in ((0)));", options: ["functions"] },
{ code: "var a = (b = c)", options: ["functions"] },
{ code: "var a = ((b = c))", options: ["functions"] },
{ code: "_ => (a = 0)", options: ["functions"] },
{ code: "_ => ((a = 0))", options: ["functions"] },
// ["all", { conditionalAssign: false }] enables extra parens around conditional assignments
{ code: "while ((foo = bar())) {}", options: ["all", { conditionalAssign: false }] },
{ code: "if ((foo = bar())) {}", options: ["all", { conditionalAssign: false }] },
{ code: "do; while ((foo = bar()))", options: ["all", { conditionalAssign: false }] },
{ code: "for (;(a = b););", options: ["all", { conditionalAssign: false }] },
{ code: "var a = ((b = c)) ? foo : bar;", options: ["all", { conditionalAssign: false }] },
{ code: "while (((foo = bar()))) {}", options: ["all", { conditionalAssign: false }] },
{ code: "var a = (((b = c))) ? foo : bar;", options: ["all", { conditionalAssign: false }] },
// ["all", { nestedBinaryExpressions: false }] enables extra parens around conditional assignments
{ code: "a + (b * c)", options: ["all", { nestedBinaryExpressions: false }] },
{ code: "(a * b) + c", options: ["all", { nestedBinaryExpressions: false }] },
{ code: "(a * b) / c", options: ["all", { nestedBinaryExpressions: false }] },
{ code: "a || (b && c)", options: ["all", { nestedBinaryExpressions: false }] },
{ code: "a + ((b * c))", options: ["all", { nestedBinaryExpressions: false }] },
{ code: "((a * b)) + c", options: ["all", { nestedBinaryExpressions: false }] },
{ code: "((a * b)) / c", options: ["all", { nestedBinaryExpressions: false }] },
{ code: "a || ((b && c))", options: ["all", { nestedBinaryExpressions: false }] },
// ["all", { returnAssign: false }] enables extra parens around expressions returned by return statements
{ code: "function a(b) { return b || c; }", options: ["all", { returnAssign: false }] },
{ code: "function a(b) { return; }", options: ["all", { returnAssign: false }] },
{ code: "function a(b) { return (b = 1); }", options: ["all", { returnAssign: false }] },
{ code: "function a(b) { return (b = c) || (b = d); }", options: ["all", { returnAssign: false }] },
{ code: "function a(b) { return c ? (d = b) : (e = b); }", options: ["all", { returnAssign: false }] },
{ code: "b => b || c;", options: ["all", { returnAssign: false }] },
{ code: "b => (b = 1);", options: ["all", { returnAssign: false }] },
{ code: "b => (b = c) || (b = d);", options: ["all", { returnAssign: false }] },
{ code: "b => c ? (d = b) : (e = b);", options: ["all", { returnAssign: false }] },
{ code: "b => { return b || c };", options: ["all", { returnAssign: false }] },
{ code: "b => { return (b = 1) };", options: ["all", { returnAssign: false }] },
{ code: "b => { return (b = c) || (b = d) };", options: ["all", { returnAssign: false }] },
{ code: "b => { return c ? (d = b) : (e = b) };", options: ["all", { returnAssign: false }] },
{ code: "function a(b) { return ((b = 1)); }", options: ["all", { returnAssign: false }] },
{ code: "b => ((b = 1));", options: ["all", { returnAssign: false }] },
// https://github.com/eslint/eslint/issues/3653
"(function(){}).foo(), 1, 2;",
"(function(){}).foo++;",
"(function(){}).foo() || bar;",
"(function(){}).foo() + 1;",
"(function(){}).foo() ? bar : baz;",
"(function(){}).foo.bar();",
"(function(){}.foo());",
"(function(){}.foo.bar);",
"(class{}).foo(), 1, 2;",
"(class{}).foo++;",
"(class{}).foo() || bar;",
"(class{}).foo() + 1;",
"(class{}).foo() ? bar : baz;",
"(class{}).foo.bar();",
"(class{}.foo());",
"(class{}.foo.bar);",
// https://github.com/eslint/eslint/issues/4608
"function *a() { yield b; }",
"function *a() { yield yield; }",
"function *a() { yield b, c; }",
"function *a() { yield (b, c); }",
"function *a() { yield b + c; }",
"function *a() { (yield b) + c; }",
// https://github.com/eslint/eslint/issues/4229
[
"function a() {",
" return (",
" b",
" );",
"}"
].join("\n"),
[
"function a() {",
" return (",
" <JSX />",
" );",
"}"
].join("\n"),
[
"function a() {",
" return (",
" <></>",
" );",
"}"
].join("\n"),
[
"throw (",
" a",
");"
].join("\n"),
[
"function *a() {",
" yield (",
" b",
" );",
"}"
].join("\n"),
// linebreaks before postfix update operators are not allowed
"(a\n)++",
"(a\n)--",
"(a\n\n)++",
"(a.b\n)--",
"(a\n.b\n)++",
"(a[\nb\n]\n)--",
"(a[b]\n\n)++",
// async/await
"async function a() { await (a + b) }",
"async function a() { await (a + await b) }",
"async function a() { (await a)() }",
"async function a() { new (await a) }",
"async function a() { await (a ** b) }",
"async function a() { (await a) ** b }",
{ code: "(foo instanceof bar) instanceof baz", options: ["all", { nestedBinaryExpressions: false }] },
{ code: "(foo in bar) in baz", options: ["all", { nestedBinaryExpressions: false }] },
{ code: "(foo + bar) + baz", options: ["all", { nestedBinaryExpressions: false }] },
{ code: "(foo && bar) && baz", options: ["all", { nestedBinaryExpressions: false }] },
{ code: "foo instanceof (bar instanceof baz)", options: ["all", { nestedBinaryExpressions: false }] },
{ code: "foo in (bar in baz)", options: ["all", { nestedBinaryExpressions: false }] },
{ code: "foo + (bar + baz)", options: ["all", { nestedBinaryExpressions: false }] },
{ code: "foo && (bar && baz)", options: ["all", { nestedBinaryExpressions: false }] },
{ code: "((foo instanceof bar)) instanceof baz", options: ["all", { nestedBinaryExpressions: false }] },
{ code: "((foo in bar)) in baz", options: ["all", { nestedBinaryExpressions: false }] },
// https://github.com/eslint/eslint/issues/9019
"(async function() {});",
"(async function () { }());",
// ["all", { ignoreJSX: "all" }]
{ code: "const Component = (<div />)", options: ["all", { ignoreJSX: "all" }] },
{ code: "const Component = ((<div />))", options: ["all", { ignoreJSX: "all" }] },
{
code: [
"const Component = (<>",
" <p />",
"</>);"
].join("\n"),
options: ["all", { ignoreJSX: "all" }]
},
{
code: [
"const Component = ((<>",
" <p />",
"</>));"
].join("\n"),
options: ["all", { ignoreJSX: "all" }]
},
{
code: [
"const Component = (<div>",
" <p />",
"</div>);"
].join("\n"),
options: ["all", { ignoreJSX: "all" }]
},
{
code: [
"const Component = (",
" <div />",
");"
].join("\n"),
options: ["all", { ignoreJSX: "all" }]
},
{
code: [
"const Component =",
" (<div />)"
].join("\n"),
options: ["all", { ignoreJSX: "all" }]
},
// ["all", { ignoreJSX: "single-line" }]
{ code: "const Component = (<div />);", options: ["all", { ignoreJSX: "single-line" }] },
{ code: "const Component = ((<div />));", options: ["all", { ignoreJSX: "single-line" }] },
{
code: [
"const Component = (",
" <div />",
");"
].join("\n"),
options: ["all", { ignoreJSX: "single-line" }]
},
{
code: [
"const Component =",
"(<div />)"
].join("\n"),
options: ["all", { ignoreJSX: "single-line" }]
},
// ["all", { ignoreJSX: "multi-line" }]
{
code: [
"const Component = (",
"<div>",
" <p />",
"</div>",
");"
].join("\n"),
options: ["all", { ignoreJSX: "multi-line" }]
},
{
code: [
"const Component = ((",
"<div>",
" <p />",
"</div>",
"));"
].join("\n"),
options: ["all", { ignoreJSX: "multi-line" }]
},
{
code: [
"const Component = (<div>",
" <p />",
"</div>);"
].join("\n"),
options: ["all", { ignoreJSX: "multi-line" }]
},
{
code: [
"const Component =",
"(<div>",
" <p />",
"</div>);"
].join("\n"),
options: ["all", { ignoreJSX: "multi-line" }]
},
{
code: [
"const Component = (<div",
" prop={true}",
"/>)"
].join("\n"),
options: ["all", { ignoreJSX: "multi-line" }]
},
// ["all", { enforceForArrowConditionals: false }]
{ code: "var a = b => 1 ? 2 : 3", options: ["all", { enforceForArrowConditionals: false }] },
{ code: "var a = (b) => (1 ? 2 : 3)", options: ["all", { enforceForArrowConditionals: false }] },
{ code: "var a = (b) => ((1 ? 2 : 3))", options: ["all", { enforceForArrowConditionals: false }] },
// ["all", { enforceForSequenceExpressions: false }]
{ code: "(a, b)", options: ["all", { enforceForSequenceExpressions: false }] },
{ code: "((a, b))", options: ["all", { enforceForSequenceExpressions: false }] },
{ code: "(foo(), bar());", options: ["all", { enforceForSequenceExpressions: false }] },
{ code: "((foo(), bar()));", options: ["all", { enforceForSequenceExpressions: false }] },
{ code: "if((a, b)){}", options: ["all", { enforceForSequenceExpressions: false }] },
{ code: "if(((a, b))){}", options: ["all", { enforceForSequenceExpressions: false }] },
{ code: "while ((val = foo(), val < 10));", options: ["all", { enforceForSequenceExpressions: false }] },
// ["all", { enforceForNewInMemberExpressions: false }]
{ code: "(new foo()).bar", options: ["all", { enforceForNewInMemberExpressions: false }] },
{ code: "(new foo())[bar]", options: ["all", { enforceForNewInMemberExpressions: false }] },
{ code: "(new foo()).bar()", options: ["all", { enforceForNewInMemberExpressions: false }] },
{ code: "(new foo(bar)).baz", options: ["all", { enforceForNewInMemberExpressions: false }] },
{ code: "(new foo.bar()).baz", options: ["all", { enforceForNewInMemberExpressions: false }] },
{ code: "(new foo.bar()).baz()", options: ["all", { enforceForNewInMemberExpressions: false }] },
{ code: "((new foo.bar())).baz()", options: ["all", { enforceForNewInMemberExpressions: false }] },
// ["all", { enforceForFunctionPrototypeMethods: false }]
{ code: "var foo = (function(){}).call()", options: ["all", { enforceForFunctionPrototypeMethods: false }] },
{ code: "var foo = (function(){}).apply()", options: ["all", { enforceForFunctionPrototypeMethods: false }] },
{ code: "var foo = (function(){}.call())", options: ["all", { enforceForFunctionPrototypeMethods: false }] },
{ code: "var foo = (function(){}.apply())", options: ["all", { enforceForFunctionPrototypeMethods: false }] },
{ code: "var foo = (function(){}).call(arg)", options: ["all", { enforceForFunctionPrototypeMethods: false }] },
{ code: "var foo = (function(){}.apply(arg))", options: ["all", { enforceForFunctionPrototypeMethods: false }] },
{ code: "var foo = (function(){}['call']())", options: ["all", { enforceForFunctionPrototypeMethods: false }] },
{ code: "var foo = (function(){})[`apply`]()", options: ["all", { enforceForFunctionPrototypeMethods: false }] },
{ code: "var foo = ((function(){})).call()", options: ["all", { enforceForFunctionPrototypeMethods: false }] },
{ code: "var foo = ((function(){}).apply())", options: ["all", { enforceForFunctionPrototypeMethods: false }] },
{ code: "var foo = ((function(){}.call()))", options: ["all", { enforceForFunctionPrototypeMethods: false }] },
{ code: "var foo = ((((function(){})).apply()))", options: ["all", { enforceForFunctionPrototypeMethods: false }] },
{ code: "foo((function(){}).call().bar)", options: ["all", { enforceForFunctionPrototypeMethods: false }] },
{ code: "foo = (function(){}).call()()", options: ["all", { enforceForFunctionPrototypeMethods: false }] },
{ code: "foo = (function(){}.call())()", options: ["all", { enforceForFunctionPrototypeMethods: false }] },
{ code: "var foo = { bar: (function(){}.call()) }", options: ["all", { enforceForFunctionPrototypeMethods: false }] },
{ code: "var foo = { [(function(){}.call())]: bar }", options: ["all", { enforceForFunctionPrototypeMethods: false }] },
{ code: "if((function(){}).call()){}", options: ["all", { enforceForFunctionPrototypeMethods: false }] },
{ code: "while((function(){}.apply())){}", options: ["all", { enforceForFunctionPrototypeMethods: false }] },
"let a = [ ...b ]",
"let a = { ...b }",
{
code: "let a = { ...b }",
parserOptions: { ecmaVersion: 2018 }
},
"let a = [ ...(b, c) ]",
"let a = { ...(b, c) }",
{
code: "let a = { ...(b, c) }",
parserOptions: { ecmaVersion: 2018 }
},
"var [x = (1, foo)] = bar",
"class A extends B {}",
"const A = class extends B {}",
"class A extends (B=C) {}",
"const A = class extends (B=C) {}",
"class A extends (++foo) {}",
"() => ({ foo: 1 })",
"() => ({ foo: 1 }).foo",
"() => ({ foo: 1 }.foo().bar).baz.qux()",
"() => ({ foo: 1 }.foo().bar + baz)",
{
code: "export default (a, b)",
parserOptions: { sourceType: "module" }
},
{
code: "export default (function(){}).foo",
parserOptions: { sourceType: "module" }
},
{
code: "export default (class{}).foo",
parserOptions: { sourceType: "module" }
},
"({}).hasOwnProperty.call(foo, bar)",
"({}) ? foo() : bar()",
"({}) + foo",
"(function(){}) + foo",
"(let)\nfoo",
"(let[foo]) = 1", // setting the 'foo' property of the 'let' variable to 1
{
code: "((function(){}).foo.bar)();",
options: ["functions"]
},
{
code: "((function(){}).foo)();",
options: ["functions"]
},
"(let)[foo]",
// ForStatement#init expression cannot start with `let[`. It would be parsed as a `let` declaration with array pattern, or a syntax error.
"for ((let[a]);;);",
"for ((let)[a];;);",
"for ((let[a] = 1);;);",
"for ((let[a]) = 1;;);",
"for ((let)[a] = 1;;);",
"for ((let[a, b] = foo);;);",
"for ((let[a].b = 1);;);",
"for ((let[a].b) = 1;;);",
"for ((let[a]).b = 1;;);",
"for ((let)[a].b = 1;;);",
"for ((let[a])();;);",
"for ((let)[a]();;);",
"for ((let[a]) + b;;);",
// ForInStatement#left expression cannot start with `let[`. It would be parsed as a `let` declaration with array pattern, or a syntax error.
"for ((let[foo]) in bar);",
"for ((let)[foo] in bar);",
"for ((let[foo].bar) in baz);",
"for ((let[foo]).bar in baz);",
"for ((let)[foo].bar in baz);",
// ForOfStatement#left expression cannot start with `let`. It's explicitly forbidden by the specification.
"for ((let) of foo);",
"for ((let).foo of bar);",
"for ((let.foo) of bar);",
"for ((let[foo]) of bar);",
"for ((let)[foo] of bar);",
"for ((let.foo.bar) of baz);",
"for ((let.foo).bar of baz);",
"for ((let).foo.bar of baz);",
"for ((let[foo].bar) of baz);",
"for ((let[foo]).bar of baz);",
"for ((let)[foo].bar of baz);",
"for ((let)().foo of bar);",
"for ((let()).foo of bar);",
"for ((let().foo) of bar);",
// https://github.com/eslint/eslint/issues/11706 (also in invalid[])
"for (let a = (b in c); ;);",
"for (let a = (b && c in d); ;);",
"for (let a = (b in c && d); ;);",
"for (let a = (b => b in c); ;);",
"for (let a = b => (b in c); ;);",
"for (let a = (b in c in d); ;);",
"for (let a = (b in c), d = (e in f); ;);",
"for (let a = (b => c => b in c); ;);",
"for (let a = (b && c && d in e); ;);",
"for (let a = b && (c in d); ;);",
"for (let a = (b in c) && (d in e); ;);",
"for ((a in b); ;);",
"for (a = (b in c); ;);",
"for ((a in b && c in d && e in f); ;);",
"for (let a = [] && (b in c); ;);",
"for (let a = (b in [c]); ;);",
"for (let a = b => (c in d); ;);",
"for (let a = (b in c) ? d : e; ;);",
"for (let a = (b in c ? d : e); ;);",
"for (let a = b ? c : (d in e); ;);",
"for (let a = (b in c), d = () => { for ((e in f);;); for ((g in h);;); }; ;); for((i in j); ;);",
// https://github.com/eslint/eslint/issues/11706 regression tests (also in invalid[])
"for (let a = b; a; a); a; a;",
"for (a; a; a); a; a;",
"for (; a; a); a; a;",
"for (let a = (b && c) === d; ;);",
"new (a()).b.c;",
"new (a().b).c;",
"new (a().b.c);",
"new (a().b().d);",
"new a().b().d;",
"new (a(b()).c)",
"new (a.b()).c",
// Nullish coalescing
{ code: "var v = (a ?? b) || c", parserOptions: { ecmaVersion: 2020 } },
{ code: "var v = a ?? (b || c)", parserOptions: { ecmaVersion: 2020 } },
{ code: "var v = (a ?? b) && c", parserOptions: { ecmaVersion: 2020 } },
{ code: "var v = a ?? (b && c)", parserOptions: { ecmaVersion: 2020 } },
{ code: "var v = (a || b) ?? c", parserOptions: { ecmaVersion: 2020 } },
{ code: "var v = a || (b ?? c)", parserOptions: { ecmaVersion: 2020 } },
{ code: "var v = (a && b) ?? c", parserOptions: { ecmaVersion: 2020 } },
{ code: "var v = a && (b ?? c)", parserOptions: { ecmaVersion: 2020 } },
// Optional chaining
{ code: "var v = (obj?.aaa).bbb", parserOptions: { ecmaVersion: 2020 } },
{ code: "var v = (obj?.aaa)()", parserOptions: { ecmaVersion: 2020 } },
{ code: "var v = new (obj?.aaa)()", parserOptions: { ecmaVersion: 2020 } },
{ code: "var v = new (obj?.aaa)", parserOptions: { ecmaVersion: 2020 } },
{ code: "var v = (obj?.aaa)`template`", parserOptions: { ecmaVersion: 2020 } },
{ code: "var v = (obj?.()).bbb", parserOptions: { ecmaVersion: 2020 } },
{ code: "var v = (obj?.())()", parserOptions: { ecmaVersion: 2020 } },
{ code: "var v = new (obj?.())()", parserOptions: { ecmaVersion: 2020 } },
{ code: "var v = new (obj?.())", parserOptions: { ecmaVersion: 2020 } },
{ code: "var v = (obj?.())`template`", parserOptions: { ecmaVersion: 2020 } },
{ code: "(obj?.aaa).bbb = 0", parserOptions: { ecmaVersion: 2020 } },
{ code: "var foo = (function(){})?.()", parserOptions: { ecmaVersion: 2020 } },
{ code: "var foo = (function(){}?.())", parserOptions: { ecmaVersion: 2020 } },
{
code: "var foo = (function(){})?.call()",
options: ["all", { enforceForFunctionPrototypeMethods: false }],
parserOptions: { ecmaVersion: 2020 }
},
{
code: "var foo = (function(){}?.call())",
options: ["all", { enforceForFunctionPrototypeMethods: false }],
parserOptions: { ecmaVersion: 2020 }
},
{
code: "(Object.prototype.toString.call())",
options: ["functions"]
},
// "allowParensAfterCommentPattern" option
{
code: "const span = /**@type {HTMLSpanElement}*/(event.currentTarget);",
options: ["all", { allowParensAfterCommentPattern: "@type" }]
},
{
code: "if (/** @type {Compiler | MultiCompiler} */(options).hooks) console.log('good');",
options: ["all", { allowParensAfterCommentPattern: "@type" }]
},
{
code: `
validate(/** @type {Schema} */ (schema), options, {
name: "Dev Server",
baseDataPath: "options",
});
`,
options: ["all", { allowParensAfterCommentPattern: "@type" }]
},
{
code: `
if (condition) {
/** @type {ServerOptions} */
(options.server.options).requestCert = false;
}
`,
options: ["all", { allowParensAfterCommentPattern: "@type" }]
},
{
code: "const net = ipaddr.parseCIDR(/** @type {string} */ (cidr));",
options: ["all", { allowParensAfterCommentPattern: "@type" }]
},
// https://github.com/eslint/eslint/issues/16850
"(a) = function () {};",
"(a) = () => {};",
"(a) = class {};",
"(a) ??= function () {};",
"(a) &&= class extends SuperClass {};",
"(a) ||= async () => {}",
{
code: "((a)) = function () {};",
options: ["functions"]
}
],
invalid: [
invalid("(0)", "0", "Literal"),
invalid("( 0 )", " 0 ", "Literal"),
invalid("if((0));", "if(0);", "Literal"),
invalid("if(( 0 ));", "if( 0 );", "Literal"),
invalid("with((0)){}", "with(0){}", "Literal"),
invalid("switch((0)){}", "switch(0){}", "Literal"),
invalid("switch(0){ case (1): break; }", "switch(0){ case 1: break; }", "Literal"),
invalid("for((0);;);", "for(0;;);", "Literal"),
invalid("for(;(0););", "for(;0;);", "Literal"),
invalid("for(;;(0));", "for(;;0);", "Literal"),
invalid("throw(0)", "throw 0", "Literal"),
invalid("while((0));", "while(0);", "Literal"),
invalid("do; while((0))", "do; while(0)", "Literal"),
invalid("for(a in (0));", "for(a in 0);", "Literal"),
invalid("for(a of (0));", "for(a of 0);", "Literal", 1),
invalid("const foo = {[(a)]:1}", "const foo = {[a]:1}", "Identifier", 1),
invalid("const foo = {[(a=b)]:1}", "const foo = {[a=b]:1}", "AssignmentExpression", 1),
invalid("const foo = {*[(Symbol.iterator)]() {}}", "const foo = {*[Symbol.iterator]() {}}", "MemberExpression", 1),
invalid("const foo = { get [(a)]() {}}", "const foo = { get [a]() {}}", "Identifier", 1),
invalid("const foo = {[(a+b)]:c, d}", "const foo = {[a+b]:c, d}", "BinaryExpression", 1),
invalid("const foo = {a, [(b+c)]:d, e}", "const foo = {a, [b+c]:d, e}", "BinaryExpression", 1),
invalid("const foo = {[(a+b)]:c, d:e}", "const foo = {[a+b]:c, d:e}", "BinaryExpression", 1),
invalid("const foo = {a:b, [(c+d)]:e, f:g}", "const foo = {a:b, [c+d]:e, f:g}", "BinaryExpression", 1),
invalid("const foo = {[(a+b)]:c, [d]:e}", "const foo = {[a+b]:c, [d]:e}", "BinaryExpression", 1),
invalid("const foo = {[a]:b, [(c+d)]:e, [f]:g}", "const foo = {[a]:b, [c+d]:e, [f]:g}", "BinaryExpression", 1),
invalid("const foo = {[(a+b)]:c, [(d,e)]:f}", "const foo = {[a+b]:c, [(d,e)]:f}", "BinaryExpression", 1),
invalid("const foo = {[(a,b)]:c, [(d+e)]:f, [(g,h)]:e}", "const foo = {[(a,b)]:c, [d+e]:f, [(g,h)]:e}", "BinaryExpression", 1),
invalid("const foo = {a, b:c, [(d+e)]:f, [(g,h)]:i, [j]:k}", "const foo = {a, b:c, [d+e]:f, [(g,h)]:i, [j]:k}", "BinaryExpression", 1),
invalid("const foo = {[a+(b*c)]:d}", "const foo = {[a+b*c]:d}", "BinaryExpression", 1),
invalid("const foo = {[(a, (b+c))]:d}", "const foo = {[(a, b+c)]:d}", "BinaryExpression", 1),
invalid("const {[(a)]:b} = {}", "const {[a]:b} = {}", "Identifier", 1),
invalid("const {[(a=b)]:c=1} = {}", "const {[a=b]:c=1} = {}", "AssignmentExpression", 1),
invalid("const {[(a+b)]:c, d} = {}", "const {[a+b]:c, d} = {}", "BinaryExpression", 1),
invalid("const {a, [(b+c)]:d, e} = {}", "const {a, [b+c]:d, e} = {}", "BinaryExpression", 1),
invalid("const {[(a+b)]:c, d:e} = {}", "const {[a+b]:c, d:e} = {}", "BinaryExpression", 1),
invalid("const {a:b, [(c+d)]:e, f:g} = {}", "const {a:b, [c+d]:e, f:g} = {}", "BinaryExpression", 1),
invalid("const {[(a+b)]:c, [d]:e} = {}", "const {[a+b]:c, [d]:e} = {}", "BinaryExpression", 1),
invalid("const {[a]:b, [(c+d)]:e, [f]:g} = {}", "const {[a]:b, [c+d]:e, [f]:g} = {}", "BinaryExpression", 1),
invalid("const {[(a+b)]:c, [(d,e)]:f} = {}", "const {[a+b]:c, [(d,e)]:f} = {}", "BinaryExpression", 1),
invalid("const {[(a,b)]:c, [(d+e)]:f, [(g,h)]:e} = {}", "const {[(a,b)]:c, [d+e]:f, [(g,h)]:e} = {}", "BinaryExpression", 1),
invalid("const {a, b:c, [(d+e)]:f, [(g,h)]:i, [j]:k} = {}", "const {a, b:c, [d+e]:f, [(g,h)]:i, [j]:k} = {}", "BinaryExpression", 1),
invalid("const {[a+(b*c)]:d} = {}", "const {[a+b*c]:d} = {}", "BinaryExpression", 1),
invalid("const {[(a, (b+c))]:d} = {}", "const {[(a, b+c)]:d} = {}", "BinaryExpression", 1),
invalid("class foo { [(a)](){} }", "class foo { [a](){} }", "Identifier"),
invalid("class foo {*[(Symbol.iterator)]() {}}", "class foo {*[Symbol.iterator]() {}}", "MemberExpression"),
invalid("class foo { get [(a)](){} }", "class foo { get [a](){} }", "Identifier"),
invalid("class foo { set [(a)](bar){} }", "class foo { set [a](bar){} }", "Identifier"),
invalid("class foo { static [(a)](bar){} }", "class foo { static [a](bar){} }", "Identifier"),
invalid("class foo { [(a=b)](){} }", "class foo { [a=b](){} }", "AssignmentExpression"),
invalid("class foo { constructor (){} [(a+b)](){} }", "class foo { constructor (){} [a+b](){} }", "BinaryExpression"),
invalid("class foo { [(a+b)](){} constructor (){} }", "class foo { [a+b](){} constructor (){} }", "BinaryExpression"),
invalid("class foo { [(a+b)](){} c(){} }", "class foo { [a+b](){} c(){} }", "BinaryExpression"),
invalid("class foo { a(){} [(b+c)](){} d(){} }", "class foo { a(){} [b+c](){} d(){} }", "BinaryExpression"),
invalid("class foo { [(a+b)](){} [c](){} }", "class foo { [a+b](){} [c](){} }", "BinaryExpression"),
invalid("class foo { [a](){} [(b+c)](){} [d](){} }", "class foo { [a](){} [b+c](){} [d](){} }", "BinaryExpression"),
invalid("class foo { [(a+b)](){} [(c,d)](){} }", "class foo { [a+b](){} [(c,d)](){} }", "BinaryExpression"),
invalid("class foo { [(a,b)](){} [(c+d)](){} }", "class foo { [(a,b)](){} [c+d](){} }", "BinaryExpression"),
invalid("class foo { [a+(b*c)](){} }", "class foo { [a+b*c](){} }", "BinaryExpression"),
invalid("const foo = class { [(a)](){} }", "const foo = class { [a](){} }", "Identifier"),
invalid("class foo { [(x)]; }", "class foo { [x]; }", "Identifier"),
invalid("class foo { static [(x)]; }", "class foo { static [x]; }", "Identifier"),
invalid("class foo { [(x)] = 1; }", "class foo { [x] = 1; }", "Identifier"),
invalid("class foo { static [(x)] = 1; }", "class foo { static [x] = 1; }", "Identifier"),
invalid("const foo = class { [(x)]; }", "const foo = class { [x]; }", "Identifier"),
invalid("class foo { [(x = y)]; }", "class foo { [x = y]; }", "AssignmentExpression"),
invalid("class foo { [(x + y)]; }", "class foo { [x + y]; }", "BinaryExpression"),
invalid("class foo { [(x ? y : z)]; }", "class foo { [x ? y : z]; }", "ConditionalExpression"),
invalid("class foo { [((x, y))]; }", "class foo { [(x, y)]; }", "SequenceExpression"),
invalid("class foo { x = (y); }", "class foo { x = y; }", "Identifier"),
invalid("class foo { static x = (y); }", "class foo { static x = y; }", "Identifier"),
invalid("class foo { #x = (y); }", "class foo { #x = y; }", "Identifier"),
invalid("class foo { static #x = (y); }", "class foo { static #x = y; }", "Identifier"),
invalid("const foo = class { x = (y); }", "const foo = class { x = y; }", "Identifier"),
invalid("class foo { x = (() => {}); }", "class foo { x = () => {}; }", "ArrowFunctionExpression"),
invalid("class foo { x = (y + z); }", "class foo { x = y + z; }", "BinaryExpression"),
invalid("class foo { x = (y ? z : q); }", "class foo { x = y ? z : q; }", "ConditionalExpression"),
invalid("class foo { x = ((y, z)); }", "class foo { x = (y, z); }", "SequenceExpression"),
//
invalid(
"var foo = (function*() { if ((yield foo())) { return; } }())",
"var foo = (function*() { if (yield foo()) { return; } }())",
"YieldExpression",
1
),
invalid("f((0))", "f(0)", "Literal"),
invalid("f(0, (1))", "f(0, 1)", "Literal"),
invalid("!(0)", "!0", "Literal"),
invalid("a[(1)]", "a[1]", "Literal"),
invalid("(a)(b)", "a(b)", "Identifier"),
invalid("(async)", "async", "Identifier"),
invalid("(a, b)", "a, b", "SequenceExpression"),
invalid("var a = (b = c);", "var a = b = c;", "AssignmentExpression"),
invalid("function f(){ return (a); }", "function f(){ return a; }", "Identifier"),
invalid("[a, (b = c)]", "[a, b = c]", "AssignmentExpression"),
invalid("!{a: (b = c)}", "!{a: b = c}", "AssignmentExpression"),
invalid("typeof(0)", "typeof 0", "Literal"),
invalid("typeof (0)", "typeof 0", "Literal"),
invalid("typeof([])", "typeof[]", "ArrayExpression"),
invalid("typeof ([])", "typeof []", "ArrayExpression"),
invalid("typeof( 0)", "typeof 0", "Literal"),
invalid("typeof(typeof 5)", "typeof typeof 5", "UnaryExpression"),
invalid("typeof (typeof 5)", "typeof typeof 5", "UnaryExpression"),
invalid("+(+foo)", "+ +foo", "UnaryExpression"),
invalid("-(-foo)", "- -foo", "UnaryExpression"),
invalid("+(-foo)", "+-foo", "UnaryExpression"),
invalid("-(+foo)", "-+foo", "UnaryExpression"),
invalid("-((bar+foo))", "-(bar+foo)", "BinaryExpression"),
invalid("+((bar-foo))", "+(bar-foo)", "BinaryExpression"),
invalid("++(foo)", "++foo", "Identifier"),
invalid("--(foo)", "--foo", "Identifier"),
invalid("++\n(foo)", "++\nfoo", "Identifier"),
invalid("--\n(foo)", "--\nfoo", "Identifier"),
invalid("++(\nfoo)", "++\nfoo", "Identifier"),
invalid("--(\nfoo)", "--\nfoo", "Identifier"),
invalid("(foo)++", "foo++", "Identifier"),
invalid("(foo)--", "foo--", "Identifier"),
invalid("((foo)\n)++", "(foo\n)++", "Identifier"),
invalid("((foo\n))--", "(foo\n)--", "Identifier"),
invalid("((foo\n)\n)++", "(foo\n\n)++", "Identifier"),
invalid("(a\n.b)--", "a\n.b--", "MemberExpression"),
invalid("(a.\nb)++", "a.\nb++", "MemberExpression"),
invalid("(a\n[\nb\n])--", "a\n[\nb\n]--", "MemberExpression"),
invalid("(a || b) ? c : d", "a || b ? c : d", "LogicalExpression"),
invalid("a ? (b = c) : d", "a ? b = c : d", "AssignmentExpression"),
invalid("a ? b : (c = d)", "a ? b : c = d", "AssignmentExpression"),
invalid("(c = d) ? (b) : c", "(c = d) ? b : c", "Identifier", null, { options: ["all", { conditionalAssign: false }] }),
invalid("(c = d) ? b : (c)", "(c = d) ? b : c", "Identifier", null, { options: ["all", { conditionalAssign: false }] }),
invalid("f((a = b))", "f(a = b)", "AssignmentExpression"),
invalid("a, (b = c)", "a, b = c", "AssignmentExpression"),
invalid("a = (b * c)", "a = b * c", "BinaryExpression"),
invalid("a + (b * c)", "a + b * c", "BinaryExpression"),
invalid("(a * b) + c", "a * b + c", "BinaryExpression"),
invalid("(a * b) / c", "a * b / c", "BinaryExpression"),
invalid("(2) ** 3 ** 4", "2 ** 3 ** 4", "Literal", null),
invalid("2 ** (3 ** 4)", "2 ** 3 ** 4", "BinaryExpression", null),
invalid("(2 ** 3)", "2 ** 3", "BinaryExpression", null),
invalid("(2 ** 3) + 1", "2 ** 3 + 1", "BinaryExpression", null),
invalid("1 - (2 ** 3)", "1 - 2 ** 3", "BinaryExpression", null),
invalid("-((2 ** 3))", "-(2 ** 3)", "BinaryExpression", null),
invalid("typeof ((a ** b));", "typeof (a ** b);", "BinaryExpression", null),
invalid("((-2)) ** 3", "(-2) ** 3", "UnaryExpression", null),
invalid("a = (b * c)", "a = b * c", "BinaryExpression", null, { options: ["all", { nestedBinaryExpressions: false }] }),
invalid("(b * c)", "b * c", "BinaryExpression", null, { options: ["all", { nestedBinaryExpressions: false }] }),
invalid("a = (b = c)", "a = b = c", "AssignmentExpression"),
invalid("(a).b", "a.b", "Identifier"),
invalid("(0)[a]", "0[a]", "Literal"),
invalid("(0.0).a", "0.0.a", "Literal"),
invalid("(123.4).a", "123.4.a", "Literal"),
invalid("(0.0_0).a", "0.0_0.a", "Literal"),
invalid("(0xBEEF).a", "0xBEEF.a", "Literal"),
invalid("(0xBE_EF).a", "0xBE_EF.a", "Literal"),
invalid("(1e6).a", "1e6.a", "Literal"),
invalid("(0123).a", "0123.a", "Literal"),
invalid("(08.1).a", "08.1.a", "Literal"),
invalid("(09.).a", "09..a", "Literal"),
invalid("a[(function() {})]", "a[function() {}]", "FunctionExpression"),
invalid("new (function(){})", "new function(){}", "FunctionExpression"),
invalid("new (\nfunction(){}\n)", "new \nfunction(){}\n", "FunctionExpression", 1),
invalid("((function foo() {return 1;}))()", "(function foo() {return 1;})()", "FunctionExpression"),
invalid("((function(){ return bar(); })())", "(function(){ return bar(); })()", "CallExpression"),
invalid("(foo()).bar", "foo().bar", "CallExpression"),
invalid("(foo.bar()).baz", "foo.bar().baz", "CallExpression"),
invalid("(foo\n.bar())\n.baz", "foo\n.bar()\n.baz", "CallExpression"),
invalid("(new foo()).bar", "new foo().bar", "NewExpression"),
invalid("(new foo())[bar]", "new foo()[bar]", "NewExpression"),
invalid("(new foo()).bar()", "new foo().bar()", "NewExpression"),
invalid("(new foo(bar)).baz", "new foo(bar).baz", "NewExpression"),
invalid("(new foo.bar()).baz", "new foo.bar().baz", "NewExpression"),
invalid("(new foo.bar()).baz()", "new foo.bar().baz()", "NewExpression"),
invalid("new a[(b()).c]", "new a[b().c]", "CallExpression"),
invalid("(a)()", "a()", "Identifier"),
invalid("(a.b)()", "a.b()", "MemberExpression"),
invalid("(a())()", "a()()", "CallExpression"),
invalid("(a.b())()", "a.b()()", "CallExpression"),
invalid("(a().b)()", "a().b()", "MemberExpression"),
invalid("(a().b.c)()", "a().b.c()", "MemberExpression"),
invalid("new (A)", "new A", "Identifier"),
invalid("(new A())()", "new A()()", "NewExpression"),
invalid("(new A(1))()", "new A(1)()", "NewExpression"),
invalid("((new A))()", "(new A)()", "NewExpression"),
invalid("new (foo\n.baz\n.bar\n.foo.baz)", "new foo\n.baz\n.bar\n.foo.baz", "MemberExpression"),
invalid("new (foo.baz.bar.baz)", "new foo.baz.bar.baz", "MemberExpression"),
invalid("new ((a.b())).c", "new (a.b()).c", "CallExpression"),
invalid("new ((a().b)).c", "new (a().b).c", "MemberExpression"),
invalid("new ((a().b().d))", "new (a().b().d)", "MemberExpression"),
invalid("new ((a())).b.d", "new (a()).b.d", "CallExpression"),
invalid("new (a.b).d;", "new a.b.d;", "MemberExpression"),
invalid("new (new A())();", "new new A()();", "NewExpression"),
invalid("new (new A());", "new new A();", "NewExpression"),
invalid("new (new A);", "new new A;", "NewExpression"),
invalid("new (new a.b);", "new new a.b;", "NewExpression"),
invalid("(a().b).d;", "a().b.d;", "MemberExpression"),
invalid("(a.b()).d;", "a.b().d;", "CallExpression"),
invalid("(a.b).d;", "a.b.d;", "MemberExpression"),
invalid("0, (_ => 0)", "0, _ => 0", "ArrowFunctionExpression", 1),
invalid("(_ => 0), 0", "_ => 0, 0", "ArrowFunctionExpression", 1),
invalid("a = (_ => 0)", "a = _ => 0", "ArrowFunctionExpression", 1),
invalid("_ => (a = 0)", "_ => a = 0", "AssignmentExpression", 1),
invalid("x => (({}))", "x => ({})", "ObjectExpression", 1),
invalid("new (function(){})", "new function(){}", "FunctionExpression", null, { options: ["functions"] }),
invalid("new (\nfunction(){}\n)", "new \nfunction(){}\n", "FunctionExpression", 1, { options: ["functions"] }),
invalid("((function foo() {return 1;}))()", "(function foo() {return 1;})()", "FunctionExpression", null, { options: ["functions"] }),
invalid("a[(function() {})]", "a[function() {}]", "FunctionExpression", null, { options: ["functions"] }),
invalid("0, (_ => 0)", "0, _ => 0", "ArrowFunctionExpression", 1, { options: ["functions"] }),
invalid("(_ => 0), 0", "_ => 0, 0", "ArrowFunctionExpression", 1, { options: ["functions"] }),
invalid("a = (_ => 0)", "a = _ => 0", "ArrowFunctionExpression", 1, { options: ["functions"] }),
invalid("while ((foo = bar())) {}", "while (foo = bar()) {}", "AssignmentExpression"),
invalid("while ((foo = bar())) {}", "while (foo = bar()) {}", "AssignmentExpression", 1, { options: ["all", { conditionalAssign: true }] }),
invalid("if ((foo = bar())) {}", "if (foo = bar()) {}", "AssignmentExpression"),
invalid("do; while ((foo = bar()))", "do; while (foo = bar())", "AssignmentExpression"),
invalid("for (;(a = b););", "for (;a = b;);", "AssignmentExpression"),
// https://github.com/eslint/eslint/issues/3653
invalid("((function(){})).foo();", "(function(){}).foo();", "FunctionExpression"),
invalid("((function(){}).foo());", "(function(){}).foo();", "CallExpression"),
invalid("((function(){}).foo);", "(function(){}).foo;", "MemberExpression"),
invalid("0, (function(){}).foo();", "0, function(){}.foo();", "FunctionExpression"),
invalid("void (function(){}).foo();", "void function(){}.foo();", "FunctionExpression"),
invalid("++(function(){}).foo;", "++function(){}.foo;", "FunctionExpression"),
invalid("bar || (function(){}).foo();", "bar || function(){}.foo();", "FunctionExpression"),
invalid("1 + (function(){}).foo();", "1 + function(){}.foo();", "FunctionExpression"),
invalid("bar ? (function(){}).foo() : baz;", "bar ? function(){}.foo() : baz;", "FunctionExpression"),
invalid("bar ? baz : (function(){}).foo();", "bar ? baz : function(){}.foo();", "FunctionExpression"),
invalid("bar((function(){}).foo(), 0);", "bar(function(){}.foo(), 0);", "FunctionExpression"),
invalid("bar[(function(){}).foo()];", "bar[function(){}.foo()];", "FunctionExpression"),
invalid("var bar = (function(){}).foo();", "var bar = function(){}.foo();", "FunctionExpression"),
invalid("((class{})).foo();", "(class{}).foo();", "ClassExpression", null),
invalid("((class{}).foo());", "(class{}).foo();", "CallExpression", null),
invalid("((class{}).foo);", "(class{}).foo;", "MemberExpression", null),
invalid("0, (class{}).foo();", "0, class{}.foo();", "ClassExpression", null),
invalid("void (class{}).foo();", "void class{}.foo();", "ClassExpression", null),
invalid("++(class{}).foo;", "++class{}.foo;", "ClassExpression", null),
invalid("bar || (class{}).foo();", "bar || class{}.foo();", "ClassExpression", null),
invalid("1 + (class{}).foo();", "1 + class{}.foo();", "ClassExpression", null),
invalid("bar ? (class{}).foo() : baz;", "bar ? class{}.foo() : baz;", "ClassExpression", null),
invalid("bar ? baz : (class{}).foo();", "bar ? baz : class{}.foo();", "ClassExpression", null),
invalid("bar((class{}).foo(), 0);", "bar(class{}.foo(), 0);", "ClassExpression", null),
invalid("bar[(class{}).foo()];", "bar[class{}.foo()];", "ClassExpression", null),
invalid("var bar = (class{}).foo();", "var bar = class{}.foo();", "ClassExpression", null),
invalid("var foo = ((bar, baz));", "var foo = (bar, baz);", "SequenceExpression", null),
// https://github.com/eslint/eslint/issues/4608
invalid("function *a() { yield (b); }", "function *a() { yield b; }", "Identifier", null),
invalid("function *a() { (yield b), c; }", "function *a() { yield b, c; }", "YieldExpression", null),
invalid("function *a() { yield ((b, c)); }", "function *a() { yield (b, c); }", "SequenceExpression", null),
invalid("function *a() { yield (b + c); }", "function *a() { yield b + c; }", "BinaryExpression", null),
// https://github.com/eslint/eslint/issues/4229
invalid([
"function a() {",
" return (b);",
"}"
].join("\n"), [
"function a() {",
" return b;",
"}"
].join("\n"), "Identifier"),
invalid([
"function a() {",
" return",
" (b);",
"}"
].join("\n"), [
"function a() {",
" return",
" b;",
"}"
].join("\n"), "Identifier"),
invalid([
"function a() {",
" return ((",
" b",
" ));",
"}"
].join("\n"), [
"function a() {",
" return (",
" b",
" );",
"}"
].join("\n"), "Identifier"),
invalid([
"function a() {",
" return (<JSX />);",
"}"
].join("\n"), [
"function a() {",
" return <JSX />;",
"}"
].join("\n"), "JSXElement", null),
invalid([
"function a() {",
" return",
" (<JSX />);",
"}"
].join("\n"), [
"function a() {",
" return",
" <JSX />;",
"}"
].join("\n"), "JSXElement", null),
invalid([
"function a() {",
" return ((",
" <JSX />",
" ));",
"}"
].join("\n"), [
"function a() {",
" return (",
" <JSX />",
" );",
"}"
].join("\n"), "JSXElement", null),
invalid([
"function a() {",
" return ((",
" <></>",
" ));",
"}"
].join("\n"), [
"function a() {",
" return (",
" <></>",
" );",
"}"
].join("\n"), "JSXFragment", null),
invalid("throw (a);", "throw a;", "Identifier"),
invalid([
"throw ((",
" a",
"));"
].join("\n"), [
"throw (",
" a",
");"
].join("\n"), "Identifier"),
invalid([
"function *a() {",
" yield (b);",
"}"
].join("\n"), [
"function *a() {",
" yield b;",
"}"
].join("\n"), "Identifier", null),
invalid([
"function *a() {",
" yield",
" (b);",
"}"
].join("\n"), [
"function *a() {",
" yield",
" b;",
"}"
].join("\n"), "Identifier", null),
invalid([
"function *a() {",
" yield ((",
" b",
" ));",
"}"
].join("\n"), [
"function *a() {",
" yield (",
" b",
" );",
"}"
].join("\n"), "Identifier", null),
// returnAssign option
{
code: "function a(b) { return (b || c); }",
output: "function a(b) { return b || c; }",
options: ["all", { returnAssign: false }],
errors: [
{
messageId: "unexpected",
type: "LogicalExpression"
}
]
},
{
code: "function a(b) { return ((b = c) || (d = e)); }",
output: "function a(b) { return (b = c) || (d = e); }",
errors: [
{
messageId: "unexpected",
type: "LogicalExpression"
}
]
},
{
code: "function a(b) { return (b = 1); }",
output: "function a(b) { return b = 1; }",
errors: [
{
messageId: "unexpected",
type: "AssignmentExpression"
}
]
},
{
code: "function a(b) { return c ? (d = b) : (e = b); }",
output: "function a(b) { return c ? d = b : e = b; }",
errors: [
{
messageId: "unexpected",
type: "AssignmentExpression"
},
{
messageId: "unexpected",
type: "AssignmentExpression"
}
]
},
{
code: "b => (b || c);",
output: "b => b || c;",
options: ["all", { returnAssign: false }],
errors: [
{
messageId: "unexpected",
type: "LogicalExpression"
}
]
},
{
code: "b => ((b = c) || (d = e));",
output: "b => (b = c) || (d = e);",
errors: [
{
messageId: "unexpected",
type: "LogicalExpression"
}
]
},
{
code: "b => (b = 1);",
output: "b => b = 1;",
errors: [
{
messageId: "unexpected",
type: "AssignmentExpression"
}
]
},
{
code: "b => c ? (d = b) : (e = b);",
output: "b => c ? d = b : e = b;",
errors: [
{
messageId: "unexpected",
type: "AssignmentExpression"
},
{
messageId: "unexpected",
type: "AssignmentExpression"
}
]
},
{
code: "b => { return (b || c); }",
output: "b => { return b || c; }",
options: ["all", { returnAssign: false }],
errors: [
{
messageId: "unexpected",
type: "LogicalExpression"
}
]
},
{
code: "b => { return ((b = c) || (d = e)) };",
output: "b => { return (b = c) || (d = e) };",
errors: [
{
messageId: "unexpected",
type: "LogicalExpression"
}
]
},
{
code: "b => { return (b = 1) };",
output: "b => { return b = 1 };",
errors: [
{
messageId: "unexpected",
type: "AssignmentExpression"
}
]
},
{
code: "b => { return c ? (d = b) : (e = b); }",
output: "b => { return c ? d = b : e = b; }",
errors: [
{
messageId: "unexpected",
type: "AssignmentExpression"
},
{
messageId: "unexpected",
type: "AssignmentExpression"
}
]
},
// async/await
{
code: "async function a() { (await a) + (await b); }",
output: "async function a() { await a + await b; }",
errors: [
{
messageId: "unexpected",
type: "AwaitExpression"
},
{
messageId: "unexpected",
type: "AwaitExpression"
}
]
},
invalid("async function a() { await (a); }", "async function a() { await a; }", "Identifier", null),
invalid("async function a() { await (a()); }", "async function a() { await a(); }", "CallExpression", null),
invalid("async function a() { await (+a); }", "async function a() { await +a; }", "UnaryExpression", null),
invalid("async function a() { +(await a); }", "async function a() { +await a; }", "AwaitExpression", null),
invalid("async function a() { await ((a,b)); }", "async function a() { await (a,b); }", "SequenceExpression", null),
invalid("async function a() { a ** (await b); }", "async function a() { a ** await b; }", "AwaitExpression", null),
invalid("(foo) instanceof bar", "foo instanceof bar", "Identifier", 1, { options: ["all", { nestedBinaryExpressions: false }] }),
invalid("(foo) in bar", "foo in bar", "Identifier", 1, { options: ["all", { nestedBinaryExpressions: false }] }),
invalid("(foo) + bar", "foo + bar", "Identifier", 1, { options: ["all", { nestedBinaryExpressions: false }] }),
invalid("(foo) && bar", "foo && bar", "Identifier", 1, { options: ["all", { nestedBinaryExpressions: false }] }),
invalid("foo instanceof (bar)", "foo instanceof bar", "Identifier", 1, { options: ["all", { nestedBinaryExpressions: false }] }),
invalid("foo in (bar)", "foo in bar", "Identifier", 1, { options: ["all", { nestedBinaryExpressions: false }] }),
invalid("foo + (bar)", "foo + bar", "Identifier", 1, { options: ["all", { nestedBinaryExpressions: false }] }),
invalid("foo && (bar)", "foo && bar", "Identifier", 1, { options: ["all", { nestedBinaryExpressions: false }] }),
// ["all", { ignoreJSX: "multi-line" }]
invalid("const Component = (<div />);", "const Component = <div />;", "JSXElement", 1, {
options: ["all", { ignoreJSX: "multi-line" }]
}),
invalid([
"const Component = (",
" <div />",
");"
].join("\n"), "const Component = \n <div />\n;", "JSXElement", 1, {
options: ["all", { ignoreJSX: "multi-line" }]
}),
invalid([
"const Component = (",
" <></>",
");"
].join("\n"), "const Component = \n <></>\n;", "JSXFragment", 1, {
options: ["all", { ignoreJSX: "multi-line" }]
}),
// ["all", { ignoreJSX: "single-line" }]
invalid([
"const Component = (",
"<div>",
" <p />",
"</div>",
");"
].join("\n"), "const Component = \n<div>\n <p />\n</div>\n;", "JSXElement", 1, {
options: ["all", { ignoreJSX: "single-line" }]
}),
invalid([
"const Component = (<div>",
" <p />",
"</div>);"
].join("\n"), "const Component = <div>\n <p />\n</div>;", "JSXElement", 1, {
options: ["all", { ignoreJSX: "single-line" }]
}),
invalid([
"const Component = (<div",
" prop={true}",
"/>)"
].join("\n"), "const Component = <div\n prop={true}\n/>", "JSXElement", 1, {
options: ["all", { ignoreJSX: "single-line" }]
}),
// ["all", { ignoreJSX: "none" }] default, same as unspecified
invalid("const Component = (<div />);", "const Component = <div />;", "JSXElement", 1, {
options: ["all", { ignoreJSX: "none" }]
}),
invalid([
"const Component = (<div>",
"<p />",
"</div>)"
].join("\n"), "const Component = <div>\n<p />\n</div>", "JSXElement", 1, {
options: ["all", { ignoreJSX: "none" }]
}),
// ["all", { enforceForArrowConditionals: true }]
{
code: "var a = (b) => (1 ? 2 : 3)",
output: "var a = (b) => 1 ? 2 : 3",
options: ["all", { enforceForArrowConditionals: true }],
errors: [
{
messageId: "unexpected"
}
]
},
{
code: "var a = (b) => ((1 ? 2 : 3))",
output: "var a = (b) => (1 ? 2 : 3)",
options: ["all", { enforceForArrowConditionals: true }],
errors: [
{
messageId: "unexpected"
}
]
},
// ["all", { enforceForSequenceExpressions: true }]
{
code: "(a, b)",
output: "a, b",
options: ["all"],
errors: [
{
messageId: "unexpected",
type: "SequenceExpression"
}
]
},
{
code: "(a, b)",
output: "a, b",
options: ["all", {}],
errors: [
{
messageId: "unexpected",
type: "SequenceExpression"
}
]
},
{
code: "(a, b)",
output: "a, b",
options: ["all", { enforceForSequenceExpressions: true }],
errors: [
{
messageId: "unexpected",
type: "SequenceExpression"
}
]
},
{
code: "(foo(), bar());",
output: "foo(), bar();",
options: ["all", { enforceForSequenceExpressions: true }],
errors: [
{
messageId: "unexpected",
type: "SequenceExpression"
}
]
},
{
code: "if((a, b)){}",
output: "if(a, b){}",
options: ["all", { enforceForSequenceExpressions: true }],
errors: [
{
messageId: "unexpected",
type: "SequenceExpression"
}
]
},
{
code: "while ((val = foo(), val < 10));",
output: "while (val = foo(), val < 10);",
options: ["all", { enforceForSequenceExpressions: true }],
errors: [
{
messageId: "unexpected",
type: "SequenceExpression"
}
]
},
// ["all", { enforceForNewInMemberExpressions: true }]
{
code: "(new foo()).bar",
output: "new foo().bar",
options: ["all"],
errors: [
{
messageId: "unexpected",
type: "NewExpression"
}
]
},
{
code: "(new foo()).bar",
output: "new foo().bar",
options: ["all", {}],
errors: [
{
messageId: "unexpected",
type: "NewExpression"
}
]
},
{
code: "(new foo()).bar",
output: "new foo().bar",
options: ["all", { enforceForNewInMemberExpressions: true }],
errors: [
{
messageId: "unexpected",
type: "NewExpression"
}
]
},
{
code: "(new foo())[bar]",
output: "new foo()[bar]",
options: ["all", { enforceForNewInMemberExpressions: true }],
errors: [
{
messageId: "unexpected",
type: "NewExpression"
}
]
},
{
code: "(new foo.bar()).baz",
output: "new foo.bar().baz",
options: ["all", { enforceForNewInMemberExpressions: true }],
errors: [
{
messageId: "unexpected",
type: "NewExpression"
}
]
},
// enforceForFunctionPrototypeMethods
{
code: "var foo = (function(){}).call()",
output: "var foo = function(){}.call()",
options: ["all"],
errors: [
{
messageId: "unexpected",
type: "FunctionExpression"
}
]
},
{
code: "var foo = (function(){}.apply())",
output: "var foo = function(){}.apply()",
options: ["all"],
errors: [
{
messageId: "unexpected",
type: "CallExpression"
}
]
},
{
code: "var foo = (function(){}).apply()",
output: "var foo = function(){}.apply()",
options: ["all", {}],
errors: [
{
messageId: "unexpected",
type: "FunctionExpression"
}
]
},
{
code: "var foo = (function(){}.call())",
output: "var foo = function(){}.call()",
options: ["all", {}],
errors: [
{
messageId: "unexpected",
type: "CallExpression"
}
]
},
{
code: "var foo = (function(){}).call()",
output: "var foo = function(){}.call()",
options: ["all", { enforceForFunctionPrototypeMethods: true }],
errors: [
{
messageId: "unexpected",
type: "FunctionExpression"
}
]
},
{
code: "var foo = (function(){}).apply()",
output: "var foo = function(){}.apply()",
options: ["all", { enforceForFunctionPrototypeMethods: true }],
errors: [
{
messageId: "unexpected",
type: "FunctionExpression"
}
]
},
{
code: "var foo = (function(){}.call())",
output: "var foo = function(){}.call()",
options: ["all", { enforceForFunctionPrototypeMethods: true }],
errors: [
{
messageId: "unexpected",
type: "CallExpression"
}
]
},
{
code: "var foo = (function(){}.apply())",
output: "var foo = function(){}.apply()",
options: ["all", { enforceForFunctionPrototypeMethods: true }],
errors: [
{
messageId: "unexpected",
type: "CallExpression"
}
]
},
{
code: "var foo = (function(){}.call)()", // removing these parens does not cause any conflicts with wrap-iife
output: "var foo = function(){}.call()",
options: ["all", { enforceForFunctionPrototypeMethods: false }],
errors: [
{
messageId: "unexpected",
type: "MemberExpression"
}
]
},
{
code: "var foo = (function(){}.apply)()", // removing these parens does not cause any conflicts with wrap-iife
output: "var foo = function(){}.apply()",
options: ["all", { enforceForFunctionPrototypeMethods: false }],
errors: [
{
messageId: "unexpected",
type: "MemberExpression"
}
]
},
{
code: "var foo = (function(){}).call",
output: "var foo = function(){}.call",
options: ["all", { enforceForFunctionPrototypeMethods: false }],
errors: [
{
messageId: "unexpected",
type: "FunctionExpression"
}
]
},
{
code: "var foo = (function(){}.call)",
output: "var foo = function(){}.call",
options: ["all", { enforceForFunctionPrototypeMethods: false }],
errors: [
{
messageId: "unexpected",
type: "MemberExpression"
}
]
},
{
code: "var foo = new (function(){}).call()",
output: "var foo = new function(){}.call()",
options: ["all", { enforceForFunctionPrototypeMethods: false }],
errors: [
{
messageId: "unexpected",
type: "FunctionExpression"
}
]
},
{
code: "var foo = (new function(){}.call())",
output: "var foo = new function(){}.call()",
options: ["all", { enforceForFunctionPrototypeMethods: false }],
errors: [
{
messageId: "unexpected",
type: "NewExpression"
}
]
},
{
code: "var foo = (function(){})[call]()",
output: "var foo = function(){}[call]()",
options: ["all", { enforceForFunctionPrototypeMethods: false }],
errors: [
{
messageId: "unexpected",
type: "FunctionExpression"
}
]
},
{
code: "var foo = (function(){}[apply]())",
output: "var foo = function(){}[apply]()",
options: ["all", { enforceForFunctionPrototypeMethods: false }],
errors: [
{
messageId: "unexpected",
type: "CallExpression"
}
]
},
{
code: "var foo = (function(){}).bar()",
output: "var foo = function(){}.bar()",
options: ["all", { enforceForFunctionPrototypeMethods: false }],
errors: [
{
messageId: "unexpected",
type: "FunctionExpression"
}
]
},
{
code: "var foo = (function(){}.bar())",
output: "var foo = function(){}.bar()",
options: ["all", { enforceForFunctionPrototypeMethods: false }],
errors: [
{
messageId: "unexpected",
type: "CallExpression"
}
]
},
{
code: "var foo = (function(){}).call.call()",
output: "var foo = function(){}.call.call()",
options: ["all", { enforceForFunctionPrototypeMethods: false }],
errors: [
{
messageId: "unexpected",
type: "FunctionExpression"
}
]
},
{
code: "var foo = (function(){}.call.call())",
output: "var foo = function(){}.call.call()",
options: ["all", { enforceForFunctionPrototypeMethods: false }],
errors: [
{
messageId: "unexpected",
type: "CallExpression"
}
]
},
{
code: "var foo = (call())",
output: "var foo = call()",
options: ["all", { enforceForFunctionPrototypeMethods: false }],
errors: [
{
messageId: "unexpected",
type: "CallExpression"
}
]
},
{
code: "var foo = (apply())",
output: "var foo = apply()",
options: ["all", { enforceForFunctionPrototypeMethods: false }],
errors: [
{
messageId: "unexpected",
type: "CallExpression"
}
]
},
{
code: "var foo = (bar).call()",
output: "var foo = bar.call()",
options: ["all", { enforceForFunctionPrototypeMethods: false }],
errors: [
{
messageId: "unexpected",
type: "Identifier"
}
]
},
{
code: "var foo = (bar.call())",
output: "var foo = bar.call()",
options: ["all", { enforceForFunctionPrototypeMethods: false }],
errors: [
{
messageId: "unexpected",
type: "CallExpression"
}
]
},
{
code: "((() => {}).call())",
output: "(() => {}).call()",
options: ["all", { enforceForFunctionPrototypeMethods: false }],
errors: [
{
messageId: "unexpected",
type: "CallExpression"
}
]
},
{
code: "var foo = function(){}.call((a.b))",
output: "var foo = function(){}.call(a.b)",
options: ["all", { enforceForFunctionPrototypeMethods: false }],
errors: [
{
messageId: "unexpected",
type: "MemberExpression"
}
]
},
{
code: "var foo = function(){}.call((a).b)",
output: "var foo = function(){}.call(a.b)",
options: ["all", { enforceForFunctionPrototypeMethods: false }],
errors: [
{
messageId: "unexpected",
type: "Identifier"
}
]
},
{
code: "var foo = function(){}[('call')]()",
output: "var foo = function(){}['call']()",
options: ["all", { enforceForFunctionPrototypeMethods: false }],
errors: [
{
messageId: "unexpected",
type: "Literal"
}
]
},
// https://github.com/eslint/eslint/issues/8175
invalid(
"let a = [...(b)]",
"let a = [...b]",
"Identifier",
1
),
invalid(
"let a = {...(b)}",
"let a = {...b}",
"Identifier",
1
),
invalid(
"let a = {...(b)}",
"let a = {...b}",
"Identifier",
1,
{ parserOptions: { ecmaVersion: 2018 } }
),
invalid(
"let a = [...((b, c))]",
"let a = [...(b, c)]",
"SequenceExpression",
1
),
invalid(
"let a = {...((b, c))}",
"let a = {...(b, c)}",
"SequenceExpression",
1
),
invalid(
"let a = {...((b, c))}",
"let a = {...(b, c)}",
"SequenceExpression",
1,
{ parserOptions: { ecmaVersion: 2018 } }
),
invalid(
"class A extends (B) {}",
"class A extends B {}",
"Identifier",
1
),
invalid(
"const A = class extends (B) {}",
"const A = class extends B {}",
"Identifier",
1
),
invalid(
"class A extends ((B=C)) {}",
"class A extends (B=C) {}",
"AssignmentExpression",
1
),
invalid(
"const A = class extends ((B=C)) {}",
"const A = class extends (B=C) {}",
"AssignmentExpression",
1
),
invalid(
"class A extends ((++foo)) {}",
"class A extends (++foo) {}",
"UpdateExpression",
1
),
invalid(
"export default ((a, b))",
"export default (a, b)",
"SequenceExpression",
1,
{ parserOptions: { sourceType: "module" } }
),
invalid(
"export default (() => {})",
"export default () => {}",
"ArrowFunctionExpression",
1,
{ parserOptions: { sourceType: "module" } }
),
invalid(
"export default ((a, b) => a + b)",
"export default (a, b) => a + b",
"ArrowFunctionExpression",
1,
{ parserOptions: { sourceType: "module" } }
),
invalid(
"export default (a => a)",
"export default a => a",
"ArrowFunctionExpression",
1,
{ parserOptions: { sourceType: "module" } }
),
invalid(
"export default (a = b)",
"export default a = b",
"AssignmentExpression",
1,
{ parserOptions: { sourceType: "module" } }
),
invalid(
"export default (a ? b : c)",
"export default a ? b : c",
"ConditionalExpression",
1,
{ parserOptions: { sourceType: "module" } }
),
invalid(
"export default (a)",
"export default a",
"Identifier",
1,
{ parserOptions: { sourceType: "module" } }
),
invalid(
"for (foo of(bar));",
"for (foo of bar);",
"Identifier",
1
),
invalid(
"for ((foo) of bar);",
"for (foo of bar);",
"Identifier",
1
),
invalid(
"for (foo of (baz = bar));",
"for (foo of baz = bar);",
"AssignmentExpression",
1
),
invalid(
"function* f() { for (foo of (yield bar)); }",
"function* f() { for (foo of yield bar); }",
"YieldExpression",
1
),
invalid(
"for (foo of ((bar, baz)));",
"for (foo of (bar, baz));",
"SequenceExpression",
1
),
invalid(
"for ((foo)in bar);",
"for (foo in bar);",
"Identifier",
1
),
invalid(
"for ((foo['bar'])of baz);",
"for (foo['bar']of baz);",
"MemberExpression",
1
),
invalid(
"() => (({ foo: 1 }).foo)",
"() => ({ foo: 1 }).foo",
"MemberExpression",
1
),
invalid(
"(let).foo",
"let.foo",
"Identifier",
1
),
// ForStatement#init expression cannot start with `let[`, but it can start with `let` if it isn't followed by `[`
invalid(
"for ((let);;);",
"for (let;;);",
"Identifier",
1
),
invalid(
"for ((let = 1);;);",
"for (let = 1;;);",
"AssignmentExpression",
1
),
invalid(
"for ((let) = 1;;);",
"for (let = 1;;);",
"Identifier",
1
),
invalid(
"for ((let = []);;);",
"for (let = [];;);",
"AssignmentExpression",
1
),
invalid(
"for ((let) = [];;);",
"for (let = [];;);",
"Identifier",
1
),
invalid(
"for ((let());;);",
"for (let();;);",
"CallExpression",
1
),
invalid(
"for ((let([]));;);",
"for (let([]);;);",
"CallExpression",
1
),
invalid(
"for ((let())[a];;);",
"for (let()[a];;);",
"CallExpression",
1
),
invalid(
"for ((let`[]`);;);",
"for (let`[]`;;);",
"TaggedTemplateExpression",
1
),
invalid(
"for ((let.a);;);",
"for (let.a;;);",
"MemberExpression",
1
),
invalid(
"for ((let).a;;);",
"for (let.a;;);",
"Identifier",
1
),
invalid(
"for ((let).a = 1;;);",
"for (let.a = 1;;);",
"Identifier",
1
),
invalid(
"for ((let).a[b];;);",
"for (let.a[b];;);",
"Identifier",
1
),
invalid(
"for ((let.a)[b];;);",
"for (let.a[b];;);",
"MemberExpression",
1
),
invalid(
"for ((let.a[b]);;);",
"for (let.a[b];;);",
"MemberExpression",
1
),
invalid(
"for ((let);[];);",
"for (let;[];);",
"Identifier",
1
),
invalid(
"for (((let[a]));;);",
"for ((let[a]);;);",
"MemberExpression",
1
),
invalid(
"for (((let))[a];;);",
"for ((let)[a];;);",
"Identifier",
1
),
invalid(
"for (((let[a])).b;;);",
"for ((let[a]).b;;);",
"MemberExpression",
1
),
invalid(
"for (((let))[a].b;;);",
"for ((let)[a].b;;);",
"Identifier",
1
),
invalid(
"for (((let)[a]).b;;);",
"for ((let)[a].b;;);",
"MemberExpression",
1
),
invalid(
"for (((let[a]) = b);;);",
"for ((let[a]) = b;;);",
"AssignmentExpression",
1
),
invalid(
"for (((let)[a]) = b;;);",
"for ((let)[a] = b;;);",
"MemberExpression",
1
),
invalid(
"for (((let)[a] = b);;);",
"for ((let)[a] = b;;);",
"AssignmentExpression",
1
),
invalid(
"for ((Let[a]);;);",
"for (Let[a];;);",
"MemberExpression",
1
),
invalid(
"for ((lett)[a];;);",
"for (lett[a];;);",
"Identifier",
1
),
// ForInStatement#left expression cannot start with `let[`, but it can start with `let` if it isn't followed by `[`
invalid(
"for ((let) in foo);",
"for (let in foo);",
"Identifier",
1
),
invalid(
"for ((let())[a] in foo);",
"for (let()[a] in foo);",
"CallExpression",
1
),
invalid(
"for ((let.a) in foo);",
"for (let.a in foo);",
"MemberExpression",
1
),
invalid(
"for ((let).a in foo);",
"for (let.a in foo);",
"Identifier",
1
),
invalid(
"for ((let).a.b in foo);",
"for (let.a.b in foo);",
"Identifier",
1
),
invalid(
"for ((let).a[b] in foo);",
"for (let.a[b] in foo);",
"Identifier",
1
),
invalid(
"for ((let.a)[b] in foo);",
"for (let.a[b] in foo);",
"MemberExpression",
1
),
invalid(
"for ((let.a[b]) in foo);",
"for (let.a[b] in foo);",
"MemberExpression",
1
),
invalid(
"for (((let[a])) in foo);",
"for ((let[a]) in foo);",
"MemberExpression",
1
),
invalid(
"for (((let))[a] in foo);",
"for ((let)[a] in foo);",
"Identifier",
1
),
invalid(
"for (((let[a])).b in foo);",
"for ((let[a]).b in foo);",
"MemberExpression",
1
),
invalid(
"for (((let))[a].b in foo);",
"for ((let)[a].b in foo);",
"Identifier",
1
),
invalid(
"for (((let)[a]).b in foo);",
"for ((let)[a].b in foo);",
"MemberExpression",
1
),
invalid(
"for (((let[a]).b) in foo);",
"for ((let[a]).b in foo);",
"MemberExpression",
1
),
invalid(
"for ((Let[a]) in foo);",
"for (Let[a] in foo);",
"MemberExpression",
1
),
invalid(
"for ((lett)[a] in foo);",
"for (lett[a] in foo);",
"Identifier",
1
),
// ForOfStatement#left expression cannot start with `let`
invalid(
"for (((let)) of foo);",
"for ((let) of foo);",
"Identifier",
1
),
invalid(
"for (((let)).a of foo);",
"for ((let).a of foo);",
"Identifier",
1
),
invalid(
"for (((let))[a] of foo);",
"for ((let)[a] of foo);",
"Identifier",
1
),
invalid(
"for (((let).a) of foo);",
"for ((let).a of foo);",
"MemberExpression",
1
),
invalid(
"for (((let[a]).b) of foo);",
"for ((let[a]).b of foo);",
"MemberExpression",
1
),
invalid(
"for (((let).a).b of foo);",
"for ((let).a.b of foo);",
"MemberExpression",
1
),
invalid(
"for (((let).a.b) of foo);",
"for ((let).a.b of foo);",
"MemberExpression",
1
),
invalid(
"for (((let.a).b) of foo);",
"for ((let.a).b of foo);",
"MemberExpression",
1
),
invalid(
"for (((let()).a) of foo);",
"for ((let()).a of foo);",
"MemberExpression",
1
),
invalid(
"for ((Let) of foo);",
"for (Let of foo);",
"Identifier",
1
),
invalid(
"for ((lett) of foo);",
"for (lett of foo);",
"Identifier",
1
),
invalid("for (a in (b, c));", "for (a in b, c);", "SequenceExpression", null),
invalid(
"(let)",
"let",
"Identifier",
1
),
invalid(
"((let))",
"(let)",
"Identifier",
1
),
invalid("let s = `${(v)}`", "let s = `${v}`", "Identifier"),
invalid("let s = `${(a, b)}`", "let s = `${a, b}`", "SequenceExpression"),
invalid("function foo(a = (b)) {}", "function foo(a = b) {}", "Identifier"),
invalid("const bar = (a = (b)) => a", "const bar = (a = b) => a", "Identifier"),
invalid("const [a = (b)] = []", "const [a = b] = []", "Identifier"),
invalid("const {a = (b)} = {}", "const {a = b} = {}", "Identifier"),
// LHS of assignments/Assignment targets
invalid("(a) = b", "a = b", "Identifier"),
invalid("(a.b) = c", "a.b = c", "MemberExpression"),
invalid("(a) += b", "a += b", "Identifier"),
invalid("(a.b) >>= c", "a.b >>= c", "MemberExpression"),
invalid("[(a) = b] = []", "[a = b] = []", "Identifier"),
invalid("[(a.b) = c] = []", "[a.b = c] = []", "MemberExpression"),
invalid("({ a: (b) = c } = {})", "({ a: b = c } = {})", "Identifier"),
invalid("({ a: (b.c) = d } = {})", "({ a: b.c = d } = {})", "MemberExpression"),
invalid("[(a)] = []", "[a] = []", "Identifier"),
invalid("[(a.b)] = []", "[a.b] = []", "MemberExpression"),
invalid("[,(a),,] = []", "[,a,,] = []", "Identifier"),
invalid("[...(a)] = []", "[...a] = []", "Identifier"),
invalid("[...(a.b)] = []", "[...a.b] = []", "MemberExpression"),
invalid("({ a: (b) } = {})", "({ a: b } = {})", "Identifier"),
invalid("({ a: (b.c) } = {})", "({ a: b.c } = {})", "MemberExpression"),
invalid("({ ...(a) } = {})", "({ ...a } = {})", "Identifier"),
invalid("({ ...(a.b) } = {})", "({ ...a.b } = {})", "MemberExpression"),
// https://github.com/eslint/eslint/issues/11706 (also in valid[])
{
code: "for ((a = (b in c)); ;);",
output: "for ((a = b in c); ;);",
errors: [
{
messageId: "unexpected"
}
]
},
{
code: "for (let a = ((b in c) && (d in e)); ;);",
output: "for (let a = (b in c && d in e); ;);",
errors: Array(2).fill(
{
messageId: "unexpected"
}
)
},
{
code: "for (let a = ((b in c) in d); ;);",
output: "for (let a = (b in c in d); ;);",
errors: [
{
messageId: "unexpected"
}
]
},
{
code: "for (let a = (b && (c in d)), e = (f in g); ;);",
output: "for (let a = (b && c in d), e = (f in g); ;);",
errors: [
{
messageId: "unexpected"
}
]
},
{
code: "for (let a = (b + c), d = (e in f); ;);",
output: "for (let a = b + c, d = (e in f); ;);",
errors: [
{
messageId: "unexpected"
}
]
},
{
code: "for (let a = [(b in c)]; ;);",
output: "for (let a = [b in c]; ;);",
errors: [
{
messageId: "unexpected"
}
]
},
{
code: "for (let a = [b, (c in d)]; ;);",
output: "for (let a = [b, c in d]; ;);",
errors: [
{
messageId: "unexpected"
}
]
},
{
code: "for (let a = ([b in c]); ;);",
output: "for (let a = [b in c]; ;);",
errors: [
{
messageId: "unexpected"
}
]
},
{
code: "for (let a = ([b, c in d]); ;);",
output: "for (let a = [b, c in d]; ;);",
errors: [
{
messageId: "unexpected"
}
]
},
{
code: "for ((a = [b in c]); ;);",
output: "for (a = [b in c]; ;);",
errors: [
{
messageId: "unexpected"
}
]
},
{
code: "for (let a = [b && (c in d)]; ;);",
output: "for (let a = [b && c in d]; ;);",
errors: [
{
messageId: "unexpected"
}
]
},
{
code: "for (let a = [(b && c in d)]; ;);",
output: "for (let a = [b && c in d]; ;);",
errors: [
{
messageId: "unexpected"
}
]
},
{
code: "for (let a = ([b && c in d]); ;);",
output: "for (let a = [b && c in d]; ;);",
errors: [
{
messageId: "unexpected"
}
]
},
{
code: "for ((a = [b && c in d]); ;);",
output: "for (a = [b && c in d]; ;);",
errors: [
{
messageId: "unexpected"
}
]
},
{
code: "for ([(a in b)]; ;);",
output: "for ([a in b]; ;);",
errors: [
{
messageId: "unexpected"
}
]
},
{
code: "for (([a in b]); ;);",
output: "for ([a in b]; ;);",
errors: [
{
messageId: "unexpected"
}
]
},
{
code: "for (let a = [(b in c)], d = (e in f); ;);",
output: "for (let a = [b in c], d = (e in f); ;);",
errors: [
{
messageId: "unexpected"
}
]
},
{
code: "for (let [a = (b in c)] = []; ;);",
output: "for (let [a = b in c] = []; ;);",
errors: [
{
messageId: "unexpected"
}
]
},
{
code: "for (let [a = b && (c in d)] = []; ;);",
output: "for (let [a = b && c in d] = []; ;);",
errors: [
{
messageId: "unexpected"
}
]
},
{
code: "for (let a = () => { (b in c) }; ;);",
output: "for (let a = () => { b in c }; ;);",
errors: [
{
messageId: "unexpected"
}
]
},
{
code: "for (let a = () => { a && (b in c) }; ;);",
output: "for (let a = () => { a && b in c }; ;);",
errors: [
{
messageId: "unexpected"
}
]
},
{
code: "for (let a = function () { (b in c) }; ;);",
output: "for (let a = function () { b in c }; ;);",
errors: [
{
messageId: "unexpected"
}
]
},
{
code: "for (let a = { a: (b in c) }; ;);",
output: "for (let a = { a: b in c }; ;);",
errors: [
{
messageId: "unexpected"
}
]
},
{
code: "for (let a = { a: b && (c in d) }; ;);",
output: "for (let a = { a: b && c in d }; ;);",
errors: [
{
messageId: "unexpected"
}
]
},
{
code: "for (let { a = (b in c) } = {}; ;);",
output: "for (let { a = b in c } = {}; ;);",
errors: [
{
messageId: "unexpected"
}
]
},
{
code: "for (let { a = b && (c in d) } = {}; ;);",
output: "for (let { a = b && c in d } = {}; ;);",
errors: [
{
messageId: "unexpected"
}
]
},
{
code: "for (let { a: { b = c && (d in e) } } = {}; ;);",
output: "for (let { a: { b = c && d in e } } = {}; ;);",
errors: [
{
messageId: "unexpected"
}
]
},
{
code: "for (let a = `${(a in b)}`; ;);",
output: "for (let a = `${a in b}`; ;);",
errors: [
{
messageId: "unexpected"
}
]
},
{
code: "for (let a = `${a && (b in c)}`; ;);",
output: "for (let a = `${a && b in c}`; ;);",
errors: [
{
messageId: "unexpected"
}
]
},
{
code: "for (let a = (b = (c in d)) => {}; ;);",
output: "for (let a = (b = c in d) => {}; ;);",
errors: [
{
messageId: "unexpected"
}
]
},
{
code: "for (let a = (b = c && (d in e)) => {}; ;);",
output: "for (let a = (b = c && d in e) => {}; ;);",
errors: [
{
messageId: "unexpected"
}
]
},
{
code: "for (let a = (b, c = d && (e in f)) => {}; ;);",
output: "for (let a = (b, c = d && e in f) => {}; ;);",
errors: [
{
messageId: "unexpected"
}
]
},
{
code: "for (let a = function (b = c && (d in e)) {}; ;);",
output: "for (let a = function (b = c && d in e) {}; ;);",
errors: [
{
messageId: "unexpected"
}
]
},
{
code: "for (let a = function (b, c = d && (e in f)) {}; ;);",
output: "for (let a = function (b, c = d && e in f) {}; ;);",
errors: [
{
messageId: "unexpected"
}
]
},
{
code: "for (let a = b((c in d)); ;);",
output: "for (let a = b(c in d); ;);",
errors: [
{
messageId: "unexpected"
}
]
},
{
code: "for (let a = b(c, (d in e)); ;);",
output: "for (let a = b(c, d in e); ;);",
errors: [
{
messageId: "unexpected"
}
]
},
{
code: "for (let a = b(c && (d in e)); ;);",
output: "for (let a = b(c && d in e); ;);",
errors: [
{
messageId: "unexpected"
}
]
},
{
code: "for (let a = b(c, d && (e in f)); ;);",
output: "for (let a = b(c, d && e in f); ;);",
errors: [
{
messageId: "unexpected"
}
]
},
{
code: "for (let a = new b((c in d)); ;);",
output: "for (let a = new b(c in d); ;);",
errors: [
{
messageId: "unexpected"
}
]
},
{
code: "for (let a = new b(c, (d in e)); ;);",
output: "for (let a = new b(c, d in e); ;);",
errors: [
{
messageId: "unexpected"
}
]
},
{
code: "for (let a = new b(c && (d in e)); ;);",
output: "for (let a = new b(c && d in e); ;);",
errors: [
{
messageId: "unexpected"
}
]
},
{
code: "for (let a = new b(c, d && (e in f)); ;);",
output: "for (let a = new b(c, d && e in f); ;);",
errors: [
{
messageId: "unexpected"
}
]
},
{
code: "for (let a = b[(c in d)]; ;);",
output: "for (let a = b[c in d]; ;);",
errors: [
{
messageId: "unexpected"
}
]
},
{
code: "for (let a = b[c && (d in e)]; ;);",
output: "for (let a = b[c && d in e]; ;);",
errors: [
{
messageId: "unexpected"
}
]
},
{
code: "for (let a = b ? (c in d) : e; ;);",
output: "for (let a = b ? c in d : e; ;);",
errors: [
{
messageId: "unexpected"
}
]
},
{
code: "for (let a = b ? c && (d in e) : f; ;);",
output: "for (let a = b ? c && d in e : f; ;);",
errors: [
{
messageId: "unexpected"
}
]
},
{
code: "for (a ? b && (c in d) : e; ;);",
output: "for (a ? b && c in d : e; ;);",
errors: [
{
messageId: "unexpected"
}
]
},
{
code: "for (let a = ((b in c)); ;);",
output: "for (let a = (b in c); ;);",
errors: [
{
messageId: "unexpected"
}
]
},
{
code: "for (((a in b)); ;);",
output: "for ((a in b); ;);",
errors: [
{
messageId: "unexpected"
}
]
},
{
code: "for (((a && b in c && d)); ;);",
output: "for ((a && b in c && d); ;);",
errors: [
{
messageId: "unexpected"
}
]
},
{
code: "for (let a = (!(b in c)); ;);",
output: "for (let a = !(b in c); ;);",
errors: [
{
messageId: "unexpected"
}
]
},
{
code: "for (let a = (!(b && c in d)); ;);",
output: "for (let a = !(b && c in d); ;);",
errors: [
{
messageId: "unexpected"
}
]
},
{
code: "for (let a = !((b in c) && (d in e)); ;);",
output: "for (let a = !(b in c && d in e); ;);",
errors: Array(2).fill(
{
messageId: "unexpected"
}
)
},
{
code: "for (let a = (x && (b in c)), d = () => { for ((e in f); ;); for ((g in h); ;); }; ;); for((i in j); ;);",
output: "for (let a = (x && b in c), d = () => { for ((e in f); ;); for ((g in h); ;); }; ;); for((i in j); ;);",
errors: [
{
messageId: "unexpected"
}
]
},
{
code: "for (let a = (b in c), d = () => { for ((x && (e in f)); ;); for ((g in h); ;); }; ;); for((i in j); ;);",
output: "for (let a = (b in c), d = () => { for ((x && e in f); ;); for ((g in h); ;); }; ;); for((i in j); ;);",
errors: [
{
messageId: "unexpected"
}
]
},
{
code: "for (let a = (b in c), d = () => { for ((e in f); ;); for ((x && (g in h)); ;); }; ;); for((i in j); ;);",
output: "for (let a = (b in c), d = () => { for ((e in f); ;); for ((x && g in h); ;); }; ;); for((i in j); ;);",
errors: [
{
messageId: "unexpected"
}
]
},
{
code: "for (let a = (b in c), d = () => { for ((e in f); ;); for ((g in h); ;); }; ;); for((x && (i in j)); ;);",
output: "for (let a = (b in c), d = () => { for ((e in f); ;); for ((g in h); ;); }; ;); for((x && i in j); ;);",
errors: [
{
messageId: "unexpected"
}
]
},
{
code: "for (let a = (x && (b in c)), d = () => { for ((e in f); ;); for ((y && (g in h)); ;); }; ;); for((i in j); ;);",
output: "for (let a = (x && b in c), d = () => { for ((e in f); ;); for ((y && g in h); ;); }; ;); for((i in j); ;);",
errors: Array(2).fill(
{
messageId: "unexpected"
}
)
},
{
code: "for (let a = (x && (b in c)), d = () => { for ((y && (e in f)); ;); for ((z && (g in h)); ;); }; ;); for((w && (i in j)); ;);",
output: "for (let a = (x && b in c), d = () => { for ((y && e in f); ;); for ((z && g in h); ;); }; ;); for((w && i in j); ;);",
errors: Array(4).fill(
{
messageId: "unexpected"
}
)
},
// https://github.com/eslint/eslint/issues/11706 regression tests (also in valid[])
{
code: "for (let a = (b); a > (b); a = (b)) a = (b); a = (b);",
output: "for (let a = b; a > b; a = b) a = b; a = b;",
errors: Array(5).fill(
{
messageId: "unexpected"
}
)
},
{
code: "for ((a = b); (a > b); (a = b)) (a = b); (a = b);",
output: "for (a = b; a > b; a = b) a = b; a = b;",
errors: Array(5).fill(
{
messageId: "unexpected"
}
)
},
{
code: "for (let a = b; a > (b); a = (b)) a = (b); a = (b);",
output: "for (let a = b; a > b; a = b) a = b; a = b;",
errors: Array(4).fill(
{
messageId: "unexpected"
}
)
},
{
code: "for (let a = b; (a > b); (a = b)) (a = b); (a = b);",
output: "for (let a = b; a > b; a = b) a = b; a = b;",
errors: Array(4).fill(
{
messageId: "unexpected"
}
)
},
{
code: "for (; a > (b); a = (b)) a = (b); a = (b);",
output: "for (; a > b; a = b) a = b; a = b;",
errors: Array(4).fill(
{
messageId: "unexpected"
}
)
},
{
code: "for (; (a > b); (a = b)) (a = b); (a = b);",
output: "for (; a > b; a = b) a = b; a = b;",
errors: Array(4).fill(
{
messageId: "unexpected"
}
)
},
{
code: "for (let a = (b); a = (b in c); a = (b in c)) a = (b in c); a = (b in c);",
output: "for (let a = b; a = b in c; a = b in c) a = b in c; a = b in c;",
errors: Array(5).fill(
{
messageId: "unexpected"
}
)
},
{
code: "for (let a = (b); (a in b); (a in b)) (a in b); (a in b);",
output: "for (let a = b; a in b; a in b) a in b; a in b;",
errors: Array(5).fill(
{
messageId: "unexpected"
}
)
},
{
code: "for (let a = b; a = (b in c); a = (b in c)) a = (b in c); a = (b in c);",
output: "for (let a = b; a = b in c; a = b in c) a = b in c; a = b in c;",
errors: Array(4).fill(
{
messageId: "unexpected"
}
)
},
{
code: "for (let a = b; (a in b); (a in b)) (a in b); (a in b);",
output: "for (let a = b; a in b; a in b) a in b; a in b;",
errors: Array(4).fill(
{
messageId: "unexpected"
}
)
},
{
code: "for (; a = (b in c); a = (b in c)) a = (b in c); a = (b in c);",
output: "for (; a = b in c; a = b in c) a = b in c; a = b in c;",
errors: Array(4).fill(
{
messageId: "unexpected"
}
)
},
{
code: "for (; (a in b); (a in b)) (a in b); (a in b);",
output: "for (; a in b; a in b) a in b; a in b;",
errors: Array(4).fill(
{
messageId: "unexpected"
}
)
},
{
code: "for (let a = (b + c), d = () => { for ((e + f); ;); for ((g + h); ;); }; ;); for((i + j); ;);",
output: "for (let a = b + c, d = () => { for (e + f; ;); for (g + h; ;); }; ;); for(i + j; ;);",
errors: Array(4).fill(
{
messageId: "unexpected"
}
)
},
// import expressions
invalid(
"import((source))",
"import(source)",
"Identifier",
1,
{ parserOptions: { ecmaVersion: 2020 } }
),
invalid(
"import((source = 'foo.js'))",
"import(source = 'foo.js')",
"AssignmentExpression",
1,
{ parserOptions: { ecmaVersion: 2020 } }
),
invalid(
"import(((s,t)))",
"import((s,t))",
"SequenceExpression",
1,
{ parserOptions: { ecmaVersion: 2020 } }
),
// https://github.com/eslint/eslint/issues/12127
{
code: "[1, ((2, 3))];",
output: "[1, (2, 3)];",
errors: [{ messageId: "unexpected" }]
},
{
code: "const foo = () => ((bar, baz));",
output: "const foo = () => (bar, baz);",
errors: [{ messageId: "unexpected" }]
},
{
code: "foo = ((bar, baz));",
output: "foo = (bar, baz);",
errors: [{ messageId: "unexpected" }]
},
{
code: "foo + ((bar + baz));",
output: "foo + (bar + baz);",
errors: [{ messageId: "unexpected" }]
},
{
code: "((foo + bar)) + baz;",
output: "(foo + bar) + baz;",
errors: [{ messageId: "unexpected" }]
},
{
code: "foo * ((bar + baz));",
output: "foo * (bar + baz);",
errors: [{ messageId: "unexpected" }]
},
{
code: "((foo + bar)) * baz;",
output: "(foo + bar) * baz;",
errors: [{ messageId: "unexpected" }]
},
{
code: "new A(((foo, bar)))",
output: "new A((foo, bar))",
errors: [{ messageId: "unexpected" }]
},
{
code: "class A{ [((foo, bar))]() {} }",
output: "class A{ [(foo, bar)]() {} }",
errors: [{ messageId: "unexpected" }]
},
{
code: "new ((A, B))()",
output: "new (A, B)()",
errors: [{ messageId: "unexpected" }]
},
{
code: "((foo, bar)) ? bar : baz;",
output: "(foo, bar) ? bar : baz;",
errors: [{ messageId: "unexpected" }]
},
{
code: "((f ? o : o)) ? bar : baz;",
output: "(f ? o : o) ? bar : baz;",
errors: [{ messageId: "unexpected" }]
},
{
code: "((f = oo)) ? bar : baz;",
output: "(f = oo) ? bar : baz;",
errors: [{ messageId: "unexpected" }]
},
{
code: "foo ? ((bar, baz)) : baz;",
output: "foo ? (bar, baz) : baz;",
errors: [{ messageId: "unexpected" }]
},
{
code: "foo ? bar : ((bar, baz));",
output: "foo ? bar : (bar, baz);",
errors: [{ messageId: "unexpected" }]
},
{
code: "function foo(bar = ((baz1, baz2))) {}",
output: "function foo(bar = (baz1, baz2)) {}",
errors: [{ messageId: "unexpected" }]
},
{
code: "var foo = { bar: ((baz1, baz2)) };",
output: "var foo = { bar: (baz1, baz2) };",
errors: [{ messageId: "unexpected" }]
},
{
code: "var foo = { [((bar1, bar2))]: baz };",
output: "var foo = { [(bar1, bar2)]: baz };",
errors: [{ messageId: "unexpected" }]
},
// adjacent tokens tests for division operator, comments and regular expressions
invalid("a+/**/(/**/b)", "a+/**//**/b", "Identifier"),
invalid("a+/**/(//\nb)", "a+/**///\nb", "Identifier"),
invalid("a in(/**/b)", "a in/**/b", "Identifier"),
invalid("a in(//\nb)", "a in//\nb", "Identifier"),
invalid("a+(/**/b)", "a+/**/b", "Identifier"),
invalid("a+/**/(b)", "a+/**/b", "Identifier"),
invalid("a+(//\nb)", "a+//\nb", "Identifier"),
invalid("a+//\n(b)", "a+//\nb", "Identifier"),
invalid("a+(/^b$/)", "a+/^b$/", "Literal"),
invalid("a/(/**/b)", "a/ /**/b", "Identifier"),
invalid("a/(//\nb)", "a/ //\nb", "Identifier"),
invalid("a/(/^b$/)", "a/ /^b$/", "Literal"),
// Nullish coalescing
{
code: "var v = ((a ?? b)) || c",
output: "var v = (a ?? b) || c",
parserOptions: { ecmaVersion: 2020 },
errors: [{ messageId: "unexpected" }]
},
{
code: "var v = a ?? ((b || c))",
output: "var v = a ?? (b || c)",
parserOptions: { ecmaVersion: 2020 },
errors: [{ messageId: "unexpected" }]
},
{
code: "var v = ((a ?? b)) && c",
output: "var v = (a ?? b) && c",
parserOptions: { ecmaVersion: 2020 },
errors: [{ messageId: "unexpected" }]
},
{
code: "var v = a ?? ((b && c))",
output: "var v = a ?? (b && c)",
parserOptions: { ecmaVersion: 2020 },
errors: [{ messageId: "unexpected" }]
},
{
code: "var v = ((a || b)) ?? c",
output: "var v = (a || b) ?? c",
parserOptions: { ecmaVersion: 2020 },
errors: [{ messageId: "unexpected" }]
},
{
code: "var v = a || ((b ?? c))",
output: "var v = a || (b ?? c)",
parserOptions: { ecmaVersion: 2020 },
errors: [{ messageId: "unexpected" }]
},
{
code: "var v = ((a && b)) ?? c",
output: "var v = (a && b) ?? c",
parserOptions: { ecmaVersion: 2020 },
errors: [{ messageId: "unexpected" }]
},
{
code: "var v = a && ((b ?? c))",
output: "var v = a && (b ?? c)",
parserOptions: { ecmaVersion: 2020 },
errors: [{ messageId: "unexpected" }]
},
{
code: "var v = (a ?? b) ? b : c",
output: "var v = a ?? b ? b : c",
parserOptions: { ecmaVersion: 2020 },
errors: [{ messageId: "unexpected" }]
},
{
code: "var v = (a | b) ?? c | d",
output: "var v = a | b ?? c | d",
parserOptions: { ecmaVersion: 2020 },
errors: [{ messageId: "unexpected" }]
},
{
code: "var v = a | b ?? (c | d)",
output: "var v = a | b ?? c | d",
parserOptions: { ecmaVersion: 2020 },
errors: [{ messageId: "unexpected" }]
},
// "allowParensAfterCommentPattern" option (off by default)
{
code: "const span = /**@type {HTMLSpanElement}*/(event.currentTarget);",
output: "const span = /**@type {HTMLSpanElement}*/event.currentTarget;",
options: ["all"],
errors: [{ messageId: "unexpected" }]
},
{
code: "if (/** @type {Compiler | MultiCompiler} */(options).hooks) console.log('good');",
output: "if (/** @type {Compiler | MultiCompiler} */options.hooks) console.log('good');",
options: ["all"],
errors: [{ messageId: "unexpected" }]
},
{
code: `
validate(/** @type {Schema} */ (schema), options, {
name: "Dev Server",
baseDataPath: "options",
});
`,
output: `
validate(/** @type {Schema} */ schema, options, {
name: "Dev Server",
baseDataPath: "options",
});
`,
options: ["all"],
errors: [{ messageId: "unexpected" }]
},
{
code: `
if (condition) {
/** @type {ServerOptions} */
(options.server.options).requestCert = false;
}
`,
output: `
if (condition) {
/** @type {ServerOptions} */
options.server.options.requestCert = false;
}
`,
options: ["all"],
errors: [{ messageId: "unexpected" }]
},
{
code: "const net = ipaddr.parseCIDR(/** @type {string} */ (cidr));",
output: "const net = ipaddr.parseCIDR(/** @type {string} */ cidr);",
options: ["all"],
errors: [{ messageId: "unexpected" }]
},
{
code: "const span = /**@type {HTMLSpanElement}*/(event.currentTarget);",
output: "const span = /**@type {HTMLSpanElement}*/event.currentTarget;",
options: ["all", { allowParensAfterCommentPattern: "invalid" }],
errors: [{ messageId: "unexpected" }]
},
{
code: "if (/** @type {Compiler | MultiCompiler} */(options).hooks) console.log('good');",
output: "if (/** @type {Compiler | MultiCompiler} */options.hooks) console.log('good');",
options: ["all", { allowParensAfterCommentPattern: "invalid" }],
errors: [{ messageId: "unexpected" }]
},
{
code: `
validate(/** @type {Schema} */ (schema), options, {
name: "Dev Server",
baseDataPath: "options",
});
`,
output: `
validate(/** @type {Schema} */ schema, options, {
name: "Dev Server",
baseDataPath: "options",
});
`,
options: ["all", { allowParensAfterCommentPattern: "invalid" }],
errors: [{ messageId: "unexpected" }]
},
{
code: `
if (condition) {
/** @type {ServerOptions} */
(options.server.options).requestCert = false;
}
`,
output: `
if (condition) {
/** @type {ServerOptions} */
options.server.options.requestCert = false;
}
`,
options: ["all", { allowParensAfterCommentPattern: "invalid" }],
errors: [{ messageId: "unexpected" }]
},
{
code: `
if (condition) {
/** @type {ServerOptions} */
/** extra comment */
(options.server.options).requestCert = false;
}
`,
output: `
if (condition) {
/** @type {ServerOptions} */
/** extra comment */
options.server.options.requestCert = false;
}
`,
options: ["all", { allowParensAfterCommentPattern: "@type" }],
errors: [{ messageId: "unexpected" }]
},
{
code: `
if (condition) {
/** @type {ServerOptions} */
((options.server.options)).requestCert = false;
}
`,
output: `
if (condition) {
/** @type {ServerOptions} */
(options.server.options).requestCert = false;
}
`,
options: ["all", { allowParensAfterCommentPattern: "@type" }],
errors: [{ messageId: "unexpected" }]
},
{
code: `
if (condition) {
/** @type {ServerOptions} */
let foo = "bar";
(options.server.options).requestCert = false;
}
`,
output: `
if (condition) {
/** @type {ServerOptions} */
let foo = "bar";
options.server.options.requestCert = false;
}
`,
options: ["all", { allowParensAfterCommentPattern: "@type" }],
errors: [{ messageId: "unexpected" }]
},
{
code: "const net = ipaddr.parseCIDR(/** @type {string} */ (cidr));",
output: "const net = ipaddr.parseCIDR(/** @type {string} */ cidr);",
options: ["all", { allowParensAfterCommentPattern: "invalid" }],
errors: [{ messageId: "unexpected" }]
},
// Optional chaining
{
code: "var v = (obj?.aaa)?.aaa",
output: "var v = obj?.aaa?.aaa",
parserOptions: { ecmaVersion: 2020 },
errors: [{ messageId: "unexpected" }]
},
{
code: "var v = (obj.aaa)?.aaa",
output: "var v = obj.aaa?.aaa",
parserOptions: { ecmaVersion: 2020 },
errors: [{ messageId: "unexpected" }]
},
{
code: "var foo = (function(){})?.call()",
output: "var foo = function(){}?.call()",
options: ["all", { enforceForFunctionPrototypeMethods: true }],
parserOptions: { ecmaVersion: 2020 },
errors: [{ messageId: "unexpected" }]
},
{
code: "var foo = (function(){}?.call())",
output: "var foo = function(){}?.call()",
options: ["all", { enforceForFunctionPrototypeMethods: true }],
parserOptions: { ecmaVersion: 2020 },
errors: [{ messageId: "unexpected" }]
},
{
code: "(Object.prototype.toString.call())",
output: "Object.prototype.toString.call()",
options: ["all"],
parserOptions: { ecmaVersion: 2020 },
errors: [{ messageId: "unexpected" }]
},
// https://github.com/eslint/eslint/issues/16850
invalid("(a) = function foo() {};", "a = function foo() {};", "Identifier"),
invalid("(a) = class Bar {};", "a = class Bar {};", "Identifier"),
invalid("(a.b) = function () {};", "a.b = function () {};", "MemberExpression"),
{
code: "(newClass) = [(one)] = class { static * [Symbol.iterator]() { yield 1; } };",
output: "newClass = [one] = class { static * [Symbol.iterator]() { yield 1; } };",
errors: [
{ messageId: "unexpected", type: "Identifier" },
{ messageId: "unexpected", type: "Identifier" }
]
},
invalid("((a)) = () => {};", "(a) = () => {};", "Identifier"),
invalid("(a) = (function () {})();", "a = (function () {})();", "Identifier"),
...["**=", "*=", "/=", "%=", "+=", "-=", "<<=", ">>=", ">>>=", "&=", "^=", "|="].map(
operator => invalid(
`(a) ${operator} function () {};`,
`a ${operator} function () {};`,
"Identifier"
)
)
]
});