@@ -293,26 +293,8 @@ private function buildArrayType(
293
293
$ i = 0 ;
294
294
foreach ($ captureGroups as $ captureGroup ) {
295
295
$ isTrailingOptional = $ i >= $ countGroups - $ trailingOptionals ;
296
- $ groupValueType = $ this ->getValueType ($ captureGroup ->getType (), $ flags );
297
-
298
- if (!$ wasMatched ->yes ()) {
299
- $ optional = true ;
300
- } else {
301
- if (!$ isTrailingOptional ) {
302
- $ optional = false ;
303
- if ($ this ->containsUnmatchedAsNull ($ flags ) && !$ captureGroup ->isOptional ()) {
304
- $ groupValueType = TypeCombinator::removeNull ($ groupValueType );
305
- }
306
- } elseif ($ this ->containsUnmatchedAsNull ($ flags )) {
307
- $ optional = false ;
308
- } else {
309
- $ optional = $ captureGroup ->isOptional ();
310
- }
311
- }
312
-
313
- if (!$ isTrailingOptional && $ captureGroup ->isOptional () && !$ this ->containsUnmatchedAsNull ($ flags )) {
314
- $ groupValueType = TypeCombinator::union ($ groupValueType , new ConstantStringType ('' ));
315
- }
296
+ $ groupValueType = $ this ->createGroupValueType ($ captureGroup , $ wasMatched , $ flags , $ isTrailingOptional );
297
+ $ optional = $ this ->isGroupOptional ($ captureGroup , $ wasMatched , $ flags , $ isTrailingOptional );
316
298
317
299
if ($ captureGroup ->isNamed ()) {
318
300
$ builder ->setOffsetValueType (
@@ -346,6 +328,40 @@ private function buildArrayType(
346
328
return $ builder ->getArray ();
347
329
}
348
330
331
+ private function isGroupOptional (RegexCapturingGroup $ captureGroup , TrinaryLogic $ wasMatched , int $ flags , bool $ isTrailingOptional ): bool
332
+ {
333
+ if (!$ wasMatched ->yes ()) {
334
+ $ optional = true ;
335
+ } else {
336
+ if (!$ isTrailingOptional ) {
337
+ $ optional = false ;
338
+ } elseif ($ this ->containsUnmatchedAsNull ($ flags )) {
339
+ $ optional = false ;
340
+ } else {
341
+ $ optional = $ captureGroup ->isOptional ();
342
+ }
343
+ }
344
+
345
+ return $ optional ;
346
+ }
347
+
348
+ private function createGroupValueType (RegexCapturingGroup $ captureGroup , TrinaryLogic $ wasMatched , int $ flags , bool $ isTrailingOptional ): Type
349
+ {
350
+ $ groupValueType = $ this ->getValueType ($ captureGroup ->getType (), $ flags );
351
+
352
+ if ($ wasMatched ->yes ()) {
353
+ if (!$ isTrailingOptional && $ this ->containsUnmatchedAsNull ($ flags ) && !$ captureGroup ->isOptional ()) {
354
+ $ groupValueType = TypeCombinator::removeNull ($ groupValueType );
355
+ }
356
+ }
357
+
358
+ if (!$ isTrailingOptional && !$ this ->containsUnmatchedAsNull ($ flags ) && $ captureGroup ->isOptional ()) {
359
+ $ groupValueType = TypeCombinator::union ($ groupValueType , new ConstantStringType ('' ));
360
+ }
361
+
362
+ return $ groupValueType ;
363
+ }
364
+
349
365
private function containsUnmatchedAsNull (int $ flags ): bool
350
366
{
351
367
return ($ flags & PREG_UNMATCHED_AS_NULL ) !== 0 && (($ flags & self ::PREG_UNMATCHED_AS_NULL_ON_72_73 ) !== 0 || $ this ->phpVersion ->supportsPregUnmatchedAsNull ());
0 commit comments