Skip to content

Commit d4b0554

Browse files
authored
Python: Add MethodCallNode class
Roughly patterned after the JS equivalent.
1 parent 6333752 commit d4b0554

File tree

1 file changed

+24
-0
lines changed

1 file changed

+24
-0
lines changed

python/ql/src/semmle/python/dataflow/new/internal/DataFlowPublic.qll

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -180,6 +180,30 @@ class CallCfgNode extends CfgNode, LocalSourceNode {
180180
Node getArgByName(string name) { result.asCfgNode() = node.getArgByName(name) }
181181
}
182182

183+
/**
184+
* A data-flow node corresponding to a method call, that is `foo.bar(...)`.
185+
*
186+
* Also covers the case where the method lookup is done separately from the call itself, as in
187+
* `temp = foo.bar; temp(...)`.
188+
*/
189+
class MethodCallNode extends CallCfgNode {
190+
AttrRead method_lookup;
191+
192+
MethodCallNode() { method_lookup = this.getFunction().getALocalSource() }
193+
194+
/** Gets the name of the method being invoked (the `bar` in `foo.bar(...)`, if it can be determined. */
195+
string getMethodName() { result = method_lookup.getAttributeName() }
196+
197+
/** Gets the data-flow node corresponding to the receiver of this call. That is, the `foo` in `foo.bar(...)`. */
198+
Node getReceiver() { result = method_lookup.getObject() }
199+
200+
/** Holds if this data-flow node calls method `methodName` on receiver node `receiver`. */
201+
predicate calls(Node receiver, string methodName) {
202+
receiver = this.getReceiver() and
203+
methodName = this.getMethodName()
204+
}
205+
}
206+
183207
/**
184208
* An expression, viewed as a node in a data flow graph.
185209
*

0 commit comments

Comments
 (0)