@@ -46,33 +46,26 @@ class DirectEval extends CallExpr {
4646}
4747
4848/**
49- * Flow analysis for `this` expressions inside a function that is called with
50- * `Array.prototype.map` or a similar Array function that binds `this`.
51- *
52- * However, since the function could be invoked in another way, we additionally
53- * still infer the ordinary abstract value.
49+ * Models `Array.prototype.map` and friends as partial invocations that pass their second
50+ * argument as the receiver to the callback.
5451 */
55- private class AnalyzedThisInArrayIterationFunction extends AnalyzedNode , DataFlow:: ThisNode {
56- AnalyzedNode thisSource ;
57-
58- AnalyzedThisInArrayIterationFunction ( ) {
59- exists ( DataFlow:: MethodCallNode bindingCall , string name |
52+ private class ArrayIterationCallbackAsPartialInvoke extends DataFlow:: PartialInvokeNode:: Range , DataFlow:: MethodCallNode {
53+ ArrayIterationCallbackAsPartialInvoke ( ) {
54+ getNumArgument ( ) = 2 and
55+ // Filter out library methods named 'forEach' etc
56+ not DataFlow:: moduleImport ( _) .flowsTo ( getReceiver ( ) ) and
57+ exists ( string name | name = getMethodName ( ) |
6058 name = "filter" or
6159 name = "forEach" or
6260 name = "map" or
6361 name = "some" or
6462 name = "every"
65- |
66- name = bindingCall .getMethodName ( ) and
67- 2 = bindingCall .getNumArgument ( ) and
68- getBinder ( ) = bindingCall .getCallback ( 0 ) and
69- thisSource = bindingCall .getArgument ( 1 )
7063 )
7164 }
7265
73- override AbstractValue getALocalValue ( ) {
74- result = thisSource . getALocalValue ( ) or
75- result = AnalyzedNode . super . getALocalValue ( )
66+ override DataFlow :: Node getBoundReceiver ( DataFlow :: Node callback ) {
67+ callback = getArgument ( 0 ) and
68+ result = getArgument ( 1 )
7669 }
7770}
7871
0 commit comments