@@ -286,6 +286,17 @@ module API {
286286 /** Gets a node corresponding to an export of module `m`. */
287287 Node moduleExport ( string m ) { result = Impl:: MkModuleDef ( m ) .( Node ) .getMember ( "exports" ) }
288288
289+ /** Provides helper predicates for accessing API-graph nodes. */
290+ module Node {
291+ /** Gets a node whose type has the given qualified name. */
292+ Node ofType ( string moduleName , string exportedName ) {
293+ exists ( TypeName tn |
294+ tn .hasQualifiedName ( moduleName , exportedName ) and
295+ result = Impl:: MkCanonicalNameUse ( tn ) .( Node ) .getInstance ( )
296+ )
297+ }
298+ }
299+
289300 /**
290301 * An API entry point.
291302 *
@@ -301,9 +312,6 @@ module API {
301312
302313 /** Gets a data-flow node that defines this entry point. */
303314 abstract DataFlow:: Node getARhs ( ) ;
304-
305- /** Gets an API-graph node for this entry point. */
306- API:: Node getNode ( ) { result = root ( ) .getASuccessor ( this ) }
307315 }
308316
309317 /**
@@ -346,16 +354,42 @@ module API {
346354 exists ( SSA:: implicitInit ( [ nm .getModuleVariable ( ) , nm .getExportsVariable ( ) ] ) )
347355 )
348356 )
357+ or
358+ m = any ( CanonicalName n | isDefined ( n ) ) .getExternalModuleName ( )
359+ } or
360+ MkModuleImport ( string m ) {
361+ imports ( _, m )
362+ or
363+ m = any ( CanonicalName n | isUsed ( n ) ) .getExternalModuleName ( )
349364 } or
350- MkModuleImport ( string m ) { imports ( _, m ) } or
351365 MkClassInstance ( DataFlow:: ClassNode cls ) { cls = trackDefNode ( _) and hasSemantics ( cls ) } or
352366 MkAsyncFuncResult ( DataFlow:: FunctionNode f ) {
353367 f = trackDefNode ( _) and f .getFunction ( ) .isAsync ( ) and hasSemantics ( f )
354368 } or
355369 MkDef ( DataFlow:: Node nd ) { rhs ( _, _, nd ) } or
356370 MkUse ( DataFlow:: Node nd ) { use ( _, _, nd ) } or
357- MkCanonicalNameDef ( CanonicalName n ) { isDefined ( n ) } or
358- MkCanonicalNameUse ( CanonicalName n ) { isUsed ( n ) }
371+ /**
372+ * A TypeScript canonical name that is defined somewhere, and that isn't a module root.
373+ * (Module roots are represented by `MkModuleExport` nodes instead.)
374+ *
375+ * For most purposes, you probably want to use the `mkCanonicalNameDef` predicate instead of
376+ * this constructor.
377+ */
378+ MkCanonicalNameDef ( CanonicalName n ) {
379+ not n .isRoot ( ) and
380+ isDefined ( n )
381+ } or
382+ /**
383+ * A TypeScript canonical name that is used somewhere, and that isn't a module root.
384+ * (Module roots are represented by `MkModuleImport` nodes instead.)
385+ *
386+ * For most purposes, you probably want to use the `mkCanonicalNameUse` predicate instead of
387+ * this constructor.
388+ */
389+ MkCanonicalNameUse ( CanonicalName n ) {
390+ not n .isRoot ( ) and
391+ isUsed ( n )
392+ }
359393
360394 class TDef = MkModuleDef or TNonModuleDef ;
361395
@@ -399,6 +433,20 @@ module API {
399433 )
400434 }
401435
436+ /** An API-graph node representing definitions of the canonical name `cn`. */
437+ private TApiNode mkCanonicalNameDef ( CanonicalName cn ) {
438+ if cn .isModuleRoot ( )
439+ then result = MkModuleExport ( cn .getExternalModuleName ( ) )
440+ else result = MkCanonicalNameDef ( cn )
441+ }
442+
443+ /** An API-graph node representing uses of the canonical name `cn`. */
444+ private TApiNode mkCanonicalNameUse ( CanonicalName cn ) {
445+ if cn .isModuleRoot ( )
446+ then result = MkModuleImport ( cn .getExternalModuleName ( ) )
447+ else result = MkCanonicalNameUse ( cn )
448+ }
449+
402450 /**
403451 * Holds if `rhs` is the right-hand side of a definition of a node that should have an
404452 * incoming edge from `base` labeled `lbl` in the API graph.
@@ -713,20 +761,11 @@ module API {
713761 succ = MkClassInstance ( trackDefNode ( def ) )
714762 )
715763 or
716- exists ( CanonicalName cn |
717- pred = MkRoot ( ) and
718- lbl = Label:: mod ( cn .getExternalModuleName ( ) )
719- |
720- succ = MkCanonicalNameUse ( cn ) or
721- succ = MkCanonicalNameDef ( cn )
722- )
723- or
724- exists ( CanonicalName cn1 , CanonicalName cn2 |
725- cn2 = cn1 .getAChild ( ) and
726- lbl = Label:: member ( cn2 .getName ( ) )
727- |
728- ( pred = MkCanonicalNameDef ( cn1 ) or pred = MkCanonicalNameUse ( cn1 ) ) and
729- ( succ = MkCanonicalNameDef ( cn2 ) or succ = MkCanonicalNameUse ( cn2 ) )
764+ exists ( CanonicalName cn1 , string n , CanonicalName cn2 |
765+ pred in [ mkCanonicalNameDef ( cn1 ) , mkCanonicalNameUse ( cn1 ) ] and
766+ cn2 = cn1 .getChild ( n ) and
767+ lbl = Label:: member ( n ) and
768+ succ in [ mkCanonicalNameDef ( cn2 ) , mkCanonicalNameUse ( cn2 ) ]
730769 )
731770 or
732771 exists ( DataFlow:: Node nd , DataFlow:: FunctionNode f |
0 commit comments