@@ -92,19 +92,10 @@ module API {
9292 */
9393 class Node extends Impl:: TApiNode {
9494 /**
95- * Gets a data-flow node corresponding to a use of the API component represented by this node .
95+ * Gets a data-flow node where this value may flow after entering the current codebase .
9696 *
97- * For example, `import re; re.escape` is a use of the `escape` function from the
98- * `re` module, and `import re; re.escape("hello")` is a use of the return of that function.
99- *
100- * This includes indirect uses found via data flow, meaning that in
101- * ```python
102- * def f(x):
103- * pass
104- *
105- * f(obj.foo)
106- * ```
107- * both `obj.foo` and `x` are uses of the `foo` member from `obj`.
97+ * This is similar to `asSource()` but additionally includes nodes that are transitively reachable by data flow.
98+ * See `asSource()` for examples.
10899 */
109100 DataFlow:: Node getAValueReachableFromSource ( ) {
110101 exists ( DataFlow:: LocalSourceNode src | Impl:: use ( this , src ) |
@@ -113,39 +104,48 @@ module API {
113104 }
114105
115106 /**
116- * Gets a data-flow node corresponding to the right-hand side of a definition of the API
117- * component represented by this node .
107+ * Gets a data-flow node where this value leaves the current codebase and flows into an
108+ * external library (or in general, any external codebase) .
118109 *
119- * For example, in the property write `foo.bar = x`, variable `x` is the the right-hand side
120- * of a write to the `bar` property of `foo` .
110+ * Concretely, this is either an argument passed to a call to external code,
111+ * or the right-hand side of a property write on an object flowing into such a call .
121112 *
122- * Note that for parameters, it is the arguments flowing into that parameter that count as
123- * right-hand sides of the definition, not the declaration of the parameter itself.
124- * Consequently, in :
113+ * For example:
125114 * ```python
126- * from mypkg import foo;
115+ * import foo
116+ *
117+ * # 'x' is matched by API::moduleImport("foo").getMember("bar").getParameter(0).asSink()
127118 * foo.bar(x)
119+ *
120+ * # 'x' is matched by API::moduleImport("foo").getMember("bar").getParameter(0).getMember("prop").asSink()
121+ * obj.prop = x
122+ * foo.bar(obj);
128123 * ```
129- * `x` is the right-hand side of a definition of the first parameter of `bar` from the `mypkg.foo` module.
130124 */
131125 DataFlow:: Node asSink ( ) { Impl:: rhs ( this , result ) }
132126
133127 /**
134- * Gets a data-flow node that may interprocedurally flow to the right-hand side of a definition
135- * of the API component represented by this node.
128+ * Gets a data-flow node that transitively flows to an external library (or in general, any external codebase).
129+ *
130+ * This is similar to `asSink()` but additionally includes nodes that transitively reach a sink by data flow.
131+ * See `asSink()` for examples.
136132 */
137133 DataFlow:: Node getAValueReachingSink ( ) { result = Impl:: trackDefNode ( this .asSink ( ) ) }
138134
139135 /**
140- * Gets an immediate use of the API component represented by this node .
136+ * Gets a data-flow node where this value enters the current codebase .
141137 *
142- * For example, `import re; re.escape` is a an immediate use of the `escape` member
143- * from the `re` module.
138+ * For example:
139+ * ```python
140+ * # API::moduleImport("re").asSource()
141+ * import re
144142 *
145- * Unlike `getAUse()`, this predicate only gets the immediate references, not the indirect uses
146- * found via data flow. This means that in `x = re.escape` only `re.escape` is a reference
147- * to the `escape` member of `re`, neither `x` nor any node that `x` flows to is a reference to
148- * this API component.
143+ * # API::moduleImport("re").getMember("escape").asSource()
144+ * re.escape
145+ *
146+ * # API::moduleImport("re").getMember("escape").getReturn().asSource()
147+ * re.escape()
148+ * ```
149149 */
150150 DataFlow:: LocalSourceNode asSource ( ) { Impl:: use ( this , result ) }
151151
0 commit comments