@@ -950,7 +950,7 @@ private module MethodCalls {
950
950
)
951
951
}
952
952
953
- predicate resolveMethodCall ( ControlFlowNode call , Function target , CallType type , Node self ) {
953
+ predicate resolveMethodCall ( CallNode call , Function target , CallType type , Node self ) {
954
954
(
955
955
directCall ( call , target , _, _, _, self )
956
956
or
@@ -1046,11 +1046,11 @@ predicate resolveClassInstanceCall(CallNode call, Function target, Node self) {
1046
1046
* Holds if `call` is a call to the `target`, with call-type `type`.
1047
1047
*/
1048
1048
cached
1049
- predicate resolveCall ( ControlFlowNode call , Function target , CallType type ) {
1049
+ predicate resolveCall ( CallNode call , Function target , CallType type ) {
1050
1050
Stages:: DataFlow:: ref ( ) and
1051
1051
(
1052
1052
type instanceof CallTypePlainFunction and
1053
- call .( CallNode ) . getFunction ( ) = functionTracker ( target ) .asCfgNode ( ) and
1053
+ call .getFunction ( ) = functionTracker ( target ) .asCfgNode ( ) and
1054
1054
not exists ( Class cls | cls .getAMethod ( ) = target )
1055
1055
or
1056
1056
resolveMethodCall ( call , target , type , _)
@@ -1128,83 +1128,77 @@ predicate normalCallArg(CallNode call, Node arg, ArgumentPosition apos) {
1128
1128
* sending both `self` arguments to that function, which is by definition the right thing to do.
1129
1129
*/
1130
1130
cached
1131
- predicate getCallArg (
1132
- ControlFlowNode call , Function target , CallType type , Node arg , ArgumentPosition apos
1133
- ) {
1131
+ predicate getCallArg ( CallNode call , Function target , CallType type , Node arg , ArgumentPosition apos ) {
1134
1132
Stages:: DataFlow:: ref ( ) and
1133
+ resolveCall ( call , target , type ) and
1135
1134
(
1136
- // normal calls with a real call node
1137
- resolveCall ( call , target , type ) and
1138
- call instanceof CallNode and
1135
+ type instanceof CallTypePlainFunction and
1136
+ normalCallArg ( call , arg , apos )
1137
+ or
1138
+ // self argument for normal method calls
1139
+ type instanceof CallTypeNormalMethod and
1140
+ apos .isSelf ( ) and
1141
+ resolveMethodCall ( call , target , type , arg ) and
1142
+ // dataflow lib has requirement that arguments and calls are in same enclosing callable.
1143
+ exists ( CfgNode cfgNode | cfgNode .getNode ( ) = call |
1144
+ cfgNode .getEnclosingCallable ( ) = arg .getEnclosingCallable ( )
1145
+ )
1146
+ or
1147
+ // cls argument for classmethod calls
1148
+ type instanceof CallTypeClassMethod and
1149
+ apos .isSelf ( ) and
1150
+ resolveMethodCall ( call , target , type , arg ) and
1151
+ ( arg = classTracker ( _) or arg = clsArgumentTracker ( _) ) and
1152
+ // dataflow lib has requirement that arguments and calls are in same enclosing callable.
1153
+ exists ( CfgNode cfgNode | cfgNode .getNode ( ) = call |
1154
+ cfgNode .getEnclosingCallable ( ) = arg .getEnclosingCallable ( )
1155
+ )
1156
+ or
1157
+ // normal arguments for method calls
1139
1158
(
1140
- type instanceof CallTypePlainFunction and
1141
- normalCallArg ( call , arg , apos )
1159
+ type instanceof CallTypeNormalMethod or
1160
+ type instanceof CallTypeStaticMethod or
1161
+ type instanceof CallTypeClassMethod
1162
+ ) and
1163
+ normalCallArg ( call , arg , apos )
1164
+ or
1165
+ // method as plain function call.
1166
+ //
1167
+ // argument index 0 of call has position self (and MUST be given as positional
1168
+ // argument in call). This also means that call-arguments are shifted by 1, such
1169
+ // that argument index 1 of call has argument position 0
1170
+ type instanceof CallTypeMethodAsPlainFunction and
1171
+ (
1172
+ apos .isSelf ( ) and arg .asCfgNode ( ) = call .( CallNode ) .getArg ( 0 )
1142
1173
or
1143
- // self argument for normal method calls
1144
- type instanceof CallTypeNormalMethod and
1145
- apos .isSelf ( ) and
1146
- resolveMethodCall ( call , target , type , arg ) and
1147
- // dataflow lib has requirement that arguments and calls are in same enclosing callable.
1148
- exists ( CfgNode cfgNode | cfgNode .getNode ( ) = call |
1149
- cfgNode .getEnclosingCallable ( ) = arg .getEnclosingCallable ( )
1150
- )
1174
+ not apos .isPositional ( _) and normalCallArg ( call , arg , apos )
1151
1175
or
1152
- // cls argument for classmethod calls
1153
- type instanceof CallTypeClassMethod and
1154
- apos .isSelf ( ) and
1155
- resolveMethodCall ( call , target , type , arg ) and
1156
- ( arg = classTracker ( _) or arg = clsArgumentTracker ( _) ) and
1157
- // dataflow lib has requirement that arguments and calls are in same enclosing callable.
1158
- exists ( CfgNode cfgNode | cfgNode .getNode ( ) = call |
1159
- cfgNode .getEnclosingCallable ( ) = arg .getEnclosingCallable ( )
1176
+ exists ( ArgumentPosition normalPos , int index |
1177
+ apos .isPositional ( index - 1 ) and
1178
+ normalPos .isPositional ( index ) and
1179
+ normalCallArg ( call , arg , normalPos )
1160
1180
)
1181
+ )
1182
+ or
1183
+ // class call
1184
+ type instanceof CallTypeClass and
1185
+ (
1186
+ // only pass synthetic node for created object to __init__, and not __new__ since
1187
+ // __new__ is a classmethod.
1188
+ target = invokedFunctionFromClassConstruction ( _, "__init__" ) and
1189
+ apos .isSelf ( ) and
1190
+ arg = TSyntheticPreUpdateNode ( call )
1161
1191
or
1162
- // normal arguments for method calls
1163
- (
1164
- type instanceof CallTypeNormalMethod or
1165
- type instanceof CallTypeStaticMethod or
1166
- type instanceof CallTypeClassMethod
1167
- ) and
1168
1192
normalCallArg ( call , arg , apos )
1193
+ )
1194
+ or
1195
+ // call on class instance, which goes to `__call__` method
1196
+ type instanceof CallTypeClassInstanceCall and
1197
+ (
1198
+ apos .isSelf ( ) and
1199
+ resolveClassInstanceCall ( call , target , arg )
1169
1200
or
1170
- // method as plain function call.
1171
- //
1172
- // argument index 0 of call has position self (and MUST be given as positional
1173
- // argument in call). This also means that call-arguments are shifted by 1, such
1174
- // that argument index 1 of call has argument position 0
1175
- type instanceof CallTypeMethodAsPlainFunction and
1176
- (
1177
- apos .isSelf ( ) and arg .asCfgNode ( ) = call .( CallNode ) .getArg ( 0 )
1178
- or
1179
- not apos .isPositional ( _) and normalCallArg ( call , arg , apos )
1180
- or
1181
- exists ( ArgumentPosition normalPos , int index |
1182
- apos .isPositional ( index - 1 ) and
1183
- normalPos .isPositional ( index ) and
1184
- normalCallArg ( call , arg , normalPos )
1185
- )
1186
- )
1187
- or
1188
- // class call
1189
- type instanceof CallTypeClass and
1190
- (
1191
- // only pass synthetic node for created object to __init__, and not __new__ since
1192
- // __new__ is a classmethod.
1193
- target = invokedFunctionFromClassConstruction ( _, "__init__" ) and
1194
- apos .isSelf ( ) and
1195
- arg = TSyntheticPreUpdateNode ( call )
1196
- or
1197
- normalCallArg ( call , arg , apos )
1198
- )
1199
- or
1200
- // call on class instance, which goes to `__call__` method
1201
- type instanceof CallTypeClassInstanceCall and
1202
- (
1203
- apos .isSelf ( ) and
1204
- resolveClassInstanceCall ( call , target , arg )
1205
- or
1206
- normalCallArg ( call , arg , apos )
1207
- )
1201
+ normalCallArg ( call , arg , apos )
1208
1202
)
1209
1203
)
1210
1204
}
0 commit comments