@@ -198,13 +198,9 @@ module API {
198198 }
199199
200200 /** A node corresponding to the use of an API component. */
201- class Use extends Node , Impl:: TUse {
201+ class Use extends Node , Impl:: MkUse {
202202 override string toString ( ) {
203- exists ( string type |
204- this = Impl:: MkUse ( _) and type = "Use "
205- or
206- this = Impl:: MkModule ( _) and type = "ModuleUse "
207- |
203+ exists ( string type | this = Impl:: MkUse ( _) and type = "Use " |
208204 result = type + getPath ( )
209205 or
210206 not exists ( this .getPath ( ) ) and result = type + "with no path"
@@ -216,27 +212,13 @@ module API {
216212 Root root ( ) { any ( ) }
217213
218214 /**
219- * Gets a node corresponding to an import of module `m`.
215+ * Gets a node corresponding to an import of top-level module `m`.
220216 *
221217 * Note: You should only use this predicate for top level modules or classes. If you want nodes corresponding to a nested module or class,
222218 * you should use `.getMember` on the parent module/class. For example, for nodes corresponding to the class `Gem::Version`,
223219 * use `moduleImport("Gem").getMember("Version")`.
224220 */
225- Node moduleImport ( string m ) {
226- result = Impl:: MkModule ( m ) and not m .matches ( "%::%" )
227- or
228- result = Impl:: MkUse ( unresolvedModuleReference ( m ) )
229- }
230-
231- DataFlow:: Node unresolvedModuleReference ( string m ) {
232- exists ( ConstantReadAccess iexpr , DataFlow:: Node node |
233- not exists ( resolveScopeExpr ( iexpr ) ) and
234- not exists ( iexpr .getScopeExpr ( ) ) and
235- m = iexpr .getName ( ) and
236- result = node and
237- node .asExpr ( ) .getExpr ( ) = iexpr
238- )
239- }
221+ Node moduleImport ( string m ) { result = root ( ) .getMember ( m ) }
240222
241223 /**
242224 * Provides the actual implementation of API graphs, cached for performance.
@@ -266,23 +248,30 @@ module API {
266248 newtype TApiNode =
267249 /** The root of the API graph. */
268250 MkRoot ( ) or
269- /** An abstract representative for imports of the module called `name`. */
270- MkModule ( string name ) { exists ( TResolved ( name ) ) } or
271251 /** A use of an API member at the node `nd`. */
272- MkUse ( DataFlow:: Node nd ) {
273- use ( _, _, nd )
274- or
275- nd = unresolvedModuleReference ( _)
276- }
277-
278- class TUse = MkModule or MkUse ;
252+ MkUse ( DataFlow:: Node nd ) { use ( _, _, nd ) }
279253
280254 /**
281255 * Holds if `ref` is a use of a node that should have an incoming edge from `base` labeled
282256 * `lbl` in the API graph.
283257 */
284258 cached
285259 predicate use ( TApiNode base , string lbl , DataFlow:: Node ref ) {
260+ base = MkRoot ( ) and
261+ exists ( string name , ExprNodes:: ConstantAccessCfgNode access , ConstantReadAccess read |
262+ access = ref .asExpr ( ) and
263+ lbl = Label:: member ( read .getName ( ) ) and
264+ read = access .getExpr ( )
265+ |
266+ TResolved ( name ) = resolveScopeExpr ( read ) and
267+ not name .matches ( "%::%" )
268+ or
269+ name = read .getName ( ) and
270+ not exists ( resolveScopeExpr ( read ) ) and
271+ not exists ( read .getScopeExpr ( ) ) and
272+ not exists ( read .getValue ( ) )
273+ )
274+ or
286275 exists ( DataFlow:: LocalSourceNode src , DataFlow:: LocalSourceNode pred |
287276 // First, we find a predecessor of the node `ref` that we want to determine. The predecessor
288277 // is any node that is a type-tracked use of a data flow node (`src`), which is itself a
@@ -331,16 +320,7 @@ module API {
331320 * Holds if `ref` is a use of node `nd`.
332321 */
333322 cached
334- predicate use ( TApiNode nd , DataFlow:: Node ref ) {
335- exists ( string name , ExprNodes:: ConstantAccessCfgNode access , ConstantReadAccess read |
336- access = ref .asExpr ( ) and
337- nd = MkModule ( name ) and
338- read = access .getExpr ( ) and
339- TResolved ( name ) = resolveScopeExpr ( read )
340- )
341- or
342- nd = MkUse ( ref )
343- }
323+ predicate use ( TApiNode nd , DataFlow:: Node ref ) { nd = MkUse ( ref ) }
344324
345325 /**
346326 * Gets a data-flow node to which `src`, which is a use of an API-graph node, flows.
@@ -370,14 +350,6 @@ module API {
370350 */
371351 cached
372352 predicate edge ( TApiNode pred , string lbl , TApiNode succ ) {
373- /* There's an edge from the root node for each imported module. */
374- exists ( string m |
375- pred = MkRoot ( ) and
376- lbl = Label:: mod ( m )
377- |
378- succ = moduleImport ( m )
379- )
380- or
381353 /* Every node that is a use of an API component is itself added to the API graph. */
382354 exists ( DataFlow:: LocalSourceNode ref |
383355 use ( pred , lbl , ref ) and
@@ -397,11 +369,6 @@ module API {
397369}
398370
399371private module Label {
400- /** Gets the edge label for the module `m`. */
401- bindingset [ m]
402- bindingset [ result ]
403- string mod ( string m ) { result = "moduleImport(\"" + m + "\")" }
404-
405372 /** Gets the `member` edge label for member `m`. */
406373 bindingset [ m]
407374 bindingset [ result ]
0 commit comments