[NI] Support assigning single array elements in named form to varargs
This commit is contained in:
+4
-2
@@ -16,6 +16,7 @@
|
||||
|
||||
package org.jetbrains.kotlin.resolve.calls.components
|
||||
|
||||
import org.jetbrains.kotlin.config.LanguageVersionSettings
|
||||
import org.jetbrains.kotlin.descriptors.CallableDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.ReceiverParameterDescriptor
|
||||
import org.jetbrains.kotlin.resolve.calls.model.*
|
||||
@@ -25,7 +26,7 @@ import org.jetbrains.kotlin.types.checker.KotlinTypeChecker
|
||||
// very initial state of component
|
||||
// todo: handle all diagnostic inside DiagnosticReporterByTrackingStrategy
|
||||
// move it to frontend module
|
||||
class AdditionalDiagnosticReporter {
|
||||
class AdditionalDiagnosticReporter(private val languageVersionSettings: LanguageVersionSettings) {
|
||||
|
||||
fun reportAdditionalDiagnostics(
|
||||
candidate: ResolvedCallAtom,
|
||||
@@ -79,7 +80,8 @@ class AdditionalDiagnosticReporter {
|
||||
|
||||
for (parameter in resultingDescriptor.valueParameters) {
|
||||
for (argument in candidate.argumentMappingByOriginal[parameter.original]?.arguments ?: continue) {
|
||||
val smartCastDiagnostic = createSmartCastDiagnostic(candidate, argument, argument.getExpectedType(parameter)) ?: continue
|
||||
val effectiveExpectedType = argument.getExpectedType(parameter, languageVersionSettings)
|
||||
val smartCastDiagnostic = createSmartCastDiagnostic(candidate, argument, effectiveExpectedType) ?: continue
|
||||
|
||||
val thereIsUnstableSmartCastError = candidate.diagnostics.filterIsInstance<UnstableSmartCast>().any {
|
||||
it.argument == argument
|
||||
|
||||
+28
-2
@@ -16,9 +16,15 @@
|
||||
|
||||
package org.jetbrains.kotlin.resolve.calls.components
|
||||
|
||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
||||
import org.jetbrains.kotlin.config.LanguageFeature
|
||||
import org.jetbrains.kotlin.config.LanguageVersionSettings
|
||||
import org.jetbrains.kotlin.descriptors.ParameterDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor
|
||||
import org.jetbrains.kotlin.resolve.calls.model.CollectionLiteralKotlinCallArgument
|
||||
import org.jetbrains.kotlin.resolve.calls.model.KotlinCallArgument
|
||||
import org.jetbrains.kotlin.resolve.calls.model.SimpleKotlinCallArgument
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.isParameterOfAnnotation
|
||||
import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValueWithSmartCastInfo
|
||||
import org.jetbrains.kotlin.types.UnwrappedType
|
||||
import org.jetbrains.kotlin.types.checker.intersectWrappedTypes
|
||||
@@ -42,8 +48,8 @@ internal val ReceiverValueWithSmartCastInfo.stableType: UnwrappedType
|
||||
return intersectWrappedTypes(possibleTypes + receiverValue.type)
|
||||
}
|
||||
|
||||
internal fun KotlinCallArgument.getExpectedType(parameter: ParameterDescriptor) =
|
||||
if (this.isSpread) {
|
||||
internal fun KotlinCallArgument.getExpectedType(parameter: ParameterDescriptor, languageVersionSettings: LanguageVersionSettings) =
|
||||
if (this.isSpread || this.isArrayAssignedAsNamedArgumentInAnnotation(parameter, languageVersionSettings)) {
|
||||
parameter.type.unwrap()
|
||||
}
|
||||
else {
|
||||
@@ -51,3 +57,23 @@ internal fun KotlinCallArgument.getExpectedType(parameter: ParameterDescriptor)
|
||||
}
|
||||
|
||||
val ValueParameterDescriptor.isVararg: Boolean get() = varargElementType != null
|
||||
val ParameterDescriptor.isVararg: Boolean get() = this.safeAs<ValueParameterDescriptor>()?.isVararg ?: false
|
||||
|
||||
private fun KotlinCallArgument.isArrayAssignedAsNamedArgumentInAnnotation(
|
||||
parameter: ParameterDescriptor,
|
||||
languageVersionSettings: LanguageVersionSettings
|
||||
): Boolean {
|
||||
if (!languageVersionSettings.supportsFeature(LanguageFeature.AssigningArraysToVarargsInNamedFormInAnnotations)) return false
|
||||
|
||||
if (this.argumentName == null || !parameter.isVararg) return false
|
||||
|
||||
return isParameterOfAnnotation(parameter) && this.isArrayOrArrayLiteral()
|
||||
}
|
||||
|
||||
private fun KotlinCallArgument.isArrayOrArrayLiteral(): Boolean {
|
||||
if (this is CollectionLiteralKotlinCallArgument) return true
|
||||
if (this !is SimpleKotlinCallArgument) return false
|
||||
|
||||
val type = this.receiver.receiverValue.type
|
||||
return KotlinBuiltIns.isArrayOrPrimitiveArray(type)
|
||||
}
|
||||
|
||||
+1
-1
@@ -225,7 +225,7 @@ private fun KotlinResolutionCandidate.resolveKotlinArgument(
|
||||
isReceiver: Boolean
|
||||
) {
|
||||
val expectedType = candidateParameter?.let {
|
||||
resolvedCall.substitutor.substituteKeepAnnotations(argument.getExpectedType(candidateParameter))
|
||||
resolvedCall.substitutor.substituteKeepAnnotations(argument.getExpectedType(candidateParameter, callComponents.languageVersionSettings))
|
||||
}
|
||||
addResolvedKtPrimitive(resolveKtPrimitive(csBuilder, argument, expectedType, this, isReceiver))
|
||||
}
|
||||
|
||||
+3
-1
@@ -18,6 +18,7 @@ package org.jetbrains.kotlin.resolve.calls.model
|
||||
|
||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
||||
import org.jetbrains.kotlin.builtins.ReflectionTypes
|
||||
import org.jetbrains.kotlin.config.LanguageVersionSettings
|
||||
import org.jetbrains.kotlin.descriptors.CallableDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
||||
import org.jetbrains.kotlin.resolve.calls.components.*
|
||||
@@ -40,7 +41,8 @@ class KotlinCallComponents(
|
||||
val typeArgumentsToParametersMapper: TypeArgumentsToParametersMapper,
|
||||
val constraintInjector: ConstraintInjector,
|
||||
val reflectionTypes: ReflectionTypes,
|
||||
val builtIns: KotlinBuiltIns
|
||||
val builtIns: KotlinBuiltIns,
|
||||
val languageVersionSettings: LanguageVersionSettings
|
||||
)
|
||||
|
||||
class SimpleCandidateFactory(
|
||||
|
||||
Reference in New Issue
Block a user