diff --git a/package.json b/package.json index 1e23237ee..14bdb1368 100644 --- a/package.json +++ b/package.json @@ -32,8 +32,8 @@ "dependencies": { "@angular/compiler": "18.1.0", "@babel/code-frame": "7.24.7", - "@babel/parser": "7.24.7", - "@babel/types": "7.24.7", + "@babel/parser": "7.24.8", + "@babel/types": "7.24.8", "@glimmer/syntax": "0.92.0", "@iarna/toml": "2.2.5", "@prettier/is-es5-identifier-name": "0.2.0", @@ -105,7 +105,7 @@ "yaml-unist-parser": "2.0.1" }, "devDependencies": { - "@babel/generator": "7.24.7", + "@babel/generator": "7.24.8", "@eslint/compat": "1.0.3", "@eslint/eslintrc": "3.1.0", "@eslint/js": "9.5.0", diff --git a/src/language-js/needs-parens.js b/src/language-js/needs-parens.js index 4b8c2ac4c..67383e9e8 100644 --- a/src/language-js/needs-parens.js +++ b/src/language-js/needs-parens.js @@ -288,6 +288,24 @@ function needsParens(path, options) { return true; } break; + + case "VariableDeclarator": + // Legacy syntax + // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Errors/Invalid_for-in_initializer + // `for (var a = 1 in b);` + if ( + key === "init" && + path.match( + undefined, + undefined, + (node, key) => + key === "declarations" && node.type === "VariableDeclaration", + (node, key) => key === "left" && node.type === "ForInStatement", + ) + ) { + return true; + } + break; } switch (node.type) { diff --git a/src/language-js/parse/babel.js b/src/language-js/parse/babel.js index 3b707848e..0efd5f0ce 100644 --- a/src/language-js/parse/babel.js +++ b/src/language-js/parse/babel.js @@ -174,6 +174,7 @@ const allowedReasonCodes = new Set([ "StrictEvalArguments", "StrictEvalArgumentsBinding", "StrictFunction", + "ForInOfLoopInitializer", "EmptyTypeArguments", "EmptyTypeParameters", diff --git a/tests/format/js/for/__snapshots__/format.test.js.snap b/tests/format/js/for/__snapshots__/format.test.js.snap index 69f2556fe..5112371ac 100644 --- a/tests/format/js/for/__snapshots__/format.test.js.snap +++ b/tests/format/js/for/__snapshots__/format.test.js.snap @@ -799,6 +799,71 @@ for (var i = 0; i < 10; ++i) 0; ================================================================================ `; +exports[`for-in-with-initializer.js [flow] format 1`] = ` +"Invalid left-hand side in for-in (3:6) + 1 | // https://github.com/babel/babel/blob/HEAD/packages/babel-generator/test/fixtures/parentheses/in-inside-for/input.js + 2 | +> 3 | for (var a = (b in c) in {}); + | ^^^^^^^^^^^^^^^^ + 4 | for (var a = 1 || (b in c) in {}); + 5 | for (var a = 1 + (2 || (b in c)) in {}); + 6 | for (var a = (() => b in c) in {});" +`; + +exports[`for-in-with-initializer.js [typescript] format 1`] = ` +"',' expected. (9:17) + 7 | for (var a = 1 || (() => b in c) in {}); + 8 | for (var a = (() => { b in c; }) in {}); +> 9 | for (var a = [b in c] in {}); + | ^ + 10 | for (var a = {b: b in c} in {}); + 11 | // Meriyah can't parse + 12 | // for (var a = (x = b in c) => {} in {}); +Cause: ',' expected." +`; + +exports[`for-in-with-initializer.js format 1`] = ` +====================================options===================================== +parsers: ["babel", "flow", "typescript"] +printWidth: 80 + | printWidth +=====================================input====================================== +// https://github.com/babel/babel/blob/HEAD/packages/babel-generator/test/fixtures/parentheses/in-inside-for/input.js + +for (var a = (b in c) in {}); +for (var a = 1 || (b in c) in {}); +for (var a = 1 + (2 || (b in c)) in {}); +for (var a = (() => b in c) in {}); +for (var a = 1 || (() => b in c) in {}); +for (var a = (() => { b in c; }) in {}); +for (var a = [b in c] in {}); +for (var a = {b: b in c} in {}); +// Meriyah can't parse +// for (var a = (x = b in c) => {} in {}); +for (var a = class extends (b in c) {} in {}); +for (var a = function (x = b in c) {} in {}); + +=====================================output===================================== +// https://github.com/babel/babel/blob/HEAD/packages/babel-generator/test/fixtures/parentheses/in-inside-for/input.js + +for (var a = (b in c) in {}); +for (var a = (1 || b in c) in {}); +for (var a = (1 + (2 || b in c)) in {}); +for (var a = (() => b in c) in {}); +for (var a = (1 || (() => b in c)) in {}); +for (var a = (() => { + b in c; +}) in {}); +for (var a = ([b in c]) in {}); +for (var a = ({ b: b in c }) in {}); +// Meriyah can't parse +// for (var a = (x = b in c) => {} in {}); +for (var a = (class extends (b in c) {}) in {}); +for (var a = (function (x = b in c) {}) in {}); + +================================================================================ +`; + exports[`in.js format 1`] = ` ====================================options===================================== parsers: ["babel", "flow", "typescript"] @@ -835,6 +900,129 @@ for (a in b) 0; ================================================================================ `; +exports[`parentheses.js [flow] format 1`] = ` +"Unexpected token \`=>\`, expected the token \`;\` (11:27) + 9 | for (var a = [b in c];;); + 10 | for (var a = {b: b in c};;); +> 11 | for (var a = (x = b in c) => {};;); + | ^^ + 12 | for (var a = class extends (b in c) {};;); + 13 | for (var a = function (x = b in c) {};;); + 14 |" +`; + +exports[`parentheses.js [typescript] format 1`] = ` +"',' expected. (9:17) + 7 | for (var a = 1 || (() => b in c);;); + 8 | for (var a = (() => { b in c; });;); +> 9 | for (var a = [b in c];;); + | ^ + 10 | for (var a = {b: b in c};;); + 11 | for (var a = (x = b in c) => {};;); + 12 | for (var a = class extends (b in c) {};;); +Cause: ',' expected." +`; + +exports[`parentheses.js format 1`] = ` +====================================options===================================== +parsers: ["babel", "flow", "typescript"] +printWidth: 80 + | printWidth +=====================================input====================================== +// https://github.com/babel/babel/blob/HEAD/packages/babel-generator/test/fixtures/parentheses/in-inside-for/input.js + +for (var a = (b in c);;); +for (var a = 1 || (b in c);;); +for (var a = 1 + (2 || (b in c));;); +for (var a = (() => b in c);;); +for (var a = 1 || (() => b in c);;); +for (var a = (() => { b in c; });;); +for (var a = [b in c];;); +for (var a = {b: b in c};;); +for (var a = (x = b in c) => {};;); +for (var a = class extends (b in c) {};;); +for (var a = function (x = b in c) {};;); + +for (var a in (b in c)); +for (var a in 1 || (b in c)); +for (var a in 1 + (2 || (b in c))); +for (var a in (() => b in c)); +for (var a in 1 || (() => b in c)); +for (var a in (() => { b in c; })); +for (var a in [b in c]); +for (var a in {b: b in c}); +for (var a in (x = b in c) => {}); +for (var a in class extends (b in c) {}); +for (var a in function (x = b in c) {}); + +for (;a = (b in c);); +for (;a = 1 || (b in c);); +for (;a = 1 + (2 || (b in c));); +for (;a = (() => b in c);); +for (;a = 1 || (() => b in c);); +for (;a = (() => { b in c; });); +for (;a = [b in c];); +for (;a = {b: b in c};); +for (;a = (x = b in c) => {};); +for (;a = class extends (b in c) {};); +for (;a = function (x = b in c) {};); + +=====================================output===================================== +// https://github.com/babel/babel/blob/HEAD/packages/babel-generator/test/fixtures/parentheses/in-inside-for/input.js + +for (var a = (b in c); ; ); +for (var a = 1 || (b in c); ; ); +for (var a = 1 + (2 || (b in c)); ; ); +for (var a = () => (b in c); ; ); +for (var a = 1 || (() => (b in c)); ; ); +for ( + var a = () => { + (b in c); + }; + ; + +); +for (var a = [(b in c)]; ; ); +for (var a = { b: (b in c) }; ; ); +for (var a = (x = (b in c)) => {}; ; ); +for (var a = class extends (b in c) {}; ; ); +for (var a = function (x = (b in c)) {}; ; ); + +for (var a in b in c); +for (var a in 1 || b in c); +for (var a in 1 + (2 || b in c)); +for (var a in () => b in c); +for (var a in 1 || (() => b in c)); +for (var a in () => { + b in c; +}); +for (var a in [b in c]); +for (var a in { b: b in c }); +for (var a in (x = b in c) => {}); +for (var a in class extends (b in c) {}); +for (var a in function (x = b in c) {}); + +for (; (a = b in c); ); +for (; (a = 1 || b in c); ); +for (; (a = 1 + (2 || b in c)); ); +for (; (a = () => b in c); ); +for (; (a = 1 || (() => b in c)); ); +for ( + ; + (a = () => { + b in c; + }); + +); +for (; (a = [b in c]); ); +for (; (a = { b: b in c }); ); +for (; (a = (x = b in c) => {}); ); +for (; (a = class extends (b in c) {}); ); +for (; (a = function (x = b in c) {}); ); + +================================================================================ +`; + exports[`var.js format 1`] = ` ====================================options===================================== parsers: ["babel", "flow", "typescript"] diff --git a/tests/format/js/for/for-in-with-initializer.js b/tests/format/js/for/for-in-with-initializer.js new file mode 100644 index 000000000..616920da7 --- /dev/null +++ b/tests/format/js/for/for-in-with-initializer.js @@ -0,0 +1,14 @@ +// https://github.com/babel/babel/blob/HEAD/packages/babel-generator/test/fixtures/parentheses/in-inside-for/input.js + +for (var a = (b in c) in {}); +for (var a = 1 || (b in c) in {}); +for (var a = 1 + (2 || (b in c)) in {}); +for (var a = (() => b in c) in {}); +for (var a = 1 || (() => b in c) in {}); +for (var a = (() => { b in c; }) in {}); +for (var a = [b in c] in {}); +for (var a = {b: b in c} in {}); +// Meriyah can't parse +// for (var a = (x = b in c) => {} in {}); +for (var a = class extends (b in c) {} in {}); +for (var a = function (x = b in c) {} in {}); diff --git a/tests/format/js/for/format.test.js b/tests/format/js/for/format.test.js index 67c251cce..441b72f6d 100644 --- a/tests/format/js/for/format.test.js +++ b/tests/format/js/for/format.test.js @@ -1 +1,6 @@ -runFormatTest(import.meta, ["babel", "flow", "typescript"]); +runFormatTest(import.meta, ["babel", "flow", "typescript"], { + errors: { + flow: ["parentheses.js", "for-in-with-initializer.js"], + typescript: ["parentheses.js", "for-in-with-initializer.js"], + }, +}); diff --git a/tests/format/js/for/parentheses.js b/tests/format/js/for/parentheses.js new file mode 100644 index 000000000..2a150ba8e --- /dev/null +++ b/tests/format/js/for/parentheses.js @@ -0,0 +1,37 @@ +// https://github.com/babel/babel/blob/HEAD/packages/babel-generator/test/fixtures/parentheses/in-inside-for/input.js + +for (var a = (b in c);;); +for (var a = 1 || (b in c);;); +for (var a = 1 + (2 || (b in c));;); +for (var a = (() => b in c);;); +for (var a = 1 || (() => b in c);;); +for (var a = (() => { b in c; });;); +for (var a = [b in c];;); +for (var a = {b: b in c};;); +for (var a = (x = b in c) => {};;); +for (var a = class extends (b in c) {};;); +for (var a = function (x = b in c) {};;); + +for (var a in (b in c)); +for (var a in 1 || (b in c)); +for (var a in 1 + (2 || (b in c))); +for (var a in (() => b in c)); +for (var a in 1 || (() => b in c)); +for (var a in (() => { b in c; })); +for (var a in [b in c]); +for (var a in {b: b in c}); +for (var a in (x = b in c) => {}); +for (var a in class extends (b in c) {}); +for (var a in function (x = b in c) {}); + +for (;a = (b in c);); +for (;a = 1 || (b in c);); +for (;a = 1 + (2 || (b in c));); +for (;a = (() => b in c);); +for (;a = 1 || (() => b in c);); +for (;a = (() => { b in c; });); +for (;a = [b in c];); +for (;a = {b: b in c};); +for (;a = (x = b in c) => {};); +for (;a = class extends (b in c) {};); +for (;a = function (x = b in c) {};); diff --git a/tests/format/misc/errors/js/explicit-resource-management/__snapshots__/format.test.js.snap b/tests/format/misc/errors/js/explicit-resource-management/__snapshots__/format.test.js.snap index 31287efa1..962fe84db 100644 --- a/tests/format/misc/errors/js/explicit-resource-management/__snapshots__/format.test.js.snap +++ b/tests/format/misc/errors/js/explicit-resource-management/__snapshots__/format.test.js.snap @@ -80,14 +80,15 @@ exports[`invalid-using-binding-let.js [flow] format 1`] = ` `; exports[`invalid-using-binding-pattern.js [babel] format 1`] = ` -"Unexpected token (2:17) - 1 | { -> 2 | using { foo } = f(); - | ^ +"Unexpected token, expected ")" (4:25) + 2 | using { foo } = f(); 3 | using [ bar ] = g(); - 4 | for (using { qux } of h()); +> 4 | for (using { qux } of h()); + | ^ 5 | for (using [ quux ] of i()); -Cause: Unexpected token (2:16)" + 6 | } + 7 | +Cause: Unexpected token, expected ")" (4:24)" `; exports[`invalid-using-binding-pattern.js [flow] format 1`] = ` diff --git a/tests/unit/__snapshots__/visitor-keys.js.snap b/tests/unit/__snapshots__/visitor-keys.js.snap index f26eae456..fee7bd210 100644 --- a/tests/unit/__snapshots__/visitor-keys.js.snap +++ b/tests/unit/__snapshots__/visitor-keys.js.snap @@ -628,9 +628,6 @@ exports[`visitor keys estree 1`] = ` "ObjectTypeInternalSlot": [ "id", "value", - "optional", - "static", - "method", ], "ObjectTypeMappedTypeProperty": [ "keyTparam", diff --git a/yarn.lock b/yarn.lock index 84027d36e..b2fe39388 100644 --- a/yarn.lock +++ b/yarn.lock @@ -78,15 +78,15 @@ __metadata: languageName: node linkType: hard -"@babel/generator@npm:7.24.7, @babel/generator@npm:^7.24.7, @babel/generator@npm:^7.7.2": - version: 7.24.7 - resolution: "@babel/generator@npm:7.24.7" +"@babel/generator@npm:7.24.8, @babel/generator@npm:^7.24.7, @babel/generator@npm:^7.7.2": + version: 7.24.8 + resolution: "@babel/generator@npm:7.24.8" dependencies: - "@babel/types": "npm:^7.24.7" + "@babel/types": "npm:^7.24.8" "@jridgewell/gen-mapping": "npm:^0.3.5" "@jridgewell/trace-mapping": "npm:^0.3.25" jsesc: "npm:^2.5.1" - checksum: 10/c71d24a4b41b19c10d2f2eb819f27d4cf94220e2322f7c8fed8bfbbb115b2bebbdd6dc1f27dac78a175e90604def58d763af87e0fa81ce4ab1582858162cf768 + checksum: 10/dc1bd931120f93e7a5b35fdf66c13ca56b966b07ee9ba124f7e24b1905cbcf7d7891cc7c281961876eff9fcff67c46652cce89847665e263bc04d283d4343164 languageName: node linkType: hard @@ -182,10 +182,10 @@ __metadata: languageName: node linkType: hard -"@babel/helper-string-parser@npm:^7.24.7": - version: 7.24.7 - resolution: "@babel/helper-string-parser@npm:7.24.7" - checksum: 10/603d8d962bbe89907aa99a8f19a006759ab7b2464615f20a6a22e3e2e8375af37ddd0e5175c9e622e1c4b2d83607ffb41055a59d0ce34404502af30fde573a5c +"@babel/helper-string-parser@npm:^7.24.8": + version: 7.24.8 + resolution: "@babel/helper-string-parser@npm:7.24.8" + checksum: 10/6d1bf8f27dd725ce02bdc6dffca3c95fb9ab8a06adc2edbd9c1c9d68500274230d1a609025833ed81981eff560045b6b38f7b4c6fb1ab19fc90e5004e3932535 languageName: node linkType: hard @@ -225,12 +225,12 @@ __metadata: languageName: node linkType: hard -"@babel/parser@npm:7.24.7, @babel/parser@npm:^7.1.0, @babel/parser@npm:^7.14.7, @babel/parser@npm:^7.20.7, @babel/parser@npm:^7.23.9, @babel/parser@npm:^7.24.7": - version: 7.24.7 - resolution: "@babel/parser@npm:7.24.7" +"@babel/parser@npm:7.24.8, @babel/parser@npm:^7.1.0, @babel/parser@npm:^7.14.7, @babel/parser@npm:^7.20.7, @babel/parser@npm:^7.23.9, @babel/parser@npm:^7.24.7": + version: 7.24.8 + resolution: "@babel/parser@npm:7.24.8" bin: parser: ./bin/babel-parser.js - checksum: 10/ef9ebce60e13db560ccc7af9235d460f6726bb7e23ae2d675098c1fc43d5249067be60d4118889dad33b1d4f85162cf66baf554719e1669f29bb20e71322568e + checksum: 10/e44b8327da46e8659bc9fb77f66e2dc4364dd66495fb17d046b96a77bf604f0446f1e9a89cf2f011d78fc3f5cdfbae2e9e0714708e1c985988335683b2e781ef languageName: node linkType: hard @@ -417,14 +417,14 @@ __metadata: languageName: node linkType: hard -"@babel/types@npm:7.24.7, @babel/types@npm:^7.0.0, @babel/types@npm:^7.20.7, @babel/types@npm:^7.24.7, @babel/types@npm:^7.3.3, @babel/types@npm:^7.8.3": - version: 7.24.7 - resolution: "@babel/types@npm:7.24.7" +"@babel/types@npm:7.24.8, @babel/types@npm:^7.0.0, @babel/types@npm:^7.20.7, @babel/types@npm:^7.24.7, @babel/types@npm:^7.24.8, @babel/types@npm:^7.3.3, @babel/types@npm:^7.8.3": + version: 7.24.8 + resolution: "@babel/types@npm:7.24.8" dependencies: - "@babel/helper-string-parser": "npm:^7.24.7" + "@babel/helper-string-parser": "npm:^7.24.8" "@babel/helper-validator-identifier": "npm:^7.24.7" to-fast-properties: "npm:^2.0.0" - checksum: 10/ad3c8c0d6fb4acb0bb74bb5b4bb849b181bf6185677ef9c59c18856c81e43628d0858253cf232f0eca806f02e08eff85a1d3e636a3e94daea737597796b0b430 + checksum: 10/29b080b2753c22ee5e2455ff767a971443245d945dea4d1b3130e036dcdf0949a89539a581753c68d03d2f2f2325244ee0f91fb83dabee1cbac5db5246838137 languageName: node linkType: hard @@ -7350,9 +7350,9 @@ __metadata: dependencies: "@angular/compiler": "npm:18.1.0" "@babel/code-frame": "npm:7.24.7" - "@babel/generator": "npm:7.24.7" - "@babel/parser": "npm:7.24.7" - "@babel/types": "npm:7.24.7" + "@babel/generator": "npm:7.24.8" + "@babel/parser": "npm:7.24.8" + "@babel/types": "npm:7.24.8" "@eslint/compat": "npm:1.0.3" "@eslint/eslintrc": "npm:3.1.0" "@eslint/js": "npm:9.5.0"