|
1 | 1 | private import python |
2 | 2 | private import DataFlowPublic |
| 3 | +import semmle.python.Magic |
3 | 4 |
|
4 | 5 | //-------- |
5 | 6 | // Data flow graph |
@@ -157,17 +158,67 @@ class DataFlowClassValue extends DataFlowCallable, TClassValue { |
157 | 158 | override string getName() { result = c.getName() } |
158 | 159 | } |
159 | 160 |
|
160 | | -/** Represents a call to a callable */ |
161 | | -class DataFlowCall extends CallNode { |
162 | | - DataFlowCallable callable; |
| 161 | +newtype TDataFlowCall = |
| 162 | + TCallNode(CallNode call) or |
| 163 | + TMagicCall(MagicMethod::Actual magic) |
163 | 164 |
|
164 | | - DataFlowCall() { this = callable.getACall() } |
| 165 | +abstract class DataFlowCall extends TDataFlowCall { |
| 166 | + /** Gets a textual representation of this element. */ |
| 167 | + abstract string toString(); |
165 | 168 |
|
166 | 169 | /** Get the callable to which this call goes. */ |
167 | | - DataFlowCallable getCallable() { result = callable } |
| 170 | + abstract DataFlowCallable getCallable(); |
| 171 | + |
| 172 | + /** Get the specified arguemnt to this call. */ |
| 173 | + abstract ControlFlowNode getArg(int n); |
| 174 | + |
| 175 | + /** Get the control flow node representing this call. */ |
| 176 | + abstract ControlFlowNode getNode(); |
168 | 177 |
|
169 | 178 | /** Gets the enclosing callable of this call. */ |
170 | | - DataFlowCallable getEnclosingCallable() { result.getScope() = this.getNode().getScope() } |
| 179 | + abstract DataFlowCallable getEnclosingCallable(); |
| 180 | +} |
| 181 | + |
| 182 | + |
| 183 | +/** Represents a call to a callable */ |
| 184 | +class CallNodeCall extends DataFlowCall, TCallNode { |
| 185 | + CallNode call; |
| 186 | + DataFlowCallable callable; |
| 187 | + |
| 188 | + CallNodeCall() { |
| 189 | + this = TCallNode(call) and |
| 190 | + call = callable.getACall() |
| 191 | + } |
| 192 | + |
| 193 | + override string toString() { result = call.toString() } |
| 194 | + |
| 195 | + override ControlFlowNode getArg(int n) { |
| 196 | + result = call.getArg(n) |
| 197 | + } |
| 198 | + |
| 199 | + override ControlFlowNode getNode() { result = call } |
| 200 | + |
| 201 | + override DataFlowCallable getCallable() { result = callable } |
| 202 | + |
| 203 | + override DataFlowCallable getEnclosingCallable() { result.getScope() = call.getNode().getScope() } |
| 204 | +} |
| 205 | + |
| 206 | +class MagicCall extends DataFlowCall, TMagicCall { |
| 207 | + MagicMethod::Actual magic; |
| 208 | + |
| 209 | + MagicCall() { this = TMagicCall(magic) } |
| 210 | + |
| 211 | + override string toString() { result = magic.toString() } |
| 212 | + |
| 213 | + override ControlFlowNode getArg(int n) { |
| 214 | + result = magic.(MagicMethod::Potential).getArg(n) |
| 215 | + } |
| 216 | + |
| 217 | + override ControlFlowNode getNode() { result = magic } |
| 218 | + |
| 219 | + override DataFlowCallable getCallable() { result = TCallableValue(magic.getResolvedMagicMethod()) } |
| 220 | + |
| 221 | + override DataFlowCallable getEnclosingCallable() { result.getScope() = magic.getNode().getScope() } |
171 | 222 | } |
172 | 223 |
|
173 | 224 | /** A data flow node that represents a call argument. */ |
@@ -220,7 +271,7 @@ class OutNode extends CfgNode { |
220 | 271 | * `kind`. |
221 | 272 | */ |
222 | 273 | OutNode getAnOutNode(DataFlowCall call, ReturnKind kind) { |
223 | | - call = result.getNode() and |
| 274 | + call.getNode() = result.getNode() and |
224 | 275 | kind = TNormalReturnKind() |
225 | 276 | } |
226 | 277 |
|
|
0 commit comments