@@ -241,15 +241,23 @@ module API {
241241 }
242242
243243 /**
244- * Gets a node representing an instance of this API component, that is, an object whose
245- * constructor is the function represented by this node .
244+ * Gets a node representing an instance of the class represented by this node.
245+ * This includes instances of subclasses .
246246 *
247- * For example, if this node represents a use of some class `A`, then there might be a node
248- * representing instances of `A`, typically corresponding to expressions `new A()` at the
249- * source level.
247+ * For example:
248+ * ```js
249+ * import { C } from "foo";
250+ *
251+ * new C(); // API::moduleImport("foo").getMember("C").getInstance()
252+ *
253+ * class D extends C {
254+ * m() {
255+ * this; // API::moduleImport("foo").getMember("C").getInstance()
256+ * }
257+ * }
250258 *
251- * This predicate may have multiple results when there are multiple constructor calls invoking this API component.
252- * Consider using `getAnInstantiation()` if there is a need to distinguish between individual constructor calls.
259+ * new D(); // API::moduleImport("foo").getMember("C").getInstance()
260+ * ```
253261 */
254262 cached
255263 Node getInstance ( ) {
@@ -891,6 +899,17 @@ module API {
891899 ( propDesc = Promises:: errorProp ( ) or propDesc = "" )
892900 }
893901
902+ pragma [ nomagic]
903+ private DataFlow:: ClassNode getALocalSubclass ( DataFlow:: SourceNode node ) {
904+ result .getASuperClassNode ( ) .getALocalSource ( ) = node
905+ }
906+
907+ bindingset [ node]
908+ pragma [ inline_late]
909+ private DataFlow:: ClassNode getALocalSubclassFwd ( DataFlow:: SourceNode node ) {
910+ result = getALocalSubclass ( node )
911+ }
912+
894913 /**
895914 * Holds if `ref` is a use of a node that should have an incoming edge from `base` labeled
896915 * `lbl` in the API graph.
@@ -927,6 +946,15 @@ module API {
927946 or
928947 lbl = Label:: forwardingFunction ( ) and
929948 DataFlow:: functionForwardingStep ( pred .getALocalUse ( ) , ref )
949+ or
950+ exists ( DataFlow:: ClassNode cls |
951+ lbl = Label:: instance ( ) and
952+ cls = getALocalSubclassFwd ( pred ) .getADirectSubClass * ( )
953+ |
954+ ref = cls .getAReceiverNode ( )
955+ or
956+ ref = cls .getAClassReference ( ) .getAnInstantiation ( )
957+ )
930958 )
931959 or
932960 exists ( DataFlow:: Node def , DataFlow:: FunctionNode fn |
0 commit comments