FIR: Resolve callable references separately for each outer candidate
^KT-32725 In Progress
This commit is contained in:
@@ -7,8 +7,6 @@ package org.jetbrains.kotlin.fir
|
|||||||
|
|
||||||
import org.jetbrains.kotlin.fir.declarations.FirFile
|
import org.jetbrains.kotlin.fir.declarations.FirFile
|
||||||
import org.jetbrains.kotlin.fir.declarations.FirMemberDeclaration
|
import org.jetbrains.kotlin.fir.declarations.FirMemberDeclaration
|
||||||
import org.jetbrains.kotlin.fir.declarations.FirProperty
|
|
||||||
import org.jetbrains.kotlin.fir.declarations.FirSimpleFunction
|
|
||||||
import org.jetbrains.kotlin.fir.expressions.*
|
import org.jetbrains.kotlin.fir.expressions.*
|
||||||
import org.jetbrains.kotlin.fir.expressions.impl.FirExpressionStub
|
import org.jetbrains.kotlin.fir.expressions.impl.FirExpressionStub
|
||||||
import org.jetbrains.kotlin.fir.expressions.impl.FirResolvedQualifierImpl
|
import org.jetbrains.kotlin.fir.expressions.impl.FirResolvedQualifierImpl
|
||||||
@@ -35,9 +33,10 @@ import org.jetbrains.kotlin.fir.symbols.impl.*
|
|||||||
import org.jetbrains.kotlin.fir.types.ConeKotlinErrorType
|
import org.jetbrains.kotlin.fir.types.ConeKotlinErrorType
|
||||||
import org.jetbrains.kotlin.fir.types.ConeKotlinType
|
import org.jetbrains.kotlin.fir.types.ConeKotlinType
|
||||||
import org.jetbrains.kotlin.fir.types.FirTypeRef
|
import org.jetbrains.kotlin.fir.types.FirTypeRef
|
||||||
import org.jetbrains.kotlin.fir.types.coneTypeSafe
|
|
||||||
import org.jetbrains.kotlin.fir.types.impl.FirResolvedTypeRefImpl
|
import org.jetbrains.kotlin.fir.types.impl.FirResolvedTypeRefImpl
|
||||||
import org.jetbrains.kotlin.name.Name
|
import org.jetbrains.kotlin.name.Name
|
||||||
|
import org.jetbrains.kotlin.resolve.calls.inference.ConstraintSystemBuilder
|
||||||
|
import org.jetbrains.kotlin.resolve.calls.inference.model.SimpleConstraintSystemConstraintPosition
|
||||||
import org.jetbrains.kotlin.resolve.calls.results.TypeSpecificityComparator
|
import org.jetbrains.kotlin.resolve.calls.results.TypeSpecificityComparator
|
||||||
|
|
||||||
class FirCallResolver(
|
class FirCallResolver(
|
||||||
@@ -221,65 +220,77 @@ class FirCallResolver(
|
|||||||
return resultExpression
|
return resultExpression
|
||||||
}
|
}
|
||||||
|
|
||||||
fun resolveCallableReference(callableReferenceAccess: FirCallableReferenceAccess, lhs: DoubleColonLHS?): FirCallableReferenceAccess {
|
fun resolveCallableReference(
|
||||||
val resultCollector = ReferencesCandidateCollector(this, resolutionStageRunner)
|
constraintSystemBuilder: ConstraintSystemBuilder,
|
||||||
|
resolvedCallableReferenceAtom: ResolvedCallableReferenceAtom
|
||||||
|
): Boolean {
|
||||||
|
val callableReferenceAccess = resolvedCallableReferenceAtom.atom
|
||||||
|
val lhs = resolvedCallableReferenceAtom.lhs
|
||||||
|
val expectedType = resolvedCallableReferenceAtom.expectedType ?: return false
|
||||||
|
|
||||||
|
val result = CandidateCollector(this, resolutionStageRunner)
|
||||||
val consumer =
|
val consumer =
|
||||||
createCallableReferencesConsumerForLHS(
|
createCallableReferencesConsumerForLHS(
|
||||||
callableReferenceAccess, lhs, resultCollector
|
callableReferenceAccess, lhs,
|
||||||
|
result, expectedType,
|
||||||
|
constraintSystemBuilder
|
||||||
)
|
)
|
||||||
|
|
||||||
towerResolver.runResolver(consumer, implicitReceiverStack.receiversAsReversed())
|
towerResolver.runResolver(consumer, implicitReceiverStack.receiversAsReversed())
|
||||||
|
val bestCandidates = result.bestCandidates()
|
||||||
val result = resultCollector.results.firstOrNull() ?: return callableReferenceAccess
|
val noSuccessfulCandidates = result.currentApplicability < CandidateApplicability.SYNTHETIC_RESOLVED
|
||||||
|
val reducedCandidates = if (noSuccessfulCandidates) {
|
||||||
val resultingType: ConeKotlinType = when (val fir = result.symbol.fir) {
|
bestCandidates.toSet()
|
||||||
is FirSimpleFunction -> createKFunctionType(fir, lhs)
|
} else {
|
||||||
is FirProperty -> createKPropertyType(fir)
|
conflictResolver.chooseMaximallySpecificCandidates(bestCandidates, discriminateGenerics = false)
|
||||||
else -> ConeKotlinErrorType("Unknown callable kind: ${fir::class}")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
callableReferenceAccess.replaceTypeRef(FirResolvedTypeRefImpl(null, resultingType))
|
when {
|
||||||
|
noSuccessfulCandidates -> {
|
||||||
return callableReferenceAccess.transformCalleeReference(
|
return false
|
||||||
StoreNameReference,
|
}
|
||||||
FirNamedReferenceWithCandidate(callableReferenceAccess.psi, callableReferenceAccess.calleeReference.name, result)
|
reducedCandidates.size > 1 -> {
|
||||||
)
|
// TODO: add postponed atom
|
||||||
}
|
return true
|
||||||
|
}
|
||||||
private fun createKPropertyType(fir: FirProperty): ConeKotlinType {
|
|
||||||
TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun createKFunctionType(
|
|
||||||
function: FirSimpleFunction,
|
|
||||||
lhs: DoubleColonLHS?
|
|
||||||
): ConeKotlinType {
|
|
||||||
val receiverType = (lhs as? DoubleColonLHS.Type)?.type
|
|
||||||
val parameterTypes = function.valueParameters.map {
|
|
||||||
it.returnTypeRef.coneTypeSafe<ConeKotlinType>() ?: ConeKotlinErrorType("No type for parameter $it")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return createFunctionalType(
|
val chosenCandidate = reducedCandidates.single()
|
||||||
parameterTypes, receiverType = receiverType,
|
constraintSystemBuilder.runTransaction {
|
||||||
rawReturnType = function.returnTypeRef.coneTypeSafe() ?: ConeKotlinErrorType("No type for return type of $this")
|
addOtherSystem(chosenCandidate.system.asReadOnlyStorage())
|
||||||
)
|
|
||||||
|
val position = SimpleConstraintSystemConstraintPosition //TODO
|
||||||
|
addSubtypeConstraint(chosenCandidate.resultingTypeForCallableReference!!, expectedType, position)
|
||||||
|
|
||||||
|
true
|
||||||
|
}
|
||||||
|
|
||||||
|
resolvedCallableReferenceAtom.resultingCandidate = Pair(chosenCandidate, result.currentApplicability)
|
||||||
|
|
||||||
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun createCallableReferencesConsumerForLHS(
|
private fun createCallableReferencesConsumerForLHS(
|
||||||
callableReferenceAccess: FirCallableReferenceAccess,
|
callableReferenceAccess: FirCallableReferenceAccess,
|
||||||
lhs: DoubleColonLHS?,
|
lhs: DoubleColonLHS?,
|
||||||
resultCollector: CandidateCollector
|
resultCollector: CandidateCollector,
|
||||||
|
expectedType: ConeKotlinType?,
|
||||||
|
outerConstraintSystemBuilder: ConstraintSystemBuilder?
|
||||||
): TowerDataConsumer {
|
): TowerDataConsumer {
|
||||||
val name = callableReferenceAccess.calleeReference.name
|
val name = callableReferenceAccess.calleeReference.name
|
||||||
|
|
||||||
return when (lhs) {
|
return when (lhs) {
|
||||||
is DoubleColonLHS.Expression, null -> createCallableReferencesConsumerForReceiver(
|
is DoubleColonLHS.Expression, null -> createCallableReferencesConsumerForReceiver(
|
||||||
name, resultCollector, callableReferenceAccess.explicitReceiver
|
name, resultCollector, callableReferenceAccess.explicitReceiver, expectedType, outerConstraintSystemBuilder,
|
||||||
|
lhs
|
||||||
)
|
)
|
||||||
is DoubleColonLHS.Type -> createCallableReferencesConsumerForReceiver(
|
is DoubleColonLHS.Type -> createCallableReferencesConsumerForReceiver(
|
||||||
name, resultCollector,
|
name,
|
||||||
FirExpressionStub(callableReferenceAccess.psi).apply { replaceTypeRef(FirResolvedTypeRefImpl(null, lhs.type)) }
|
resultCollector,
|
||||||
|
FirExpressionStub(callableReferenceAccess.psi).apply { replaceTypeRef(FirResolvedTypeRefImpl(null, lhs.type)) },
|
||||||
|
expectedType,
|
||||||
|
outerConstraintSystemBuilder,
|
||||||
|
lhs
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -287,7 +298,10 @@ class FirCallResolver(
|
|||||||
private fun createCallableReferencesConsumerForReceiver(
|
private fun createCallableReferencesConsumerForReceiver(
|
||||||
name: Name,
|
name: Name,
|
||||||
resultCollector: CandidateCollector,
|
resultCollector: CandidateCollector,
|
||||||
receiver: FirExpression?
|
receiver: FirExpression?,
|
||||||
|
expectedType: ConeKotlinType?,
|
||||||
|
outerConstraintSystemBuilder: ConstraintSystemBuilder?,
|
||||||
|
lhs: DoubleColonLHS?
|
||||||
): TowerDataConsumer {
|
): TowerDataConsumer {
|
||||||
val info = CallInfo(
|
val info = CallInfo(
|
||||||
CallKind.CallableReference,
|
CallKind.CallableReference,
|
||||||
@@ -297,7 +311,10 @@ class FirCallResolver(
|
|||||||
emptyList(),
|
emptyList(),
|
||||||
session,
|
session,
|
||||||
file,
|
file,
|
||||||
transformer.components.container
|
transformer.components.container,
|
||||||
|
expectedType,
|
||||||
|
outerConstraintSystemBuilder,
|
||||||
|
lhs
|
||||||
) { it.resultType }
|
) { it.resultType }
|
||||||
|
|
||||||
return createCallableReferencesConsumer(session, name, info, this, resultCollector)
|
return createCallableReferencesConsumer(session, name, info, this, resultCollector)
|
||||||
|
|||||||
@@ -5,6 +5,7 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.fir.resolve
|
package org.jetbrains.kotlin.fir.resolve
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.fir.FirCallResolver
|
||||||
import org.jetbrains.kotlin.fir.FirSession
|
import org.jetbrains.kotlin.fir.FirSession
|
||||||
import org.jetbrains.kotlin.fir.FirSymbolOwner
|
import org.jetbrains.kotlin.fir.FirSymbolOwner
|
||||||
import org.jetbrains.kotlin.fir.declarations.FirDeclaration
|
import org.jetbrains.kotlin.fir.declarations.FirDeclaration
|
||||||
@@ -32,6 +33,8 @@ interface BodyResolveComponents : SessionHolder {
|
|||||||
val resolutionStageRunner: ResolutionStageRunner
|
val resolutionStageRunner: ResolutionStageRunner
|
||||||
val scopeSession: ScopeSession
|
val scopeSession: ScopeSession
|
||||||
val samResolver: FirSamResolver
|
val samResolver: FirSamResolver
|
||||||
|
val callResolver: FirCallResolver
|
||||||
|
val doubleColonExpressionResolver: FirDoubleColonExpressionResolver
|
||||||
|
|
||||||
val <D> AbstractFirBasedSymbol<D>.phasedFir: D where D : FirDeclaration, D : FirSymbolOwner<D>
|
val <D> AbstractFirBasedSymbol<D>.phasedFir: D where D : FirDeclaration, D : FirSymbolOwner<D>
|
||||||
get() = phasedFir(session, FirResolvePhase.DECLARATIONS)
|
get() = phasedFir(session, FirResolvePhase.DECLARATIONS)
|
||||||
|
|||||||
@@ -17,7 +17,6 @@ import org.jetbrains.kotlin.fir.types.*
|
|||||||
import org.jetbrains.kotlin.resolve.calls.inference.ConstraintSystemBuilder
|
import org.jetbrains.kotlin.resolve.calls.inference.ConstraintSystemBuilder
|
||||||
import org.jetbrains.kotlin.resolve.calls.inference.addSubtypeConstraintIfCompatible
|
import org.jetbrains.kotlin.resolve.calls.inference.addSubtypeConstraintIfCompatible
|
||||||
import org.jetbrains.kotlin.resolve.calls.inference.model.SimpleConstraintSystemConstraintPosition
|
import org.jetbrains.kotlin.resolve.calls.inference.model.SimpleConstraintSystemConstraintPosition
|
||||||
import org.jetbrains.kotlin.resolve.calls.model.PostponedResolvedAtomMarker
|
|
||||||
|
|
||||||
|
|
||||||
fun Candidate.resolveArgumentExpression(
|
fun Candidate.resolveArgumentExpression(
|
||||||
@@ -48,7 +47,7 @@ fun Candidate.resolveArgumentExpression(
|
|||||||
typeProvider
|
typeProvider
|
||||||
)
|
)
|
||||||
// TODO:!
|
// TODO:!
|
||||||
is FirCallableReferenceAccess -> preprocessCallableReference(csBuilder, argument, expectedType, sink)
|
is FirCallableReferenceAccess -> preprocessCallableReference(argument, expectedType)
|
||||||
// NB: FirCallableReferenceAccess should be checked earlier
|
// NB: FirCallableReferenceAccess should be checked earlier
|
||||||
is FirQualifiedAccessExpression -> resolvePlainExpressionArgument(
|
is FirQualifiedAccessExpression -> resolvePlainExpressionArgument(
|
||||||
csBuilder,
|
csBuilder,
|
||||||
|
|||||||
@@ -29,7 +29,8 @@ sealed class CallKind {
|
|||||||
CreateFreshTypeVariableSubstitutorStage,
|
CreateFreshTypeVariableSubstitutorStage,
|
||||||
CheckReceivers.Dispatch,
|
CheckReceivers.Dispatch,
|
||||||
CheckReceivers.Extension,
|
CheckReceivers.Extension,
|
||||||
CheckArguments
|
CheckArguments,
|
||||||
|
EagerResolveOfCallableReferences
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -48,7 +49,8 @@ sealed class CallKind {
|
|||||||
override val resolutionSequence: List<ResolutionStage> = listOf(
|
override val resolutionSequence: List<ResolutionStage> = listOf(
|
||||||
CheckVisibility,
|
CheckVisibility,
|
||||||
DiscriminateSynthetics,
|
DiscriminateSynthetics,
|
||||||
CreateFreshTypeVariableSubstitutorStage
|
CreateFreshTypeVariableSubstitutorStage,
|
||||||
|
CheckCallableReferenceExpectedType
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,10 +12,13 @@ import org.jetbrains.kotlin.fir.declarations.FirValueParameter
|
|||||||
import org.jetbrains.kotlin.fir.expressions.FirExpression
|
import org.jetbrains.kotlin.fir.expressions.FirExpression
|
||||||
import org.jetbrains.kotlin.fir.expressions.impl.FirNoReceiverExpression
|
import org.jetbrains.kotlin.fir.expressions.impl.FirNoReceiverExpression
|
||||||
import org.jetbrains.kotlin.fir.resolve.BodyResolveComponents
|
import org.jetbrains.kotlin.fir.resolve.BodyResolveComponents
|
||||||
|
import org.jetbrains.kotlin.fir.resolve.DoubleColonLHS
|
||||||
import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutor
|
import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutor
|
||||||
import org.jetbrains.kotlin.fir.symbols.AbstractFirBasedSymbol
|
import org.jetbrains.kotlin.fir.symbols.AbstractFirBasedSymbol
|
||||||
|
import org.jetbrains.kotlin.fir.types.ConeKotlinType
|
||||||
import org.jetbrains.kotlin.fir.types.FirTypeProjection
|
import org.jetbrains.kotlin.fir.types.FirTypeProjection
|
||||||
import org.jetbrains.kotlin.fir.types.FirTypeRef
|
import org.jetbrains.kotlin.fir.types.FirTypeRef
|
||||||
|
import org.jetbrains.kotlin.resolve.calls.inference.ConstraintSystemBuilder
|
||||||
import org.jetbrains.kotlin.resolve.calls.inference.model.ConstraintStorage
|
import org.jetbrains.kotlin.resolve.calls.inference.model.ConstraintStorage
|
||||||
import org.jetbrains.kotlin.resolve.calls.model.PostponedResolvedAtomMarker
|
import org.jetbrains.kotlin.resolve.calls.model.PostponedResolvedAtomMarker
|
||||||
import org.jetbrains.kotlin.resolve.calls.tasks.ExplicitReceiverKind
|
import org.jetbrains.kotlin.resolve.calls.tasks.ExplicitReceiverKind
|
||||||
@@ -31,6 +34,12 @@ class CallInfo(
|
|||||||
val session: FirSession,
|
val session: FirSession,
|
||||||
val containingFile: FirFile,
|
val containingFile: FirFile,
|
||||||
val container: FirDeclaration,
|
val container: FirDeclaration,
|
||||||
|
|
||||||
|
// Three properties for callable references only
|
||||||
|
val expectedType: ConeKotlinType? = null,
|
||||||
|
val outerCSBuilder: ConstraintSystemBuilder? = null,
|
||||||
|
val lhs: DoubleColonLHS? = null,
|
||||||
|
|
||||||
val typeProvider: (FirExpression) -> FirTypeRef?
|
val typeProvider: (FirExpression) -> FirTypeRef?
|
||||||
) {
|
) {
|
||||||
val argumentCount get() = arguments.size
|
val argumentCount get() = arguments.size
|
||||||
@@ -50,7 +59,7 @@ class Candidate(
|
|||||||
val dispatchReceiverValue: ClassDispatchReceiverValue?,
|
val dispatchReceiverValue: ClassDispatchReceiverValue?,
|
||||||
val implicitExtensionReceiverValue: ImplicitReceiverValue<*>?,
|
val implicitExtensionReceiverValue: ImplicitReceiverValue<*>?,
|
||||||
val explicitReceiverKind: ExplicitReceiverKind,
|
val explicitReceiverKind: ExplicitReceiverKind,
|
||||||
private val bodyResolveComponents: BodyResolveComponents,
|
val bodyResolveComponents: BodyResolveComponents,
|
||||||
private val baseSystem: ConstraintStorage,
|
private val baseSystem: ConstraintStorage,
|
||||||
val callInfo: CallInfo
|
val callInfo: CallInfo
|
||||||
) {
|
) {
|
||||||
@@ -63,6 +72,7 @@ class Candidate(
|
|||||||
val samResolver get() = bodyResolveComponents.samResolver
|
val samResolver get() = bodyResolveComponents.samResolver
|
||||||
|
|
||||||
lateinit var substitutor: ConeSubstitutor
|
lateinit var substitutor: ConeSubstitutor
|
||||||
|
var resultingTypeForCallableReference: ConeKotlinType? = null
|
||||||
|
|
||||||
var argumentMapping: Map<FirExpression, FirValueParameter>? = null
|
var argumentMapping: Map<FirExpression, FirValueParameter>? = null
|
||||||
val postponedAtoms = mutableListOf<PostponedResolvedAtomMarker>()
|
val postponedAtoms = mutableListOf<PostponedResolvedAtomMarker>()
|
||||||
|
|||||||
+3
-14
@@ -66,20 +66,6 @@ open class CandidateCollector(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class ReferencesCandidateCollector(components: BodyResolveComponents, resolutionStageRunner: ResolutionStageRunner) :
|
|
||||||
CandidateCollector(components, resolutionStageRunner) {
|
|
||||||
|
|
||||||
val results = mutableListOf<Candidate>()
|
|
||||||
|
|
||||||
override fun consumeCandidate(group: Int, candidate: Candidate): CandidateApplicability {
|
|
||||||
val applicability = resolutionStageRunner.processCandidate(candidate)
|
|
||||||
if (applicability >= CandidateApplicability.SYNTHETIC_RESOLVED) {
|
|
||||||
results.add(candidate)
|
|
||||||
}
|
|
||||||
return CandidateApplicability.SYNTHETIC_RESOLVED
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Collects properties that potentially could be invoke receivers, like 'propertyName()',
|
// Collects properties that potentially could be invoke receivers, like 'propertyName()',
|
||||||
// and initiates further invoke resolution by adding property-bound invoke consumers
|
// and initiates further invoke resolution by adding property-bound invoke consumers
|
||||||
class InvokeReceiverCandidateCollector(
|
class InvokeReceiverCandidateCollector(
|
||||||
@@ -113,6 +99,9 @@ class InvokeReceiverCandidateCollector(
|
|||||||
session,
|
session,
|
||||||
invokeCallInfo.containingFile,
|
invokeCallInfo.containingFile,
|
||||||
invokeCallInfo.container,
|
invokeCallInfo.container,
|
||||||
|
invokeCallInfo.expectedType,
|
||||||
|
invokeCallInfo.outerCSBuilder,
|
||||||
|
invokeCallInfo.lhs,
|
||||||
invokeCallInfo.typeProvider
|
invokeCallInfo.typeProvider
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
+7
-3
@@ -78,11 +78,15 @@ class ConeOverloadConflictResolver(
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun createFlatSignature(call: Candidate, function: FirSimpleFunction): FlatSignature<Candidate> {
|
private fun createFlatSignature(call: Candidate, function: FirSimpleFunction): FlatSignature<Candidate> {
|
||||||
|
val valueParametersTypes =
|
||||||
|
call.resultingTypeForCallableReference?.typeArguments?.map { it as ConeKotlinType }
|
||||||
|
?: (listOfNotNull<ConeKotlinType>(function.receiverTypeRef?.coneTypeUnsafe()) +
|
||||||
|
call.argumentMapping?.map { it.value.argumentType() }.orEmpty())
|
||||||
|
|
||||||
return FlatSignature(
|
return FlatSignature(
|
||||||
call,
|
call,
|
||||||
function.typeParameters.map { it.symbol },
|
function.typeParameters.map { it.symbol },
|
||||||
listOfNotNull<ConeKotlinType>(function.receiverTypeRef?.coneTypeUnsafe()) +
|
valueParametersTypes,
|
||||||
call.argumentMapping?.map { it.value.argumentType() }.orEmpty(),
|
|
||||||
function.receiverTypeRef != null,
|
function.receiverTypeRef != null,
|
||||||
function.valueParameters.any { it.isVararg },
|
function.valueParameters.any { it.isVararg },
|
||||||
function.valueParameters.count { it.defaultValue != null },
|
function.valueParameters.count { it.defaultValue != null },
|
||||||
@@ -253,4 +257,4 @@ class ConeSimpleConstraintSystemImpl(val system: NewConstraintSystemImpl) : Simp
|
|||||||
override val context: TypeSystemInferenceExtensionContext
|
override val context: TypeSystemInferenceExtensionContext
|
||||||
get() = system
|
get() = system
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -72,6 +72,9 @@ fun createFunctionConsumer(
|
|||||||
bodyResolveComponents.session,
|
bodyResolveComponents.session,
|
||||||
callInfo.containingFile,
|
callInfo.containingFile,
|
||||||
callInfo.container,
|
callInfo.container,
|
||||||
|
callInfo.expectedType,
|
||||||
|
callInfo.outerCSBuilder,
|
||||||
|
callInfo.lhs,
|
||||||
callInfo.typeProvider
|
callInfo.typeProvider
|
||||||
)
|
)
|
||||||
return PrioritizedTowerDataConsumer(
|
return PrioritizedTowerDataConsumer(
|
||||||
|
|||||||
+25
-12
@@ -7,13 +7,12 @@ package org.jetbrains.kotlin.fir.resolve.calls
|
|||||||
|
|
||||||
import org.jetbrains.kotlin.fir.declarations.FirAnonymousFunction
|
import org.jetbrains.kotlin.fir.declarations.FirAnonymousFunction
|
||||||
import org.jetbrains.kotlin.fir.expressions.FirCallableReferenceAccess
|
import org.jetbrains.kotlin.fir.expressions.FirCallableReferenceAccess
|
||||||
|
import org.jetbrains.kotlin.fir.resolve.DoubleColonLHS
|
||||||
import org.jetbrains.kotlin.fir.resolve.constructType
|
import org.jetbrains.kotlin.fir.resolve.constructType
|
||||||
import org.jetbrains.kotlin.fir.resolve.firSymbolProvider
|
import org.jetbrains.kotlin.fir.resolve.firSymbolProvider
|
||||||
import org.jetbrains.kotlin.fir.symbols.StandardClassIds
|
import org.jetbrains.kotlin.fir.symbols.StandardClassIds
|
||||||
import org.jetbrains.kotlin.fir.symbols.impl.ConeClassLikeLookupTagImpl
|
|
||||||
import org.jetbrains.kotlin.fir.symbols.invoke
|
import org.jetbrains.kotlin.fir.symbols.invoke
|
||||||
import org.jetbrains.kotlin.fir.types.*
|
import org.jetbrains.kotlin.fir.types.*
|
||||||
import org.jetbrains.kotlin.fir.types.impl.ConeClassTypeImpl
|
|
||||||
import org.jetbrains.kotlin.resolve.calls.inference.ConstraintSystemBuilder
|
import org.jetbrains.kotlin.resolve.calls.inference.ConstraintSystemBuilder
|
||||||
import org.jetbrains.kotlin.resolve.calls.model.PostponedResolvedAtomMarker
|
import org.jetbrains.kotlin.resolve.calls.model.PostponedResolvedAtomMarker
|
||||||
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
||||||
@@ -44,18 +43,12 @@ fun Candidate.preprocessLambdaArgument(
|
|||||||
postponedAtoms += resolvedArgument
|
postponedAtoms += resolvedArgument
|
||||||
}
|
}
|
||||||
|
|
||||||
fun preprocessCallableReference(
|
fun Candidate.preprocessCallableReference(
|
||||||
csBuilder: ConstraintSystemBuilder,
|
|
||||||
argument: FirCallableReferenceAccess,
|
argument: FirCallableReferenceAccess,
|
||||||
expectedType: ConeKotlinType,
|
expectedType: ConeKotlinType
|
||||||
sink: CheckerSink
|
|
||||||
) {
|
) {
|
||||||
val type = argument.typeRef.coneTypeSafe<ConeKotlinType>() ?: return
|
val lhs = bodyResolveComponents.doubleColonExpressionResolver.resolveDoubleColonLHS(argument)
|
||||||
val candidate = argument.candidate() ?: return resolvePlainArgumentType(
|
postponedAtoms += EagerCallableReferenceAtom(argument, expectedType, lhs)
|
||||||
csBuilder, type, expectedType, sink, isReceiver = false, isSafeCall = false
|
|
||||||
)
|
|
||||||
val argumentType = candidate.substitutor.substituteOrSelf(type)
|
|
||||||
resolvePlainArgumentType(csBuilder, argumentType, expectedType, sink, isReceiver = false, isSafeCall = false)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
val ConeKotlinType.isBuiltinFunctionalType: Boolean
|
val ConeKotlinType.isBuiltinFunctionalType: Boolean
|
||||||
@@ -211,3 +204,23 @@ class ResolvedLambdaAtom(
|
|||||||
override val inputTypes: Collection<ConeKotlinType> get() = receiver?.let { parameters + it } ?: parameters
|
override val inputTypes: Collection<ConeKotlinType> get() = receiver?.let { parameters + it } ?: parameters
|
||||||
override val outputType: ConeKotlinType get() = returnType
|
override val outputType: ConeKotlinType get() = returnType
|
||||||
}
|
}
|
||||||
|
|
||||||
|
abstract class ResolvedCallableReferenceAtom(
|
||||||
|
val atom: FirCallableReferenceAccess,
|
||||||
|
val expectedType: ConeKotlinType?,
|
||||||
|
val lhs: DoubleColonLHS?
|
||||||
|
) : PostponedResolvedAtomMarker {
|
||||||
|
override var analyzed: Boolean = false
|
||||||
|
|
||||||
|
var resultingCandidate: Pair<Candidate, CandidateApplicability>? = null
|
||||||
|
}
|
||||||
|
|
||||||
|
class EagerCallableReferenceAtom(
|
||||||
|
atom: FirCallableReferenceAccess,
|
||||||
|
expectedType: ConeKotlinType?,
|
||||||
|
lhs: DoubleColonLHS?
|
||||||
|
) : ResolvedCallableReferenceAtom(atom, expectedType, lhs) {
|
||||||
|
|
||||||
|
override val inputTypes: Collection<ConeKotlinType> get() = emptyList()
|
||||||
|
override val outputType: ConeKotlinType? get() = null
|
||||||
|
}
|
||||||
|
|||||||
+36
-5
@@ -7,17 +7,23 @@ package org.jetbrains.kotlin.fir.resolve.calls
|
|||||||
|
|
||||||
import org.jetbrains.kotlin.fir.declarations.FirAnonymousFunction
|
import org.jetbrains.kotlin.fir.declarations.FirAnonymousFunction
|
||||||
import org.jetbrains.kotlin.fir.expressions.FirExpression
|
import org.jetbrains.kotlin.fir.expressions.FirExpression
|
||||||
|
import org.jetbrains.kotlin.fir.references.impl.FirErrorNamedReferenceImpl
|
||||||
import org.jetbrains.kotlin.fir.resolve.constructType
|
import org.jetbrains.kotlin.fir.resolve.constructType
|
||||||
import org.jetbrains.kotlin.fir.resolve.firSymbolProvider
|
import org.jetbrains.kotlin.fir.resolve.firSymbolProvider
|
||||||
|
import org.jetbrains.kotlin.fir.resolve.transformers.StoreNameReference
|
||||||
import org.jetbrains.kotlin.fir.symbols.StandardClassIds.Unit
|
import org.jetbrains.kotlin.fir.symbols.StandardClassIds.Unit
|
||||||
|
import org.jetbrains.kotlin.fir.symbols.invoke
|
||||||
import org.jetbrains.kotlin.fir.types.ConeKotlinType
|
import org.jetbrains.kotlin.fir.types.ConeKotlinType
|
||||||
import org.jetbrains.kotlin.fir.types.FirTypeRef
|
import org.jetbrains.kotlin.fir.types.FirTypeRef
|
||||||
|
import org.jetbrains.kotlin.fir.types.impl.FirResolvedTypeRefImpl
|
||||||
import org.jetbrains.kotlin.resolve.calls.components.InferenceSession
|
import org.jetbrains.kotlin.resolve.calls.components.InferenceSession
|
||||||
import org.jetbrains.kotlin.resolve.calls.components.PostponedArgumentsAnalyzer
|
import org.jetbrains.kotlin.resolve.calls.components.PostponedArgumentsAnalyzer
|
||||||
import org.jetbrains.kotlin.resolve.calls.inference.model.SimpleConstraintSystemConstraintPosition
|
import org.jetbrains.kotlin.resolve.calls.inference.model.SimpleConstraintSystemConstraintPosition
|
||||||
import org.jetbrains.kotlin.resolve.calls.model.PostponedResolvedAtomMarker
|
import org.jetbrains.kotlin.resolve.calls.model.PostponedResolvedAtomMarker
|
||||||
import org.jetbrains.kotlin.types.model.*
|
import org.jetbrains.kotlin.types.model.StubTypeMarker
|
||||||
import org.jetbrains.kotlin.fir.symbols.invoke
|
import org.jetbrains.kotlin.types.model.TypeVariableMarker
|
||||||
|
import org.jetbrains.kotlin.types.model.freshTypeConstructor
|
||||||
|
import org.jetbrains.kotlin.types.model.safeSubstitute
|
||||||
|
|
||||||
interface LambdaAnalyzer {
|
interface LambdaAnalyzer {
|
||||||
fun analyzeAndGetLambdaReturnArguments(
|
fun analyzeAndGetLambdaReturnArguments(
|
||||||
@@ -36,7 +42,8 @@ class PostponedArgumentsAnalyzer(
|
|||||||
private val lambdaAnalyzer: LambdaAnalyzer,
|
private val lambdaAnalyzer: LambdaAnalyzer,
|
||||||
private val typeProvider: (FirExpression) -> FirTypeRef?,
|
private val typeProvider: (FirExpression) -> FirTypeRef?,
|
||||||
private val components: InferenceComponents,
|
private val components: InferenceComponents,
|
||||||
private val candidate: Candidate
|
private val candidate: Candidate,
|
||||||
|
private val replacements: MutableMap<FirExpression, FirExpression>
|
||||||
) {
|
) {
|
||||||
|
|
||||||
fun analyze(
|
fun analyze(
|
||||||
@@ -54,8 +61,7 @@ class PostponedArgumentsAnalyzer(
|
|||||||
// c, resolutionCallbacks, argument.transformToResolvedLambda(c.getBuilder()), diagnosticsHolder
|
// c, resolutionCallbacks, argument.transformToResolvedLambda(c.getBuilder()), diagnosticsHolder
|
||||||
// )
|
// )
|
||||||
|
|
||||||
// is ResolvedCallableReferenceAtom ->
|
is ResolvedCallableReferenceAtom -> processCallableReference(argument)
|
||||||
// callableReferenceResolver.processCallableReferenceArgument(c.getBuilder(), argument, diagnosticsHolder)
|
|
||||||
//
|
//
|
||||||
// is ResolvedCollectionLiteralAtom -> TODO("Not supported")
|
// is ResolvedCollectionLiteralAtom -> TODO("Not supported")
|
||||||
|
|
||||||
@@ -63,6 +69,31 @@ class PostponedArgumentsAnalyzer(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun processCallableReference(atom: ResolvedCallableReferenceAtom) {
|
||||||
|
val callableReferenceAccess = atom.atom
|
||||||
|
atom.analyzed = true
|
||||||
|
val (candidate, applicability) = atom.resultingCandidate ?: Pair(null, CandidateApplicability.INAPPLICABLE)
|
||||||
|
|
||||||
|
val namedReference = when {
|
||||||
|
candidate == null || applicability < CandidateApplicability.SYNTHETIC_RESOLVED ->
|
||||||
|
FirErrorNamedReferenceImpl(
|
||||||
|
callableReferenceAccess.psi,
|
||||||
|
"Unresolved reference: ${callableReferenceAccess.calleeReference.name}"
|
||||||
|
)
|
||||||
|
else -> FirNamedReferenceWithCandidate(callableReferenceAccess.psi, callableReferenceAccess.calleeReference.name, candidate)
|
||||||
|
}
|
||||||
|
|
||||||
|
val transformedCalleeReference = callableReferenceAccess.transformCalleeReference(
|
||||||
|
StoreNameReference,
|
||||||
|
namedReference
|
||||||
|
).apply {
|
||||||
|
if (candidate != null) {
|
||||||
|
replaceTypeRef(FirResolvedTypeRefImpl(null, candidate.resultingTypeForCallableReference!!))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
replacements[callableReferenceAccess] = transformedCalleeReference
|
||||||
|
}
|
||||||
|
|
||||||
private fun analyzeLambda(
|
private fun analyzeLambda(
|
||||||
c: PostponedArgumentsAnalyzer.Context,
|
c: PostponedArgumentsAnalyzer.Context,
|
||||||
|
|||||||
@@ -7,17 +7,24 @@ package org.jetbrains.kotlin.fir.resolve.calls
|
|||||||
|
|
||||||
import org.jetbrains.kotlin.descriptors.Visibilities
|
import org.jetbrains.kotlin.descriptors.Visibilities
|
||||||
import org.jetbrains.kotlin.fir.declarations.FirMemberDeclaration
|
import org.jetbrains.kotlin.fir.declarations.FirMemberDeclaration
|
||||||
|
import org.jetbrains.kotlin.fir.declarations.FirProperty
|
||||||
|
import org.jetbrains.kotlin.fir.declarations.FirSimpleFunction
|
||||||
import org.jetbrains.kotlin.fir.declarations.visibility
|
import org.jetbrains.kotlin.fir.declarations.visibility
|
||||||
import org.jetbrains.kotlin.fir.expressions.FirResolvedQualifier
|
import org.jetbrains.kotlin.fir.expressions.FirResolvedQualifier
|
||||||
|
import org.jetbrains.kotlin.fir.resolve.DoubleColonLHS
|
||||||
|
import org.jetbrains.kotlin.fir.resolve.createFunctionalType
|
||||||
import org.jetbrains.kotlin.fir.resolve.firProvider
|
import org.jetbrains.kotlin.fir.resolve.firProvider
|
||||||
import org.jetbrains.kotlin.fir.symbols.AbstractFirBasedSymbol
|
import org.jetbrains.kotlin.fir.symbols.AbstractFirBasedSymbol
|
||||||
import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol
|
import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol
|
||||||
import org.jetbrains.kotlin.fir.symbols.impl.FirClassLikeSymbol
|
import org.jetbrains.kotlin.fir.symbols.impl.FirClassLikeSymbol
|
||||||
import org.jetbrains.kotlin.fir.symbols.impl.FirFunctionSymbol
|
import org.jetbrains.kotlin.fir.symbols.impl.FirFunctionSymbol
|
||||||
|
import org.jetbrains.kotlin.fir.types.ConeKotlinErrorType
|
||||||
import org.jetbrains.kotlin.fir.types.ConeKotlinType
|
import org.jetbrains.kotlin.fir.types.ConeKotlinType
|
||||||
import org.jetbrains.kotlin.fir.types.FirResolvedTypeRef
|
import org.jetbrains.kotlin.fir.types.FirResolvedTypeRef
|
||||||
|
import org.jetbrains.kotlin.fir.types.coneTypeSafe
|
||||||
import org.jetbrains.kotlin.load.java.JavaVisibilities
|
import org.jetbrains.kotlin.load.java.JavaVisibilities
|
||||||
import org.jetbrains.kotlin.name.FqName
|
import org.jetbrains.kotlin.name.FqName
|
||||||
|
import org.jetbrains.kotlin.resolve.calls.inference.model.SimpleConstraintSystemConstraintPosition
|
||||||
import org.jetbrains.kotlin.resolve.calls.tasks.ExplicitReceiverKind
|
import org.jetbrains.kotlin.resolve.calls.tasks.ExplicitReceiverKind
|
||||||
import org.jetbrains.kotlin.resolve.calls.tasks.ExplicitReceiverKind.*
|
import org.jetbrains.kotlin.resolve.calls.tasks.ExplicitReceiverKind.*
|
||||||
|
|
||||||
@@ -156,6 +163,69 @@ internal object CheckArguments : CheckerStage() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal object EagerResolveOfCallableReferences : CheckerStage() {
|
||||||
|
override suspend fun check(candidate: Candidate, sink: CheckerSink, callInfo: CallInfo) {
|
||||||
|
for (atom in candidate.postponedAtoms.filterIsInstance<EagerCallableReferenceAtom>()) {
|
||||||
|
if (!candidate.bodyResolveComponents.callResolver.resolveCallableReference(candidate.csBuilder, atom)) {
|
||||||
|
sink.yieldApplicability(CandidateApplicability.INAPPLICABLE)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
internal object CheckCallableReferenceExpectedType : CheckerStage() {
|
||||||
|
override suspend fun check(candidate: Candidate, sink: CheckerSink, callInfo: CallInfo) {
|
||||||
|
val outerCsBuilder = callInfo.outerCSBuilder ?: return
|
||||||
|
val expectedType = callInfo.expectedType ?: return
|
||||||
|
val lhs = callInfo.lhs
|
||||||
|
|
||||||
|
val resultingType: ConeKotlinType = when (val fir = candidate.symbol.fir) {
|
||||||
|
is FirSimpleFunction -> createKFunctionType(fir, lhs)
|
||||||
|
is FirProperty -> createKPropertyType(fir)
|
||||||
|
else -> ConeKotlinErrorType("Unknown callable kind: ${fir::class}")
|
||||||
|
}.let(candidate.substitutor::substituteOrSelf)
|
||||||
|
|
||||||
|
candidate.resultingTypeForCallableReference = resultingType
|
||||||
|
|
||||||
|
var isApplicable = true
|
||||||
|
|
||||||
|
outerCsBuilder.runTransaction {
|
||||||
|
addOtherSystem(candidate.system.asReadOnlyStorage())
|
||||||
|
|
||||||
|
val position = SimpleConstraintSystemConstraintPosition //TODO
|
||||||
|
|
||||||
|
addSubtypeConstraint(resultingType, expectedType, position)
|
||||||
|
isApplicable = !hasContradiction
|
||||||
|
|
||||||
|
false
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!isApplicable) {
|
||||||
|
sink.yieldApplicability(CandidateApplicability.INAPPLICABLE)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun createKPropertyType(fir: FirProperty): ConeKotlinType {
|
||||||
|
TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun createKFunctionType(
|
||||||
|
function: FirSimpleFunction,
|
||||||
|
lhs: DoubleColonLHS?
|
||||||
|
): ConeKotlinType {
|
||||||
|
val receiverType = (lhs as? DoubleColonLHS.Type)?.type
|
||||||
|
val parameterTypes = function.valueParameters.map {
|
||||||
|
it.returnTypeRef.coneTypeSafe<ConeKotlinType>() ?: ConeKotlinErrorType("No type for parameter $it")
|
||||||
|
}
|
||||||
|
|
||||||
|
return createFunctionalType(
|
||||||
|
parameterTypes, receiverType = receiverType,
|
||||||
|
rawReturnType = function.returnTypeRef.coneTypeSafe() ?: ConeKotlinErrorType("No type for return type of $function"),
|
||||||
|
isKFunctionType = true
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
internal object DiscriminateSynthetics : CheckerStage() {
|
internal object DiscriminateSynthetics : CheckerStage() {
|
||||||
override suspend fun check(candidate: Candidate, sink: CheckerSink, callInfo: CallInfo) {
|
override suspend fun check(candidate: Candidate, sink: CheckerSink, callInfo: CallInfo) {
|
||||||
if (candidate.symbol is SyntheticSymbol) {
|
if (candidate.symbol is SyntheticSymbol) {
|
||||||
@@ -203,4 +273,4 @@ internal object CheckVisibility : CheckerStage() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -71,7 +71,7 @@ class FirCallCompleter(
|
|||||||
val replacements = mutableMapOf<FirExpression, FirExpression>()
|
val replacements = mutableMapOf<FirExpression, FirExpression>()
|
||||||
|
|
||||||
val analyzer =
|
val analyzer =
|
||||||
PostponedArgumentsAnalyzer(LambdaAnalyzerImpl(replacements), { it.resultType }, inferenceComponents, candidate)
|
PostponedArgumentsAnalyzer(LambdaAnalyzerImpl(replacements), { it.resultType }, inferenceComponents, candidate, replacements)
|
||||||
|
|
||||||
completer.complete(candidate.system.asConstraintSystemCompleterContext(), completionMode, listOf(call), initialType) {
|
completer.complete(candidate.system.asConstraintSystemCompleterContext(), completionMode, listOf(call), initialType) {
|
||||||
analyzer.analyze(candidate.system.asPostponedArgumentsAnalyzerContext(), it)
|
analyzer.analyze(candidate.system.asPostponedArgumentsAnalyzerContext(), it)
|
||||||
|
|||||||
+1
-3
@@ -266,9 +266,7 @@ class FirExpressionsResolveTransformer(transformer: FirBodyResolveTransformer) :
|
|||||||
else
|
else
|
||||||
callableReferenceAccess
|
callableReferenceAccess
|
||||||
|
|
||||||
val lhsResult = doubleColonExpressionResolver.resolveDoubleColonLHS(callableReferenceAccessWithTransformedLHS)
|
return callableReferenceAccessWithTransformedLHS.compose()
|
||||||
|
|
||||||
return callResolver.resolveCallableReference(callableReferenceAccessWithTransformedLHS, lhsResult).compose()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun transformGetClassCall(getClassCall: FirGetClassCall, data: Any?): CompositeTransformResult<FirStatement> {
|
override fun transformGetClassCall(getClassCall: FirGetClassCall, data: Any?): CompositeTransformResult<FirStatement> {
|
||||||
|
|||||||
+10
@@ -0,0 +1,10 @@
|
|||||||
|
fun foo(x: () -> Int, y: Int) {}
|
||||||
|
fun bar(x: String): Int = 1
|
||||||
|
|
||||||
|
fun main() {
|
||||||
|
fun bar(): Int = 1
|
||||||
|
fun foo(x: (String) -> Int, y: String) {}
|
||||||
|
|
||||||
|
foo(::bar, 1)
|
||||||
|
foo(::bar, "")
|
||||||
|
}
|
||||||
+17
@@ -0,0 +1,17 @@
|
|||||||
|
FILE: differentLevels.kt
|
||||||
|
public final fun foo(x: R|kotlin/Function0<kotlin/Int>|, y: R|kotlin/Int|): R|kotlin/Unit| {
|
||||||
|
}
|
||||||
|
public final fun bar(x: R|kotlin/String|): R|kotlin/Int| {
|
||||||
|
^bar Int(1)
|
||||||
|
}
|
||||||
|
public final fun main(): R|kotlin/Unit| {
|
||||||
|
local final fun bar(): R|kotlin/Int| {
|
||||||
|
^bar Int(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
local final fun foo(x: R|kotlin/Function1<kotlin/String, kotlin/Int>|, y: R|kotlin/String|): R|kotlin/Unit| {
|
||||||
|
}
|
||||||
|
|
||||||
|
R|/foo|(::R|<local>/bar|, Int(1))
|
||||||
|
R|<local>/foo|(::R|/bar|, String())
|
||||||
|
}
|
||||||
+8
@@ -0,0 +1,8 @@
|
|||||||
|
fun foo(x: Int) {}
|
||||||
|
fun foo(y: String) {}
|
||||||
|
|
||||||
|
fun <T> bar(f: (T) -> Unit) {}
|
||||||
|
|
||||||
|
fun test() {
|
||||||
|
bar(::foo)
|
||||||
|
}
|
||||||
+10
@@ -0,0 +1,10 @@
|
|||||||
|
FILE: ambiguityWhenNoApplicableCallableReferenceCandidate.kt
|
||||||
|
public final fun foo(x: R|kotlin/Int|): R|kotlin/Unit| {
|
||||||
|
}
|
||||||
|
public final fun foo(y: R|kotlin/String|): R|kotlin/Unit| {
|
||||||
|
}
|
||||||
|
public final fun <T> bar(f: R|kotlin/Function1<T, kotlin/Unit>|): R|kotlin/Unit| {
|
||||||
|
}
|
||||||
|
public final fun test(): R|kotlin/Unit| {
|
||||||
|
R|/bar|<R|kotlin/Any?|>(::<Unresolved reference: foo>#)
|
||||||
|
}
|
||||||
+12
@@ -0,0 +1,12 @@
|
|||||||
|
fun foo(s: String) {}
|
||||||
|
|
||||||
|
object Scope {
|
||||||
|
fun foo(a: Int) {}
|
||||||
|
fun foo(b: Boolean) {}
|
||||||
|
|
||||||
|
fun <T> bar(f: (T) -> Unit): T = TODO()
|
||||||
|
|
||||||
|
fun test() {
|
||||||
|
val s: String = bar(::foo)
|
||||||
|
}
|
||||||
|
}
|
||||||
+23
@@ -0,0 +1,23 @@
|
|||||||
|
FILE: applicableCallableReferenceFromDistantScope.kt
|
||||||
|
public final fun foo(s: R|kotlin/String|): R|kotlin/Unit| {
|
||||||
|
}
|
||||||
|
public final object Scope : R|kotlin/Any| {
|
||||||
|
private constructor(): R|Scope| {
|
||||||
|
super<R|kotlin/Any|>()
|
||||||
|
}
|
||||||
|
|
||||||
|
public final fun foo(a: R|kotlin/Int|): R|kotlin/Unit| {
|
||||||
|
}
|
||||||
|
|
||||||
|
public final fun foo(b: R|kotlin/Boolean|): R|kotlin/Unit| {
|
||||||
|
}
|
||||||
|
|
||||||
|
public final fun <T> bar(f: R|kotlin/Function1<T, kotlin/Unit>|): R|T| {
|
||||||
|
^bar R|kotlin/TODO|()
|
||||||
|
}
|
||||||
|
|
||||||
|
public final fun test(): R|kotlin/Unit| {
|
||||||
|
lval s: R|kotlin/String| = this@R|/Scope|.R|/Scope.bar|<R|kotlin/String|>(::<Unresolved reference: foo>#)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
+33
@@ -0,0 +1,33 @@
|
|||||||
|
class A {
|
||||||
|
fun foo(i: A) {}
|
||||||
|
|
||||||
|
fun baz(i: A) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
class B {
|
||||||
|
fun foo(s: B) {}
|
||||||
|
fun foo(c: Char) {}
|
||||||
|
|
||||||
|
fun baz(s: B) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun <T> bar(f: (T) -> Unit): T = TODO()
|
||||||
|
|
||||||
|
fun test() {
|
||||||
|
myWith(A()) {
|
||||||
|
val t1 = bar(::foo)
|
||||||
|
|
||||||
|
val t2 = bar(::baz)
|
||||||
|
|
||||||
|
myWith(B()) {
|
||||||
|
val a: A = bar(::foo)
|
||||||
|
val b: B = bar(::foo)
|
||||||
|
|
||||||
|
val t3 = bar(::baz)
|
||||||
|
|
||||||
|
bar(::foo)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
inline fun <T, R> myWith(receiver: T, block: T.() -> R): R = TODO()
|
||||||
+48
@@ -0,0 +1,48 @@
|
|||||||
|
FILE: chooseCallableReferenceDependingOnInferredReceiver.kt
|
||||||
|
public final class A : R|kotlin/Any| {
|
||||||
|
public constructor(): R|A| {
|
||||||
|
super<R|kotlin/Any|>()
|
||||||
|
}
|
||||||
|
|
||||||
|
public final fun foo(i: R|A|): R|kotlin/Unit| {
|
||||||
|
}
|
||||||
|
|
||||||
|
public final fun baz(i: R|A|): R|kotlin/Unit| {
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
public final class B : R|kotlin/Any| {
|
||||||
|
public constructor(): R|B| {
|
||||||
|
super<R|kotlin/Any|>()
|
||||||
|
}
|
||||||
|
|
||||||
|
public final fun foo(s: R|B|): R|kotlin/Unit| {
|
||||||
|
}
|
||||||
|
|
||||||
|
public final fun foo(c: R|kotlin/Char|): R|kotlin/Unit| {
|
||||||
|
}
|
||||||
|
|
||||||
|
public final fun baz(s: R|B|): R|kotlin/Unit| {
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
public final fun <T> bar(f: R|kotlin/Function1<T, kotlin/Unit>|): R|T| {
|
||||||
|
^bar R|kotlin/TODO|()
|
||||||
|
}
|
||||||
|
public final fun test(): R|kotlin/Unit| {
|
||||||
|
R|/myWith|<R|A|, R|kotlin/Unit|>(R|/A.A|(), <L> = myWith@fun <anonymous>(it: R|A|): R|kotlin/Unit| <kind=EXACTLY_ONCE> {
|
||||||
|
lval t1: <ERROR TYPE REF: Inapplicable(INAPPLICABLE): [/bar]> = <Inapplicable(INAPPLICABLE): [/bar]>#(::foo#)
|
||||||
|
lval t2: <ERROR TYPE REF: Inapplicable(INAPPLICABLE): [/bar]> = <Inapplicable(INAPPLICABLE): [/bar]>#(::baz#)
|
||||||
|
R|/myWith|<R|B|, R|kotlin/Unit|>(R|/B.B|(), <L> = myWith@fun <anonymous>(it: R|B|): R|kotlin/Unit| <kind=EXACTLY_ONCE> {
|
||||||
|
lval a: R|A| = <Inapplicable(INAPPLICABLE): [/bar]>#(::foo#)
|
||||||
|
lval b: R|B| = <Inapplicable(INAPPLICABLE): [/bar]>#(::foo#)
|
||||||
|
lval t3: <ERROR TYPE REF: Inapplicable(INAPPLICABLE): [/bar]> = <Inapplicable(INAPPLICABLE): [/bar]>#(::baz#)
|
||||||
|
<Inapplicable(INAPPLICABLE): [/bar]>#(::foo#)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
public final inline fun <T, R> myWith(receiver: R|T|, block: R|kotlin/Function1<T, R>|): R|R| {
|
||||||
|
^myWith R|kotlin/TODO|()
|
||||||
|
}
|
||||||
+12
@@ -0,0 +1,12 @@
|
|||||||
|
interface Parent
|
||||||
|
interface Child1 : Parent
|
||||||
|
interface Child2 : Parent
|
||||||
|
|
||||||
|
fun foo(): Child1 = TODO()
|
||||||
|
fun bar(): Child2 = TODO()
|
||||||
|
|
||||||
|
fun <K> select(x: K, y: K): K = TODO()
|
||||||
|
|
||||||
|
fun test() {
|
||||||
|
val a = select(::foo, ::bar)
|
||||||
|
}
|
||||||
+19
@@ -0,0 +1,19 @@
|
|||||||
|
FILE: commonSupertypeFromReturnTypesOfCallableReference.kt
|
||||||
|
public abstract interface Parent : R|kotlin/Any| {
|
||||||
|
}
|
||||||
|
public abstract interface Child1 : R|Parent| {
|
||||||
|
}
|
||||||
|
public abstract interface Child2 : R|Parent| {
|
||||||
|
}
|
||||||
|
public final fun foo(): R|Child1| {
|
||||||
|
^foo R|kotlin/TODO|()
|
||||||
|
}
|
||||||
|
public final fun bar(): R|Child2| {
|
||||||
|
^bar R|kotlin/TODO|()
|
||||||
|
}
|
||||||
|
public final fun <K> select(x: R|K|, y: R|K|): R|K| {
|
||||||
|
^select R|kotlin/TODO|()
|
||||||
|
}
|
||||||
|
public final fun test(): R|kotlin/Unit| {
|
||||||
|
lval a: R|kotlin/reflect/KFunction0<Parent>| = R|/select|<R|kotlin/reflect/KFunction0<Parent>|>(::R|/foo|, ::R|/bar|)
|
||||||
|
}
|
||||||
+26
@@ -0,0 +1,26 @@
|
|||||||
|
interface A
|
||||||
|
interface B
|
||||||
|
|
||||||
|
fun multiple(a: A) {}
|
||||||
|
fun multiple(b: B) {}
|
||||||
|
|
||||||
|
fun singleA(a: A) {}
|
||||||
|
fun singleB(a: B) {}
|
||||||
|
|
||||||
|
fun <T> foo(f: (T) -> Unit, g: (T) -> Unit): T = TODO()
|
||||||
|
|
||||||
|
fun test() {
|
||||||
|
val a1 = foo(::singleA, ::multiple)
|
||||||
|
|
||||||
|
val a2 = foo(::singleB, ::multiple)
|
||||||
|
|
||||||
|
val a3 = foo(::multiple, ::singleA)
|
||||||
|
|
||||||
|
val a4 = foo(::multiple, ::singleB)
|
||||||
|
|
||||||
|
val a5 = foo(::singleA, ::singleA)
|
||||||
|
|
||||||
|
val a6 = foo(::singleA, ::singleB)
|
||||||
|
|
||||||
|
foo(::multiple, ::multiple)
|
||||||
|
}
|
||||||
+25
@@ -0,0 +1,25 @@
|
|||||||
|
FILE: eagerAndPostponedCallableReferences.kt
|
||||||
|
public abstract interface A : R|kotlin/Any| {
|
||||||
|
}
|
||||||
|
public abstract interface B : R|kotlin/Any| {
|
||||||
|
}
|
||||||
|
public final fun multiple(a: R|A|): R|kotlin/Unit| {
|
||||||
|
}
|
||||||
|
public final fun multiple(b: R|B|): R|kotlin/Unit| {
|
||||||
|
}
|
||||||
|
public final fun singleA(a: R|A|): R|kotlin/Unit| {
|
||||||
|
}
|
||||||
|
public final fun singleB(a: R|B|): R|kotlin/Unit| {
|
||||||
|
}
|
||||||
|
public final fun <T> foo(f: R|kotlin/Function1<T, kotlin/Unit>|, g: R|kotlin/Function1<T, kotlin/Unit>|): R|T| {
|
||||||
|
^foo R|kotlin/TODO|()
|
||||||
|
}
|
||||||
|
public final fun test(): R|kotlin/Unit| {
|
||||||
|
lval a1: R|A| = R|/foo|<R|A|>(::R|/singleA|, ::<Unresolved reference: multiple>#)
|
||||||
|
lval a2: R|B| = R|/foo|<R|B|>(::R|/singleB|, ::<Unresolved reference: multiple>#)
|
||||||
|
lval a3: R|A| = R|/foo|<R|A|>(::<Unresolved reference: multiple>#, ::R|/singleA|)
|
||||||
|
lval a4: R|B| = R|/foo|<R|B|>(::<Unresolved reference: multiple>#, ::R|/singleB|)
|
||||||
|
lval a5: R|A| = R|/foo|<R|A|>(::R|/singleA|, ::R|/singleA|)
|
||||||
|
lval a6: R|it(A & B)| = R|/foo|<R|it(A & B)|>(::R|/singleA|, ::R|/singleB|)
|
||||||
|
R|/foo|<R|kotlin/Unit|>(::<Unresolved reference: multiple>#, ::<Unresolved reference: multiple>#)
|
||||||
|
}
|
||||||
+15
@@ -0,0 +1,15 @@
|
|||||||
|
// !LANGUAGE: -NewInference
|
||||||
|
// !DIAGNOSTICS: -UNUSED_PARAMETER
|
||||||
|
|
||||||
|
open class A
|
||||||
|
class B : A()
|
||||||
|
|
||||||
|
class Or(left: A, right: A) : A()
|
||||||
|
|
||||||
|
class Out<out T>
|
||||||
|
|
||||||
|
fun test(ls: Out<B>) {
|
||||||
|
ls.reduce(::Or)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun <S, T : S> Out<T>.reduce(operation: (S, T) -> S): S = TODO()
|
||||||
+31
@@ -0,0 +1,31 @@
|
|||||||
|
FILE: eagerResolveOfSingleCallableReference.kt
|
||||||
|
public open class A : R|kotlin/Any| {
|
||||||
|
public constructor(): R|A| {
|
||||||
|
super<R|kotlin/Any|>()
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
public final class B : R|A| {
|
||||||
|
public constructor(): R|B| {
|
||||||
|
super<R|A|>()
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
public final class Or : R|A| {
|
||||||
|
public constructor(left: R|A|, right: R|A|): R|Or| {
|
||||||
|
super<R|A|>()
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
public final class Out<out T> : R|kotlin/Any| {
|
||||||
|
public constructor<T>(): R|Out<T>| {
|
||||||
|
super<R|kotlin/Any|>()
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
public final fun test(ls: R|Out<B>|): R|kotlin/Unit| {
|
||||||
|
R|<local>/ls|.R|/reduce|<R|A|, R|B|>(::R|/Or.Or|)
|
||||||
|
}
|
||||||
|
public final fun <S, T : R|S|> R|Out<T>|.reduce(operation: R|kotlin/Function2<S, T, S>|): R|S| {
|
||||||
|
^reduce R|kotlin/TODO|()
|
||||||
|
}
|
||||||
+18
@@ -0,0 +1,18 @@
|
|||||||
|
interface IA
|
||||||
|
interface IB : IA
|
||||||
|
|
||||||
|
fun IA.extFun(x: IB) {}
|
||||||
|
fun IB.extFun(x: IA) {}
|
||||||
|
|
||||||
|
fun test() {
|
||||||
|
val extFun1 = IA::extFun
|
||||||
|
val extFun2 = IB::extFun
|
||||||
|
}
|
||||||
|
|
||||||
|
fun testWithExpectedType() {
|
||||||
|
val extFun_AB_A: IA.(IB) -> Unit = IA::extFun
|
||||||
|
val extFun_AA_B: IA.(IA) -> Unit = IB::extFun
|
||||||
|
val extFun_BB_A: IB.(IB) -> Unit = IA::extFun
|
||||||
|
val extFun_BA_B: IB.(IA) -> Unit = IB::extFun
|
||||||
|
val extFun_BB_B: IB.(IB) -> Unit = IB::extFun
|
||||||
|
}
|
||||||
+20
@@ -0,0 +1,20 @@
|
|||||||
|
FILE: moreSpecificAmbiguousExtensions.kt
|
||||||
|
public abstract interface IA : R|kotlin/Any| {
|
||||||
|
}
|
||||||
|
public abstract interface IB : R|IA| {
|
||||||
|
}
|
||||||
|
public final fun R|IA|.extFun(x: R|IB|): R|kotlin/Unit| {
|
||||||
|
}
|
||||||
|
public final fun R|IB|.extFun(x: R|IA|): R|kotlin/Unit| {
|
||||||
|
}
|
||||||
|
public final fun test(): R|kotlin/Unit| {
|
||||||
|
lval extFun1: <ERROR TYPE REF: No result type for initializer> = Q|IA|::extFun#
|
||||||
|
lval extFun2: <ERROR TYPE REF: No result type for initializer> = Q|IB|::extFun#
|
||||||
|
}
|
||||||
|
public final fun testWithExpectedType(): R|kotlin/Unit| {
|
||||||
|
lval extFun_AB_A: R|kotlin/Function2<IA, IB, kotlin/Unit>| = Q|IA|::extFun#
|
||||||
|
lval extFun_AA_B: R|kotlin/Function2<IA, IA, kotlin/Unit>| = Q|IB|::extFun#
|
||||||
|
lval extFun_BB_A: R|kotlin/Function2<IB, IB, kotlin/Unit>| = Q|IA|::extFun#
|
||||||
|
lval extFun_BA_B: R|kotlin/Function2<IB, IA, kotlin/Unit>| = Q|IB|::extFun#
|
||||||
|
lval extFun_BB_B: R|kotlin/Function2<IB, IB, kotlin/Unit>| = Q|IB|::extFun#
|
||||||
|
}
|
||||||
+13
@@ -0,0 +1,13 @@
|
|||||||
|
interface Base
|
||||||
|
class Inv<K> : Base
|
||||||
|
|
||||||
|
fun foo(x: Int): Inv<Int> = TODO()
|
||||||
|
fun foo(y: String): Inv<String> = TODO()
|
||||||
|
|
||||||
|
fun <T, R : Number> bar(f: (T) -> Inv<R>, p: String = "") {}
|
||||||
|
|
||||||
|
fun <T, R : Base> bar(f: (T) -> Inv<R>, p: Int = 4) {}
|
||||||
|
|
||||||
|
fun test() {
|
||||||
|
bar(::foo)
|
||||||
|
}
|
||||||
+22
@@ -0,0 +1,22 @@
|
|||||||
|
FILE: multipleOutersAndMultipleCallableReferences.kt
|
||||||
|
public abstract interface Base : R|kotlin/Any| {
|
||||||
|
}
|
||||||
|
public final class Inv<K> : R|Base| {
|
||||||
|
public constructor<K>(): R|Inv<K>| {
|
||||||
|
super<R|kotlin/Any|>()
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
public final fun foo(x: R|kotlin/Int|): R|Inv<kotlin/Int>| {
|
||||||
|
^foo R|kotlin/TODO|()
|
||||||
|
}
|
||||||
|
public final fun foo(y: R|kotlin/String|): R|Inv<kotlin/String>| {
|
||||||
|
^foo R|kotlin/TODO|()
|
||||||
|
}
|
||||||
|
public final fun <T, R : R|kotlin/Number|> bar(f: R|kotlin/Function1<T, Inv<R>>|, p: R|kotlin/String| = String()): R|kotlin/Unit| {
|
||||||
|
}
|
||||||
|
public final fun <T, R : R|Base|> bar(f: R|kotlin/Function1<T, Inv<R>>|, p: R|kotlin/Int| = Int(4)): R|kotlin/Unit| {
|
||||||
|
}
|
||||||
|
public final fun test(): R|kotlin/Unit| {
|
||||||
|
R|/bar|<R|kotlin/Int|, R|kotlin/Int|>(::R|/foo|)
|
||||||
|
}
|
||||||
+14
@@ -0,0 +1,14 @@
|
|||||||
|
import kotlin.reflect.KProperty0
|
||||||
|
import kotlin.reflect.KProperty1
|
||||||
|
|
||||||
|
fun <R> property(property: KProperty0<R>): Int = 1
|
||||||
|
fun <T, R> property(property: KProperty1<T, R>): String = ""
|
||||||
|
|
||||||
|
val subject = ""
|
||||||
|
|
||||||
|
class O {
|
||||||
|
val subject = ""
|
||||||
|
}
|
||||||
|
|
||||||
|
val someProperty0 = property(::subject)
|
||||||
|
val someProperty1 = property(O::subject)
|
||||||
+22
@@ -0,0 +1,22 @@
|
|||||||
|
FILE: noAmbiguityBetweenTopLevelAndMemberProperty.kt
|
||||||
|
public final fun <R> property(property: R|kotlin/reflect/KProperty0<R>|): R|kotlin/Int| {
|
||||||
|
^property Int(1)
|
||||||
|
}
|
||||||
|
public final fun <T, R> property(property: R|kotlin/reflect/KProperty1<T, R>|): R|kotlin/String| {
|
||||||
|
^property String()
|
||||||
|
}
|
||||||
|
public final val subject: R|kotlin/String| = String()
|
||||||
|
public get(): R|kotlin/String|
|
||||||
|
public final class O : R|kotlin/Any| {
|
||||||
|
public constructor(): R|O| {
|
||||||
|
super<R|kotlin/Any|>()
|
||||||
|
}
|
||||||
|
|
||||||
|
public final val subject: R|kotlin/String| = String()
|
||||||
|
public get(): R|kotlin/String|
|
||||||
|
|
||||||
|
}
|
||||||
|
public final val someProperty0: <ERROR TYPE REF: Inapplicable(INAPPLICABLE): [/property, /property]> = <Inapplicable(INAPPLICABLE): [/property, /property]>#(::subject#)
|
||||||
|
public get(): <ERROR TYPE REF: Inapplicable(INAPPLICABLE): [/property, /property]>
|
||||||
|
public final val someProperty1: <ERROR TYPE REF: Inapplicable(INAPPLICABLE): [/property, /property]> = <Inapplicable(INAPPLICABLE): [/property, /property]>#(Q|O|::subject#)
|
||||||
|
public get(): <ERROR TYPE REF: Inapplicable(INAPPLICABLE): [/property, /property]>
|
||||||
+10
@@ -0,0 +1,10 @@
|
|||||||
|
class C {
|
||||||
|
fun xf1(){}
|
||||||
|
fun xf1(s: String){}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun foo(p: (String) -> Unit){}
|
||||||
|
|
||||||
|
fun bar(c: C) {
|
||||||
|
foo(c::xf1)
|
||||||
|
}
|
||||||
+18
@@ -0,0 +1,18 @@
|
|||||||
|
FILE: overloadsBound.kt
|
||||||
|
public final class C : R|kotlin/Any| {
|
||||||
|
public constructor(): R|C| {
|
||||||
|
super<R|kotlin/Any|>()
|
||||||
|
}
|
||||||
|
|
||||||
|
public final fun xf1(): R|kotlin/Unit| {
|
||||||
|
}
|
||||||
|
|
||||||
|
public final fun xf1(s: R|kotlin/String|): R|kotlin/Unit| {
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
public final fun foo(p: R|kotlin/Function1<kotlin/String, kotlin/Unit>|): R|kotlin/Unit| {
|
||||||
|
}
|
||||||
|
public final fun bar(c: R|C|): R|kotlin/Unit| {
|
||||||
|
R|/foo|(R|<local>/c|::R|/C.xf1|)
|
||||||
|
}
|
||||||
+16
@@ -0,0 +1,16 @@
|
|||||||
|
interface A
|
||||||
|
interface B
|
||||||
|
|
||||||
|
fun foo(i: A) {}
|
||||||
|
fun foo(b: B) {}
|
||||||
|
|
||||||
|
fun <T> bar1(f: (T) -> Unit): T = TODO()
|
||||||
|
fun <T> bar2(f: (T) -> Unit, e: T) {}
|
||||||
|
|
||||||
|
fun test(a: A, b: B) {
|
||||||
|
val expectedType1: A = bar1(::foo)
|
||||||
|
val expectedType2: B = bar1(::foo)
|
||||||
|
|
||||||
|
bar2(::foo, a)
|
||||||
|
bar2(::foo, b)
|
||||||
|
}
|
||||||
+20
@@ -0,0 +1,20 @@
|
|||||||
|
FILE: postponedResolveOfManyCallableReference.kt
|
||||||
|
public abstract interface A : R|kotlin/Any| {
|
||||||
|
}
|
||||||
|
public abstract interface B : R|kotlin/Any| {
|
||||||
|
}
|
||||||
|
public final fun foo(i: R|A|): R|kotlin/Unit| {
|
||||||
|
}
|
||||||
|
public final fun foo(b: R|B|): R|kotlin/Unit| {
|
||||||
|
}
|
||||||
|
public final fun <T> bar1(f: R|kotlin/Function1<T, kotlin/Unit>|): R|T| {
|
||||||
|
^bar1 R|kotlin/TODO|()
|
||||||
|
}
|
||||||
|
public final fun <T> bar2(f: R|kotlin/Function1<T, kotlin/Unit>|, e: R|T|): R|kotlin/Unit| {
|
||||||
|
}
|
||||||
|
public final fun test(a: R|A|, b: R|B|): R|kotlin/Unit| {
|
||||||
|
lval expectedType1: R|A| = R|/bar1|<R|A|>(::<Unresolved reference: foo>#)
|
||||||
|
lval expectedType2: R|B| = R|/bar1|<R|B|>(::<Unresolved reference: foo>#)
|
||||||
|
R|/bar2|<R|A|>(::R|/foo|, R|<local>/a|)
|
||||||
|
R|/bar2|<R|B|>(::R|/foo|, R|<local>/b|)
|
||||||
|
}
|
||||||
+12
@@ -0,0 +1,12 @@
|
|||||||
|
interface A
|
||||||
|
interface B
|
||||||
|
|
||||||
|
fun fooB(b: B) {}
|
||||||
|
|
||||||
|
fun <T> bar(f: (T) -> Unit, e: T) {}
|
||||||
|
fun <T> baz(e: T, f: (T) -> Unit) {}
|
||||||
|
|
||||||
|
fun test(a: A, b: B) {
|
||||||
|
baz(a, ::fooB)
|
||||||
|
bar(::fooB, a)
|
||||||
|
}
|
||||||
+15
@@ -0,0 +1,15 @@
|
|||||||
|
FILE: resolveCallableReferencesAfterAllSimpleArguments.kt
|
||||||
|
public abstract interface A : R|kotlin/Any| {
|
||||||
|
}
|
||||||
|
public abstract interface B : R|kotlin/Any| {
|
||||||
|
}
|
||||||
|
public final fun fooB(b: R|B|): R|kotlin/Unit| {
|
||||||
|
}
|
||||||
|
public final fun <T> bar(f: R|kotlin/Function1<T, kotlin/Unit>|, e: R|T|): R|kotlin/Unit| {
|
||||||
|
}
|
||||||
|
public final fun <T> baz(e: R|T|, f: R|kotlin/Function1<T, kotlin/Unit>|): R|kotlin/Unit| {
|
||||||
|
}
|
||||||
|
public final fun test(a: R|A|, b: R|B|): R|kotlin/Unit| {
|
||||||
|
<Inapplicable(INAPPLICABLE): [/baz]>#(R|<local>/a|, ::fooB#)
|
||||||
|
<Inapplicable(INAPPLICABLE): [/bar]>#(::fooB#, R|<local>/a|)
|
||||||
|
}
|
||||||
+7
@@ -0,0 +1,7 @@
|
|||||||
|
fun <T, R> apply(x: T, f: (T) -> R): R = f(x)
|
||||||
|
|
||||||
|
fun foo(i: Int) {}
|
||||||
|
fun foo(s: String) {}
|
||||||
|
|
||||||
|
val x1 = apply(1, ::foo)
|
||||||
|
val x2 = apply("hello", ::foo)
|
||||||
+12
@@ -0,0 +1,12 @@
|
|||||||
|
FILE: withGenericFun.kt
|
||||||
|
public final fun <T, R> apply(x: R|T|, f: R|kotlin/Function1<T, R>|): R|R| {
|
||||||
|
^apply R|<local>/f|.R|FakeOverride<kotlin/Function1.invoke: R|R|>|(R|<local>/x|)
|
||||||
|
}
|
||||||
|
public final fun foo(i: R|kotlin/Int|): R|kotlin/Unit| {
|
||||||
|
}
|
||||||
|
public final fun foo(s: R|kotlin/String|): R|kotlin/Unit| {
|
||||||
|
}
|
||||||
|
public final val x1: R|kotlin/Unit| = R|/apply|<R|kotlin/Int|, R|kotlin/Unit|>(Int(1), ::R|/foo|)
|
||||||
|
public get(): R|kotlin/Unit|
|
||||||
|
public final val x2: R|kotlin/Unit| = R|/apply|<R|kotlin/String|, R|kotlin/Unit|>(String(hello), ::R|/foo|)
|
||||||
|
public get(): R|kotlin/Unit|
|
||||||
+10
@@ -0,0 +1,10 @@
|
|||||||
|
fun <T> foo(x: () -> T, y: Int) {}
|
||||||
|
fun <E> bar(x: E): Int = 1
|
||||||
|
|
||||||
|
fun main() {
|
||||||
|
fun bar(): Int = 1
|
||||||
|
fun foo(x: (String) -> Int, y: String) {}
|
||||||
|
|
||||||
|
foo(::bar, 1)
|
||||||
|
foo(::bar, "")
|
||||||
|
}
|
||||||
+17
@@ -0,0 +1,17 @@
|
|||||||
|
FILE: manyCandidatesInference.kt
|
||||||
|
public final fun <T> foo(x: R|kotlin/Function0<T>|, y: R|kotlin/Int|): R|kotlin/Unit| {
|
||||||
|
}
|
||||||
|
public final fun <E> bar(x: R|E|): R|kotlin/Int| {
|
||||||
|
^bar Int(1)
|
||||||
|
}
|
||||||
|
public final fun main(): R|kotlin/Unit| {
|
||||||
|
local final fun bar(): R|kotlin/Int| {
|
||||||
|
^bar Int(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
local final fun foo(x: R|kotlin/Function1<kotlin/String, kotlin/Int>|, y: R|kotlin/String|): R|kotlin/Unit| {
|
||||||
|
}
|
||||||
|
|
||||||
|
R|/foo|<R|kotlin/Int|>(::R|<local>/bar|, Int(1))
|
||||||
|
R|<local>/foo|(::R|/bar<kotlin/String>|, String())
|
||||||
|
}
|
||||||
+9
@@ -0,0 +1,9 @@
|
|||||||
|
fun foo(x: (String) -> Int) {}
|
||||||
|
|
||||||
|
|
||||||
|
fun bar(y: Any): Int = 1
|
||||||
|
fun bar(x: String): Int = 1
|
||||||
|
|
||||||
|
fun main() {
|
||||||
|
foo(::bar)
|
||||||
|
}
|
||||||
+12
@@ -0,0 +1,12 @@
|
|||||||
|
FILE: manyInnerCandidates.kt
|
||||||
|
public final fun foo(x: R|kotlin/Function1<kotlin/String, kotlin/Int>|): R|kotlin/Unit| {
|
||||||
|
}
|
||||||
|
public final fun bar(y: R|kotlin/Any|): R|kotlin/Int| {
|
||||||
|
^bar Int(1)
|
||||||
|
}
|
||||||
|
public final fun bar(x: R|kotlin/String|): R|kotlin/Int| {
|
||||||
|
^bar Int(1)
|
||||||
|
}
|
||||||
|
public final fun main(): R|kotlin/Unit| {
|
||||||
|
R|/foo|(::R|/bar|)
|
||||||
|
}
|
||||||
Vendored
+10
@@ -0,0 +1,10 @@
|
|||||||
|
fun foo(x: (String) -> Int) {}
|
||||||
|
fun foo(x: () -> Int) {}
|
||||||
|
|
||||||
|
|
||||||
|
fun bar(): Int = 1
|
||||||
|
fun bar(x: Double): Int = 1
|
||||||
|
|
||||||
|
fun main() {
|
||||||
|
foo(::bar)
|
||||||
|
}
|
||||||
Vendored
+14
@@ -0,0 +1,14 @@
|
|||||||
|
FILE: manyInnerManyOuterCandidates.kt
|
||||||
|
public final fun foo(x: R|kotlin/Function1<kotlin/String, kotlin/Int>|): R|kotlin/Unit| {
|
||||||
|
}
|
||||||
|
public final fun foo(x: R|kotlin/Function0<kotlin/Int>|): R|kotlin/Unit| {
|
||||||
|
}
|
||||||
|
public final fun bar(): R|kotlin/Int| {
|
||||||
|
^bar Int(1)
|
||||||
|
}
|
||||||
|
public final fun bar(x: R|kotlin/Double|): R|kotlin/Int| {
|
||||||
|
^bar Int(1)
|
||||||
|
}
|
||||||
|
public final fun main(): R|kotlin/Unit| {
|
||||||
|
R|/foo|(::R|/bar|)
|
||||||
|
}
|
||||||
+10
@@ -0,0 +1,10 @@
|
|||||||
|
fun foo(x: (String) -> Int) {}
|
||||||
|
fun foo(x: () -> Int) {}
|
||||||
|
|
||||||
|
|
||||||
|
fun bar(): Int = 1
|
||||||
|
fun bar(x: String): Int = 1
|
||||||
|
|
||||||
|
fun main() {
|
||||||
|
foo(::bar)
|
||||||
|
}
|
||||||
+14
@@ -0,0 +1,14 @@
|
|||||||
|
FILE: manyInnermanyOuterCandidatesAmbiguity.kt
|
||||||
|
public final fun foo(x: R|kotlin/Function1<kotlin/String, kotlin/Int>|): R|kotlin/Unit| {
|
||||||
|
}
|
||||||
|
public final fun foo(x: R|kotlin/Function0<kotlin/Int>|): R|kotlin/Unit| {
|
||||||
|
}
|
||||||
|
public final fun bar(): R|kotlin/Int| {
|
||||||
|
^bar Int(1)
|
||||||
|
}
|
||||||
|
public final fun bar(x: R|kotlin/String|): R|kotlin/Int| {
|
||||||
|
^bar Int(1)
|
||||||
|
}
|
||||||
|
public final fun main(): R|kotlin/Unit| {
|
||||||
|
<Ambiguity: foo, [/foo, /foo]>#(::bar#)
|
||||||
|
}
|
||||||
+9
@@ -0,0 +1,9 @@
|
|||||||
|
fun foo(x: (String) -> Int) {}
|
||||||
|
fun foo(x: () -> Int) {}
|
||||||
|
|
||||||
|
|
||||||
|
fun bar(): Int = 1
|
||||||
|
|
||||||
|
fun main() {
|
||||||
|
foo(::bar)
|
||||||
|
}
|
||||||
+11
@@ -0,0 +1,11 @@
|
|||||||
|
FILE: manyOuterCandidates.kt
|
||||||
|
public final fun foo(x: R|kotlin/Function1<kotlin/String, kotlin/Int>|): R|kotlin/Unit| {
|
||||||
|
}
|
||||||
|
public final fun foo(x: R|kotlin/Function0<kotlin/Int>|): R|kotlin/Unit| {
|
||||||
|
}
|
||||||
|
public final fun bar(): R|kotlin/Int| {
|
||||||
|
^bar Int(1)
|
||||||
|
}
|
||||||
|
public final fun main(): R|kotlin/Unit| {
|
||||||
|
R|/foo|(::R|/bar|)
|
||||||
|
}
|
||||||
+108
@@ -40,6 +40,11 @@ public class FirDiagnosticsTestGenerated extends AbstractFirDiagnosticsTest {
|
|||||||
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/fir/resolve/testData/diagnostics/callableReferences"), Pattern.compile("^(.+)\\.kt$"), true);
|
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/fir/resolve/testData/diagnostics/callableReferences"), Pattern.compile("^(.+)\\.kt$"), true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("differentLevels.kt")
|
||||||
|
public void testDifferentLevels() throws Exception {
|
||||||
|
runTest("compiler/fir/resolve/testData/diagnostics/callableReferences/differentLevels.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("inferenceFromCallableReferenceType.kt")
|
@TestMetadata("inferenceFromCallableReferenceType.kt")
|
||||||
public void testInferenceFromCallableReferenceType() throws Exception {
|
public void testInferenceFromCallableReferenceType() throws Exception {
|
||||||
runTest("compiler/fir/resolve/testData/diagnostics/callableReferences/inferenceFromCallableReferenceType.kt");
|
runTest("compiler/fir/resolve/testData/diagnostics/callableReferences/inferenceFromCallableReferenceType.kt");
|
||||||
@@ -50,6 +55,31 @@ public class FirDiagnosticsTestGenerated extends AbstractFirDiagnosticsTest {
|
|||||||
runTest("compiler/fir/resolve/testData/diagnostics/callableReferences/inferenceFromExpectedType.kt");
|
runTest("compiler/fir/resolve/testData/diagnostics/callableReferences/inferenceFromExpectedType.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("manyCandidatesInference.kt")
|
||||||
|
public void testManyCandidatesInference() throws Exception {
|
||||||
|
runTest("compiler/fir/resolve/testData/diagnostics/callableReferences/manyCandidatesInference.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("manyInnerCandidates.kt")
|
||||||
|
public void testManyInnerCandidates() throws Exception {
|
||||||
|
runTest("compiler/fir/resolve/testData/diagnostics/callableReferences/manyInnerCandidates.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("manyInnerManyOuterCandidates.kt")
|
||||||
|
public void testManyInnerManyOuterCandidates() throws Exception {
|
||||||
|
runTest("compiler/fir/resolve/testData/diagnostics/callableReferences/manyInnerManyOuterCandidates.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("manyInnermanyOuterCandidatesAmbiguity.kt")
|
||||||
|
public void testManyInnermanyOuterCandidatesAmbiguity() throws Exception {
|
||||||
|
runTest("compiler/fir/resolve/testData/diagnostics/callableReferences/manyInnermanyOuterCandidatesAmbiguity.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("manyOuterCandidates.kt")
|
||||||
|
public void testManyOuterCandidates() throws Exception {
|
||||||
|
runTest("compiler/fir/resolve/testData/diagnostics/callableReferences/manyOuterCandidates.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("simpleClassReceiver.kt")
|
@TestMetadata("simpleClassReceiver.kt")
|
||||||
public void testSimpleClassReceiver() throws Exception {
|
public void testSimpleClassReceiver() throws Exception {
|
||||||
runTest("compiler/fir/resolve/testData/diagnostics/callableReferences/simpleClassReceiver.kt");
|
runTest("compiler/fir/resolve/testData/diagnostics/callableReferences/simpleClassReceiver.kt");
|
||||||
@@ -64,6 +94,84 @@ public class FirDiagnosticsTestGenerated extends AbstractFirDiagnosticsTest {
|
|||||||
public void testSimpleNoReceiver() throws Exception {
|
public void testSimpleNoReceiver() throws Exception {
|
||||||
runTest("compiler/fir/resolve/testData/diagnostics/callableReferences/simpleNoReceiver.kt");
|
runTest("compiler/fir/resolve/testData/diagnostics/callableReferences/simpleNoReceiver.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("compiler/fir/resolve/testData/diagnostics/callableReferences/fromBasicDiagnosticTests")
|
||||||
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
|
@RunWith(JUnit3RunnerWithInners.class)
|
||||||
|
public static class FromBasicDiagnosticTests extends AbstractFirDiagnosticsTest {
|
||||||
|
private void runTest(String testDataFilePath) throws Exception {
|
||||||
|
KotlinTestUtils.runTest(this::doTest, this, testDataFilePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testAllFilesPresentInFromBasicDiagnosticTests() throws Exception {
|
||||||
|
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/fir/resolve/testData/diagnostics/callableReferences/fromBasicDiagnosticTests"), Pattern.compile("^(.+)\\.kt$"), true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("ambiguityWhenNoApplicableCallableReferenceCandidate.kt")
|
||||||
|
public void testAmbiguityWhenNoApplicableCallableReferenceCandidate() throws Exception {
|
||||||
|
runTest("compiler/fir/resolve/testData/diagnostics/callableReferences/fromBasicDiagnosticTests/ambiguityWhenNoApplicableCallableReferenceCandidate.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("applicableCallableReferenceFromDistantScope.kt")
|
||||||
|
public void testApplicableCallableReferenceFromDistantScope() throws Exception {
|
||||||
|
runTest("compiler/fir/resolve/testData/diagnostics/callableReferences/fromBasicDiagnosticTests/applicableCallableReferenceFromDistantScope.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("chooseCallableReferenceDependingOnInferredReceiver.kt")
|
||||||
|
public void testChooseCallableReferenceDependingOnInferredReceiver() throws Exception {
|
||||||
|
runTest("compiler/fir/resolve/testData/diagnostics/callableReferences/fromBasicDiagnosticTests/chooseCallableReferenceDependingOnInferredReceiver.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("commonSupertypeFromReturnTypesOfCallableReference.kt")
|
||||||
|
public void testCommonSupertypeFromReturnTypesOfCallableReference() throws Exception {
|
||||||
|
runTest("compiler/fir/resolve/testData/diagnostics/callableReferences/fromBasicDiagnosticTests/commonSupertypeFromReturnTypesOfCallableReference.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("eagerAndPostponedCallableReferences.kt")
|
||||||
|
public void testEagerAndPostponedCallableReferences() throws Exception {
|
||||||
|
runTest("compiler/fir/resolve/testData/diagnostics/callableReferences/fromBasicDiagnosticTests/eagerAndPostponedCallableReferences.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("eagerResolveOfSingleCallableReference.kt")
|
||||||
|
public void testEagerResolveOfSingleCallableReference() throws Exception {
|
||||||
|
runTest("compiler/fir/resolve/testData/diagnostics/callableReferences/fromBasicDiagnosticTests/eagerResolveOfSingleCallableReference.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("moreSpecificAmbiguousExtensions.kt")
|
||||||
|
public void testMoreSpecificAmbiguousExtensions() throws Exception {
|
||||||
|
runTest("compiler/fir/resolve/testData/diagnostics/callableReferences/fromBasicDiagnosticTests/moreSpecificAmbiguousExtensions.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("multipleOutersAndMultipleCallableReferences.kt")
|
||||||
|
public void testMultipleOutersAndMultipleCallableReferences() throws Exception {
|
||||||
|
runTest("compiler/fir/resolve/testData/diagnostics/callableReferences/fromBasicDiagnosticTests/multipleOutersAndMultipleCallableReferences.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("noAmbiguityBetweenTopLevelAndMemberProperty.kt")
|
||||||
|
public void testNoAmbiguityBetweenTopLevelAndMemberProperty() throws Exception {
|
||||||
|
runTest("compiler/fir/resolve/testData/diagnostics/callableReferences/fromBasicDiagnosticTests/noAmbiguityBetweenTopLevelAndMemberProperty.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("overloadsBound.kt")
|
||||||
|
public void testOverloadsBound() throws Exception {
|
||||||
|
runTest("compiler/fir/resolve/testData/diagnostics/callableReferences/fromBasicDiagnosticTests/overloadsBound.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("postponedResolveOfManyCallableReference.kt")
|
||||||
|
public void testPostponedResolveOfManyCallableReference() throws Exception {
|
||||||
|
runTest("compiler/fir/resolve/testData/diagnostics/callableReferences/fromBasicDiagnosticTests/postponedResolveOfManyCallableReference.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("resolveCallableReferencesAfterAllSimpleArguments.kt")
|
||||||
|
public void testResolveCallableReferencesAfterAllSimpleArguments() throws Exception {
|
||||||
|
runTest("compiler/fir/resolve/testData/diagnostics/callableReferences/fromBasicDiagnosticTests/resolveCallableReferencesAfterAllSimpleArguments.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("withGenericFun.kt")
|
||||||
|
public void testWithGenericFun() throws Exception {
|
||||||
|
runTest("compiler/fir/resolve/testData/diagnostics/callableReferences/fromBasicDiagnosticTests/withGenericFun.kt");
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@TestMetadata("compiler/fir/resolve/testData/diagnostics/j+k")
|
@TestMetadata("compiler/fir/resolve/testData/diagnostics/j+k")
|
||||||
|
|||||||
+7
-2
@@ -19,7 +19,10 @@ package org.jetbrains.kotlin.resolve.calls.inference
|
|||||||
import org.jetbrains.kotlin.resolve.calls.components.PostponedArgumentsAnalyzer
|
import org.jetbrains.kotlin.resolve.calls.components.PostponedArgumentsAnalyzer
|
||||||
import org.jetbrains.kotlin.resolve.calls.inference.model.ConstraintPosition
|
import org.jetbrains.kotlin.resolve.calls.inference.model.ConstraintPosition
|
||||||
import org.jetbrains.kotlin.resolve.calls.inference.model.ConstraintStorage
|
import org.jetbrains.kotlin.resolve.calls.inference.model.ConstraintStorage
|
||||||
import org.jetbrains.kotlin.resolve.calls.model.*
|
import org.jetbrains.kotlin.resolve.calls.model.CallableReferenceKotlinCallArgument
|
||||||
|
import org.jetbrains.kotlin.resolve.calls.model.KotlinCallArgument
|
||||||
|
import org.jetbrains.kotlin.resolve.calls.model.LHSResult
|
||||||
|
import org.jetbrains.kotlin.resolve.calls.model.SubKotlinCallArgument
|
||||||
import org.jetbrains.kotlin.types.model.KotlinTypeMarker
|
import org.jetbrains.kotlin.types.model.KotlinTypeMarker
|
||||||
import org.jetbrains.kotlin.types.model.TypeConstructorMarker
|
import org.jetbrains.kotlin.types.model.TypeConstructorMarker
|
||||||
import org.jetbrains.kotlin.types.model.TypeSubstitutorMarker
|
import org.jetbrains.kotlin.types.model.TypeSubstitutorMarker
|
||||||
@@ -40,6 +43,8 @@ interface ConstraintSystemOperation {
|
|||||||
fun isPostponedTypeVariable(typeVariable: TypeVariableMarker): Boolean
|
fun isPostponedTypeVariable(typeVariable: TypeVariableMarker): Boolean
|
||||||
|
|
||||||
fun getProperSuperTypeConstructors(type: KotlinTypeMarker): List<TypeConstructorMarker>
|
fun getProperSuperTypeConstructors(type: KotlinTypeMarker): List<TypeConstructorMarker>
|
||||||
|
|
||||||
|
fun addOtherSystem(otherSystem: ConstraintStorage)
|
||||||
}
|
}
|
||||||
|
|
||||||
interface ConstraintSystemBuilder : ConstraintSystemOperation {
|
interface ConstraintSystemBuilder : ConstraintSystemOperation {
|
||||||
@@ -70,4 +75,4 @@ fun PostponedArgumentsAnalyzer.Context.addSubsystemFromArgument(argument: Kotlin
|
|||||||
addSubsystemFromArgument(argument.lhsResult.safeAs<LHSResult.Expression>()?.lshCallArgument)
|
addSubsystemFromArgument(argument.lhsResult.safeAs<LHSResult.Expression>()?.lshCallArgument)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user