Repository: prettier/plugin-php
Pull request #588 (2018-09-07 16:42:19)

feat: better print yield node
We always wrap yield in parens in many cases to avoid `Caution` from http://php.net/manual/en/language.generators.syntax.php and don't break code for `php5` and `php7`


Patch:
diff --git a/src/needs-parens.js b/src/needs-parens.js
index 086cc63..675b5c4 100644
--- a/src/needs-parens.js
+++ b/src/needs-parens.js
@@ -73,6 +73,21 @@ function needsParens(path) {
 
       return false;
     }
+    case "yield": {
+      switch (parent.kind) {
+        case "propertylookup":
+        case "staticlookup":
+        case "offsetlookup":
+        case "call":
+          return name === "what" && parent.what === node;
+
+        case "retif":
+          return parent.test === node;
+
+        default:
+          return !!(node.key || node.value);
+      }
+    }
     case "assign": {
       if (
         parent.kind === "for" &&
diff --git a/src/printer.js b/src/printer.js
index 7544143..1adfc4a 100644
--- a/src/printer.js
+++ b/src/printer.js
@@ -2137,7 +2137,8 @@ function printNode(path, options, print) {
     }
     case "yield":
       return concat([
-        "yield ",
+        "yield",
+        node.key || node.value ? " " : "",
         node.key ? concat([path.call(print, "key"), " => "]) : "",
         path.call(print, "value")
       ]);


Test patch:
diff --git a/tests/parens/__snapshots__/jsfmt.spec.js.snap b/tests/parens/__snapshots__/jsfmt.spec.js.snap
index 5ec4492..91ab7d9 100644
--- a/tests/parens/__snapshots__/jsfmt.spec.js.snap
+++ b/tests/parens/__snapshots__/jsfmt.spec.js.snap
@@ -1142,3 +1142,93 @@ function foo($a = 1, $b = 'string', $c = true, $d = __LINE__)
 }
 
 `;
+
+exports[`yield.php 1`] = `
+<?php
+
+function gen_one_to_three() {
+    for ($i = 1; $i <= 3; $i++) {
+        yield;
+        yield $i;
+        (yield $i);
+        yield from from();
+        (yield from from());
+        (yield f())->b;
+        !(yield $var);
+        yield (yield $var);
+    }
+
+    $var = yield;
+    $var = yield $var;
+    $var += yield $var;
+    $var = (yield $var);
+    $var += (yield $var);
+    $var = yield $key => $var;
+    $var = (yield $key => $var);
+    $var = !yield $var;
+    $var = !(yield $var);
+    $var = yield (yield $var);
+    $var = yield 1 ? 1 : 1;
+    $var = (yield 1) ? 1 : 1;
+    $var = yield 1 ? yield 1 : yield 1;
+    $var = (yield 1) ? (yield 1) : (yield 1);
+    $var = yield $var->b;
+    $var = (yield $var)->b;
+    $var = yield $var->b();
+    $var = (yield $var)->b();
+    $var = yield $var[1];
+    $var = (yield $var)[1];
+
+    call(yield $var);
+
+    return yield from nine_ten();
+
+    foreach($SubTrav as $SubItem) yield $SubItem;
+}
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+<?php
+
+function gen_one_to_three()
+{
+    for ($i = 1; $i <= 3; $i++) {
+        yield;
+        yield $i;
+        yield $i;
+        yield from from();
+        yield from from();
+        (yield f())->b;
+        !(yield $var);
+        yield (yield $var);
+    }
+
+    $var = yield;
+    $var = (yield $var);
+    $var += (yield $var);
+    $var = (yield $var);
+    $var += (yield $var);
+    $var = (yield $key => $var);
+    $var = (yield $key => $var);
+    $var = !(yield $var);
+    $var = !(yield $var);
+    $var = (yield (yield $var));
+    $var = (yield 1 ? 1 : 1);
+    $var = (yield 1) ? 1 : 1;
+    $var = (yield 1 ? yield 1 : yield 1);
+    $var = (yield 1) ? yield 1 : yield 1;
+    $var = (yield $var->b);
+    $var = (yield $var)->b;
+    $var = (yield $var->b());
+    $var = (yield $var)->b();
+    $var = (yield $var[1]);
+    $var = (yield $var)[1];
+
+    call(yield $var);
+
+    return yield from nine_ten();
+
+    foreach ($SubTrav as $SubItem) {
+        yield $SubItem;
+    }
+}
+
+`;
diff --git a/tests/parens/yield.php b/tests/parens/yield.php
new file mode 100644
index 0000000..82a1aec
--- /dev/null
+++ b/tests/parens/yield.php
@@ -0,0 +1,41 @@
+<?php
+
+function gen_one_to_three() {
+    for ($i = 1; $i <= 3; $i++) {
+        yield;
+        yield $i;
+        (yield $i);
+        yield from from();
+        (yield from from());
+        (yield f())->b;
+        !(yield $var);
+        yield (yield $var);
+    }
+
+    $var = yield;
+    $var = yield $var;
+    $var += yield $var;
+    $var = (yield $var);
+    $var += (yield $var);
+    $var = yield $key => $var;
+    $var = (yield $key => $var);
+    $var = !yield $var;
+    $var = !(yield $var);
+    $var = yield (yield $var);
+    $var = yield 1 ? 1 : 1;
+    $var = (yield 1) ? 1 : 1;
+    $var = yield 1 ? yield 1 : yield 1;
+    $var = (yield 1) ? (yield 1) : (yield 1);
+    $var = yield $var->b;
+    $var = (yield $var)->b;
+    $var = yield $var->b();
+    $var = (yield $var)->b();
+    $var = yield $var[1];
+    $var = (yield $var)[1];
+
+    call(yield $var);
+
+    return yield from nine_ten();
+
+    foreach($SubTrav as $SubItem) yield $SubItem;
+}
diff --git a/tests/yield/__snapshots__/jsfmt.spec.js.snap b/tests/yield/__snapshots__/jsfmt.spec.js.snap
index fcd0947..56b1dd0 100644
--- a/tests/yield/__snapshots__/jsfmt.spec.js.snap
+++ b/tests/yield/__snapshots__/jsfmt.spec.js.snap
@@ -3,10 +3,13 @@
 exports[`yield.php 1`] = `
 <?php
 function from() {
+  yield;
   yield 1;
   yield 2;
   yield 3;
   yield $test => 3;
+  yield [$i++, $value];
+  yield $arr->current();
 }
 function gen() {
   yield 0;
@@ -22,14 +25,46 @@ function gen_one_to_three() {
         yield from $veryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryLongObjName->veryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryLongMethod();
     }
 }
+
+function count_to_ten() {
+    yield 1;
+    yield 2;
+    yield from [3, 4];
+    yield from new ArrayIterator([5, 6]);
+    yield from seven_eight();
+    yield 9;
+    yield 10;
+}
+
+function seven_eight() {
+    yield 7;
+    yield from eight();
+}
+
+function eight() {
+    yield 8;
+}
+
+function count_to_ten() {
+    yield 1;
+    yield 2;
+    yield from [3, 4];
+    yield from new ArrayIterator([5, 6]);
+    yield from seven_eight();
+
+    return yield from nine_ten();
+}
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 <?php
 function from()
 {
+    yield;
     yield 1;
     yield 2;
     yield 3;
     yield $test => 3;
+    yield [$i++, $value];
+    yield $arr->current();
 }
 function gen()
 {
@@ -47,4 +82,37 @@ function gen_one_to_three()
     }
 }
 
+function count_to_ten()
+{
+    yield 1;
+    yield 2;
+    yield from [3, 4];
+    yield from new ArrayIterator([5, 6]);
+    yield from seven_eight();
+    yield 9;
+    yield 10;
+}
+
+function seven_eight()
+{
+    yield 7;
+    yield from eight();
+}
+
+function eight()
+{
+    yield 8;
+}
+
+function count_to_ten()
+{
+    yield 1;
+    yield 2;
+    yield from [3, 4];
+    yield from new ArrayIterator([5, 6]);
+    yield from seven_eight();
+
+    return yield from nine_ten();
+}
+
 `;
diff --git a/tests/yield/yield.php b/tests/yield/yield.php
index b255874..597e27c 100644
--- a/tests/yield/yield.php
+++ b/tests/yield/yield.php
@@ -1,9 +1,12 @@
 <?php
 function from() {
+  yield;
   yield 1;
   yield 2;
   yield 3;
   yield $test => 3;
+  yield [$i++, $value];
+  yield $arr->current();
 }
 function gen() {
   yield 0;
@@ -19,3 +22,32 @@ function gen_one_to_three() {
         yield from $veryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryLongObjName->veryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryLongMethod();
     }
 }
+
+function count_to_ten() {
+    yield 1;
+    yield 2;
+    yield from [3, 4];
+    yield from new ArrayIterator([5, 6]);
+    yield from seven_eight();
+    yield 9;
+    yield 10;
+}
+
+function seven_eight() {
+    yield 7;
+    yield from eight();
+}
+
+function eight() {
+    yield 8;
+}
+
+function count_to_ten() {
+    yield 1;
+    yield 2;
+    yield from [3, 4];
+    yield from new ArrayIterator([5, 6]);
+    yield from seven_eight();
+
+    return yield from nine_ten();
+}