|
14 | 14 | use PhpParser\PhpVersion; |
15 | 15 | use PhpParser\PrettyPrinter; |
16 | 16 | use PhpParser\PrettyPrinter\Standard; |
17 | | -use Symfony\Component\Filesystem\Exception\IOException; |
18 | | -use Symfony\Component\Filesystem\Filesystem; |
| 17 | +use Symfony\Component\Config\ConfigCacheFactoryInterface; |
19 | 18 | use Symfony\Component\JsonStreamer\DataModel\DataAccessorInterface; |
20 | 19 | use Symfony\Component\JsonStreamer\DataModel\FunctionDataAccessor; |
21 | 20 | use Symfony\Component\JsonStreamer\DataModel\Read\BackedEnumNode; |
|
29 | 28 | use Symfony\Component\JsonStreamer\Exception\RuntimeException; |
30 | 29 | use Symfony\Component\JsonStreamer\Exception\UnsupportedException; |
31 | 30 | use Symfony\Component\JsonStreamer\Mapping\PropertyMetadataLoaderInterface; |
| 31 | +use Symfony\Component\JsonStreamer\StreamerDumper; |
32 | 32 | use Symfony\Component\TypeInfo\Type; |
33 | 33 | use Symfony\Component\TypeInfo\Type\BackedEnumType; |
34 | 34 | use Symfony\Component\TypeInfo\Type\BuiltinType; |
|
47 | 47 | */ |
48 | 48 | final class StreamReaderGenerator |
49 | 49 | { |
| 50 | + private StreamerDumper $dumper; |
50 | 51 | private ?PhpAstBuilder $phpAstBuilder = null; |
51 | 52 | private ?PrettyPrinter $phpPrinter = null; |
52 | | - private ?Filesystem $fs = null; |
53 | 53 |
|
54 | 54 | public function __construct( |
55 | 55 | private PropertyMetadataLoaderInterface $propertyMetadataLoader, |
56 | 56 | private string $streamReadersDir, |
57 | 57 | ) { |
| 58 | + $this->dumper = new StreamerDumper($propertyMetadataLoader, $streamReadersDir); |
58 | 59 | } |
59 | 60 |
|
60 | 61 | /** |
61 | 62 | * Generates and writes a stream reader PHP file and return its path. |
62 | 63 | * |
63 | 64 | * @param array<string, mixed> $options |
64 | 65 | */ |
65 | | - public function generate(Type $type, bool $decodeFromStream, array $options = []): string |
| 66 | + public function generate(Type $type, bool $decodeFromStream, array $options = [], ?ConfigCacheFactoryInterface $cacheFactory = null): string |
66 | 67 | { |
67 | | - $path = $this->getPath($type, $decodeFromStream); |
68 | | - if (is_file($path)) { |
69 | | - return $path; |
70 | | - } |
71 | | - |
72 | | - $this->phpAstBuilder ??= new PhpAstBuilder(); |
73 | | - $this->phpPrinter ??= new Standard(['phpVersion' => PhpVersion::fromComponents(8, 2)]); |
74 | | - $this->fs ??= new Filesystem(); |
| 68 | + $path = \sprintf('%s%s%s.json%s.php', $this->streamReadersDir, \DIRECTORY_SEPARATOR, hash('xxh128', (string) $type), $decodeFromStream ? '.stream' : ''); |
| 69 | + $generateContent = function () use ($type, $decodeFromStream, $options): string { |
| 70 | + $this->phpAstBuilder ??= new PhpAstBuilder(); |
| 71 | + $this->phpPrinter ??= new Standard(['phpVersion' => PhpVersion::fromComponents(8, 2)]); |
75 | 72 |
|
76 | | - $dataModel = $this->createDataModel($type, $options); |
77 | | - $nodes = $this->phpAstBuilder->build($dataModel, $decodeFromStream, $options); |
78 | | - $content = $this->phpPrinter->prettyPrintFile($nodes)."\n"; |
79 | | - |
80 | | - if (!$this->fs->exists($this->streamReadersDir)) { |
81 | | - $this->fs->mkdir($this->streamReadersDir); |
82 | | - } |
| 73 | + $dataModel = $this->createDataModel($type, $options); |
| 74 | + $nodes = $this->phpAstBuilder->build($dataModel, $decodeFromStream, $options); |
83 | 75 |
|
84 | | - $tmpFile = $this->fs->tempnam(\dirname($path), basename($path)); |
| 76 | + return $this->phpPrinter->prettyPrintFile($nodes)."\n"; |
| 77 | + }; |
85 | 78 |
|
86 | | - try { |
87 | | - $this->fs->dumpFile($tmpFile, $content); |
88 | | - $this->fs->rename($tmpFile, $path); |
89 | | - $this->fs->chmod($path, 0666 & ~umask()); |
90 | | - } catch (IOException $e) { |
91 | | - throw new RuntimeException(\sprintf('Failed to write "%s" stream reader file.', $path), previous: $e); |
92 | | - } |
| 79 | + $this->dumper->dump($type, $path, $generateContent, $cacheFactory); |
93 | 80 |
|
94 | 81 | return $path; |
95 | 82 | } |
96 | 83 |
|
97 | | - private function getPath(Type $type, bool $decodeFromStream): string |
98 | | - { |
99 | | - return \sprintf('%s%s%s.json%s.php', $this->streamReadersDir, \DIRECTORY_SEPARATOR, hash('xxh128', (string) $type), $decodeFromStream ? '.stream' : ''); |
100 | | - } |
101 | | - |
102 | 84 | /** |
103 | 85 | * @param array<string, mixed> $options |
104 | 86 | * @param array<string, mixed> $context |
105 | 87 | */ |
106 | | - public function createDataModel(Type $type, array $options = [], array $context = []): DataModelNodeInterface |
| 88 | + private function createDataModel(Type $type, array $options = [], array $context = []): DataModelNodeInterface |
107 | 89 | { |
108 | 90 | $context['original_type'] ??= $type; |
109 | 91 |
|
|
0 commit comments