<?php declare(strict_types=1); namespace PhpParser; class JsonDecoder { /** @var \ReflectionClass[] Node type to reflection class map */ private $reflectionClassCache; public function decode(string $json) { $value = json_decode($json, true); if (json_last_error()) { throw new \RuntimeException('JSON decoding error: ' . json_last_error_msg()); } return $this->decodeRecursive($value); } private function decodeRecursive($value) { if (\is_array($value)) { if (isset($value['nodeType'])) { if ($value['nodeType'] === 'Comment' || $value['nodeType'] === 'Comment_Doc') { return $this->decodeComment($value); } return $this->decodeNode($value); } return $this->decodeArray($value); } return $value; } private function decodeArray(array $array) : array { $decodedArray = []; foreach ($array as $key => $value) { $decodedArray[$key] = $this->decodeRecursive($value); } return $decodedArray; } private function decodeNode(array $value) : Node { $nodeType = $value['nodeType']; if (!\is_string($nodeType)) { throw new \RuntimeException('Node type must be a string'); } $reflectionClass = $this->reflectionClassFromNodeType($nodeType); /** @var Node $node */ $node = $reflectionClass->newInstanceWithoutConstructor(); if (isset($value['attributes'])) { if (!\is_array($value['attributes'])) { throw new \RuntimeException('Attributes must be an array'); } $node->setAttributes($this->decodeArray($value['attributes'])); } foreach ($value as $name => $subNode) { if ($name === 'nodeType' || $name === 'attributes') { continue; } $node->$name = $this->decodeRecursive($subNode); } return $node; } private function decodeComment(array $value) : Comment { $className = $value['nodeType'] === 'Comment' ? Comment::class : Comment\Doc::class; if (!isset($value['text'])) { throw new \RuntimeException('Comment must have text'); } return new $className( $value['text'], $value['line'] ?? -1, $value['filePos'] ?? -1, $value['tokenPos'] ?? -1, $value['endLine'] ?? -1, $value['endFilePos'] ?? -1, $value['endTokenPos'] ?? -1 ); } private function reflectionClassFromNodeType(string $nodeType) : \ReflectionClass { if (!isset($this->reflectionClassCache[$nodeType])) { $className = $this->classNameFromNodeType($nodeType); $this->reflectionClassCache[$nodeType] = new \ReflectionClass($className); } return $this->reflectionClassCache[$nodeType]; } private function classNameFromNodeType(string $nodeType) : string { $className = 'PhpParser\\Node\\' . strtr($nodeType, '_', '\\'); if (class_exists($className)) { return $className; } $className .= '_'; if (class_exists($className)) { return $className; } throw new \RuntimeException("Unknown node type \"$nodeType\""); } }
Name | Type | Size | Permission | Actions |
---|---|---|---|---|
Builder | Folder | 0755 |
|
|
Comment | Folder | 0755 |
|
|
ErrorHandler | Folder | 0755 |
|
|
Internal | Folder | 0755 |
|
|
Lexer | Folder | 0755 |
|
|
Node | Folder | 0755 |
|
|
NodeVisitor | Folder | 0755 |
|
|
Parser | Folder | 0755 |
|
|
PrettyPrinter | Folder | 0755 |
|
|
Builder.php | File | 203 B | 0644 |
|
BuilderFactory.php | File | 10.84 KB | 0644 |
|
BuilderHelpers.php | File | 9.54 KB | 0644 |
|
Comment.php | File | 7.37 KB | 0644 |
|
ConstExprEvaluationException.php | File | 86 B | 0644 |
|
ConstExprEvaluator.php | File | 9.05 KB | 0644 |
|
Error.php | File | 4.92 KB | 0644 |
|
ErrorHandler.php | File | 294 B | 0644 |
|
JsonDecoder.php | File | 3.3 KB | 0644 |
|
Lexer.php | File | 23.51 KB | 0644 |
|
NameContext.php | File | 9.69 KB | 0644 |
|
Node.php | File | 3.88 KB | 0644 |
|
NodeAbstract.php | File | 5.03 KB | 0644 |
|
NodeDumper.php | File | 6.69 KB | 0644 |
|
NodeFinder.php | File | 2.39 KB | 0644 |
|
NodeTraverser.php | File | 10.34 KB | 0644 |
|
NodeTraverserInterface.php | File | 629 B | 0644 |
|
NodeVisitor.php | File | 1.98 KB | 0644 |
|
NodeVisitorAbstract.php | File | 438 B | 0644 |
|
Parser.php | File | 628 B | 0644 |
|
ParserAbstract.php | File | 41.22 KB | 0644 |
|
ParserFactory.php | File | 1.58 KB | 0644 |
|
PrettyPrinterAbstract.php | File | 60.3 KB | 0644 |
|