@@ -390,7 +390,15 @@ class CastNode extends DataFlow::Node {
390
390
cached
391
391
newtype TDataFlowCallable =
392
392
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
+ }
394
402
395
403
/**
396
404
* A callable entity. This is a wrapper around either a `StmtContainer` or a `LibraryCallable`.
@@ -401,14 +409,21 @@ class DataFlowCallable extends TDataFlowCallable {
401
409
result = this .asSourceCallable ( ) .toString ( )
402
410
or
403
411
result = this .asLibraryCallable ( )
412
+ or
413
+ result = this .asClassHarness ( ) .toString ( )
404
414
}
405
415
406
416
/** 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
+ }
408
420
409
421
/** Gets the corresponding `StmtContainer` if this is a source callable. */
410
422
StmtContainer asSourceCallable ( ) { this = MkSourceCallable ( result ) }
411
423
424
+ /** Gets the class constructor for which this is a class harness. */
425
+ Function asClassHarness ( ) { this = MkClassHarnessCallable ( result ) }
426
+
412
427
/** Gets the corresponding `StmtContainer` if this is a source callable. */
413
428
pragma [ nomagic]
414
429
StmtContainer asSourceCallableNotExterns ( ) {
0 commit comments