FIR IDE: Add substitutor to KtCall

This commit is contained in:
Tianyu Geng
2021-08-26 15:23:47 -07:00
committed by Ilya Kirillov
parent 9f0f1781c9
commit d2ed203528
43 changed files with 233 additions and 57 deletions
@@ -5,6 +5,24 @@
package org.jetbrains.kotlin.analysis.api.fir.components package org.jetbrains.kotlin.analysis.api.fir.components
import org.jetbrains.kotlin.analysis.api.KtAnalysisSession
import org.jetbrains.kotlin.analysis.api.calls.*
import org.jetbrains.kotlin.analysis.api.components.KtCallResolver
import org.jetbrains.kotlin.analysis.api.diagnostics.KtNonBoundToPsiErrorDiagnostic
import org.jetbrains.kotlin.analysis.api.fir.KtFirAnalysisSession
import org.jetbrains.kotlin.analysis.api.fir.buildSymbol
import org.jetbrains.kotlin.analysis.api.fir.getCandidateSymbols
import org.jetbrains.kotlin.analysis.api.fir.isImplicitFunctionCall
import org.jetbrains.kotlin.analysis.api.fir.symbols.KtFirArrayOfSymbolProvider.arrayOf
import org.jetbrains.kotlin.analysis.api.fir.symbols.KtFirArrayOfSymbolProvider.arrayOfSymbol
import org.jetbrains.kotlin.analysis.api.fir.symbols.KtFirArrayOfSymbolProvider.arrayTypeToArrayOfCall
import org.jetbrains.kotlin.analysis.api.fir.symbols.KtFirFunctionSymbol
import org.jetbrains.kotlin.analysis.api.symbols.*
import org.jetbrains.kotlin.analysis.api.symbols.markers.KtSymbolWithMembers
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.getOrBuildFir
import org.jetbrains.kotlin.builtins.StandardNames import org.jetbrains.kotlin.builtins.StandardNames
import org.jetbrains.kotlin.fir.FirSourceElement import org.jetbrains.kotlin.fir.FirSourceElement
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirDiagnostic import org.jetbrains.kotlin.fir.analysis.diagnostics.FirDiagnostic
@@ -17,26 +35,12 @@ import org.jetbrains.kotlin.fir.references.FirResolvedNamedReference
import org.jetbrains.kotlin.fir.references.FirSuperReference import org.jetbrains.kotlin.fir.references.FirSuperReference
import org.jetbrains.kotlin.fir.references.impl.FirSimpleNamedReference import org.jetbrains.kotlin.fir.references.impl.FirSimpleNamedReference
import org.jetbrains.kotlin.fir.resolve.calls.FirErrorReferenceWithCandidate import org.jetbrains.kotlin.fir.resolve.calls.FirErrorReferenceWithCandidate
import org.jetbrains.kotlin.fir.resolve.substitution.substitutorByMap
import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirNamedFunctionSymbol import org.jetbrains.kotlin.fir.symbols.impl.FirNamedFunctionSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirPropertySymbol import org.jetbrains.kotlin.fir.symbols.impl.FirPropertySymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirTypeParameterSymbol
import org.jetbrains.kotlin.fir.types.* import org.jetbrains.kotlin.fir.types.*
import org.jetbrains.kotlin.analysis.api.fir.getCandidateSymbols
import org.jetbrains.kotlin.analysis.api.fir.isImplicitFunctionCall
import org.jetbrains.kotlin.analysis.low.level.api.fir.api.getOrBuildFir
import org.jetbrains.kotlin.analysis.api.KtAnalysisSession
import org.jetbrains.kotlin.analysis.api.calls.*
import org.jetbrains.kotlin.analysis.api.components.KtCallResolver
import org.jetbrains.kotlin.analysis.api.diagnostics.KtNonBoundToPsiErrorDiagnostic
import org.jetbrains.kotlin.analysis.api.fir.KtFirAnalysisSession
import org.jetbrains.kotlin.analysis.api.fir.buildSymbol
import org.jetbrains.kotlin.analysis.api.fir.symbols.KtFirArrayOfSymbolProvider.arrayOf
import org.jetbrains.kotlin.analysis.api.fir.symbols.KtFirArrayOfSymbolProvider.arrayOfSymbol
import org.jetbrains.kotlin.analysis.api.fir.symbols.KtFirArrayOfSymbolProvider.arrayTypeToArrayOfCall
import org.jetbrains.kotlin.analysis.api.fir.symbols.KtFirFunctionSymbol
import org.jetbrains.kotlin.analysis.api.symbols.*
import org.jetbrains.kotlin.analysis.api.symbols.markers.KtSymbolWithMembers
import org.jetbrains.kotlin.analysis.api.tokens.ValidityToken
import org.jetbrains.kotlin.analysis.api.withValidityAssertion
import org.jetbrains.kotlin.idea.references.FirReferenceResolveHelper import org.jetbrains.kotlin.idea.references.FirReferenceResolveHelper
import org.jetbrains.kotlin.idea.references.readWriteAccess import org.jetbrains.kotlin.idea.references.readWriteAccess
import org.jetbrains.kotlin.name.CallableId import org.jetbrains.kotlin.name.CallableId
@@ -77,7 +81,7 @@ internal class KtFirCallResolver(
val setterParameterSymbol = accessor.valueParameters.single().buildSymbol(firSymbolBuilder) as KtValueParameterSymbol val setterParameterSymbol = accessor.valueParameters.single().buildSymbol(firSymbolBuilder) as KtValueParameterSymbol
ktArgumentMapping[setterValue] = setterParameterSymbol ktArgumentMapping[setterValue] = setterParameterSymbol
} }
return KtFunctionCall(ktArgumentMapping, target, token) return KtFunctionCall(ktArgumentMapping, target, KtSubstitutor.Empty(token), token)
} }
else -> return null else -> return null
} }
@@ -134,14 +138,32 @@ internal class KtFirCallResolver(
arrayOfCall.createArgumentMapping(defaultArrayOfSymbol), arrayOfCall.createArgumentMapping(defaultArrayOfSymbol),
KtErrorCallTarget( KtErrorCallTarget(
listOf(defaultArrayOfSymbol), listOf(defaultArrayOfSymbol),
KtNonBoundToPsiErrorDiagnostic(factoryName = null, "type of arrayOf call is not resolved", token) KtNonBoundToPsiErrorDiagnostic(factoryName = null, "type of arrayOf call is not resolved", token),
) token
),
arrayOfCall.createSubstitutorFromTypeArguments(defaultArrayOfSymbol),
token
) )
} }
val call = arrayTypeToArrayOfCall[type.lookupTag.classId] ?: arrayOf val call = arrayTypeToArrayOfCall[type.lookupTag.classId] ?: arrayOf
arrayOfSymbol(call) arrayOfSymbol(call)
} ?: return null } ?: return null
return KtFunctionCall(arrayOfCall.createArgumentMapping(arrayOfSymbol), KtSuccessCallTarget(arrayOfSymbol)) return KtFunctionCall(
arrayOfCall.createArgumentMapping(arrayOfSymbol),
KtSuccessCallTarget(arrayOfSymbol, token),
arrayOfCall.createSubstitutorFromTypeArguments(arrayOfSymbol),
token
)
}
private fun FirArrayOfCall.createSubstitutorFromTypeArguments(arrayOfSymbol: KtFirFunctionSymbol): KtSubstitutor {
return arrayOfSymbol.firRef.withFir {
// No type parameter means this is an arrayOf call of primitives, in which case there is no type arguments
val typeParameter = it.typeParameters.singleOrNull() ?: return@withFir null
val elementType = typeRef.coneTypeSafe<ConeClassLikeType>()?.arrayElementType() ?: return@withFir null
val coneSubstitutor = substitutorByMap(mapOf(typeParameter.symbol to elementType), rootModuleSession)
firSymbolBuilder.typeBuilder.buildSubstitutor(coneSubstitutor)
} ?: KtSubstitutor.Empty(token)
} }
private fun resolveCall(firCall: FirFunctionCall): KtCall? { private fun resolveCall(firCall: FirFunctionCall): KtCall? {
@@ -178,15 +200,41 @@ internal class KtFirCallResolver(
} }
val callableId = functionSymbol?.callableId ?: return null val callableId = functionSymbol?.callableId ?: return null
return if (callableId in kotlinFunctionInvokeCallableIds) { return if (callableId in kotlinFunctionInvokeCallableIds) {
KtFunctionalTypeVariableCall(variableLikeSymbol, createArgumentMapping(), target, token) // A fake override is always created for a function type with all types substituted properly inside the dispatch receiver. Hence
// there is no need for additional substitutor.
KtFunctionalTypeVariableCall(variableLikeSymbol, createArgumentMapping(), target, KtSubstitutor.Empty(token), token)
} else { } else {
KtVariableWithInvokeFunctionCall(variableLikeSymbol, createArgumentMapping(), target, token) val substitutor = createSubstitutorFromTypeArguments(functionSymbol)
KtVariableWithInvokeFunctionCall(
variableLikeSymbol,
createArgumentMapping(),
target,
substitutor, token
)
} }
} }
private fun FirFunctionCall.asSimpleFunctionCall(): KtFunctionCall? { private fun FirFunctionCall.asSimpleFunctionCall(): KtFunctionCall? {
val calleeReference = this.calleeReference
val target = calleeReference.createCallTarget() ?: return null val target = calleeReference.createCallTarget() ?: return null
return KtFunctionCall(createArgumentMapping(), target, token) val symbol = when (calleeReference) {
is FirResolvedNamedReference -> calleeReference.resolvedSymbol as? FirCallableSymbol<*>
is FirErrorNamedReference -> calleeReference.candidateSymbol as? FirCallableSymbol<*>
else -> null
} ?: return null
return KtFunctionCall(createArgumentMapping(), target, createSubstitutorFromTypeArguments(symbol), token)
}
private fun FirFunctionCall.createSubstitutorFromTypeArguments(functionSymbol: FirCallableSymbol<*>): KtSubstitutor {
val typeArgumentMap = mutableMapOf<FirTypeParameterSymbol, ConeKotlinType>()
for (i in typeArguments.indices) {
val type = typeArguments[i].safeAs<FirTypeProjectionWithVariance>()?.typeRef?.coneType
if (type != null) {
typeArgumentMap[functionSymbol.typeParameterSymbols[i]] = type
}
}
val coneSubstitutor = substitutorByMap(typeArgumentMap, rootModuleSession)
return firSymbolBuilder.typeBuilder.buildSubstitutor(coneSubstitutor)
} }
private fun FirAnnotationCall.asAnnotationCall(): KtAnnotationCall? { private fun FirAnnotationCall.asAnnotationCall(): KtAnnotationCall? {
@@ -6,17 +6,21 @@
package org.jetbrains.kotlin.analysis.api.fir.components package org.jetbrains.kotlin.analysis.api.fir.components
import com.intellij.psi.PsiElement import com.intellij.psi.PsiElement
import org.jetbrains.kotlin.analysis.api.fir.executeOnPooledThreadInReadAction
import org.jetbrains.kotlin.analysis.api.fir.test.framework.AbstractHLApiSingleModuleTest
import org.jetbrains.kotlin.analysis.low.level.api.fir.test.base.expressionMarkerProvider
import org.jetbrains.kotlin.analysis.api.KtAnalysisSession import org.jetbrains.kotlin.analysis.api.KtAnalysisSession
import org.jetbrains.kotlin.analysis.api.analyse import org.jetbrains.kotlin.analysis.api.analyse
import org.jetbrains.kotlin.analysis.api.calls.KtCall import org.jetbrains.kotlin.analysis.api.calls.KtCall
import org.jetbrains.kotlin.analysis.api.calls.KtDelegatedConstructorCallKind import org.jetbrains.kotlin.analysis.api.calls.KtDelegatedConstructorCallKind
import org.jetbrains.kotlin.analysis.api.calls.KtErrorCallTarget import org.jetbrains.kotlin.analysis.api.calls.KtErrorCallTarget
import org.jetbrains.kotlin.analysis.api.calls.KtSuccessCallTarget import org.jetbrains.kotlin.analysis.api.calls.KtSuccessCallTarget
import org.jetbrains.kotlin.analysis.api.fir.executeOnPooledThreadInReadAction
import org.jetbrains.kotlin.analysis.api.fir.test.framework.AbstractHLApiSingleModuleTest
import org.jetbrains.kotlin.analysis.api.fir.types.KtFirSubstitutor
import org.jetbrains.kotlin.analysis.api.symbols.* import org.jetbrains.kotlin.analysis.api.symbols.*
import org.jetbrains.kotlin.analysis.api.symbols.markers.KtPossibleMemberSymbol
import org.jetbrains.kotlin.analysis.api.types.KtSubstitutor
import org.jetbrains.kotlin.analysis.api.types.KtType import org.jetbrains.kotlin.analysis.api.types.KtType
import org.jetbrains.kotlin.analysis.low.level.api.fir.test.base.expressionMarkerProvider
import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutorByMap
import org.jetbrains.kotlin.psi.* import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.test.model.TestModule import org.jetbrains.kotlin.test.model.TestModule
import org.jetbrains.kotlin.test.services.TestServices import org.jetbrains.kotlin.test.services.TestServices
@@ -52,7 +56,7 @@ abstract class AbstractResolveCallTest : AbstractHLApiSingleModuleTest() {
} }
private fun KtCall.stringRepresentation(): String { private fun KtCall.stringRepresentation(): String {
fun KtType.render() = asStringForDebugging().replace('/', '.') fun KtType.render() = substitutor.substituteOrSelf(this).asStringForDebugging().replace('/', '.')
fun Any.stringValue(): String = when (this) { fun Any.stringValue(): String = when (this) {
is KtFunctionLikeSymbol -> buildString { is KtFunctionLikeSymbol -> buildString {
append( append(
@@ -66,7 +70,11 @@ private fun KtCall.stringRepresentation(): String {
) )
append("(") append("(")
(this@stringValue as? KtFunctionSymbol)?.receiverType?.let { receiver -> (this@stringValue as? KtFunctionSymbol)?.receiverType?.let { receiver ->
append("<receiver>: ${receiver.type.render()}") append("<extension receiver>: ${receiver.type.render()}")
if (valueParameters.isNotEmpty()) append(", ")
}
(this@stringValue as? KtPossibleMemberSymbol)?.dispatchType?.let { dispatchReceiverType ->
append("<dispatch receiver>: ${dispatchReceiverType.render()}")
if (valueParameters.isNotEmpty()) append(", ") if (valueParameters.isNotEmpty()) append(", ")
} }
valueParameters.joinTo(this) { it.stringValue() } valueParameters.joinTo(this) { it.stringValue() }
@@ -80,6 +88,13 @@ private fun KtCall.stringRepresentation(): String {
is Map<*, *> -> entries.joinToString(prefix = "{ ", postfix = " }") { (k, v) -> "${k?.stringValue()} -> (${v?.stringValue()})" } is Map<*, *> -> entries.joinToString(prefix = "{ ", postfix = " }") { (k, v) -> "${k?.stringValue()} -> (${v?.stringValue()})" }
is KtExpression -> this.text is KtExpression -> this.text
is KtDelegatedConstructorCallKind -> toString() is KtDelegatedConstructorCallKind -> toString()
is KtSubstitutor.Empty -> "<empty substitutor>"
is KtFirSubstitutor -> {
when (val substitutor = substitutor) {
is ConeSubstitutorByMap -> "<map substitutor: ${substitutor.substitution}>"
else -> "<complex substitutor>"
}
}
else -> error("unexpected parameter type ${this::class}") else -> error("unexpected parameter type ${this::class}")
} }
@@ -60,6 +60,12 @@ public class ResolveCallTestGenerated extends AbstractResolveCallTest {
runTest("analysis/analysis-api/testData/analysisSession/resolveCall/functionCallInTheSameFile.kt"); runTest("analysis/analysis-api/testData/analysisSession/resolveCall/functionCallInTheSameFile.kt");
} }
@Test
@TestMetadata("functionCallWithExtensionReceiverAndTypeArgument.kt")
public void testFunctionCallWithExtensionReceiverAndTypeArgument() throws Exception {
runTest("analysis/analysis-api/testData/analysisSession/resolveCall/functionCallWithExtensionReceiverAndTypeArgument.kt");
}
@Test @Test
@TestMetadata("functionCallWithLambdaArgument.kt") @TestMetadata("functionCallWithLambdaArgument.kt")
public void testFunctionCallWithLambdaArgument() throws Exception { public void testFunctionCallWithLambdaArgument() throws Exception {
@@ -84,6 +90,12 @@ public class ResolveCallTestGenerated extends AbstractResolveCallTest {
runTest("analysis/analysis-api/testData/analysisSession/resolveCall/functionCallWithSpreadArgument.kt"); runTest("analysis/analysis-api/testData/analysisSession/resolveCall/functionCallWithSpreadArgument.kt");
} }
@Test
@TestMetadata("functionCallWithTypeArgument.kt")
public void testFunctionCallWithTypeArgument() throws Exception {
runTest("analysis/analysis-api/testData/analysisSession/resolveCall/functionCallWithTypeArgument.kt");
}
@Test @Test
@TestMetadata("functionCallWithVarargArgument.kt") @TestMetadata("functionCallWithVarargArgument.kt")
public void testFunctionCallWithVarargArgument() throws Exception { public void testFunctionCallWithVarargArgument() throws Exception {
@@ -210,6 +222,12 @@ public class ResolveCallTestGenerated extends AbstractResolveCallTest {
runTest("analysis/analysis-api/testData/analysisSession/resolveCall/kotlinPropertySetter.kt"); runTest("analysis/analysis-api/testData/analysisSession/resolveCall/kotlinPropertySetter.kt");
} }
@Test
@TestMetadata("memberFunctionCallWithTypeArgument.kt")
public void testMemberFunctionCallWithTypeArgument() throws Exception {
runTest("analysis/analysis-api/testData/analysisSession/resolveCall/memberFunctionCallWithTypeArgument.kt");
}
@Test @Test
@TestMetadata("resolveCallInSuperConstructorParam.kt") @TestMetadata("resolveCallInSuperConstructorParam.kt")
public void testResolveCallInSuperConstructorParam() throws Exception { public void testResolveCallInSuperConstructorParam() throws Exception {
@@ -239,4 +257,10 @@ public class ResolveCallTestGenerated extends AbstractResolveCallTest {
public void testVariableAsFunctionLikeCall() throws Exception { public void testVariableAsFunctionLikeCall() throws Exception {
runTest("analysis/analysis-api/testData/analysisSession/resolveCall/variableAsFunctionLikeCall.kt"); runTest("analysis/analysis-api/testData/analysisSession/resolveCall/variableAsFunctionLikeCall.kt");
} }
@Test
@TestMetadata("variableWithInvoke.kt")
public void testVariableWithInvoke() throws Exception {
runTest("analysis/analysis-api/testData/analysisSession/resolveCall/variableWithInvoke.kt");
}
} }
@@ -11,6 +11,7 @@ import org.jetbrains.kotlin.analysis.api.symbols.KtFunctionLikeSymbol
import org.jetbrains.kotlin.analysis.api.symbols.KtValueParameterSymbol import org.jetbrains.kotlin.analysis.api.symbols.KtValueParameterSymbol
import org.jetbrains.kotlin.analysis.api.symbols.KtVariableLikeSymbol import org.jetbrains.kotlin.analysis.api.symbols.KtVariableLikeSymbol
import org.jetbrains.kotlin.analysis.api.tokens.ValidityToken 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.api.withValidityAssertion
import org.jetbrains.kotlin.psi.KtExpression import org.jetbrains.kotlin.psi.KtExpression
@@ -21,6 +22,7 @@ public sealed class KtCall : ValidityTokenOwner {
public abstract val isErrorCall: Boolean public abstract val isErrorCall: Boolean
public abstract val argumentMapping: LinkedHashMap<KtExpression, KtValueParameterSymbol> public abstract val argumentMapping: LinkedHashMap<KtExpression, KtValueParameterSymbol>
public abstract val targetFunction: KtCallTarget public abstract val targetFunction: KtCallTarget
public abstract val substitutor: KtSubstitutor
} }
/** /**
@@ -34,6 +36,7 @@ public class KtFunctionalTypeVariableCall(
private val _target: KtVariableLikeSymbol, private val _target: KtVariableLikeSymbol,
private val _argumentMapping: LinkedHashMap<KtExpression, KtValueParameterSymbol>, private val _argumentMapping: LinkedHashMap<KtExpression, KtValueParameterSymbol>,
private val _targetFunction: KtCallTarget, private val _targetFunction: KtCallTarget,
private val _substitutor: KtSubstitutor,
override val token: ValidityToken override val token: ValidityToken
) : KtCall() { ) : KtCall() {
public val target: KtVariableLikeSymbol get() = withValidityAssertion { _target } public val target: KtVariableLikeSymbol get() = withValidityAssertion { _target }
@@ -42,6 +45,8 @@ public class KtFunctionalTypeVariableCall(
get() = withValidityAssertion { _argumentMapping } get() = withValidityAssertion { _argumentMapping }
override val targetFunction: KtCallTarget override val targetFunction: KtCallTarget
get() = withValidityAssertion { _targetFunction } get() = withValidityAssertion { _targetFunction }
override val substitutor: KtSubstitutor
get() = withValidityAssertion { _substitutor }
} }
/** /**
@@ -65,12 +70,15 @@ public class KtVariableWithInvokeFunctionCall(
public val target: KtVariableLikeSymbol, public val target: KtVariableLikeSymbol,
private val _argumentMapping: LinkedHashMap<KtExpression, KtValueParameterSymbol>, private val _argumentMapping: LinkedHashMap<KtExpression, KtValueParameterSymbol>,
private val _targetFunction: KtCallTarget, private val _targetFunction: KtCallTarget,
private val _substitutor: KtSubstitutor,
override val token: ValidityToken override val token: ValidityToken
) : KtDeclaredFunctionCall() { ) : KtDeclaredFunctionCall() {
override val argumentMapping: LinkedHashMap<KtExpression, KtValueParameterSymbol> override val argumentMapping: LinkedHashMap<KtExpression, KtValueParameterSymbol>
get() = withValidityAssertion { _argumentMapping } get() = withValidityAssertion { _argumentMapping }
override val targetFunction: KtCallTarget override val targetFunction: KtCallTarget
get() = withValidityAssertion { _targetFunction } get() = withValidityAssertion { _targetFunction }
override val substitutor: KtSubstitutor
get() = withValidityAssertion { _substitutor }
} }
/** /**
@@ -81,12 +89,15 @@ public class KtVariableWithInvokeFunctionCall(
public class KtFunctionCall( public class KtFunctionCall(
private val _argumentMapping: LinkedHashMap<KtExpression, KtValueParameterSymbol>, private val _argumentMapping: LinkedHashMap<KtExpression, KtValueParameterSymbol>,
private val _targetFunction: KtCallTarget, private val _targetFunction: KtCallTarget,
private val _substitutor: KtSubstitutor,
override val token: ValidityToken override val token: ValidityToken
) : KtDeclaredFunctionCall() { ) : KtDeclaredFunctionCall() {
override val argumentMapping: LinkedHashMap<KtExpression, KtValueParameterSymbol> override val argumentMapping: LinkedHashMap<KtExpression, KtValueParameterSymbol>
get() = withValidityAssertion { _argumentMapping } get() = withValidityAssertion { _argumentMapping }
override val targetFunction: KtCallTarget override val targetFunction: KtCallTarget
get() = withValidityAssertion { _targetFunction } get() = withValidityAssertion { _targetFunction }
override val substitutor: KtSubstitutor
get() = withValidityAssertion { _substitutor }
} }
/** /**
@@ -104,6 +115,9 @@ public class KtAnnotationCall(
get() = withValidityAssertion { _argumentMapping } get() = withValidityAssertion { _argumentMapping }
override val targetFunction: KtCallTarget override val targetFunction: KtCallTarget
get() = withValidityAssertion { _targetFunction } get() = withValidityAssertion { _targetFunction }
// Type parameter is allowed for an annotation class but not allowed as members. So substitutor is probably never useful.
override val substitutor: KtSubstitutor = KtSubstitutor.Empty(token)
} }
// TODO: Add other properties, e.g., useSiteTarget // TODO: Add other properties, e.g., useSiteTarget
@@ -125,6 +139,9 @@ public class KtDelegatedConstructorCall(
get() = withValidityAssertion { _argumentMapping } get() = withValidityAssertion { _argumentMapping }
override val targetFunction: KtCallTarget override val targetFunction: KtCallTarget
get() = withValidityAssertion { _targetFunction } get() = withValidityAssertion { _targetFunction }
// A delegate constructor call never has any type argument.
override val substitutor: KtSubstitutor = KtSubstitutor.Empty(token)
} }
public enum class KtDelegatedConstructorCallKind { SUPER_CALL, THIS_CALL } public enum class KtDelegatedConstructorCallKind { SUPER_CALL, THIS_CALL }
@@ -1,3 +1,4 @@
KtFunctionCall: KtFunctionCall:
argumentMapping = { 1 -> (vararg elements: T), 2 -> (vararg elements: T), 3 -> (vararg elements: T) } argumentMapping = { 1 -> (vararg elements: kotlin.Int), 2 -> (vararg elements: kotlin.Int), 3 -> (vararg elements: kotlin.Int) }
targetFunction = kotlin/arrayOf(vararg elements: T): kotlin.Array<T> targetFunction = kotlin/arrayOf(vararg elements: kotlin.Int): kotlin.Array<kotlin.Int>
substitutor = <map substitutor: {FirTypeParameterSymbol T=kotlin/Int}>
@@ -1,3 +1,4 @@
KtFunctionCall: KtFunctionCall:
argumentMapping = { 1 -> (a: kotlin.Int) } argumentMapping = { 1 -> (a: kotlin.Int) }
targetFunction = /function(a: kotlin.Int): kotlin.Unit targetFunction = /function(a: kotlin.Int): kotlin.Unit
substitutor = <empty substitutor>
@@ -0,0 +1,5 @@
fun <A, B> A.function(a: B) {}
fun call() {
"str".<expr>function(1)</expr>
}
@@ -0,0 +1,4 @@
KtFunctionCall:
argumentMapping = { 1 -> (a: kotlin.Int) }
targetFunction = /function(<extension receiver>: kotlin.String, a: kotlin.Int): kotlin.Unit
substitutor = <map substitutor: {FirTypeParameterSymbol A=kotlin/String, FirTypeParameterSymbol B=kotlin/Int}>
@@ -1,3 +1,4 @@
KtFunctionCall: KtFunctionCall:
argumentMapping = { 1 -> (a: kotlin.Int), { s -> true } -> (b: kotlin.Function1<kotlin.String, kotlin.Boolean>) } argumentMapping = { 1 -> (a: kotlin.Int), { s -> true } -> (b: kotlin.Function1<kotlin.String, kotlin.Boolean>) }
targetFunction = /function(a: kotlin.Int, b: kotlin.Function1<kotlin.String, kotlin.Boolean>): kotlin.Unit targetFunction = /function(a: kotlin.Int, b: kotlin.Function1<kotlin.String, kotlin.Boolean>): kotlin.Unit
substitutor = <empty substitutor>
@@ -1,3 +1,4 @@
KtFunctionCall: KtFunctionCall:
argumentMapping = { "foo" -> (b: kotlin.String), 1 -> (a: kotlin.Int) } argumentMapping = { "foo" -> (b: kotlin.String), 1 -> (a: kotlin.Int) }
targetFunction = /function(a: kotlin.Int, b: kotlin.String): kotlin.Unit targetFunction = /function(a: kotlin.Int, b: kotlin.String): kotlin.Unit
substitutor = <empty substitutor>
@@ -1,3 +1,4 @@
KtFunctionCall: KtFunctionCall:
argumentMapping = { 1 -> (a: kotlin.Int), { s -> true } -> (b: kotlin.Function1<kotlin.String, kotlin.Boolean>) } argumentMapping = { 1 -> (a: kotlin.Int), { s -> true } -> (b: kotlin.Function1<kotlin.String, kotlin.Boolean>) }
targetFunction = /function(a: kotlin.Int, b: kotlin.Function1<kotlin.String, kotlin.Boolean>): kotlin.Unit targetFunction = /function(a: kotlin.Int, b: kotlin.Function1<kotlin.String, kotlin.Boolean>): kotlin.Unit
substitutor = <empty substitutor>
@@ -1,3 +1,4 @@
KtFunctionCall: KtFunctionCall:
argumentMapping = { args -> (vararg a: kotlin.Int) } argumentMapping = { args -> (vararg a: kotlin.Int) }
targetFunction = /function(vararg a: kotlin.Int): kotlin.Unit targetFunction = /function(vararg a: kotlin.Int): kotlin.Unit
substitutor = <empty substitutor>
@@ -0,0 +1,5 @@
fun <A, B> function(a: A, b: B) {}
fun call() {
<expr>function(1, "")</expr>
}
@@ -0,0 +1,4 @@
KtFunctionCall:
argumentMapping = { 1 -> (a: kotlin.Int), "" -> (b: kotlin.String) }
targetFunction = /function(a: kotlin.Int, b: kotlin.String): kotlin.Unit
substitutor = <map substitutor: {FirTypeParameterSymbol A=kotlin/Int, FirTypeParameterSymbol B=kotlin/String}>
@@ -1,3 +1,4 @@
KtFunctionCall: KtFunctionCall:
argumentMapping = { 1 -> (vararg a: kotlin.Int), 2 -> (vararg a: kotlin.Int), 3 -> (vararg a: kotlin.Int) } argumentMapping = { 1 -> (vararg a: kotlin.Int), 2 -> (vararg a: kotlin.Int), 3 -> (vararg a: kotlin.Int) }
targetFunction = /function(vararg a: kotlin.Int): kotlin.Unit targetFunction = /function(vararg a: kotlin.Int): kotlin.Unit
substitutor = <empty substitutor>
@@ -1,3 +1,4 @@
KtFunctionCall: KtFunctionCall:
argumentMapping = { 1 -> (a: kotlin.Int) } argumentMapping = { 1 -> (a: kotlin.Int) }
targetFunction = /function(<receiver>: kotlin.String, a: kotlin.Int): kotlin.Unit targetFunction = /function(<extension receiver>: kotlin.String, a: kotlin.Int): kotlin.Unit
substitutor = <empty substitutor>
@@ -1,3 +1,4 @@
KtFunctionCall: KtFunctionCall:
argumentMapping = { 1 -> (a: kotlin.Int) } argumentMapping = { 1 -> (a: kotlin.Int) }
targetFunction = /function(<receiver>: kotlin.String, a: kotlin.Int): kotlin.Unit targetFunction = /function(<extension receiver>: kotlin.String, a: kotlin.Int): kotlin.Unit
substitutor = <empty substitutor>
@@ -1,3 +1,4 @@
KtFunctionCall: KtFunctionCall:
argumentMapping = { 42 -> (i: kotlin.Int) } argumentMapping = { 42 -> (i: kotlin.Int) }
targetFunction = <constructor>(i: kotlin.Int): A targetFunction = <constructor>(i: kotlin.Int): A
substitutor = <empty substitutor>
@@ -1,3 +1,4 @@
KtFunctionCall: KtFunctionCall:
argumentMapping = { } argumentMapping = { }
targetFunction = <constructor>(): A targetFunction = <constructor>(): A
substitutor = <empty substitutor>
@@ -1,3 +1,4 @@
KtFunctionCall: KtFunctionCall:
argumentMapping = { } argumentMapping = { }
targetFunction = <constructor>(): A targetFunction = <constructor>(): A
substitutor = <empty substitutor>
@@ -1,3 +1,4 @@
KtFunctionCall: KtFunctionCall:
argumentMapping = { 1 -> (a: kotlin.Int), "foo" -> (b: kotlin.String) } argumentMapping = { 1 -> (a: kotlin.Int), "foo" -> (b: kotlin.String) }
targetFunction = /C.get(a: kotlin.Int, b: kotlin.String): kotlin.Boolean targetFunction = /C.get(<dispatch receiver>: C, a: kotlin.Int, b: kotlin.String): kotlin.Boolean
substitutor = <empty substitutor>
@@ -1,3 +1,4 @@
KtFunctionCall: KtFunctionCall:
argumentMapping = { 1 -> (a: kotlin.Int) } argumentMapping = { 1 -> (a: kotlin.Int) }
targetFunction = ERR<No value passed for parameter 'b', [/C.get(a: kotlin.Int, b: kotlin.String): kotlin.Boolean]> targetFunction = ERR<No value passed for parameter 'b', [/C.get(<dispatch receiver>: C, a: kotlin.Int, b: kotlin.String): kotlin.Boolean]>
substitutor = <empty substitutor>
@@ -1,3 +1,4 @@
KtFunctionCall: KtFunctionCall:
argumentMapping = { 1 -> (a: kotlin.Int), "foo" -> (b: kotlin.String) } argumentMapping = { 1 -> (a: kotlin.Int), "foo" -> (b: kotlin.String) }
targetFunction = ERR<Too many arguments for public final operator fun /C.get(a: R|kotlin/Int|, b: R|kotlin/String|): R|kotlin/Boolean|, [/C.get(a: kotlin.Int, b: kotlin.String): kotlin.Boolean]> targetFunction = ERR<Too many arguments for public final operator fun /C.get(a: R|kotlin/Int|, b: R|kotlin/String|): R|kotlin/Boolean|, [/C.get(<dispatch receiver>: C, a: kotlin.Int, b: kotlin.String): kotlin.Boolean]>
substitutor = <empty substitutor>
@@ -1,3 +1,4 @@
KtFunctionCall: KtFunctionCall:
argumentMapping = { 1 -> (a: kotlin.Int), "foo" -> (b: kotlin.String), false -> (value: kotlin.Boolean) } argumentMapping = { 1 -> (a: kotlin.Int), "foo" -> (b: kotlin.String), false -> (value: kotlin.Boolean) }
targetFunction = /C.set(a: kotlin.Int, b: kotlin.String, value: kotlin.Boolean): kotlin.Unit targetFunction = /C.set(<dispatch receiver>: C, a: kotlin.Int, b: kotlin.String, value: kotlin.Boolean): kotlin.Unit
substitutor = <empty substitutor>
@@ -1,3 +1,4 @@
KtFunctionCall: KtFunctionCall:
argumentMapping = { 1 -> (a: kotlin.Int), false -> (value: kotlin.Boolean) } argumentMapping = { 1 -> (a: kotlin.Int), false -> (value: kotlin.Boolean) }
targetFunction = ERR<No value passed for parameter 'b', [/C.set(a: kotlin.Int, b: kotlin.String, value: kotlin.Boolean): kotlin.Unit]> targetFunction = ERR<No value passed for parameter 'b', [/C.set(<dispatch receiver>: C, a: kotlin.Int, b: kotlin.String, value: kotlin.Boolean): kotlin.Unit]>
substitutor = <empty substitutor>
@@ -1,3 +1,4 @@
KtFunctionCall: KtFunctionCall:
argumentMapping = { 1 -> (a: kotlin.Int), "foo" -> (b: kotlin.String), false -> (value: kotlin.Boolean) } argumentMapping = { 1 -> (a: kotlin.Int), "foo" -> (b: kotlin.String), false -> (value: kotlin.Boolean) }
targetFunction = ERR<Too many arguments for public final operator fun /C.set(a: R|kotlin/Int|, b: R|kotlin/String|, value: R|kotlin/Boolean|): R|kotlin/Unit|, [/C.set(a: kotlin.Int, b: kotlin.String, value: kotlin.Boolean): kotlin.Unit]> targetFunction = ERR<Too many arguments for public final operator fun /C.set(a: R|kotlin/Int|, b: R|kotlin/String|, value: R|kotlin/Boolean|): R|kotlin/Unit|, [/C.set(<dispatch receiver>: C, a: kotlin.Int, b: kotlin.String, value: kotlin.Boolean): kotlin.Unit]>
substitutor = <empty substitutor>
@@ -1,3 +1,4 @@
KtFunctionCall: KtFunctionCall:
argumentMapping = { 1 -> (vararg elements: kotlin.Int), 2 -> (vararg elements: kotlin.Int), 3 -> (vararg elements: kotlin.Int) } argumentMapping = { 1 -> (vararg elements: kotlin.Int), 2 -> (vararg elements: kotlin.Int), 3 -> (vararg elements: kotlin.Int) }
targetFunction = kotlin/intArrayOf(vararg elements: kotlin.Int): kotlin.IntArray targetFunction = kotlin/intArrayOf(vararg elements: kotlin.Int): kotlin.IntArray
substitutor = <empty substitutor>
@@ -1,3 +1,4 @@
KtFunctionCall: KtFunctionCall:
argumentMapping = { } argumentMapping = { }
targetFunction = /JavaClass.javaMethod(): kotlin.Unit targetFunction = /JavaClass.javaMethod(<dispatch receiver>: JavaClass): kotlin.Unit
substitutor = <empty substitutor>
@@ -1,3 +1,4 @@
KtFunctionCall: KtFunctionCall:
argumentMapping = { } argumentMapping = { }
targetFunction = /JavaClass.getFoo(): kotlin.Int targetFunction = /JavaClass.getFoo(<dispatch receiver>: JavaClass): kotlin.Int
substitutor = <empty substitutor>
@@ -1,3 +1,4 @@
KtFunctionCall: KtFunctionCall:
argumentMapping = { } argumentMapping = { }
targetFunction = /JavaClass.getSub(): ft<JavaSubClass, JavaSubClass?> targetFunction = /JavaClass.getSub(<dispatch receiver>: JavaClass): ft<JavaSubClass, JavaSubClass?>
substitutor = <empty substitutor>
@@ -1,3 +1,4 @@
KtFunctionCall: KtFunctionCall:
argumentMapping = { 42 -> (v: kotlin.Int) } argumentMapping = { 42 -> (v: kotlin.Int) }
targetFunction = /JavaClass.setFoo(v: kotlin.Int): kotlin.Unit targetFunction = /JavaClass.setFoo(<dispatch receiver>: JavaClass, v: kotlin.Int): kotlin.Unit
substitutor = <empty substitutor>
@@ -1,3 +1,4 @@
KtFunctionCall: KtFunctionCall:
argumentMapping = { } argumentMapping = { }
targetFunction = ERR<Setter value is missing, [/JavaClass.setFoo(v: kotlin.Int): kotlin.Unit]> targetFunction = ERR<Setter value is missing, [/JavaClass.setFoo(<dispatch receiver>: JavaClass, v: kotlin.Int): kotlin.Unit]>
substitutor = <empty substitutor>
@@ -1,3 +1,4 @@
KtFunctionCall: KtFunctionCall:
argumentMapping = { } argumentMapping = { }
targetFunction = <getter>(): kotlin.Int targetFunction = <getter>(): kotlin.Int
substitutor = <empty substitutor>
@@ -1,3 +1,4 @@
KtFunctionCall: KtFunctionCall:
argumentMapping = { } argumentMapping = { }
targetFunction = <getter>(): KtSubClass targetFunction = <getter>(): KtSubClass
substitutor = <empty substitutor>
@@ -1,3 +1,4 @@
KtFunctionCall: KtFunctionCall:
argumentMapping = { 42 -> (value: kotlin.Int) } argumentMapping = { 42 -> (value: kotlin.Int) }
targetFunction = <setter>(value: kotlin.Int): kotlin.Unit targetFunction = <setter>(value: kotlin.Int): kotlin.Unit
substitutor = <empty substitutor>
@@ -0,0 +1,7 @@
interface A<T> {
fun <R> foo(r: R)
}
fun call(a: A<String>) {
a.<expr>foo(1)</expr>
}
@@ -0,0 +1,4 @@
KtFunctionCall:
argumentMapping = { 1 -> (r: kotlin.Int) }
targetFunction = /A.foo(<dispatch receiver>: A<kotlin.String>, r: kotlin.Int): kotlin.Unit
substitutor = <map substitutor: {FirTypeParameterSymbol R=kotlin/Int}>
@@ -1,3 +1,4 @@
KtFunctionCall: KtFunctionCall:
argumentMapping = { 2 -> (other: B) } argumentMapping = { 2 -> (other: kotlin.Int) }
targetFunction = /to(<receiver>: A, other: B): A targetFunction = /to(<extension receiver>: kotlin.Int, other: kotlin.Int): kotlin.Int
substitutor = <map substitutor: {FirTypeParameterSymbol A=kotlin/Int, FirTypeParameterSymbol B=kotlin/Int}>
@@ -1,3 +1,4 @@
KtFunctionCall: KtFunctionCall:
argumentMapping = { } argumentMapping = { }
targetFunction = ERR<Too many arguments for public final fun /foo(): R|kotlin/Unit|, [/foo(): kotlin.Unit]> targetFunction = ERR<Too many arguments for public final fun /foo(): R|kotlin/Unit|, [/foo(): kotlin.Unit]>
substitutor = <empty substitutor>
@@ -1,4 +1,5 @@
KtFunctionalTypeVariableCall: KtFunctionalTypeVariableCall:
target = x: kotlin.Function1<kotlin.Int, kotlin.String> target = x: kotlin.Function1<kotlin.Int, kotlin.String>
argumentMapping = { 1 -> (p1: kotlin.Int) } argumentMapping = { 1 -> (p1: kotlin.Int) }
targetFunction = kotlin/Function1.invoke(p1: kotlin.Int): kotlin.String targetFunction = kotlin/Function1.invoke(<dispatch receiver>: kotlin.Function1<kotlin.Int, kotlin.String>, p1: kotlin.Int): kotlin.String
substitutor = <empty substitutor>
@@ -1,3 +1,4 @@
KtFunctionCall: KtFunctionCall:
argumentMapping = { } argumentMapping = { }
targetFunction = /invoke(<receiver>: kotlin.Int): kotlin.String targetFunction = /invoke(<extension receiver>: kotlin.Int): kotlin.String
substitutor = <empty substitutor>
@@ -0,0 +1,7 @@
interface Foo {
operator fun <T> invoke(t: T)
}
fun test(f: Foo) {
<expr>f("")</expr>
}
@@ -0,0 +1,5 @@
KtVariableWithInvokeFunctionCall:
target = f: Foo
argumentMapping = { "" -> (t: kotlin.String) }
targetFunction = /Foo.invoke(<dispatch receiver>: Foo, t: kotlin.String): kotlin.Unit
substitutor = <map substitutor: {FirTypeParameterSymbol T=kotlin/String}>