@@ -950,7 +950,7 @@ private module MethodCalls {
950950 )
951951 }
952952
953- predicate resolveMethodCall ( ControlFlowNode call , Function target , CallType type , Node self ) {
953+ predicate resolveMethodCall ( CallNode call , Function target , CallType type , Node self ) {
954954 (
955955 directCall ( call , target , _, _, _, self )
956956 or
@@ -1046,11 +1046,11 @@ predicate resolveClassInstanceCall(CallNode call, Function target, Node self) {
10461046 * Holds if `call` is a call to the `target`, with call-type `type`.
10471047 */
10481048cached
1049- predicate resolveCall ( ControlFlowNode call , Function target , CallType type ) {
1049+ predicate resolveCall ( CallNode call , Function target , CallType type ) {
10501050 Stages:: DataFlow:: ref ( ) and
10511051 (
10521052 type instanceof CallTypePlainFunction and
1053- call .( CallNode ) . getFunction ( ) = functionTracker ( target ) .asCfgNode ( ) and
1053+ call .getFunction ( ) = functionTracker ( target ) .asCfgNode ( ) and
10541054 not exists ( Class cls | cls .getAMethod ( ) = target )
10551055 or
10561056 resolveMethodCall ( call , target , type , _)
@@ -1128,83 +1128,77 @@ predicate normalCallArg(CallNode call, Node arg, ArgumentPosition apos) {
11281128 * sending both `self` arguments to that function, which is by definition the right thing to do.
11291129 */
11301130cached
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 ) {
11341132 Stages:: DataFlow:: ref ( ) and
1133+ resolveCall ( call , target , type ) and
11351134 (
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
11391158 (
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 )
11421173 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 )
11511175 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 )
11601180 )
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 )
11611191 or
1162- // normal arguments for method calls
1163- (
1164- type instanceof CallTypeNormalMethod or
1165- type instanceof CallTypeStaticMethod or
1166- type instanceof CallTypeClassMethod
1167- ) and
11681192 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 )
11691200 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 )
12081202 )
12091203 )
12101204}
0 commit comments