@@ -304,35 +304,25 @@ private function createGroupType(TreeNode $group, bool $maybeConstant, string $p
304
304
return TypeCombinator::union (...$ types );
305
305
}
306
306
307
- $ isNonEmpty = TrinaryLogic::createMaybe ();
308
- $ isNonFalsy = TrinaryLogic::createMaybe ();
309
- $ isNumeric = TrinaryLogic::createMaybe ();
310
- $ inOptionalQuantification = false ;
311
- $ onlyLiterals = [];
312
-
313
- $ this ->walkGroupAst (
307
+ $ walkResult = $ this ->walkGroupAst (
314
308
$ group ,
315
309
false ,
316
- $ isNonEmpty ,
317
- $ isNonFalsy ,
318
- $ isNumeric ,
319
- $ inOptionalQuantification ,
320
- $ onlyLiterals ,
321
310
false ,
322
311
$ patternModifiers ,
312
+ RegexGroupWalkResult::createEmpty (),
323
313
);
324
314
325
- if ($ maybeConstant && $ onlyLiterals !== null && $ onlyLiterals !== []) {
315
+ if ($ maybeConstant && $ walkResult -> getOnlyLiterals () !== null && $ walkResult -> getOnlyLiterals () !== []) {
326
316
$ result = [];
327
- foreach ($ onlyLiterals as $ literal ) {
317
+ foreach ($ walkResult -> getOnlyLiterals () as $ literal ) {
328
318
$ result [] = new ConstantStringType ($ literal );
329
319
330
320
}
331
321
return TypeCombinator::union (...$ result );
332
322
}
333
323
334
- if ($ isNumeric ->yes ()) {
335
- if ($ isNonFalsy ->yes ()) {
324
+ if ($ walkResult -> isNumeric () ->yes ()) {
325
+ if ($ walkResult -> isNonFalsy () ->yes ()) {
336
326
return new IntersectionType ([
337
327
new StringType (),
338
328
new AccessoryNumericStringType (),
@@ -341,13 +331,13 @@ private function createGroupType(TreeNode $group, bool $maybeConstant, string $p
341
331
}
342
332
343
333
$ result = new IntersectionType ([new StringType (), new AccessoryNumericStringType ()]);
344
- if (!$ isNonEmpty ->yes ()) {
334
+ if (!$ walkResult -> isNonEmpty () ->yes ()) {
345
335
return TypeCombinator::union (new ConstantStringType ('' ), $ result );
346
336
}
347
337
return $ result ;
348
- } elseif ($ isNonFalsy ->yes ()) {
338
+ } elseif ($ walkResult -> isNonFalsy () ->yes ()) {
349
339
return new IntersectionType ([new StringType (), new AccessoryNonFalsyStringType ()]);
350
- } elseif ($ isNonEmpty ->yes ()) {
340
+ } elseif ($ walkResult -> isNonEmpty () ->yes ()) {
351
341
return new IntersectionType ([new StringType (), new AccessoryNonEmptyStringType ()]);
352
342
}
353
343
@@ -376,20 +366,13 @@ private function getRootAlternation(TreeNode $group): ?TreeNode
376
366
return null ;
377
367
}
378
368
379
- /**
380
- * @param array<string>|null $onlyLiterals
381
- */
382
369
private function walkGroupAst (
383
370
TreeNode $ ast ,
384
371
bool $ inAlternation ,
385
- TrinaryLogic &$ isNonEmpty ,
386
- TrinaryLogic &$ isNonFalsy ,
387
- TrinaryLogic &$ isNumeric ,
388
- bool &$ inOptionalQuantification ,
389
- ?array &$ onlyLiterals ,
390
372
bool $ inClass ,
391
373
string $ patternModifiers ,
392
- ): void
374
+ RegexGroupWalkResult $ walkResult ,
375
+ ): RegexGroupWalkResult
393
376
{
394
377
$ children = $ ast ->getChildren ();
395
378
@@ -411,61 +394,65 @@ private function walkGroupAst(
411
394
}
412
395
413
396
// a single token non-falsy on its own
414
- $ isNonFalsy = TrinaryLogic::createYes ();
397
+ $ walkResult = $ walkResult -> nonFalsy ( TrinaryLogic::createYes () );
415
398
break ;
416
399
}
417
400
418
401
if ($ meaningfulTokens > 0 ) {
419
- $ isNonEmpty = TrinaryLogic::createYes ();
402
+ $ walkResult = $ walkResult -> nonEmpty ( TrinaryLogic::createYes () );
420
403
421
404
// two non-empty tokens concatenated results in a non-falsy string
422
405
if ($ meaningfulTokens > 1 && !$ inAlternation ) {
423
- $ isNonFalsy = TrinaryLogic::createYes ();
406
+ $ walkResult = $ walkResult -> nonFalsy ( TrinaryLogic::createYes () );
424
407
}
425
408
}
426
409
} elseif ($ ast ->getId () === '#quantification ' ) {
427
410
[$ min ] = $ this ->getQuantificationRange ($ ast );
428
411
429
412
if ($ min === 0 ) {
430
- $ inOptionalQuantification = true ;
413
+ $ walkResult = $ walkResult -> inOptionalQuantification ( true ) ;
431
414
}
432
415
if ($ min >= 1 ) {
433
- $ isNonEmpty = TrinaryLogic::createYes ();
434
- $ inOptionalQuantification = false ;
416
+ $ walkResult = $ walkResult
417
+ ->nonEmpty (TrinaryLogic::createYes ())
418
+ ->inOptionalQuantification (false );
435
419
}
436
420
if ($ min >= 2 && !$ inAlternation ) {
437
- $ isNonFalsy = TrinaryLogic::createYes ();
421
+ $ walkResult = $ walkResult -> nonFalsy ( TrinaryLogic::createYes () );
438
422
}
439
423
440
- $ onlyLiterals = null ;
441
- } elseif ($ ast ->getId () === '#class ' && $ onlyLiterals !== null ) {
424
+ $ walkResult = $ walkResult -> onlyLiterals ( null ) ;
425
+ } elseif ($ ast ->getId () === '#class ' && $ walkResult -> getOnlyLiterals () !== null ) {
442
426
$ inClass = true ;
443
427
444
428
$ newLiterals = [];
445
429
foreach ($ children as $ child ) {
446
- $ oldLiterals = $ onlyLiterals ;
430
+ $ oldLiterals = $ walkResult -> getOnlyLiterals () ;
447
431
448
432
$ this ->getLiteralValue ($ child , $ oldLiterals , true , $ patternModifiers , true );
449
433
foreach ($ oldLiterals ?? [] as $ oldLiteral ) {
450
434
$ newLiterals [] = $ oldLiteral ;
451
435
}
452
436
}
453
- $ onlyLiterals = $ newLiterals ;
437
+ $ walkResult = $ walkResult -> onlyLiterals ( $ newLiterals) ;
454
438
} elseif ($ ast ->getId () === 'token ' ) {
439
+ $ onlyLiterals = $ walkResult ->getOnlyLiterals ();
455
440
$ literalValue = $ this ->getLiteralValue ($ ast , $ onlyLiterals , !$ inClass , $ patternModifiers , false );
441
+ $ walkResult = $ walkResult ->onlyLiterals ($ onlyLiterals );
442
+
456
443
if ($ literalValue !== null ) {
457
444
if (Strings::match ($ literalValue , '/^\d+$/ ' ) === null ) {
458
- $ isNumeric = TrinaryLogic::createNo ();
459
- } elseif ($ isNumeric ->maybe ()) {
460
- $ isNumeric = TrinaryLogic::createYes ();
445
+ $ walkResult = $ walkResult -> numeric ( TrinaryLogic::createNo () );
446
+ } elseif ($ walkResult -> isNumeric () ->maybe ()) {
447
+ $ walkResult = $ walkResult -> numeric ( TrinaryLogic::createYes () );
461
448
}
462
449
463
- if (!$ inOptionalQuantification && $ literalValue !== '' ) {
464
- $ isNonEmpty = TrinaryLogic::createYes ();
450
+ if (!$ walkResult -> isInOptionalQuantification () && $ literalValue !== '' ) {
451
+ $ walkResult = $ walkResult -> nonEmpty ( TrinaryLogic::createYes () );
465
452
}
466
453
}
467
454
} elseif (!in_array ($ ast ->getId (), ['#capturing ' , '#namedcapturing ' , '#alternation ' ], true )) {
468
- $ onlyLiterals = null ;
455
+ $ walkResult = $ walkResult -> onlyLiterals ( null ) ;
469
456
}
470
457
471
458
if ($ ast ->getId () === '#alternation ' ) {
@@ -476,22 +463,20 @@ private function walkGroupAst(
476
463
// doable but really silly compared to just \d so we can safely assume the string is not numeric
477
464
// for negative classes
478
465
if ($ ast ->getId () === '#negativeclass ' ) {
479
- $ isNumeric = TrinaryLogic::createNo ();
466
+ $ walkResult = $ walkResult -> numeric ( TrinaryLogic::createNo () );
480
467
}
481
468
482
469
foreach ($ children as $ child ) {
483
- $ this ->walkGroupAst (
470
+ $ walkResult = $ this ->walkGroupAst (
484
471
$ child ,
485
472
$ inAlternation ,
486
- $ isNonEmpty ,
487
- $ isNonFalsy ,
488
- $ isNumeric ,
489
- $ inOptionalQuantification ,
490
- $ onlyLiterals ,
491
473
$ inClass ,
492
474
$ patternModifiers ,
475
+ $ walkResult ,
493
476
);
494
477
}
478
+
479
+ return $ walkResult ;
495
480
}
496
481
497
482
private function isMaybeEmptyNode (TreeNode $ node , string $ patternModifiers , bool &$ isNonFalsy ): bool
0 commit comments