@@ -18,29 +18,19 @@ private predicate genericCollectionType(ValueOrRefType t, TypeParameter tp) {
18
18
)
19
19
}
20
20
21
- /**
22
- * Holds if `tp` is a type parameter of `generic`.
23
- */
24
- private predicate unboundGeneric ( UnboundGeneric generic , TypeParameter tp ) {
25
- tp = generic .getATypeParameter ( )
26
- }
27
-
28
21
/**
29
22
* Holds if `tp` is a type parameter of the immediate type declaring `callable`.
30
23
*/
31
24
private predicate classTypeParameter ( DotNet:: Callable callable , TypeParameter tp ) {
32
- unboundGeneric ( callable .getDeclaringType ( ) , tp )
25
+ callable .getDeclaringType ( ) . ( UnboundGeneric ) . getATypeParameter ( ) = tp
33
26
}
34
27
35
28
/**
36
29
* Holds if `tp` is type parameter of `callable` or the type declaring `callable`.
37
30
*/
38
31
private predicate localTypeParameter ( DotNet:: Callable callable , TypeParameter tp ) {
39
- classTypeParameter ( callable , tp ) or unboundGeneric ( callable , tp )
40
- }
41
-
42
- private predicate constructedGeneric ( ConstructedType t , TypeParameter tp ) {
43
- t .getATypeArgument ( ) = tp
32
+ classTypeParameter ( callable , tp ) or
33
+ callable .( UnboundGeneric ) .getATypeParameter ( ) = tp
44
34
}
45
35
46
36
/**
@@ -101,17 +91,17 @@ private predicate delegate(DotNet::Callable callable, DelegateType dt, int posit
101
91
* Note: This predicate has to be inlined as `callable` is not related to `return` or `tp`
102
92
* in every disjunction.
103
93
*/
104
- pragma [ inline ]
94
+ bindingset [ callable ]
105
95
private string getAccess ( DotNet:: Callable callable , Type return , TypeParameter tp ) {
106
96
return = tp and result = ""
107
97
or
108
98
genericCollectionType ( return , tp ) and result = ".Element"
109
99
or
110
100
not genericCollectionType ( return , tp ) and
111
101
(
112
- constructedGeneric ( return , tp )
102
+ return . ( ConstructedGeneric ) . getATypeArgument ( ) = tp
113
103
or
114
- callable .getDeclaringType ( ) = return and unboundGeneric ( return , tp )
104
+ callable .getDeclaringType ( ) = return and return . ( UnboundGeneric ) . getATypeParameter ( ) = tp
115
105
) and
116
106
result = getSyntheticField ( tp )
117
107
}
@@ -120,7 +110,7 @@ private string getAccess(DotNet::Callable callable, Type return, TypeParameter t
120
110
* Holds if `input` is a models as data string representation of, how a value of type `tp`
121
111
* (or a generic parameterized over `tp`) can be generated by a delegate parameter of `callable`.
122
112
*/
123
- private predicate source ( DotNet:: Callable callable , string input , TypeParameter tp ) {
113
+ private predicate delegateSource ( DotNet:: Callable callable , string input , TypeParameter tp ) {
124
114
exists ( DelegateType dt , int position , Type return , string access |
125
115
delegate ( callable , dt , position ) and
126
116
return = dt .getReturnType ( ) and
@@ -143,7 +133,7 @@ private predicate input(DotNet::Callable callable, string input, TypeParameter t
143
133
or
144
134
parameter ( callable , input , tp )
145
135
or
146
- source ( callable , input , tp )
136
+ delegateSource ( callable , input , tp )
147
137
}
148
138
149
139
/**
@@ -162,12 +152,11 @@ private predicate returns(DotNet::Callable callable, TypeParameter tp, string ou
162
152
* and `output` is the models as data string representation of, how data is routed to
163
153
* the delegate parameter.
164
154
*/
165
- private predicate sink ( DotNet:: Callable callable , TypeParameter tp , string output ) {
166
- exists ( DelegateType dt , int position , Type t , Parameter p |
155
+ private predicate delegateSink ( DotNet:: Callable callable , TypeParameter tp , string output ) {
156
+ exists ( DelegateType dt , int position , Parameter p |
167
157
delegate ( callable , dt , position ) and
168
158
p = dt .getAParameter ( ) and
169
- t = p .getType ( ) and
170
- t = tp and
159
+ p .getType ( ) = tp and
171
160
output = "Argument[" + position + "]" + ".Parameter[" + p .getPosition ( ) + "]"
172
161
)
173
162
}
@@ -185,7 +174,7 @@ private predicate output(DotNet::Callable callable, TypeParameter tp, string out
185
174
or
186
175
returns ( callable , tp , output )
187
176
or
188
- sink ( callable , tp , output )
177
+ delegateSink ( callable , tp , output )
189
178
}
190
179
191
180
/**
@@ -196,22 +185,24 @@ class TypeBasedFlowTargetApi extends Specific::TargetApiSpecific {
196
185
TypeBasedFlowTargetApi ( ) { Specific:: isRelevantForTypeBasedFlowModels ( this ) }
197
186
198
187
/**
199
- * Gets the string representation of all type based summaries inspired by
200
- * the Theorems for Free approach.
201
- *
202
- * Basic example signatures could be
203
- * this : T -> \alpha
204
- * this : \beta -> T
205
- * where T is type parameter on `this` or on the declaring type of `this`.
206
- *
207
- * Important special cases are \alpha = unit (setter),
208
- * \alpha = T (getter, setter and id) and \beta = unit (getter).
188
+ * Gets the string representation of all type based summaries for `this`
189
+ * inspired by the Theorems for Free approach.
209
190
*
210
- * Complex example signatures could be
211
- * this : (T -> S) -> S
212
- * this : S1 x (S1 -> S2) -> S2
213
- * where T is type parameter of the class declaring `this` and S, S1 and S2 are type parameters
214
- * of `this`.
191
+ * Examples could be (see C# psuedo code below)
192
+ * (1) `Get` returns a value of type `T`. We assume that the returned
193
+ * value was fetched from a (synthetic) field.
194
+ * (2) `Set` consumes a value of type `T`. We assume that the value is stored in
195
+ * a (synthetic) field.
196
+ * (3) `Apply<S>` is assumed to apply the provided function to a value stored in
197
+ * a (synthetic) field and return the result.
198
+ * (4) `Apply<S1,S2>` is assumed to apply the provided function to provided value
199
+ * and return the result.
200
+ * public class MyGeneric<T> {
201
+ * public void Set(T x) { ... }
202
+ * public T Get() { ... }
203
+ * public S Apply<S>(Func<T, S> f) { ... }
204
+ * public S2 Apply<S1, S2>(S1 x, Func<S1, S2> f) { ... }
205
+ * }
215
206
*/
216
207
string getSummaries ( ) {
217
208
exists ( TypeParameter tp , string input , string output |
0 commit comments