From 3357d07ef6405da0e37223718b6e54ab998de5f2 Mon Sep 17 00:00:00 2001 From: Dextheking1 Date: Tue, 22 Sep 2026 22:41:58 +0200 Subject: [PATCH] fix: keep $ on nested variables in "${...}" interpolation Printing `"${foo[$index_var]}"` swallowed the dollar sign of the nested variable, producing `"${foo[index_var]}"` and silently changing semantics (the variable becomes a bare constant). The `variable` printer dropped `$` for any variable whose parent was an offsetlookup under a curly-simple encapsedpart, but only the base variable of the lookup (which directly follows the `${` emitted by the encapsedpart printer) may lose its `$`; a variable in the offset position is nested and keeps its own `$`. Closes prettier/plugin-php#2177 --- src/printer.mjs | 4 ++++ tests/encapsed/__snapshots__/jsfmt.spec.mjs.snap | 4 ++++ tests/encapsed/encapsed.php | 1 + 3 files changed, 9 insertions(+) diff --git a/src/printer.mjs b/src/printer.mjs index f789a340b..cda9bb7a1 100644 --- a/src/printer.mjs +++ b/src/printer.mjs @@ -2314,6 +2314,10 @@ function printNode(path, options, print) { parent.curly) || (parentParent && parent.kind === "offsetlookup" && + // Only the base variable of the lookup follows the `${` printed + // by the encapsedpart; a variable in the offset position is a + // nested variable and keeps its own `$`. + parent.what === node && parentParent.kind === "encapsedpart" && parentParent.syntax === "simple" && parentParent.curly) diff --git a/tests/encapsed/__snapshots__/jsfmt.spec.mjs.snap b/tests/encapsed/__snapshots__/jsfmt.spec.mjs.snap index 8c5c4dcea..0b8acbec2 100644 --- a/tests/encapsed/__snapshots__/jsfmt.spec.mjs.snap +++ b/tests/encapsed/__snapshots__/jsfmt.spec.mjs.snap @@ -414,6 +414,7 @@ echo "text \${foo['foo']} text"; echo "text \${foo[foo]} text"; echo "text \${foo[call()]} text"; echo "text \${foo[$var ? 'foo' : 'bar']} text"; +echo "text \${foo[$index_var]} text"; // T_CURLY_OPEN variable '}' echo "text {$var} text"; @@ -952,6 +953,7 @@ echo "text \${foo["foo"]} text"; echo "text \${foo[foo]} text"; echo "text \${foo[call()]} text"; echo "text \${foo[$var ? "foo" : "bar"]} text"; +echo "text \${foo[$index_var]} text"; // T_CURLY_OPEN variable '}' echo "text {$var} text"; @@ -1449,6 +1451,7 @@ echo "text \${foo['foo']} text"; echo "text \${foo[foo]} text"; echo "text \${foo[call()]} text"; echo "text \${foo[$var ? 'foo' : 'bar']} text"; +echo "text \${foo[$index_var]} text"; // T_CURLY_OPEN variable '}' echo "text {$var} text"; @@ -1988,6 +1991,7 @@ echo "text \${foo["foo"]} text"; echo "text \${foo[foo]} text"; echo "text \${foo[call()]} text"; echo "text \${foo[$var ? "foo" : "bar"]} text"; +echo "text \${foo[$index_var]} text"; // T_CURLY_OPEN variable '}' echo "text {$var} text"; diff --git a/tests/encapsed/encapsed.php b/tests/encapsed/encapsed.php index 8cb08d2a0..2ee2d204d 100644 --- a/tests/encapsed/encapsed.php +++ b/tests/encapsed/encapsed.php @@ -405,6 +405,7 @@ function foo1( echo "text ${foo[foo]} text"; echo "text ${foo[call()]} text"; echo "text ${foo[$var ? 'foo' : 'bar']} text"; +echo "text ${foo[$index_var]} text"; // T_CURLY_OPEN variable '}' echo "text {$var} text";