@@ -40,7 +40,7 @@ public function __construct(
40
40
{
41
41
}
42
42
43
- public function matchType (Type $ patternType , ?Type $ flagsType , TrinaryLogic $ wasMatched ): ?Type
43
+ public function matchType (Type $ patternType , ?Type $ flagsType , TrinaryLogic $ wasMatched, bool $ supportsUnmatchedAsNullOn72 = false ): ?Type
44
44
{
45
45
if ($ wasMatched ->no ()) {
46
46
return new ConstantArrayType ([], []);
@@ -65,7 +65,7 @@ public function matchType(Type $patternType, ?Type $flagsType, TrinaryLogic $was
65
65
66
66
$ matchedTypes = [];
67
67
foreach ($ constantStrings as $ constantString ) {
68
- $ matched = $ this ->matchRegex ($ constantString ->getValue (), $ flags , $ wasMatched );
68
+ $ matched = $ this ->matchRegex ($ constantString ->getValue (), $ flags , $ wasMatched, $ supportsUnmatchedAsNullOn72 );
69
69
if ($ matched === null ) {
70
70
return null ;
71
71
}
@@ -83,7 +83,7 @@ public function matchType(Type $patternType, ?Type $flagsType, TrinaryLogic $was
83
83
/**
84
84
* @param int-mask<PREG_OFFSET_CAPTURE|PREG_UNMATCHED_AS_NULL>|null $flags
85
85
*/
86
- private function matchRegex (string $ regex , ?int $ flags , TrinaryLogic $ wasMatched ): ?Type
86
+ private function matchRegex (string $ regex , ?int $ flags , TrinaryLogic $ wasMatched, bool $ supportsUnmatchedAsNullOn72 ): ?Type
87
87
{
88
88
$ parseResult = $ this ->parseGroups ($ regex );
89
89
if ($ parseResult === null ) {
@@ -100,7 +100,7 @@ private function matchRegex(string $regex, ?int $flags, TrinaryLogic $wasMatched
100
100
$ trailingOptionals ++;
101
101
}
102
102
103
- $ valueType = $ this ->getValueType ($ flags ?? 0 );
103
+ $ valueType = $ this ->getValueType ($ flags ?? 0 , $ supportsUnmatchedAsNullOn72 );
104
104
$ onlyOptionalTopLevelGroup = $ this ->getOnlyOptionalTopLevelGroup ($ groupList );
105
105
$ onlyTopLevelAlternationId = $ this ->getOnlyTopLevelAlternationId ($ groupList );
106
106
@@ -119,6 +119,7 @@ private function matchRegex(string $regex, ?int $flags, TrinaryLogic $wasMatched
119
119
$ wasMatched ,
120
120
$ trailingOptionals ,
121
121
$ flags ?? 0 ,
122
+ $ supportsUnmatchedAsNullOn72 ,
122
123
);
123
124
124
125
return TypeCombinator::union (
@@ -154,6 +155,7 @@ private function matchRegex(string $regex, ?int $flags, TrinaryLogic $wasMatched
154
155
$ wasMatched ,
155
156
$ trailingOptionals ,
156
157
$ flags ?? 0 ,
158
+ $ supportsUnmatchedAsNullOn72 ,
157
159
);
158
160
159
161
$ combiTypes [] = $ combiType ;
@@ -177,6 +179,7 @@ private function matchRegex(string $regex, ?int $flags, TrinaryLogic $wasMatched
177
179
$ wasMatched ,
178
180
$ trailingOptionals ,
179
181
$ flags ?? 0 ,
182
+ $ supportsUnmatchedAsNullOn72 ,
180
183
);
181
184
}
182
185
@@ -239,6 +242,7 @@ private function buildArrayType(
239
242
TrinaryLogic $ wasMatched ,
240
243
int $ trailingOptionals ,
241
244
int $ flags ,
245
+ bool $ supportsUnmatchedAsNullOn72 ,
242
246
): Type
243
247
{
244
248
$ builder = ConstantArrayTypeBuilder::createEmpty ();
@@ -260,10 +264,10 @@ private function buildArrayType(
260
264
} else {
261
265
if ($ i < $ countGroups - $ trailingOptionals ) {
262
266
$ optional = false ;
263
- if ($ this ->containsUnmatchedAsNull ($ flags )) {
267
+ if ($ this ->containsUnmatchedAsNull ($ flags, $ supportsUnmatchedAsNullOn72 )) {
264
268
$ groupValueType = TypeCombinator::removeNull ($ groupValueType );
265
269
}
266
- } elseif ($ this ->containsUnmatchedAsNull ($ flags )) {
270
+ } elseif ($ this ->containsUnmatchedAsNull ($ flags, $ supportsUnmatchedAsNullOn72 )) {
267
271
$ optional = false ;
268
272
} else {
269
273
$ optional = $ captureGroup ->isOptional ();
@@ -290,9 +294,9 @@ private function buildArrayType(
290
294
return $ builder ->getArray ();
291
295
}
292
296
293
- private function containsUnmatchedAsNull (int $ flags ): bool
297
+ private function containsUnmatchedAsNull (int $ flags, bool $ supportsUnmatchedAsNullOn72 ): bool
294
298
{
295
- return ($ flags & PREG_UNMATCHED_AS_NULL ) !== 0 && $ this ->phpVersion ->supportsPregUnmatchedAsNull ();
299
+ return ($ flags & PREG_UNMATCHED_AS_NULL ) !== 0 && ( $ supportsUnmatchedAsNullOn72 || $ this ->phpVersion ->supportsPregUnmatchedAsNull () );
296
300
}
297
301
298
302
private function getKeyType (int |string $ key ): Type
@@ -304,11 +308,11 @@ private function getKeyType(int|string $key): Type
304
308
return new ConstantIntegerType ($ key );
305
309
}
306
310
307
- private function getValueType (int $ flags ): Type
311
+ private function getValueType (int $ flags, bool $ supportsUnmatchedAsNullOn72 ): Type
308
312
{
309
313
$ valueType = new StringType ();
310
314
$ offsetType = IntegerRangeType::fromInterval (0 , null );
311
- if ($ this ->containsUnmatchedAsNull ($ flags )) {
315
+ if ($ this ->containsUnmatchedAsNull ($ flags, $ supportsUnmatchedAsNullOn72 )) {
312
316
$ valueType = TypeCombinator::addNull ($ valueType );
313
317
// unmatched groups return -1 as offset
314
318
$ offsetType = IntegerRangeType::fromInterval (-1 , null );
0 commit comments