Java: Basic support for pass-through barrier models.

This commit is contained in:
Anders Schack-Mulligen
2025-12-08 14:53:09 +01:00
parent e13bb0f866
commit d24b0ff596
5 changed files with 104 additions and 6 deletions

View File

@@ -174,6 +174,15 @@ predicate sinkModel(
) )
} }
/** Holds if a barrier model exists for the given parameters. */
predicate barrierModel(
string package, string type, boolean subtypes, string name, string signature, string ext,
string output, string kind, string provenance, QlBuiltins::ExtensionId madId
) {
Extensions::barrierModel(package, type, subtypes, name, signature, ext, output, kind, provenance,
madId)
}
/** Holds if a summary model exists for the given parameters. */ /** Holds if a summary model exists for the given parameters. */
predicate summaryModel( predicate summaryModel(
string package, string type, boolean subtypes, string name, string signature, string ext, string package, string type, boolean subtypes, string name, string signature, string ext,
@@ -234,6 +243,7 @@ predicate interpretModelForTest(QlBuiltins::ExtensionId madId, string model) {
"Summary: " + package + "; " + type + "; " + subtypes + "; " + name + "; " + signature + "; " + "Summary: " + package + "; " + type + "; " + subtypes + "; " + name + "; " + signature + "; " +
ext + "; " + input + "; " + output + "; " + kind + "; " + provenance ext + "; " + input + "; " + output + "; " + kind + "; " + provenance
) )
//TODO: possibly barrier models?
} }
/** Holds if a neutral model exists for the given parameters. */ /** Holds if a neutral model exists for the given parameters. */
@@ -292,6 +302,7 @@ predicate modelCoverage(string package, int pkgs, string kind, string part, int
summaryModel(subpkg, type, subtypes, name, signature, ext, input, output, kind, provenance, summaryModel(subpkg, type, subtypes, name, signature, ext, input, output, kind, provenance,
_) _)
) )
// TODO: possibly barrier models?
) )
} }
@@ -303,7 +314,8 @@ module ModelValidation {
summaryModel(_, _, _, _, _, _, path, _, _, _, _) or summaryModel(_, _, _, _, _, _, path, _, _, _, _) or
summaryModel(_, _, _, _, _, _, _, path, _, _, _) or summaryModel(_, _, _, _, _, _, _, path, _, _, _) or
sinkModel(_, _, _, _, _, _, path, _, _, _) or sinkModel(_, _, _, _, _, _, path, _, _, _) or
sourceModel(_, _, _, _, _, _, path, _, _, _) sourceModel(_, _, _, _, _, _, path, _, _, _) or
barrierModel(_, _, _, _, _, _, path, _, _, _)
} }
private module MkAccessPath = AccessPathSyntax::AccessPath<getRelevantAccessPath/1>; private module MkAccessPath = AccessPathSyntax::AccessPath<getRelevantAccessPath/1>;
@@ -338,6 +350,8 @@ module ModelValidation {
exists(string pred, AccessPath output, AccessPathToken part | exists(string pred, AccessPath output, AccessPathToken part |
sourceModel(_, _, _, _, _, _, output, _, _, _) and pred = "source" sourceModel(_, _, _, _, _, _, output, _, _, _) and pred = "source"
or or
barrierModel(_, _, _, _, _, _, output, _, _, _) and pred = "barrier"
or
summaryModel(_, _, _, _, _, _, _, output, _, _, _) and pred = "summary" summaryModel(_, _, _, _, _, _, _, output, _, _, _) and pred = "summary"
| |
( (
@@ -355,7 +369,11 @@ module ModelValidation {
private module KindValConfig implements SharedModelVal::KindValidationConfigSig { private module KindValConfig implements SharedModelVal::KindValidationConfigSig {
predicate summaryKind(string kind) { summaryModel(_, _, _, _, _, _, _, _, kind, _, _) } predicate summaryKind(string kind) { summaryModel(_, _, _, _, _, _, _, _, kind, _, _) }
predicate sinkKind(string kind) { sinkModel(_, _, _, _, _, _, _, kind, _, _) } predicate sinkKind(string kind) {
sinkModel(_, _, _, _, _, _, _, kind, _, _)
or
barrierModel(_, _, _, _, _, _, _, kind, _, _)
}
predicate sourceKind(string kind) { sourceModel(_, _, _, _, _, _, _, kind, _, _) } predicate sourceKind(string kind) { sourceModel(_, _, _, _, _, _, _, kind, _, _) }
@@ -373,6 +391,8 @@ module ModelValidation {
or or
sinkModel(package, type, _, name, signature, ext, _, _, provenance, _) and pred = "sink" sinkModel(package, type, _, name, signature, ext, _, _, provenance, _) and pred = "sink"
or or
barrierModel(package, type, _, name, signature, ext, _, _, provenance, _) and pred = "barrier"
or
summaryModel(package, type, _, name, signature, ext, _, _, _, provenance, _) and summaryModel(package, type, _, name, signature, ext, _, _, _, provenance, _) and
pred = "summary" pred = "summary"
or or
@@ -418,6 +438,8 @@ private predicate elementSpec(
or or
sinkModel(package, type, subtypes, name, signature, ext, _, _, _, _) sinkModel(package, type, subtypes, name, signature, ext, _, _, _, _)
or or
barrierModel(package, type, subtypes, name, signature, ext, _, _, _, _)
or
summaryModel(package, type, subtypes, name, signature, ext, _, _, _, _, _) summaryModel(package, type, subtypes, name, signature, ext, _, _, _, _, _)
or or
neutralModel(package, type, name, signature, _, _) and ext = "" and subtypes = true neutralModel(package, type, name, signature, _, _) and ext = "" and subtypes = true
@@ -578,6 +600,17 @@ private module Cached {
isSinkNode(n, kind, model) and n.asNode() = node isSinkNode(n, kind, model) and n.asNode() = node
) )
} }
/**
* Holds if `node` is specified as a barrier with the given kind in a MaD flow
* model.
*/
cached
predicate barrierNode(Node node, string kind, string model) {
exists(SourceSinkInterpretationInput::InterpretNode n |
isBarrierNode(n, kind, model) and n.asNode() = node
)
}
} }
import Cached import Cached
@@ -594,6 +627,12 @@ predicate sourceNode(Node node, string kind) { sourceNode(node, kind, _) }
*/ */
predicate sinkNode(Node node, string kind) { sinkNode(node, kind, _) } predicate sinkNode(Node node, string kind) { sinkNode(node, kind, _) }
/**
* Holds if `node` is specified as a barrier with the given kind in a MaD flow
* model.
*/
predicate barrierNode(Node node, string kind) { barrierNode(node, kind, _) }
// adapter class for converting Mad summaries to `SummarizedCallable`s // adapter class for converting Mad summaries to `SummarizedCallable`s
private class SummarizedCallableAdapter extends SummarizedCallable { private class SummarizedCallableAdapter extends SummarizedCallable {
SummarizedCallableAdapter() { summaryElement(this, _, _, _, _, _, _) } SummarizedCallableAdapter() { summaryElement(this, _, _, _, _, _, _) }

View File

@@ -20,6 +20,14 @@ extensible predicate sinkModel(
string input, string kind, string provenance, QlBuiltins::ExtensionId madId string input, string kind, string provenance, QlBuiltins::ExtensionId madId
); );
/**
* Holds if a barrier model exists for the given parameters.
*/
extensible predicate barrierModel(
string package, string type, boolean subtypes, string name, string signature, string ext,
string output, string kind, string provenance, QlBuiltins::ExtensionId madId
);
/** /**
* Holds if a summary model exists for the given parameters. * Holds if a summary model exists for the given parameters.
*/ */

View File

@@ -158,7 +158,8 @@ private predicate relatedArgSpec(Callable c, string spec) {
summaryModel(namespace, type, subtypes, name, signature, ext, spec, _, _, _, _) or summaryModel(namespace, type, subtypes, name, signature, ext, spec, _, _, _, _) or
summaryModel(namespace, type, subtypes, name, signature, ext, _, spec, _, _, _) or summaryModel(namespace, type, subtypes, name, signature, ext, _, spec, _, _, _) or
sourceModel(namespace, type, subtypes, name, signature, ext, spec, _, _, _) or sourceModel(namespace, type, subtypes, name, signature, ext, spec, _, _, _) or
sinkModel(namespace, type, subtypes, name, signature, ext, spec, _, _, _) sinkModel(namespace, type, subtypes, name, signature, ext, spec, _, _, _) or
barrierModel(namespace, type, subtypes, name, signature, ext, spec, _, _, _)
| |
c = interpretElement(namespace, type, subtypes, name, signature, ext, _) c = interpretElement(namespace, type, subtypes, name, signature, ext, _)
) )
@@ -259,6 +260,25 @@ module SourceSinkInterpretationInput implements
) )
} }
predicate barrierElement(
Element e, string output, string kind, Public::Provenance provenance, string model
) {
exists(
string namespace, string type, boolean subtypes, string name, string signature, string ext,
SourceOrSinkElement baseBarrier, string originalOutput, QlBuiltins::ExtensionId madId
|
barrierModel(namespace, type, subtypes, name, signature, ext, originalOutput, kind, provenance,
madId) and
model = "MaD:" + madId.toString() and
baseBarrier = interpretElement(namespace, type, subtypes, name, signature, ext, _) and
(
e = baseBarrier and output = originalOutput
or
correspondingKotlinParameterDefaultsArgSpec(baseBarrier, e, originalOutput, output)
)
)
}
class SourceOrSinkElement = Element; class SourceOrSinkElement = Element;
private newtype TInterpretNode = private newtype TInterpretNode =

View File

@@ -2052,6 +2052,14 @@ module Make<
Element n, string input, string kind, Provenance provenance, string model Element n, string input, string kind, Provenance provenance, string model
); );
/**
* Holds if an external barrier specification exists for `n` with output specification
* `output` and kind `kind`.
*/
predicate barrierElement(
Element n, string output, string kind, Provenance provenance, string model
);
class SourceOrSinkElement extends Element; class SourceOrSinkElement extends Element;
/** An entity used to interpret a source/sink specification. */ /** An entity used to interpret a source/sink specification. */
@@ -2105,7 +2113,8 @@ module Make<
private predicate sourceSinkSpec(string spec) { private predicate sourceSinkSpec(string spec) {
sourceElement(_, spec, _, _, _) or sourceElement(_, spec, _, _, _) or
sinkElement(_, spec, _, _, _) sinkElement(_, spec, _, _, _) or
barrierElement(_, spec, _, _, _)
} }
private module AccessPath = AccessPathSyntax::AccessPath<sourceSinkSpec/1>; private module AccessPath = AccessPathSyntax::AccessPath<sourceSinkSpec/1>;
@@ -2160,11 +2169,22 @@ module Make<
) )
} }
private predicate barrierElementRef(
InterpretNode ref, SourceSinkAccessPath output, string kind, string model
) {
exists(SourceOrSinkElement e |
barrierElement(e, output, kind, _, model) and
if outputNeedsReferenceExt(output.getToken(0))
then e = ref.getCallTarget()
else e = ref.asElement()
)
}
/** Holds if the first `n` tokens of `output` resolve to the given interpretation. */ /** Holds if the first `n` tokens of `output` resolve to the given interpretation. */
private predicate interpretOutput( private predicate interpretOutput(
SourceSinkAccessPath output, int n, InterpretNode ref, InterpretNode node SourceSinkAccessPath output, int n, InterpretNode ref, InterpretNode node
) { ) {
sourceElementRef(ref, output, _, _) and (sourceElementRef(ref, output, _, _) or barrierElementRef(ref, output, _, _)) and
n = 0 and n = 0 and
( (
if output = "" if output = ""
@@ -2280,6 +2300,17 @@ module Make<
) )
} }
/**
* Holds if `node` is specified as a barrier with the given kind in a MaD flow
* model.
*/
predicate isBarrierNode(InterpretNode node, string kind, string model) {
exists(InterpretNode ref, SourceSinkAccessPath output |
barrierElementRef(ref, output, kind, model) and
interpretOutput(output, output.getNumToken(), ref, node)
)
}
final private class SourceOrSinkElementFinal = SourceOrSinkElement; final private class SourceOrSinkElementFinal = SourceOrSinkElement;
signature predicate sourceOrSinkElementSig( signature predicate sourceOrSinkElementSig(

View File

@@ -173,7 +173,7 @@ module KindValidation<KindValidationConfigSig Config> {
or or
exists(string kind, string msg | Config::sinkKind(kind) | exists(string kind, string msg | Config::sinkKind(kind) |
not kind instanceof ValidSinkKind and not kind instanceof ValidSinkKind and
msg = "Invalid kind \"" + kind + "\" in sink model." and msg = "Invalid kind \"" + kind + "\" in sink or barrier model." and
// The part of this message that refers to outdated sink kinds can be deleted after June 1st, 2024. // The part of this message that refers to outdated sink kinds can be deleted after June 1st, 2024.
if kind instanceof OutdatedSinkKind if kind instanceof OutdatedSinkKind
then result = msg + " " + kind.(OutdatedSinkKind).outdatedMessage() then result = msg + " " + kind.(OutdatedSinkKind).outdatedMessage()