Python: Fix bad join in method call order computation

This join had badness 1127 on the project FiacreT/M-moire, producing ~31
million tuples in order to end up with only ~27k tuples later in the
pipeline. With the fix, we reduce this by roughly the full 31 million
(the new materialised helper predicate accounting for roughly 130k
tuples on its own).

Co-authored-by: Mathias Vorreiter Pedersen <mathiasvp@github.com>
This commit is contained in:
Taus
2026-03-09 12:58:08 +00:00
parent be9c1d074f
commit c5360ba46c

View File

@@ -152,11 +152,7 @@ predicate missingCallToSuperclassMethod(Class base, Function shouldCall, string
*/
predicate missingCallToSuperclassMethodRestricted(Class base, Function shouldCall, string name) {
missingCallToSuperclassMethod(base, shouldCall, name) and
not exists(Class superBase |
// Alert only on the highest base class that has the issue
superBase = getADirectSuperclass+(base) and
missingCallToSuperclassMethod(superBase, shouldCall, name)
) and
not superclassAlsoMissesCall(base, shouldCall, name) and
not exists(Function subShouldCall |
// Mention in the alert only the lowest method we're missing the call to
subShouldCall.getScope() = getADirectSubclass+(shouldCall.getScope()) and
@@ -164,6 +160,15 @@ predicate missingCallToSuperclassMethodRestricted(Class base, Function shouldCal
)
}
/**
* Holds if a strict superclass of `base` is also missing a call to `shouldCall` named `name`,
* indicating that `base` is not the highest class in the hierarchy with this issue.
*/
pragma[nomagic]
private predicate superclassAlsoMissesCall(Class base, Function shouldCall, string name) {
missingCallToSuperclassMethod(getADirectSuperclass+(base), shouldCall, name)
}
/**
* If `base` contains a `super()` call, gets a method in the inheritance hierarchy of `name` in the MRO of `base`
* that does not contain a `super()` call, but would call `shouldCall` if it did, which does not otherwise get called