@@ -11,29 +11,64 @@ private import semmle.python.essa.SsaCompute
1111//--------
1212predicate isExpressionNode ( ControlFlowNode node ) { node .getNode ( ) instanceof Expr }
1313
14- /** A data flow node for which we should synthesise an associated pre-update node. */
15- abstract class NeedsSyntheticPreUpdateNode extends Node {
16- /** A label for this kind of node. This will figure in the textual representation of the synthesized pre-update node. */
17- abstract string label ( ) ;
18- }
14+ /** A module collecting the different reasons for synthesising a pre-update node. */
15+ module syntheticPreUpdateNode {
16+ class SyntheticPreUpdateNode extends Node , TSyntheticPreUpdateNode {
17+ NeedsSyntheticPreUpdateNode post ;
18+
19+ SyntheticPreUpdateNode ( ) { this = TSyntheticPreUpdateNode ( post ) }
20+
21+ /** Gets the node for which this is a synthetic pre-update node. */
22+ Node getPostUpdateNode ( ) { result = post }
23+
24+ override string toString ( ) { result = "[pre " + post .label ( ) + "] " + post .toString ( ) }
1925
20- class SyntheticPreUpdateNode extends Node , TSyntheticPreUpdateNode {
21- NeedsSyntheticPreUpdateNode post ;
26+ override Scope getScope ( ) { result = post .getScope ( ) }
2227
23- SyntheticPreUpdateNode ( ) { this = TSyntheticPreUpdateNode ( post ) }
28+ override Location getLocation ( ) { result = post .getLocation ( ) }
29+ }
2430
25- /** Gets the node for which this is a synthetic pre-update node. */
26- Node getPostUpdateNode ( ) { result = post }
31+ /** A data flow node for which we should synthesise an associated pre-update node. */
32+ class NeedsSyntheticPreUpdateNode extends PostUpdateNode {
33+ NeedsSyntheticPreUpdateNode ( ) { this = objectCreationNode ( ) }
2734
28- override string toString ( ) { result = "[pre " + post . label ( ) + "] " + post . toString ( ) }
35+ override Node getPreUpdateNode ( ) { result . ( SyntheticPreUpdateNode ) . getPostUpdateNode ( ) = this }
2936
30- override Scope getScope ( ) { result = post .getScope ( ) }
37+ /**
38+ * A label for this kind of node. This will figure in the textual representation of the synthesized pre-update node.
39+ *
40+ * There is currently only one reason for needing a pre-update node, so we always use that as the label.
41+ */
42+ string label ( ) { result = "objCreate" }
43+ }
3144
32- override Location getLocation ( ) { result = post .getLocation ( ) }
45+ /**
46+ * Calls to constructors are treated as post-update nodes for the synthesized argument
47+ * that is mapped to the `self` parameter. That way, constructor calls represent the value of the
48+ * object after the constructor (currently only `__init__`) has run.
49+ */
50+ CfgNode objectCreationNode ( ) { result .getNode ( ) .( CallNode ) = any ( ClassCall c ) .getNode ( ) }
3351}
3452
53+ import syntheticPreUpdateNode
54+
3555/** A module collecting the different reasons for synthesising a post-update node. */
36- module needsSyntheticPostUpdateNode {
56+ module syntheticPostUpdateNode {
57+ /** A post-update node is synthesized for all nodes which satisfy `NeedsSyntheticPostUpdateNode`. */
58+ class SyntheticPostUpdateNode extends PostUpdateNode , TSyntheticPostUpdateNode {
59+ NeedsSyntheticPostUpdateNode pre ;
60+
61+ SyntheticPostUpdateNode ( ) { this = TSyntheticPostUpdateNode ( pre ) }
62+
63+ override Node getPreUpdateNode ( ) { result = pre }
64+
65+ override string toString ( ) { result = "[post " + pre .label ( ) + "] " + pre .toString ( ) }
66+
67+ override Scope getScope ( ) { result = pre .getScope ( ) }
68+
69+ override Location getLocation ( ) { result = pre .getLocation ( ) }
70+ }
71+
3772 /** A data flow node for which we should synthesise an associated post-update node. */
3873 class NeedsSyntheticPostUpdateNode extends Node {
3974 NeedsSyntheticPostUpdateNode ( ) {
@@ -107,35 +142,7 @@ module needsSyntheticPostUpdateNode {
107142 }
108143}
109144
110- import needsSyntheticPostUpdateNode
111-
112- /** A post-update node is synthesized for all nodes which satisfy `NeedsSyntheticPostUpdateNode`. */
113- class SyntheticPostUpdateNode extends PostUpdateNode , TSyntheticPostUpdateNode {
114- NeedsSyntheticPostUpdateNode pre ;
115-
116- SyntheticPostUpdateNode ( ) { this = TSyntheticPostUpdateNode ( pre ) }
117-
118- override Node getPreUpdateNode ( ) { result = pre }
119-
120- override string toString ( ) { result = "[post " + pre .label ( ) + "] " + pre .toString ( ) }
121-
122- override Scope getScope ( ) { result = pre .getScope ( ) }
123-
124- override Location getLocation ( ) { result = pre .getLocation ( ) }
125- }
126-
127- /**
128- * Calls to constructors are treated as post-update nodes for the synthesized argument
129- * that is mapped to the `self` parameter. That way, constructor calls represent the value of the
130- * object after the constructor (currently only `__init__`) has run.
131- */
132- class ObjectCreationNode extends PostUpdateNode , NeedsSyntheticPreUpdateNode , CfgNode {
133- ObjectCreationNode ( ) { node .( CallNode ) = any ( ClassCall c ) .getNode ( ) }
134-
135- override Node getPreUpdateNode ( ) { result .( SyntheticPreUpdateNode ) .getPostUpdateNode ( ) = this }
136-
137- override string label ( ) { result = "objCreate" }
138- }
145+ import syntheticPostUpdateNode
139146
140147class DataFlowExpr = Expr ;
141148
0 commit comments