@@ -502,7 +502,7 @@ class ClassNode extends DataFlow::SourceNode {
502502 /**
503503 * Gets a description of the class.
504504 */
505- string desribe ( ) { result = impl .describe ( ) }
505+ string describe ( ) { result = impl .describe ( ) }
506506
507507 /**
508508 * Gets the constructor function of this class.
@@ -535,79 +535,88 @@ class ClassNode extends DataFlow::SourceNode {
535535}
536536
537537module ClassNode {
538- class Range extends DataFlow:: SourceNode , DataFlow:: ValueNode {
539- Range ( ) {
540- astNode instanceof ClassDefinition
541- or
542- astNode instanceof Function and
543- exists ( getAPropertyReference ( "prototype" ) )
544- }
545-
538+ /**
539+ * A dataflow node that should be considered a class node.
540+ *
541+ * Subclass this to introduce new kinds of class nodes. If you want to refine
542+ * the definition of existing class nodes, subclass `DataFlow::ClassNode` instead.
543+ */
544+ abstract class Range extends DataFlow:: SourceNode {
546545 /**
547546 * Gets the name of the class, if it has one.
548547 */
549- string getName ( ) {
550- result = astNode .( ClassDefinition ) .getName ( )
551- or
552- result = astNode .( Function ) .getName ( )
553- }
548+ abstract string getName ( ) ;
554549
555550 /**
556551 * Gets a description of the class.
557552 */
558- string describe ( ) {
559- result = astNode .( ClassDefinition ) .describe ( )
560- or
561- result = astNode .( Function ) .describe ( )
562- }
553+ abstract string describe ( ) ;
563554
564555 /**
565556 * Gets the constructor function of this class.
566557 */
567- FunctionNode getConstructor ( ) {
568- result = astNode .( ClassDefinition ) .getConstructor ( ) .getBody ( ) .flow ( )
569- or
570- result = this
571- }
558+ abstract FunctionNode getConstructor ( ) ;
572559
573560 /**
574561 * Gets an instance method with the given name, if any.
575562 */
576- FunctionNode getInstanceMethod ( string name ) {
563+ abstract FunctionNode getInstanceMethod ( string name ) ;
564+
565+ /**
566+ * Gets an instance method of this class.
567+ *
568+ * The constructor is not considered an instance method.
569+ */
570+ abstract FunctionNode getAnInstanceMethod ( ) ;
571+
572+ /**
573+ * Gets the static method of this class with the given name.
574+ */
575+ abstract FunctionNode getStaticMethod ( string name ) ;
576+
577+ /**
578+ * Gets a static method of this class.
579+ *
580+ * The constructor is not considered a static method.
581+ */
582+ abstract FunctionNode getAStaticMethod ( ) ;
583+ }
584+
585+ /**
586+ * An ES6 class as a `ClassNode` instance.
587+ */
588+ private class ES6Class extends Range , DataFlow:: ValueNode {
589+ override ClassDefinition astNode ;
590+
591+ override string getName ( ) { result = astNode .getName ( ) }
592+
593+ override string describe ( ) { result = astNode .describe ( ) }
594+
595+ override FunctionNode getConstructor ( ) { result = astNode .getConstructor ( ) .getBody ( ) .flow ( ) }
596+
597+ override FunctionNode getInstanceMethod ( string name ) {
577598 exists ( MethodDeclaration method |
578- method = astNode .( ClassDefinition ) . getMethod ( name ) and
599+ method = astNode .getMethod ( name ) and
579600 not method .isStatic ( ) and
580601 not method .isAmbient ( ) and
581602 not method instanceof ConstructorDeclaration and
582603 result = method .getBody ( ) .flow ( )
583604 )
584- or
585- result = getAPrototypeReference ( ) .getAPropertyWrite ( name ) .getRhs ( ) .getALocalSource ( )
586605 }
587606
588- /**
589- * Gets an instance method of this class.
590- *
591- * The constructor is not considered an instance method.
592- */
593- FunctionNode getAnInstanceMethod ( ) {
607+ override FunctionNode getAnInstanceMethod ( ) {
594608 exists ( MethodDeclaration method |
595- method = astNode .( ClassDefinition ) . getAMethod ( ) and
609+ method = astNode .getAMethod ( ) and
596610 not method .isStatic ( ) and
597611 not method .isAmbient ( ) and
598612 not method instanceof ConstructorDeclaration and
599613 result = method .getBody ( ) .flow ( )
600614 )
601- or
602- result = getAPrototypeReference ( ) .getAPropertyWrite ( ) .getRhs ( ) .getALocalSource ( )
603615 }
604616
605- /**
606- * Gets the static method of this class with the given name.
607- */
608- FunctionNode getStaticMethod ( string name ) {
617+ override FunctionNode getStaticMethod ( string name ) {
609618 exists ( MethodDeclaration method |
610- method = astNode .( ClassDefinition ) . getMethod ( name ) and
619+ method = astNode .getMethod ( name ) and
611620 method .isStatic ( ) and
612621 not method .isAmbient ( ) and
613622 result = method .getBody ( ) .flow ( )
@@ -616,19 +625,43 @@ module ClassNode {
616625 result = getAPropertyWrite ( name ) .getRhs ( ) .getALocalSource ( )
617626 }
618627
619- /**
620- * Gets a static method of this class.
621- *
622- * The constructor is not considered a static method.
623- */
624- FunctionNode getAStaticMethod ( ) {
628+ override FunctionNode getAStaticMethod ( ) {
625629 exists ( MethodDeclaration method |
626630 method = astNode .( ClassDefinition ) .getAMethod ( ) and
627631 method .isStatic ( ) and
628632 not method .isAmbient ( ) and
629633 result = method .getBody ( ) .flow ( )
630634 )
631- or
635+ }
636+ }
637+
638+ /**
639+ * A function definition with prototype manipulation as a `ClassNode` instance.
640+ */
641+ class FunctionStyleClass extends Range , DataFlow:: ValueNode {
642+ override Function astNode ;
643+
644+ FunctionStyleClass ( ) { exists ( getAPropertyReference ( "prototype" ) ) }
645+
646+ override string getName ( ) { result = astNode .getName ( ) }
647+
648+ override string describe ( ) { result = astNode .describe ( ) }
649+
650+ override FunctionNode getConstructor ( ) { result = this }
651+
652+ override FunctionNode getInstanceMethod ( string name ) {
653+ result = getAPrototypeReference ( ) .getAPropertyWrite ( name ) .getRhs ( ) .getALocalSource ( )
654+ }
655+
656+ override FunctionNode getAnInstanceMethod ( ) {
657+ result = getAPrototypeReference ( ) .getAPropertyWrite ( ) .getRhs ( ) .getALocalSource ( )
658+ }
659+
660+ override FunctionNode getStaticMethod ( string name ) {
661+ result = getAPropertyWrite ( name ) .getRhs ( ) .getALocalSource ( )
662+ }
663+
664+ override FunctionNode getAStaticMethod ( ) {
632665 result = getAPropertyWrite ( ) .getRhs ( ) .getALocalSource ( )
633666 }
634667
0 commit comments