Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 1317d2d

Browse files
tamasvajkigfoo
authored andcommitted
Fix DB inconsistencies with KFunction and KFunction::invoke call extraction
1 parent 0b4cf6e commit 1317d2d

6 files changed

Lines changed: 102 additions & 7 deletions

File tree

java/kotlin-extractor/src/main/kotlin/KotlinFileExtractor.kt

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1131,11 +1131,13 @@ open class KotlinFileExtractor(
11311131
extractTypeArguments(typeArguments, locId, id, enclosingCallable, enclosingStmt, -2, true)
11321132

11331133
val drType = dispatchReceiver?.type
1134-
val isBigArityFunctionInvoke = drType != null
1134+
1135+
val isFunctionInvoke = drType != null
11351136
&& drType is IrSimpleType
11361137
&& drType.isFunctionOrKFunction()
11371138
&& callTarget.name.asString() == OperatorNameConventions.INVOKE.asString()
1138-
&& drType.arguments.size > BuiltInFunctionArity.BIG_ARITY
1139+
val isBigArityFunctionInvoke = isFunctionInvoke
1140+
&& (drType as IrSimpleType).arguments.size > BuiltInFunctionArity.BIG_ARITY
11391141

11401142
if (callTarget.isLocalFunction()) {
11411143
val ids = getLocallyVisibleFunctionLabels(callTarget)
@@ -1147,12 +1149,19 @@ open class KotlinFileExtractor(
11471149
} else {
11481150
val methodId =
11491151
if (drType != null && extractClassTypeArguments && drType is IrSimpleType && !isUnspecialised(drType)) {
1152+
1153+
val extractionMethod = if (isFunctionInvoke) {
1154+
val interfaceType = getFunctionalInterfaceTypeWithTypeArgs(drType.arguments).classOrNull!!.owner
1155+
val substituted = getJavaEquivalentClass(interfaceType) ?: interfaceType
1156+
findFunction(substituted, OperatorNameConventions.INVOKE.asString())!!
1157+
} else {
1158+
callTarget
1159+
}
1160+
11501161
if (isBigArityFunctionInvoke) {
1151-
val interfaceType = getFunctionalInterfaceTypeWithTypeArgs(drType.arguments)
1152-
val invokeMethod = findFunction(interfaceType.classOrNull!!.owner, OperatorNameConventions.INVOKE.asString())!!
1153-
useFunction<DbCallable>(invokeMethod, listOf(drType.arguments.last()))
1162+
useFunction<DbCallable>(extractionMethod, listOf(drType.arguments.last()))
11541163
} else {
1155-
useFunction<DbCallable>(callTarget, getDeclaringTypeArguments(callTarget, drType))
1164+
useFunction<DbCallable>(extractionMethod, getDeclaringTypeArguments(callTarget, drType))
11561165
}
11571166
}
11581167
else

java/kotlin-extractor/src/main/kotlin/KotlinUsesExtractor.kt

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -195,7 +195,14 @@ open class KotlinUsesExtractor(
195195

196196
val extractClass = substituteClass ?: c
197197

198-
val classTypeResult = addClassLabel(extractClass, typeArgs, inReceiverContext)
198+
// `KFunction1<T1,T2>` is substituted by `KFunction<T>`. The last type argument is the return type.
199+
val extractedTypeArgs = if (c.symbol.isKFunction() && typeArgs != null && typeArgs.isNotEmpty()) {
200+
listOf(typeArgs.last())
201+
} else {
202+
typeArgs
203+
}
204+
205+
val classTypeResult = addClassLabel(extractClass, extractedTypeArgs, inReceiverContext)
199206

200207
// Extract both the Kotlin and equivalent Java classes, so that we have database entries
201208
// for both even if all internal references to the Kotlin type are substituted.

java/ql/test/kotlin/library-tests/exprs/PrintAst.expected

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4219,6 +4219,56 @@ funcExprs.kt:
42194219
# 79| 5: [BlockStmt] { ... }
42204220
# 79| 0: [SuperConstructorInvocationStmt] super(...)
42214221
# 79| 1: [BlockStmt] { ... }
4222+
kFunctionInvoke.kt:
4223+
# 0| [CompilationUnit] kFunctionInvoke
4224+
# 0| 1: [Class] KFunctionInvokeKt
4225+
# 7| 1: [Method] useRef
4226+
#-----| 4: (Parameters)
4227+
# 7| 0: [Parameter] a
4228+
# 7| 1: [Parameter] s
4229+
# 7| 5: [BlockStmt] { ... }
4230+
# 8| 0: [LocalVariableDeclStmt] var ...;
4231+
# 8| 1: [LocalVariableDeclExpr] toCall
4232+
# 8| 0: [MemberRefExpr] ...::...
4233+
# 8| -4: [AnonymousClass] new Function1<String,Unit>(...) { ... }
4234+
# 8| 1: [Constructor]
4235+
#-----| 4: (Parameters)
4236+
# 8| 0: [Parameter] <dispatchReceiver>
4237+
# 8| 5: [BlockStmt] { ... }
4238+
# 8| 0: [SuperConstructorInvocationStmt] super(...)
4239+
# 8| 1: [ExprStmt] <Expr>;
4240+
# 8| 0: [AssignExpr] ...=...
4241+
# 8| 0: [VarAccess] this.<dispatchReceiver>
4242+
# 8| -1: [ThisAccess] this
4243+
# 8| 1: [VarAccess] <dispatchReceiver>
4244+
# 8| 1: [Method] invoke
4245+
#-----| 4: (Parameters)
4246+
# 8| 0: [Parameter] a0
4247+
# 8| 5: [BlockStmt] { ... }
4248+
# 8| 0: [ReturnStmt] return ...
4249+
# 8| 0: [MethodAccess] f(...)
4250+
# 8| -1: [VarAccess] this.<dispatchReceiver>
4251+
# 8| -1: [ThisAccess] this
4252+
# 8| 0: [VarAccess] a0
4253+
# 8| 1: [FieldDeclaration] A <dispatchReceiver>;
4254+
# 8| -1: [TypeAccess] A
4255+
# 8| -3: [TypeAccess] Function1<String,Unit>
4256+
# 8| 0: [TypeAccess] String
4257+
# 8| 1: [TypeAccess] Unit
4258+
# 8| 0: [VarAccess] a
4259+
# 9| 1: [ExprStmt] <Expr>;
4260+
# 9| 0: [MethodAccess] invoke(...)
4261+
# 9| -1: [VarAccess] toCall
4262+
# 9| 0: [VarAccess] s
4263+
# 3| 2: [Class] A
4264+
# 3| 1: [Constructor] A
4265+
# 3| 5: [BlockStmt] { ... }
4266+
# 3| 0: [SuperConstructorInvocationStmt] super(...)
4267+
# 3| 1: [BlockStmt] { ... }
4268+
# 4| 2: [Method] f
4269+
#-----| 4: (Parameters)
4270+
# 4| 0: [Parameter] s
4271+
# 4| 5: [BlockStmt] { ... }
42224272
localFunctionCalls.kt:
42234273
# 0| [CompilationUnit] localFunctionCalls
42244274
# 0| 1: [Class] LocalFunctionCallsKt

java/ql/test/kotlin/library-tests/exprs/exprs.expected

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2311,6 +2311,24 @@
23112311
| funcExprs.kt:75:12:75:22 | Integer | funcExprs.kt:74:5:76:5 | call | TypeAccess |
23122312
| funcExprs.kt:75:12:75:22 | String | funcExprs.kt:74:5:76:5 | call | TypeAccess |
23132313
| funcExprs.kt:75:20:75:20 | a | funcExprs.kt:75:12:75:22 | invoke | StringLiteral |
2314+
| kFunctionInvoke.kt:8:5:8:47 | toCall | kFunctionInvoke.kt:7:1:10:1 | useRef | LocalVariableDeclExpr |
2315+
| kFunctionInvoke.kt:8:44:8:44 | a | kFunctionInvoke.kt:7:1:10:1 | useRef | VarAccess |
2316+
| kFunctionInvoke.kt:8:44:8:47 | ...::... | kFunctionInvoke.kt:7:1:10:1 | useRef | MemberRefExpr |
2317+
| kFunctionInvoke.kt:8:44:8:47 | ...=... | kFunctionInvoke.kt:8:44:8:47 | | AssignExpr |
2318+
| kFunctionInvoke.kt:8:44:8:47 | <dispatchReceiver> | kFunctionInvoke.kt:8:44:8:47 | | VarAccess |
2319+
| kFunctionInvoke.kt:8:44:8:47 | A | file://:0:0:0:0 | <none> | TypeAccess |
2320+
| kFunctionInvoke.kt:8:44:8:47 | Function1<String,Unit> | kFunctionInvoke.kt:7:1:10:1 | useRef | TypeAccess |
2321+
| kFunctionInvoke.kt:8:44:8:47 | String | kFunctionInvoke.kt:7:1:10:1 | useRef | TypeAccess |
2322+
| kFunctionInvoke.kt:8:44:8:47 | Unit | kFunctionInvoke.kt:7:1:10:1 | useRef | TypeAccess |
2323+
| kFunctionInvoke.kt:8:44:8:47 | a0 | kFunctionInvoke.kt:8:44:8:47 | invoke | VarAccess |
2324+
| kFunctionInvoke.kt:8:44:8:47 | f(...) | kFunctionInvoke.kt:8:44:8:47 | invoke | MethodAccess |
2325+
| kFunctionInvoke.kt:8:44:8:47 | this | kFunctionInvoke.kt:8:44:8:47 | | ThisAccess |
2326+
| kFunctionInvoke.kt:8:44:8:47 | this | kFunctionInvoke.kt:8:44:8:47 | invoke | ThisAccess |
2327+
| kFunctionInvoke.kt:8:44:8:47 | this.<dispatchReceiver> | kFunctionInvoke.kt:8:44:8:47 | | VarAccess |
2328+
| kFunctionInvoke.kt:8:44:8:47 | this.<dispatchReceiver> | kFunctionInvoke.kt:8:44:8:47 | invoke | VarAccess |
2329+
| kFunctionInvoke.kt:9:5:9:10 | toCall | kFunctionInvoke.kt:7:1:10:1 | useRef | VarAccess |
2330+
| kFunctionInvoke.kt:9:5:9:13 | invoke(...) | kFunctionInvoke.kt:7:1:10:1 | useRef | MethodAccess |
2331+
| kFunctionInvoke.kt:9:12:9:12 | s | kFunctionInvoke.kt:7:1:10:1 | useRef | VarAccess |
23142332
| localFunctionCalls.kt:4:5:4:13 | x | localFunctionCalls.kt:3:1:12:1 | x | LocalVariableDeclExpr |
23152333
| localFunctionCalls.kt:4:13:4:13 | 5 | localFunctionCalls.kt:3:1:12:1 | x | IntegerLiteral |
23162334
| localFunctionCalls.kt:5:25:5:25 | i | localFunctionCalls.kt:5:5:5:29 | a | VarAccess |

java/ql/test/kotlin/library-tests/exprs/funcExprs.expected

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,5 +34,6 @@ memberRefExprs
3434
| funcExprs.kt:46:30:46:41 | ...::... | funcExprs.kt:46:30:46:41 | invoke | invoke(java.lang.Object[]) | funcExprs.kt:46:30:46:41 | new FunctionN<String>(...) { ... } |
3535
| funcExprs.kt:49:26:49:32 | ...::... | funcExprs.kt:49:26:49:32 | invoke | invoke() | funcExprs.kt:49:26:49:32 | new Function0<Integer>(...) { ... } |
3636
| funcExprs.kt:51:8:51:16 | ...::... | funcExprs.kt:51:8:51:16 | invoke | invoke() | funcExprs.kt:51:8:51:16 | new Function0<FuncRef>(...) { ... } |
37+
| kFunctionInvoke.kt:8:44:8:47 | ...::... | kFunctionInvoke.kt:8:44:8:47 | invoke | invoke(java.lang.String) | kFunctionInvoke.kt:8:44:8:47 | new Function1<String,Unit>(...) { ... } |
3738
| samConversion.kt:5:27:5:31 | ...::... | samConversion.kt:5:27:5:31 | invoke | invoke(int,int) | samConversion.kt:5:27:5:31 | new Function2<Integer,Integer,Unit>(...) { ... } |
3839
| samConversion.kt:41:13:41:16 | ...::... | samConversion.kt:41:13:41:16 | invoke | invoke(java.lang.Object[]) | samConversion.kt:41:13:41:16 | new FunctionN<Boolean>(...) { ... } |
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
import kotlin.reflect.*
2+
3+
class A {
4+
fun f(s: String) { }
5+
}
6+
7+
fun useRef(a: A, s: String) {
8+
val toCall: KFunction1<String, Unit> = a::f
9+
toCall(s)
10+
}

0 commit comments

Comments
 (0)