@@ -278,13 +278,19 @@ private module Cached {
278
278
nodeFrom .asPattern ( ) .( TypedPattern ) .getSubPattern ( )
279
279
]
280
280
or
281
- // Flow from the unique parameter of a key path expression to
282
- // the first component in the chain.
283
- nodeTo .( KeyPathComponentNodeImpl ) .getComponent ( ) =
284
- nodeFrom .( KeyPathParameterNode ) .getComponent ( 0 )
281
+ // Flow from the last component in a key path chain to
282
+ // the return node for the key path.
283
+ exists ( KeyPathExpr keyPath |
284
+ nodeFrom .( KeyPathComponentNodeImpl ) .getComponent ( ) =
285
+ keyPath .getComponent ( keyPath .getNumberOfComponents ( ) - 1 ) and
286
+ nodeTo .( KeyPathReturnNodeImpl ) .getKeyPathExpr ( ) = keyPath
287
+ )
285
288
or
286
- nodeFrom .( KeyPathComponentPostUpdateNode ) .getComponent ( ) =
287
- nodeTo .( KeyPathParameterPostUpdateNode ) .getComponent ( 0 )
289
+ exists ( KeyPathExpr keyPath |
290
+ nodeTo .( KeyPathComponentPostUpdateNode ) .getComponent ( ) =
291
+ keyPath .getComponent ( keyPath .getNumberOfComponents ( ) - 1 ) and
292
+ nodeFrom .( KeyPathReturnPostUpdateNode ) .getKeyPathExpr ( ) = keyPath
293
+ )
288
294
or
289
295
// Flow to the result of a keypath assignment
290
296
exists ( KeyPathApplicationExpr apply , AssignExpr assign |
@@ -1085,8 +1091,8 @@ predicate storeStep(Node node1, ContentSet c, Node node2) {
1085
1091
// creation of an optional via implicit wrapping keypath component
1086
1092
exists ( KeyPathComponent component |
1087
1093
component .isOptionalWrapping ( ) and
1088
- node1 .( KeyPathComponentNodeImpl ) .getComponent ( ) = component and
1089
- node2 .( KeyPathReturnNodeImpl ) . getKeyPathExpr ( ) = component . getKeyPathExpr ( ) and
1094
+ node1 .( KeyPathComponentNodeImpl ) .getComponent ( ) . getNextComponent ( ) = component and
1095
+ node2 .( KeyPathComponentNodeImpl ) . getComponent ( ) = component and
1090
1096
c instanceof OptionalSomeContentSet
1091
1097
)
1092
1098
or
@@ -1174,7 +1180,13 @@ predicate readStep(Node node1, ContentSet c, Node node2) {
1174
1180
or
1175
1181
// read of a component in a key-path expression chain
1176
1182
exists ( KeyPathComponent component |
1177
- component = node1 .( KeyPathComponentNodeImpl ) .getComponent ( ) and
1183
+ // the first node is either the previous element in the chain
1184
+ node1 .( KeyPathComponentNodeImpl ) .getComponent ( ) .getNextComponent ( ) = component
1185
+ or
1186
+ // or the start node, if this is the first component in the chain
1187
+ component = node1 .( KeyPathParameterNode ) .getComponent ( 0 )
1188
+ |
1189
+ component = node2 .( KeyPathComponentNodeImpl ) .getComponent ( ) and
1178
1190
(
1179
1191
c .isSingleton ( any ( Content:: FieldContent ct | ct .getField ( ) = component .getDeclRef ( ) ) )
1180
1192
or
@@ -1188,13 +1200,6 @@ predicate readStep(Node node1, ContentSet c, Node node2) {
1188
1200
component .isOptionalChaining ( )
1189
1201
)
1190
1202
)
1191
- |
1192
- // the next node is either the next element in the chain
1193
- node2 .( KeyPathComponentNodeImpl ) .getComponent ( ) = component .getNextComponent ( )
1194
- or
1195
- // or the return node, if this is the last component in the chain
1196
- not exists ( component .getNextComponent ( ) ) and
1197
- node2 .( KeyPathReturnNodeImpl ) .getKeyPathExpr ( ) = component .getKeyPathExpr ( )
1198
1203
)
1199
1204
or
1200
1205
// read of array or collection content via subscript operator
0 commit comments