Improve join ordering

This commit is contained in:
Chris Smowton
2023-02-08 16:43:27 +00:00
parent d5f7ef08b7
commit 62d10f91d8
3 changed files with 37 additions and 15 deletions

View File

@@ -397,14 +397,21 @@ private predicate potentialInterfaceImplementationWithSignature(string sig, RefT
not t.isAbstract()
}
pragma[nomagic]
private predicate implementsInterfaceMethod(SrcMethod impl, SrcMethod m) {
exists(RefType t, Interface i, Method minst, Method implinst |
m = minst.getSourceDeclaration() and
pragma[noinline]
private predicate isInterfaceSourceImplementation(Method minst, RefType t) {
exists(Interface i |
i = minst.getDeclaringType() and
t.extendsOrImplements+(i) and
t.isSourceDeclaration() and
t.isSourceDeclaration()
)
}
pragma[nomagic]
private predicate implementsInterfaceMethod(SrcMethod impl, SrcMethod m) {
exists(RefType t, Method minst, Method implinst |
isInterfaceSourceImplementation(minst, t) and
potentialInterfaceImplementationWithSignature(minst.getSignature(), t, implinst) and
m = minst.getSourceDeclaration() and
impl = implinst.getSourceDeclaration()
)
}
@@ -542,7 +549,7 @@ class Method extends Callable, @method {
/** A method that is the same as its source declaration. */
class SrcMethod extends Method {
SrcMethod() { methods(_, _, _, _, _, this) }
SrcMethod() { methods(this, _, _, _, _, this) }
/**
* All the methods that could possibly be called when this method

View File

@@ -681,9 +681,14 @@ private predicate unionTypeFlow0(TypeFlowNode n, RefType t, boolean exact) {
private predicate unionTypeFlow(TypeFlowNode n, RefType t, boolean exact) {
unionTypeFlow0(n, t, exact) and
// filter impossible union parts:
if exact = true
then t.getErasure().(RefType).getASourceSupertype*() = getTypeBound(n).getErasure()
else haveIntersection(getTypeBound(n), t)
exists(RefType tErased, RefType boundErased |
pragma[only_bind_into](tErased) = t.getErasure() and
pragma[only_bind_into](boundErased) = getTypeBound(n).getErasure()
|
if exact = true
then tErased.getASourceSupertype*() = boundErased
else erasedHaveIntersection(tErased, boundErased)
)
}
/**

View File

@@ -22,6 +22,17 @@ module MkUnification<unificationTarget/1 targetLeft, unificationTarget/1 targetR
targetRight(t2) and t2.getGenericType() = g
}
pragma[noinline]
private predicate unificationTargetsWithCommonSourceDecl(
ParameterizedType pt1, ParameterizedType pt2
) {
exists(RefType commonSourceDecl |
unificationTargets(pt1, pt2) and
pragma[only_bind_out](pt1).getSourceDeclaration() = pragma[only_bind_out](commonSourceDecl) and
pragma[only_bind_out](pt2).getSourceDeclaration() = commonSourceDecl
)
}
private predicate unificationTargets(Type t1, Type t2) {
exists(GenericType g | unificationTargetLeft(t1, g) and unificationTargetRight(t2, g))
or
@@ -32,10 +43,9 @@ module MkUnification<unificationTarget/1 targetLeft, unificationTarget/1 targetR
)
or
exists(ParameterizedType pt1, ParameterizedType pt2, int pos |
unificationTargets(pt1, pt2) and
not pt1.getSourceDeclaration() != pt2.getSourceDeclaration() and
t1 = pt1.getTypeArgument(pos) and
t2 = pt2.getTypeArgument(pos)
unificationTargetsWithCommonSourceDecl(pt1, pt2) and
t1 = pt1.getTypeArgument(pragma[only_bind_into](pos)) and
t2 = pt2.getTypeArgument(pragma[only_bind_into](pos))
)
}
@@ -44,8 +54,8 @@ module MkUnification<unificationTarget/1 targetLeft, unificationTarget/1 targetR
ParameterizedType t1, ParameterizedType t2, int pos, RefType arg1, RefType arg2
) {
unificationTargets(t1, t2) and
arg1 = t1.getTypeArgument(pos) and
arg2 = t2.getTypeArgument(pos)
arg1 = t1.getTypeArgument(pragma[only_bind_into](pos)) and
arg2 = t2.getTypeArgument(pragma[only_bind_into](pos))
}
private RefType getUpperBound(RefType t) {