@@ -557,13 +557,7 @@ class ThrowStmt extends Stmt, @throwstmt {
557557}
558558
559559/** A `break`, `yield` or `continue` statement. */
560- class JumpStmt extends Stmt {
561- JumpStmt ( ) {
562- this instanceof BreakStmt or
563- this instanceof YieldStmt or
564- this instanceof ContinueStmt
565- }
566-
560+ abstract class JumpStmt extends Stmt {
567561 /**
568562 * Gets the labeled statement that this `break` or
569563 * `continue` statement refers to, if any.
@@ -584,12 +578,7 @@ class JumpStmt extends Stmt {
584578 )
585579 }
586580
587- private SwitchExpr getSwitchExprTarget ( ) { result = this .( YieldStmt ) .getParent + ( ) }
588-
589581 private StmtParent getEnclosingTarget ( ) {
590- result = this .getSwitchExprTarget ( )
591- or
592- not exists ( this .getSwitchExprTarget ( ) ) and
593582 result = this .getAPotentialTarget ( ) and
594583 not exists ( Stmt other | other = this .getAPotentialTarget ( ) | other .getEnclosingStmt + ( ) = result )
595584 }
@@ -598,14 +587,15 @@ class JumpStmt extends Stmt {
598587 * Gets the statement or `switch` expression that this `break`, `yield` or `continue` jumps to.
599588 */
600589 StmtParent getTarget ( ) {
590+ // Note: This implementation only considers `break` and `continue`; YieldStmt overrides this predicate
601591 result = this .getLabelTarget ( )
602592 or
603593 not exists ( this .getLabelTarget ( ) ) and result = this .getEnclosingTarget ( )
604594 }
605595}
606596
607597/** A `break` statement. */
608- class BreakStmt extends Stmt , @breakstmt {
598+ class BreakStmt extends JumpStmt , @breakstmt {
609599 /** Gets the label targeted by this `break` statement, if any. */
610600 string getLabel ( ) { namestrings ( result , _, this ) }
611601
@@ -626,12 +616,21 @@ class BreakStmt extends Stmt, @breakstmt {
626616/**
627617 * A `yield` statement.
628618 */
629- class YieldStmt extends Stmt , @yieldstmt {
619+ class YieldStmt extends JumpStmt , @yieldstmt {
630620 /**
631621 * Gets the value of this `yield` statement.
632622 */
633623 Expr getValue ( ) { result .getParent ( ) = this }
634624
625+ /**
626+ * Gets the `switch` expression target of this `yield` statement.
627+ */
628+ override SwitchExpr getTarget ( ) {
629+ // Get the innermost enclosing SwitchExpr; this works because getParent() is defined for Stmt and
630+ // therefore won't proceed after the innermost SwitchExpr (due to it being an Expr)
631+ result = this .getParent + ( )
632+ }
633+
635634 override string pp ( ) { result = "yield ..." }
636635
637636 override string toString ( ) { result = "yield ..." }
@@ -642,7 +641,7 @@ class YieldStmt extends Stmt, @yieldstmt {
642641}
643642
644643/** A `continue` statement. */
645- class ContinueStmt extends Stmt , @continuestmt {
644+ class ContinueStmt extends JumpStmt , @continuestmt {
646645 /** Gets the label targeted by this `continue` statement, if any. */
647646 string getLabel ( ) { namestrings ( result , _, this ) }
648647
0 commit comments