@@ -187,13 +187,29 @@ class TypeTracker extends TTypeTracker {
187187 )
188188 }
189189
190- /**
190+ /**
191191 * Gets the summary that corresponds to having taken a forwards
192192 * local, heap and/or inter-procedural step from `pred` to `succ`.
193193 *
194194 * Unlike `TypeTracker::step`, this predicate exposes all edges
195195 * in the flow graph, and not just the edges between `SourceNode`s.
196196 * It may therefore be less performant.
197+ *
198+ * Type tracking predicates using small steps typically take the following form:
199+ * ```ql
200+ * DataFlow::Node myType(DataFlow::TypeTracker t) {
201+ * t.start() and
202+ * result = < source of myType >
203+ * or
204+ * exists (DataFlow::TypeTracker t2 |
205+ * t = t2.smallstep(myType(t2), result)
206+ * )
207+ * }
208+ *
209+ * DataFlow::Node myType() {
210+ * result = myType(DataFlow::TypeTracker::end())
211+ * }
212+ * ```
197213 */
198214 pragma [ inline]
199215 TypeTracker smallstep ( DataFlow:: Node pred , DataFlow:: Node succ ) {
@@ -319,6 +335,22 @@ class TypeBackTracker extends TTypeBackTracker {
319335 * Unlike `TypeBackTracker::step`, this predicate exposes all edges
320336 * in the flowgraph, and not just the edges between
321337 * `SourceNode`s. It may therefore be less performant.
338+ *
339+ * Type tracking predicates using small steps typically take the following form:
340+ * ```ql
341+ * DataFlow::Node myType(DataFlow::TypeBackTracker t) {
342+ * t.start() and
343+ * result = < some API call >.getArgument(< n >)
344+ * or
345+ * exists (DataFlow::TypeTracker t2 |
346+ * t = t2.smallstep(result, myType(t2))
347+ * )
348+ * }
349+ *
350+ * DataFlow::Node myType() {
351+ * result = myType(DataFlow::TypeBackTracker::end())
352+ * }
353+ * ```
322354 */
323355 pragma [ inline]
324356 TypeBackTracker smallstep ( DataFlow:: Node pred , DataFlow:: Node succ ) {
0 commit comments