Skip to content

Commit 109db11

Browse files
czoselcseufert
andauthored
feat: PHP8 Promoted Props / Match Statement / Throw Statement / Union Types (#1753)
* Added support for PHP 8 promoted properties * Added tests for Throw as expression * added support for match statement * added support for union types * remove useless test * added missing union tests * fix ci Co-authored-by: Chris Seufert <chris@modd.com.au>
1 parent 58ba9a9 commit 109db11

13 files changed

Lines changed: 259 additions & 3 deletions

File tree

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
"dependencies": {
1414
"linguist-languages": "^7.5.1",
1515
"mem": "^8.0.0",
16-
"php-parser": "czosel/php-parser#177699bf5f19b2ac4a95049fb19000fbc4ffa0fd"
16+
"php-parser": "https://github.com/glayzzle/php-parser#bb89fff"
1717
},
1818
"devDependencies": {
1919
"@babel/preset-env": "^7.7.5",

src/printer.js

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1753,7 +1753,16 @@ function printNode(path, options, print) {
17531753
path.call(print, "body"),
17541754
]);
17551755
case "parameter": {
1756+
let promoted = "";
1757+
if (node.flags === 1) {
1758+
promoted = "public ";
1759+
} else if (node.flags === 2) {
1760+
promoted = "protected ";
1761+
} else if (node.flags === 4) {
1762+
promoted = "private ";
1763+
}
17561764
const name = concat([
1765+
promoted,
17571766
node.nullable ? "?" : "",
17581767
node.type ? concat([path.call(print, "type"), " "]) : "",
17591768
node.byref ? "&" : "",
@@ -2847,6 +2856,17 @@ function printNode(path, options, print) {
28472856
quote,
28482857
]);
28492858
}
2859+
case "uniontype": {
2860+
return group(
2861+
concat(
2862+
path.map(
2863+
(uPath, i) =>
2864+
concat(i === 0 ? [path.call(print)] : ["|", path.call(print)]),
2865+
"types"
2866+
)
2867+
)
2868+
);
2869+
}
28502870
case "encapsedpart": {
28512871
const open =
28522872
(node.syntax === "simple" && node.curly) || node.syntax === "complex"
@@ -2925,6 +2945,50 @@ function printNode(path, options, print) {
29252945

29262946
return path.call(print, "name");
29272947
}
2948+
case "match": {
2949+
const arms = path.map((armPath, armIdx) => {
2950+
const conds =
2951+
armPath.getValue().conds === null
2952+
? "default"
2953+
: concat(
2954+
armPath.map(
2955+
(condPath, condIdx) =>
2956+
group(
2957+
concat(
2958+
condIdx > 0
2959+
? [",", line, print(condPath)]
2960+
: [print(condPath)]
2961+
)
2962+
),
2963+
"conds"
2964+
)
2965+
);
2966+
const body = armPath.call(print, "body");
2967+
return concat(
2968+
armIdx > 0
2969+
? [", ", line, conds, " => ", body]
2970+
: [line, conds, " => ", body]
2971+
);
2972+
}, "arms");
2973+
return group(
2974+
concat([
2975+
"match (",
2976+
group(
2977+
concat([
2978+
softline,
2979+
indent(concat([path.call(print, "cond")])),
2980+
softline,
2981+
])
2982+
),
2983+
") {",
2984+
indent(concat(arms)),
2985+
" ",
2986+
softline,
2987+
"}",
2988+
])
2989+
);
2990+
}
2991+
29282992
case "noop":
29292993
return node.comments
29302994
? comments.printComments(path.getValue().comments, options)

tests/class/__snapshots__/jsfmt.spec.js.snap

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -929,6 +929,11 @@ class User {
929929
}
930930
}
931931
932+
class Promoted {
933+
public function __construct( public int $a, private float $b, protected string $d ){
934+
935+
}
936+
}
932937
=====================================output=====================================
933938
<?php
934939
@@ -1434,5 +1439,15 @@ class User
14341439
}
14351440
}
14361441
1442+
class Promoted
1443+
{
1444+
public function __construct(
1445+
public int $a,
1446+
private float $b,
1447+
protected string $d
1448+
) {
1449+
}
1450+
}
1451+
14371452
================================================================================
14381453
`;

tests/class/class.php

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -293,3 +293,9 @@ public function __construct(int $id, string $name) {
293293
$this->name = $name;
294294
}
295295
}
296+
297+
class Promoted {
298+
public function __construct( public int $a, private float $b, protected string $d ){
299+
300+
}
301+
}
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
// Jest Snapshot v1, https://goo.gl/fbAQLP
2+
3+
exports[`match.php 1`] = `
4+
====================================options=====================================
5+
parsers: ["php"]
6+
phpVersion: "8.0"
7+
printWidth: 80
8+
| printWidth
9+
=====================================input======================================
10+
<?php
11+
12+
$really_really_really_long_variable_name = match(getValue()) {
13+
true => implode(',',[1,2,3]),
14+
false => $a || 'Empty',
15+
null => null,
16+
default => throw new \\InvalidArgumentException('Unknown Value'),
17+
};
18+
19+
$boolStr = match($v) {true => 'true', false => 'false'};
20+
21+
$boolish = match($v) {
22+
true, 1 => true,
23+
false,0,'',null => false,
24+
default => null
25+
};
26+
27+
$a = match(true) {
28+
test() => 'Good',
29+
test2() => 'Two',
30+
default => 'fail'
31+
};
32+
33+
$nest = match(match($a) {true => 1, false => 2}) {
34+
1 => match($b) {
35+
'ok' => true,
36+
'fail' => false,
37+
default => false
38+
},
39+
2 => 'null'
40+
};
41+
=====================================output=====================================
42+
<?php
43+
44+
$really_really_really_long_variable_name = match (getValue()) {
45+
true => implode(",", [1, 2, 3]),
46+
false => $a || "Empty",
47+
null => null,
48+
default => throw new \\InvalidArgumentException("Unknown Value")
49+
};
50+
51+
$boolStr = match ($v) { true => "true", false => "false" };
52+
53+
$boolish = match ($v) {
54+
true, 1 => true,
55+
false, 0, "", null => false,
56+
default => null
57+
};
58+
59+
$a = match (true) { test() => "Good", test2() => "Two", default => "fail" };
60+
61+
$nest = match (match ($a) { true => 1, false => 2 }) {
62+
1 => match ($b) { "ok" => true, "fail" => false, default => false },
63+
2 => "null"
64+
};
65+
66+
================================================================================
67+
`;

tests/match/jsfmt.spec.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
run_spec(__dirname, ["php"], { phpVersion: "8.0" });

tests/match/match.php

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
<?php
2+
3+
$really_really_really_long_variable_name = match(getValue()) {
4+
true => implode(',',[1,2,3]),
5+
false => $a || 'Empty',
6+
null => null,
7+
default => throw new \InvalidArgumentException('Unknown Value'),
8+
};
9+
10+
$boolStr = match($v) {true => 'true', false => 'false'};
11+
12+
$boolish = match($v) {
13+
true, 1 => true,
14+
false,0,'',null => false,
15+
default => null
16+
};
17+
18+
$a = match(true) {
19+
test() => 'Good',
20+
test2() => 'Two',
21+
default => 'fail'
22+
};
23+
24+
$nest = match(match($a) {true => 1, false => 2}) {
25+
1 => match($b) {
26+
'ok' => true,
27+
'fail' => false,
28+
default => false
29+
},
30+
2 => 'null'
31+
};

tests/parens/__snapshots__/jsfmt.spec.js.snap

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3172,6 +3172,9 @@ if (!$var) {
31723172
throw (new \\Exception("Bye"));
31733173
}
31743174
3175+
die(throw new \\Exception('In Statement'));
3176+
$throws = fn() => throw new \\RuntimeException('In arrow function');
3177+
$value = $a ? $a : throw new \\InvalidArgumentException('In ternary');
31753178
=====================================output=====================================
31763179
<?php
31773180
@@ -3191,6 +3194,10 @@ if (!$var) {
31913194
throw new \\Exception("Bye");
31923195
}
31933196
3197+
die(throw new \\Exception("In Statement"));
3198+
$throws = fn() => throw new \\RuntimeException("In arrow function");
3199+
$value = $a ? $a : throw new \\InvalidArgumentException("In ternary");
3200+
31943201
================================================================================
31953202
`;
31963203

tests/parens/throw.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,3 +15,7 @@
1515
throw new \Exception("Bye");
1616
throw (new \Exception("Bye"));
1717
}
18+
19+
die(throw new \Exception('In Statement'));
20+
$throws = fn() => throw new \RuntimeException('In arrow function');
21+
$value = $a ? $a : throw new \InvalidArgumentException('In ternary');
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
// Jest Snapshot v1, https://goo.gl/fbAQLP
2+
3+
exports[`union.php 1`] = `
4+
====================================options=====================================
5+
parsers: ["php"]
6+
phpVersion: "8.0"
7+
printWidth: 80
8+
| printWidth
9+
=====================================input======================================
10+
<?php
11+
function a(int|float $a):int|float {}
12+
13+
class UnionClass {
14+
public int|float $v = 0;
15+
16+
public function __construct(public bool|int $flag) {}
17+
18+
public function get():bool|int|float {}
19+
}
20+
21+
interface UnionInterface { function do(string|int $in):string|bool; }
22+
23+
=====================================output=====================================
24+
<?php
25+
function a(int|float $a): int|float
26+
{
27+
}
28+
29+
class UnionClass
30+
{
31+
public int|float $v = 0;
32+
33+
public function __construct(public bool|int $flag)
34+
{
35+
}
36+
37+
public function get(): bool|int|float
38+
{
39+
}
40+
}
41+
42+
interface UnionInterface
43+
{
44+
function do(string|int $in): string|bool;
45+
}
46+
47+
================================================================================
48+
`;

0 commit comments

Comments
 (0)