@@ -373,7 +373,15 @@ cached
373373newtype TDataFlowCallable =
374374 MkSourceCallable ( StmtContainer container ) or
375375 MkLibraryCallable ( LibraryCallable callable ) or
376- MkFileCallable ( File file )
376+ MkFileCallable ( File file ) or
377+ MkClassHarnessCallable ( Function f ) {
378+ // We only need a class harness for functions that act as classes (i.e. constructors),
379+ // but since DataFlow::Node has not been materialised at this stage, we can't use DataFlow::ClassNode.
380+ // Exclude arrow functions as they can't be called with 'new'.
381+ not f instanceof ArrowFunctionExpr and
382+ // We also don't need harnesses for externs
383+ not f .getTopLevel ( ) .isExterns ( )
384+ }
377385
378386/**
379387 * A callable entity. This is a wrapper around either a `StmtContainer`, `LibraryCallable`, or `File`.
@@ -383,14 +391,20 @@ class DataFlowCallable extends TDataFlowCallable {
383391 string toString ( ) {
384392 result = this .asSourceCallable ( ) .toString ( )
385393 or
386- result = this .asLibraryCallable ( )
394+ result = this .asLibraryCallable ( ) . toString ( )
387395 or
388396 result = this .asFileCallable ( ) .toString ( )
397+ or
398+ result = this .asClassHarness ( ) .toString ( )
389399 }
390400
391401 /** Gets the location of this callable, if it is present in the source code. */
392402 Location getLocation ( ) {
393- result = this .asSourceCallable ( ) .getLocation ( ) or result = this .asFileCallable ( ) .getLocation ( )
403+ result = this .asSourceCallable ( ) .getLocation ( )
404+ or
405+ result = this .asFileCallable ( ) .getLocation ( )
406+ or
407+ result = this .asClassHarness ( ) .getLocation ( )
394408 }
395409
396410 /** Gets the corresponding `StmtContainer` if this is a source callable. */
@@ -399,6 +413,9 @@ class DataFlowCallable extends TDataFlowCallable {
399413 /** Gets the corresponding `File` if this is a file representing a callable. */
400414 File asFileCallable ( ) { this = MkFileCallable ( result ) }
401415
416+ /** Gets the class constructor for which this is a class harness. */
417+ Function asClassHarness ( ) { this = MkClassHarnessCallable ( result ) }
418+
402419 /** Gets the corresponding `StmtContainer` if this is a source callable. */
403420 pragma [ nomagic]
404421 StmtContainer asSourceCallableNotExterns ( ) {
0 commit comments