Java: add negative numbers

This commit is contained in:
Jami Cogswell
2022-12-07 17:17:35 -05:00
parent b82f9b1911
commit aa7e6d7811
7 changed files with 179 additions and 38 deletions

View File

@@ -9,6 +9,7 @@
//import java // not needed I guess
import semmle.code.java.dataflow.FlowSummary // for SummarizedCallable
import utils.modelgenerator.internal.CaptureModels // for DataFlowTargetApi
import semmle.code.java.dataflow.internal.FlowSummaryImpl as FlowSummaryImpl // for NegativeSummarizedCallable
// ! improve QLDoc?
/**
@@ -19,7 +20,10 @@ import utils.modelgenerator.internal.CaptureModels // for DataFlowTargetApi
class MadModeledCallable extends SummarizedCallableBase {
// ! better name for this class?
MadModeledCallable() {
this instanceof SummarizedCallable and
(
this instanceof SummarizedCallable or
this instanceof FlowSummaryImpl::Public::NegativeSummarizedCallable
) and
exists(DataFlowTargetApi dataFlowTargApi |
this.asCallable() = dataFlowTargApi and
not exists(FunctionalExpr funcExpr | dataFlowTargApi = funcExpr.asMethod()) // ! remove this if DataFlowTargetApi itself is adjusted to exclude FunctionalExpr (see static-team slack thread)
@@ -28,29 +32,48 @@ class MadModeledCallable extends SummarizedCallableBase {
}
// ! move to other file
// ! separate this into pos and neg predicates instead of using `posOrNeg` flag?
/**
* Returns the number of APIs with MaD models
* for a given package and provenance.
*/
float getNumMadModels(string package, string provenance) {
float getNumMadModels(string package, string provenance, string posOrNeg) {
exists(MadModeledCallable mc |
package = mc.asCallable().getDeclaringType().getPackage().toString() and
provenance in ["generated", "manual", "both"]
provenance in ["generated", "manual", "both"] and
posOrNeg in ["positive", "negative"]
|
result =
count(MadModeledCallable c |
package = c.asCallable().getDeclaringType().getPackage().toString() and
(
c.(SummarizedCallable).isAutoGenerated() and // generated and NOT manual = "auto-only"
provenance = "generated"
or
c.(SummarizedCallable).isManuallyGenerated() and // manual and NOT generated = "manual-only"
provenance = "manual"
or
c.(SummarizedCallable).isBothAutoAndManuallyGenerated() and // BOTH generated and manual = "both"
provenance = "both"
if posOrNeg = "positive"
then
result =
count(MadModeledCallable c |
package = c.asCallable().getDeclaringType().getPackage().toString() and
(
c.(SummarizedCallable).isAutoGenerated() and // generated and NOT manual = "auto-only"
provenance = "generated"
or
c.(SummarizedCallable).isManuallyGenerated() and // manual and NOT generated = "manual-only"
provenance = "manual"
or
c.(SummarizedCallable).isBothAutoAndManuallyGenerated() and // BOTH generated and manual = "both"
provenance = "both"
)
)
else
result =
count(MadModeledCallable c |
package = c.asCallable().getDeclaringType().getPackage().toString() and
(
c.(FlowSummaryImpl::Public::NegativeSummarizedCallable).isAutoGenerated() and // generated and NOT manual = "auto-only"
provenance = "generated"
or
c.(FlowSummaryImpl::Public::NegativeSummarizedCallable).isManuallyGenerated() and // manual and NOT generated = "manual-only"
provenance = "manual"
or
c.(FlowSummaryImpl::Public::NegativeSummarizedCallable).isBothAutoAndManuallyGenerated() and // BOTH generated and manual = "both"
provenance = "both"
)
)
)
)
}
@@ -87,14 +110,18 @@ float getNumApisWithoutMadModel(string package) {
*/
from
string package, float generated, float manual, float both, float notModeled, float all,
float metric1, float metric2
string package, float generatedPos, float manualPos, float bothPos, float generatedNeg,
float manualNeg, float bothNeg, float notModeled, float all, float metric1, float metric2
where
generated = getNumMadModels(package, "generated") and
manual = getNumMadModels(package, "manual") and
both = getNumMadModels(package, "both") and
notModeled = getNumApisWithoutMadModel(package) and // ! better name for this?, "none" is a reserved keyword :(
all = generated + manual + both + notModeled and
metric1 = (both / (both + manual)) and
metric2 = (generated + both + manual) / all
select package, generated, manual, both, notModeled, all, metric1, metric2 order by package
generatedPos = getNumMadModels(package, "generated", "positive") and
manualPos = getNumMadModels(package, "manual", "positive") and
bothPos = getNumMadModels(package, "both", "positive") and
generatedNeg = getNumMadModels(package, "generated", "negative") and
manualNeg = getNumMadModels(package, "manual", "negative") and
bothNeg = getNumMadModels(package, "both", "negative") and
notModeled = getNumApisWithoutMadModel(package) and
all = generatedPos + manualPos + bothPos + generatedNeg + manualNeg + bothNeg + notModeled and
metric1 = (bothPos / (bothPos + manualPos)) and // ! I believe this metric was intended to be only on the positive ones?
metric2 = (generatedPos + generatedNeg + bothPos + bothNeg + manualPos + manualNeg) / all
select package, generatedPos, manualPos, bothPos, generatedNeg, manualNeg, bothNeg, notModeled, all,
metric1, metric2 order by package