Prohibit adapted reference resolve against reflective types
There are design questions about reflection for adapted references, so the current proposal is to prohibit reflection on them and support it properly later #KT-40406 Fixed
This commit is contained in:
+16
-2
@@ -228,6 +228,12 @@ class CallableReferencesCandidateFactory(
|
||||
markCandidateForCompatibilityResolve(diagnostics)
|
||||
}
|
||||
|
||||
if (callableReferenceAdaptation != null && expectedType != null && hasNonTrivialAdaptation(callableReferenceAdaptation)) {
|
||||
if (!expectedType.isFunctionType && !expectedType.isSuspendFunctionType) { // expectedType has some reflection type
|
||||
diagnostics.add(AdaptedCallableReferenceIsUsedWithReflection(argument))
|
||||
}
|
||||
}
|
||||
|
||||
if (callableReferenceAdaptation != null &&
|
||||
callableReferenceAdaptation.defaults != 0 &&
|
||||
!callComponents.languageVersionSettings.supportsFeature(LanguageFeature.FunctionReferenceWithDefaultValueAsOtherType)
|
||||
@@ -278,11 +284,14 @@ class CallableReferencesCandidateFactory(
|
||||
|
||||
if (callableReferenceAdaptation == null) return false
|
||||
|
||||
return callableReferenceAdaptation.defaults != 0 ||
|
||||
return hasNonTrivialAdaptation(callableReferenceAdaptation)
|
||||
}
|
||||
|
||||
private fun hasNonTrivialAdaptation(callableReferenceAdaptation: CallableReferenceAdaptation) =
|
||||
callableReferenceAdaptation.defaults != 0 ||
|
||||
callableReferenceAdaptation.suspendConversionStrategy != SuspendConversionStrategy.NO_CONVERSION ||
|
||||
callableReferenceAdaptation.coercionStrategy != CoercionStrategy.NO_COERCION ||
|
||||
callableReferenceAdaptation.mappedArguments.values.any { it is ResolvedCallArgument.VarargArgument }
|
||||
}
|
||||
|
||||
private enum class VarargMappingState {
|
||||
UNMAPPED, MAPPED_WITH_PLAIN_ARGS, MAPPED_WITH_ARRAY
|
||||
@@ -296,6 +305,11 @@ class CallableReferencesCandidateFactory(
|
||||
): CallableReferenceAdaptation? {
|
||||
if (callComponents.languageVersionSettings.apiVersion < ApiVersion.KOTLIN_1_4) return null
|
||||
|
||||
if (expectedType == null) return null
|
||||
|
||||
// Do not adapt references against KCallable type as it's impossible to map defaults/vararg to absent parameters of KCallable
|
||||
if (ReflectionTypes.hasKCallableTypeFqName(expectedType)) return null
|
||||
|
||||
val inputOutputTypes = extractInputOutputTypesFromCallableReferenceExpectedType(expectedType) ?: return null
|
||||
|
||||
val expectedArgumentCount = inputOutputTypes.inputTypes.size - unboundReceiverCount
|
||||
|
||||
+9
@@ -263,4 +263,13 @@ class CompatibilityWarningOnArgument(
|
||||
override fun report(reporter: DiagnosticReporter) {
|
||||
reporter.onCallArgument(argument, this)
|
||||
}
|
||||
}
|
||||
|
||||
class AdaptedCallableReferenceIsUsedWithReflection(
|
||||
val argument: CallableReferenceKotlinCallArgument,
|
||||
) : KotlinCallDiagnostic(RESOLVED_WITH_ERROR) {
|
||||
override fun report(reporter: DiagnosticReporter) {
|
||||
reporter.onCallArgument(argument, this)
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user