@@ -1595,10 +1595,10 @@ import IterableUnpacking
1595
1595
*
1596
1596
* - as pattern: subject flows to alias as well as to the interior pattern
1597
1597
* - 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
1599
1599
* - capture pattern: subject flows to the variable
1600
1600
* - wildcard pattern: no flow
1601
- * - value pattern: no flow
1601
+ * - value pattern: flow from the value to the pattern, to add information
1602
1602
* - sequence pattern: each element reads from subject at the associated index
1603
1603
* - star pattern: subject flows to the variable, possibly via a conversion
1604
1604
* - mapping pattern: each value reads from subject at the associated key
@@ -1636,14 +1636,16 @@ module MatchUnpacking {
1636
1636
*/
1637
1637
predicate matchAsFlowStep ( Node nodeFrom , Node nodeTo ) {
1638
1638
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
1639
1643
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
1647
1649
)
1648
1650
}
1649
1651
@@ -1658,6 +1660,17 @@ module MatchUnpacking {
1658
1660
)
1659
1661
}
1660
1662
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
+
1661
1674
/**
1662
1675
* capture pattern: subject flows to the variable
1663
1676
* syntax (toplevel): `case var:`
@@ -1669,6 +1682,17 @@ module MatchUnpacking {
1669
1682
)
1670
1683
}
1671
1684
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
+
1672
1696
/**
1673
1697
* sequence pattern: each element reads from subject at the associated index
1674
1698
* syntax (toplevel): `case [a, b]:`
@@ -1814,8 +1838,12 @@ module MatchUnpacking {
1814
1838
or
1815
1839
matchOrFlowStep ( nodeFrom , nodeTo )
1816
1840
or
1841
+ matchLiteralFlowStep ( nodeFrom , nodeTo )
1842
+ or
1817
1843
matchCaptureFlowStep ( nodeFrom , nodeTo )
1818
1844
or
1845
+ matchValueFlowStep ( nodeFrom , nodeTo )
1846
+ or
1819
1847
matchMappingFlowStep ( nodeFrom , nodeTo )
1820
1848
}
1821
1849
0 commit comments