Merge pull request #4474 from tausbn/python-fix-tostring-divergence

Python: Fix divergence in tuple/subscripted type `toString`
This commit is contained in:
Rasmus Wriedt Larsen
2020-10-15 10:29:33 +02:00
committed by GitHub
4 changed files with 21 additions and 7 deletions

View File

@@ -311,7 +311,8 @@ class SubscriptedTypeInternal extends ObjectInternal, TSubscriptedType {
override string getName() { result = this.getGeneric().getName() }
override string toString() {
result = this.getGeneric().toString() + "[" + this.getSpecializer().toString() + "]"
result =
bounded_toString(this.getGeneric()) + "[" + bounded_toString(this.getSpecializer()) + "]"
}
override predicate introducedAt(ControlFlowNode node, PointsToContext context) {

View File

@@ -379,7 +379,8 @@ private predicate cls_descriptor(ClassObjectInternal cls, string name, ObjectInt
/** A class representing an instance of the `super` class */
class SuperInstance extends TSuperInstance, ObjectInternal {
override string toString() {
result = "super(" + this.getStartClass().toString() + ", " + this.getSelf().toString() + ")"
result =
"super(" + this.getStartClass().toString() + ", " + bounded_toString(this.getSelf()) + ")"
}
override boolean booleanValue() { result = true }

View File

@@ -515,7 +515,7 @@ class DecoratedFunction extends ObjectInternal, TDecoratedFunction {
override string getName() { result = this.decoratedObject().getName() }
override string toString() {
result = "Decorated " + this.decoratedObject().toString()
result = "Decorated " + bounded_toString(this.decoratedObject())
or
not exists(this.decoratedObject()) and result = "Decorated function"
}
@@ -592,3 +592,18 @@ pragma[nomagic]
predicate receiver_type(AttrNode attr, string name, ObjectInternal value, ClassObjectInternal cls) {
PointsToInternal::pointsTo(attr.getObject(name), _, value, _) and value.getClass() = cls
}
/**
* Returns a string representation of `obj`. Because some classes have (mutually) recursive
* `toString` implementations, this predicate acts as a stop for these classes, preventing an
* unbounded `toString` from being materialized.
*/
string bounded_toString(ObjectInternal obj) {
if
obj instanceof DecoratedFunction or
obj instanceof TupleObjectInternal or
obj instanceof SubscriptedTypeInternal or
obj instanceof SuperInstance
then result = "(...)"
else result = obj.toString()
}

View File

@@ -54,10 +54,7 @@ abstract class TupleObjectInternal extends SequenceObjectInternal {
}
private string item(int n) {
exists(ObjectInternal item | item = this.getItem(n) |
// To avoid infinite recursion, nested tuples are replaced with the string "...".
if item instanceof TupleObjectInternal then result = "(...)" else result = item.toString()
)
result = bounded_toString(this.getItem(n))
or
n in [0 .. this.length() - 1] and
not exists(this.getItem(n)) and