fix: handle parameter default object value compilation

This commit is contained in:
Romain Canon 2022-03-09 10:25:44 +01:00
parent e3592e18c5
commit fdef93074c
4 changed files with 46 additions and 1 deletions

View File

@ -6,6 +6,8 @@ namespace CuyZ\Valinor\Definition\Repository\Cache\Compiler;
use CuyZ\Valinor\Definition\ParameterDefinition;
use function is_scalar;
/** @internal */
final class ParameterDefinitionCompiler
{
@ -23,7 +25,7 @@ final class ParameterDefinitionCompiler
{
$isOptional = var_export($parameter->isOptional(), true);
$isVariadic = var_export($parameter->isVariadic(), true);
$defaultValue = var_export($parameter->defaultValue(), true);
$defaultValue = $this->defaultValue($parameter);
$type = $this->typeCompiler->compile($parameter->type());
$attributes = $this->attributesCompiler->compile($parameter->attributes());
@ -39,4 +41,13 @@ final class ParameterDefinitionCompiler
)
PHP;
}
private function defaultValue(ParameterDefinition $parameter): string
{
$defaultValue = $parameter->defaultValue();
return is_scalar($defaultValue)
? var_export($parameter->defaultValue(), true)
: 'unserialize(' . var_export(serialize($defaultValue), true) . ')';
}
}

View File

@ -4,6 +4,7 @@ declare(strict_types=1);
namespace CuyZ\Valinor\Tests\Fake\Type;
use CuyZ\Valinor\Tests\Fixture\Object\StringableObject;
use CuyZ\Valinor\Type\Type;
use CuyZ\Valinor\Type\Types\ArrayKeyType;
use CuyZ\Valinor\Type\Types\BooleanType;
@ -50,6 +51,10 @@ final class FakeType implements Type
return new ClassType(stdClass::class);
}
if ($raw === StringableObject::class) {
return new ClassType(StringableObject::class);
}
return new self();
}

View File

@ -0,0 +1,13 @@
<?php
declare(strict_types=1);
namespace CuyZ\Valinor\Tests\Fixture\Object;
final class ObjectWithParameterDefaultObjectValue
{
public function method(StringableObject $object = new StringableObject('bar')): StringableObject
{
return $object;
}
}

View File

@ -7,6 +7,7 @@ namespace CuyZ\Valinor\Tests\Functional\Definition\Repository\Cache\Compiler;
use CuyZ\Valinor\Definition\ClassDefinition;
use CuyZ\Valinor\Definition\Repository\Cache\Compiler\ClassDefinitionCompiler;
use CuyZ\Valinor\Tests\Fake\Definition\FakeClassDefinition;
use CuyZ\Valinor\Tests\Fixture\Object\ObjectWithParameterDefaultObjectValue;
use CuyZ\Valinor\Type\Types\NativeStringType;
use DateTime;
use Error;
@ -88,6 +89,21 @@ final class ClassDefinitionCompilerTest extends TestCase
self::assertTrue($variadic->isVariadic());
}
/**
* @PHP8.1 move to test above
*
* @requires PHP >= 8.1
*/
public function test_parameter_with_object_default_value_is_compiled_correctly(): void
{
$class = FakeClassDefinition::fromReflection(new ReflectionClass(ObjectWithParameterDefaultObjectValue::class));
$class = $this->eval($this->compiler->compile($class));
self::assertInstanceOf(ClassDefinition::class, $class);
self::assertSame(ObjectWithParameterDefaultObjectValue::class, $class->name());
}
public function test_modifying_class_definition_file_invalids_compiled_class_definition(): void
{
/** @var class-string $className */