Improve QLDocs of CallNode and MethodCallNode

When a function is assigned to a variable and called through that
variable then we can't always tell it was a method.
This commit is contained in:
Owen Mansel-Chan
2023-11-22 16:32:10 +00:00
parent 30891ca4aa
commit dd8fb29a65

View File

@@ -480,7 +480,11 @@ module Public {
class CallNode extends ExprNode {
override CallExpr expr;
/** Gets the declared target of this call */
/**
* Gets the declared target of this call, if it exists.
*
* This doesn't exist when a function is called via a variable.
*/
Function getTarget() { result = expr.getTarget() }
private DataFlow::Node getACalleeSource() { result = getACalleeSource(this) }
@@ -637,14 +641,41 @@ module Public {
/** Gets a result of this call. */
Node getAResult() { result = this.getResult(_) }
/** Gets the data flow node corresponding to the receiver of this call, if any. */
/**
* Gets the data flow node corresponding to the receiver of this call, if any.
*
* When a method value is assigned to a variable then when it is called it
* looks like a function call, as in the following example.
*
* ```go
* file, _ := os.Open("test.txt")
* f := file.Close
* f()
* ```
*
* In this case we use local flow to try to find the receiver (`file` in
* the above example).
*/
Node getReceiver() { result = this.getACalleeSource().(MethodReadNode).getReceiver() }
/** Holds if this call has an ellipsis after its last argument. */
predicate hasEllipsis() { expr.hasEllipsis() }
}
/** A data flow node that represents a call to a method. */
/**
* A data flow node that represents a direct call to a method.
*
* When a method value is assigned to a variable then when it is called it
* syntactically looks like a function call, as in the following example.
*
* ```go
* file, _ := os.Open("test.txt")
* f := file.Close
* f()
* ```
*
* In this case it will not be considered a `MethodCallNode`.
*/
class MethodCallNode extends CallNode {
MethodCallNode() { expr.getTarget() instanceof Method }