CandidateApplicability: add K1/K2 prefixes when applicable

This commit is contained in:
Mikhail Glukhikh
2022-07-19 14:42:13 +02:00
committed by Space
parent 8e9e8302f7
commit 0611f3b8e7
10 changed files with 39 additions and 37 deletions
@@ -408,7 +408,7 @@ class FirCallResolver(
noSuccessfulCandidates -> { noSuccessfulCandidates -> {
val errorReference = buildErrorReference( val errorReference = buildErrorReference(
info, info,
if (applicability == CandidateApplicability.UNSUPPORTED) { if (applicability == CandidateApplicability.K2_UNSUPPORTED) {
val unsupportedResolutionDiagnostic = reducedCandidates.firstOrNull()?.diagnostics?.firstOrNull() as? Unsupported val unsupportedResolutionDiagnostic = reducedCandidates.firstOrNull()?.diagnostics?.firstOrNull() as? Unsupported
ConeUnsupported(unsupportedResolutionDiagnostic?.message ?: "", unsupportedResolutionDiagnostic?.source) ConeUnsupported(unsupportedResolutionDiagnostic?.message ?: "", unsupportedResolutionDiagnostic?.source)
} else { } else {
@@ -571,9 +571,9 @@ fun createConeDiagnosticForCandidateWithError(
): ConeDiagnostic { ): ConeDiagnostic {
return when (applicability) { return when (applicability) {
CandidateApplicability.HIDDEN -> ConeHiddenCandidateError(candidate) CandidateApplicability.HIDDEN -> ConeHiddenCandidateError(candidate)
CandidateApplicability.VISIBILITY_ERROR -> ConeVisibilityError(candidate.symbol) CandidateApplicability.K2_VISIBILITY_ERROR -> ConeVisibilityError(candidate.symbol)
CandidateApplicability.INAPPLICABLE_WRONG_RECEIVER -> ConeInapplicableWrongReceiver(listOf(candidate)) CandidateApplicability.INAPPLICABLE_WRONG_RECEIVER -> ConeInapplicableWrongReceiver(listOf(candidate))
CandidateApplicability.NO_COMPANION_OBJECT -> ConeNoCompanionObject(candidate) CandidateApplicability.K2_NO_COMPANION_OBJECT -> ConeNoCompanionObject(candidate)
else -> ConeInapplicableCandidateError(applicability, candidate) else -> ConeInapplicableCandidateError(applicability, candidate)
} }
} }
@@ -8,7 +8,7 @@ package org.jetbrains.kotlin.fir.resolve.calls
import org.jetbrains.kotlin.fir.resolve.BodyResolveComponents import org.jetbrains.kotlin.fir.resolve.BodyResolveComponents
import org.jetbrains.kotlin.fir.resolve.calls.tower.TowerGroup import org.jetbrains.kotlin.fir.resolve.calls.tower.TowerGroup
import org.jetbrains.kotlin.resolve.calls.tower.CandidateApplicability import org.jetbrains.kotlin.resolve.calls.tower.CandidateApplicability
import org.jetbrains.kotlin.resolve.calls.tower.CandidateApplicability.DSL_SCOPE_VIOLATION import org.jetbrains.kotlin.resolve.calls.tower.CandidateApplicability.K2_DSL_SCOPE_VIOLATION
import org.jetbrains.kotlin.resolve.calls.tower.CandidateApplicability.K2_SYNTHETIC_RESOLVED import org.jetbrains.kotlin.resolve.calls.tower.CandidateApplicability.K2_SYNTHETIC_RESOLVED
import org.jetbrains.kotlin.resolve.calls.tower.isSuccess import org.jetbrains.kotlin.resolve.calls.tower.isSuccess
@@ -53,7 +53,7 @@ open class CandidateCollector(
shouldStopResolve && bestGroup < group shouldStopResolve && bestGroup < group
private val shouldStopResolve: Boolean private val shouldStopResolve: Boolean
get() = currentApplicability == DSL_SCOPE_VIOLATION || currentApplicability >= K2_SYNTHETIC_RESOLVED get() = currentApplicability == K2_DSL_SCOPE_VIOLATION || currentApplicability >= K2_SYNTHETIC_RESOLVED
val isSuccess: Boolean val isSuccess: Boolean
get() = currentApplicability.isSuccess get() = currentApplicability.isSuccess
@@ -123,7 +123,7 @@ class FirTypeResolverImpl(private val session: FirSession) : FirTypeResolver() {
var diagnostic: ConeDiagnostic? = null var diagnostic: ConeDiagnostic? = null
if (!symbol.isVisible(useSiteFile, containingDeclarations, supertypeSupplier)) { if (!symbol.isVisible(useSiteFile, containingDeclarations, supertypeSupplier)) {
symbolApplicability = minOf(CandidateApplicability.VISIBILITY_ERROR, symbolApplicability) symbolApplicability = minOf(CandidateApplicability.K2_VISIBILITY_ERROR, symbolApplicability)
diagnostic = ConeVisibilityError(symbol) diagnostic = ConeVisibilityError(symbol)
} }
@@ -80,7 +80,7 @@ object InapplicableCandidate : ResolutionDiagnostic(INAPPLICABLE)
object HiddenCandidate : ResolutionDiagnostic(HIDDEN) object HiddenCandidate : ResolutionDiagnostic(HIDDEN)
object VisibilityError : ResolutionDiagnostic(VISIBILITY_ERROR) object VisibilityError : ResolutionDiagnostic(K2_VISIBILITY_ERROR)
object ResolvedWithLowPriority : ResolutionDiagnostic(RESOLVED_LOW_PRIORITY) object ResolvedWithLowPriority : ResolutionDiagnostic(RESOLVED_LOW_PRIORITY)
@@ -91,7 +91,7 @@ class InapplicableWrongReceiver(
val actualType: ConeKotlinType? = null, val actualType: ConeKotlinType? = null,
) : ResolutionDiagnostic(INAPPLICABLE_WRONG_RECEIVER) ) : ResolutionDiagnostic(INAPPLICABLE_WRONG_RECEIVER)
object NoCompanionObject : ResolutionDiagnostic(NO_COMPANION_OBJECT) object NoCompanionObject : ResolutionDiagnostic(K2_NO_COMPANION_OBJECT)
class UnsafeCall(val actualType: ConeKotlinType) : ResolutionDiagnostic(UNSAFE_CALL) class UnsafeCall(val actualType: ConeKotlinType) : ResolutionDiagnostic(UNSAFE_CALL)
@@ -123,11 +123,11 @@ class InfixCallOfNonInfixFunction(val function: FirNamedFunctionSymbol) : Resolu
class OperatorCallOfNonOperatorFunction(val function: FirNamedFunctionSymbol) : ResolutionDiagnostic(CONVENTION_ERROR) class OperatorCallOfNonOperatorFunction(val function: FirNamedFunctionSymbol) : ResolutionDiagnostic(CONVENTION_ERROR)
class InferenceError(val constraintError: ConstraintSystemError) : ResolutionDiagnostic(constraintError.applicability) class InferenceError(val constraintError: ConstraintSystemError) : ResolutionDiagnostic(constraintError.applicability)
class Unsupported(val message: String, val source: KtSourceElement? = null) : ResolutionDiagnostic(UNSUPPORTED) class Unsupported(val message: String, val source: KtSourceElement? = null) : ResolutionDiagnostic(K2_UNSUPPORTED)
object PropertyAsOperator : ResolutionDiagnostic(K2_PROPERTY_AS_OPERATOR) object PropertyAsOperator : ResolutionDiagnostic(K2_PROPERTY_AS_OPERATOR)
class DslScopeViolation(val calleeSymbol: FirBasedSymbol<*>) : ResolutionDiagnostic(DSL_SCOPE_VIOLATION) class DslScopeViolation(val calleeSymbol: FirBasedSymbol<*>) : ResolutionDiagnostic(K2_DSL_SCOPE_VIOLATION)
class MultipleContextReceiversApplicableForExtensionReceivers : ResolutionDiagnostic(INAPPLICABLE) class MultipleContextReceiversApplicableForExtensionReceivers : ResolutionDiagnostic(INAPPLICABLE)
@@ -124,7 +124,7 @@ fun ResolvedCall<*>.hasInferredReturnType(): Boolean {
fun CandidateApplicability.toResolutionStatus(): ResolutionStatus = when (this) { fun CandidateApplicability.toResolutionStatus(): ResolutionStatus = when (this) {
CandidateApplicability.RESOLVED, CandidateApplicability.RESOLVED,
CandidateApplicability.RESOLVED_LOW_PRIORITY, CandidateApplicability.RESOLVED_LOW_PRIORITY,
CandidateApplicability.RESOLVED_WITH_ERROR, CandidateApplicability.K1_RESOLVED_WITH_ERROR,
CandidateApplicability.RESOLVED_NEED_PRESERVE_COMPATIBILITY -> ResolutionStatus.SUCCESS CandidateApplicability.RESOLVED_NEED_PRESERVE_COMPATIBILITY -> ResolutionStatus.SUCCESS
CandidateApplicability.INAPPLICABLE_WRONG_RECEIVER -> ResolutionStatus.RECEIVER_TYPE_ERROR CandidateApplicability.INAPPLICABLE_WRONG_RECEIVER -> ResolutionStatus.RECEIVER_TYPE_ERROR
CandidateApplicability.UNSAFE_CALL -> ResolutionStatus.UNSAFE_CALL_ERROR CandidateApplicability.UNSAFE_CALL -> ResolutionStatus.UNSAFE_CALL_ERROR
@@ -6,29 +6,31 @@
package org.jetbrains.kotlin.resolve.calls.tower package org.jetbrains.kotlin.resolve.calls.tower
enum class CandidateApplicability { enum class CandidateApplicability {
RESOLVED_TO_SAM_WITH_VARARG, // migration warning up to 1.5 (when resolve to function with SAM conversion and array without spread as vararg) K1_RESOLVED_TO_SAM_WITH_VARARG, // migration warning up to 1.5 (when resolve to function with SAM conversion and array without spread as vararg)
HIDDEN, // removed from resolve HIDDEN, // removed from resolve (should get UNRESOLVED_REFERENCE, used for HIDDEN deprecations and similar things)
VISIBILITY_ERROR, // problems with visibility K2_VISIBILITY_ERROR, // problems with visibility (should get INVISIBLE_REFERENCE)
UNSUPPORTED, // unsupported feature K2_UNSUPPORTED, // unsupported feature
INAPPLICABLE_WRONG_RECEIVER, // receiver not matched INAPPLICABLE_WRONG_RECEIVER, // receiver not matched
INAPPLICABLE_ARGUMENTS_MAPPING_ERROR, // arguments not mapped to parameters (i.e. different size of arguments and parameters) INAPPLICABLE_ARGUMENTS_MAPPING_ERROR, // arguments not mapped to parameters (i.e. different size of arguments and parameters)
INAPPLICABLE, // arguments have wrong types INAPPLICABLE, // arguments have wrong types
NO_COMPANION_OBJECT, // Classifier does not have a companion object K2_NO_COMPANION_OBJECT, // Classifier does not have a companion object
IMPOSSIBLE_TO_GENERATE, // access to outer class from nested K1_IMPOSSIBLE_TO_GENERATE, // access to outer class from nested
RUNTIME_ERROR, // TODO: FE 1.0 uses this as catch-all for all other errors. Consider re-assigning those diagnostics. K1_RUNTIME_ERROR, // TODO: FE 1.0 uses this as catch-all for all other errors. Consider re-assigning those diagnostics.
UNSAFE_CALL, // receiver or argument nullability doesn't match UNSAFE_CALL, // receiver or argument nullability doesn't match
UNSTABLE_SMARTCAST, // unstable smart cast UNSTABLE_SMARTCAST, // unstable smart cast
CONVENTION_ERROR, // missing infix, operator etc (= no expected modifier) CONVENTION_ERROR, // missing infix, operator etc (= no expected modifier)
// Below has shouldStopResolve = true K2_DSL_SCOPE_VIOLATION, // Skip other levels for DSL_SCOPE_VIOLATION because if the candidate is marked DSL_SCOPE_VIOLATION with an inner receiver, one should not keep going to outer receivers.
DSL_SCOPE_VIOLATION, // Skip other levels for DSL_SCOPE_VIOLATION because if the candidate is marked DSL_SCOPE_VIOLATION with an inner receiver, one should not keep going to outer receivers.
// Below has isSuccess = true // Below has isSuccess = true
RESOLVED_LOW_PRIORITY, RESOLVED_LOW_PRIORITY,
K2_PROPERTY_AS_OPERATOR, // using property of functional type as an operator. From resolution perspective, this is considered successful. K2_PROPERTY_AS_OPERATOR, // using property of functional type as an operator. From resolution perspective, this is considered successful.
RESOLVED_NEED_PRESERVE_COMPATIBILITY, // call resolved successfully, but using new features that changes resolve RESOLVED_NEED_PRESERVE_COMPATIBILITY, // call resolved successfully, but using new features that changes resolve
// Tower resolve does not go to further scopes if candidate with applicability below is found
K2_SYNTHETIC_RESOLVED, // used in K2 for (Java) synthetic discrimination at the same level K2_SYNTHETIC_RESOLVED, // used in K2 for (Java) synthetic discrimination at the same level
RESOLVED_WITH_ERROR, // call has error, but it is still successful from resolution perspective K1_RESOLVED_WITH_ERROR, // call has error, but it is still successful from resolution perspective
RESOLVED, // call success or has uncompleted inference or in other words possible successful candidate RESOLVED, // call success or has uncompleted inference or in other words possible successful candidate
} }
@@ -157,7 +157,7 @@ class NotCallableExpectedType(
) : CallableReferenceInapplicableDiagnostic(argument) ) : CallableReferenceInapplicableDiagnostic(argument)
class AdaptedCallableReferenceIsUsedWithReflection(val argument: CallableReferenceResolutionAtom) : class AdaptedCallableReferenceIsUsedWithReflection(val argument: CallableReferenceResolutionAtom) :
CallableReferenceInapplicableDiagnostic(argument, RESOLVED_WITH_ERROR) CallableReferenceInapplicableDiagnostic(argument, K1_RESOLVED_WITH_ERROR)
// SmartCasts // SmartCasts
class SmartCastDiagnostic( class SmartCastDiagnostic(
@@ -194,7 +194,7 @@ class UnstableSmartCastResolutionError(
class UnstableSmartCastDiagnosticError( class UnstableSmartCastDiagnosticError(
argument: ExpressionKotlinCallArgument, argument: ExpressionKotlinCallArgument,
targetType: UnwrappedType, targetType: UnwrappedType,
) : UnstableSmartCast(argument, targetType, RESOLVED_WITH_ERROR) ) : UnstableSmartCast(argument, targetType, K1_RESOLVED_WITH_ERROR)
class UnsafeCallError( class UnsafeCallError(
val receiver: SimpleKotlinCallArgument, val receiver: SimpleKotlinCallArgument,
@@ -204,23 +204,23 @@ class UnsafeCallError(
} }
// Other // Other
object InstantiationOfAbstractClass : KotlinCallDiagnostic(RUNTIME_ERROR) { object InstantiationOfAbstractClass : KotlinCallDiagnostic(K1_RUNTIME_ERROR) {
override fun report(reporter: DiagnosticReporter) = reporter.onCall(this) override fun report(reporter: DiagnosticReporter) = reporter.onCall(this)
} }
class AbstractSuperCall(val receiver: SimpleKotlinCallArgument) : KotlinCallDiagnostic(RUNTIME_ERROR) { class AbstractSuperCall(val receiver: SimpleKotlinCallArgument) : KotlinCallDiagnostic(K1_RUNTIME_ERROR) {
override fun report(reporter: DiagnosticReporter) { override fun report(reporter: DiagnosticReporter) {
reporter.onCall(this) reporter.onCall(this)
} }
} }
object AbstractFakeOverrideSuperCall : KotlinCallDiagnostic(RUNTIME_ERROR) { object AbstractFakeOverrideSuperCall : KotlinCallDiagnostic(K1_RUNTIME_ERROR) {
override fun report(reporter: DiagnosticReporter) { override fun report(reporter: DiagnosticReporter) {
reporter.onCall(this) reporter.onCall(this)
} }
} }
class SuperAsExtensionReceiver(val receiver: SimpleKotlinCallArgument) : KotlinCallDiagnostic(RUNTIME_ERROR) { class SuperAsExtensionReceiver(val receiver: SimpleKotlinCallArgument) : KotlinCallDiagnostic(K1_RUNTIME_ERROR) {
override fun report(reporter: DiagnosticReporter) { override fun report(reporter: DiagnosticReporter) {
reporter.onCallReceiver(receiver, this) reporter.onCallReceiver(receiver, this)
} }
@@ -273,7 +273,7 @@ class ArgumentNullabilityWarningDiagnostic(
} }
} }
class ResolvedToSamWithVarargDiagnostic(val argument: KotlinCallArgument) : KotlinCallDiagnostic(RESOLVED_TO_SAM_WITH_VARARG) { class ResolvedToSamWithVarargDiagnostic(val argument: KotlinCallArgument) : KotlinCallDiagnostic(K1_RESOLVED_TO_SAM_WITH_VARARG) {
override fun report(reporter: DiagnosticReporter) { override fun report(reporter: DiagnosticReporter) {
reporter.onCallArgument(argument, this) reporter.onCallArgument(argument, this)
} }
@@ -282,7 +282,7 @@ class ResolvedToSamWithVarargDiagnostic(val argument: KotlinCallArgument) : Kotl
class NotEnoughInformationForLambdaParameter( class NotEnoughInformationForLambdaParameter(
val lambdaArgument: LambdaKotlinCallArgument, val lambdaArgument: LambdaKotlinCallArgument,
val parameterIndex: Int val parameterIndex: Int
) : KotlinCallDiagnostic(RESOLVED_WITH_ERROR) { ) : KotlinCallDiagnostic(K1_RESOLVED_WITH_ERROR) {
override fun report(reporter: DiagnosticReporter) { override fun report(reporter: DiagnosticReporter) {
reporter.onCallArgument(lambdaArgument, this) reporter.onCallArgument(lambdaArgument, this)
} }
@@ -114,20 +114,20 @@ abstract class ResolutionDiagnostic(candidateApplicability: CandidateApplicabili
} }
} }
class ContextReceiverAmbiguity : ResolutionDiagnostic(RESOLVED_WITH_ERROR) { class ContextReceiverAmbiguity : ResolutionDiagnostic(K1_RESOLVED_WITH_ERROR) {
override fun report(reporter: DiagnosticReporter) { override fun report(reporter: DiagnosticReporter) {
reporter.onCall(this) reporter.onCall(this)
} }
} }
class UnsupportedContextualDeclarationCall : ResolutionDiagnostic(RESOLVED_WITH_ERROR) { class UnsupportedContextualDeclarationCall : ResolutionDiagnostic(K1_RESOLVED_WITH_ERROR) {
override fun report(reporter: DiagnosticReporter) { override fun report(reporter: DiagnosticReporter) {
reporter.onCall(this) reporter.onCall(this)
} }
} }
// todo error for this access from nested class // todo error for this access from nested class
class VisibilityError(val invisibleMember: DeclarationDescriptorWithVisibility) : ResolutionDiagnostic(RUNTIME_ERROR) { class VisibilityError(val invisibleMember: DeclarationDescriptorWithVisibility) : ResolutionDiagnostic(K1_RUNTIME_ERROR) {
override fun report(reporter: DiagnosticReporter) { override fun report(reporter: DiagnosticReporter) {
reporter.onCall(this) reporter.onCall(this)
} }
@@ -136,15 +136,15 @@ class VisibilityError(val invisibleMember: DeclarationDescriptorWithVisibility)
class VisibilityErrorOnArgument( class VisibilityErrorOnArgument(
val argument: KotlinCallArgument, val argument: KotlinCallArgument,
val invisibleMember: DeclarationDescriptorWithVisibility val invisibleMember: DeclarationDescriptorWithVisibility
) : ResolutionDiagnostic(RUNTIME_ERROR) { ) : ResolutionDiagnostic(K1_RUNTIME_ERROR) {
override fun report(reporter: DiagnosticReporter) { override fun report(reporter: DiagnosticReporter) {
reporter.onCallArgument(argument, this) reporter.onCallArgument(argument, this)
} }
} }
class NestedClassViaInstanceReference(val classDescriptor: ClassDescriptor) : ResolutionDiagnostic(IMPOSSIBLE_TO_GENERATE) class NestedClassViaInstanceReference(val classDescriptor: ClassDescriptor) : ResolutionDiagnostic(K1_IMPOSSIBLE_TO_GENERATE)
class InnerClassViaStaticReference(val classDescriptor: ClassDescriptor) : ResolutionDiagnostic(IMPOSSIBLE_TO_GENERATE) class InnerClassViaStaticReference(val classDescriptor: ClassDescriptor) : ResolutionDiagnostic(K1_IMPOSSIBLE_TO_GENERATE)
class UnsupportedInnerClassCall(val message: String) : ResolutionDiagnostic(IMPOSSIBLE_TO_GENERATE) class UnsupportedInnerClassCall(val message: String) : ResolutionDiagnostic(K1_IMPOSSIBLE_TO_GENERATE)
class UsedSmartCastForDispatchReceiver(val smartCastType: KotlinType) : ResolutionDiagnostic(RESOLVED) class UsedSmartCastForDispatchReceiver(val smartCastType: KotlinType) : ResolutionDiagnostic(RESOLVED)
object ErrorDescriptorDiagnostic : ResolutionDiagnostic(RESOLVED) // todo discuss and change to INAPPLICABLE object ErrorDescriptorDiagnostic : ResolutionDiagnostic(RESOLVED) // todo discuss and change to INAPPLICABLE
@@ -457,7 +457,7 @@ class TowerResolver {
private fun isSuccessfulCandidate(candidate: C): Boolean { private fun isSuccessfulCandidate(candidate: C): Boolean {
return candidate.resultingApplicability == CandidateApplicability.RESOLVED return candidate.resultingApplicability == CandidateApplicability.RESOLVED
|| candidate.resultingApplicability == CandidateApplicability.RESOLVED_WITH_ERROR || candidate.resultingApplicability == CandidateApplicability.K1_RESOLVED_WITH_ERROR
} }
private fun isSuccessfulPreserveCompatibility(candidate: C): Boolean = private fun isSuccessfulPreserveCompatibility(candidate: C): Boolean =