@@ -54,17 +54,17 @@ module API {
5454 /**
5555 * Gets a call to the function represented by this API component.
5656 */
57- DataFlow :: CallNode getACall ( ) { result = getReturn ( ) .getAnImmediateUse ( ) }
57+ CallNode getACall ( ) { result = getReturn ( ) .getAnImmediateUse ( ) }
5858
5959 /**
6060 * Gets a `new` call to the function represented by this API component.
6161 */
62- DataFlow :: NewNode getAnInstantiation ( ) { result = getInstance ( ) .getAnImmediateUse ( ) }
62+ NewNode getAnInstantiation ( ) { result = getInstance ( ) .getAnImmediateUse ( ) }
6363
6464 /**
6565 * Gets an invocation (with our without `new`) to the function represented by this API component.
6666 */
67- DataFlow :: InvokeNode getAnInvocation ( ) { result = getACall ( ) or result = getAnInstantiation ( ) }
67+ InvokeNode getAnInvocation ( ) { result = getACall ( ) or result = getAnInstantiation ( ) }
6868
6969 /**
7070 * Gets a data-flow node corresponding to the right-hand side of a definition of the API
@@ -82,6 +82,12 @@ module API {
8282 */
8383 DataFlow:: Node getARhs ( ) { Impl:: rhs ( this , result ) }
8484
85+ /**
86+ * Gets a data-flow node that may interprocedurally flow to the right-hand side of a definition
87+ * of the API component represented by this node.
88+ */
89+ DataFlow:: Node getAValueReachingRhs ( ) { result = Impl:: trackDefNode ( getARhs ( ) ) }
90+
8591 /**
8692 * Gets a node representing member `m` of this API component.
8793 *
@@ -114,11 +120,17 @@ module API {
114120 * For example, if this node represents a use of some class `A`, then there might be a node
115121 * representing instances of `A`, typically corresponding to expressions `new A()` at the
116122 * source level.
123+ *
124+ * This predicate may have multiple results when there are multiple constructor calls invoking this API component.
125+ * Consider using `getAnInstantiation()` if there is a need to distinguish between individual constructor calls.
117126 */
118127 Node getInstance ( ) { result = getASuccessor ( Label:: instance ( ) ) }
119128
120129 /**
121130 * Gets a node representing the `i`th parameter of the function represented by this node.
131+ *
132+ * This predicate may have multiple results when there are multiple invocations of this API component.
133+ * Consider using `getAnInvocation()` if there is a need to distingiush between individual calls.
122134 */
123135 bindingset [ i]
124136 Node getParameter ( int i ) { result = getASuccessor ( Label:: parameter ( i ) ) }
@@ -133,6 +145,9 @@ module API {
133145
134146 /**
135147 * Gets a node representing the last parameter of the function represented by this node.
148+ *
149+ * This predicate may have multiple results when there are multiple invocations of this API component.
150+ * Consider using `getAnInvocation()` if there is a need to distingiush between individual calls.
136151 */
137152 Node getLastParameter ( ) { result = getParameter ( getNumParameter ( ) - 1 ) }
138153
@@ -144,6 +159,10 @@ module API {
144159 /**
145160 * Gets a node representing a parameter or the receiver of the function represented by this
146161 * node.
162+ *
163+ * This predicate may result in a mix of parameters from different call sites in cases where
164+ * there are multiple invocations of this API component.
165+ * Consider using `getAnInvocation()` if there is a need to distingiush between individual calls.
147166 */
148167 Node getAParameter ( ) {
149168 result = getASuccessor ( Label:: parameterByStringIndex ( _) ) or
@@ -152,6 +171,9 @@ module API {
152171
153172 /**
154173 * Gets a node representing the result of the function represented by this node.
174+ *
175+ * This predicate may have multiple results when there are multiple invocations of this API component.
176+ * Consider using `getACall()` if there is a need to distingiush between individual calls.
155177 */
156178 Node getReturn ( ) { result = getASuccessor ( Label:: return ( ) ) }
157179
@@ -871,6 +893,54 @@ module API {
871893 }
872894
873895 import Label as EdgeLabel
896+
897+ /**
898+ * An `InvokeNode` that is connected to the API graph.
899+ *
900+ * Can be used to reason about calls to an external API in which the correlation between
901+ * parameters and/or return values must be retained.
902+ *
903+ * The member predicates `getParameter`, `getReturn`, and `getInstance` mimic the corresponding
904+ * predicates from `API::Node`. These are guaranteed to exist and be unique to this call.
905+ */
906+ class InvokeNode extends DataFlow:: InvokeNode {
907+ API:: Node callee ;
908+
909+ InvokeNode ( ) {
910+ this = callee .getReturn ( ) .getAnImmediateUse ( ) or
911+ this = callee .getInstance ( ) .getAnImmediateUse ( )
912+ }
913+
914+ /** Gets the API node for the `i`th parameter of this invocation. */
915+ Node getParameter ( int i ) {
916+ result = callee .getParameter ( i ) and
917+ result .getARhs ( ) = getArgument ( i )
918+ }
919+
920+ /** Gets the API node for a parameter of this invocation. */
921+ Node getAParameter ( ) { result = getParameter ( _) }
922+
923+ /** Gets the API node for the last parameter of this invocation. */
924+ Node getLastParameter ( ) { result = getParameter ( getNumArgument ( ) - 1 ) }
925+
926+ /** Gets the API node for the return value of this call. */
927+ Node getReturn ( ) {
928+ result = callee .getReturn ( ) and
929+ result .getAnImmediateUse ( ) = this
930+ }
931+
932+ /** Gets the API node for the object constructed by this invocation. */
933+ Node getInstance ( ) {
934+ result = callee .getInstance ( ) and
935+ result .getAnImmediateUse ( ) = this
936+ }
937+ }
938+
939+ /** A call connected to the API graph. */
940+ class CallNode extends InvokeNode , DataFlow:: CallNode { }
941+
942+ /** A `new` call connected to the API graph. */
943+ class NewNode extends InvokeNode , DataFlow:: NewNode { }
874944}
875945
876946private module Label {
0 commit comments