@@ -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
@@ -114,11 +114,17 @@ module API {
114114 * For example, if this node represents a use of some class `A`, then there might be a node
115115 * representing instances of `A`, typically corresponding to expressions `new A()` at the
116116 * source level.
117+ *
118+ * This predicate may have multiple results when there are multiple constructor calls invoking this API component.
119+ * Consider using `getAnInstantiation()` if there is a need to distingiush between individual constructor calls.
117120 */
118121 Node getInstance ( ) { result = getASuccessor ( Label:: instance ( ) ) }
119122
120123 /**
121124 * Gets a node representing the `i`th parameter of the function represented by this node.
125+ *
126+ * This predicate may have multiple results when there are multiple invocations of this API component.
127+ * Consider using `getAnInvocation()` if there is a need to distingiush between individual calls.
122128 */
123129 bindingset [ i]
124130 Node getParameter ( int i ) { result = getASuccessor ( Label:: parameter ( i ) ) }
@@ -133,6 +139,9 @@ module API {
133139
134140 /**
135141 * Gets a node representing the last parameter of the function represented by this node.
142+ *
143+ * This predicate may have multiple results when there are multiple invocations of this API component.
144+ * Consider using `getAnInvocation()` if there is a need to distingiush between individual calls.
136145 */
137146 Node getLastParameter ( ) { result = getParameter ( getNumParameter ( ) - 1 ) }
138147
@@ -144,6 +153,10 @@ module API {
144153 /**
145154 * Gets a node representing a parameter or the receiver of the function represented by this
146155 * node.
156+ *
157+ * This predicate may result in a mix of parameters from different call sites in cases where
158+ * there are multiple invocations of this API component.
159+ * Consider using `getAnInvocation()` if there is a need to distingiush between individual calls.
147160 */
148161 Node getAParameter ( ) {
149162 result = getASuccessor ( Label:: parameterByStringIndex ( _) ) or
@@ -152,6 +165,9 @@ module API {
152165
153166 /**
154167 * Gets a node representing the result of the function represented by this node.
168+ *
169+ * This predicate may have multiple results when there are multiple invocations of this API component.
170+ * Consider using `getACall()` if there is a need to distingiush between individual calls.
155171 */
156172 Node getReturn ( ) { result = getASuccessor ( Label:: return ( ) ) }
157173
@@ -787,6 +803,46 @@ module API {
787803 }
788804
789805 import Label as EdgeLabel
806+
807+ /**
808+ * An `InvokeNode` that is connected to the API graph.
809+ *
810+ * Can be used to reason about calls to an external API in which the correlation between
811+ * parameters and/or return values must be retained.
812+ *
813+ * The member predicates `getParameter`, `getReturn`, and `getInstance` mimic the corresponding
814+ * predicates from `API::Node`. These are guaranteed to exist and be unique to this call.
815+ */
816+ class InvokeNode extends DataFlow:: InvokeNode {
817+ API:: Node callee ;
818+
819+ InvokeNode ( ) { this = callee .getReturn ( ) .getAnImmediateUse ( ) or this = callee .getInstance ( ) .getAnImmediateUse ( ) }
820+
821+ /** Gets the API node for the `i`th parameter of this invocation. */
822+ Node getParameter ( int i ) {
823+ result = callee .getParameter ( i ) and
824+ result .getARhs ( ) = getArgument ( i )
825+ }
826+
827+ /** Gets the API node a parameter of this invocation. */
828+ Node getAParameter ( ) {
829+ result = getParameter ( _)
830+ }
831+
832+ /** Gets the API node for the return value of this call. */
833+ Node getReturn ( ) { result .getAnImmediateUse ( ) = this }
834+
835+ /** Gets the API node for the object constructed by this invocation. */
836+ Node getInstance ( ) { result .getAnImmediateUse ( ) = this }
837+ }
838+
839+ /** A call connected to the API graph. */
840+ class CallNode extends InvokeNode , DataFlow:: CallNode {
841+ }
842+
843+ /** A `new` call connected to the API graph. */
844+ class NewNode extends InvokeNode , DataFlow:: NewNode {
845+ }
790846}
791847
792848private module Label {
0 commit comments