Java: add class and predicates to approximate an effectively public method

This commit is contained in:
Jami Cogswell
2023-04-14 16:22:40 -04:00
parent 1f861fda25
commit 2e76e12316

View File

@@ -340,6 +340,61 @@ class Callable extends StmtParent, Member, @callable {
}
}
/** A callable that is the same as its source declaration. */
class SrcCallable extends Callable {
SrcCallable() { this.isSourceDeclaration() }
/**
* Holds if the given type is public and not a nested type.
* If the given type is a nested type, holds if its enclosing type
* is also public.
*/
private predicate veryPublic(RefType t) {
t.isPublic() and
(
not t instanceof NestedType or
veryPublic(t.(NestedType).getEnclosingType())
)
}
/**
* Holds if this callable is effectively `public`, meaning that it can be
* called outside the codebase.
*/
predicate isEffectivelyPublic() {
exists(RefType t | t = this.getDeclaringType() |
this.isPublic() and veryPublic(t)
or
this.isProtected() and not t.isFinal() and veryPublic(t)
)
or
exists(SrcRefType tsub, Method m |
veryPublic(tsub) and
tsub.hasMethod(m, _) and
m.getSourceDeclaration() = this
|
this.isPublic()
or
this.isProtected() and not tsub.isFinal()
)
}
/**
* Holds if this callable is implicitly `public`, meaning that it can be
* called outside the codebase or if there exists a method that can be called
* outside the codebase and this callable is a possible implementation of that
* method.
*/
predicate isImplicitlyPublic() {
this.isEffectivelyPublic()
or
exists(SrcMethod m |
m.(SrcCallable).isEffectivelyPublic() and
m.getAPossibleImplementationOfSrcMethod() = this
)
}
}
/** Gets the erasure of `t1` if it is a raw type, or `t1` itself otherwise. */
private Type eraseRaw(Type t1) {
if t1 instanceof RawType then result = t1.getErasure() else result = t1