Skip to content

Commit 75c9ba3

Browse files
committed
Dumper: refactoring, added dumpCustomObject()
1 parent b74f58d commit 75c9ba3

File tree

4 files changed

+42
-27
lines changed

4 files changed

+42
-27
lines changed

src/PhpGenerator/Dumper.php

Lines changed: 35 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -49,10 +49,10 @@ private function dumpVar(mixed &$var, array $parents = [], int $level = 0, int $
4949
return $this->dumpLiteral($var, $level);
5050

5151
} elseif (is_object($var)) {
52-
return $this->dumpObject($var, $parents, $level);
52+
return $this->dumpObject($var, $parents, $level, $column);
5353

5454
} elseif (is_resource($var)) {
55-
throw new Nette\InvalidArgumentException('Cannot dump resource.');
55+
throw new Nette\InvalidStateException('Cannot dump value of type resource.');
5656

5757
} else {
5858
return var_export($var, return: true);
@@ -106,7 +106,7 @@ private function dumpArray(array &$var, array $parents, int $level, int $column)
106106
return '[]';
107107

108108
} elseif ($level > $this->maxDepth || in_array($var, $parents, strict: true)) {
109-
throw new Nette\InvalidArgumentException('Nesting level too deep or recursive dependency.');
109+
throw new Nette\InvalidStateException('Nesting level too deep or recursive dependency.');
110110
}
111111

112112
$space = str_repeat($this->indentation, $level);
@@ -136,12 +136,25 @@ private function dumpArray(array &$var, array $parents, int $level, int $column)
136136

137137

138138
/** @param array<mixed[]|object> $parents */
139-
private function dumpObject(object $var, array $parents, int $level): string
139+
private function dumpObject(object $var, array $parents, int $level, int $column): string
140140
{
141+
if ($level > $this->maxDepth || in_array($var, $parents, strict: true)) {
142+
throw new Nette\InvalidStateException('Nesting level too deep or recursive dependency.');
143+
}
144+
141145
$class = $var::class;
146+
$parents[] = $var;
142147

143-
if (in_array($class, [\DateTime::class, \DateTimeImmutable::class], strict: true)) {
144-
return $this->format("new \\$class(?, new \\DateTimeZone(?))", $var->format('Y-m-d H:i:s.u'), $var->getTimeZone()->getName());
148+
if ($class === \stdClass::class) {
149+
$var = (array) $var;
150+
return '(object) ' . $this->dumpArray($var, $parents, $level, $column + 10);
151+
152+
} elseif ($class === \DateTime::class || $class === \DateTimeImmutable::class) {
153+
return $this->format(
154+
"new \\$class(?, new \\DateTimeZone(?))",
155+
$var->format('Y-m-d H:i:s.u'),
156+
$var->getTimeZone()->getName(),
157+
);
145158

146159
} elseif ($var instanceof \UnitEnum) {
147160
return '\\' . $var::class . '::' . $var->name;
@@ -154,15 +167,25 @@ private function dumpObject(object $var, array $parents, int $level): string
154167
: implode('::', (array) $inner) . '(...)';
155168
}
156169

157-
throw new Nette\InvalidArgumentException('Cannot dump closure.');
170+
throw new Nette\InvalidStateException('Cannot dump object of type Closure.');
171+
172+
} else {
173+
return $this->dumpCustomObject($var, $parents, $level);
174+
}
175+
}
158176

159-
} elseif ((new \ReflectionObject($var))->isAnonymous()) {
160-
throw new Nette\InvalidArgumentException('Cannot dump anonymous class.');
161177

162-
} elseif ($level > $this->maxDepth || in_array($var, $parents, strict: true)) {
163-
throw new Nette\InvalidArgumentException('Nesting level too deep or recursive dependency.');
178+
/** @param array<mixed[]|object> $parents */
179+
private function dumpCustomObject(object $var, array $parents, int $level): string
180+
{
181+
if ((new \ReflectionObject($var))->isAnonymous()) {
182+
throw new Nette\InvalidStateException('Cannot dump an instance of an anonymous class.');
164183
}
165184

185+
$class = $var::class;
186+
$space = str_repeat($this->indentation, $level);
187+
$out = "\n";
188+
166189
if (method_exists($var, '__serialize')) {
167190
$arr = $var->__serialize();
168191
} else {
@@ -174,10 +197,6 @@ private function dumpObject(object $var, array $parents, int $level): string
174197
}
175198
}
176199

177-
$space = str_repeat($this->indentation, $level);
178-
$out = "\n";
179-
$parents[] = $var;
180-
181200
foreach ($arr as $k => &$v) {
182201
if (!isset($props) || isset($props[$k])) {
183202
$out .= $space . $this->indentation
@@ -187,11 +206,7 @@ private function dumpObject(object $var, array $parents, int $level): string
187206
}
188207
}
189208

190-
array_pop($parents);
191-
$out .= $space;
192-
return $class === \stdClass::class
193-
? "(object) [$out]"
194-
: '\\' . self::class . "::createObject(\\$class::class, [$out])";
209+
return '\\' . self::class . "::createObject(\\$class::class, [$out$space])";
195210
}
196211

197212

tests/PhpGenerator/Dumper.dump().errors.phpt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,12 @@ Assert::exception(function () {
1717
$rec[] = &$rec;
1818
$dumper = new Dumper;
1919
$dumper->dump($rec);
20-
}, Nette\InvalidArgumentException::class, 'Nesting level too deep or recursive dependency.');
20+
}, Nette\InvalidStateException::class, 'Nesting level too deep or recursive dependency.');
2121

2222

2323
Assert::exception(function () {
2424
$rec = new stdClass;
2525
$rec->x = &$rec;
2626
$dumper = new Dumper;
2727
$dumper->dump($rec);
28-
}, Nette\InvalidArgumentException::class, 'Nesting level too deep or recursive dependency.');
28+
}, Nette\InvalidStateException::class, 'Nesting level too deep or recursive dependency.');

tests/PhpGenerator/Dumper.dump().phpt

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -70,12 +70,12 @@ Assert::same("[0 => 'a', -2 => 'b', 1 => 'c']", $dumper->dump(['a', -2 => 'b', 1
7070

7171
// stdClass
7272
Assert::same(
73-
"(object) [\n\t'a' => 1,\n\t'b' => 2,\n]",
73+
"(object) ['a' => 1, 'b' => 2]",
7474
$dumper->dump((object) ['a' => 1, 'b' => 2]),
7575
);
7676

7777
Assert::same(
78-
"(object) [\n\t'a' => (object) [\n\t\t'b' => 2,\n\t],\n]",
78+
"(object) ['a' => (object) ['b' => 2]]",
7979
$dumper->dump((object) ['a' => (object) ['b' => 2]]),
8080
);
8181

@@ -128,7 +128,7 @@ Assert::exception(function () {
128128
$dumper = new Dumper;
129129
$dumper->dump(new class {
130130
});
131-
}, Nette\InvalidArgumentException::class, 'Cannot dump anonymous class.');
131+
}, Nette\InvalidStateException::class, 'Cannot dump an instance of an anonymous class.');
132132

133133

134134

@@ -150,7 +150,7 @@ Assert::same(
150150
Assert::exception(function () {
151151
$dumper = new Dumper;
152152
$dumper->dump(function () {});
153-
}, Nette\InvalidArgumentException::class, 'Cannot dump closure.');
153+
}, Nette\InvalidStateException::class, 'Cannot dump object of type Closure.');
154154

155155

156156

tests/PhpGenerator/Dumper.dump().wrap.phpt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ require __DIR__ . '/../bootstrap.php';
1313

1414

1515
$dumper = new Dumper;
16-
$dumper->wrapLength = 21;
16+
$dumper->wrapLength = 28;
1717
same(
1818
<<<'XX'
1919
[

0 commit comments

Comments
 (0)