@@ -348,6 +348,9 @@ class CaseExpr extends ControlExpr, TCaseExpr {
348
348
*/
349
349
final Expr getABranch ( ) { result = this .getBranch ( _) }
350
350
351
+ /** Gets the `n`th `when` branch of this case expression. */
352
+ final WhenExpr getWhenBranch ( int n ) { result = this .getBranch ( n ) }
353
+
351
354
/** Gets a `when` branch of this case expression. */
352
355
final WhenExpr getAWhenBranch ( ) { result = this .getABranch ( ) }
353
356
@@ -367,6 +370,10 @@ class CaseExpr extends ControlExpr, TCaseExpr {
367
370
pred = "getValue" and result = this .getValue ( )
368
371
or
369
372
pred = "getBranch" and result = this .getBranch ( _)
373
+ or
374
+ pred = "getWhenBranch" and result = this .getWhenBranch ( _)
375
+ or
376
+ pred = "getElseBranch" and result = this .getElseBranch ( )
370
377
}
371
378
}
372
379
@@ -422,6 +429,204 @@ class WhenExpr extends Expr, TWhenExpr {
422
429
}
423
430
}
424
431
432
+ /**
433
+ * A `case` statement used for pattern matching. For example:
434
+ * ```rb
435
+ * config = {db: {user: 'admin', password: 'abc123'}}
436
+ * case config
437
+ * in db: {user:} # matches subhash and puts matched value in variable user
438
+ * puts "Connect with user '#{user}'"
439
+ * in connection: {username: } unless username == 'admin'
440
+ * puts "Connect with user '#{username}'"
441
+ * else
442
+ * puts "Unrecognized structure of config"
443
+ * end
444
+ * ```
445
+ */
446
+ class CaseMatch extends ControlExpr , TCaseMatch {
447
+ private Ruby:: CaseMatch g ;
448
+
449
+ CaseMatch ( ) { this = TCaseMatch ( g ) }
450
+
451
+ final override string getAPrimaryQlClass ( ) { result = "CaseMatch" }
452
+
453
+ /**
454
+ * Gets the expression being matched. For example, `foo` in the following example.
455
+ * ```rb
456
+ * case foo
457
+ * in 0
458
+ * puts 'zero'
459
+ * in 1
460
+ * puts 'one'
461
+ * end
462
+ * ```
463
+ */
464
+ final Expr getValue ( ) { toGenerated ( result ) = g .getValue ( ) }
465
+
466
+ /**
467
+ * Gets the `n`th branch of this case expression, either an `InClause` or a
468
+ * `StmtSequence`.
469
+ */
470
+ final Expr getBranch ( int n ) {
471
+ toGenerated ( result ) = g .getClauses ( n )
472
+ or
473
+ n = count ( g .getClauses ( _) ) and toGenerated ( result ) = g .getElse ( )
474
+ }
475
+
476
+ /**
477
+ * Gets a branch of this case expression, either an `InClause` or an
478
+ * `StmtSequence`.
479
+ */
480
+ final Expr getABranch ( ) { result = this .getBranch ( _) }
481
+
482
+ /** Gets the `n`th `in` clause of this case expression. */
483
+ final InClause getInClause ( int n ) { result = this .getBranch ( n ) }
484
+
485
+ /** Gets an `in` clause of this case expression. */
486
+ final InClause getAnInClause ( ) { result = this .getABranch ( ) }
487
+
488
+ /** Gets the `else` branch of this case expression, if any. */
489
+ final StmtSequence getElseBranch ( ) { result = this .getABranch ( ) }
490
+
491
+ /**
492
+ * Gets the number of branches of this case expression.
493
+ */
494
+ final int getNumberOfBranches ( ) { result = count ( this .getBranch ( _) ) }
495
+
496
+ final override string toString ( ) { result = "case ... in" }
497
+
498
+ override AstNode getAChild ( string pred ) {
499
+ result = super .getAChild ( pred )
500
+ or
501
+ pred = "getValue" and result = this .getValue ( )
502
+ or
503
+ pred = "getBranch" and result = this .getBranch ( _)
504
+ or
505
+ pred = "getInClause" and result = this .getInClause ( _)
506
+ or
507
+ pred = "getElseBranch" and result = this .getElseBranch ( )
508
+ }
509
+ }
510
+
511
+ /**
512
+ * An `in` clause of a `case` expression.
513
+ * ```rb
514
+ * case foo
515
+ * in [ a ] then a
516
+ * end
517
+ * ```
518
+ */
519
+ class InClause extends Expr , TInClause {
520
+ private Ruby:: InClause g ;
521
+
522
+ InClause ( ) { this = TInClause ( g ) }
523
+
524
+ final override string getAPrimaryQlClass ( ) { result = "InClause" }
525
+
526
+ /** Gets the body of this case-in expression. */
527
+ final Stmt getBody ( ) { toGenerated ( result ) = g .getBody ( ) }
528
+
529
+ /**
530
+ * Gets the pattern in this case-in expression. In the
531
+ * following example, the pattern is `Point{ x:, y: }`.
532
+ * ```rb
533
+ * case foo
534
+ * in Point{ x:, y: }
535
+ * x + y
536
+ * end
537
+ * ```
538
+ */
539
+ final CasePattern getPattern ( ) { toGenerated ( result ) = g .getPattern ( ) }
540
+
541
+ /**
542
+ * Gets the pattern guard in this case-in expression. In the
543
+ * following example, the pattern guard is `x > 10`.
544
+ * ```rb
545
+ * case foo
546
+ * in [ x ] if x > 10 then ...
547
+ * end
548
+ * ```
549
+ */
550
+ final PatternGuard getPatternGuard ( ) { toGenerated ( result ) = g .getGuard ( ) }
551
+
552
+ final override string toString ( ) { result = "in ... then ..." }
553
+
554
+ override AstNode getAChild ( string pred ) {
555
+ result = super .getAChild ( pred )
556
+ or
557
+ pred = "getBody" and result = this .getBody ( )
558
+ or
559
+ pred = "getPattern" and result = this .getPattern ( )
560
+ or
561
+ pred = "getGuard" and result = this .getPatternGuard ( )
562
+ }
563
+ }
564
+
565
+ /**
566
+ * A guard used in pattern matching. For example:
567
+ * ```rb
568
+ * in pattern if guard
569
+ * in pattern unless guard
570
+ * ```
571
+ */
572
+ class PatternGuard extends AstNode , TPatternGuard {
573
+ /**
574
+ * Gets the condition expression. For example, the result is `foo` in the
575
+ * following:
576
+ * ```rb
577
+ * if foo
578
+ * unless foo
579
+ * ```
580
+ */
581
+ Expr getCondition ( ) { none ( ) }
582
+
583
+ override AstNode getAChild ( string pred ) {
584
+ result = super .getAChild ( pred )
585
+ or
586
+ pred = "getCondition" and result = this .getCondition ( )
587
+ }
588
+ }
589
+
590
+ /**
591
+ * An `if` pattern guard. For example:
592
+ * ```rb
593
+ * case foo
594
+ * in [ bar] if bar > 10
595
+ * end
596
+ * ```
597
+ */
598
+ class IfGuard extends PatternGuard , TIfGuard {
599
+ private Ruby:: IfGuard g ;
600
+
601
+ IfGuard ( ) { this = TIfGuard ( g ) }
602
+
603
+ final override Expr getCondition ( ) { toGenerated ( result ) = g .getCondition ( ) }
604
+
605
+ final override string getAPrimaryQlClass ( ) { result = "IfGuard" }
606
+
607
+ final override string toString ( ) { result = "if ..." }
608
+ }
609
+
610
+ /**
611
+ * An `unless` pattern guard. For example:
612
+ * ```rb
613
+ * case foo
614
+ * in [ bar] unless bar > 10
615
+ * end
616
+ * ```
617
+ */
618
+ class UnlessGuard extends PatternGuard , TUnlessGuard {
619
+ private Ruby:: UnlessGuard g ;
620
+
621
+ UnlessGuard ( ) { this = TUnlessGuard ( g ) }
622
+
623
+ final override Expr getCondition ( ) { toGenerated ( result ) = g .getCondition ( ) }
624
+
625
+ final override string getAPrimaryQlClass ( ) { result = "UnlessGuard" }
626
+
627
+ final override string toString ( ) { result = "unless ..." }
628
+ }
629
+
425
630
/**
426
631
* A loop. That is, a `for` loop, a `while` or `until` loop, or their
427
632
* expression-modifier variants.
0 commit comments