11
11
12
12
namespace Prophecy \Doubler \Generator ;
13
13
14
+ use Prophecy \Doubler \Generator \Node \ArgumentTypeNode ;
14
15
use Prophecy \Doubler \Generator \Node \ReturnTypeNode ;
15
16
use Prophecy \Doubler \Generator \Node \TypeNodeAbstract ;
16
17
@@ -78,14 +79,14 @@ private function generateMethod(Node\MethodNode $method): string
78
79
return $ php .'} ' ;
79
80
}
80
81
81
- private function generateTypes (TypeNodeAbstract $ typeNode ): string
82
+ private function generateTypes (TypeNodeAbstract $ typeNode, bool $ nullable = FALSE ): string
82
83
{
83
84
if (!$ typeNode ->getTypes ()) {
84
85
return '' ;
85
86
}
86
87
87
88
// 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 ) {
89
90
return sprintf ( '?%s ' , $ typeNode ->getNonNullTypes ()[0 ]);
90
91
} else {
91
92
return join ('| ' , $ typeNode ->getTypes ());
@@ -101,7 +102,18 @@ private function generateArguments(array $arguments): array
101
102
{
102
103
return array_map (function (Node \ArgumentNode $ argument ){
103
104
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 );
105
117
106
118
$ php .= ' ' .($ argument ->isPassedByReference () ? '& ' : '' );
107
119
0 commit comments