Analysis API: Fix issues related to implicit invoke calls:
- Correctly set explicit receiver value. - Restore original function call from FirImplicitFunctionCall (i.e., calls implicitly resolved to `invoke`) to get the correct name for getting all candidates. - Collect candidates at all tower levels. Also make order of candidate calls in tests deterministic.
This commit is contained in:
committed by
Ilya Kirillov
parent
ace826c570
commit
9b9da94a09
+6
@@ -40,6 +40,12 @@ public class Fe10ResolveCallTestGenerated extends AbstractResolveCallTest {
|
|||||||
runTest("analysis/analysis-api/testData/components/callResolver/resolveCall/ambiguous.kt");
|
runTest("analysis/analysis-api/testData/components/callResolver/resolveCall/ambiguous.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("ambiguousImplicitInvoke.kt")
|
||||||
|
public void testAmbiguousImplicitInvoke() throws Exception {
|
||||||
|
runTest("analysis/analysis-api/testData/components/callResolver/resolveCall/ambiguousImplicitInvoke.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestMetadata("ambiguousWithExplicitTypeParameters.kt")
|
@TestMetadata("ambiguousWithExplicitTypeParameters.kt")
|
||||||
public void testAmbiguousWithExplicitTypeParameters() throws Exception {
|
public void testAmbiguousWithExplicitTypeParameters() throws Exception {
|
||||||
|
|||||||
@@ -42,7 +42,10 @@ fun FirFunctionCall.isImplicitFunctionCall(): Boolean {
|
|||||||
calleeReference.getCandidateSymbols().any(FirBasedSymbol<*>::isInvokeFunction)
|
calleeReference.getCandidateSymbols().any(FirBasedSymbol<*>::isInvokeFunction)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun FirBasedSymbol<*>.isInvokeFunction() =
|
/**
|
||||||
|
* Returns `true` if the symbol is for a function named `invoke`.
|
||||||
|
*/
|
||||||
|
internal fun FirBasedSymbol<*>.isInvokeFunction() =
|
||||||
(this as? FirNamedFunctionSymbol)?.fir?.name == OperatorNameConventions.INVOKE
|
(this as? FirNamedFunctionSymbol)?.fir?.name == OperatorNameConventions.INVOKE
|
||||||
|
|
||||||
fun FirFunctionCall.getCalleeSymbol(): FirBasedSymbol<*>? =
|
fun FirFunctionCall.getCalleeSymbol(): FirBasedSymbol<*>? =
|
||||||
|
|||||||
+147
-84
@@ -9,11 +9,13 @@ import org.jetbrains.kotlin.analysis.api.calls.*
|
|||||||
import org.jetbrains.kotlin.analysis.api.diagnostics.KtNonBoundToPsiErrorDiagnostic
|
import org.jetbrains.kotlin.analysis.api.diagnostics.KtNonBoundToPsiErrorDiagnostic
|
||||||
import org.jetbrains.kotlin.analysis.api.fir.KtFirAnalysisSession
|
import org.jetbrains.kotlin.analysis.api.fir.KtFirAnalysisSession
|
||||||
import org.jetbrains.kotlin.analysis.api.fir.getCandidateSymbols
|
import org.jetbrains.kotlin.analysis.api.fir.getCandidateSymbols
|
||||||
|
import org.jetbrains.kotlin.analysis.api.fir.isInvokeFunction
|
||||||
import org.jetbrains.kotlin.analysis.api.fir.symbols.KtFirArrayOfSymbolProvider.arrayOf
|
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.arrayOfSymbol
|
||||||
import org.jetbrains.kotlin.analysis.api.fir.symbols.KtFirArrayOfSymbolProvider.arrayTypeToArrayOfCall
|
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.fir.symbols.KtFirFunctionSymbol
|
||||||
import org.jetbrains.kotlin.analysis.api.impl.barebone.parentOfType
|
import org.jetbrains.kotlin.analysis.api.impl.barebone.parentOfType
|
||||||
|
import org.jetbrains.kotlin.analysis.api.impl.barebone.parentsOfType
|
||||||
import org.jetbrains.kotlin.analysis.api.impl.base.components.AbstractKtCallResolver
|
import org.jetbrains.kotlin.analysis.api.impl.base.components.AbstractKtCallResolver
|
||||||
import org.jetbrains.kotlin.analysis.api.symbols.*
|
import org.jetbrains.kotlin.analysis.api.symbols.*
|
||||||
import org.jetbrains.kotlin.analysis.api.tokens.ValidityToken
|
import org.jetbrains.kotlin.analysis.api.tokens.ValidityToken
|
||||||
@@ -21,14 +23,16 @@ 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.analysis.low.level.api.fir.api.getOrBuildFir
|
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.analysis.low.level.api.fir.api.getOrBuildFirFile
|
||||||
|
import org.jetbrains.kotlin.analysis.low.level.api.fir.api.resolveToFirSymbol
|
||||||
import org.jetbrains.kotlin.diagnostics.KtDiagnostic
|
import org.jetbrains.kotlin.diagnostics.KtDiagnostic
|
||||||
import org.jetbrains.kotlin.fir.*
|
import org.jetbrains.kotlin.fir.*
|
||||||
import org.jetbrains.kotlin.fir.analysis.checkers.toRegularClassSymbol
|
import org.jetbrains.kotlin.fir.analysis.checkers.toRegularClassSymbol
|
||||||
import org.jetbrains.kotlin.fir.declarations.FirDeclaration
|
|
||||||
import org.jetbrains.kotlin.fir.declarations.FirFile
|
import org.jetbrains.kotlin.fir.declarations.FirFile
|
||||||
import org.jetbrains.kotlin.fir.declarations.FirResolvePhase
|
import org.jetbrains.kotlin.fir.declarations.FirResolvePhase
|
||||||
import org.jetbrains.kotlin.fir.declarations.FirValueParameter
|
import org.jetbrains.kotlin.fir.declarations.FirValueParameter
|
||||||
import org.jetbrains.kotlin.fir.expressions.*
|
import org.jetbrains.kotlin.fir.expressions.*
|
||||||
|
import org.jetbrains.kotlin.fir.expressions.builder.buildFunctionCall
|
||||||
|
import org.jetbrains.kotlin.fir.expressions.impl.FirNoReceiverExpression
|
||||||
import org.jetbrains.kotlin.fir.references.FirErrorNamedReference
|
import org.jetbrains.kotlin.fir.references.FirErrorNamedReference
|
||||||
import org.jetbrains.kotlin.fir.references.FirNamedReference
|
import org.jetbrains.kotlin.fir.references.FirNamedReference
|
||||||
import org.jetbrains.kotlin.fir.references.FirResolvedNamedReference
|
import org.jetbrains.kotlin.fir.references.FirResolvedNamedReference
|
||||||
@@ -38,6 +42,7 @@ import org.jetbrains.kotlin.fir.resolve.calls.AbstractCandidate
|
|||||||
import org.jetbrains.kotlin.fir.resolve.calls.Candidate
|
import org.jetbrains.kotlin.fir.resolve.calls.Candidate
|
||||||
import org.jetbrains.kotlin.fir.resolve.calls.ResolutionContext
|
import org.jetbrains.kotlin.fir.resolve.calls.ResolutionContext
|
||||||
import org.jetbrains.kotlin.fir.resolve.createConeDiagnosticForCandidateWithError
|
import org.jetbrains.kotlin.fir.resolve.createConeDiagnosticForCandidateWithError
|
||||||
|
import org.jetbrains.kotlin.fir.resolve.dfa.unwrapSmartcastExpression
|
||||||
import org.jetbrains.kotlin.fir.resolve.diagnostics.ConeDiagnosticWithCandidates
|
import org.jetbrains.kotlin.fir.resolve.diagnostics.ConeDiagnosticWithCandidates
|
||||||
import org.jetbrains.kotlin.fir.resolve.diagnostics.ConeHiddenCandidateError
|
import org.jetbrains.kotlin.fir.resolve.diagnostics.ConeHiddenCandidateError
|
||||||
import org.jetbrains.kotlin.fir.resolve.fullyExpandedType
|
import org.jetbrains.kotlin.fir.resolve.fullyExpandedType
|
||||||
@@ -52,8 +57,10 @@ import org.jetbrains.kotlin.fir.symbols.SymbolInternals
|
|||||||
import org.jetbrains.kotlin.fir.symbols.impl.*
|
import org.jetbrains.kotlin.fir.symbols.impl.*
|
||||||
import org.jetbrains.kotlin.fir.types.*
|
import org.jetbrains.kotlin.fir.types.*
|
||||||
import org.jetbrains.kotlin.lexer.KtTokens
|
import org.jetbrains.kotlin.lexer.KtTokens
|
||||||
|
import org.jetbrains.kotlin.name.Name
|
||||||
import org.jetbrains.kotlin.psi.*
|
import org.jetbrains.kotlin.psi.*
|
||||||
import org.jetbrains.kotlin.psi.KtPsiUtil.deparenthesize
|
import org.jetbrains.kotlin.psi.KtPsiUtil.deparenthesize
|
||||||
|
import org.jetbrains.kotlin.resolve.calls.tasks.ExplicitReceiverKind
|
||||||
import org.jetbrains.kotlin.toKtPsiSourceElement
|
import org.jetbrains.kotlin.toKtPsiSourceElement
|
||||||
import org.jetbrains.kotlin.util.OperatorNameConventions
|
import org.jetbrains.kotlin.util.OperatorNameConventions
|
||||||
import org.jetbrains.kotlin.util.OperatorNameConventions.EQUALS
|
import org.jetbrains.kotlin.util.OperatorNameConventions.EQUALS
|
||||||
@@ -255,59 +262,88 @@ internal class KtFirCallResolver(
|
|||||||
handleCompoundAccessCall(psi, fir, resolveFragmentOfCall)?.let { return it }
|
handleCompoundAccessCall(psi, fir, resolveFragmentOfCall)?.let { return it }
|
||||||
|
|
||||||
var firstArgIsExtensionReceiver = false
|
var firstArgIsExtensionReceiver = false
|
||||||
|
var isImplicitInvoke = false
|
||||||
|
|
||||||
val partiallyAppliedSymbol = if (candidate != null) {
|
// TODO: Ideally, we should get the substitutor from the candidate. But it seems there is no way to get the substitutor from the
|
||||||
// TODO: Ideally, we should get the substitutor from the candidate. But it seems there is no way to get the substitutor from the
|
// candidate, `Candidate.substitutor` is not complete. maybe we can carry over the final substitutor if it's available from
|
||||||
// candidate, `Candidate.substitutor` is not complete. maybe we can carry over the final substitutor if it's available from
|
// body resolve phase?
|
||||||
// body resolve phase?
|
val substitutor =
|
||||||
val substitutor =
|
(fir as? FirQualifiedAccess)?.createSubstitutorFromTypeArguments(targetSymbol) ?: KtSubstitutor.Empty(token)
|
||||||
(fir as? FirQualifiedAccess)?.createSubstitutorFromTypeArguments(targetSymbol) ?: KtSubstitutor.Empty(token)
|
|
||||||
KtPartiallyAppliedSymbol(
|
|
||||||
unsubstitutedKtSignature.substitute(substitutor),
|
|
||||||
candidate.dispatchReceiverValue?.receiverExpression?.toKtReceiverValue(),
|
|
||||||
candidate.extensionReceiverValue?.receiverExpression?.toKtReceiverValue(),
|
|
||||||
)
|
|
||||||
} else if (fir is FirQualifiedAccess) {
|
|
||||||
val dispatchReceiver: KtReceiverValue?
|
|
||||||
val extensionReceiver: KtReceiverValue?
|
|
||||||
if (fir is FirImplicitInvokeCall) {
|
|
||||||
val explicitReceiverPsi = when (psi) {
|
|
||||||
is KtQualifiedExpression -> (psi.selectorExpression as KtCallExpression).calleeExpression
|
|
||||||
is KtCallExpression -> psi.calleeExpression
|
|
||||||
else -> error("unexpected PSI $psi for FirImplicitInvokeCall")
|
|
||||||
} ?: error("missing calleeExpression in PSI $psi for FirImplicitInvokeCall")
|
|
||||||
// For implicit invoke, the explicit receiver is always set in FIR and this receiver is the variable or property that has
|
|
||||||
// the `invoke` member function. In this case, we use the `calleeExpression` in the `KtCallExpression` as the PSI
|
|
||||||
// representation of this receiver. Caller can then use this PSI for further call resolution, which is implemented by the
|
|
||||||
// parameter `resolveCalleeExpressionOfFunctionCall` in `toKtCallInfo`.
|
|
||||||
val explicitReceiver = KtExplicitReceiverValue(explicitReceiverPsi, false, token)
|
|
||||||
|
|
||||||
// Specially handle @ExtensionFunctionType
|
fun createKtPartiallyAppliedSymbolForImplicitInvoke(
|
||||||
if (fir.dispatchReceiver.typeRef.coneTypeSafe<ConeKotlinType>()?.isExtensionFunctionType == true) {
|
dispatchReceiver: FirExpression,
|
||||||
firstArgIsExtensionReceiver = true
|
extensionReceiver: FirExpression,
|
||||||
}
|
explicitReceiverKind: ExplicitReceiverKind
|
||||||
|
): KtPartiallyAppliedSymbol<KtCallableSymbol, KtSignature<KtCallableSymbol>> {
|
||||||
|
isImplicitInvoke = true
|
||||||
|
val explicitReceiverPsi = when (psi) {
|
||||||
|
is KtQualifiedExpression -> (psi.selectorExpression as KtCallExpression).calleeExpression
|
||||||
|
is KtCallExpression -> psi.calleeExpression
|
||||||
|
else -> error("unexpected PSI $psi for FirImplicitInvokeCall")
|
||||||
|
} ?: error("missing calleeExpression in PSI $psi for FirImplicitInvokeCall")
|
||||||
|
// For implicit invoke, the explicit receiver is always set in FIR and this receiver is the variable or property that has
|
||||||
|
// the `invoke` member function. In this case, we use the `calleeExpression` in the `KtCallExpression` as the PSI
|
||||||
|
// representation of this receiver. Caller can then use this PSI for further call resolution, which is implemented by the
|
||||||
|
// parameter `resolveCalleeExpressionOfFunctionCall` in `toKtCallInfo`.
|
||||||
|
val explicitReceiverValue = KtExplicitReceiverValue(explicitReceiverPsi, false, token)
|
||||||
|
|
||||||
if (fir.explicitReceiver == fir.dispatchReceiver) {
|
// Specially handle @ExtensionFunctionType
|
||||||
dispatchReceiver = explicitReceiver
|
if (dispatchReceiver.typeRef.coneTypeSafe<ConeKotlinType>()?.isExtensionFunctionType == true) {
|
||||||
if (firstArgIsExtensionReceiver) {
|
firstArgIsExtensionReceiver = true
|
||||||
extensionReceiver = fir.arguments.first().toKtReceiverValue()
|
}
|
||||||
} else {
|
|
||||||
extensionReceiver = fir.extensionReceiver.toKtReceiverValue()
|
val dispatchReceiverValue: KtReceiverValue?
|
||||||
}
|
val extensionReceiverValue: KtReceiverValue?
|
||||||
|
if (explicitReceiverKind == ExplicitReceiverKind.DISPATCH_RECEIVER) {
|
||||||
|
dispatchReceiverValue = explicitReceiverValue
|
||||||
|
if (firstArgIsExtensionReceiver) {
|
||||||
|
extensionReceiverValue = (fir as FirFunctionCall).arguments.first().toKtReceiverValue()
|
||||||
} else {
|
} else {
|
||||||
dispatchReceiver = fir.dispatchReceiver.toKtReceiverValue()
|
extensionReceiverValue = extensionReceiver.toKtReceiverValue()
|
||||||
extensionReceiver = explicitReceiver
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
dispatchReceiver = fir.dispatchReceiver.toKtReceiverValue()
|
dispatchReceiverValue = dispatchReceiver.toKtReceiverValue()
|
||||||
extensionReceiver = fir.extensionReceiver.toKtReceiverValue()
|
extensionReceiverValue = explicitReceiverValue
|
||||||
}
|
}
|
||||||
val substitutor = fir.createConeSubstitutorFromTypeArguments() ?: return null
|
return KtPartiallyAppliedSymbol(
|
||||||
KtPartiallyAppliedSymbol(
|
unsubstitutedKtSignature.substitute(substitutor),
|
||||||
unsubstitutedKtSignature.substitute(substitutor.toKtSubstitutor()),
|
dispatchReceiverValue,
|
||||||
dispatchReceiver,
|
extensionReceiverValue,
|
||||||
extensionReceiver,
|
|
||||||
)
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
val partiallyAppliedSymbol = if (candidate != null) {
|
||||||
|
if (fir is FirImplicitInvokeCall ||
|
||||||
|
(fir.calleeOrCandidateName != OperatorNameConventions.INVOKE && targetSymbol.isInvokeFunction())
|
||||||
|
) {
|
||||||
|
// Implicit invoke (e.g., `x()`) will have a different callee symbol (e.g., `x`) than the candidate (e.g., `invoke`).
|
||||||
|
createKtPartiallyAppliedSymbolForImplicitInvoke(
|
||||||
|
candidate.dispatchReceiverValue?.receiverExpression ?: FirNoReceiverExpression,
|
||||||
|
candidate.extensionReceiverValue?.receiverExpression ?: FirNoReceiverExpression,
|
||||||
|
candidate.explicitReceiverKind
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
KtPartiallyAppliedSymbol(
|
||||||
|
unsubstitutedKtSignature.substitute(substitutor),
|
||||||
|
candidate.dispatchReceiverValue?.receiverExpression?.toKtReceiverValue(),
|
||||||
|
candidate.extensionReceiverValue?.receiverExpression?.toKtReceiverValue(),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
} else if (fir is FirQualifiedAccess) {
|
||||||
|
if (fir is FirImplicitInvokeCall) {
|
||||||
|
val explicitReceiverKind = if (fir.explicitReceiver == fir.dispatchReceiver) {
|
||||||
|
ExplicitReceiverKind.DISPATCH_RECEIVER
|
||||||
|
} else {
|
||||||
|
ExplicitReceiverKind.EXTENSION_RECEIVER
|
||||||
|
}
|
||||||
|
createKtPartiallyAppliedSymbolForImplicitInvoke(fir.dispatchReceiver, fir.extensionReceiver, explicitReceiverKind)
|
||||||
|
} else {
|
||||||
|
KtPartiallyAppliedSymbol(
|
||||||
|
unsubstitutedKtSignature.substitute(substitutor),
|
||||||
|
fir.dispatchReceiver.toKtReceiverValue(),
|
||||||
|
fir.extensionReceiver.toKtReceiverValue()
|
||||||
|
)
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
KtPartiallyAppliedSymbol(unsubstitutedKtSignature, _dispatchReceiver = null, _extensionReceiver = null)
|
KtPartiallyAppliedSymbol(unsubstitutedKtSignature, _dispatchReceiver = null, _extensionReceiver = null)
|
||||||
}
|
}
|
||||||
@@ -366,7 +402,7 @@ internal class KtFirCallResolver(
|
|||||||
argumentMappingWithoutExtensionReceiver
|
argumentMappingWithoutExtensionReceiver
|
||||||
?.createArgumentMapping(partiallyAppliedSymbol.signature as KtFunctionLikeSignature<*>)
|
?.createArgumentMapping(partiallyAppliedSymbol.signature as KtFunctionLikeSignature<*>)
|
||||||
?: LinkedHashMap(),
|
?: LinkedHashMap(),
|
||||||
fir is FirImplicitInvokeCall
|
isImplicitInvoke
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
is FirExpressionWithSmartcast -> createKtCall(psi, fir.originalExpression, candidate, resolveFragmentOfCall)
|
is FirExpressionWithSmartcast -> createKtCall(psi, fir.originalExpression, candidate, resolveFragmentOfCall)
|
||||||
@@ -673,51 +709,50 @@ internal class KtFirCallResolver(
|
|||||||
|
|
||||||
private val resolutionContext = ResolutionContext(firSession, bodyResolveComponents, stubBodyResolveTransformer.context)
|
private val resolutionContext = ResolutionContext(firSession, bodyResolveComponents, stubBodyResolveTransformer.context)
|
||||||
|
|
||||||
@OptIn(PrivateForInline::class)
|
|
||||||
fun getAllCandidates(functionCall: FirFunctionCall, element: KtElement): List<KtCallInfo> {
|
fun getAllCandidates(functionCall: FirFunctionCall, element: KtElement): List<KtCallInfo> {
|
||||||
val towerContext = firResolveState.getTowerContextProvider(element.containingKtFile).getClosestAvailableParentContext(element)
|
initializeBodyResolveContext(element)
|
||||||
towerContext?.let { bodyResolveComponents.context.replaceTowerDataContext(it) }
|
|
||||||
// Note: All candidate symbols should have the same name
|
// If a function call is resolved to an implicit invoke call, the FirImplicitInvokeCall will have the `invoke()` function as the
|
||||||
val name =
|
// callee and the variable as the explicit receiver. To correctly get all candidates, we need to get the original function
|
||||||
functionCall.calleeReference.getCandidateSymbols().firstOrNull()?.safeAs<FirFunctionSymbol<*>>()?.name ?: return emptyList()
|
// call's explicit receiver (if there is any) and callee (i.e., the variable).
|
||||||
return bodyResolveComponents.context.withFile(firFile, bodyResolveComponents) {
|
val unwrappedExplicitReceiver = functionCall.explicitReceiver?.unwrapSmartcastExpression()
|
||||||
val candidates = bodyResolveComponents.callResolver.collectAllCandidates(
|
val originalFunctionCall =
|
||||||
functionCall,
|
if (functionCall is FirImplicitInvokeCall && unwrappedExplicitReceiver is FirPropertyAccessExpression) {
|
||||||
name,
|
val originalCallee = unwrappedExplicitReceiver.calleeReference.safeAs<FirNamedReference>() ?: return emptyList()
|
||||||
element.getContainingDeclarations(),
|
buildFunctionCall {
|
||||||
|
source = functionCall.source
|
||||||
|
annotations.addAll(functionCall.annotations)
|
||||||
|
typeArguments.addAll(functionCall.typeArguments)
|
||||||
|
explicitReceiver = unwrappedExplicitReceiver.explicitReceiver
|
||||||
|
argumentList = functionCall.argumentList
|
||||||
|
calleeReference = originalCallee
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
functionCall
|
||||||
|
}
|
||||||
|
|
||||||
|
val calleeName = originalFunctionCall.calleeOrCandidateName ?: return emptyList()
|
||||||
|
val candidates = bodyResolveComponents.context.withFile(firFile, bodyResolveComponents) {
|
||||||
|
bodyResolveComponents.callResolver.collectAllCandidates(
|
||||||
|
originalFunctionCall,
|
||||||
|
calleeName,
|
||||||
|
bodyResolveComponents.context.containers,
|
||||||
resolutionContext
|
resolutionContext
|
||||||
)
|
)
|
||||||
candidates.mapNotNull { convertToKtCallInfo(functionCall, element, it.candidate, it.isInBestCandidates) }
|
|
||||||
}
|
}
|
||||||
|
return candidates.mapNotNull { convertToKtCallInfo(originalFunctionCall, element, it.candidate, it.isInBestCandidates) }
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun KtElement.getContainingDeclarations(): List<FirDeclaration> {
|
@OptIn(PrivateForInline::class, SymbolInternals::class)
|
||||||
fun KtElement.getContainingKtDeclaration(): KtDeclaration? =
|
private fun initializeBodyResolveContext(element: KtElement) {
|
||||||
when (val container = this.parentOfType<KtDeclaration>()) {
|
// Set up needed context to get all candidates.
|
||||||
is KtDestructuringDeclaration -> container.parentOfType()
|
val towerContext = firResolveState.getTowerContextProvider(element.containingKtFile).getClosestAvailableParentContext(element)
|
||||||
else -> container
|
towerContext?.let { bodyResolveComponents.context.replaceTowerDataContext(it) }
|
||||||
}
|
val containingDeclarations =
|
||||||
|
element.parentsOfType<KtDeclaration>().map { it.resolveToFirSymbol(firResolveState).fir }.toList().asReversed()
|
||||||
val containingDeclarations = mutableListOf<FirDeclaration>()
|
bodyResolveComponents.context.containers.addAll(containingDeclarations)
|
||||||
var current = getContainingKtDeclaration()
|
|
||||||
while (current != null) {
|
|
||||||
val firElement = current.getOrBuildFir(firResolveState)
|
|
||||||
val firDeclaration = when (firElement) {
|
|
||||||
is FirAnonymousObjectExpression -> firElement.anonymousObject
|
|
||||||
is FirAnonymousFunctionExpression -> firElement.anonymousFunction
|
|
||||||
is FirDeclaration -> firElement
|
|
||||||
else -> error(
|
|
||||||
"Expected a FirDeclaration for KtDeclaration (type: ${current::class.simpleName}) " +
|
|
||||||
"but was ${firElement?.let { it::class.simpleName }}. KtDeclaration text:\n${current.text}"
|
|
||||||
)
|
|
||||||
}
|
|
||||||
containingDeclarations += firDeclaration
|
|
||||||
current = current.getContainingKtDeclaration()
|
|
||||||
}
|
|
||||||
return containingDeclarations.asReversed()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@OptIn(SymbolInternals::class)
|
|
||||||
private fun convertToKtCallInfo(
|
private fun convertToKtCallInfo(
|
||||||
functionCall: FirFunctionCall,
|
functionCall: FirFunctionCall,
|
||||||
element: KtElement,
|
element: KtElement,
|
||||||
@@ -739,6 +774,34 @@ internal class KtFirCallResolver(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private val FirResolvable.calleeOrCandidateName: Name?
|
||||||
|
get() {
|
||||||
|
val calleeReference = calleeReference
|
||||||
|
if (calleeReference !is FirNamedReference) return null
|
||||||
|
|
||||||
|
// In most cases, we can get the callee name from the callee's candidate symbols. However, there is at least one case where we
|
||||||
|
// cannot do so:
|
||||||
|
// ```
|
||||||
|
// fun x(c: Char) {}
|
||||||
|
// fun call(x: kotlin.Int) {
|
||||||
|
// operator fun Int.invoke(a: Int) {}
|
||||||
|
// operator fun Int.invoke(b: Boolean) {}
|
||||||
|
// <expr>x()</expr>
|
||||||
|
// }
|
||||||
|
// ```
|
||||||
|
// The candidates for the call will both be `invoke`. We can keep it simple by getting the name from the callee reference's PSI
|
||||||
|
// element (`x` in the above example) if possible.
|
||||||
|
return when (val psi = calleeReference.psi) {
|
||||||
|
is KtNameReferenceExpression -> psi.getReferencedNameAsName()
|
||||||
|
else -> {
|
||||||
|
// This could be KtArrayAccessExpression or KtOperationReferenceExpression.
|
||||||
|
// Note: All candidate symbols should have the same name. We go by the symbol because `originalCallee.name` will include
|
||||||
|
// the applicability if not successful.
|
||||||
|
calleeReference.getCandidateSymbols().firstOrNull()?.safeAs<FirCallableSymbol<*>>()?.name
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private fun FirArrayOfCall.toKtCallInfo(): KtCallInfo? {
|
private fun FirArrayOfCall.toKtCallInfo(): KtCallInfo? {
|
||||||
val arrayOfSymbol = with(analysisSession) {
|
val arrayOfSymbol = with(analysisSession) {
|
||||||
val type = typeRef.coneTypeSafe<ConeClassLikeType>()
|
val type = typeRef.coneTypeSafe<ConeClassLikeType>()
|
||||||
|
|||||||
+6
@@ -40,6 +40,12 @@ public class FirResolveCallTestGenerated extends AbstractResolveCallTest {
|
|||||||
runTest("analysis/analysis-api/testData/components/callResolver/resolveCall/ambiguous.kt");
|
runTest("analysis/analysis-api/testData/components/callResolver/resolveCall/ambiguous.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("ambiguousImplicitInvoke.kt")
|
||||||
|
public void testAmbiguousImplicitInvoke() throws Exception {
|
||||||
|
runTest("analysis/analysis-api/testData/components/callResolver/resolveCall/ambiguousImplicitInvoke.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestMetadata("ambiguousWithExplicitTypeParameters.kt")
|
@TestMetadata("ambiguousWithExplicitTypeParameters.kt")
|
||||||
public void testAmbiguousWithExplicitTypeParameters() throws Exception {
|
public void testAmbiguousWithExplicitTypeParameters() throws Exception {
|
||||||
|
|||||||
+36
@@ -55,6 +55,12 @@ public class FirResolveCandidatesTestGenerated extends AbstractResolveCandidates
|
|||||||
runTest("analysis/analysis-api/testData/components/callResolver/resolveCandidates/multipleCandidates/ambiguous.kt");
|
runTest("analysis/analysis-api/testData/components/callResolver/resolveCandidates/multipleCandidates/ambiguous.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("ambiguousImplicitInvoke.kt")
|
||||||
|
public void testAmbiguousImplicitInvoke() throws Exception {
|
||||||
|
runTest("analysis/analysis-api/testData/components/callResolver/resolveCandidates/multipleCandidates/ambiguousImplicitInvoke.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestMetadata("ambiguousWithExplicitTypeParameters.kt")
|
@TestMetadata("ambiguousWithExplicitTypeParameters.kt")
|
||||||
public void testAmbiguousWithExplicitTypeParameters() throws Exception {
|
public void testAmbiguousWithExplicitTypeParameters() throws Exception {
|
||||||
@@ -66,6 +72,18 @@ public class FirResolveCandidatesTestGenerated extends AbstractResolveCandidates
|
|||||||
public void testAmbiguousWithInferredTypeParameters() throws Exception {
|
public void testAmbiguousWithInferredTypeParameters() throws Exception {
|
||||||
runTest("analysis/analysis-api/testData/components/callResolver/resolveCandidates/multipleCandidates/ambiguousWithInferredTypeParameters.kt");
|
runTest("analysis/analysis-api/testData/components/callResolver/resolveCandidates/multipleCandidates/ambiguousWithInferredTypeParameters.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("implicitInvoke.kt")
|
||||||
|
public void testImplicitInvoke() throws Exception {
|
||||||
|
runTest("analysis/analysis-api/testData/components/callResolver/resolveCandidates/multipleCandidates/implicitInvoke.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("implicitInvokeWithReceiver.kt")
|
||||||
|
public void testImplicitInvokeWithReceiver() throws Exception {
|
||||||
|
runTest("analysis/analysis-api/testData/components/callResolver/resolveCandidates/multipleCandidates/implicitInvokeWithReceiver.kt");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nested
|
@Nested
|
||||||
@@ -77,6 +95,24 @@ public class FirResolveCandidatesTestGenerated extends AbstractResolveCandidates
|
|||||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("analysis/analysis-api/testData/components/callResolver/resolveCandidates/singleCandidate"), Pattern.compile("^(.+)\\.kt$"), null, true);
|
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("analysis/analysis-api/testData/components/callResolver/resolveCandidates/singleCandidate"), Pattern.compile("^(.+)\\.kt$"), null, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("consecutiveImplicitInvoke1.kt")
|
||||||
|
public void testConsecutiveImplicitInvoke1() throws Exception {
|
||||||
|
runTest("analysis/analysis-api/testData/components/callResolver/resolveCandidates/singleCandidate/consecutiveImplicitInvoke1.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("consecutiveImplicitInvoke2.kt")
|
||||||
|
public void testConsecutiveImplicitInvoke2() throws Exception {
|
||||||
|
runTest("analysis/analysis-api/testData/components/callResolver/resolveCandidates/singleCandidate/consecutiveImplicitInvoke2.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("consecutiveImplicitInvoke3.kt")
|
||||||
|
public void testConsecutiveImplicitInvoke3() throws Exception {
|
||||||
|
runTest("analysis/analysis-api/testData/components/callResolver/resolveCandidates/singleCandidate/consecutiveImplicitInvoke3.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestMetadata("functionCall.kt")
|
@TestMetadata("functionCall.kt")
|
||||||
public void testFunctionCall() throws Exception {
|
public void testFunctionCall() throws Exception {
|
||||||
|
|||||||
+16
-4
@@ -7,7 +7,9 @@ package org.jetbrains.kotlin.analysis.api.impl.base.test.components
|
|||||||
|
|
||||||
import com.intellij.psi.PsiElement
|
import com.intellij.psi.PsiElement
|
||||||
import org.jetbrains.kotlin.analysis.api.KtAnalysisSession
|
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.calls.KtCallInfo
|
||||||
|
import org.jetbrains.kotlin.analysis.api.calls.KtCallableMemberCall
|
||||||
import org.jetbrains.kotlin.analysis.api.diagnostics.KtDiagnostic
|
import org.jetbrains.kotlin.analysis.api.diagnostics.KtDiagnostic
|
||||||
import org.jetbrains.kotlin.analysis.api.impl.base.KtMapBackedSubstitutor
|
import org.jetbrains.kotlin.analysis.api.impl.base.KtMapBackedSubstitutor
|
||||||
import org.jetbrains.kotlin.analysis.api.symbols.*
|
import org.jetbrains.kotlin.analysis.api.symbols.*
|
||||||
@@ -80,7 +82,8 @@ internal fun KtAnalysisSession.stringRepresentation(call: KtCallInfo): String {
|
|||||||
is Name -> asString()
|
is Name -> asString()
|
||||||
else -> buildString {
|
else -> buildString {
|
||||||
val clazz = this@stringValue::class
|
val clazz = this@stringValue::class
|
||||||
append(clazz.simpleName!!)
|
val className = clazz.simpleName!!
|
||||||
|
append(className)
|
||||||
appendLine(":")
|
appendLine(":")
|
||||||
clazz.memberProperties
|
clazz.memberProperties
|
||||||
.filter { it.name != "token" && it.visibility == KVisibility.PUBLIC }
|
.filter { it.name != "token" && it.visibility == KVisibility.PUBLIC }
|
||||||
@@ -88,9 +91,18 @@ internal fun KtAnalysisSession.stringRepresentation(call: KtCallInfo): String {
|
|||||||
val name = property.name
|
val name = property.name
|
||||||
|
|
||||||
@Suppress("UNCHECKED_CAST")
|
@Suppress("UNCHECKED_CAST")
|
||||||
val value =
|
val value = (property as KProperty1<Any, *>).get(this@stringValue)?.let {
|
||||||
(property as KProperty1<Any, *>).get(this@stringValue)?.stringValue()?.indented()
|
if (className == "KtErrorCallInfo" && name == "candidateCalls") {
|
||||||
"$name = $value"
|
// The order of calls in KtErrorCallInfo.candidateCalls is non-deterministic. Sort by symbol string value.
|
||||||
|
(it as Collection<KtCall>).sortedWith { call1, call2 ->
|
||||||
|
if (call1 is KtCallableMemberCall<*, *> && call2 is KtCallableMemberCall<*, *>) {
|
||||||
|
call1.partiallyAppliedSymbol.stringValue().compareTo(call2.partiallyAppliedSymbol.stringValue())
|
||||||
|
} else 0
|
||||||
|
}
|
||||||
|
} else it
|
||||||
|
}
|
||||||
|
val valueAsString = value?.stringValue()?.indented()
|
||||||
|
"$name = $valueAsString"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+44
@@ -0,0 +1,44 @@
|
|||||||
|
KtErrorCallInfo:
|
||||||
|
candidateCalls = [
|
||||||
|
KtSimpleFunctionCall:
|
||||||
|
isImplicitInvoke = true
|
||||||
|
partiallyAppliedSymbol = KtPartiallyAppliedSymbol:
|
||||||
|
dispatchReceiver = null
|
||||||
|
extensionReceiver = KtExplicitReceiverValue:
|
||||||
|
expression = x
|
||||||
|
isSafeNavigation = false
|
||||||
|
signature = KtFunctionLikeSignature:
|
||||||
|
receiverType = kotlin.Int
|
||||||
|
returnType = kotlin.Unit
|
||||||
|
symbol = invoke(<extension receiver>: kotlin.Int, a: kotlin.String): kotlin.Unit
|
||||||
|
valueParameters = [
|
||||||
|
KtVariableLikeSignature:
|
||||||
|
name = a
|
||||||
|
receiverType = null
|
||||||
|
returnType = kotlin.String
|
||||||
|
symbol = a: kotlin.String
|
||||||
|
]
|
||||||
|
argumentMapping = {},
|
||||||
|
KtSimpleFunctionCall:
|
||||||
|
isImplicitInvoke = true
|
||||||
|
partiallyAppliedSymbol = KtPartiallyAppliedSymbol:
|
||||||
|
dispatchReceiver = null
|
||||||
|
extensionReceiver = KtExplicitReceiverValue:
|
||||||
|
expression = x
|
||||||
|
isSafeNavigation = false
|
||||||
|
signature = KtFunctionLikeSignature:
|
||||||
|
receiverType = kotlin.Int
|
||||||
|
returnType = kotlin.Unit
|
||||||
|
symbol = invoke(<extension receiver>: kotlin.Int, b: kotlin.Boolean): kotlin.Unit
|
||||||
|
valueParameters = [
|
||||||
|
KtVariableLikeSignature:
|
||||||
|
name = b
|
||||||
|
receiverType = null
|
||||||
|
returnType = kotlin.Boolean
|
||||||
|
symbol = b: kotlin.Boolean
|
||||||
|
]
|
||||||
|
argumentMapping = {}
|
||||||
|
]
|
||||||
|
diagnostic = ERROR<NONE_APPLICABLE: None of the following functions can be called with the arguments supplied:
|
||||||
|
local final operator fun Int.invoke(b: Boolean): Unit defined in call
|
||||||
|
local final operator fun Int.invoke(a: String): Unit defined in call>
|
||||||
Vendored
+7
@@ -0,0 +1,7 @@
|
|||||||
|
fun x(c: Char) {}
|
||||||
|
|
||||||
|
fun call(x: kotlin.Int) {
|
||||||
|
operator fun Int.invoke(a: String) {}
|
||||||
|
operator fun Int.invoke(b: Boolean) {}
|
||||||
|
<expr>x()</expr>
|
||||||
|
}
|
||||||
Vendored
+42
@@ -0,0 +1,42 @@
|
|||||||
|
KtErrorCallInfo:
|
||||||
|
candidateCalls = [
|
||||||
|
KtSimpleFunctionCall:
|
||||||
|
isImplicitInvoke = true
|
||||||
|
partiallyAppliedSymbol = KtPartiallyAppliedSymbol:
|
||||||
|
dispatchReceiver = null
|
||||||
|
extensionReceiver = KtExplicitReceiverValue:
|
||||||
|
expression = x
|
||||||
|
isSafeNavigation = false
|
||||||
|
signature = KtFunctionLikeSignature:
|
||||||
|
receiverType = kotlin.Int
|
||||||
|
returnType = kotlin.Unit
|
||||||
|
symbol = invoke(<extension receiver>: kotlin.Int, a: kotlin.String): kotlin.Unit
|
||||||
|
valueParameters = [
|
||||||
|
KtVariableLikeSignature:
|
||||||
|
name = a
|
||||||
|
receiverType = null
|
||||||
|
returnType = kotlin.String
|
||||||
|
symbol = a: kotlin.String
|
||||||
|
]
|
||||||
|
argumentMapping = {},
|
||||||
|
KtSimpleFunctionCall:
|
||||||
|
isImplicitInvoke = true
|
||||||
|
partiallyAppliedSymbol = KtPartiallyAppliedSymbol:
|
||||||
|
dispatchReceiver = null
|
||||||
|
extensionReceiver = KtExplicitReceiverValue:
|
||||||
|
expression = x
|
||||||
|
isSafeNavigation = false
|
||||||
|
signature = KtFunctionLikeSignature:
|
||||||
|
receiverType = kotlin.Int
|
||||||
|
returnType = kotlin.Unit
|
||||||
|
symbol = invoke(<extension receiver>: kotlin.Int, b: kotlin.Boolean): kotlin.Unit
|
||||||
|
valueParameters = [
|
||||||
|
KtVariableLikeSignature:
|
||||||
|
name = b
|
||||||
|
receiverType = null
|
||||||
|
returnType = kotlin.Boolean
|
||||||
|
symbol = b: kotlin.Boolean
|
||||||
|
]
|
||||||
|
argumentMapping = {}
|
||||||
|
]
|
||||||
|
diagnostic = ERROR<NONE_APPLICABLE: None of the following functions are applicable: [<local>/invoke, <local>/invoke]>
|
||||||
+17
-17
@@ -1,22 +1,5 @@
|
|||||||
KtErrorCallInfo:
|
KtErrorCallInfo:
|
||||||
candidateCalls = [
|
candidateCalls = [
|
||||||
KtDelegatedConstructorCall:
|
|
||||||
kind = THIS_CALL
|
|
||||||
partiallyAppliedSymbol = KtPartiallyAppliedSymbol:
|
|
||||||
dispatchReceiver = null
|
|
||||||
extensionReceiver = null
|
|
||||||
signature = KtFunctionLikeSignature:
|
|
||||||
receiverType = null
|
|
||||||
returnType = Sub
|
|
||||||
symbol = <constructor>(p: kotlin.Int): Sub
|
|
||||||
valueParameters = [
|
|
||||||
KtVariableLikeSignature:
|
|
||||||
name = p
|
|
||||||
receiverType = null
|
|
||||||
returnType = kotlin.Int
|
|
||||||
symbol = p: kotlin.Int
|
|
||||||
]
|
|
||||||
argumentMapping = {},
|
|
||||||
KtDelegatedConstructorCall:
|
KtDelegatedConstructorCall:
|
||||||
kind = THIS_CALL
|
kind = THIS_CALL
|
||||||
partiallyAppliedSymbol = KtPartiallyAppliedSymbol:
|
partiallyAppliedSymbol = KtPartiallyAppliedSymbol:
|
||||||
@@ -38,6 +21,23 @@ KtErrorCallInfo:
|
|||||||
returnType = kotlin.Int
|
returnType = kotlin.Int
|
||||||
symbol = j: kotlin.Int
|
symbol = j: kotlin.Int
|
||||||
]
|
]
|
||||||
|
argumentMapping = {},
|
||||||
|
KtDelegatedConstructorCall:
|
||||||
|
kind = THIS_CALL
|
||||||
|
partiallyAppliedSymbol = KtPartiallyAppliedSymbol:
|
||||||
|
dispatchReceiver = null
|
||||||
|
extensionReceiver = null
|
||||||
|
signature = KtFunctionLikeSignature:
|
||||||
|
receiverType = null
|
||||||
|
returnType = Sub
|
||||||
|
symbol = <constructor>(p: kotlin.Int): Sub
|
||||||
|
valueParameters = [
|
||||||
|
KtVariableLikeSignature:
|
||||||
|
name = p
|
||||||
|
receiverType = null
|
||||||
|
returnType = kotlin.Int
|
||||||
|
symbol = p: kotlin.Int
|
||||||
|
]
|
||||||
argumentMapping = {}
|
argumentMapping = {}
|
||||||
]
|
]
|
||||||
diagnostic = ERROR<NONE_APPLICABLE: None of the following functions are applicable: [/Sub.Sub, /Sub.Sub]>
|
diagnostic = ERROR<NONE_APPLICABLE: None of the following functions are applicable: [/Sub.Sub, /Sub.Sub]>
|
||||||
|
|||||||
+6
@@ -11,12 +11,14 @@ KtErrorCallInfo:
|
|||||||
symbol = /function(a: kotlin.Char): kotlin.Unit
|
symbol = /function(a: kotlin.Char): kotlin.Unit
|
||||||
valueParameters = [
|
valueParameters = [
|
||||||
KtVariableLikeSignature:
|
KtVariableLikeSignature:
|
||||||
|
name = a
|
||||||
receiverType = null
|
receiverType = null
|
||||||
returnType = kotlin.Char
|
returnType = kotlin.Char
|
||||||
symbol = a: kotlin.Char
|
symbol = a: kotlin.Char
|
||||||
]
|
]
|
||||||
argumentMapping = {
|
argumentMapping = {
|
||||||
1 -> (KtVariableLikeSignature:
|
1 -> (KtVariableLikeSignature:
|
||||||
|
name = a
|
||||||
receiverType = null
|
receiverType = null
|
||||||
returnType = kotlin.Char
|
returnType = kotlin.Char
|
||||||
symbol = a: kotlin.Char)
|
symbol = a: kotlin.Char)
|
||||||
@@ -37,12 +39,14 @@ KtErrorCallInfo:
|
|||||||
symbol = /function(b: kotlin.Boolean): kotlin.Unit
|
symbol = /function(b: kotlin.Boolean): kotlin.Unit
|
||||||
valueParameters = [
|
valueParameters = [
|
||||||
KtVariableLikeSignature:
|
KtVariableLikeSignature:
|
||||||
|
name = b
|
||||||
receiverType = null
|
receiverType = null
|
||||||
returnType = kotlin.Boolean
|
returnType = kotlin.Boolean
|
||||||
symbol = b: kotlin.Boolean
|
symbol = b: kotlin.Boolean
|
||||||
]
|
]
|
||||||
argumentMapping = {
|
argumentMapping = {
|
||||||
1 -> (KtVariableLikeSignature:
|
1 -> (KtVariableLikeSignature:
|
||||||
|
name = b
|
||||||
receiverType = null
|
receiverType = null
|
||||||
returnType = kotlin.Boolean
|
returnType = kotlin.Boolean
|
||||||
symbol = b: kotlin.Boolean)
|
symbol = b: kotlin.Boolean)
|
||||||
@@ -63,12 +67,14 @@ KtErrorCallInfo:
|
|||||||
symbol = /function(c: kotlin.String): kotlin.Unit
|
symbol = /function(c: kotlin.String): kotlin.Unit
|
||||||
valueParameters = [
|
valueParameters = [
|
||||||
KtVariableLikeSignature:
|
KtVariableLikeSignature:
|
||||||
|
name = c
|
||||||
receiverType = null
|
receiverType = null
|
||||||
returnType = kotlin.String
|
returnType = kotlin.String
|
||||||
symbol = c: kotlin.String
|
symbol = c: kotlin.String
|
||||||
]
|
]
|
||||||
argumentMapping = {
|
argumentMapping = {
|
||||||
1 -> (KtVariableLikeSignature:
|
1 -> (KtVariableLikeSignature:
|
||||||
|
name = c
|
||||||
receiverType = null
|
receiverType = null
|
||||||
returnType = kotlin.String
|
returnType = kotlin.String
|
||||||
symbol = c: kotlin.String)
|
symbol = c: kotlin.String)
|
||||||
|
|||||||
+7
@@ -0,0 +1,7 @@
|
|||||||
|
fun x(c: Char) {}
|
||||||
|
|
||||||
|
fun call(x: kotlin.Int) {
|
||||||
|
operator fun Int.invoke(a: String) {}
|
||||||
|
operator fun Int.invoke(b: Boolean) {}
|
||||||
|
<expr>x()</expr>
|
||||||
|
}
|
||||||
+69
@@ -0,0 +1,69 @@
|
|||||||
|
KtErrorCallInfo:
|
||||||
|
candidateCalls = [
|
||||||
|
KtSimpleFunctionCall:
|
||||||
|
isImplicitInvoke = true
|
||||||
|
partiallyAppliedSymbol = KtPartiallyAppliedSymbol:
|
||||||
|
dispatchReceiver = null
|
||||||
|
extensionReceiver = KtExplicitReceiverValue:
|
||||||
|
expression = x
|
||||||
|
isSafeNavigation = false
|
||||||
|
signature = KtFunctionLikeSignature:
|
||||||
|
receiverType = kotlin.Int
|
||||||
|
returnType = kotlin.Unit
|
||||||
|
symbol = invoke(<extension receiver>: kotlin.Int, a: kotlin.String): kotlin.Unit
|
||||||
|
valueParameters = [
|
||||||
|
KtVariableLikeSignature:
|
||||||
|
name = a
|
||||||
|
receiverType = null
|
||||||
|
returnType = kotlin.String
|
||||||
|
symbol = a: kotlin.String
|
||||||
|
]
|
||||||
|
argumentMapping = {}
|
||||||
|
]
|
||||||
|
diagnostic = ERROR<NO_VALUE_FOR_PARAMETER: No value passed for parameter 'a'>
|
||||||
|
|
||||||
|
KtErrorCallInfo:
|
||||||
|
candidateCalls = [
|
||||||
|
KtSimpleFunctionCall:
|
||||||
|
isImplicitInvoke = true
|
||||||
|
partiallyAppliedSymbol = KtPartiallyAppliedSymbol:
|
||||||
|
dispatchReceiver = null
|
||||||
|
extensionReceiver = KtExplicitReceiverValue:
|
||||||
|
expression = x
|
||||||
|
isSafeNavigation = false
|
||||||
|
signature = KtFunctionLikeSignature:
|
||||||
|
receiverType = kotlin.Int
|
||||||
|
returnType = kotlin.Unit
|
||||||
|
symbol = invoke(<extension receiver>: kotlin.Int, b: kotlin.Boolean): kotlin.Unit
|
||||||
|
valueParameters = [
|
||||||
|
KtVariableLikeSignature:
|
||||||
|
name = b
|
||||||
|
receiverType = null
|
||||||
|
returnType = kotlin.Boolean
|
||||||
|
symbol = b: kotlin.Boolean
|
||||||
|
]
|
||||||
|
argumentMapping = {}
|
||||||
|
]
|
||||||
|
diagnostic = ERROR<NO_VALUE_FOR_PARAMETER: No value passed for parameter 'b'>
|
||||||
|
|
||||||
|
KtErrorCallInfo:
|
||||||
|
candidateCalls = [
|
||||||
|
KtSimpleFunctionCall:
|
||||||
|
isImplicitInvoke = false
|
||||||
|
partiallyAppliedSymbol = KtPartiallyAppliedSymbol:
|
||||||
|
dispatchReceiver = null
|
||||||
|
extensionReceiver = null
|
||||||
|
signature = KtFunctionLikeSignature:
|
||||||
|
receiverType = null
|
||||||
|
returnType = kotlin.Unit
|
||||||
|
symbol = /x(c: kotlin.Char): kotlin.Unit
|
||||||
|
valueParameters = [
|
||||||
|
KtVariableLikeSignature:
|
||||||
|
name = c
|
||||||
|
receiverType = null
|
||||||
|
returnType = kotlin.Char
|
||||||
|
symbol = c: kotlin.Char
|
||||||
|
]
|
||||||
|
argumentMapping = {}
|
||||||
|
]
|
||||||
|
diagnostic = ERROR<NO_VALUE_FOR_PARAMETER: No value passed for parameter 'c'>
|
||||||
+9
@@ -11,16 +11,19 @@ KtErrorCallInfo:
|
|||||||
symbol = /function(t: T, a: kotlin.Char): kotlin.Unit
|
symbol = /function(t: T, a: kotlin.Char): kotlin.Unit
|
||||||
valueParameters = [
|
valueParameters = [
|
||||||
KtVariableLikeSignature:
|
KtVariableLikeSignature:
|
||||||
|
name = t
|
||||||
receiverType = null
|
receiverType = null
|
||||||
returnType = kotlin.Int
|
returnType = kotlin.Int
|
||||||
symbol = t: T,
|
symbol = t: T,
|
||||||
KtVariableLikeSignature:
|
KtVariableLikeSignature:
|
||||||
|
name = a
|
||||||
receiverType = null
|
receiverType = null
|
||||||
returnType = kotlin.Char
|
returnType = kotlin.Char
|
||||||
symbol = a: kotlin.Char
|
symbol = a: kotlin.Char
|
||||||
]
|
]
|
||||||
argumentMapping = {
|
argumentMapping = {
|
||||||
1 -> (KtVariableLikeSignature:
|
1 -> (KtVariableLikeSignature:
|
||||||
|
name = t
|
||||||
receiverType = null
|
receiverType = null
|
||||||
returnType = kotlin.Int
|
returnType = kotlin.Int
|
||||||
symbol = t: T)
|
symbol = t: T)
|
||||||
@@ -41,16 +44,19 @@ KtErrorCallInfo:
|
|||||||
symbol = /function(u: U, b: kotlin.Boolean): kotlin.Unit
|
symbol = /function(u: U, b: kotlin.Boolean): kotlin.Unit
|
||||||
valueParameters = [
|
valueParameters = [
|
||||||
KtVariableLikeSignature:
|
KtVariableLikeSignature:
|
||||||
|
name = u
|
||||||
receiverType = null
|
receiverType = null
|
||||||
returnType = kotlin.Int
|
returnType = kotlin.Int
|
||||||
symbol = u: U,
|
symbol = u: U,
|
||||||
KtVariableLikeSignature:
|
KtVariableLikeSignature:
|
||||||
|
name = b
|
||||||
receiverType = null
|
receiverType = null
|
||||||
returnType = kotlin.Boolean
|
returnType = kotlin.Boolean
|
||||||
symbol = b: kotlin.Boolean
|
symbol = b: kotlin.Boolean
|
||||||
]
|
]
|
||||||
argumentMapping = {
|
argumentMapping = {
|
||||||
1 -> (KtVariableLikeSignature:
|
1 -> (KtVariableLikeSignature:
|
||||||
|
name = u
|
||||||
receiverType = null
|
receiverType = null
|
||||||
returnType = kotlin.Int
|
returnType = kotlin.Int
|
||||||
symbol = u: U)
|
symbol = u: U)
|
||||||
@@ -71,16 +77,19 @@ KtErrorCallInfo:
|
|||||||
symbol = /function(v: V, c: kotlin.String): kotlin.Unit
|
symbol = /function(v: V, c: kotlin.String): kotlin.Unit
|
||||||
valueParameters = [
|
valueParameters = [
|
||||||
KtVariableLikeSignature:
|
KtVariableLikeSignature:
|
||||||
|
name = v
|
||||||
receiverType = null
|
receiverType = null
|
||||||
returnType = kotlin.Int
|
returnType = kotlin.Int
|
||||||
symbol = v: V,
|
symbol = v: V,
|
||||||
KtVariableLikeSignature:
|
KtVariableLikeSignature:
|
||||||
|
name = c
|
||||||
receiverType = null
|
receiverType = null
|
||||||
returnType = kotlin.String
|
returnType = kotlin.String
|
||||||
symbol = c: kotlin.String
|
symbol = c: kotlin.String
|
||||||
]
|
]
|
||||||
argumentMapping = {
|
argumentMapping = {
|
||||||
1 -> (KtVariableLikeSignature:
|
1 -> (KtVariableLikeSignature:
|
||||||
|
name = v
|
||||||
receiverType = null
|
receiverType = null
|
||||||
returnType = kotlin.Int
|
returnType = kotlin.Int
|
||||||
symbol = v: V)
|
symbol = v: V)
|
||||||
|
|||||||
+9
@@ -11,16 +11,19 @@ KtErrorCallInfo:
|
|||||||
symbol = /function(t: T, a: kotlin.Char): kotlin.Unit
|
symbol = /function(t: T, a: kotlin.Char): kotlin.Unit
|
||||||
valueParameters = [
|
valueParameters = [
|
||||||
KtVariableLikeSignature:
|
KtVariableLikeSignature:
|
||||||
|
name = t
|
||||||
receiverType = null
|
receiverType = null
|
||||||
returnType = T
|
returnType = T
|
||||||
symbol = t: T,
|
symbol = t: T,
|
||||||
KtVariableLikeSignature:
|
KtVariableLikeSignature:
|
||||||
|
name = a
|
||||||
receiverType = null
|
receiverType = null
|
||||||
returnType = kotlin.Char
|
returnType = kotlin.Char
|
||||||
symbol = a: kotlin.Char
|
symbol = a: kotlin.Char
|
||||||
]
|
]
|
||||||
argumentMapping = {
|
argumentMapping = {
|
||||||
1 -> (KtVariableLikeSignature:
|
1 -> (KtVariableLikeSignature:
|
||||||
|
name = t
|
||||||
receiverType = null
|
receiverType = null
|
||||||
returnType = T
|
returnType = T
|
||||||
symbol = t: T)
|
symbol = t: T)
|
||||||
@@ -41,16 +44,19 @@ KtErrorCallInfo:
|
|||||||
symbol = /function(u: U, b: kotlin.Boolean): kotlin.Unit
|
symbol = /function(u: U, b: kotlin.Boolean): kotlin.Unit
|
||||||
valueParameters = [
|
valueParameters = [
|
||||||
KtVariableLikeSignature:
|
KtVariableLikeSignature:
|
||||||
|
name = u
|
||||||
receiverType = null
|
receiverType = null
|
||||||
returnType = U
|
returnType = U
|
||||||
symbol = u: U,
|
symbol = u: U,
|
||||||
KtVariableLikeSignature:
|
KtVariableLikeSignature:
|
||||||
|
name = b
|
||||||
receiverType = null
|
receiverType = null
|
||||||
returnType = kotlin.Boolean
|
returnType = kotlin.Boolean
|
||||||
symbol = b: kotlin.Boolean
|
symbol = b: kotlin.Boolean
|
||||||
]
|
]
|
||||||
argumentMapping = {
|
argumentMapping = {
|
||||||
1 -> (KtVariableLikeSignature:
|
1 -> (KtVariableLikeSignature:
|
||||||
|
name = u
|
||||||
receiverType = null
|
receiverType = null
|
||||||
returnType = U
|
returnType = U
|
||||||
symbol = u: U)
|
symbol = u: U)
|
||||||
@@ -71,16 +77,19 @@ KtErrorCallInfo:
|
|||||||
symbol = /function(v: V, c: kotlin.String): kotlin.Unit
|
symbol = /function(v: V, c: kotlin.String): kotlin.Unit
|
||||||
valueParameters = [
|
valueParameters = [
|
||||||
KtVariableLikeSignature:
|
KtVariableLikeSignature:
|
||||||
|
name = v
|
||||||
receiverType = null
|
receiverType = null
|
||||||
returnType = V
|
returnType = V
|
||||||
symbol = v: V,
|
symbol = v: V,
|
||||||
KtVariableLikeSignature:
|
KtVariableLikeSignature:
|
||||||
|
name = c
|
||||||
receiverType = null
|
receiverType = null
|
||||||
returnType = kotlin.String
|
returnType = kotlin.String
|
||||||
symbol = c: kotlin.String
|
symbol = c: kotlin.String
|
||||||
]
|
]
|
||||||
argumentMapping = {
|
argumentMapping = {
|
||||||
1 -> (KtVariableLikeSignature:
|
1 -> (KtVariableLikeSignature:
|
||||||
|
name = v
|
||||||
receiverType = null
|
receiverType = null
|
||||||
returnType = V
|
returnType = V
|
||||||
symbol = v: V)
|
symbol = v: V)
|
||||||
|
|||||||
+8
@@ -0,0 +1,8 @@
|
|||||||
|
operator fun Int.invoke(i: Int) {}
|
||||||
|
|
||||||
|
fun x(c: Char) {}
|
||||||
|
|
||||||
|
fun call(x: kotlin.Int) {
|
||||||
|
fun x(b: Boolean) {}
|
||||||
|
<expr>x(true)</expr>
|
||||||
|
}
|
||||||
+82
@@ -0,0 +1,82 @@
|
|||||||
|
KtSuccessCallInfo:
|
||||||
|
call = KtSimpleFunctionCall:
|
||||||
|
isImplicitInvoke = false
|
||||||
|
partiallyAppliedSymbol = KtPartiallyAppliedSymbol:
|
||||||
|
dispatchReceiver = null
|
||||||
|
extensionReceiver = null
|
||||||
|
signature = KtFunctionLikeSignature:
|
||||||
|
receiverType = null
|
||||||
|
returnType = kotlin.Unit
|
||||||
|
symbol = x(b: kotlin.Boolean): kotlin.Unit
|
||||||
|
valueParameters = [
|
||||||
|
KtVariableLikeSignature:
|
||||||
|
name = b
|
||||||
|
receiverType = null
|
||||||
|
returnType = kotlin.Boolean
|
||||||
|
symbol = b: kotlin.Boolean
|
||||||
|
]
|
||||||
|
argumentMapping = {
|
||||||
|
true -> (KtVariableLikeSignature:
|
||||||
|
name = b
|
||||||
|
receiverType = null
|
||||||
|
returnType = kotlin.Boolean
|
||||||
|
symbol = b: kotlin.Boolean)
|
||||||
|
}
|
||||||
|
|
||||||
|
KtErrorCallInfo:
|
||||||
|
candidateCalls = [
|
||||||
|
KtSimpleFunctionCall:
|
||||||
|
isImplicitInvoke = false
|
||||||
|
partiallyAppliedSymbol = KtPartiallyAppliedSymbol:
|
||||||
|
dispatchReceiver = null
|
||||||
|
extensionReceiver = null
|
||||||
|
signature = KtFunctionLikeSignature:
|
||||||
|
receiverType = null
|
||||||
|
returnType = kotlin.Unit
|
||||||
|
symbol = /x(c: kotlin.Char): kotlin.Unit
|
||||||
|
valueParameters = [
|
||||||
|
KtVariableLikeSignature:
|
||||||
|
name = c
|
||||||
|
receiverType = null
|
||||||
|
returnType = kotlin.Char
|
||||||
|
symbol = c: kotlin.Char
|
||||||
|
]
|
||||||
|
argumentMapping = {
|
||||||
|
true -> (KtVariableLikeSignature:
|
||||||
|
name = c
|
||||||
|
receiverType = null
|
||||||
|
returnType = kotlin.Char
|
||||||
|
symbol = c: kotlin.Char)
|
||||||
|
}
|
||||||
|
]
|
||||||
|
diagnostic = ERROR<ARGUMENT_TYPE_MISMATCH: Argument type mismatch: actual type is kotlin/Boolean but kotlin/Char was expected>
|
||||||
|
|
||||||
|
KtErrorCallInfo:
|
||||||
|
candidateCalls = [
|
||||||
|
KtSimpleFunctionCall:
|
||||||
|
isImplicitInvoke = true
|
||||||
|
partiallyAppliedSymbol = KtPartiallyAppliedSymbol:
|
||||||
|
dispatchReceiver = null
|
||||||
|
extensionReceiver = KtExplicitReceiverValue:
|
||||||
|
expression = x
|
||||||
|
isSafeNavigation = false
|
||||||
|
signature = KtFunctionLikeSignature:
|
||||||
|
receiverType = kotlin.Int
|
||||||
|
returnType = kotlin.Unit
|
||||||
|
symbol = /invoke(<extension receiver>: kotlin.Int, i: kotlin.Int): kotlin.Unit
|
||||||
|
valueParameters = [
|
||||||
|
KtVariableLikeSignature:
|
||||||
|
name = i
|
||||||
|
receiverType = null
|
||||||
|
returnType = kotlin.Int
|
||||||
|
symbol = i: kotlin.Int
|
||||||
|
]
|
||||||
|
argumentMapping = {
|
||||||
|
true -> (KtVariableLikeSignature:
|
||||||
|
name = i
|
||||||
|
receiverType = null
|
||||||
|
returnType = kotlin.Int
|
||||||
|
symbol = i: kotlin.Int)
|
||||||
|
}
|
||||||
|
]
|
||||||
|
diagnostic = ERROR<ARGUMENT_TYPE_MISMATCH: Argument type mismatch: actual type is kotlin/Boolean but kotlin/Int was expected>
|
||||||
+9
@@ -0,0 +1,9 @@
|
|||||||
|
operator fun Int.invoke(i: Int) {}
|
||||||
|
|
||||||
|
class A(val x: Int) {
|
||||||
|
fun x(b: Boolean) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun call(a: A) {
|
||||||
|
<expr>a.x(1)</expr>
|
||||||
|
}
|
||||||
+56
@@ -0,0 +1,56 @@
|
|||||||
|
KtErrorCallInfo:
|
||||||
|
candidateCalls = [
|
||||||
|
KtSimpleFunctionCall:
|
||||||
|
isImplicitInvoke = false
|
||||||
|
partiallyAppliedSymbol = KtPartiallyAppliedSymbol:
|
||||||
|
dispatchReceiver = KtExplicitReceiverValue:
|
||||||
|
expression = a
|
||||||
|
isSafeNavigation = false
|
||||||
|
extensionReceiver = null
|
||||||
|
signature = KtFunctionLikeSignature:
|
||||||
|
receiverType = null
|
||||||
|
returnType = kotlin.Unit
|
||||||
|
symbol = /A.x(<dispatch receiver>: A, b: kotlin.Boolean): kotlin.Unit
|
||||||
|
valueParameters = [
|
||||||
|
KtVariableLikeSignature:
|
||||||
|
name = b
|
||||||
|
receiverType = null
|
||||||
|
returnType = kotlin.Boolean
|
||||||
|
symbol = b: kotlin.Boolean
|
||||||
|
]
|
||||||
|
argumentMapping = {
|
||||||
|
1 -> (KtVariableLikeSignature:
|
||||||
|
name = b
|
||||||
|
receiverType = null
|
||||||
|
returnType = kotlin.Boolean
|
||||||
|
symbol = b: kotlin.Boolean)
|
||||||
|
}
|
||||||
|
]
|
||||||
|
diagnostic = ERROR<ARGUMENT_TYPE_MISMATCH: Argument type mismatch: actual type is kotlin/Int but kotlin/Boolean was expected>
|
||||||
|
|
||||||
|
KtSuccessCallInfo:
|
||||||
|
call = KtSimpleFunctionCall:
|
||||||
|
isImplicitInvoke = true
|
||||||
|
partiallyAppliedSymbol = KtPartiallyAppliedSymbol:
|
||||||
|
dispatchReceiver = null
|
||||||
|
extensionReceiver = KtExplicitReceiverValue:
|
||||||
|
expression = x
|
||||||
|
isSafeNavigation = false
|
||||||
|
signature = KtFunctionLikeSignature:
|
||||||
|
receiverType = kotlin.Int
|
||||||
|
returnType = kotlin.Unit
|
||||||
|
symbol = /invoke(<extension receiver>: kotlin.Int, i: kotlin.Int): kotlin.Unit
|
||||||
|
valueParameters = [
|
||||||
|
KtVariableLikeSignature:
|
||||||
|
name = i
|
||||||
|
receiverType = null
|
||||||
|
returnType = kotlin.Int
|
||||||
|
symbol = i: kotlin.Int
|
||||||
|
]
|
||||||
|
argumentMapping = {
|
||||||
|
1 -> (KtVariableLikeSignature:
|
||||||
|
name = i
|
||||||
|
receiverType = null
|
||||||
|
returnType = kotlin.Int
|
||||||
|
symbol = i: kotlin.Int)
|
||||||
|
}
|
||||||
+6
@@ -0,0 +1,6 @@
|
|||||||
|
operator fun Int.invoke() : Long = 1L
|
||||||
|
operator fun Long.invoke() : Double = 1.0
|
||||||
|
operator fun Double.invoke() {}
|
||||||
|
fun test(i: Int) {
|
||||||
|
<expr>i()</expr>()()
|
||||||
|
}
|
||||||
+50
@@ -0,0 +1,50 @@
|
|||||||
|
KtSuccessCallInfo:
|
||||||
|
call = KtSimpleFunctionCall:
|
||||||
|
isImplicitInvoke = true
|
||||||
|
partiallyAppliedSymbol = KtPartiallyAppliedSymbol:
|
||||||
|
dispatchReceiver = null
|
||||||
|
extensionReceiver = KtExplicitReceiverValue:
|
||||||
|
expression = i
|
||||||
|
isSafeNavigation = false
|
||||||
|
signature = KtFunctionLikeSignature:
|
||||||
|
receiverType = kotlin.Int
|
||||||
|
returnType = kotlin.Long
|
||||||
|
symbol = /invoke(<extension receiver>: kotlin.Int): kotlin.Long
|
||||||
|
valueParameters = []
|
||||||
|
argumentMapping = {}
|
||||||
|
|
||||||
|
KtErrorCallInfo:
|
||||||
|
candidateCalls = [
|
||||||
|
KtSimpleFunctionCall:
|
||||||
|
isImplicitInvoke = true
|
||||||
|
partiallyAppliedSymbol = KtPartiallyAppliedSymbol:
|
||||||
|
dispatchReceiver = null
|
||||||
|
extensionReceiver = KtExplicitReceiverValue:
|
||||||
|
expression = i
|
||||||
|
isSafeNavigation = false
|
||||||
|
signature = KtFunctionLikeSignature:
|
||||||
|
receiverType = kotlin.Long
|
||||||
|
returnType = kotlin.Double
|
||||||
|
symbol = /invoke(<extension receiver>: kotlin.Long): kotlin.Double
|
||||||
|
valueParameters = []
|
||||||
|
argumentMapping = {}
|
||||||
|
]
|
||||||
|
diagnostic = ERROR<UNRESOLVED_REFERENCE_WRONG_RECEIVER: Unresolved reference. None of the following candidates is applicable because of receiver type mismatch: [/invoke]>
|
||||||
|
|
||||||
|
KtErrorCallInfo:
|
||||||
|
candidateCalls = [
|
||||||
|
KtSimpleFunctionCall:
|
||||||
|
isImplicitInvoke = true
|
||||||
|
partiallyAppliedSymbol = KtPartiallyAppliedSymbol:
|
||||||
|
dispatchReceiver = null
|
||||||
|
extensionReceiver = KtExplicitReceiverValue:
|
||||||
|
expression = i
|
||||||
|
isSafeNavigation = false
|
||||||
|
signature = KtFunctionLikeSignature:
|
||||||
|
receiverType = kotlin.Double
|
||||||
|
returnType = kotlin.Unit
|
||||||
|
symbol = /invoke(<extension receiver>: kotlin.Double): kotlin.Unit
|
||||||
|
valueParameters = []
|
||||||
|
argumentMapping = {}
|
||||||
|
]
|
||||||
|
diagnostic = ERROR<UNRESOLVED_REFERENCE_WRONG_RECEIVER: Unresolved reference. None of the following candidates is applicable because of receiver type mismatch: [/invoke]>
|
||||||
+6
@@ -0,0 +1,6 @@
|
|||||||
|
operator fun Int.invoke() : Long = 1L
|
||||||
|
operator fun Long.invoke() : Double = 1.0
|
||||||
|
operator fun Double.invoke() {}
|
||||||
|
fun test(i: Int) {
|
||||||
|
<expr>i()()</expr>()
|
||||||
|
}
|
||||||
+50
@@ -0,0 +1,50 @@
|
|||||||
|
KtErrorCallInfo:
|
||||||
|
candidateCalls = [
|
||||||
|
KtSimpleFunctionCall:
|
||||||
|
isImplicitInvoke = true
|
||||||
|
partiallyAppliedSymbol = KtPartiallyAppliedSymbol:
|
||||||
|
dispatchReceiver = null
|
||||||
|
extensionReceiver = KtExplicitReceiverValue:
|
||||||
|
expression = i()
|
||||||
|
isSafeNavigation = false
|
||||||
|
signature = KtFunctionLikeSignature:
|
||||||
|
receiverType = kotlin.Int
|
||||||
|
returnType = kotlin.Long
|
||||||
|
symbol = /invoke(<extension receiver>: kotlin.Int): kotlin.Long
|
||||||
|
valueParameters = []
|
||||||
|
argumentMapping = {}
|
||||||
|
]
|
||||||
|
diagnostic = ERROR<UNRESOLVED_REFERENCE_WRONG_RECEIVER: Unresolved reference. None of the following candidates is applicable because of receiver type mismatch: [/invoke]>
|
||||||
|
|
||||||
|
KtSuccessCallInfo:
|
||||||
|
call = KtSimpleFunctionCall:
|
||||||
|
isImplicitInvoke = true
|
||||||
|
partiallyAppliedSymbol = KtPartiallyAppliedSymbol:
|
||||||
|
dispatchReceiver = null
|
||||||
|
extensionReceiver = KtExplicitReceiverValue:
|
||||||
|
expression = i()
|
||||||
|
isSafeNavigation = false
|
||||||
|
signature = KtFunctionLikeSignature:
|
||||||
|
receiverType = kotlin.Long
|
||||||
|
returnType = kotlin.Double
|
||||||
|
symbol = /invoke(<extension receiver>: kotlin.Long): kotlin.Double
|
||||||
|
valueParameters = []
|
||||||
|
argumentMapping = {}
|
||||||
|
|
||||||
|
KtErrorCallInfo:
|
||||||
|
candidateCalls = [
|
||||||
|
KtSimpleFunctionCall:
|
||||||
|
isImplicitInvoke = true
|
||||||
|
partiallyAppliedSymbol = KtPartiallyAppliedSymbol:
|
||||||
|
dispatchReceiver = null
|
||||||
|
extensionReceiver = KtExplicitReceiverValue:
|
||||||
|
expression = i()
|
||||||
|
isSafeNavigation = false
|
||||||
|
signature = KtFunctionLikeSignature:
|
||||||
|
receiverType = kotlin.Double
|
||||||
|
returnType = kotlin.Unit
|
||||||
|
symbol = /invoke(<extension receiver>: kotlin.Double): kotlin.Unit
|
||||||
|
valueParameters = []
|
||||||
|
argumentMapping = {}
|
||||||
|
]
|
||||||
|
diagnostic = ERROR<UNRESOLVED_REFERENCE_WRONG_RECEIVER: Unresolved reference. None of the following candidates is applicable because of receiver type mismatch: [/invoke]>
|
||||||
+6
@@ -0,0 +1,6 @@
|
|||||||
|
operator fun Int.invoke() : Long = 1L
|
||||||
|
operator fun Long.invoke() : Double = 1.0
|
||||||
|
operator fun Double.invoke() {}
|
||||||
|
fun test(i: Int) {
|
||||||
|
<expr>i()()()</expr>
|
||||||
|
}
|
||||||
+50
@@ -0,0 +1,50 @@
|
|||||||
|
KtErrorCallInfo:
|
||||||
|
candidateCalls = [
|
||||||
|
KtSimpleFunctionCall:
|
||||||
|
isImplicitInvoke = true
|
||||||
|
partiallyAppliedSymbol = KtPartiallyAppliedSymbol:
|
||||||
|
dispatchReceiver = null
|
||||||
|
extensionReceiver = KtExplicitReceiverValue:
|
||||||
|
expression = i()()
|
||||||
|
isSafeNavigation = false
|
||||||
|
signature = KtFunctionLikeSignature:
|
||||||
|
receiverType = kotlin.Int
|
||||||
|
returnType = kotlin.Long
|
||||||
|
symbol = /invoke(<extension receiver>: kotlin.Int): kotlin.Long
|
||||||
|
valueParameters = []
|
||||||
|
argumentMapping = {}
|
||||||
|
]
|
||||||
|
diagnostic = ERROR<UNRESOLVED_REFERENCE_WRONG_RECEIVER: Unresolved reference. None of the following candidates is applicable because of receiver type mismatch: [/invoke]>
|
||||||
|
|
||||||
|
KtErrorCallInfo:
|
||||||
|
candidateCalls = [
|
||||||
|
KtSimpleFunctionCall:
|
||||||
|
isImplicitInvoke = true
|
||||||
|
partiallyAppliedSymbol = KtPartiallyAppliedSymbol:
|
||||||
|
dispatchReceiver = null
|
||||||
|
extensionReceiver = KtExplicitReceiverValue:
|
||||||
|
expression = i()()
|
||||||
|
isSafeNavigation = false
|
||||||
|
signature = KtFunctionLikeSignature:
|
||||||
|
receiverType = kotlin.Long
|
||||||
|
returnType = kotlin.Double
|
||||||
|
symbol = /invoke(<extension receiver>: kotlin.Long): kotlin.Double
|
||||||
|
valueParameters = []
|
||||||
|
argumentMapping = {}
|
||||||
|
]
|
||||||
|
diagnostic = ERROR<UNRESOLVED_REFERENCE_WRONG_RECEIVER: Unresolved reference. None of the following candidates is applicable because of receiver type mismatch: [/invoke]>
|
||||||
|
|
||||||
|
KtSuccessCallInfo:
|
||||||
|
call = KtSimpleFunctionCall:
|
||||||
|
isImplicitInvoke = true
|
||||||
|
partiallyAppliedSymbol = KtPartiallyAppliedSymbol:
|
||||||
|
dispatchReceiver = null
|
||||||
|
extensionReceiver = KtExplicitReceiverValue:
|
||||||
|
expression = i()()
|
||||||
|
isSafeNavigation = false
|
||||||
|
signature = KtFunctionLikeSignature:
|
||||||
|
receiverType = kotlin.Double
|
||||||
|
returnType = kotlin.Unit
|
||||||
|
symbol = /invoke(<extension receiver>: kotlin.Double): kotlin.Unit
|
||||||
|
valueParameters = []
|
||||||
|
argumentMapping = {}
|
||||||
+3
-1
@@ -2,7 +2,9 @@ KtSuccessCallInfo:
|
|||||||
call = KtSimpleFunctionCall:
|
call = KtSimpleFunctionCall:
|
||||||
isImplicitInvoke = true
|
isImplicitInvoke = true
|
||||||
partiallyAppliedSymbol = KtPartiallyAppliedSymbol:
|
partiallyAppliedSymbol = KtPartiallyAppliedSymbol:
|
||||||
dispatchReceiver = null
|
dispatchReceiver = KtExplicitReceiverValue:
|
||||||
|
expression = x
|
||||||
|
isSafeNavigation = false
|
||||||
extensionReceiver = null
|
extensionReceiver = null
|
||||||
signature = KtFunctionLikeSignature:
|
signature = KtFunctionLikeSignature:
|
||||||
receiverType = null
|
receiverType = null
|
||||||
|
|||||||
+3
-1
@@ -3,7 +3,9 @@ KtSuccessCallInfo:
|
|||||||
isImplicitInvoke = true
|
isImplicitInvoke = true
|
||||||
partiallyAppliedSymbol = KtPartiallyAppliedSymbol:
|
partiallyAppliedSymbol = KtPartiallyAppliedSymbol:
|
||||||
dispatchReceiver = null
|
dispatchReceiver = null
|
||||||
extensionReceiver = null
|
extensionReceiver = KtExplicitReceiverValue:
|
||||||
|
expression = x
|
||||||
|
isSafeNavigation = false
|
||||||
signature = KtFunctionLikeSignature:
|
signature = KtFunctionLikeSignature:
|
||||||
receiverType = kotlin.Int
|
receiverType = kotlin.Int
|
||||||
returnType = kotlin.String
|
returnType = kotlin.String
|
||||||
|
|||||||
@@ -178,6 +178,9 @@ class FirCallResolver(
|
|||||||
return super.consumeCandidate(group, candidate, context)
|
return super.consumeCandidate(group, candidate, context)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// We want to get candidates at all tower levels.
|
||||||
|
override fun shouldStopAtTheLevel(group: TowerGroup): Boolean = false
|
||||||
|
|
||||||
val allCandidates: List<Candidate>
|
val allCandidates: List<Candidate>
|
||||||
get() = allCandidatesSet.toList()
|
get() = allCandidatesSet.toList()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -322,6 +322,11 @@ private inline fun <T : FirExpression> BodyResolveComponents.transformExpression
|
|||||||
smartcastBuilder: () -> FirWrappedExpressionWithSmartcastBuilder<T>,
|
smartcastBuilder: () -> FirWrappedExpressionWithSmartcastBuilder<T>,
|
||||||
smartcastToNullBuilder: () -> FirWrappedExpressionWithSmartcastToNullBuilder<T>
|
smartcastToNullBuilder: () -> FirWrappedExpressionWithSmartcastToNullBuilder<T>
|
||||||
): FirWrappedExpressionWithSmartcastBuilder<T>? {
|
): FirWrappedExpressionWithSmartcastBuilder<T>? {
|
||||||
|
// No need to check for smartcast if the expression was already resolved.
|
||||||
|
containingDeclarations.lastOrNull()?.let { closestDeclaration ->
|
||||||
|
if (closestDeclaration.resolvePhase >= FirResolvePhase.BODY_RESOLVE) return null
|
||||||
|
}
|
||||||
|
|
||||||
val (stability, typesFromSmartCast) = smartcastExtractor(expression) ?: return null
|
val (stability, typesFromSmartCast) = smartcastExtractor(expression) ?: return null
|
||||||
val smartcastStability = stability.impliedSmartcastStability
|
val smartcastStability = stability.impliedSmartcastStability
|
||||||
?: if (dataFlowAnalyzer.isAccessToUnstableLocalVariable(expression)) {
|
?: if (dataFlowAnalyzer.isAccessToUnstableLocalVariable(expression)) {
|
||||||
|
|||||||
+1
-1
@@ -48,7 +48,7 @@ open class CandidateCollector(
|
|||||||
|
|
||||||
fun bestCandidates(): List<Candidate> = candidates
|
fun bestCandidates(): List<Candidate> = candidates
|
||||||
|
|
||||||
fun shouldStopAtTheLevel(group: TowerGroup): Boolean =
|
open fun shouldStopAtTheLevel(group: TowerGroup): Boolean =
|
||||||
currentApplicability.shouldStopResolve && bestGroup < group
|
currentApplicability.shouldStopResolve && bestGroup < group
|
||||||
|
|
||||||
fun isSuccess(): Boolean {
|
fun isSuccess(): Boolean {
|
||||||
|
|||||||
Reference in New Issue
Block a user