10
10
11
11
use function explode ;
12
12
use function implode ;
13
+ use function in_array ;
13
14
use function preg_replace ;
14
15
use function preg_split ;
15
16
use function rtrim ;
16
17
use function substr ;
17
18
use function var_export ;
18
19
19
20
use const PREG_SPLIT_DELIM_CAPTURE ;
21
+ use const PREG_SPLIT_NO_EMPTY ;
20
22
21
23
/**
22
24
* @internal do not use this in your code: it is only here for internal use
@@ -50,16 +52,20 @@ public function generate(): string
50
52
return parent ::generate ();
51
53
} catch (RuntimeException $ e ) {
52
54
if ($ this ->reflection ) {
53
- $ value = rtrim ( substr ( explode ( ' $ ' . $ this ->reflection -> getName () . ' = ' , ( string ) $ this -> reflection , 2 )[ 1 ], 0 , - 2 ) );
55
+ $ value = self :: exportDefault ( $ this ->reflection );
54
56
} else {
55
57
$ value = var_export ($ this ->value , true );
58
+
59
+ if (\PHP_VERSION_ID < 80200 ) {
60
+ return self ::fixVarExport ($ value );
61
+ }
56
62
}
57
63
58
- return self :: fixExport ( $ value) ;
64
+ return $ value ;
59
65
}
60
66
}
61
67
62
- private static function fixExport (string $ value ): string
68
+ private static function fixVarExport (string $ value ): string
63
69
{
64
70
$ parts = preg_split ('{( \'(?:[^ \'\\\\]*(?: \\\\.[^ \'\\\\]*)*) \')} ' , $ value , -1 , PREG_SPLIT_DELIM_CAPTURE );
65
71
@@ -73,4 +79,47 @@ private static function fixExport(string $value): string
73
79
74
80
return implode ('' , $ parts );
75
81
}
82
+
83
+ private static function exportDefault (\ReflectionParameter $ param ): string
84
+ {
85
+ $ default = rtrim (substr (explode ('$ ' .$ param ->name .' = ' , (string ) $ param , 2 )[1 ] ?? '' , 0 , -2 ));
86
+
87
+ if (in_array ($ default , ['<default> ' , 'NULL ' ], true )) {
88
+ return 'null ' ;
89
+ }
90
+ if (str_ends_with ($ default , "...' " ) && preg_match ("/^'(?:[^' \\\\]*+(?: \\\\.)*+)*+'$/ " , $ default )) {
91
+ return var_export ($ param ->getDefaultValue (), true );
92
+ }
93
+
94
+ $ regexp = "/( \"(?:[^ \"\\\\]*+(?: \\\\.)*+)*+ \"|'(?:[^' \\\\]*+(?: \\\\.)*+)*+')/ " ;
95
+ $ parts = preg_split ($ regexp , $ default , -1 , PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY );
96
+
97
+ $ regexp = '/([\[\( ]|^)([a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*+(?: \\\\[a-zA-Z0-9_\x7f-\xff]++)*+)(?!: )/ ' ;
98
+ $ callback = (false !== strpbrk ($ default , "\\:(' " ) && $ class = $ param ->getDeclaringClass ())
99
+ ? function ($ m ) use ($ class ) {
100
+ switch ($ m [2 ]) {
101
+ case 'new ' : case 'false ' : case 'true ' : case 'null ' : return $ m [1 ].$ m [2 ];
102
+ case 'NULL ' : return $ m [1 ].'null ' ;
103
+ case 'self ' : return $ m [1 ].'\\' .$ class ->name ;
104
+ case 'namespace \\parent ' :
105
+ case 'parent ' : $ m [1 ].(($ parent = $ class ->getParentClass ()) ? '\\' .$ parent ->name : 'parent ' );
106
+ default : return $ m [1 ].'\\' .$ m [2 ];
107
+ }
108
+ }
109
+ : function ($ m ) {
110
+ switch ($ m [2 ]) {
111
+ case 'new ' : case 'false ' : case 'true ' : case 'null ' : return $ m [1 ].$ m [2 ];
112
+ case 'NULL ' : return $ m [1 ].'null ' ;
113
+ default : return $ m [1 ].'\\' .$ m [2 ];
114
+ }
115
+ };
116
+
117
+ return implode ('' , array_map (function ($ part ) use ($ regexp , $ callback ) {
118
+ switch ($ part [0 ]) {
119
+ case '" ' : return $ part ; // for internal classes only
120
+ case "' " : return false !== strpbrk ($ part , "\\\0\r\n" ) ? '" ' .substr (str_replace (['$ ' , "\0" , "\r" , "\n" ], ['\$ ' , '\0 ' , '\r ' , '\n ' ], $ part ), 1 , -1 ).'" ' : $ part ;
121
+ default : return preg_replace_callback ($ regexp , $ callback , $ part );
122
+ }
123
+ }, $ parts ));
124
+ }
76
125
}
0 commit comments