@@ -642,16 +642,23 @@ class ClassNode extends DataFlow::SourceNode {
642642 */
643643 FunctionNode getAStaticMethod ( ) { result = impl .getAStaticMethod ( ) }
644644
645+ /**
646+ * Gets a dataflow node that refers to the superclass of this class.
647+ */
648+ DataFlow:: Node getASuperClassNode ( ) { result = impl .getASuperClassNode ( ) }
649+
645650 /**
646651 * Gets a direct super class of this class.
647652 */
648653 ClassNode getADirectSuperClass ( ) {
649- result .getConstructor ( ) .getAstNode ( ) = impl
650- .getASuperClassNode ( )
651- .analyze ( )
652- .getAValue ( )
653- .( AbstractCallable )
654- .getFunction ( )
654+ result .getAClassReference ( ) .flowsTo ( getASuperClassNode ( ) )
655+ }
656+
657+ /**
658+ * Gets a direct subclass of this class.
659+ */
660+ final ClassNode getADirectSubClass ( ) {
661+ this = result .getADirectSuperClass ( )
655662 }
656663
657664 /**
@@ -662,6 +669,63 @@ class ClassNode extends DataFlow::SourceNode {
662669 or
663670 result = getAnInstanceMember ( ) .getReceiver ( )
664671 }
672+
673+ /**
674+ * Gets the abstract value representing the class itself.
675+ */
676+ AbstractValue getAbstractClassValue ( ) {
677+ result = this .( AnalyzedNode ) .getAValue ( )
678+ }
679+
680+ /**
681+ * Gets the abstract value representing an instance of this class.
682+ */
683+ AbstractValue getAbstractInstanceValue ( ) {
684+ result = AbstractInstance:: of ( getAstNode ( ) )
685+ }
686+
687+ /**
688+ * Gets a dataflow node that refers to this class object.
689+ */
690+ private DataFlow:: SourceNode getAClassReference ( DataFlow:: TypeTracker t ) {
691+ t .start ( ) and
692+ result .( AnalyzedNode ) .getAValue ( ) = getAbstractClassValue ( )
693+ or
694+ exists ( DataFlow:: TypeTracker t2 |
695+ result = getAClassReference ( t2 ) .track ( t2 , t )
696+ )
697+ }
698+
699+ /**
700+ * Gets a dataflow node that refers to this class object.
701+ */
702+ DataFlow:: SourceNode getAClassReference ( ) {
703+ result = getAClassReference ( DataFlow:: TypeTracker:: end ( ) )
704+ }
705+
706+ /**
707+ * Gets a dataflow node that refers to an instance of this class.
708+ */
709+ private DataFlow:: SourceNode getAnInstanceReference ( DataFlow:: TypeTracker t ) {
710+ result = getAClassReference ( t .continue ( ) ) .getAnInstantiation ( )
711+ or
712+ t .start ( ) and
713+ result .( AnalyzedNode ) .getAValue ( ) = getAbstractInstanceValue ( )
714+ or
715+ t .start ( ) and
716+ result = getAReceiverNode ( )
717+ or
718+ exists ( DataFlow:: TypeTracker t2 |
719+ result = getAnInstanceReference ( t2 ) .track ( t2 , t )
720+ )
721+ }
722+
723+ /**
724+ * Gets a dataflow node that refers to an instance of this class.
725+ */
726+ DataFlow:: SourceNode getAnInstanceReference ( ) {
727+ result = getAnInstanceReference ( DataFlow:: TypeTracker:: end ( ) )
728+ }
665729}
666730
667731module ClassNode {
@@ -803,6 +867,9 @@ module ClassNode {
803867 kind = MemberKind:: method ( ) and
804868 result = getAPrototypeReference ( ) .getAPropertySource ( name )
805869 or
870+ kind = MemberKind:: method ( ) and
871+ result = getConstructor ( ) .getReceiver ( ) .getAPropertyWrite ( name ) .getRhs ( ) .getALocalSource ( )
872+ or
806873 exists ( PropertyAccessor accessor |
807874 accessor = getAnAccessor ( kind ) and
808875 accessor .getName ( ) = name and
@@ -814,6 +881,9 @@ module ClassNode {
814881 kind = MemberKind:: method ( ) and
815882 result = getAPrototypeReference ( ) .getAPropertyWrite ( ) .getRhs ( ) .getALocalSource ( )
816883 or
884+ kind = MemberKind:: method ( ) and
885+ result = getConstructor ( ) .getReceiver ( ) .getAPropertyWrite ( ) .getRhs ( ) .getALocalSource ( )
886+ or
817887 exists ( PropertyAccessor accessor |
818888 accessor = getAnAccessor ( kind ) and
819889 result = accessor .getInit ( ) .flow ( )
0 commit comments