Analysis API: Add tests for KtCallResolver.resolveCandidates().

This commit is contained in:
Mark Punzalan
2022-01-31 17:58:23 +00:00
committed by Ilya Kirillov
parent f62bdf5826
commit 0ed802bca4
27 changed files with 597 additions and 100 deletions
@@ -19,7 +19,6 @@ import org.jetbrains.kotlin.analysis.api.symbols.*
import org.jetbrains.kotlin.analysis.api.tokens.ValidityToken
import org.jetbrains.kotlin.analysis.api.types.KtSubstitutor
import org.jetbrains.kotlin.analysis.api.withValidityAssertion
import org.jetbrains.kotlin.analysis.low.level.api.fir.api.LowLevelFirApiFacadeForResolveOnAir.getTowerContextProvider
import org.jetbrains.kotlin.analysis.low.level.api.fir.api.getOrBuildFir
import org.jetbrains.kotlin.analysis.low.level.api.fir.api.getOrBuildFirFile
import org.jetbrains.kotlin.diagnostics.KtDiagnostic
@@ -640,7 +639,7 @@ internal class KtFirCallResolver(
override fun resolveCandidates(psi: KtElement): List<KtCallInfo> = withValidityAssertion {
val firCall = when (val fir = psi.getOrBuildFir(firResolveState)) {
is FirFunctionCall -> fir
is FirSafeCallExpression -> fir.regularQualifiedAccess.safeAs<FirFunctionCall>()
is FirSafeCallExpression -> fir.selector.safeAs<FirFunctionCall>()
// TODO: FirDelegatedConstructorColl, FirAnnotationCall, FirArrayOfCall, FirConstructor
else -> null
} ?: return@withValidityAssertion emptyList()
@@ -671,7 +670,7 @@ internal class KtFirCallResolver(
@OptIn(PrivateForInline::class)
fun getAllCandidates(functionCall: FirFunctionCall, element: KtElement): List<KtCallInfo> {
val towerContext = firResolveState.getTowerContextProvider().getClosestAvailableParentContext(element)
val towerContext = firResolveState.getTowerContextProvider(element.containingKtFile).getClosestAvailableParentContext(element)
towerContext?.let { bodyResolveComponents.context.replaceTowerDataContext(it) }
// Note: All candidate symbols should have the same name
val name =
@@ -0,0 +1,106 @@
/*
* Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.analysis.api.fir.components;
import com.intellij.testFramework.TestDataPath;
import org.jetbrains.kotlin.test.util.KtTestUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.kotlin.analysis.api.impl.barebone.test.FrontendApiTestConfiguratorService;
import org.jetbrains.kotlin.analysis.api.fir.FirFrontendApiTestConfiguratorService;
import org.jetbrains.kotlin.analysis.api.impl.base.test.components.AbstractResolveCandidatesTest;
import org.jetbrains.kotlin.test.TestMetadata;
import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test;
import java.io.File;
import java.util.regex.Pattern;
/** This class is generated by {@link GenerateNewCompilerTests.kt}. DO NOT MODIFY MANUALLY */
@SuppressWarnings("all")
@TestMetadata("analysis/analysis-api/testData/components/callResolver/resolveCandidates")
@TestDataPath("$PROJECT_ROOT")
public class FirResolveCandidatesTestGenerated extends AbstractResolveCandidatesTest {
@NotNull
@Override
public FrontendApiTestConfiguratorService getConfigurator() {
return FirFrontendApiTestConfiguratorService.INSTANCE;
}
@Test
public void testAllFilesPresentInResolveCandidates() throws Exception {
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("analysis/analysis-api/testData/components/callResolver/resolveCandidates"), Pattern.compile("^(.+)\\.kt$"), null, true);
}
@Test
@TestMetadata("noCandidates.kt")
public void testNoCandidates() throws Exception {
runTest("analysis/analysis-api/testData/components/callResolver/resolveCandidates/noCandidates.kt");
}
@Nested
@TestMetadata("analysis/analysis-api/testData/components/callResolver/resolveCandidates/singleCandidate")
@TestDataPath("$PROJECT_ROOT")
public class SingleCandidate {
@Test
public void testAllFilesPresentInSingleCandidate() throws Exception {
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("analysis/analysis-api/testData/components/callResolver/resolveCandidates/singleCandidate"), Pattern.compile("^(.+)\\.kt$"), null, true);
}
@Test
@TestMetadata("functionCall.kt")
public void testFunctionCall() throws Exception {
runTest("analysis/analysis-api/testData/components/callResolver/resolveCandidates/singleCandidate/functionCall.kt");
}
@Test
@TestMetadata("functionCallWithNotEnoughArgs.kt")
public void testFunctionCallWithNotEnoughArgs() throws Exception {
runTest("analysis/analysis-api/testData/components/callResolver/resolveCandidates/singleCandidate/functionCallWithNotEnoughArgs.kt");
}
@Test
@TestMetadata("indexedGet.kt")
public void testIndexedGet() throws Exception {
runTest("analysis/analysis-api/testData/components/callResolver/resolveCandidates/singleCandidate/indexedGet.kt");
}
@Test
@TestMetadata("indexedGetWithNotEnoughArgs.kt")
public void testIndexedGetWithNotEnoughArgs() throws Exception {
runTest("analysis/analysis-api/testData/components/callResolver/resolveCandidates/singleCandidate/indexedGetWithNotEnoughArgs.kt");
}
@Test
@TestMetadata("indexedSet.kt")
public void testIndexedSet() throws Exception {
runTest("analysis/analysis-api/testData/components/callResolver/resolveCandidates/singleCandidate/indexedSet.kt");
}
@Test
@TestMetadata("indexedSetWithNotEnoughArgs.kt")
public void testIndexedSetWithNotEnoughArgs() throws Exception {
runTest("analysis/analysis-api/testData/components/callResolver/resolveCandidates/singleCandidate/indexedSetWithNotEnoughArgs.kt");
}
@Test
@TestMetadata("samConstructorCall.kt")
public void testSamConstructorCall() throws Exception {
runTest("analysis/analysis-api/testData/components/callResolver/resolveCandidates/singleCandidate/samConstructorCall.kt");
}
@Test
@TestMetadata("variableAsFunction.kt")
public void testVariableAsFunction() throws Exception {
runTest("analysis/analysis-api/testData/components/callResolver/resolveCandidates/singleCandidate/variableAsFunction.kt");
}
@Test
@TestMetadata("variableAsFunctionLikeCall.kt")
public void testVariableAsFunctionLikeCall() throws Exception {
runTest("analysis/analysis-api/testData/components/callResolver/resolveCandidates/singleCandidate/variableAsFunctionLikeCall.kt");
}
}
}
@@ -8,23 +8,12 @@ package org.jetbrains.kotlin.analysis.api.impl.base.test.components
import com.intellij.psi.PsiElement
import org.jetbrains.kotlin.analysis.api.KtAnalysisSession
import org.jetbrains.kotlin.analysis.api.calls.KtCallInfo
import org.jetbrains.kotlin.analysis.api.diagnostics.KtDiagnostic
import org.jetbrains.kotlin.analysis.api.impl.barebone.test.FrontendApiTestConfiguratorService
import org.jetbrains.kotlin.analysis.api.impl.barebone.test.expressionMarkerProvider
import org.jetbrains.kotlin.analysis.api.impl.base.KtMapBackedSubstitutor
import org.jetbrains.kotlin.analysis.api.impl.base.test.test.framework.AbstractHLApiSingleModuleTest
import org.jetbrains.kotlin.analysis.api.symbols.*
import org.jetbrains.kotlin.analysis.api.symbols.DebugSymbolRenderer.render
import org.jetbrains.kotlin.analysis.api.types.KtSubstitutor
import org.jetbrains.kotlin.analysis.api.types.KtType
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.test.model.TestModule
import org.jetbrains.kotlin.test.services.TestServices
import org.jetbrains.kotlin.test.services.assertions
import kotlin.reflect.KProperty1
import kotlin.reflect.KVisibility
import kotlin.reflect.full.memberProperties
abstract class AbstractResolveCallTest : AbstractHLApiSingleModuleTest() {
override fun doTestByFileStructure(ktFiles: List<KtFile>, module: TestModule, testServices: TestServices) {
@@ -56,85 +45,3 @@ abstract class AbstractResolveCallTest : AbstractHLApiSingleModuleTest() {
}
}
private fun KtAnalysisSession.stringRepresentation(call: KtCallInfo): String {
fun Any.stringValue(): String {
fun KtType.render() = asStringForDebugging().replace('/', '.')
fun String.indented() = replace("\n", "\n ")
return when (this) {
is KtFunctionLikeSymbol -> buildString {
append(
when (this@stringValue) {
is KtFunctionSymbol -> callableIdIfNonLocal ?: name
is KtSamConstructorSymbol -> callableIdIfNonLocal ?: name
is KtConstructorSymbol -> "<constructor>"
is KtPropertyGetterSymbol -> callableIdIfNonLocal ?: "<getter>"
is KtPropertySetterSymbol -> callableIdIfNonLocal ?: "<setter>"
else -> error("unexpected symbol kind in KtCall: ${this@stringValue::class.java}")
}
)
append("(")
(this@stringValue as? KtFunctionSymbol)?.receiverType?.let { receiver ->
append("<extension receiver>: ${receiver.render()}")
if (valueParameters.isNotEmpty()) append(", ")
}
@Suppress("DEPRECATION")
(this@stringValue as? KtCallableSymbol)?.getDispatchReceiverType()?.let { dispatchReceiverType ->
append("<dispatch receiver>: ${dispatchReceiverType.render()}")
if (valueParameters.isNotEmpty()) append(", ")
}
valueParameters.joinTo(this) { it.stringValue() }
append(")")
append(": ${returnType.render()}")
}
is KtValueParameterSymbol -> "${if (isVararg) "vararg " else ""}$name: ${returnType.render()}"
is KtTypeParameterSymbol -> this.nameOrAnonymous.asString()
is KtVariableSymbol -> "${if (isVal) "val" else "var"} $name: ${returnType.render()}"
is KtSymbol -> render(this)
is Boolean -> toString()
is Map<*, *> -> if (isEmpty()) "{}" else entries.joinToString(
separator = ",\n ",
prefix = "{\n ",
postfix = "\n}"
) { (k, v) -> "${k?.stringValue()?.indented()} -> (${v?.stringValue()?.indented()})" }
is Collection<*> -> if (isEmpty()) "[]" else joinToString(
separator = ",\n ",
prefix = "[\n ",
postfix = "\n]"
) {
it?.stringValue()?.indented() ?: "null"
}
is PsiElement -> this.text
is KtSubstitutor.Empty -> "<empty substitutor>"
is KtMapBackedSubstitutor -> {
val mappingText = getAsMap().entries
.joinToString(prefix = "{", postfix = "}") { (k, v) -> k.stringValue() + " = " + v.asStringForDebugging() }
"<map substitutor: $mappingText>"
}
is KtSubstitutor -> "<complex substitutor>"
is KtDiagnostic -> "$severity<$factoryName: $defaultMessage>"
is KtType -> render()
is Enum<*> -> name
is Name -> asString()
else -> buildString {
val clazz = this@stringValue::class
append(clazz.simpleName!!)
appendLine(":")
clazz.memberProperties
.filter { it.name != "token" && it.visibility == KVisibility.PUBLIC }
.joinTo(this, separator = "\n ", prefix = " ") { property ->
val name = property.name
@Suppress("UNCHECKED_CAST")
val value =
(property as KProperty1<Any, *>).get(this@stringValue)?.stringValue()?.indented()
"$name = $value"
}
}
}
}
return call.stringValue()
}
@@ -0,0 +1,54 @@
/*
* Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.analysis.api.impl.base.test.components
import com.intellij.psi.PsiElement
import org.jetbrains.kotlin.analysis.api.KtAnalysisSession
import org.jetbrains.kotlin.analysis.api.calls.KtCall
import org.jetbrains.kotlin.analysis.api.calls.KtCallInfo
import org.jetbrains.kotlin.analysis.api.impl.barebone.test.FrontendApiTestConfiguratorService
import org.jetbrains.kotlin.analysis.api.impl.barebone.test.expressionMarkerProvider
import org.jetbrains.kotlin.analysis.api.impl.base.test.test.framework.AbstractHLApiSingleModuleTest
import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.test.model.TestModule
import org.jetbrains.kotlin.test.services.TestServices
import org.jetbrains.kotlin.test.services.assertions
abstract class AbstractResolveCandidatesTest : AbstractHLApiSingleModuleTest() {
override fun doTestByFileStructure(ktFiles: List<KtFile>, module: TestModule, testServices: TestServices) {
val ktFile = ktFiles.first()
val expression = testServices.expressionMarkerProvider.getSelectedElement(ktFile)
val actual = executeOnPooledThreadInReadAction {
analyseForTest(expression) {
val candidates = resolveCandidates(expression)
if (candidates.isEmpty()) {
"NO_CANDIDATES"
} else {
candidates.joinToString("\n\n") { stringRepresentation(it) }
}
}
}
testServices.assertions.assertEqualsToTestDataFileSibling(actual)
}
private fun KtAnalysisSession.resolveCandidates(element: PsiElement): List<KtCallInfo> = when (element) {
is KtValueArgument -> resolveCandidates(element.getArgumentExpression()!!)
is KtDeclarationModifierList -> {
val annotationEntry = element.annotationEntries.singleOrNull()
?: error("Only single annotation entry is supported for now")
annotationEntry.resolveCandidates()
}
is KtFileAnnotationList -> {
val annotationEntry = element.annotationEntries.singleOrNull()
?: error("Only single annotation entry is supported for now")
annotationEntry.resolveCandidates()
}
is KtElement -> element.resolveCandidates()
else -> error("Selected element type (${element::class.simpleName}) is not supported for resolveCandidates()")
}
}
@@ -0,0 +1,100 @@
/*
* Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.analysis.api.impl.base.test.components
import com.intellij.psi.PsiElement
import org.jetbrains.kotlin.analysis.api.KtAnalysisSession
import org.jetbrains.kotlin.analysis.api.calls.KtCallInfo
import org.jetbrains.kotlin.analysis.api.diagnostics.KtDiagnostic
import org.jetbrains.kotlin.analysis.api.impl.base.KtMapBackedSubstitutor
import org.jetbrains.kotlin.analysis.api.symbols.*
import org.jetbrains.kotlin.analysis.api.types.KtSubstitutor
import org.jetbrains.kotlin.analysis.api.types.KtType
import org.jetbrains.kotlin.name.Name
import kotlin.reflect.KProperty1
import kotlin.reflect.KVisibility
import kotlin.reflect.full.memberProperties
internal fun KtAnalysisSession.stringRepresentation(call: KtCallInfo): String {
fun Any.stringValue(): String {
fun KtType.render() = asStringForDebugging().replace('/', '.')
fun String.indented() = replace("\n", "\n ")
return when (this) {
is KtFunctionLikeSymbol -> buildString {
append(
when (this@stringValue) {
is KtFunctionSymbol -> callableIdIfNonLocal ?: name
is KtSamConstructorSymbol -> callableIdIfNonLocal ?: name
is KtConstructorSymbol -> "<constructor>"
is KtPropertyGetterSymbol -> callableIdIfNonLocal ?: "<getter>"
is KtPropertySetterSymbol -> callableIdIfNonLocal ?: "<setter>"
else -> error("unexpected symbol kind in KtCall: ${this@stringValue::class.java}")
}
)
append("(")
(this@stringValue as? KtFunctionSymbol)?.receiverType?.let { receiver ->
append("<extension receiver>: ${receiver.render()}")
if (valueParameters.isNotEmpty()) append(", ")
}
@Suppress("DEPRECATION")
(this@stringValue as? KtCallableSymbol)?.getDispatchReceiverType()?.let { dispatchReceiverType ->
append("<dispatch receiver>: ${dispatchReceiverType.render()}")
if (valueParameters.isNotEmpty()) append(", ")
}
valueParameters.joinTo(this) { it.stringValue() }
append(")")
append(": ${returnType.render()}")
}
is KtValueParameterSymbol -> "${if (isVararg) "vararg " else ""}$name: ${returnType.render()}"
is KtTypeParameterSymbol -> this.nameOrAnonymous.asString()
is KtVariableSymbol -> "${if (isVal) "val" else "var"} $name: ${returnType.render()}"
is KtSymbol -> DebugSymbolRenderer.render(this)
is Boolean -> toString()
is Map<*, *> -> if (isEmpty()) "{}" else entries.joinToString(
separator = ",\n ",
prefix = "{\n ",
postfix = "\n}"
) { (k, v) -> "${k?.stringValue()?.indented()} -> (${v?.stringValue()?.indented()})" }
is Collection<*> -> if (isEmpty()) "[]" else joinToString(
separator = ",\n ",
prefix = "[\n ",
postfix = "\n]"
) {
it?.stringValue()?.indented() ?: "null"
}
is PsiElement -> this.text
is KtSubstitutor.Empty -> "<empty substitutor>"
is KtMapBackedSubstitutor -> {
val mappingText = getAsMap().entries
.joinToString(prefix = "{", postfix = "}") { (k, v) -> k.stringValue() + " = " + v.asStringForDebugging() }
"<map substitutor: $mappingText>"
}
is KtSubstitutor -> "<complex substitutor>"
is KtDiagnostic -> "$severity<$factoryName: $defaultMessage>"
is KtType -> render()
is Enum<*> -> name
is Name -> asString()
else -> buildString {
val clazz = this@stringValue::class
append(clazz.simpleName!!)
appendLine(":")
clazz.memberProperties
.filter { it.name != "token" && it.visibility == KVisibility.PUBLIC }
.joinTo(this, separator = "\n ", prefix = " ") { property ->
val name = property.name
@Suppress("UNCHECKED_CAST")
val value =
(property as KProperty1<Any, *>).get(this@stringValue)?.stringValue()?.indented()
"$name = $value"
}
}
}
}
return call.stringValue()
}
@@ -31,9 +31,6 @@ public interface KtCallResolverMixIn : KtAnalysisSessionMixIn {
public fun KtArrayAccessExpression.resolveCall(): KtCallInfo =
analysisSession.callResolver.resolveCall(this) ?: error("KtArrayAccessExpression should always resolve to a KtCallInfo")
public fun KtCallElement.resolveCandidates(): List<KtCallInfo> =
analysisSession.callResolver.resolveCandidates(this)
public fun KtArrayAccessExpression.resolveCandidates(): List<KtCallInfo> =
public fun KtElement.resolveCandidates(): List<KtCallInfo> =
analysisSession.callResolver.resolveCandidates(this)
}
@@ -0,0 +1,3 @@
fun call() {
<expr>function(1)</expr>
}
@@ -0,0 +1 @@
NO_CANDIDATES
@@ -0,0 +1,5 @@
fun function(a: Int) {}
fun call() {
<expr>function(1)</expr>
}
@@ -0,0 +1,24 @@
KtSuccessCallInfo:
call = KtSimpleFunctionCall:
isImplicitInvoke = false
partiallyAppliedSymbol = KtPartiallyAppliedSymbol:
dispatchReceiver = null
extensionReceiver = null
signature = KtFunctionLikeSignature:
receiverType = null
returnType = kotlin.Unit
symbol = /function(a: kotlin.Int): kotlin.Unit
valueParameters = [
KtVariableLikeSignature:
name = a
receiverType = null
returnType = kotlin.Int
symbol = a: kotlin.Int
]
argumentMapping = {
1 -> (KtVariableLikeSignature:
name = a
receiverType = null
returnType = kotlin.Int
symbol = a: kotlin.Int)
}
@@ -0,0 +1,5 @@
fun function(a: Int, b: String) {}
fun call() {
<expr>function(1)</expr>
}
@@ -0,0 +1,32 @@
KtErrorCallInfo:
candidateCalls = [
KtSimpleFunctionCall:
isImplicitInvoke = false
partiallyAppliedSymbol = KtPartiallyAppliedSymbol:
dispatchReceiver = null
extensionReceiver = null
signature = KtFunctionLikeSignature:
receiverType = null
returnType = kotlin.Unit
symbol = /function(a: kotlin.Int, b: kotlin.String): kotlin.Unit
valueParameters = [
KtVariableLikeSignature:
name = a
receiverType = null
returnType = kotlin.Int
symbol = a: kotlin.Int,
KtVariableLikeSignature:
name = b
receiverType = null
returnType = kotlin.String
symbol = b: kotlin.String
]
argumentMapping = {
1 -> (KtVariableLikeSignature:
name = a
receiverType = null
returnType = kotlin.Int
symbol = a: kotlin.Int)
}
]
diagnostic = ERROR<NO_VALUE_FOR_PARAMETER: No value passed for parameter 'b'>
@@ -0,0 +1,7 @@
class C {
operator fun get(a: Int, b: String): Boolean = true
}
fun call(c: C) {
val res = <expr>c[1, "foo"]</expr>
}
@@ -0,0 +1,36 @@
KtSuccessCallInfo:
call = KtSimpleFunctionCall:
isImplicitInvoke = false
partiallyAppliedSymbol = KtPartiallyAppliedSymbol:
dispatchReceiver = KtExplicitReceiverValue:
expression = c
isSafeNavigation = false
extensionReceiver = null
signature = KtFunctionLikeSignature:
receiverType = null
returnType = kotlin.Boolean
symbol = /C.get(<dispatch receiver>: C, a: kotlin.Int, b: kotlin.String): kotlin.Boolean
valueParameters = [
KtVariableLikeSignature:
name = a
receiverType = null
returnType = kotlin.Int
symbol = a: kotlin.Int,
KtVariableLikeSignature:
name = b
receiverType = null
returnType = kotlin.String
symbol = b: kotlin.String
]
argumentMapping = {
1 -> (KtVariableLikeSignature:
name = a
receiverType = null
returnType = kotlin.Int
symbol = a: kotlin.Int),
"foo" -> (KtVariableLikeSignature:
name = b
receiverType = null
returnType = kotlin.String
symbol = b: kotlin.String)
}
@@ -0,0 +1,7 @@
class C {
operator fun get(a: Int, b: String): Boolean = true
}
fun call(c: C) {
val res = <expr>c[1]</expr>
}
@@ -0,0 +1,34 @@
KtErrorCallInfo:
candidateCalls = [
KtSimpleFunctionCall:
isImplicitInvoke = false
partiallyAppliedSymbol = KtPartiallyAppliedSymbol:
dispatchReceiver = KtExplicitReceiverValue:
expression = c
isSafeNavigation = false
extensionReceiver = null
signature = KtFunctionLikeSignature:
receiverType = null
returnType = kotlin.Boolean
symbol = /C.get(<dispatch receiver>: C, a: kotlin.Int, b: kotlin.String): kotlin.Boolean
valueParameters = [
KtVariableLikeSignature:
name = a
receiverType = null
returnType = kotlin.Int
symbol = a: kotlin.Int,
KtVariableLikeSignature:
name = b
receiverType = null
returnType = kotlin.String
symbol = b: kotlin.String
]
argumentMapping = {
1 -> (KtVariableLikeSignature:
name = a
receiverType = null
returnType = kotlin.Int
symbol = a: kotlin.Int)
}
]
diagnostic = ERROR<NO_VALUE_FOR_PARAMETER: No value passed for parameter 'b'>
@@ -0,0 +1,7 @@
class C {
operator fun set(a: Int, b: String, value: Boolean) {}
}
fun call(c: C) {
<expr>c[1, "foo"]</expr> = false
}
@@ -0,0 +1,46 @@
KtSuccessCallInfo:
call = KtSimpleFunctionCall:
isImplicitInvoke = false
partiallyAppliedSymbol = KtPartiallyAppliedSymbol:
dispatchReceiver = KtExplicitReceiverValue:
expression = c
isSafeNavigation = false
extensionReceiver = null
signature = KtFunctionLikeSignature:
receiverType = null
returnType = kotlin.Unit
symbol = /C.set(<dispatch receiver>: C, a: kotlin.Int, b: kotlin.String, value: kotlin.Boolean): kotlin.Unit
valueParameters = [
KtVariableLikeSignature:
name = a
receiverType = null
returnType = kotlin.Int
symbol = a: kotlin.Int,
KtVariableLikeSignature:
name = b
receiverType = null
returnType = kotlin.String
symbol = b: kotlin.String,
KtVariableLikeSignature:
name = value
receiverType = null
returnType = kotlin.Boolean
symbol = value: kotlin.Boolean
]
argumentMapping = {
1 -> (KtVariableLikeSignature:
name = a
receiverType = null
returnType = kotlin.Int
symbol = a: kotlin.Int),
"foo" -> (KtVariableLikeSignature:
name = b
receiverType = null
returnType = kotlin.String
symbol = b: kotlin.String),
false -> (KtVariableLikeSignature:
name = value
receiverType = null
returnType = kotlin.Boolean
symbol = value: kotlin.Boolean)
}
@@ -0,0 +1,7 @@
class C {
operator fun set(a: Int, b: String, value: Boolean) {}
}
fun call(c: C) {
<expr>c[1]</expr> = false
}
@@ -0,0 +1,44 @@
KtErrorCallInfo:
candidateCalls = [
KtSimpleFunctionCall:
isImplicitInvoke = false
partiallyAppliedSymbol = KtPartiallyAppliedSymbol:
dispatchReceiver = KtExplicitReceiverValue:
expression = c
isSafeNavigation = false
extensionReceiver = null
signature = KtFunctionLikeSignature:
receiverType = null
returnType = kotlin.Unit
symbol = /C.set(<dispatch receiver>: C, a: kotlin.Int, b: kotlin.String, value: kotlin.Boolean): kotlin.Unit
valueParameters = [
KtVariableLikeSignature:
name = a
receiverType = null
returnType = kotlin.Int
symbol = a: kotlin.Int,
KtVariableLikeSignature:
name = b
receiverType = null
returnType = kotlin.String
symbol = b: kotlin.String,
KtVariableLikeSignature:
name = value
receiverType = null
returnType = kotlin.Boolean
symbol = value: kotlin.Boolean
]
argumentMapping = {
1 -> (KtVariableLikeSignature:
name = a
receiverType = null
returnType = kotlin.Int
symbol = a: kotlin.Int),
false -> (KtVariableLikeSignature:
name = value
receiverType = null
returnType = kotlin.Boolean
symbol = value: kotlin.Boolean)
}
]
diagnostic = ERROR<NO_VALUE_FOR_PARAMETER: No value passed for parameter 'b'>
@@ -0,0 +1 @@
val c = <expr>Comparator {x: Int, y: Int -> 1}</expr>
@@ -0,0 +1,24 @@
KtSuccessCallInfo:
call = KtSimpleFunctionCall:
isImplicitInvoke = false
partiallyAppliedSymbol = KtPartiallyAppliedSymbol:
dispatchReceiver = null
extensionReceiver = null
signature = KtFunctionLikeSignature:
receiverType = null
returnType = java.util.Comparator<ft<kotlin.Int, kotlin.Int?>>
symbol = java/util/Comparator(function: kotlin.Function2<ft<T, T?>, ft<T, T?>, kotlin.Int>): java.util.Comparator<T>
valueParameters = [
KtVariableLikeSignature:
name = function
receiverType = null
returnType = kotlin.Function2<ft<kotlin.Int, kotlin.Int?>, ft<kotlin.Int, kotlin.Int?>, kotlin.Int>
symbol = function: kotlin.Function2<ft<T, T?>, ft<T, T?>, kotlin.Int>
]
argumentMapping = {
{x: Int, y: Int -> 1} -> (KtVariableLikeSignature:
name = function
receiverType = null
returnType = kotlin.Function2<ft<kotlin.Int, kotlin.Int?>, ft<kotlin.Int, kotlin.Int?>, kotlin.Int>
symbol = function: kotlin.Function2<ft<T, T?>, ft<T, T?>, kotlin.Int>)
}
@@ -0,0 +1,3 @@
fun call(x: (Int) -> String) {
<expr>x(1)</expr>
}
@@ -0,0 +1,24 @@
KtSuccessCallInfo:
call = KtSimpleFunctionCall:
isImplicitInvoke = true
partiallyAppliedSymbol = KtPartiallyAppliedSymbol:
dispatchReceiver = null
extensionReceiver = null
signature = KtFunctionLikeSignature:
receiverType = null
returnType = kotlin.String
symbol = kotlin/Function1.invoke(<dispatch receiver>: kotlin.Function1<P1, R>, p1: P1): R
valueParameters = [
KtVariableLikeSignature:
name = p1
receiverType = null
returnType = kotlin.Int
symbol = p1: P1
]
argumentMapping = {
1 -> (KtVariableLikeSignature:
name = p1
receiverType = null
returnType = kotlin.Int
symbol = p1: P1)
}
@@ -0,0 +1,5 @@
operator fun Int.invoke(): String {}
fun call(x: kotlin.Int) {
<expr>x()</expr>
}
@@ -0,0 +1,12 @@
KtSuccessCallInfo:
call = KtSimpleFunctionCall:
isImplicitInvoke = true
partiallyAppliedSymbol = KtPartiallyAppliedSymbol:
dispatchReceiver = null
extensionReceiver = null
signature = KtFunctionLikeSignature:
receiverType = kotlin.Int
returnType = kotlin.String
symbol = /invoke(<extension receiver>: kotlin.Int): kotlin.String
valueParameters = []
argumentMapping = {}
@@ -14,6 +14,7 @@ import org.jetbrains.kotlin.analysis.api.impl.base.test.annotations.AbstractAnal
import org.jetbrains.kotlin.analysis.api.impl.base.test.annotations.AbstractAnalysisApiAnnotationsOnFilesTest
import org.jetbrains.kotlin.analysis.api.impl.base.test.annotations.AbstractAnalysisApiAnnotationsOnTypesTest
import org.jetbrains.kotlin.analysis.api.impl.base.test.components.AbstractResolveCallTest
import org.jetbrains.kotlin.analysis.api.impl.base.test.components.AbstractResolveCandidatesTest
import org.jetbrains.kotlin.analysis.api.impl.base.test.components.compileTimeConstantProvider.AbstractCompileTimeConstantEvaluatorTest
import org.jetbrains.kotlin.analysis.api.impl.base.test.components.diagnosticProvider.AbstractCollectDiagnosticsTest
import org.jetbrains.kotlin.analysis.api.impl.base.test.components.expressionInfoProvider.AbstractReturnTargetSymbolTest
@@ -134,6 +135,12 @@ private fun TestGroupSuite.generateAnalysisApiComponentsTests() {
test(AbstractResolveCallTest::class) {
model("resolveCall")
}
test(
AbstractResolveCandidatesTest::class,
generateFe10 = false // TODO: Not yet implemented
) {
model("resolveCandidates")
}
}
component("compileTimeConstantProvider") {