1: <?php
2:
3: declare(strict_types=1);
4:
5: namespace PHPStan\BetterReflection\Reflection;
6:
7: use PhpParser\Node\Expr;
8: use PHPStan\BetterReflection\BetterReflection;
9:
10: final class ExprCacheHelper
11: {
12: /**
13: * One instance for every export and import: a BetterReflection memoizes
14: * its php-parser and printer, and building a Php8 parser (token map plus
15: * every reduce callback) per imported expression dominated cache hydration.
16: * @var \PHPStan\BetterReflection\BetterReflection|null
17: */
18: private static $betterReflection = null;
19:
20: private static function betterReflection(): BetterReflection
21: {
22: return self::$betterReflection ??= new BetterReflection();
23: }
24:
25: /** @return array<string, mixed> */
26: public static function export(Expr $expr): array
27: {
28: $br = self::betterReflection();
29:
30: $attributes = [];
31: foreach (['startLine', 'endLine', 'startTokenPos', 'startFilePos', 'endTokenPos', 'endFilePos'] as $key) {
32: $attributes[$key] = $expr->getAttribute($key);
33: }
34:
35: return [
36: 'code' => $br->printer()->prettyPrintExpr($expr),
37: 'attributes' => $attributes,
38: ];
39: }
40:
41: /** @param array<string, mixed> $data */
42: public static function import(array $data): Expr
43: {
44: $code = $data['code'];
45: $attributes = $data['attributes'];
46:
47: $expr = self::betterReflection()->originalPhpParser()->parse('<?php ' . $code . ';')[0]->expr;
48: foreach ($attributes as $key => $value) {
49: $expr->setAttribute($key, $value);
50: }
51:
52: return $expr;
53: }
54: }
55: