Exclude methods in tests in framework mode
This excludes methods defined in tests in framework mode, significantly
cutting down on the number of methods shown that would need to be
modeled.
For C#, this just checks that the file is not a test file, as defined
by the QL library.
For Java, this makes a copy of the internal
[`ModelExclusions.qll`](249f9f863d/java/ql/lib/semmle/code/java/dataflow/internal/ModelExclusions.qll)
file to avoid the use of internal modules. This module will tell us
whether a method is "interesting" to model or not. Not all of the checks
in this module need to happen for framework mode, but these checks might
be useful for telling a user whether a method is interesting to model
in application mode.
This commit is contained in:
@@ -39,10 +39,11 @@ select usage, apiName, supported.toString(), "supported", api.getFile().getBaseN
|
||||
|
||||
private import csharp
|
||||
private import dotnet
|
||||
private import semmle.code.csharp.frameworks.Test
|
||||
private import AutomodelVsCode
|
||||
|
||||
class PublicMethod extends CallableMethod {
|
||||
PublicMethod() { this.fromSource() }
|
||||
PublicMethod() { this.fromSource() and not this.getFile() instanceof TestFile }
|
||||
}
|
||||
|
||||
from PublicMethod publicMethod, string apiName, boolean supported
|
||||
|
||||
@@ -39,9 +39,7 @@ select usage, apiName, supported.toString(), "supported", externalApi.jarContain
|
||||
import java
|
||||
import AutomodelVsCode
|
||||
|
||||
class PublicMethodFromSource extends CallableMethod {
|
||||
PublicMethodFromSource() { this.isPublic() and this.fromSource() }
|
||||
}
|
||||
class PublicMethodFromSource extends CallableMethod, ModelApi { }
|
||||
|
||||
from PublicMethodFromSource publicMethod, string apiName, boolean supported
|
||||
where
|
||||
@@ -81,8 +79,8 @@ class CallableMethod extends Method {
|
||||
*/
|
||||
string getApiName() {
|
||||
result =
|
||||
this.getDeclaringType().getPackage() + "." + this.getDeclaringType().nestedName() +
|
||||
"#" + this.getName() + paramsString(this)
|
||||
this.getDeclaringType().getPackage() + "." + this.getDeclaringType().nestedName() + "#" +
|
||||
this.getName() + paramsString(this)
|
||||
}
|
||||
|
||||
private string getJarName() {
|
||||
@@ -148,6 +146,82 @@ boolean isSupported(CallableMethod method) {
|
||||
or
|
||||
not method.isSupported() and result = false
|
||||
}
|
||||
|
||||
// The below is a copy of https://github.com/github/codeql/blob/249f9f863db1e94e3c46ca85b49fb0ec32f8ca92/java/ql/lib/semmle/code/java/dataflow/internal/ModelExclusions.qll
|
||||
// to avoid the use of internal modules.
|
||||
/** Holds if the given package \`p\` is a test package. */
|
||||
pragma[nomagic]
|
||||
private predicate isTestPackage(Package p) {
|
||||
p.getName()
|
||||
.matches([
|
||||
"org.junit%", "junit.%", "org.mockito%", "org.assertj%",
|
||||
"com.github.tomakehurst.wiremock%", "org.hamcrest%", "org.springframework.test.%",
|
||||
"org.springframework.mock.%", "org.springframework.boot.test.%", "reactor.test%",
|
||||
"org.xmlunit%", "org.testcontainers.%", "org.opentest4j%", "org.mockserver%",
|
||||
"org.powermock%", "org.skyscreamer.jsonassert%", "org.rnorth.visibleassertions",
|
||||
"org.openqa.selenium%", "com.gargoylesoftware.htmlunit%", "org.jboss.arquillian.testng%",
|
||||
"org.testng%"
|
||||
])
|
||||
}
|
||||
|
||||
/**
|
||||
* A test library.
|
||||
*/
|
||||
class TestLibrary extends RefType {
|
||||
TestLibrary() { isTestPackage(this.getPackage()) }
|
||||
}
|
||||
|
||||
/** Holds if the given file is a test file. */
|
||||
private predicate isInTestFile(File file) {
|
||||
file.getAbsolutePath().matches(["%/test/%", "%/guava-tests/%", "%/guava-testlib/%"]) and
|
||||
not file.getAbsolutePath().matches("%/ql/test/%") // allows our test cases to work
|
||||
}
|
||||
|
||||
/** Holds if the given compilation unit's package is a JDK internal. */
|
||||
private predicate isJdkInternal(CompilationUnit cu) {
|
||||
cu.getPackage().getName().matches("org.graalvm%") or
|
||||
cu.getPackage().getName().matches("com.sun%") or
|
||||
cu.getPackage().getName().matches("sun%") or
|
||||
cu.getPackage().getName().matches("jdk%") or
|
||||
cu.getPackage().getName().matches("java2d%") or
|
||||
cu.getPackage().getName().matches("build.tools%") or
|
||||
cu.getPackage().getName().matches("propertiesparser%") or
|
||||
cu.getPackage().getName().matches("org.jcp%") or
|
||||
cu.getPackage().getName().matches("org.w3c%") or
|
||||
cu.getPackage().getName().matches("org.ietf.jgss%") or
|
||||
cu.getPackage().getName().matches("org.xml.sax%") or
|
||||
cu.getPackage().getName().matches("com.oracle%") or
|
||||
cu.getPackage().getName().matches("org.omg%") or
|
||||
cu.getPackage().getName().matches("org.relaxng%") or
|
||||
cu.getPackage().getName() = "compileproperties" or
|
||||
cu.getPackage().getName() = "transparentruler" or
|
||||
cu.getPackage().getName() = "genstubs" or
|
||||
cu.getPackage().getName() = "netscape.javascript" or
|
||||
cu.getPackage().getName() = ""
|
||||
}
|
||||
|
||||
/** Holds if the given callable is not worth modeling. */
|
||||
predicate isUninterestingForModels(Callable c) {
|
||||
isInTestFile(c.getCompilationUnit().getFile()) or
|
||||
isJdkInternal(c.getCompilationUnit()) or
|
||||
c instanceof MainMethod or
|
||||
c instanceof StaticInitializer or
|
||||
exists(FunctionalExpr funcExpr | c = funcExpr.asMethod()) or
|
||||
c.getDeclaringType() instanceof TestLibrary or
|
||||
c.(Constructor).isParameterless()
|
||||
}
|
||||
|
||||
/**
|
||||
* A class that represents all callables for which we might be
|
||||
* interested in having a MaD model.
|
||||
*/
|
||||
class ModelApi extends SrcCallable {
|
||||
ModelApi() {
|
||||
this.fromSource() and
|
||||
this.isEffectivelyPublic() and
|
||||
not isUninterestingForModels(this)
|
||||
}
|
||||
}
|
||||
`,
|
||||
},
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user