1: <?php declare(strict_types = 1);
2:
3: namespace PHPStan\Analyser;
4:
5: use JsonSerializable;
6: use ReturnTypeWillChange;
7: use Throwable;
8: use function array_map;
9: use function array_unshift;
10:
11: /**
12: * @api
13: * @phpstan-type Trace = list<array{file: string|null, line: int|null}>
14: */
15: final class InternalError implements JsonSerializable
16: {
17:
18: public const STACK_TRACE_METADATA_KEY = 'stackTrace';
19:
20: public const STACK_TRACE_AS_STRING_METADATA_KEY = 'stackTraceAsString';
21:
22: /**
23: * @param Trace $trace
24: */
25: public function __construct(
26: private string $message,
27: private string $contextDescription,
28: private array $trace,
29: private ?string $traceAsString,
30: private bool $shouldReportBug,
31: )
32: {
33: }
34:
35: /**
36: * @return Trace
37: */
38: public static function prepareTrace(Throwable $exception): array
39: {
40: $trace = array_map(static fn (array $trace) => [
41: 'file' => $trace['file'] ?? null,
42: 'line' => $trace['line'] ?? null,
43: ], $exception->getTrace());
44:
45: array_unshift($trace, [
46: 'file' => $exception->getFile(),
47: 'line' => $exception->getLine(),
48: ]);
49:
50: return $trace;
51: }
52:
53: public function getMessage(): string
54: {
55: return $this->message;
56: }
57:
58: public function getContextDescription(): string
59: {
60: return $this->contextDescription;
61: }
62:
63: /**
64: * @return Trace
65: */
66: public function getTrace(): array
67: {
68: return $this->trace;
69: }
70:
71: public function getTraceAsString(): ?string
72: {
73: return $this->traceAsString;
74: }
75:
76: public function shouldReportBug(): bool
77: {
78: return $this->shouldReportBug;
79: }
80:
81: /**
82: * @param mixed[] $json
83: */
84: public static function decode(array $json): self
85: {
86: return new self($json['message'], $json['contextDescription'], $json['trace'], $json['traceAsString'], $json['shouldReportBug']);
87: }
88:
89: /**
90: * @return mixed
91: */
92: #[ReturnTypeWillChange]
93: public function jsonSerialize()
94: {
95: return [
96: 'message' => $this->message,
97: 'contextDescription' => $this->contextDescription,
98: 'trace' => $this->trace,
99: 'traceAsString' => $this->traceAsString,
100: 'shouldReportBug' => $this->shouldReportBug,
101: ];
102: }
103:
104: }
105: