@@ -348,6 +348,9 @@ class CaseExpr extends ControlExpr, TCaseExpr {
348348 */
349349 final Expr getABranch ( ) { result = this .getBranch ( _) }
350350
351+ /** Gets the `n`th `when` branch of this case expression. */
352+ final WhenExpr getWhenBranch ( int n ) { result = this .getBranch ( n ) }
353+
351354 /** Gets a `when` branch of this case expression. */
352355 final WhenExpr getAWhenBranch ( ) { result = this .getABranch ( ) }
353356
@@ -367,6 +370,10 @@ class CaseExpr extends ControlExpr, TCaseExpr {
367370 pred = "getValue" and result = this .getValue ( )
368371 or
369372 pred = "getBranch" and result = this .getBranch ( _)
373+ or
374+ pred = "getWhenBranch" and result = this .getWhenBranch ( _)
375+ or
376+ pred = "getElseBranch" and result = this .getElseBranch ( )
370377 }
371378}
372379
@@ -422,6 +429,204 @@ class WhenExpr extends Expr, TWhenExpr {
422429 }
423430}
424431
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+
425630/**
426631 * A loop. That is, a `for` loop, a `while` or `until` loop, or their
427632 * expression-modifier variants.
0 commit comments