1: <?php declare(strict_types = 1);
2:
3: namespace PHPStan\PhpDocParser\Ast\Type;
4:
5: use PHPStan\PhpDocParser\Ast\NodeAttributes;
6: use PHPStan\PhpDocParser\Ast\PhpDoc\TemplateTagValueNode;
7: use function implode;
8:
9: class CallableTypeNode implements TypeNode
10: {
11:
12: use NodeAttributes;
13:
14: /** @var IdentifierTypeNode|NameNode */
15: public TypeNode $identifier;
16:
17: /** @var TemplateTagValueNode[] */
18: public array $templateTypes;
19:
20: /** @var CallableTypeParameterNode[] */
21: public array $parameters;
22:
23: public TypeNode $returnType;
24:
25: /**
26: * @param IdentifierTypeNode|NameNode $identifier
27: * @param CallableTypeParameterNode[] $parameters
28: * @param TemplateTagValueNode[] $templateTypes
29: */
30: public function __construct(TypeNode $identifier, array $parameters, TypeNode $returnType, array $templateTypes)
31: {
32: $this->identifier = $identifier;
33: $this->parameters = $parameters;
34: $this->returnType = $returnType;
35: $this->templateTypes = $templateTypes;
36: }
37:
38: public function __toString(): string
39: {
40: $returnType = $this->returnType;
41: if ($returnType instanceof self) {
42: $returnType = "({$returnType})";
43: }
44: $template = $this->templateTypes !== []
45: ? '<' . implode(', ', $this->templateTypes) . '>'
46: : '';
47: $parameters = implode(', ', $this->parameters);
48: return "{$this->identifier}{$template}({$parameters}): {$returnType}";
49: }
50:
51: /**
52: * @param array<string, mixed> $properties
53: */
54: public static function __set_state(array $properties): self
55: {
56: $instance = new self($properties['identifier'], $properties['parameters'], $properties['returnType'], $properties['templateTypes']);
57: if (isset($properties['attributes'])) {
58: foreach ($properties['attributes'] as $key => $value) {
59: $instance->setAttribute($key, $value);
60: }
61: }
62: return $instance;
63: }
64:
65: }
66: