Skip to content

Commit b3d66a2

Browse files
Allow short ternary for false
1 parent f9f77ef commit b3d66a2

File tree

3 files changed

+110
-5
lines changed

3 files changed

+110
-5
lines changed

src/Rules/DisallowedConstructs/DisallowedShortTernaryRule.php

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,10 @@
77
use PHPStan\Analyser\Scope;
88
use PHPStan\Rules\Rule;
99
use PHPStan\Rules\RuleErrorBuilder;
10+
use PHPStan\Type\Constant\ConstantBooleanType;
11+
use PHPStan\Type\StaticTypeFactory;
12+
use PHPStan\Type\Type;
13+
use PHPStan\Type\TypeCombinator;
1014

1115
/**
1216
* @implements Rule<Ternary>
@@ -25,11 +29,29 @@ public function processNode(Node $node, Scope $scope): array
2529
return [];
2630
}
2731

32+
if ($scope->getType($node->cond)->isSuperTypeOf($this->getNonBooleanFalseyType())->no()) {
33+
return [];
34+
}
35+
2836
return [
2937
RuleErrorBuilder::message('Short ternary operator is not allowed. Use null coalesce operator if applicable or consider using long ternary.')
3038
->identifier('ternary.shortNotAllowed')
3139
->build(),
3240
];
3341
}
3442

43+
private function getNonBooleanFalseyType(): Type
44+
{
45+
static $falseyWithoutFalse;
46+
47+
if ($falseyWithoutFalse === null) {
48+
$falseyWithoutFalse = TypeCombinator::remove(
49+
StaticTypeFactory::falsey(),
50+
new ConstantBooleanType(false),
51+
);
52+
}
53+
54+
return $falseyWithoutFalse;
55+
}
56+
3557
}

tests/Rules/DisallowedConstructs/DisallowedShortTernaryRuleTest.php

Lines changed: 34 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,11 +21,43 @@ public function testRule(): void
2121
$this->analyse([__DIR__ . '/data/short-ternary.php'], [
2222
[
2323
'Short ternary operator is not allowed. Use null coalesce operator if applicable or consider using long ternary.',
24-
3,
24+
6,
2525
],
2626
[
2727
'Short ternary operator is not allowed. Use null coalesce operator if applicable or consider using long ternary.',
28-
4,
28+
7,
29+
],
30+
[
31+
'Short ternary operator is not allowed. Use null coalesce operator if applicable or consider using long ternary.',
32+
13,
33+
],
34+
[
35+
'Short ternary operator is not allowed. Use null coalesce operator if applicable or consider using long ternary.',
36+
14,
37+
],
38+
[
39+
'Short ternary operator is not allowed. Use null coalesce operator if applicable or consider using long ternary.',
40+
31,
41+
],
42+
[
43+
'Short ternary operator is not allowed. Use null coalesce operator if applicable or consider using long ternary.',
44+
32,
45+
],
46+
[
47+
'Short ternary operator is not allowed. Use null coalesce operator if applicable or consider using long ternary.',
48+
37,
49+
],
50+
[
51+
'Short ternary operator is not allowed. Use null coalesce operator if applicable or consider using long ternary.',
52+
38,
53+
],
54+
[
55+
'Short ternary operator is not allowed. Use null coalesce operator if applicable or consider using long ternary.',
56+
49,
57+
],
58+
[
59+
'Short ternary operator is not allowed. Use null coalesce operator if applicable or consider using long ternary.',
60+
50,
2961
],
3062
]);
3163
}
Lines changed: 54 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,56 @@
11
<?php
22

3-
$foo = 123 ?: 456;
4-
$bar = 123 ? : 456;
5-
$baz = 123 ? 456 : 789;
3+
/** @var int $cond */
4+
$cond = 123;
5+
6+
$foo = $cond ?: 456;
7+
$bar = $cond ? : 456;
8+
$baz = $cond ? 456 : 789;
9+
10+
/** @var int|false $cond */
11+
$cond = 123;
12+
13+
$foo = $cond ?: 456;
14+
$bar = $cond ? : 456;
15+
16+
/** @var positive-int|false $ */
17+
$cond = 123;
18+
19+
$foo = $cond ?: 456;
20+
$bar = $cond ? : 456;
21+
22+
/** @var object|false $ */
23+
$cond = 123;
24+
25+
$foo = $cond ?: 456;
26+
$bar = $cond ? : 456;
27+
28+
/** @var string|false $ */
29+
$cond = '123';
30+
31+
$foo = $cond ?: 456;
32+
$bar = $cond ? : 456;
33+
34+
/** @var non-empty-string|false $ */
35+
$cond = '123';
36+
37+
$foo = $cond ?: 456;
38+
$bar = $cond ? : 456;
39+
40+
/** @var non-falsy-string|false $ */
41+
$cond = '123';
42+
43+
$foo = $cond ?: 456;
44+
$bar = $cond ? : 456;
45+
46+
/** @var array|false $ */
47+
$cond = [123];
48+
49+
$foo = $cond ?: 456;
50+
$bar = $cond ? : 456;
51+
52+
/** @var non-empty-array|false $ */
53+
$cond = [123];
54+
55+
$foo = $cond ?: 456;
56+
$bar = $cond ? : 456;

0 commit comments

Comments
 (0)