@@ -390,7 +390,15 @@ class CastNode extends DataFlow::Node {
390390cached
391391newtype TDataFlowCallable =
392392 MkSourceCallable ( StmtContainer container ) or
393- MkLibraryCallable ( LibraryCallable callable )
393+ MkLibraryCallable ( LibraryCallable callable ) or
394+ MkClassHarnessCallable ( Function f ) {
395+ // We only need a class harness for functions that act as classes (i.e. constructors),
396+ // but since DataFlow::Node has not been materialised at this stage, we can't use DataFlow::ClassNode.
397+ // Exclude arrow functions as they can't be called with 'new'.
398+ not f instanceof ArrowFunctionExpr and
399+ // We also don't need harnesses for externs
400+ not f .getTopLevel ( ) .isExterns ( )
401+ }
394402
395403/**
396404 * A callable entity. This is a wrapper around either a `StmtContainer` or a `LibraryCallable`.
@@ -401,14 +409,21 @@ class DataFlowCallable extends TDataFlowCallable {
401409 result = this .asSourceCallable ( ) .toString ( )
402410 or
403411 result = this .asLibraryCallable ( )
412+ or
413+ result = this .asClassHarness ( ) .toString ( )
404414 }
405415
406416 /** Gets the location of this callable, if it is present in the source code. */
407- Location getLocation ( ) { result = this .asSourceCallable ( ) .getLocation ( ) }
417+ Location getLocation ( ) {
418+ result = this .asSourceCallable ( ) .getLocation ( ) or result = this .asClassHarness ( ) .getLocation ( )
419+ }
408420
409421 /** Gets the corresponding `StmtContainer` if this is a source callable. */
410422 StmtContainer asSourceCallable ( ) { this = MkSourceCallable ( result ) }
411423
424+ /** Gets the class constructor for which this is a class harness. */
425+ Function asClassHarness ( ) { this = MkClassHarnessCallable ( result ) }
426+
412427 /** Gets the corresponding `StmtContainer` if this is a source callable. */
413428 pragma [ nomagic]
414429 StmtContainer asSourceCallableNotExterns ( ) {
0 commit comments