C#: Move asPartialModel into DataFlowPrivate (to enable re-use).

This commit is contained in:
Michael Nebel
2022-03-16 16:44:24 +01:00
parent 7a9a9d833a
commit 115cef2484
3 changed files with 48 additions and 41 deletions

View File

@@ -2031,3 +2031,47 @@ abstract class SyntheticField extends string {
* Holds if the the content `c` is a container.
*/
predicate containerContent(DataFlow::Content c) { c instanceof DataFlow::ElementContent }
/**
* Module containing predicates related to generating models as data.
*/
module Csv {
private string parameterQualifiedTypeNamesToString(DataFlowCallable c) {
result =
concat(Parameter p, int i |
p = c.getParameter(i)
|
p.getType().getQualifiedName(), "," order by i
)
}
/** Holds if the summary should apply for all overrides of this. */
private predicate isBaseCallableOrPrototype(DataFlowCallable c) {
c.getDeclaringType() instanceof Interface
or
exists(Modifiable m | m = [c.(Modifiable), c.(Accessor).getDeclaration()] |
m.isAbstract()
or
c.getDeclaringType().(Modifiable).isAbstract() and m.(Virtualizable).isVirtual()
)
}
/** Gets a string representing whether the summary should apply for all overrides of this. */
private string getCallableOverride(DataFlowCallable c) {
if isBaseCallableOrPrototype(c) then result = "true" else result = "false"
}
/** Computes the first 6 columns for CSV rows. */
string asPartialModel(DataFlowCallable c) {
exists(string namespace, string type |
c.getDeclaringType().hasQualifiedName(namespace, type) and
result =
namespace + ";" //
+ type + ";" //
+ getCallableOverride(c) + ";" //
+ c.getName() + ";" //
+ "(" + parameterQualifiedTypeNamesToString(c) + ")" //
+ /* ext + */ ";" //
)
}
}

View File

@@ -7,12 +7,12 @@ private import semmle.code.csharp.dataflow.internal.DataFlowDispatch
private predicate isRelevantForModels(Callable api) { not api instanceof MainMethod }
/**
* A class of Callables that are relevant for generating summary, source and sinks models for.
* A class of DataFlowCallables that are relevant generating summary, source and sinks models for.
*
* In the Standard library and 3rd party libraries it the Callables that can be called
* from outside the library itself.
*/
class TargetApi extends Callable {
class TargetApi extends DataFlowCallable {
TargetApi() {
[this.(Modifiable), this.(Accessor).getDeclaration()].isEffectivelyPublic() and
this.fromSource() and
@@ -20,44 +20,7 @@ class TargetApi extends Callable {
}
}
private string parameterQualifiedTypeNamesToString(TargetApi api) {
result =
concat(Parameter p, int i |
p = api.getParameter(i)
|
p.getType().getQualifiedName(), "," order by i
)
}
/** Holds if the summary should apply for all overrides of this. */
private predicate isBaseCallableOrPrototype(TargetApi api) {
api.getDeclaringType() instanceof Interface
or
exists(Modifiable m | m = [api.(Modifiable), api.(Accessor).getDeclaration()] |
m.isAbstract()
or
api.getDeclaringType().(Modifiable).isAbstract() and m.(Virtualizable).isVirtual()
)
}
/** Gets a string representing whether the summary should apply for all overrides of this. */
private string getCallableOverride(TargetApi api) {
if isBaseCallableOrPrototype(api) then result = "true" else result = "false"
}
/** Computes the first 6 columns for CSV rows. */
string asPartialModel(TargetApi api) {
exists(string namespace, string type |
api.getDeclaringType().hasQualifiedName(namespace, type) and
result =
namespace + ";" //
+ type + ";" //
+ getCallableOverride(api) + ";" //
+ api.getName() + ";" //
+ "(" + parameterQualifiedTypeNamesToString(api) + ")" //
+ /* ext + */ ";" //
)
}
predicate asPartialModel = Csv::asPartialModel/1;
/**
* Holds for type `t` for fields that are relevant as an intermediate