@@ -92,6 +92,11 @@ module API {
9292 */
9393 Node getReturn ( ) { result = getASuccessor ( Label:: return ( ) ) }
9494
95+ /**
96+ * Gets a node representing a subclass of the class represented by this node.
97+ */
98+ Node getASubclass ( ) { result = getASuccessor ( Label:: subclass ( ) ) }
99+
95100 /**
96101 * Gets a string representation of the lexicographically least among all shortest access paths
97102 * from the root to this node.
@@ -312,12 +317,11 @@ module API {
312317 * For instance, `prefix_member("foo.bar", "baz", "foo.bar.baz")` would hold.
313318 */
314319 private predicate prefix_member ( TApiNode base , string member , TApiNode sub ) {
315- exists ( string base_str , string sub_str |
316- base = MkModuleImport ( base_str ) and
320+ exists ( string sub_str , string regexp |
321+ regexp = "(.+)[.]([^.]+)" and
322+ base = MkModuleImport ( sub_str .regexpCapture ( regexp , 1 ) ) and
323+ member = sub_str .regexpCapture ( regexp , 2 ) and
317324 sub = MkModuleImport ( sub_str )
318- |
319- base_str + "." + member = sub_str and
320- not member .matches ( "%.%" )
321325 )
322326 }
323327
@@ -351,13 +355,19 @@ module API {
351355 // the relationship between `pred` and `ref`.
352356 use ( base , src ) and pred = trackUseNode ( src )
353357 |
354- // Reading an attribute on a node that is a use of `base`:
358+ // Referring to an attribute on a node that is a use of `base`:
355359 lbl = Label:: memberFromRef ( ref ) and
356- ref = pred .getAnAttributeRead ( )
360+ ref = pred .getAnAttributeReference ( )
357361 or
358362 // Calling a node that is a use of `base`
359363 lbl = Label:: return ( ) and
360364 ref = pred .getACall ( )
365+ or
366+ // Subclassing a node
367+ lbl = Label:: subclass ( ) and
368+ exists ( DataFlow:: Node superclass | pred .flowsTo ( superclass ) |
369+ ref .asExpr ( ) .( ClassExpr ) .getABase ( ) = superclass .asExpr ( )
370+ )
361371 )
362372 }
363373
@@ -468,4 +478,6 @@ private module Label {
468478
469479 /** Gets the `return` edge label. */
470480 string return ( ) { result = "getReturn()" }
481+
482+ string subclass ( ) { result = "getASubclass()" }
471483}
0 commit comments