Python: Magic subscript and format

(this in preparation for addressing reviews)
This commit is contained in:
Rasmus Lerchedahl Petersen
2020-08-18 12:56:15 +02:00
parent ca7c045d31
commit bbf925fcc4
2 changed files with 63 additions and 6 deletions

View File

@@ -22,8 +22,10 @@ module MagicMethod {
/** Gets the controlflow node that would be passed as the specified argument. */
abstract ControlFlowNode getArg(int n);
/** Gets the control flow node corresponding to the instance
* that would define the magic method. */
/**
* Gets the control flow node corresponding to the instance
* that would define the magic method.
*/
ControlFlowNode getSelf() { result = this.getArg(0) }
}
@@ -47,11 +49,9 @@ module MagicMethod {
class MagicBinOp extends MagicMethod::Potential, BinaryExprNode {
Operator operator;
MagicBinOp() { this.getOp() = operator}
MagicBinOp() { this.getOp() = operator }
override string getMagicMethodName() {
result = operator.getSpecialMethodName()
}
override string getMagicMethodName() { result = operator.getSpecialMethodName() }
override ControlFlowNode getArg(int n) {
n = 0 and result = this.getLeft()
@@ -59,3 +59,53 @@ class MagicBinOp extends MagicMethod::Potential, BinaryExprNode {
n = 1 and result = this.getRight()
}
}
/** A subscript expression node that might correspond to a magic method call. */
abstract class MagicSubscript extends MagicMethod::Potential, SubscriptNode {
override ControlFlowNode getArg(int n) {
n = 0 and result = this.getObject()
or
n = 1 and result = this.getIndex()
}
}
/** A subscript expression node that might correspond to a call to __getitem__. */
class MagicGetItem extends MagicSubscript {
MagicGetItem() { this.isLoad() }
override string getMagicMethodName() { result = "__getitem__" }
}
/** A subscript expression node that might correspond to a call to __setitem__. */
class MagicSetItem extends MagicSubscript {
MagicSetItem() { this.isStore() }
override string getMagicMethodName() { result = "__setitem__" }
override ControlFlowNode getArg(int n) {
n = 0 and result = this.getObject()
or
n = 1 and result = this.getIndex()
or
n = 2 and result = this.getValueNode()
}
private ControlFlowNode getValueNode() {
exists(AssignStmt a |
a.getATarget() = this.getNode() and
result.getNode() = a.getValue()
)
or
exists(AugAssign a |
a.getTarget() = this.getNode() and
result.getNode() = a.getValue()
)
}
}
/** A subscript expression node that might correspond to a call to __delitem__. */
class MagicDelItem extends MagicSubscript {
MagicDelItem() { this.isDelete() }
override string getMagicMethodName() { result = "__delitem__" }
}