Skip to content

Commit a3f0761

Browse files
committed
Fix generator for PHP >= 8.4 #624
1 parent ae18dbc commit a3f0761

File tree

2 files changed

+17
-5
lines changed

2 files changed

+17
-5
lines changed

spec/Prophecy/Doubler/Generator/ClassCodeGeneratorSpec.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,7 @@ class CustomClass extends \RuntimeException implements \Prophecy\Doubler\Generat
116116
public $name;
117117
private $email;
118118
119-
public static function getName(array $fullname = NULL, \ReflectionClass $class, object $instance): ?string {
119+
public static function getName(?array $fullname = NULL, \ReflectionClass $class, object $instance): ?string {
120120
return $this->name;
121121
}
122122
protected function getEmail(?string $default = '[email protected]') {
@@ -272,7 +272,7 @@ function it_overrides_properly_methods_with_args_passed_by_reference(
272272
namespace {
273273
class CustomClass extends \RuntimeException implements \Prophecy\Doubler\Generator\MirroredInterface {
274274
275-
public function getName(array &$fullname = NULL) {
275+
public function getName(?array &$fullname = NULL) {
276276
return $this->name;
277277
}
278278

src/Prophecy/Doubler/Generator/ClassCodeGenerator.php

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111

1212
namespace Prophecy\Doubler\Generator;
1313

14+
use Prophecy\Doubler\Generator\Node\ArgumentTypeNode;
1415
use Prophecy\Doubler\Generator\Node\ReturnTypeNode;
1516
use Prophecy\Doubler\Generator\Node\TypeNodeAbstract;
1617

@@ -78,14 +79,14 @@ private function generateMethod(Node\MethodNode $method): string
7879
return $php.'}';
7980
}
8081

81-
private function generateTypes(TypeNodeAbstract $typeNode): string
82+
private function generateTypes(TypeNodeAbstract $typeNode, bool $nullable = FALSE): string
8283
{
8384
if (!$typeNode->getTypes()) {
8485
return '';
8586
}
8687

8788
// When we require PHP 8 we can stop generating ?foo nullables and remove this first block
88-
if ($typeNode->canUseNullShorthand()) {
89+
if ($typeNode->canUseNullShorthand() || $nullable) {
8990
return sprintf( '?%s', $typeNode->getNonNullTypes()[0]);
9091
} else {
9192
return join('|', $typeNode->getTypes());
@@ -101,7 +102,18 @@ private function generateArguments(array $arguments): array
101102
{
102103
return array_map(function (Node\ArgumentNode $argument){
103104

104-
$php = $this->generateTypes($argument->getTypeNode());
105+
if ($nullable = $argument->isOptional() && $argument->getDefault() === NULL) {
106+
$types = $argument->getTypeNode()->getTypes();
107+
$count = \count($types);
108+
if ($count === 1 && $types[0] === 'mixed' ) {
109+
$nullable = FALSE;
110+
}
111+
elseif ($count > 1 && !isset($types['null'])) {
112+
$argument->setTypeNode(new ArgumentTypeNode('null', ...$types));
113+
$nullable = FALSE;
114+
}
115+
}
116+
$php = $this->generateTypes($argument->getTypeNode(), $nullable);
105117

106118
$php .= ' '.($argument->isPassedByReference() ? '&' : '');
107119

0 commit comments

Comments
 (0)