Skip to content

Commit a7f1295

Browse files
herndlmondrejmirtes
authored andcommitted
Support allNullOr*
1 parent 08d2db4 commit a7f1295

File tree

4 files changed

+37
-6
lines changed

4 files changed

+37
-6
lines changed

README.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ This extension specifies types of values passed to:
8989
* `Assert::minLength`
9090
* `Assert::maxLength`
9191
* `Assert::lengthBetween`
92-
* `nullOr*` and `all*` variants of the above methods
92+
* `nullOr*`, `all*` and `allNullOr*` variants of the above methods
9393

9494

9595
## Installation

composer.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
"phpstan/phpstan-phpunit": "^1.0",
1616
"phpstan/phpstan-strict-rules": "^1.0",
1717
"phpunit/phpunit": "^9.5",
18-
"webmozart/assert": "^1.10.0"
18+
"webmozart/assert": "^1.11.0"
1919
},
2020
"config": {
2121
"platform": {

src/Type/WebMozartAssert/AssertTypeSpecifyingExtension.php

+23-4
Original file line numberDiff line numberDiff line change
@@ -111,10 +111,11 @@ public function isStaticMethodSupported(
111111

112112
private static function trimName(string $name): string
113113
{
114-
if (substr($name, 0, 6) === 'nullOr') {
114+
if (substr($name, 0, 9) === 'allNullOr') {
115+
$name = substr($name, 9);
116+
} elseif (substr($name, 0, 6) === 'nullOr') {
115117
$name = substr($name, 6);
116-
}
117-
if (substr($name, 0, 3) === 'all') {
118+
} elseif (substr($name, 0, 3) === 'all') {
118119
$name = substr($name, 3);
119120
}
120121

@@ -128,6 +129,17 @@ public function specifyTypes(
128129
TypeSpecifierContext $context
129130
): SpecifiedTypes
130131
{
132+
if (substr($staticMethodReflection->getName(), 0, 9) === 'allNullOr') {
133+
return $this->handleAll(
134+
$staticMethodReflection->getName(),
135+
$node,
136+
$scope,
137+
static function (Type $type) {
138+
return TypeCombinator::addNull($type);
139+
}
140+
);
141+
}
142+
131143
if (substr($staticMethodReflection->getName(), 0, 6) === 'allNot') {
132144
return $this->handleAllNot(
133145
$staticMethodReflection->getName(),
@@ -766,10 +778,14 @@ static function (Type $type) use ($valueType): Type {
766778
throw new ShouldNotHappenException();
767779
}
768780

781+
/**
782+
* @param callable(Type): Type|null $typeModifier
783+
*/
769784
private function handleAll(
770785
string $methodName,
771786
StaticCall $node,
772-
Scope $scope
787+
Scope $scope,
788+
?callable $typeModifier = null
773789
): SpecifiedTypes
774790
{
775791
$args = $node->getArgs();
@@ -792,6 +808,9 @@ private function handleAll(
792808
}
793809

794810
$type = TypeCombinator::remove($type, $sureNotTypes[$exprStr][1] ?? new NeverType());
811+
if ($typeModifier !== null) {
812+
$type = $typeModifier($type);
813+
}
795814

796815
return $this->arrayOrIterable(
797816
$scope,

tests/Type/WebMozartAssert/data/collection.php

+12
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,18 @@ public function allCount(array $a): void
130130
assertType('array<non-empty-array>', $a);
131131
}
132132

133+
public function allNullOr(array $a, iterable $b, $c): void
134+
{
135+
Assert::allNullOrStringNotEmpty($a);
136+
assertType('array<non-empty-string|null>', $a);
137+
138+
Assert::allNullOrIsInstanceOf($b, stdClass::class);
139+
assertType('iterable<stdClass|null>', $b);
140+
141+
Assert::allNullOrScalar($c);
142+
assertType('iterable<bool|float|int|string|null>', $c);
143+
}
144+
133145
}
134146

135147
class CollectionFoo

0 commit comments

Comments
 (0)