Add compatibility warning for SAM conversions on Kotlin functions
This commit is contained in:
+14
@@ -11,6 +11,7 @@ import org.jetbrains.kotlin.config.LanguageFeature
|
||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.ParameterDescriptor
|
||||
import org.jetbrains.kotlin.incremental.record
|
||||
import org.jetbrains.kotlin.resolve.calls.inference.model.LowerPriorityToPreserveCompatibility
|
||||
import org.jetbrains.kotlin.resolve.calls.model.*
|
||||
import org.jetbrains.kotlin.resolve.sam.SAM_LOOKUP_NAME
|
||||
import org.jetbrains.kotlin.resolve.sam.getFunctionTypeForPossibleSamType
|
||||
@@ -86,6 +87,10 @@ object SamTypeConversions : ParameterTypeConversion {
|
||||
SamConversionDescription(convertedTypeByOriginal, convertedTypeByCandidate!!)
|
||||
)
|
||||
|
||||
if (needCompatibilityResolve(candidate, expectedParameterType)) {
|
||||
candidate.addDiagnostic(LowerPriorityToPreserveCompatibility)
|
||||
}
|
||||
|
||||
val samDescriptor = originalExpectedType.constructor.declarationDescriptor
|
||||
if (samDescriptor is ClassDescriptor) {
|
||||
callComponents.lookupTracker.record(candidate.scopeTower.location, samDescriptor, SAM_LOOKUP_NAME)
|
||||
@@ -93,4 +98,13 @@ object SamTypeConversions : ParameterTypeConversion {
|
||||
|
||||
return convertedTypeByCandidate
|
||||
}
|
||||
|
||||
private fun needCompatibilityResolve(candidate: KotlinResolutionCandidate, typeToConvert: UnwrappedType): Boolean {
|
||||
// fun interfaces is a new feature with a new modifier, so no compatibility resolve is needed
|
||||
val descriptor = typeToConvert.constructor.declarationDescriptor
|
||||
if (descriptor is ClassDescriptor && descriptor.isFun) return false
|
||||
|
||||
// now conversions for Kotlin candidates are possible, so we have to perform compatibility resolve
|
||||
return !candidate.callComponents.samConversionOracle.isJavaApplicableCandidate(candidate.resolvedCall.candidateDescriptor)
|
||||
}
|
||||
}
|
||||
|
||||
+3
-2
@@ -19,8 +19,7 @@ package org.jetbrains.kotlin.resolve.calls.inference.model
|
||||
import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor
|
||||
import org.jetbrains.kotlin.resolve.calls.model.*
|
||||
import org.jetbrains.kotlin.resolve.calls.tower.ResolutionCandidateApplicability
|
||||
import org.jetbrains.kotlin.resolve.calls.tower.ResolutionCandidateApplicability.INAPPLICABLE
|
||||
import org.jetbrains.kotlin.resolve.calls.tower.ResolutionCandidateApplicability.INAPPLICABLE_WRONG_RECEIVER
|
||||
import org.jetbrains.kotlin.resolve.calls.tower.ResolutionCandidateApplicability.*
|
||||
import org.jetbrains.kotlin.resolve.scopes.receivers.DetailedReceiver
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
import org.jetbrains.kotlin.types.model.KotlinTypeMarker
|
||||
@@ -123,3 +122,5 @@ class ConstrainingTypeIsError(
|
||||
val constraintType: KotlinTypeMarker,
|
||||
val position: IncorporationConstraintPosition
|
||||
) : ConstraintSystemCallDiagnostic(INAPPLICABLE)
|
||||
|
||||
object LowerPriorityToPreserveCompatibility : ConstraintSystemCallDiagnostic(RESOLVED_NEED_PRESERVE_COMPATIBILITY)
|
||||
|
||||
@@ -86,6 +86,7 @@ fun getResultApplicability(diagnostics: Collection<KotlinCallDiagnostic>) =
|
||||
enum class ResolutionCandidateApplicability {
|
||||
RESOLVED, // call success or has uncompleted inference or in other words possible successful candidate
|
||||
RESOLVED_WITH_ERROR, // call has error, but it is still successful from resolution perspective
|
||||
RESOLVED_NEED_PRESERVE_COMPATIBILITY, // call resolved successfully, but using new features that changes resolve
|
||||
RESOLVED_LOW_PRIORITY,
|
||||
CONVENTION_ERROR, // missing infix, operator etc
|
||||
MAY_THROW_RUNTIME_ERROR, // unsafe call or unstable smart cast
|
||||
@@ -120,6 +121,7 @@ class UsedSmartCastForDispatchReceiver(val smartCastType: KotlinType) : Resoluti
|
||||
object ErrorDescriptorDiagnostic : ResolutionDiagnostic(RESOLVED) // todo discuss and change to INAPPLICABLE
|
||||
object LowPriorityDescriptorDiagnostic : ResolutionDiagnostic(RESOLVED_LOW_PRIORITY)
|
||||
object DynamicDescriptorDiagnostic : ResolutionDiagnostic(RESOLVED_LOW_PRIORITY)
|
||||
object ResolvedUsingNewFeatures : ResolutionDiagnostic(RESOLVED_NEED_PRESERVE_COMPATIBILITY)
|
||||
object UnstableSmartCastDiagnostic : ResolutionDiagnostic(RESOLVED_WITH_ERROR)
|
||||
object HiddenExtensionRelatedToDynamicTypes : ResolutionDiagnostic(HIDDEN)
|
||||
object HiddenDescriptor : ResolutionDiagnostic(HIDDEN)
|
||||
|
||||
Reference in New Issue
Block a user