diff --git a/src/Generator/DefaultArgumentGenerator.php b/src/Generator/DefaultArgumentGenerator.php index 891c4b77..ef41305a 100644 --- a/src/Generator/DefaultArgumentGenerator.php +++ b/src/Generator/DefaultArgumentGenerator.php @@ -88,7 +88,8 @@ trait DefaultArgumentGenerator $code .= 'return ' . $plan->expr . ';' . PHP_EOL; } } else { - $code .= 'return ' . $argInfo->default . ';' . PHP_EOL; + $default = $this->convertRuntimeConstantDefault($type, $argInfo->default); + $code .= 'return ' . $default . ';' . PHP_EOL; } $code .= '}' . PHP_EOL . PHP_EOL; @@ -98,6 +99,28 @@ trait DefaultArgumentGenerator return $code; } + /** + * Runtime constant lookup returns Variant, but a typed default helper must + * return its native C++ type explicitly. Convert the complete expression so + * constants nested in expressions are covered as well. + */ + private function convertRuntimeConstantDefault(string $type, string $default): string + { + if (!str_contains($default, 'php::constant(')) { + return $default; + } + + return match ($type) { + Type::INT => 'php::toInt(' . $default . ')', + Type::FLOAT => 'php::toFloat(' . $default . ')', + Type::BOOL => 'php::toBool(' . $default . ')', + Type::STR => 'php::toString(' . $default . ')', + Type::ARRAY => 'php::toArray(' . $default . ')', + Type::OBJECT => 'php::toObject(' . $default . ')', + default => $default, + }; + } + private function shouldGenerateDefaultArgumentHelper(ArgInfo $argInfo): bool { if ($argInfo->variadic) { diff --git a/tests/compiler/const/class-const-default-value-typed.phpt b/tests/compiler/const/class-const-default-value-typed.phpt new file mode 100644 index 00000000..d9b5d26d --- /dev/null +++ b/tests/compiler/const/class-const-default-value-typed.phpt @@ -0,0 +1,30 @@ +--TEST-- +Typed parameter default value from an unresolvable (external) class constant +--FILE-- +run(); +} +?> +--EXPECT-- +int(2) +float(2) +string(13) "Y-m-d\TH:i:sP" +int(3) +int(1)