1+ /**
2+ * Provides support for magic methods.
3+ * This is done in two steps:
4+ * - A subset of `ControlFlowNode`s are labelled as potentially corresponding to
5+ * a magic method call (by being an instance of `MagicMethod::Potential`).
6+ * - A subset of the potential magic method calls are labelled as being actual
7+ * magic method calls (`MagicMethod::Actual`) if the appropriate method is defined.
8+ */
9+
110import python
211
12+ /**
13+ * Machinery for detecting magic method calls.
14+ * Extend `MagicMethod::Potential` to capture more cases.
15+ */
316module MagicMethod {
17+ /** A control flow node which might correpsond to a magic method call. */
418 abstract class Potential extends ControlFlowNode {
19+ /** Gets the name of the method that would be called */
520 abstract string getMagicMethodName ( ) ;
21+
22+ /** Gets the controlflow node that would be passed as the specified argument. */
623 abstract ControlFlowNode getArg ( int n ) ;
24+
25+ /** Gets the control flow node corresponding to the instance
26+ * that would define the magic method. */
727 ControlFlowNode getSelf ( ) { result = this .getArg ( 0 ) }
828 }
929
30+ /** A control flow node corresponding to a magic method call. */
1031 class Actual extends ControlFlowNode {
1132 Value resolvedMagicMethod ;
1233
@@ -17,10 +38,12 @@ module MagicMethod {
1738 )
1839 }
1940
41+ /** The method that is called. */
2042 Value getResolvedMagicMethod ( ) { result = resolvedMagicMethod }
2143 }
2244}
2345
46+ /** A binary expression node that might correspond to a magic method call. */
2447class MagicBinOp extends MagicMethod:: Potential , BinaryExprNode {
2548 Operator operator ;
2649
0 commit comments