diff --git a/changelog_unreleased/vue/pr-8747.md b/changelog_unreleased/vue/pr-8747.md
new file mode 100644
index 000000000..8e6449c51
--- /dev/null
+++ b/changelog_unreleased/vue/pr-8747.md
@@ -0,0 +1,19 @@
+#### Fix parenthesized interpolation format ([#8747](https://github.com/prettier/prettier/pull/8747) by [@fisker](https://github.com/fisker))
+
+
+```vue
+
+
+{{(a|| b)}} {{z&&(a&&b)}}
+
+
+
+
+ {{(a|| b)}} {{z&&(a&&b)}}
+
+
+
+
+ {{ a || b }} {{ z && a && b }}
+
+```
diff --git a/src/language-js/postprocess.js b/src/language-js/postprocess.js
index 132d37602..dc1421e25 100644
--- a/src/language-js/postprocess.js
+++ b/src/language-js/postprocess.js
@@ -21,7 +21,7 @@ function postprocess(ast, options) {
// E.g.: /** @type {Foo} */ (foo).bar();
// Let's use the fact that those ancestors and ParenthesizedExpression have the same start offset.
- visitNode(ast, (node) => {
+ ast = visitNode(ast, (node) => {
if (
node.leadingComments &&
node.leadingComments.some(isTypeCastComment)
@@ -30,7 +30,7 @@ function postprocess(ast, options) {
}
});
- visitNode(ast, (node) => {
+ ast = visitNode(ast, (node) => {
if (node.type === "ParenthesizedExpression") {
const start = locStart(node);
if (!startOffsetsOfTypeCastedNodes.has(start)) {
@@ -46,7 +46,7 @@ function postprocess(ast, options) {
});
}
- visitNode(ast, (node) => {
+ ast = visitNode(ast, (node) => {
switch (node.type) {
case "LogicalExpression": {
// We remove unneeded parens around same-operator LogicalExpressions
@@ -133,31 +133,26 @@ function postprocess(ast, options) {
}
}
-function visitNode(node, fn, parent, property) {
- if (!node || typeof node !== "object") {
- return;
- }
+function visitNode(node, fn) {
+ let entries;
if (Array.isArray(node)) {
- for (let i = 0; i < node.length; i++) {
- visitNode(node[i], fn, node, i);
- }
- return;
+ entries = node.entries();
+ } else if (
+ node &&
+ typeof node === "object" &&
+ typeof node.type === "string"
+ ) {
+ entries = Object.entries(node);
+ } else {
+ return node;
}
- if (typeof node.type !== "string") {
- return;
+ for (const [key, child] of entries) {
+ node[key] = visitNode(child, fn);
}
- for (const key of Object.keys(node)) {
- visitNode(node[key], fn, node, key);
- }
-
- const replacement = fn(node);
-
- if (replacement) {
- parent[property] = replacement;
- }
+ return fn(node) || node;
}
function isUnbalancedLogicalTree(node) {
diff --git a/tests/vue/interpolation/__snapshots__/jsfmt.spec.js.snap b/tests/vue/interpolation/__snapshots__/jsfmt.spec.js.snap
index 3b930d98f..91b44d2b1 100644
--- a/tests/vue/interpolation/__snapshots__/jsfmt.spec.js.snap
+++ b/tests/vue/interpolation/__snapshots__/jsfmt.spec.js.snap
@@ -1,5 +1,23 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
+exports[`parenthesized.vue format 1`] = `
+====================================options=====================================
+parsers: ["vue"]
+printWidth: 80
+ | printWidth
+=====================================input======================================
+
+{{(a|| b)}} {{z&&(a&&b)}}
+
+
+=====================================output=====================================
+
+ {{ a || b }} {{ z && a && b }}
+
+
+================================================================================
+`;
+
exports[`template.vue format 1`] = `
====================================options=====================================
parsers: ["vue"]
diff --git a/tests/vue/interpolation/parenthesized.vue b/tests/vue/interpolation/parenthesized.vue
new file mode 100644
index 000000000..3a519bd70
--- /dev/null
+++ b/tests/vue/interpolation/parenthesized.vue
@@ -0,0 +1,3 @@
+
+{{(a|| b)}} {{z&&(a&&b)}}
+