@@ -37,6 +37,16 @@ predicate hasSubtype(RefType t, Type sub) {
3737 typeVarSubtypeBound ( t , sub ) and t != sub
3838}
3939
40+ /**
41+ * Holds if reference type `anc` is a direct or indirect supertype of `sub`, including itself.
42+ */
43+ cached
44+ predicate hasDescendant ( RefType anc , Type sub ) {
45+ anc = sub
46+ or
47+ exists ( RefType mid | hasSubtype ( anc , mid ) and hasDescendant ( mid , sub ) )
48+ }
49+
4050private predicate typeVarSubtypeBound ( RefType t , TypeVariable tv ) {
4151 if tv .hasTypeBound ( ) then t = tv .getATypeBound ( ) .getType ( ) else t instanceof TypeObject
4252}
@@ -394,11 +404,17 @@ class RefType extends Type, Annotatable, Modifiable, @reftype {
394404 /** Gets a direct subtype of this type. */
395405 RefType getASubtype ( ) { hasSubtype ( this , result ) }
396406
407+ /** Gets a direct or indirect descendant of this type, including itself. */
408+ RefType getADescendant ( ) { hasDescendant ( this , result ) }
409+
397410 /** Gets a direct supertype of this type. */
398411 RefType getASupertype ( ) { hasSubtype ( result , this ) }
399412
400413 /** Gets a direct or indirect supertype of this type, including itself. */
401- RefType getAnAncestor ( ) { hasSubtype * ( result , this ) }
414+ RefType getAnAncestor ( ) { hasDescendant ( result , this ) }
415+
416+ /** Gets a direct or indirect supertype of this type, not including itself. */
417+ RefType getAStrictAncestor ( ) { result = this .getAnAncestor ( ) and result != this }
402418
403419 /**
404420 * Gets the source declaration of a direct supertype of this type, excluding itself.
0 commit comments