mirror of
https://github.com/github/codeql.git
synced 2026-05-01 03:35:13 +02:00
Merge pull request #3407 from RasmusWL/python-add-BoundMethodValue-v2
Approved by tausbn
This commit is contained in:
@@ -27,8 +27,10 @@ abstract class CallableObjectInternal extends ObjectInternal {
|
||||
none()
|
||||
}
|
||||
|
||||
/** Gets the `n`th parameter node of this callable. */
|
||||
abstract NameNode getParameter(int n);
|
||||
|
||||
/** Gets the `name`d parameter node of this callable. */
|
||||
abstract NameNode getParameterByName(string name);
|
||||
|
||||
abstract predicate neverReturns();
|
||||
@@ -438,16 +440,30 @@ class BoundMethodObjectInternal extends CallableObjectInternal, TBoundMethod {
|
||||
PointsTo::pointsTo(result.getFunction(), ctx, this, _)
|
||||
}
|
||||
|
||||
override NameNode getParameter(int n) { result = this.getFunction().getParameter(n + 1) }
|
||||
/** Gets the parameter node that will be used for `self`. */
|
||||
NameNode getSelfParameter() { result = this.getFunction().getParameter(0) }
|
||||
|
||||
override NameNode getParameter(int n) {
|
||||
result = this.getFunction().getParameter(n + 1) and
|
||||
// don't return the parameter for `self` at `n = -1`
|
||||
n >= 0
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the `name`d parameter node of this callable.
|
||||
* Will not return the parameter node for `self`, instead use `getSelfParameter`.
|
||||
*/
|
||||
override NameNode getParameterByName(string name) {
|
||||
result = this.getFunction().getParameterByName(name)
|
||||
result = this.getFunction().getParameterByName(name) and
|
||||
not result = this.getSelfParameter()
|
||||
}
|
||||
|
||||
override predicate neverReturns() { this.getFunction().neverReturns() }
|
||||
|
||||
override predicate functionAndOffset(CallableObjectInternal function, int offset) {
|
||||
function = this.getFunction() and offset = 1
|
||||
or
|
||||
function = this and offset = 0
|
||||
}
|
||||
|
||||
override predicate useOriginAsLegacyObject() { any() }
|
||||
|
||||
@@ -352,7 +352,29 @@ class CallableValue extends Value {
|
||||
result = this.(CallableObjectInternal).getParameterByName(name)
|
||||
}
|
||||
|
||||
/** Gets the argument corresponding to the `n'th parameter node of this callable. */
|
||||
/**
|
||||
* Gets the argument in `call` corresponding to the `n`'th positional parameter of this callable.
|
||||
*
|
||||
* Use this method instead of `call.getArg(n)` to handle the fact that this function might be used as
|
||||
* a bound-method, such that argument `n` of the call corresponds to the `n+1` parameter of the callable.
|
||||
*
|
||||
* This method also gives results when the argument is passed as a keyword argument in `call`, as long
|
||||
* as `this` is not a builtin function or a builtin method.
|
||||
*
|
||||
* Examples:
|
||||
*
|
||||
* - if `this` represents the `PythonFunctionValue` for `def func(a, b):`, and `call` represents
|
||||
* `func(10, 20)`, then `getArgumentForCall(call, 0)` will give the `ControlFlowNode` for `10`.
|
||||
*
|
||||
* - with `call` representing `func(b=20, a=10)`, `getArgumentForCall(call, 0)` will give
|
||||
* the `ControlFlowNode` for `10`.
|
||||
*
|
||||
* - if `this` represents the `PythonFunctionValue` for `def func(self, a, b):`, and `call`
|
||||
* represents `foo.func(10, 20)`, then `getArgumentForCall(call, 1)` will give the
|
||||
* `ControlFlowNode` for `10`.
|
||||
* Note: There will also exist a `BoundMethodValue bm` where `bm.getArgumentForCall(call, 0)`
|
||||
* will give the `ControlFlowNode` for `10` (notice the shift in index used).
|
||||
*/
|
||||
cached
|
||||
ControlFlowNode getArgumentForCall(CallNode call, int n) {
|
||||
exists(ObjectInternal called, int offset |
|
||||
@@ -363,7 +385,7 @@ class CallableValue extends Value {
|
||||
or
|
||||
exists(string name |
|
||||
call.getArgByName(name) = result and
|
||||
this.(PythonFunctionObjectInternal).getScope().getArg(n + offset).getName() = name
|
||||
this.getParameter(n).getId() = name
|
||||
)
|
||||
or
|
||||
called instanceof BoundMethodObjectInternal and
|
||||
@@ -373,21 +395,37 @@ class CallableValue extends Value {
|
||||
)
|
||||
}
|
||||
|
||||
/** Gets the argument corresponding to the `name`d parameter node of this callable. */
|
||||
/**
|
||||
* Gets the argument in `call` corresponding to the `name`d keyword parameter of this callable.
|
||||
*
|
||||
* This method also gives results when the argument is passed as a positional argument in `call`, as long
|
||||
* as `this` is not a builtin function or a builtin method.
|
||||
*
|
||||
* Examples:
|
||||
*
|
||||
* - if `this` represents the `PythonFunctionValue` for `def func(a, b):`, and `call` represents
|
||||
* `func(10, 20)`, then `getNamedArgumentForCall(call, "a")` will give the `ControlFlowNode` for `10`.
|
||||
*
|
||||
* - with `call` representing `func(b=20, a=10)`, `getNamedArgumentForCall(call, "a")` will give
|
||||
* the `ControlFlowNode` for `10`.
|
||||
*
|
||||
* - if `this` represents the `PythonFunctionValue` for `def func(self, a, b):`, and `call`
|
||||
* represents `foo.func(10, 20)`, then `getNamedArgumentForCall(call, "a")` will give the
|
||||
* `ControlFlowNode` for `10`.
|
||||
*/
|
||||
cached
|
||||
ControlFlowNode getNamedArgumentForCall(CallNode call, string name) {
|
||||
exists(CallableObjectInternal called, int offset |
|
||||
PointsToInternal::pointsTo(call.getFunction(), _, called, _) and
|
||||
called.functionAndOffset(this, offset)
|
||||
|
|
||||
call.getArgByName(name) = result
|
||||
or
|
||||
exists(int n |
|
||||
call.getArg(n) = result and
|
||||
this.(PythonFunctionObjectInternal).getScope().getArg(n + offset).getName() = name
|
||||
this.getParameter(n + offset).getId() = name
|
||||
)
|
||||
or
|
||||
call.getArgByName(name) = result and
|
||||
exists(this.(PythonFunctionObjectInternal).getScope().getArgByName(name))
|
||||
or
|
||||
called instanceof BoundMethodObjectInternal and
|
||||
offset = 1 and
|
||||
name = "self" and
|
||||
@@ -396,6 +434,29 @@ class CallableValue extends Value {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Class representing bound-methods, such as `o.func`, where `o` is an instance
|
||||
* of a class that has a callable attribute `func`.
|
||||
*/
|
||||
class BoundMethodValue extends CallableValue {
|
||||
BoundMethodValue() { this instanceof BoundMethodObjectInternal }
|
||||
|
||||
/**
|
||||
* Gets the callable that will be used when `this` is called.
|
||||
* The actual callable for `func` in `o.func`.
|
||||
*/
|
||||
CallableValue getFunction() { result = this.(BoundMethodObjectInternal).getFunction() }
|
||||
|
||||
/**
|
||||
* Gets the value that will be used for the `self` parameter when `this` is called.
|
||||
* The value for `o` in `o.func`.
|
||||
*/
|
||||
Value getSelf() { result = this.(BoundMethodObjectInternal).getSelf() }
|
||||
|
||||
/** Gets the parameter node that will be used for `self`. */
|
||||
NameNode getSelfParameter() { result = this.(BoundMethodObjectInternal).getSelfParameter() }
|
||||
}
|
||||
|
||||
/**
|
||||
* Class representing classes in the Python program, both Python and built-in.
|
||||
*/
|
||||
@@ -663,11 +724,13 @@ class PythonFunctionValue extends FunctionValue {
|
||||
ControlFlowNode getAReturnedNode() { result = this.getScope().getAReturnValueFlowNode() }
|
||||
|
||||
override ClassValue getARaisedType() { scope_raises(result, this.getScope()) }
|
||||
|
||||
|
||||
override ClassValue getAnInferredReturnType() {
|
||||
/* We have to do a special version of this because builtin functions have no
|
||||
/*
|
||||
* We have to do a special version of this because builtin functions have no
|
||||
* explicit return nodes that we can query and get the class of.
|
||||
*/
|
||||
|
||||
result = this.getAReturnedNode().pointsTo().getClass()
|
||||
}
|
||||
}
|
||||
@@ -690,9 +753,11 @@ class BuiltinFunctionValue extends FunctionValue {
|
||||
}
|
||||
|
||||
override ClassValue getAnInferredReturnType() {
|
||||
/* We have to do a special version of this because builtin functions have no
|
||||
/*
|
||||
* We have to do a special version of this because builtin functions have no
|
||||
* explicit return nodes that we can query and get the class of.
|
||||
*/
|
||||
|
||||
result = TBuiltinClassObject(this.(BuiltinFunctionObjectInternal).getReturnType())
|
||||
}
|
||||
}
|
||||
@@ -719,7 +784,7 @@ class BuiltinMethodValue extends FunctionValue {
|
||||
/* Information is unavailable for C code in general */
|
||||
none()
|
||||
}
|
||||
|
||||
|
||||
override ClassValue getAnInferredReturnType() {
|
||||
result = TBuiltinClassObject(this.(BuiltinMethodObjectInternal).getReturnType())
|
||||
}
|
||||
|
||||
@@ -1,15 +0,0 @@
|
||||
| 19 | 0 | ControlFlowNode for w | Function f |
|
||||
| 19 | 1 | ControlFlowNode for x | Function f |
|
||||
| 19 | 2 | ControlFlowNode for y | Function f |
|
||||
| 21 | 0 | ControlFlowNode for y | Function f |
|
||||
| 21 | 1 | ControlFlowNode for w | Function f |
|
||||
| 21 | 2 | ControlFlowNode for z | Function f |
|
||||
| 23 | 0 | ControlFlowNode for c | Function f |
|
||||
| 23 | 1 | ControlFlowNode for w | Function f |
|
||||
| 23 | 2 | ControlFlowNode for z | Function f |
|
||||
| 24 | 0 | ControlFlowNode for c | Function n |
|
||||
| 24 | 1 | ControlFlowNode for x | Function n |
|
||||
| 25 | 0 | ControlFlowNode for y | Function n |
|
||||
| 25 | 1 | ControlFlowNode for z | Function n |
|
||||
| 33 | 0 | ControlFlowNode for IntegerLiteral | Function foo |
|
||||
| 34 | 0 | ControlFlowNode for IntegerLiteral | Function foo |
|
||||
@@ -1,5 +0,0 @@
|
||||
import python
|
||||
|
||||
from ControlFlowNode arg, FunctionObject func, int i
|
||||
where arg = func.getArgumentForCall(_, i)
|
||||
select arg.getLocation().getStartLine(), i, arg.toString(), func.toString()
|
||||
@@ -1,7 +0,0 @@
|
||||
| 19 | ControlFlowNode for f() | Function f |
|
||||
| 21 | ControlFlowNode for f() | Function f |
|
||||
| 23 | ControlFlowNode for Attribute() | Function f |
|
||||
| 24 | ControlFlowNode for Attribute() | Function n |
|
||||
| 25 | ControlFlowNode for Attribute() | Function n |
|
||||
| 33 | ControlFlowNode for Attribute() | Function foo |
|
||||
| 34 | ControlFlowNode for Attribute() | Function foo |
|
||||
@@ -0,0 +1,19 @@
|
||||
| 19 | ControlFlowNode for f() | Function f |
|
||||
| 21 | ControlFlowNode for f() | Function f |
|
||||
| 22 | ControlFlowNode for C() | class C |
|
||||
| 23 | ControlFlowNode for Attribute() | Method(Function f, C()) |
|
||||
| 24 | ControlFlowNode for Attribute() | Method(Function C.n, C()) |
|
||||
| 25 | ControlFlowNode for Attribute() | Function C.n |
|
||||
| 29 | ControlFlowNode for staticmethod() | builtin-class staticmethod |
|
||||
| 33 | ControlFlowNode for Attribute() | Function D.foo |
|
||||
| 34 | ControlFlowNode for Attribute() | Function D.foo |
|
||||
| 34 | ControlFlowNode for D() | class D |
|
||||
| 37 | ControlFlowNode for Attribute() | Method(builtin method append, List) |
|
||||
| 38 | ControlFlowNode for len() | Builtin-function len |
|
||||
| 40 | ControlFlowNode for f() | Function f |
|
||||
| 41 | ControlFlowNode for C() | class C |
|
||||
| 42 | ControlFlowNode for Attribute() | Method(Function C.n, C()) |
|
||||
| 45 | ControlFlowNode for open() | Builtin-function open |
|
||||
| 46 | ControlFlowNode for open() | Builtin-function open |
|
||||
| 51 | ControlFlowNode for foo() | Function foo |
|
||||
| 55 | ControlFlowNode for bar() | Function bar |
|
||||
@@ -0,0 +1,5 @@
|
||||
import python
|
||||
|
||||
from CallNode call, Value func
|
||||
where call.getFunction().pointsTo(func)
|
||||
select call.getLocation().getStartLine(), call.toString(), func.toString()
|
||||
@@ -0,0 +1,23 @@
|
||||
| 19 | ControlFlowNode for f() | Function f |
|
||||
| 21 | ControlFlowNode for f() | Function f |
|
||||
| 22 | ControlFlowNode for C() | class C |
|
||||
| 23 | ControlFlowNode for Attribute() | Function f |
|
||||
| 23 | ControlFlowNode for Attribute() | Method(Function f, C()) |
|
||||
| 24 | ControlFlowNode for Attribute() | Function C.n |
|
||||
| 24 | ControlFlowNode for Attribute() | Method(Function C.n, C()) |
|
||||
| 25 | ControlFlowNode for Attribute() | Function C.n |
|
||||
| 29 | ControlFlowNode for staticmethod() | builtin-class staticmethod |
|
||||
| 33 | ControlFlowNode for Attribute() | Function D.foo |
|
||||
| 34 | ControlFlowNode for Attribute() | Function D.foo |
|
||||
| 34 | ControlFlowNode for D() | class D |
|
||||
| 37 | ControlFlowNode for Attribute() | Method(builtin method append, List) |
|
||||
| 37 | ControlFlowNode for Attribute() | builtin method append |
|
||||
| 38 | ControlFlowNode for len() | Builtin-function len |
|
||||
| 40 | ControlFlowNode for f() | Function f |
|
||||
| 41 | ControlFlowNode for C() | class C |
|
||||
| 42 | ControlFlowNode for Attribute() | Function C.n |
|
||||
| 42 | ControlFlowNode for Attribute() | Method(Function C.n, C()) |
|
||||
| 45 | ControlFlowNode for open() | Builtin-function open |
|
||||
| 46 | ControlFlowNode for open() | Builtin-function open |
|
||||
| 51 | ControlFlowNode for foo() | Function foo |
|
||||
| 55 | ControlFlowNode for bar() | Function bar |
|
||||
@@ -1,5 +1,5 @@
|
||||
import python
|
||||
|
||||
from ControlFlowNode call, FunctionObject func
|
||||
from ControlFlowNode call, Value func
|
||||
where call = func.getACall()
|
||||
select call.getLocation().getStartLine(), call.toString(), func.toString()
|
||||
@@ -0,0 +1,34 @@
|
||||
| 19 | ControlFlowNode for f() | Function f | 0 | ControlFlowNode for w |
|
||||
| 19 | ControlFlowNode for f() | Function f | 1 | ControlFlowNode for x |
|
||||
| 19 | ControlFlowNode for f() | Function f | 2 | ControlFlowNode for y |
|
||||
| 21 | ControlFlowNode for f() | Function f | 0 | ControlFlowNode for y |
|
||||
| 21 | ControlFlowNode for f() | Function f | 1 | ControlFlowNode for w |
|
||||
| 21 | ControlFlowNode for f() | Function f | 2 | ControlFlowNode for z |
|
||||
| 23 | ControlFlowNode for Attribute() | Function f | 0 | ControlFlowNode for c |
|
||||
| 23 | ControlFlowNode for Attribute() | Function f | 1 | ControlFlowNode for w |
|
||||
| 23 | ControlFlowNode for Attribute() | Function f | 2 | ControlFlowNode for z |
|
||||
| 23 | ControlFlowNode for Attribute() | Method(Function f, C()) | 0 | ControlFlowNode for w |
|
||||
| 23 | ControlFlowNode for Attribute() | Method(Function f, C()) | 1 | ControlFlowNode for z |
|
||||
| 24 | ControlFlowNode for Attribute() | Function C.n | 0 | ControlFlowNode for c |
|
||||
| 24 | ControlFlowNode for Attribute() | Function C.n | 1 | ControlFlowNode for x |
|
||||
| 24 | ControlFlowNode for Attribute() | Method(Function C.n, C()) | 0 | ControlFlowNode for x |
|
||||
| 25 | ControlFlowNode for Attribute() | Function C.n | 0 | ControlFlowNode for y |
|
||||
| 25 | ControlFlowNode for Attribute() | Function C.n | 1 | ControlFlowNode for z |
|
||||
| 33 | ControlFlowNode for Attribute() | Function D.foo | 0 | ControlFlowNode for IntegerLiteral |
|
||||
| 34 | ControlFlowNode for Attribute() | Function D.foo | 0 | ControlFlowNode for IntegerLiteral |
|
||||
| 37 | ControlFlowNode for Attribute() | Method(builtin method append, List) | 0 | ControlFlowNode for IntegerLiteral |
|
||||
| 37 | ControlFlowNode for Attribute() | builtin method append | 0 | ControlFlowNode for l |
|
||||
| 37 | ControlFlowNode for Attribute() | builtin method append | 1 | ControlFlowNode for IntegerLiteral |
|
||||
| 38 | ControlFlowNode for len() | Builtin-function len | 0 | ControlFlowNode for l |
|
||||
| 40 | ControlFlowNode for f() | Function f | 0 | ControlFlowNode for IntegerLiteral |
|
||||
| 40 | ControlFlowNode for f() | Function f | 1 | ControlFlowNode for IntegerLiteral |
|
||||
| 40 | ControlFlowNode for f() | Function f | 2 | ControlFlowNode for IntegerLiteral |
|
||||
| 42 | ControlFlowNode for Attribute() | Function C.n | 0 | ControlFlowNode for c |
|
||||
| 42 | ControlFlowNode for Attribute() | Function C.n | 1 | ControlFlowNode for IntegerLiteral |
|
||||
| 42 | ControlFlowNode for Attribute() | Method(Function C.n, C()) | 0 | ControlFlowNode for IntegerLiteral |
|
||||
| 45 | ControlFlowNode for open() | Builtin-function open | 0 | ControlFlowNode for Str |
|
||||
| 45 | ControlFlowNode for open() | Builtin-function open | 1 | ControlFlowNode for Str |
|
||||
| 51 | ControlFlowNode for foo() | Function foo | 0 | ControlFlowNode for IntegerLiteral |
|
||||
| 51 | ControlFlowNode for foo() | Function foo | 1 | ControlFlowNode for IntegerLiteral |
|
||||
| 51 | ControlFlowNode for foo() | Function foo | 2 | ControlFlowNode for IntegerLiteral |
|
||||
| 55 | ControlFlowNode for bar() | Function bar | 0 | ControlFlowNode for IntegerLiteral |
|
||||
@@ -0,0 +1,5 @@
|
||||
import python
|
||||
|
||||
from CallNode call, CallableValue callable, int i
|
||||
select call.getLocation().getStartLine(), call.toString(), callable.toString(), i,
|
||||
callable.getArgumentForCall(call, i).toString()
|
||||
@@ -0,0 +1,31 @@
|
||||
| 19 | ControlFlowNode for f() | Function f | arg0 | ControlFlowNode for w |
|
||||
| 19 | ControlFlowNode for f() | Function f | arg1 | ControlFlowNode for x |
|
||||
| 19 | ControlFlowNode for f() | Function f | arg2 | ControlFlowNode for y |
|
||||
| 21 | ControlFlowNode for f() | Function f | arg0 | ControlFlowNode for y |
|
||||
| 21 | ControlFlowNode for f() | Function f | arg1 | ControlFlowNode for w |
|
||||
| 21 | ControlFlowNode for f() | Function f | arg2 | ControlFlowNode for z |
|
||||
| 23 | ControlFlowNode for Attribute() | Function f | arg1 | ControlFlowNode for w |
|
||||
| 23 | ControlFlowNode for Attribute() | Function f | arg2 | ControlFlowNode for z |
|
||||
| 23 | ControlFlowNode for Attribute() | Function f | self | ControlFlowNode for c |
|
||||
| 23 | ControlFlowNode for Attribute() | Method(Function f, C()) | arg1 | ControlFlowNode for w |
|
||||
| 23 | ControlFlowNode for Attribute() | Method(Function f, C()) | arg2 | ControlFlowNode for z |
|
||||
| 24 | ControlFlowNode for Attribute() | Function C.n | arg1 | ControlFlowNode for x |
|
||||
| 24 | ControlFlowNode for Attribute() | Function C.n | self | ControlFlowNode for c |
|
||||
| 24 | ControlFlowNode for Attribute() | Method(Function C.n, C()) | arg1 | ControlFlowNode for x |
|
||||
| 25 | ControlFlowNode for Attribute() | Function C.n | arg1 | ControlFlowNode for z |
|
||||
| 25 | ControlFlowNode for Attribute() | Function C.n | self | ControlFlowNode for y |
|
||||
| 33 | ControlFlowNode for Attribute() | Function D.foo | arg | ControlFlowNode for IntegerLiteral |
|
||||
| 34 | ControlFlowNode for Attribute() | Function D.foo | arg | ControlFlowNode for IntegerLiteral |
|
||||
| 37 | ControlFlowNode for Attribute() | builtin method append | self | ControlFlowNode for l |
|
||||
| 40 | ControlFlowNode for f() | Function f | arg0 | ControlFlowNode for IntegerLiteral |
|
||||
| 40 | ControlFlowNode for f() | Function f | arg1 | ControlFlowNode for IntegerLiteral |
|
||||
| 40 | ControlFlowNode for f() | Function f | arg2 | ControlFlowNode for IntegerLiteral |
|
||||
| 42 | ControlFlowNode for Attribute() | Function C.n | arg1 | ControlFlowNode for IntegerLiteral |
|
||||
| 42 | ControlFlowNode for Attribute() | Function C.n | self | ControlFlowNode for c |
|
||||
| 42 | ControlFlowNode for Attribute() | Method(Function C.n, C()) | arg1 | ControlFlowNode for IntegerLiteral |
|
||||
| 46 | ControlFlowNode for open() | Builtin-function open | file | ControlFlowNode for Str |
|
||||
| 46 | ControlFlowNode for open() | Builtin-function open | mode | ControlFlowNode for Str |
|
||||
| 51 | ControlFlowNode for foo() | Function foo | a | ControlFlowNode for IntegerLiteral |
|
||||
| 55 | ControlFlowNode for bar() | Function bar | a | ControlFlowNode for IntegerLiteral |
|
||||
| 55 | ControlFlowNode for bar() | Function bar | b | ControlFlowNode for IntegerLiteral |
|
||||
| 55 | ControlFlowNode for bar() | Function bar | c | ControlFlowNode for IntegerLiteral |
|
||||
@@ -0,0 +1,5 @@
|
||||
import python
|
||||
|
||||
from CallNode call, CallableValue callable, string name
|
||||
select call.getLocation().getStartLine(), call.toString(), callable.toString(), name,
|
||||
callable.getNamedArgumentForCall(call, name).toString()
|
||||
@@ -0,0 +1,12 @@
|
||||
| Function C.n | 0 | ControlFlowNode for self |
|
||||
| Function C.n | 1 | ControlFlowNode for arg1 |
|
||||
| Function D.foo | 0 | ControlFlowNode for arg |
|
||||
| Function bar | 0 | ControlFlowNode for a |
|
||||
| Function f | 0 | ControlFlowNode for arg0 |
|
||||
| Function f | 1 | ControlFlowNode for arg1 |
|
||||
| Function f | 2 | ControlFlowNode for arg2 |
|
||||
| Function foo | 0 | ControlFlowNode for a |
|
||||
| Method(Function C.n, C()) | 0 | ControlFlowNode for arg1 |
|
||||
| Method(Function C.n, class C) | 0 | ControlFlowNode for arg1 |
|
||||
| Method(Function f, C()) | 0 | ControlFlowNode for arg1 |
|
||||
| Method(Function f, C()) | 1 | ControlFlowNode for arg2 |
|
||||
@@ -0,0 +1,4 @@
|
||||
import python
|
||||
|
||||
from CallableValue callable, int i
|
||||
select callable.toString(), i, callable.getParameter(i).toString()
|
||||
@@ -0,0 +1,12 @@
|
||||
| Function C.n | arg1 | ControlFlowNode for arg1 |
|
||||
| Function C.n | self | ControlFlowNode for self |
|
||||
| Function D.foo | arg | ControlFlowNode for arg |
|
||||
| Function bar | a | ControlFlowNode for a |
|
||||
| Function f | arg0 | ControlFlowNode for arg0 |
|
||||
| Function f | arg1 | ControlFlowNode for arg1 |
|
||||
| Function f | arg2 | ControlFlowNode for arg2 |
|
||||
| Function foo | a | ControlFlowNode for a |
|
||||
| Method(Function C.n, C()) | arg1 | ControlFlowNode for arg1 |
|
||||
| Method(Function C.n, class C) | arg1 | ControlFlowNode for arg1 |
|
||||
| Method(Function f, C()) | arg1 | ControlFlowNode for arg1 |
|
||||
| Method(Function f, C()) | arg2 | ControlFlowNode for arg2 |
|
||||
@@ -0,0 +1,4 @@
|
||||
import python
|
||||
|
||||
from CallableValue callable, string name
|
||||
select callable.toString(), name, callable.getParameterByName(name).toString()
|
||||
@@ -32,3 +32,24 @@ class D(object):
|
||||
|
||||
D.foo(1)
|
||||
D().foo(2)
|
||||
|
||||
l = [1,2,3]
|
||||
l.append(4)
|
||||
len(l)
|
||||
|
||||
f(arg0=0, arg1=1, arg2=2)
|
||||
c = C()
|
||||
c.n(arg1=1)
|
||||
|
||||
# positional/keyword arguments for a builtin function
|
||||
open("foo.txt", "rb") # TODO: Not handled by getNamedArgumentForCall
|
||||
open(file="foo.txt", mode="rb")
|
||||
|
||||
# Testing how arguments to *args and **kwargs are handled
|
||||
def foo(a, *args):
|
||||
pass
|
||||
foo(1, 2, 3)
|
||||
|
||||
def bar(a, **kwargs):
|
||||
pass
|
||||
bar(a=1, b=2, c=3)
|
||||
|
||||
Reference in New Issue
Block a user