@@ -54,17 +54,17 @@ module API {
54
54
/**
55
55
* Gets a call to the function represented by this API component.
56
56
*/
57
- DataFlow :: CallNode getACall ( ) { result = getReturn ( ) .getAnImmediateUse ( ) }
57
+ CallNode getACall ( ) { result = getReturn ( ) .getAnImmediateUse ( ) }
58
58
59
59
/**
60
60
* Gets a `new` call to the function represented by this API component.
61
61
*/
62
- DataFlow :: NewNode getAnInstantiation ( ) { result = getInstance ( ) .getAnImmediateUse ( ) }
62
+ NewNode getAnInstantiation ( ) { result = getInstance ( ) .getAnImmediateUse ( ) }
63
63
64
64
/**
65
65
* Gets an invocation (with our without `new`) to the function represented by this API component.
66
66
*/
67
- DataFlow :: InvokeNode getAnInvocation ( ) { result = getACall ( ) or result = getAnInstantiation ( ) }
67
+ InvokeNode getAnInvocation ( ) { result = getACall ( ) or result = getAnInstantiation ( ) }
68
68
69
69
/**
70
70
* Gets a data-flow node corresponding to the right-hand side of a definition of the API
@@ -82,6 +82,12 @@ module API {
82
82
*/
83
83
DataFlow:: Node getARhs ( ) { Impl:: rhs ( this , result ) }
84
84
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
+
85
91
/**
86
92
* Gets a node representing member `m` of this API component.
87
93
*
@@ -114,11 +120,17 @@ module API {
114
120
* For example, if this node represents a use of some class `A`, then there might be a node
115
121
* representing instances of `A`, typically corresponding to expressions `new A()` at the
116
122
* 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.
117
126
*/
118
127
Node getInstance ( ) { result = getASuccessor ( Label:: instance ( ) ) }
119
128
120
129
/**
121
130
* 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.
122
134
*/
123
135
bindingset [ i]
124
136
Node getParameter ( int i ) { result = getASuccessor ( Label:: parameter ( i ) ) }
@@ -133,6 +145,9 @@ module API {
133
145
134
146
/**
135
147
* 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.
136
151
*/
137
152
Node getLastParameter ( ) { result = getParameter ( getNumParameter ( ) - 1 ) }
138
153
@@ -144,6 +159,10 @@ module API {
144
159
/**
145
160
* Gets a node representing a parameter or the receiver of the function represented by this
146
161
* 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.
147
166
*/
148
167
Node getAParameter ( ) {
149
168
result = getASuccessor ( Label:: parameterByStringIndex ( _) ) or
@@ -152,6 +171,9 @@ module API {
152
171
153
172
/**
154
173
* 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.
155
177
*/
156
178
Node getReturn ( ) { result = getASuccessor ( Label:: return ( ) ) }
157
179
@@ -871,6 +893,54 @@ module API {
871
893
}
872
894
873
895
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 { }
874
944
}
875
945
876
946
private module Label {
0 commit comments