[NI] Support wrong number of type arguments and integer constants.
- report WRONG_NUMBER_OF_TYPE_ARGUMENTS
- make integral types work again: IntegerValueType is represented as {Int & Byte & Short & Long} in the constraint system
This commit is contained in:
committed by
Stanislav Erokhin
parent
f5c59b1343
commit
d67b51e91a
+13
-4
@@ -20,10 +20,7 @@ import org.jetbrains.kotlin.builtins.functions.FunctionInvokeDescriptor
|
|||||||
import org.jetbrains.kotlin.diagnostics.Errors
|
import org.jetbrains.kotlin.diagnostics.Errors
|
||||||
import org.jetbrains.kotlin.diagnostics.Errors.*
|
import org.jetbrains.kotlin.diagnostics.Errors.*
|
||||||
import org.jetbrains.kotlin.diagnostics.Errors.BadNamedArgumentsTarget.*
|
import org.jetbrains.kotlin.diagnostics.Errors.BadNamedArgumentsTarget.*
|
||||||
import org.jetbrains.kotlin.psi.Call
|
import org.jetbrains.kotlin.psi.*
|
||||||
import org.jetbrains.kotlin.psi.KtConstantExpression
|
|
||||||
import org.jetbrains.kotlin.psi.KtExpression
|
|
||||||
import org.jetbrains.kotlin.psi.KtPsiUtil
|
|
||||||
import org.jetbrains.kotlin.resolve.BindingContext
|
import org.jetbrains.kotlin.resolve.BindingContext
|
||||||
import org.jetbrains.kotlin.resolve.BindingTrace
|
import org.jetbrains.kotlin.resolve.BindingTrace
|
||||||
import org.jetbrains.kotlin.resolve.calls.components.*
|
import org.jetbrains.kotlin.resolve.calls.components.*
|
||||||
@@ -61,7 +58,19 @@ class DiagnosticReporterByTrackingStrategy(
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun onTypeArguments(diagnostic: KotlinCallDiagnostic) {
|
override fun onTypeArguments(diagnostic: KotlinCallDiagnostic) {
|
||||||
|
val psiCallElement = psiKotlinCall.psiCall.callElement
|
||||||
|
val reportElement =
|
||||||
|
if (psiCallElement is KtCallExpression)
|
||||||
|
psiCallElement.typeArgumentList ?: psiCallElement.calleeExpression ?: psiCallElement
|
||||||
|
else
|
||||||
|
psiCallElement
|
||||||
|
|
||||||
|
when (diagnostic) {
|
||||||
|
is WrongCountOfTypeArguments -> {
|
||||||
|
val expectedTypeArgumentsCount = diagnostic.descriptor.typeParameters.size
|
||||||
|
trace.report(WRONG_NUMBER_OF_TYPE_ARGUMENTS.on(reportElement, expectedTypeArgumentsCount, diagnostic.descriptor))
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onCallName(diagnostic: KotlinCallDiagnostic) {
|
override fun onCallName(diagnostic: KotlinCallDiagnostic) {
|
||||||
|
|||||||
+1
-3
@@ -25,8 +25,7 @@ import org.jetbrains.kotlin.resolve.calls.model.*
|
|||||||
import org.jetbrains.kotlin.resolve.calls.smartcasts.getReceiverValueWithSmartCast
|
import org.jetbrains.kotlin.resolve.calls.smartcasts.getReceiverValueWithSmartCast
|
||||||
import org.jetbrains.kotlin.resolve.calls.tasks.ExplicitReceiverKind.*
|
import org.jetbrains.kotlin.resolve.calls.tasks.ExplicitReceiverKind.*
|
||||||
import org.jetbrains.kotlin.resolve.calls.tower.ResolutionCandidateApplicability
|
import org.jetbrains.kotlin.resolve.calls.tower.ResolutionCandidateApplicability
|
||||||
import org.jetbrains.kotlin.resolve.calls.tower.ResolutionCandidateApplicability.IMPOSSIBLE_TO_GENERATE
|
import org.jetbrains.kotlin.resolve.calls.tower.ResolutionCandidateApplicability.*
|
||||||
import org.jetbrains.kotlin.resolve.calls.tower.ResolutionCandidateApplicability.RUNTIME_ERROR
|
|
||||||
import org.jetbrains.kotlin.resolve.calls.tower.VisibilityError
|
import org.jetbrains.kotlin.resolve.calls.tower.VisibilityError
|
||||||
import org.jetbrains.kotlin.types.IndexedParametersSubstitution
|
import org.jetbrains.kotlin.types.IndexedParametersSubstitution
|
||||||
import org.jetbrains.kotlin.types.TypeSubstitutor
|
import org.jetbrains.kotlin.types.TypeSubstitutor
|
||||||
@@ -141,7 +140,6 @@ internal object CreteDescriptorWithFreshTypeVariables : ResolutionPart {
|
|||||||
return emptyList()
|
return emptyList()
|
||||||
}
|
}
|
||||||
|
|
||||||
// add explicit type parameter
|
|
||||||
for (index in typeParameters.indices) {
|
for (index in typeParameters.indices) {
|
||||||
val typeParameter = typeParameters[index]
|
val typeParameter = typeParameters[index]
|
||||||
val typeArgument = typeArgumentMappingByOriginal.getTypeArgument(typeParameter)
|
val typeArgument = typeArgumentMappingByOriginal.getTypeArgument(typeParameter)
|
||||||
|
|||||||
+4
-7
@@ -28,19 +28,16 @@ class TypeArgumentsToParametersMapper {
|
|||||||
abstract fun getTypeArgument(typeParameterDescriptor: TypeParameterDescriptor): TypeArgument
|
abstract fun getTypeArgument(typeParameterDescriptor: TypeParameterDescriptor): TypeArgument
|
||||||
|
|
||||||
object NoExplicitArguments : TypeArgumentsMapping(emptyList()) {
|
object NoExplicitArguments : TypeArgumentsMapping(emptyList()) {
|
||||||
override fun getTypeArgument(typeParameterDescriptor: TypeParameterDescriptor): TypeArgument {
|
override fun getTypeArgument(typeParameterDescriptor: TypeParameterDescriptor): TypeArgument =
|
||||||
return TypeArgumentPlaceholder
|
TypeArgumentPlaceholder
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class TypeArgumentsMappingImpl(
|
class TypeArgumentsMappingImpl(
|
||||||
diagnostics: List<KotlinCallDiagnostic>,
|
diagnostics: List<KotlinCallDiagnostic>,
|
||||||
private val typeParameterToArgumentMap: Map<TypeParameterDescriptor, TypeArgument>
|
private val typeParameterToArgumentMap: Map<TypeParameterDescriptor, TypeArgument>
|
||||||
): TypeArgumentsMapping(diagnostics) {
|
): TypeArgumentsMapping(diagnostics) {
|
||||||
override fun getTypeArgument(typeParameterDescriptor: TypeParameterDescriptor): TypeArgument {
|
override fun getTypeArgument(typeParameterDescriptor: TypeParameterDescriptor): TypeArgument =
|
||||||
return typeParameterToArgumentMap[typeParameterDescriptor] ?:
|
typeParameterToArgumentMap[typeParameterDescriptor] ?: TypeArgumentPlaceholder
|
||||||
error("No argument for parameter: $typeParameterDescriptor. Reported diagnostics: $diagnostics")
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+12
-5
@@ -16,16 +16,15 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.resolve.calls.inference.components
|
package org.jetbrains.kotlin.resolve.calls.inference.components
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
||||||
import org.jetbrains.kotlin.resolve.calls.components.CommonSupertypeCalculator
|
import org.jetbrains.kotlin.resolve.calls.components.CommonSupertypeCalculator
|
||||||
import org.jetbrains.kotlin.resolve.calls.inference.components.FixationOrderCalculator.ResolveDirection
|
import org.jetbrains.kotlin.resolve.calls.inference.components.FixationOrderCalculator.ResolveDirection
|
||||||
import org.jetbrains.kotlin.resolve.calls.inference.model.Constraint
|
import org.jetbrains.kotlin.resolve.calls.inference.model.Constraint
|
||||||
import org.jetbrains.kotlin.resolve.calls.inference.model.ConstraintKind
|
import org.jetbrains.kotlin.resolve.calls.inference.model.ConstraintKind
|
||||||
import org.jetbrains.kotlin.resolve.calls.inference.model.VariableWithConstraints
|
import org.jetbrains.kotlin.resolve.calls.inference.model.VariableWithConstraints
|
||||||
import org.jetbrains.kotlin.resolve.constants.IntegerValueTypeConstructor
|
import org.jetbrains.kotlin.resolve.constants.IntegerValueTypeConstructor
|
||||||
import org.jetbrains.kotlin.types.TypeUtils
|
import org.jetbrains.kotlin.types.*
|
||||||
import org.jetbrains.kotlin.types.UnwrappedType
|
|
||||||
import org.jetbrains.kotlin.types.checker.intersectTypes
|
import org.jetbrains.kotlin.types.checker.intersectTypes
|
||||||
import org.jetbrains.kotlin.types.singleBestRepresentative
|
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
|
||||||
class ResultTypeResolver(val commonSupertypeCalculator: CommonSupertypeCalculator) {
|
class ResultTypeResolver(val commonSupertypeCalculator: CommonSupertypeCalculator) {
|
||||||
@@ -76,14 +75,22 @@ class ResultTypeResolver(val commonSupertypeCalculator: CommonSupertypeCalculato
|
|||||||
|
|
||||||
private fun convertLowerTypesWithKnowledgeOfNumberTypes(lowerConstraints: Collection<Constraint>): Collection<UnwrappedType> {
|
private fun convertLowerTypesWithKnowledgeOfNumberTypes(lowerConstraints: Collection<Constraint>): Collection<UnwrappedType> {
|
||||||
if (lowerConstraints.isEmpty()) return emptyList()
|
if (lowerConstraints.isEmpty()) return emptyList()
|
||||||
if (lowerConstraints.size == 1) return listOf(lowerConstraints.first().type)
|
|
||||||
|
|
||||||
val (numberLowerBounds, generalLowerBounds) = lowerConstraints.map { it.type }.partition { it.constructor is IntegerValueTypeConstructor }
|
val (numberLowerBounds, generalLowerBounds) = lowerConstraints.map { it.type }.partition { it.isNumberValueType() }
|
||||||
|
|
||||||
val numberType = commonSupertypeForNumberTypes(numberLowerBounds) ?: return generalLowerBounds
|
val numberType = commonSupertypeForNumberTypes(numberLowerBounds) ?: return generalLowerBounds
|
||||||
return generalLowerBounds + numberType
|
return generalLowerBounds + numberType
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun KotlinType.isNumberValueType() =
|
||||||
|
constructor is IntegerValueTypeConstructor ||
|
||||||
|
(constructor is IntersectionTypeConstructor && constructor.supertypes.all { it.isPrimitiveIntegerType() } )
|
||||||
|
|
||||||
|
private fun KotlinType.isPrimitiveIntegerType() =
|
||||||
|
KotlinBuiltIns.isByte(this) ||
|
||||||
|
KotlinBuiltIns.isShort(this) ||
|
||||||
|
KotlinBuiltIns.isInt(this) ||
|
||||||
|
KotlinBuiltIns.isLong(this)
|
||||||
|
|
||||||
private fun commonSupertypeForNumberTypes(numberLowerBounds: Collection<UnwrappedType>): UnwrappedType? {
|
private fun commonSupertypeForNumberTypes(numberLowerBounds: Collection<UnwrappedType>): UnwrappedType? {
|
||||||
if (numberLowerBounds.isEmpty()) return null
|
if (numberLowerBounds.isEmpty()) return null
|
||||||
|
|||||||
Reference in New Issue
Block a user