@@ -91,16 +91,39 @@ signature module InputSig {
9191 */
9292 OutNode getAnOutNode ( DataFlowCall call , ReturnKind kind ) ;
9393
94+ /**
95+ * A type for a data flow node.
96+ *
97+ * This may or may not coincide with any type system existing for the source
98+ * language, but should minimally include unique types for individual closure
99+ * expressions (typically lambdas).
100+ */
94101 class DataFlowType {
95102 /** Gets a textual representation of this element. */
96103 string toString ( ) ;
97104 }
98105
99106 string ppReprType ( DataFlowType t ) ;
100107
108+ /**
109+ * Holds if `t1` and `t2` are compatible types.
110+ *
111+ * This predicate must be symmetric and reflexive.
112+ *
113+ * This predicate is used in the following way: If the data flow library
114+ * tracks an object from node `n1` to `n2` using solely value-preserving
115+ * steps, then it will check that the types of `n1` and `n2` are compatible.
116+ * If they are not, then flow will be blocked.
117+ */
101118 bindingset [ t1, t2]
102119 predicate compatibleTypes ( DataFlowType t1 , DataFlowType t2 ) ;
103120
121+ /**
122+ * Holds if `t1` is strictly stronger than `t2`. That is, `t1` is a strict
123+ * subtype of `t2`.
124+ *
125+ * This predicate must be transitive and imply `compatibleTypes(t1, t2)`.
126+ */
104127 predicate typeStrongerThan ( DataFlowType t1 , DataFlowType t2 ) ;
105128
106129 class Content {
@@ -199,6 +222,12 @@ signature module InputSig {
199222
200223 /**
201224 * Holds if the value of `node2` is given by `node1`.
225+ *
226+ * This predicate is combined with type information in the following way: If
227+ * the data flow library is able to compute an improved type for `node1` then
228+ * it will also conclude that this type applies to `node2`. Vice versa, if
229+ * `node2` must be visited along a flow path, then any type known for `node2`
230+ * must also apply to `node1`.
202231 */
203232 predicate localMustFlowStep ( Node node1 , Node node2 ) ;
204233
0 commit comments