From 0479532fbc96fca35dcbfb4c1f5a9ef63e7625c5 Mon Sep 17 00:00:00 2001 From: Romain Canon Date: Mon, 19 Aug 2024 16:04:13 +0200 Subject: [PATCH] misc: move "float type accepting integer value" logic in `Shell` --- src/Mapper/Tree/Builder/TreeNode.php | 9 --------- src/Mapper/Tree/Shell.php | 9 +++++++++ src/Type/Types/NativeFloatType.php | 3 +-- tests/Unit/Type/Types/NativeFloatTypeTest.php | 2 +- 4 files changed, 11 insertions(+), 12 deletions(-) diff --git a/src/Mapper/Tree/Builder/TreeNode.php b/src/Mapper/Tree/Builder/TreeNode.php index ae31fdb5..3b37d5ee 100644 --- a/src/Mapper/Tree/Builder/TreeNode.php +++ b/src/Mapper/Tree/Builder/TreeNode.php @@ -9,7 +9,6 @@ use CuyZ\Valinor\Mapper\Tree\Message\Message; use CuyZ\Valinor\Mapper\Tree\Node; use CuyZ\Valinor\Mapper\Tree\Shell; -use CuyZ\Valinor\Type\FloatType; use CuyZ\Valinor\Type\Type; use Throwable; @@ -35,14 +34,6 @@ final class TreeNode private function __construct(Shell $shell, mixed $value) { - // When the value is an integer and the type is a float, the value needs - // to be cast to float — this special case needs to be handled in case a - // node is not a *native* PHP float type (for instance a class property - // with a `@var float` annotation). - if ($shell->type() instanceof FloatType && is_int($value)) { - $value = (float)$value; - } - $this->shell = $shell; $this->value = $value; } diff --git a/src/Mapper/Tree/Shell.php b/src/Mapper/Tree/Shell.php index f7e2235a..32c2d131 100644 --- a/src/Mapper/Tree/Shell.php +++ b/src/Mapper/Tree/Shell.php @@ -7,6 +7,7 @@ use CuyZ\Valinor\Definition\Attributes; use CuyZ\Valinor\Library\Settings; use CuyZ\Valinor\Mapper\Tree\Exception\UnresolvableShellType; +use CuyZ\Valinor\Type\FloatType; use CuyZ\Valinor\Type\Type; use CuyZ\Valinor\Type\Types\UnresolvableType; @@ -87,6 +88,14 @@ public function type(): Type public function withValue(mixed $value): self { + // When the value is an integer and the type is a float, the value is + // cast to float, to follow the rule of PHP regarding acceptance of an + // integer value in a float type. Note that PHPStan/Psalm analysis + // applies the same rule. + if ($this->type instanceof FloatType && is_int($value)) { + $value = (float)$value; + } + $clone = clone $this; $clone->hasValue = true; $clone->value = $value; diff --git a/src/Type/Types/NativeFloatType.php b/src/Type/Types/NativeFloatType.php index 4d5be2b5..2545d312 100644 --- a/src/Type/Types/NativeFloatType.php +++ b/src/Type/Types/NativeFloatType.php @@ -12,7 +12,6 @@ use function assert; use function is_float; -use function is_integer; use function is_numeric; /** @internal */ @@ -22,7 +21,7 @@ final class NativeFloatType implements FloatType public function accepts(mixed $value): bool { - return is_float($value) || is_integer($value); + return is_float($value); } public function matches(Type $other): bool diff --git a/tests/Unit/Type/Types/NativeFloatTypeTest.php b/tests/Unit/Type/Types/NativeFloatTypeTest.php index 8a59298a..fe1623cd 100644 --- a/tests/Unit/Type/Types/NativeFloatTypeTest.php +++ b/tests/Unit/Type/Types/NativeFloatTypeTest.php @@ -30,13 +30,13 @@ protected function setUp(): void public function test_accepts_correct_values(): void { self::assertTrue($this->floatType->accepts(42.1337)); - self::assertTrue($this->floatType->accepts(404)); } public function test_does_not_accept_incorrect_values(): void { self::assertFalse($this->floatType->accepts(null)); self::assertFalse($this->floatType->accepts('Schwifty!')); + self::assertFalse($this->floatType->accepts(404)); self::assertFalse($this->floatType->accepts(['foo' => 'bar'])); self::assertFalse($this->floatType->accepts(false)); self::assertFalse($this->floatType->accepts(new stdClass()));