| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103 | 
							- <?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\"");
 
-     }
 
- }
 
 
  |