Skip to content

Commit e6c5d51

Browse files
committed
RegexArrayShapeMatcher - turn more details immutable
1 parent c6e0450 commit e6c5d51

File tree

2 files changed

+22
-31
lines changed

2 files changed

+22
-31
lines changed

src/Type/Php/RegexArrayShapeMatcher.php

Lines changed: 14 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -123,19 +123,18 @@ private function matchRegex(string $regex, ?int $flags, TrinaryLogic $wasMatched
123123
$trailingOptionals++;
124124
}
125125

126-
$onlyOptionalTopLevelGroup = $this->getOnlyOptionalTopLevelGroup($groupList);
126+
$onlyOptionalTopLevelGroupIndex = $this->getOnlyOptionalTopLevelGroupIndex($groupList);
127127
$onlyTopLevelAlternation = $this->getOnlyTopLevelAlternation($groupList);
128128
$flags ??= 0;
129129

130130
if (
131131
!$matchesAll
132132
&& $wasMatched->yes()
133-
&& $onlyOptionalTopLevelGroup !== null
133+
&& $onlyOptionalTopLevelGroupIndex !== null
134134
) {
135135
// if only one top level capturing optional group exists
136136
// we build a more precise tagged union of a empty-match and a match with the group
137-
138-
$onlyOptionalTopLevelGroup->forceNonOptional();
137+
$groupList[$onlyOptionalTopLevelGroupIndex] = $groupList[$onlyOptionalTopLevelGroupIndex]->forceNonOptional();
139138

140139
$combiType = $this->buildArrayType(
141140
$groupList,
@@ -154,12 +153,10 @@ private function matchRegex(string $regex, ?int $flags, TrinaryLogic $wasMatched
154153
);
155154
}
156155

157-
$onlyOptionalTopLevelGroup->clearOverrides();
158-
159156
return $combiType;
160157
} elseif (
161158
!$matchesAll
162-
&& $onlyOptionalTopLevelGroup === null
159+
&& $onlyOptionalTopLevelGroupIndex === null
163160
&& $onlyTopLevelAlternation !== null
164161
&& !$wasMatched->no()
165162
) {
@@ -174,13 +171,14 @@ private function matchRegex(string $regex, ?int $flags, TrinaryLogic $wasMatched
174171
foreach ($comboList as $groupId => $group) {
175172
if (in_array($groupId, $groupCombo, true)) {
176173
$isOptionalAlternation = $group->inOptionalAlternation();
177-
$group->forceNonOptional();
174+
$forcedGroup = $group->forceNonOptional();
178175
$beforeCurrentCombo = false;
176+
$comboList[$groupId] = $forcedGroup;
179177
} elseif ($beforeCurrentCombo && !$group->resetsGroupCounter()) {
180-
$group->forceNonOptional();
181-
$group->forceType(
178+
$forcedGroup = $group->forceNonOptional()->forceType(
182179
$this->containsUnmatchedAsNull($flags, $matchesAll) ? new NullType() : new ConstantStringType(''),
183180
);
181+
$comboList[$groupId] = $forcedGroup;
184182
} elseif (
185183
$group->getAlternationId() === $onlyTopLevelAlternation->getId()
186184
&& !$this->containsUnmatchedAsNull($flags, $matchesAll)
@@ -199,11 +197,6 @@ private function matchRegex(string $regex, ?int $flags, TrinaryLogic $wasMatched
199197
);
200198

201199
$combiTypes[] = $combiType;
202-
203-
foreach ($groupCombo as $groupId) {
204-
$group = $comboList[$groupId];
205-
$group->clearOverrides();
206-
}
207200
}
208201

209202
if (
@@ -235,10 +228,10 @@ private function matchRegex(string $regex, ?int $flags, TrinaryLogic $wasMatched
235228
/**
236229
* @param array<int, RegexCapturingGroup> $captureGroups
237230
*/
238-
private function getOnlyOptionalTopLevelGroup(array $captureGroups): ?RegexCapturingGroup
231+
private function getOnlyOptionalTopLevelGroupIndex(array $captureGroups): ?int
239232
{
240-
$group = null;
241-
foreach ($captureGroups as $captureGroup) {
233+
$groupIndex = null;
234+
foreach ($captureGroups as $i => $captureGroup) {
242235
if (!$captureGroup->isTopLevel()) {
243236
continue;
244237
}
@@ -247,14 +240,14 @@ private function getOnlyOptionalTopLevelGroup(array $captureGroups): ?RegexCaptu
247240
return null;
248241
}
249242

250-
if ($group !== null) {
243+
if ($groupIndex !== null) {
251244
return null;
252245
}
253246

254-
$group = $captureGroup;
247+
$groupIndex = $i;
255248
}
256249

257-
return $group;
250+
return $groupIndex;
258251
}
259252

260253
/**

src/Type/Regex/RegexCapturingGroup.php

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -27,20 +27,18 @@ public function getId(): int
2727
return $this->id;
2828
}
2929

30-
public function forceNonOptional(): void
30+
public function forceNonOptional(): self
3131
{
32-
$this->forceNonOptional = true;
32+
$new = clone $this;
33+
$new->forceNonOptional = true;
34+
return $new;
3335
}
3436

35-
public function forceType(Type $type): void
37+
public function forceType(Type $type): self
3638
{
37-
$this->forceType = $type;
38-
}
39-
40-
public function clearOverrides(): void
41-
{
42-
$this->forceNonOptional = false;
43-
$this->forceType = null;
39+
$new = clone $this;
40+
$new->forceType = $type;
41+
return $new;
4442
}
4543

4644
public function resetsGroupCounter(): bool

0 commit comments

Comments
 (0)