1: <?php declare(strict_types=1);
2:
3: namespace Salient\PHPDoc\Tag;
4:
5: /**
6: * @api
7: */
8: class TemplateTag extends AbstractTag
9: {
10: protected ?string $Default;
11: protected bool $IsCovariant;
12: protected bool $IsContravariant;
13:
14: /**
15: * @internal
16: */
17: public function __construct(
18: string $name,
19: ?string $type = null,
20: ?string $default = null,
21: bool $isCovariant = false,
22: bool $isContravariant = false,
23: ?string $class = null,
24: ?string $member = null,
25: ?string $static = null,
26: ?string $self = null,
27: array $aliases = []
28: ) {
29: if ($isCovariant && $isContravariant) {
30: $this->throw('$isCovariant and $isContravariant cannot both be true');
31: }
32: parent::__construct('template', $name, $type, null, $class, $member, $static, $self, $aliases);
33: $this->Default = $this->filterType($default, $aliases);
34: $this->IsCovariant = $isCovariant;
35: $this->IsContravariant = $isContravariant;
36: }
37:
38: /**
39: * @inheritDoc
40: */
41: public function getName(): string
42: {
43: return $this->Name;
44: }
45:
46: /**
47: * @return null
48: */
49: public function getDescription(): ?string
50: {
51: return null;
52: }
53:
54: /**
55: * Get the default value of the template
56: */
57: public function getDefault(): ?string
58: {
59: return $this->Default;
60: }
61:
62: /**
63: * Check if the template is covariant
64: */
65: public function isCovariant(): bool
66: {
67: return $this->IsCovariant;
68: }
69:
70: /**
71: * Check if the template is contravariant
72: */
73: public function isContravariant(): bool
74: {
75: return $this->IsContravariant;
76: }
77:
78: /**
79: * Get an instance with the given name
80: *
81: * @return static
82: */
83: public function withName(string $name)
84: {
85: return $this->with('Name', $this->filterString($name, 'name'));
86: }
87:
88: /**
89: * Get an instance with the given PHPDoc type
90: *
91: * @return static
92: */
93: public function withType(?string $type)
94: {
95: if ($type === null) {
96: return $this->without('Type');
97: }
98: return $this->with('Type', $this->filterType($type));
99: }
100:
101: /**
102: * @inheritDoc
103: */
104: public function withDescription(?string $description)
105: {
106: if ($description !== null) {
107: $this->throw('Invalid description');
108: }
109: return $this;
110: }
111:
112: /**
113: * Get an instance with the given default value
114: *
115: * @return static
116: */
117: public function withDefault(?string $default)
118: {
119: return $this->with('Default', $this->filterType($default));
120: }
121:
122: /**
123: * Get an instance without covariance or contravariance
124: *
125: * @return static
126: */
127: public function withoutVariance()
128: {
129: return $this
130: ->with('IsCovariant', false)
131: ->with('IsContravariant', false);
132: }
133:
134: /**
135: * @inheritDoc
136: */
137: public function __toString(): string
138: {
139: $string = "@{$this->Tag}";
140: if ($this->IsCovariant) {
141: $string .= '-covariant';
142: } elseif ($this->IsContravariant) {
143: $string .= '-contravariant';
144: }
145: $string .= " {$this->Name}";
146: if (isset($this->Type)) {
147: $string .= " of {$this->Type}";
148: }
149: if ($this->Default !== null) {
150: $string .= " = {$this->Default}";
151: }
152: return $string;
153: }
154: }
155: