@@ -29,22 +29,39 @@ final class Dumper
2929 */
3030 public function dump ($ var ): string
3131 {
32- return $ this ->_dump ($ var );
32+ return $ this ->dumpVar ($ var );
3333 }
3434
3535
36- private function _dump (&$ var , int $ level = 0 )
36+ private function dumpVar (&$ var , int $ level = 0 ): string
3737 {
3838 if ($ var instanceof PhpLiteral) {
3939 return (string ) $ var ;
4040
41- } elseif (is_float ($ var )) {
42- return var_export ($ var , true );
43-
4441 } elseif ($ var === null ) {
4542 return 'null ' ;
4643
47- } elseif (is_string ($ var ) && (preg_match ('#[^\x09\x20-\x7E\xA0-\x{10FFFF}]#u ' , $ var ) || preg_last_error ())) {
44+ } elseif (is_string ($ var )) {
45+ return $ this ->dumpString ($ var );
46+
47+ } elseif (is_array ($ var )) {
48+ return $ this ->dumpArray ($ var , $ level );
49+
50+ } elseif (is_object ($ var )) {
51+ return $ this ->dumpObject ($ var , $ level );
52+
53+ } elseif (is_resource ($ var )) {
54+ throw new Nette \InvalidArgumentException ('Cannot dump resource. ' );
55+
56+ } else {
57+ return var_export ($ var , true );
58+ }
59+ }
60+
61+
62+ private function dumpString (string $ var ): string
63+ {
64+ if (preg_match ('#[^\x09\x20-\x7E\xA0-\x{10FFFF}]#u ' , $ var ) || preg_last_error ()) {
4865 static $ table ;
4966 if ($ table === null ) {
5067 foreach (array_merge (range ("\x00" , "\x1F" ), range ("\x7F" , "\xFF" )) as $ ch ) {
@@ -58,90 +75,90 @@ private function _dump(&$var, int $level = 0)
5875 $ table ['" ' ] = '\" ' ;
5976 }
6077 return '" ' . strtr ($ var , $ table ) . '" ' ;
78+ }
6179
62- } elseif ( is_string ( $ var )) {
63- return " ' " . preg_replace ( ' # \' | \\\\ (?=[ \'\\\\ ]|$)#D ' , '\\\\ $0 ' , $ var ) . " ' " ;
80+ return " ' " . preg_replace ( ' # \' | \\\\ (?=[ \'\\\\ ]|$)#D ' , '\\\\ $0 ' , $ var ) . " ' " ;
81+ }
6482
65- } elseif (is_array ($ var )) {
66- $ space = str_repeat ("\t" , $ level );
6783
68- static $ marker ;
69- if ($ marker === null ) {
70- $ marker = uniqid ("\x00" , true );
71- }
72- if (empty ($ var )) {
73- $ out = '' ;
74-
75- } elseif ($ level > self ::MAX_DEPTH || isset ($ var [$ marker ])) {
76- throw new Nette \InvalidArgumentException ('Nesting level too deep or recursive dependency. ' );
77-
78- } else {
79- $ out = '' ;
80- $ outWrapped = "\n$ space " ;
81- $ var [$ marker ] = true ;
82- $ counter = 0 ;
83- foreach ($ var as $ k => &$ v ) {
84- if ($ k !== $ marker ) {
85- $ item = ($ k === $ counter ? '' : $ this ->_dump ($ k , $ level + 1 ) . ' => ' ) . $ this ->_dump ($ v , $ level + 1 );
86- $ counter = is_int ($ k ) ? max ($ k + 1 , $ counter ) : $ counter ;
87- $ out .= ($ out === '' ? '' : ', ' ) . $ item ;
88- $ outWrapped .= "\t$ item, \n$ space " ;
89- }
90- }
91- unset($ var [$ marker ]);
84+ private function dumpArray (array &$ var , int $ level ): string
85+ {
86+ static $ marker ;
87+ if ($ marker === null ) {
88+ $ marker = uniqid ("\x00" , true );
89+ }
90+ if (empty ($ var )) {
91+ return '[] ' ;
92+
93+ } elseif ($ level > self ::MAX_DEPTH || isset ($ var [$ marker ])) {
94+ throw new Nette \InvalidArgumentException ('Nesting level too deep or recursive dependency. ' );
95+ }
96+
97+ $ space = str_repeat ("\t" , $ level );
98+ $ outInline = '' ;
99+ $ outWrapped = "\n$ space " ;
100+ $ var [$ marker ] = true ;
101+ $ counter = 0 ;
102+
103+ foreach ($ var as $ k => &$ v ) {
104+ if ($ k !== $ marker ) {
105+ $ item = ($ k === $ counter ? '' : $ this ->dumpVar ($ k , $ level + 1 ) . ' => ' ) . $ this ->dumpVar ($ v , $ level + 1 );
106+ $ counter = is_int ($ k ) ? max ($ k + 1 , $ counter ) : $ counter ;
107+ $ outInline .= ($ outInline === '' ? '' : ', ' ) . $ item ;
108+ $ outWrapped .= "\t$ item, \n$ space " ;
92109 }
93- $ wrap = strpos ($ out , "\n" ) !== false || strlen ($ out ) > self ::WRAP_LENGTH - $ level * self ::INDENT_LENGTH ;
94- return '[ ' . ($ wrap ? $ outWrapped : $ out ) . '] ' ;
110+ }
111+
112+ unset($ var [$ marker ]);
113+ $ wrap = strpos ($ outInline , "\n" ) !== false || strlen ($ outInline ) > self ::WRAP_LENGTH - $ level * self ::INDENT_LENGTH ;
114+ return '[ ' . ($ wrap ? $ outWrapped : $ outInline ) . '] ' ;
115+ }
116+
95117
96- } elseif ($ var instanceof \Serializable) {
97- $ var = serialize ($ var );
98- return 'unserialize( ' . $ this ->_dump ($ var , $ level ) . ') ' ;
118+ private function dumpObject (&$ var , int $ level ): string
119+ {
120+ if ($ var instanceof \Serializable) {
121+ return 'unserialize( ' . $ this ->dumpString (serialize ($ var )) . ') ' ;
99122
100123 } elseif ($ var instanceof \Closure) {
101124 throw new Nette \InvalidArgumentException ('Cannot dump closure. ' );
125+ }
102126
103- } elseif (is_object ($ var )) {
104- $ class = get_class ($ var );
105- if ((new \ReflectionObject ($ var ))->isAnonymous ()) {
106- throw new Nette \InvalidArgumentException ('Cannot dump anonymous class. ' );
127+ $ class = get_class ($ var );
128+ if ((new \ReflectionObject ($ var ))->isAnonymous ()) {
129+ throw new Nette \InvalidArgumentException ('Cannot dump anonymous class. ' );
107130
108- } elseif (in_array ($ class , ['DateTime ' , 'DateTimeImmutable ' ], true )) {
109- return $ this ->format ("new $ class(?, new DateTimeZone(?)) " , $ var ->format ('Y-m-d H:i:s.u ' ), $ var ->getTimeZone ()->getName ());
110- }
131+ } elseif (in_array ($ class , ['DateTime ' , 'DateTimeImmutable ' ], true )) {
132+ return $ this ->format ("new $ class(?, new DateTimeZone(?)) " , $ var ->format ('Y-m-d H:i:s.u ' ), $ var ->getTimeZone ()->getName ());
133+ }
111134
112- $ arr = (array ) $ var ;
113- $ space = str_repeat ("\t" , $ level );
135+ $ arr = (array ) $ var ;
136+ $ space = str_repeat ("\t" , $ level );
114137
115- static $ list = [];
116- if ($ level > self ::MAX_DEPTH || in_array ($ var , $ list , true )) {
117- throw new Nette \InvalidArgumentException ('Nesting level too deep or recursive dependency. ' );
138+ static $ list = [];
139+ if ($ level > self ::MAX_DEPTH || in_array ($ var , $ list , true )) {
140+ throw new Nette \InvalidArgumentException ('Nesting level too deep or recursive dependency. ' );
141+ }
118142
119- } else {
120- $ out = "\n" ;
121- $ list [] = $ var ;
122- if (method_exists ($ var , '__sleep ' )) {
123- foreach ($ var ->__sleep () as $ v ) {
124- $ props [$ v ] = $ props ["\x00* \x00$ v " ] = $ props ["\x00$ class \x00$ v " ] = true ;
125- }
126- }
127- foreach ($ arr as $ k => &$ v ) {
128- if (!isset ($ props ) || isset ($ props [$ k ])) {
129- $ out .= "$ space \t" . $ this ->_dump ($ k , $ level + 1 ) . ' => ' . $ this ->_dump ($ v , $ level + 1 ) . ", \n" ;
130- }
131- }
132- array_pop ($ list );
133- $ out .= $ space ;
143+ $ out = "\n" ;
144+ $ list [] = $ var ;
145+ if (method_exists ($ var , '__sleep ' )) {
146+ foreach ($ var ->__sleep () as $ v ) {
147+ $ props [$ v ] = $ props ["\x00* \x00$ v " ] = $ props ["\x00$ class \x00$ v " ] = true ;
134148 }
135- return $ class === 'stdClass '
136- ? "(object) [ $ out] "
137- : __CLASS__ . "::createObject(' $ class', [ $ out]) " ;
138-
139- } elseif (is_resource ($ var )) {
140- throw new Nette \InvalidArgumentException ('Cannot dump resource. ' );
149+ }
141150
142- } else {
143- return var_export ($ var , true );
151+ foreach ($ arr as $ k => &$ v ) {
152+ if (!isset ($ props ) || isset ($ props [$ k ])) {
153+ $ out .= "$ space \t" . $ this ->dumpVar ($ k , $ level + 1 ) . ' => ' . $ this ->dumpVar ($ v , $ level + 1 ) . ", \n" ;
154+ }
144155 }
156+
157+ array_pop ($ list );
158+ $ out .= $ space ;
159+ return $ class === 'stdClass '
160+ ? "(object) [ $ out] "
161+ : __CLASS__ . "::createObject(' $ class', [ $ out]) " ;
145162 }
146163
147164
@@ -191,7 +208,7 @@ public function format(string $statement, ...$args): string
191208 private function formatMember ($ name ): string
192209 {
193210 return $ name instanceof PhpLiteral || !Helpers::isIdentifier ($ name )
194- ? '{ ' . $ this ->_dump ($ name ) . '} '
211+ ? '{ ' . $ this ->dumpVar ($ name ) . '} '
195212 : $ name ;
196213 }
197214
0 commit comments