There are quite a lot of questions here, so we sat down at ICSE to try out some of these.
To look for redirecting calls, we want to find methods
m and
n such that
m calls
n, m does not call other methods declared in the same class as
n, and no other method in
m's class call
n . In .QL, that reads:
predicate redirect(Method m, Method n) {
// m makes call to n
m.calls(n)
and
// m makes no other calls to class of n
not exists(Method k | k.getDeclaringType() = n.getDeclaringType()
and m.calls(k) and k!=n)
and
not exists(Method l | l.getDeclaringType() = m.getDeclaringType()
and l.calls(n) and l!=m)
}
Using this predicate, we can look for occurrences of the wrapper pattern by finding a class
wrapper and another type
wrappee such that the
wrapper class redirects more than 4 methods to the
wrappee:
from Class wrapper, RefType wrappee
where wrapper.getPackage().getName().matches("org.jhotdraw%")
and
wrappee.getPackage().getName().matches("org.jhotdraw%")
and
wrapper != wrappee
and
count(Method m, Method n |
m.getDeclaringType() = wrapper and
n.getDeclaringType() = wrappee and
redirect(m,n)) > 4
select wrapper, wrappee
Thanks, Marius, for the interesting examples!