1: <?php declare(strict_types=1);
2:
3: namespace Salient\PHPDoc\Tag;
4:
5: use Salient\Core\Concern\HasMutator;
6: use Stringable;
7:
8: /**
9: * A "@template" tag
10: */
11: class TemplateTag extends AbstractTag implements Stringable
12: {
13: use HasMutator;
14:
15: /** @var "covariant"|"contravariant"|null */
16: protected ?string $Variance;
17:
18: /**
19: * Creates a new TemplateTag object
20: *
21: * @param "covariant"|"contravariant"|null $variance
22: * @param class-string|null $class
23: */
24: public function __construct(
25: string $name,
26: ?string $type = null,
27: ?string $variance = null,
28: ?string $class = null,
29: ?string $member = null
30: ) {
31: parent::__construct('template', $name, $type, null, $class, $member);
32: $this->Variance = $this->filterVariance($variance);
33: }
34:
35: /**
36: * @inheritDoc
37: */
38: public function getName(): string
39: {
40: return $this->Name;
41: }
42:
43: /**
44: * Get the variance of the template
45: *
46: * @return "covariant"|"contravariant"|null
47: */
48: public function getVariance(): ?string
49: {
50: return $this->Variance;
51: }
52:
53: /**
54: * Get an instance with the given name
55: *
56: * @return static
57: */
58: public function withName(string $name)
59: {
60: return $this->with('Name', $this->filterString($name, 'name'));
61: }
62:
63: /**
64: * Get an instance with the given PHPDoc type
65: *
66: * @return static
67: */
68: public function withType(?string $type)
69: {
70: if ($type === null) {
71: return $this->without('Type');
72: }
73: return $this->with('Type', $this->filterType($type));
74: }
75:
76: /**
77: * Get an instance with the given variance
78: *
79: * @param "covariant"|"contravariant"|null $variance
80: * @return static
81: */
82: public function withVariance(?string $variance)
83: {
84: return $this->with('Variance', $this->filterVariance($variance));
85: }
86:
87: public function __toString(): string
88: {
89: return sprintf(
90: '@template%s %s%s',
91: $this->Variance === null ? '' : '-' . $this->Variance,
92: $this->Name,
93: !isset($this->Type) ? '' : ' of ' . $this->Type
94: );
95: }
96:
97: /**
98: * @return "covariant"|"contravariant"|null
99: */
100: protected function filterVariance(?string $variance): ?string
101: {
102: if (
103: $variance === null
104: || $variance === 'covariant'
105: || $variance === 'contravariant'
106: ) {
107: return $variance;
108: }
109: $this->throw("Invalid variance '%s'", $variance);
110: }
111: }
112: