@@ -18,29 +18,19 @@ private predicate genericCollectionType(ValueOrRefType t, TypeParameter tp) {
1818 )
1919}
2020
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-
2821/**
2922 * Holds if `tp` is a type parameter of the immediate type declaring `callable`.
3023 */
3124private predicate classTypeParameter ( DotNet:: Callable callable , TypeParameter tp ) {
32- unboundGeneric ( callable .getDeclaringType ( ) , tp )
25+ callable .getDeclaringType ( ) . ( UnboundGeneric ) . getATypeParameter ( ) = tp
3326}
3427
3528/**
3629 * Holds if `tp` is type parameter of `callable` or the type declaring `callable`.
3730 */
3831private 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
4434}
4535
4636/**
@@ -101,17 +91,17 @@ private predicate delegate(DotNet::Callable callable, DelegateType dt, int posit
10191 * Note: This predicate has to be inlined as `callable` is not related to `return` or `tp`
10292 * in every disjunction.
10393 */
104- pragma [ inline ]
94+ bindingset [ callable ]
10595private string getAccess ( DotNet:: Callable callable , Type return , TypeParameter tp ) {
10696 return = tp and result = ""
10797 or
10898 genericCollectionType ( return , tp ) and result = ".Element"
10999 or
110100 not genericCollectionType ( return , tp ) and
111101 (
112- constructedGeneric ( return , tp )
102+ return . ( ConstructedGeneric ) . getATypeArgument ( ) = tp
113103 or
114- callable .getDeclaringType ( ) = return and unboundGeneric ( return , tp )
104+ callable .getDeclaringType ( ) = return and return . ( UnboundGeneric ) . getATypeParameter ( ) = tp
115105 ) and
116106 result = getSyntheticField ( tp )
117107}
@@ -120,7 +110,7 @@ private string getAccess(DotNet::Callable callable, Type return, TypeParameter t
120110 * Holds if `input` is a models as data string representation of, how a value of type `tp`
121111 * (or a generic parameterized over `tp`) can be generated by a delegate parameter of `callable`.
122112 */
123- private predicate source ( DotNet:: Callable callable , string input , TypeParameter tp ) {
113+ private predicate delegateSource ( DotNet:: Callable callable , string input , TypeParameter tp ) {
124114 exists ( DelegateType dt , int position , Type return , string access |
125115 delegate ( callable , dt , position ) and
126116 return = dt .getReturnType ( ) and
@@ -143,7 +133,7 @@ private predicate input(DotNet::Callable callable, string input, TypeParameter t
143133 or
144134 parameter ( callable , input , tp )
145135 or
146- source ( callable , input , tp )
136+ delegateSource ( callable , input , tp )
147137}
148138
149139/**
@@ -162,12 +152,11 @@ private predicate returns(DotNet::Callable callable, TypeParameter tp, string ou
162152 * and `output` is the models as data string representation of, how data is routed to
163153 * the delegate parameter.
164154 */
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 |
167157 delegate ( callable , dt , position ) and
168158 p = dt .getAParameter ( ) and
169- t = p .getType ( ) and
170- t = tp and
159+ p .getType ( ) = tp and
171160 output = "Argument[" + position + "]" + ".Parameter[" + p .getPosition ( ) + "]"
172161 )
173162}
@@ -185,7 +174,7 @@ private predicate output(DotNet::Callable callable, TypeParameter tp, string out
185174 or
186175 returns ( callable , tp , output )
187176 or
188- sink ( callable , tp , output )
177+ delegateSink ( callable , tp , output )
189178}
190179
191180/**
@@ -196,22 +185,24 @@ class TypeBasedFlowTargetApi extends Specific::TargetApiSpecific {
196185 TypeBasedFlowTargetApi ( ) { Specific:: isRelevantForTypeBasedFlowModels ( this ) }
197186
198187 /**
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.
209190 *
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+ * }
215206 */
216207 string getSummaries ( ) {
217208 exists ( TypeParameter tp , string input , string output |
0 commit comments