@@ -1595,10 +1595,10 @@ import IterableUnpacking
15951595 *
15961596 * - as pattern: subject flows to alias as well as to the interior pattern
15971597 * - or pattern: subject flows to each alternative
1598- * - literal pattern: no flow
1598+ * - literal pattern: flow from the literal to the pattern, to add information
15991599 * - capture pattern: subject flows to the variable
16001600 * - wildcard pattern: no flow
1601- * - value pattern: no flow
1601+ * - value pattern: flow from the value to the pattern, to add information
16021602 * - sequence pattern: each element reads from subject at the associated index
16031603 * - star pattern: subject flows to the variable, possibly via a conversion
16041604 * - mapping pattern: each value reads from subject at the associated key
@@ -1636,14 +1636,16 @@ module MatchUnpacking {
16361636 */
16371637 predicate matchAsFlowStep ( Node nodeFrom , Node nodeTo ) {
16381638 exists ( MatchAsPattern subject , Name alias | alias = subject .getAlias ( ) |
1639+ // We make the subject flow to the interior pattern via the alis.
1640+ // That way, information can propagate from the interior pattern to the alias.
1641+ //
1642+ // the subject flows to the interior pattern
16391643 nodeFrom .asCfgNode ( ) .getNode ( ) = subject and
1640- (
1641- // the subject flows to the alias
1642- nodeTo .asVar ( ) .getDefinition ( ) .( PatternAliasDefinition ) .getDefiningNode ( ) .getNode ( ) = alias
1643- or
1644- // the subject flows to the interior pattern
1645- nodeTo .asCfgNode ( ) .getNode ( ) = subject .getPattern ( )
1646- )
1644+ nodeTo .asCfgNode ( ) .getNode ( ) = subject .getPattern ( )
1645+ or
1646+ // the interior pattern flows to the alias
1647+ nodeFrom .asCfgNode ( ) .getNode ( ) = subject .getPattern ( ) and
1648+ nodeTo .asVar ( ) .getDefinition ( ) .( PatternAliasDefinition ) .getDefiningNode ( ) .getNode ( ) = alias
16471649 )
16481650 }
16491651
@@ -1658,6 +1660,17 @@ module MatchUnpacking {
16581660 )
16591661 }
16601662
1663+ /**
1664+ * literal pattern: flow from the literal to the pattern, to add information
1665+ * syntax (toplevel): `case literal:`
1666+ */
1667+ predicate matchLiteralFlowStep ( Node nodeFrom , Node nodeTo ) {
1668+ exists ( MatchLiteralPattern pattern , Expr literal | literal = pattern .getLiteral ( ) |
1669+ nodeFrom .asExpr ( ) = literal and
1670+ nodeTo .asCfgNode ( ) .getNode ( ) = pattern
1671+ )
1672+ }
1673+
16611674 /**
16621675 * capture pattern: subject flows to the variable
16631676 * syntax (toplevel): `case var:`
@@ -1669,6 +1682,17 @@ module MatchUnpacking {
16691682 )
16701683 }
16711684
1685+ /**
1686+ * value pattern: flow from the value to the pattern, to add information
1687+ * syntax (toplevel): `case Dotted.value:`
1688+ */
1689+ predicate matchValueFlowStep ( Node nodeFrom , Node nodeTo ) {
1690+ exists ( MatchValuePattern pattern , Expr value | value = pattern .getValue ( ) |
1691+ nodeFrom .asExpr ( ) = value and
1692+ nodeTo .asCfgNode ( ) .getNode ( ) = pattern
1693+ )
1694+ }
1695+
16721696 /**
16731697 * sequence pattern: each element reads from subject at the associated index
16741698 * syntax (toplevel): `case [a, b]:`
@@ -1814,8 +1838,12 @@ module MatchUnpacking {
18141838 or
18151839 matchOrFlowStep ( nodeFrom , nodeTo )
18161840 or
1841+ matchLiteralFlowStep ( nodeFrom , nodeTo )
1842+ or
18171843 matchCaptureFlowStep ( nodeFrom , nodeTo )
18181844 or
1845+ matchValueFlowStep ( nodeFrom , nodeTo )
1846+ or
18191847 matchMappingFlowStep ( nodeFrom , nodeTo )
18201848 }
18211849
0 commit comments