Skip to content

Commit 1d45996

Browse files
authored
Merge pull request #8466 from michaelnebel/csharp/refactor-aspartial
C#: Refactor asPartial to allow re-use.
2 parents ea065b7 + 8e2277e commit 1d45996

File tree

8 files changed

+56
-80
lines changed

8 files changed

+56
-80
lines changed

csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowPrivate.qll

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2031,3 +2031,47 @@ abstract class SyntheticField extends string {
20312031
* Holds if the the content `c` is a container.
20322032
*/
20332033
predicate containerContent(DataFlow::Content c) { c instanceof DataFlow::ElementContent }
2034+
2035+
/**
2036+
* A module containing predicates related to generating models as data.
2037+
*/
2038+
module Csv {
2039+
private string parameterQualifiedTypeNamesToString(DataFlowCallable c) {
2040+
result =
2041+
concat(Parameter p, int i |
2042+
p = c.getParameter(i)
2043+
|
2044+
p.getType().getQualifiedName(), "," order by i
2045+
)
2046+
}
2047+
2048+
/** Holds if the summary should apply for all overrides of `c`. */
2049+
predicate isBaseCallableOrPrototype(DataFlowCallable c) {
2050+
c.getDeclaringType() instanceof Interface
2051+
or
2052+
exists(Modifiable m | m = [c.(Modifiable), c.(Accessor).getDeclaration()] |
2053+
m.isAbstract()
2054+
or
2055+
c.getDeclaringType().(Modifiable).isAbstract() and m.(Virtualizable).isVirtual()
2056+
)
2057+
}
2058+
2059+
/** Gets a string representing whether the summary should apply for all overrides of `c`. */
2060+
private string getCallableOverride(DataFlowCallable c) {
2061+
if isBaseCallableOrPrototype(c) then result = "true" else result = "false"
2062+
}
2063+
2064+
/** Computes the first 6 columns for CSV rows of `c`. */
2065+
string asPartialModel(DataFlowCallable c) {
2066+
exists(string namespace, string type |
2067+
c.getDeclaringType().hasQualifiedName(namespace, type) and
2068+
result =
2069+
namespace + ";" //
2070+
+ type + ";" //
2071+
+ getCallableOverride(c) + ";" //
2072+
+ c.getName() + ";" //
2073+
+ "(" + parameterQualifiedTypeNamesToString(c) + ")" //
2074+
+ /* ext + */ ";" //
2075+
)
2076+
}
2077+
}

csharp/ql/lib/semmle/code/csharp/dataflow/internal/FlowSummaryImpl.qll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1056,7 +1056,7 @@ module Private {
10561056
|
10571057
c.relevantSummary(input, output, preservesValue) and
10581058
csv =
1059-
c.getCallableCsv() + ";;" + getComponentStackCsv(input) + ";" +
1059+
c.getCallableCsv() + ";" + getComponentStackCsv(input) + ";" +
10601060
getComponentStackCsv(output) + ";" + renderKind(preservesValue)
10611061
)
10621062
}

csharp/ql/src/utils/model-generator/ModelGeneratorUtilsSpecific.qll

Lines changed: 4 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -7,57 +7,20 @@ private import semmle.code.csharp.dataflow.internal.DataFlowDispatch
77
private predicate isRelevantForModels(Callable api) { not api instanceof MainMethod }
88

99
/**
10-
* A class of Callables that are relevant for generating summary, source and sinks models for.
10+
* A class of callables that are relevant generating summary, source and sinks models for.
1111
*
12-
* In the Standard library and 3rd party libraries it the Callables that can be called
12+
* In the Standard library and 3rd party libraries it the callables that can be called
1313
* from outside the library itself.
1414
*/
15-
class TargetApi extends Callable {
15+
class TargetApi extends DataFlowCallable {
1616
TargetApi() {
1717
[this.(Modifiable), this.(Accessor).getDeclaration()].isEffectivelyPublic() and
1818
this.fromSource() and
1919
isRelevantForModels(this)
2020
}
2121
}
2222

23-
private string parameterQualifiedTypeNamesToString(TargetApi api) {
24-
result =
25-
concat(Parameter p, int i |
26-
p = api.getParameter(i)
27-
|
28-
p.getType().getQualifiedName(), "," order by i
29-
)
30-
}
31-
32-
/** Holds if the summary should apply for all overrides of this. */
33-
private predicate isBaseCallableOrPrototype(TargetApi api) {
34-
api.getDeclaringType() instanceof Interface
35-
or
36-
exists(Modifiable m | m = [api.(Modifiable), api.(Accessor).getDeclaration()] |
37-
m.isAbstract()
38-
or
39-
api.getDeclaringType().(Modifiable).isAbstract() and m.(Virtualizable).isVirtual()
40-
)
41-
}
42-
43-
/** Gets a string representing whether the summary should apply for all overrides of this. */
44-
private string getCallableOverride(TargetApi api) {
45-
if isBaseCallableOrPrototype(api) then result = "true" else result = "false"
46-
}
47-
48-
/** Computes the first 6 columns for CSV rows. */
49-
string asPartialModel(TargetApi api) {
50-
exists(string namespace, string type |
51-
api.getDeclaringType().hasQualifiedName(namespace, type) and
52-
result =
53-
namespace + ";" //
54-
+ type + ";" //
55-
+ getCallableOverride(api) + ";" //
56-
+ api.getName() + ";" //
57-
+ "(" + parameterQualifiedTypeNamesToString(api) + ")" //
58-
+ /* ext + */ ";" //
59-
)
60-
}
23+
predicate asPartialModel = Csv::asPartialModel/1;
6124

6225
/**
6326
* Holds for type `t` for fields that are relevant as an intermediate

csharp/ql/test/library-tests/dataflow/library/FlowSummariesFiltered.ql

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import shared.FlowSummaries
2+
private import semmle.code.csharp.dataflow.internal.DataFlowPrivate::Csv
23
private import semmle.code.csharp.dataflow.ExternalFlow
34

45
class IncludeFilteredSummarizedCallable extends IncludeSummarizedCallable {
@@ -14,7 +15,7 @@ class IncludeFilteredSummarizedCallable extends IncludeSummarizedCallable {
1415
) {
1516
this.propagatesFlow(input, output, preservesValue) and
1617
not exists(IncludeSummarizedCallable rsc |
17-
rsc.isBaseCallableOrPrototype() and
18+
isBaseCallableOrPrototype(rsc) and
1819
rsc.propagatesFlow(input, output, preservesValue) and
1920
this.(UnboundCallable).overridesOrImplementsUnbound(rsc)
2021
)
Lines changed: 2 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,44 +1,12 @@
11
import semmle.code.csharp.dataflow.FlowSummary
22
import semmle.code.csharp.dataflow.internal.FlowSummaryImpl::Private::TestOutput
3+
private import semmle.code.csharp.dataflow.internal.DataFlowPrivate
34

45
abstract class IncludeSummarizedCallable extends RelevantSummarizedCallable {
56
IncludeSummarizedCallable() {
67
[this.(Modifiable), this.(Accessor).getDeclaration()].isEffectivelyPublic()
78
}
89

9-
/** Gets the qualified parameter types of this callable as a comma-separated string. */
10-
private string parameterQualifiedTypeNamesToString() {
11-
result =
12-
concat(Parameter p, int i |
13-
p = this.getParameter(i)
14-
|
15-
p.getType().getQualifiedName(), "," order by i
16-
)
17-
}
18-
19-
/** Holds if the summary should apply for all overrides of this. */
20-
predicate isBaseCallableOrPrototype() {
21-
this.getDeclaringType() instanceof Interface
22-
or
23-
exists(Modifiable m | m = [this.(Modifiable), this.(Accessor).getDeclaration()] |
24-
m.isAbstract()
25-
or
26-
this.getDeclaringType().(Modifiable).isAbstract() and m.(Virtualizable).isVirtual()
27-
)
28-
}
29-
30-
/** Gets a string representing whether the summary should apply for all overrides of this. */
31-
private string getCallableOverride() {
32-
if this.isBaseCallableOrPrototype() then result = "true" else result = "false"
33-
}
34-
3510
/** Gets a string representing the callable in semi-colon separated format for use in flow summaries. */
36-
final override string getCallableCsv() {
37-
exists(string namespace, string type |
38-
this.getDeclaringType().hasQualifiedName(namespace, type) and
39-
result =
40-
namespace + ";" + type + ";" + this.getCallableOverride() + ";" + this.getName() + ";" + "("
41-
+ this.parameterQualifiedTypeNamesToString() + ")"
42-
)
43-
}
11+
final override string getCallableCsv() { result = Csv::asPartialModel(this) }
4412
}

java/ql/lib/semmle/code/java/dataflow/internal/FlowSummaryImpl.qll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1056,7 +1056,7 @@ module Private {
10561056
|
10571057
c.relevantSummary(input, output, preservesValue) and
10581058
csv =
1059-
c.getCallableCsv() + ";;" + getComponentStackCsv(input) + ";" +
1059+
c.getCallableCsv() + ";" + getComponentStackCsv(input) + ";" +
10601060
getComponentStackCsv(output) + ";" + renderKind(preservesValue)
10611061
)
10621062
}

java/ql/src/utils/model-generator/ModelGeneratorUtilsSpecific.qll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ private import semmle.code.java.dataflow.ExternalFlow
55
private import semmle.code.java.dataflow.internal.ContainerFlow
66
private import semmle.code.java.dataflow.internal.DataFlowImplCommon
77

8-
Method superImpl(Method m) {
8+
private Method superImpl(Method m) {
99
result = m.getAnOverride() and
1010
not exists(result.getAnOverride()) and
1111
not m instanceof ToStringMethod

ruby/ql/lib/codeql/ruby/dataflow/internal/FlowSummaryImpl.qll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1056,7 +1056,7 @@ module Private {
10561056
|
10571057
c.relevantSummary(input, output, preservesValue) and
10581058
csv =
1059-
c.getCallableCsv() + ";;" + getComponentStackCsv(input) + ";" +
1059+
c.getCallableCsv() + ";" + getComponentStackCsv(input) + ";" +
10601060
getComponentStackCsv(output) + ";" + renderKind(preservesValue)
10611061
)
10621062
}

0 commit comments

Comments
 (0)