mirror of
https://github.com/github/codeql.git
synced 2026-04-28 18:25:24 +02:00
Kotlin: specialise extension receivers the same as other function parameters
This arises when a generic class extends one of its parameters; for example, `class G<T> { val T.v; get() = 1 }`, where specialisation `G<List>` should generate a method specialisation `getV(List)`.
This commit is contained in:
@@ -1188,22 +1188,16 @@ open class KotlinFileExtractor(
|
||||
id
|
||||
|
||||
val extReceiver = f.extensionReceiverParameter
|
||||
val idxOffset = if (extReceiver != null) 1 else 0
|
||||
val fParameters = overriddenAttributes?.valueParameters ?: f.valueParameters
|
||||
val fParameters = (overriddenAttributes?.valueParameters ?: f.valueParameters) + listOfNotNull(extReceiver)
|
||||
val paramTypes = fParameters.mapIndexed { i, vp ->
|
||||
extractValueParameter(vp, id, i + idxOffset, typeSubstitution, sourceDeclaration, classTypeArgsIncludingOuterClasses, extractTypeAccess = extractMethodAndParameterTypeAccesses, overriddenAttributes?.sourceLoc)
|
||||
extractValueParameter(vp, id, i, typeSubstitution, sourceDeclaration, classTypeArgsIncludingOuterClasses, extractTypeAccess = extractMethodAndParameterTypeAccesses, overriddenAttributes?.sourceLoc)
|
||||
}
|
||||
val allParamTypes = if (extReceiver != null) {
|
||||
val extendedType = useType(extReceiver.type)
|
||||
if (extReceiver != null) {
|
||||
val extendedType = paramTypes[0]
|
||||
tw.writeKtExtensionFunctions(id.cast<DbMethod>(), extendedType.javaResult.id, extendedType.kotlinResult.id)
|
||||
|
||||
val t = extractValueParameter(extReceiver, id, 0, null, sourceDeclaration, classTypeArgsIncludingOuterClasses, extractTypeAccess = extractMethodAndParameterTypeAccesses, overriddenAttributes?.sourceLoc)
|
||||
listOf(t) + paramTypes
|
||||
} else {
|
||||
paramTypes
|
||||
}
|
||||
|
||||
val paramsSignature = allParamTypes.joinToString(separator = ",", prefix = "(", postfix = ")") { signatureOrWarn(it.javaResult, f) }
|
||||
val paramsSignature = paramTypes.joinToString(separator = ",", prefix = "(", postfix = ")") { signatureOrWarn(it.javaResult, f) }
|
||||
|
||||
val adjustedReturnType = addJavaLoweringWildcards(getAdjustedReturnType(f), false, (javaCallable as? JavaMethod)?.returnType)
|
||||
val substReturnType = typeSubstitution?.let { it(adjustedReturnType, TypeContext.RETURN, pluginContext) } ?: adjustedReturnType
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
public class User {
|
||||
|
||||
public static void test(KotlinClass<String> kc) {
|
||||
|
||||
kc.getKotlinVal("Hello world");
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
| User.java:5:5:5:34 | getKotlinVal(...) | getKotlinVal | String |
|
||||
| test.kt:8:43:8:78 | with(...) | with | Function1<? super T,? extends R> |
|
||||
| test.kt:8:43:8:78 | with(...) | with | T |
|
||||
| test.kt:8:68:8:76 | getKotlinVal(...) | getKotlinVal | String |
|
||||
@@ -0,0 +1,8 @@
|
||||
class KotlinClass<T> {
|
||||
|
||||
val T.kotlinVal: Int
|
||||
get() = 1
|
||||
|
||||
}
|
||||
|
||||
fun kotlinUser(kc: KotlinClass<String>) = with(kc) { "hello world".kotlinVal }
|
||||
@@ -0,0 +1,4 @@
|
||||
from create_database_utils import *
|
||||
|
||||
os.mkdir('build')
|
||||
run_codeql_database_create(["kotlinc test.kt -d build", "javac User.java -cp build"], lang="java")
|
||||
@@ -0,0 +1,4 @@
|
||||
import java
|
||||
|
||||
from MethodAccess ma
|
||||
select ma, ma.getCallee().toString(), ma.getCallee().getAParamType().toString()
|
||||
Reference in New Issue
Block a user