Files
codeql/java/ql/src/Compatibility/JDK9/JdkInternalAccess.ql
Anders Schack-Mulligen ae44b90456 Java: Normalize parentheses.
2018-11-28 15:01:25 +01:00

134 lines
3.7 KiB
Plaintext

/**
* @name Access to unsupported JDK-internal API
* @description Use of unsupported JDK-internal APIs may cause compatibility issues
* when upgrading to newer versions of Java, in particular Java 9.
* @kind problem
* @problem.severity recommendation
* @precision high
* @id java/jdk-internal-api-access
* @tags maintainability
*/
import java
import JdkInternals
import JdkInternalsReplacement
predicate importedType(Import i, RefType t) {
i.(ImportType).getImportedType() = t or
i.(ImportStaticTypeMember).getTypeHoldingImport() = t or
i.(ImportStaticOnDemand).getTypeHoldingImport() = t or
i.(ImportOnDemandFromType).getTypeHoldingImport() = t
}
predicate importedPackage(Import i, Package p) {
i.(ImportOnDemandFromPackage).getPackageHoldingImport() = p
}
predicate typeReplacement(RefType t, string repl) {
exists(string old | jdkInternalReplacement(old, repl) | t.getQualifiedName() = old)
}
predicate packageReplacementForType(RefType t, string repl) {
exists(string old, string pkgName |
jdkInternalReplacement(old, repl) and t.getPackage().getName() = pkgName
|
pkgName = old or
pkgName.prefix(old.length() + 1) = old + "."
)
}
predicate packageReplacement(Package p, string repl) {
exists(string old | jdkInternalReplacement(old, repl) |
p.getName() = old or
p.getName().prefix(old.length() + 1) = old + "."
)
}
predicate replacement(RefType t, string repl) {
typeReplacement(t, repl)
or
not typeReplacement(t, _) and packageReplacementForType(t, repl)
}
abstract class JdkInternalAccess extends Element {
abstract string getAccessedApi();
abstract string getReplacement();
}
class JdkInternalTypeAccess extends JdkInternalAccess, TypeAccess {
JdkInternalTypeAccess() { jdkInternalApi(this.getType().(RefType).getPackage().getName()) }
override string getAccessedApi() { result = getType().(RefType).getQualifiedName() }
override string getReplacement() {
exists(RefType t | this.getType() = t |
(
replacement(t, result)
or
not replacement(t, _) and result = "unknown"
)
)
}
}
class JdkInternalImport extends JdkInternalAccess, Import {
JdkInternalImport() {
exists(RefType t | importedType(this, t) | jdkInternalApi(t.getPackage().getName()))
or
exists(Package p | importedPackage(this, p) | jdkInternalApi(p.getName()))
}
override string getAccessedApi() {
exists(RefType t | result = t.getQualifiedName() | importedType(this, t))
or
exists(Package p | result = p.getName() | importedPackage(this, p))
}
override string getReplacement() {
exists(RefType t |
importedType(this, t) and
(
replacement(t, result)
or
not replacement(t, _) and result = "unknown"
)
)
or
exists(Package p |
importedPackage(this, p) and
(
packageReplacement(p, result)
or
not packageReplacement(p, _) and result = "unknown"
)
)
}
}
predicate jdkPackage(Package p) {
exists(string pkgName |
p.getName() = pkgName or
p.getName().prefix(pkgName.length() + 1) = pkgName + "."
|
pkgName = "com.sun" or
pkgName = "sun" or
pkgName = "java" or
pkgName = "javax" or
pkgName = "com.oracle.net" or
pkgName = "genstubs" or
pkgName = "jdk" or
pkgName = "build.tools" or
pkgName = "org.omg.CORBA" or
pkgName = "org.ietf.jgss"
)
}
from JdkInternalAccess ta, string repl, string msg
where
repl = ta.getReplacement() and
(if repl = "unknown" then msg = "" else msg = " (" + repl + ")") and
not jdkInternalApi(ta.getCompilationUnit().getPackage().getName()) and
not jdkPackage(ta.getCompilationUnit().getPackage())
select ta, "Access to unsupported JDK-internal API '" + ta.getAccessedApi() + "'." + msg