@@ -263,11 +263,18 @@ private module Cached {
263263 or
264264 // Flow from the unique parameter of a key path expression to
265265 // the first component in the chain.
266- nodeTo .( KeyPathComponentNodeImpl ) .getComponent ( ) =
267- nodeFrom .( KeyPathParameterNode ) .getComponent ( 0 )
266+ exists ( KeyPathExpr keyPath |
267+ nodeFrom .( KeyPathComponentNodeImpl ) .getComponent ( ) = keyPath .getComponent ( keyPath .getNumberOfComponents ( ) - 1 ) and
268+ nodeTo .( KeyPathReturnNodeImpl ) .getKeyPathExpr ( ) = keyPath
269+ )
268270 or
269- nodeFrom .( KeyPathComponentPostUpdateNode ) .getComponent ( ) =
270- nodeTo .( KeyPathParameterPostUpdateNode ) .getComponent ( 0 )
271+ exists ( KeyPathExpr keyPath |
272+ nodeTo .( KeyPathComponentPostUpdateNode ) .getComponent ( ) = keyPath .getComponent ( keyPath .getNumberOfComponents ( ) - 1 ) and
273+ nodeFrom .( KeyPathReturnPostUpdateNode ) .getKeyPathExpr ( ) = keyPath
274+ )
275+
276+ // nodeFrom.(KeyPathComponentPostUpdateNode).getComponent() =
277+ // nodeTo.(KeyPathParameterPostUpdateNode).getComponent(0)
271278 or
272279 // Flow to the result of a keypath assignment
273280 exists ( KeyPathApplicationExpr apply , AssignExpr assign |
@@ -864,8 +871,8 @@ predicate storeStep(Node node1, ContentSet c, Node node2) {
864871 // creation of an optional via implicit wrapping keypath component
865872 exists ( KeyPathComponent component |
866873 component .isOptionalWrapping ( ) and
867- node1 .( KeyPathComponentNodeImpl ) .getComponent ( ) = component and
868- node2 .( KeyPathReturnNodeImpl ) . getKeyPathExpr ( ) = component . getKeyPathExpr ( ) and
874+ node1 .( KeyPathComponentNodeImpl ) .getComponent ( ) . getNextComponent ( ) = component and
875+ node2 .( KeyPathComponentNodeImpl ) . getComponent ( ) = component and
869876 c instanceof OptionalSomeContentSet
870877 )
871878 or
@@ -951,7 +958,14 @@ predicate readStep(Node node1, ContentSet c, Node node2) {
951958 or
952959 // read of a component in a key-path expression chain
953960 exists ( KeyPathComponent component |
954- component = node1 .( KeyPathComponentNodeImpl ) .getComponent ( ) and
961+ // the first node is either the previous element in the chain
962+ node1 .( KeyPathComponentNodeImpl ) .getComponent ( ) .getNextComponent ( ) = component
963+ or
964+ // or the start node, if this is the first component in the chain
965+ component =
966+ node1 .( KeyPathParameterNode ) .getComponent ( 0 )
967+ |
968+ component = node2 .( KeyPathComponentNodeImpl ) .getComponent ( ) and
955969 (
956970 c .isSingleton ( any ( Content:: FieldContent ct | ct .getField ( ) = component .getDeclRef ( ) ) )
957971 or
@@ -965,13 +979,6 @@ predicate readStep(Node node1, ContentSet c, Node node2) {
965979 component .isOptionalChaining ( )
966980 )
967981 )
968- |
969- // the next node is either the next element in the chain
970- node2 .( KeyPathComponentNodeImpl ) .getComponent ( ) = component .getNextComponent ( )
971- or
972- // or the return node, if this is the last component in the chain
973- not exists ( component .getNextComponent ( ) ) and
974- node2 .( KeyPathReturnNodeImpl ) .getKeyPathExpr ( ) = component .getKeyPathExpr ( )
975982 )
976983 or
977984 // read of array or collection content via subscript operator
0 commit comments