DiagnosticReporterByTrackingStrategy: extract reportArgumentConstraintErrorByPosition
This commit is contained in:
committed by
Space Team
parent
7a58c2e99f
commit
eb80ba9cf7
+62
-41
@@ -11,6 +11,8 @@ import org.jetbrains.kotlin.builtins.isExtensionFunctionType
|
|||||||
import org.jetbrains.kotlin.config.LanguageFeature
|
import org.jetbrains.kotlin.config.LanguageFeature
|
||||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
||||||
import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor
|
import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor
|
||||||
|
import org.jetbrains.kotlin.diagnostics.Diagnostic
|
||||||
|
import org.jetbrains.kotlin.diagnostics.DiagnosticFactory2
|
||||||
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.diagnostics.reportDiagnosticOnce
|
import org.jetbrains.kotlin.diagnostics.reportDiagnosticOnce
|
||||||
@@ -449,47 +451,29 @@ class DiagnosticReporterByTrackingStrategy(
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
val argument =
|
|
||||||
when (position) {
|
|
||||||
is ArgumentConstraintPosition<*> -> position.argument as KotlinCallArgument
|
|
||||||
is ReceiverConstraintPosition<*> -> position.argument as KotlinCallArgument
|
|
||||||
is LambdaArgumentConstraintPosition<*> -> (position.lambda as ResolvedLambdaAtom).atom
|
|
||||||
else -> null
|
|
||||||
}
|
|
||||||
val isWarning = error is NewConstraintWarning
|
val isWarning = error is NewConstraintWarning
|
||||||
val typeMismatchDiagnostic = if (isWarning) TYPE_MISMATCH_WARNING else TYPE_MISMATCH
|
val typeMismatchDiagnostic = if (isWarning) TYPE_MISMATCH_WARNING else TYPE_MISMATCH
|
||||||
val report = if (isWarning) trace::reportDiagnosticOnce else trace::report
|
val report = if (isWarning) trace::reportDiagnosticOnce else trace::report
|
||||||
if (argument != null) {
|
|
||||||
(argument as? LambdaKotlinCallArgument)?.let lambda@{ lambda ->
|
|
||||||
val parameterTypes = lambda.parametersTypes?.toList() ?: return@lambda
|
|
||||||
val index = parameterTypes.indexOf(error.upperKotlinType.unwrap())
|
|
||||||
val lambdaExpression = lambda.psiExpression as? KtLambdaExpression ?: return@lambda
|
|
||||||
val parameter = lambdaExpression.valueParameters.getOrNull(index) ?: return@lambda
|
|
||||||
val diagnosticFactory =
|
|
||||||
if (isWarning) EXPECTED_PARAMETER_TYPE_MISMATCH_WARNING else EXPECTED_PARAMETER_TYPE_MISMATCH
|
|
||||||
report(diagnosticFactory.on(parameter, error.lowerKotlinType))
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
val expression = argument.psiExpression ?: return
|
|
||||||
val deparenthesized = KtPsiUtil.safeDeparenthesize(expression)
|
|
||||||
if (reportConstantTypeMismatch(error, deparenthesized)) return
|
|
||||||
|
|
||||||
val compileTimeConstant = trace[BindingContext.COMPILE_TIME_VALUE, deparenthesized] as? TypedCompileTimeConstant
|
|
||||||
if (compileTimeConstant != null) {
|
|
||||||
val expressionType = trace[BindingContext.EXPRESSION_TYPE_INFO, expression]?.type
|
|
||||||
if (expressionType != null &&
|
|
||||||
!UnsignedTypes.isUnsignedType(compileTimeConstant.type) && UnsignedTypes.isUnsignedType(expressionType)
|
|
||||||
) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
report(typeMismatchDiagnostic.on(deparenthesized, error.upperKotlinType, error.lowerKotlinType))
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
@Suppress("KotlinConstantConditions")
|
|
||||||
when (position) {
|
when (position) {
|
||||||
|
is ArgumentConstraintPosition<*> -> {
|
||||||
|
reportArgumentConstraintErrorByPosition(
|
||||||
|
error, position.argument as KotlinCallArgument,
|
||||||
|
isWarning, typeMismatchDiagnostic, report
|
||||||
|
)
|
||||||
|
}
|
||||||
|
is ReceiverConstraintPosition<*> -> {
|
||||||
|
reportArgumentConstraintErrorByPosition(
|
||||||
|
error, position.argument as KotlinCallArgument,
|
||||||
|
isWarning, typeMismatchDiagnostic, report
|
||||||
|
)
|
||||||
|
}
|
||||||
|
is LambdaArgumentConstraintPosition<*> -> {
|
||||||
|
reportArgumentConstraintErrorByPosition(
|
||||||
|
error, (position.lambda as ResolvedLambdaAtom).atom,
|
||||||
|
isWarning, typeMismatchDiagnostic, report
|
||||||
|
)
|
||||||
|
}
|
||||||
is BuilderInferenceExpectedTypeConstraintPosition -> {
|
is BuilderInferenceExpectedTypeConstraintPosition -> {
|
||||||
val inferredType =
|
val inferredType =
|
||||||
if (!error.lowerKotlinType.isNullableNothing()) error.lowerKotlinType
|
if (!error.lowerKotlinType.isNullableNothing()) error.lowerKotlinType
|
||||||
@@ -540,13 +524,50 @@ class DiagnosticReporterByTrackingStrategy(
|
|||||||
}
|
}
|
||||||
is LHSArgumentConstraintPosition<*, *> -> TODO()
|
is LHSArgumentConstraintPosition<*, *> -> TODO()
|
||||||
SimpleConstraintSystemConstraintPosition -> TODO()
|
SimpleConstraintSystemConstraintPosition -> TODO()
|
||||||
// Never reachable
|
}
|
||||||
is ArgumentConstraintPosition<*>,
|
}
|
||||||
is LambdaArgumentConstraintPosition<*>,
|
|
||||||
is ReceiverConstraintPosition<*> -> {
|
private fun reportArgumentConstraintErrorByPosition(
|
||||||
throw AssertionError("Should not be here")
|
error: NewConstraintMismatch,
|
||||||
|
argument: KotlinCallArgument,
|
||||||
|
isWarning: Boolean,
|
||||||
|
typeMismatchDiagnostic: DiagnosticFactory2<KtExpression, KotlinType, KotlinType>,
|
||||||
|
report: (Diagnostic) -> Unit
|
||||||
|
) {
|
||||||
|
if (argument is LambdaKotlinCallArgument) {
|
||||||
|
val parameterTypes = argument.parametersTypes?.toList()
|
||||||
|
if (parameterTypes != null) {
|
||||||
|
val index = parameterTypes.indexOf(error.upperKotlinType.unwrap())
|
||||||
|
val lambdaExpression = argument.psiExpression as? KtLambdaExpression
|
||||||
|
val parameter = lambdaExpression?.valueParameters?.getOrNull(index)
|
||||||
|
if (parameter != null) {
|
||||||
|
val diagnosticFactory =
|
||||||
|
if (isWarning) EXPECTED_PARAMETER_TYPE_MISMATCH_WARNING else EXPECTED_PARAMETER_TYPE_MISMATCH
|
||||||
|
report(diagnosticFactory.on(parameter, error.lowerKotlinType))
|
||||||
|
return
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: FIXME (KT-55056)
|
||||||
|
val expression = argument.psiExpression ?: return
|
||||||
|
|
||||||
|
val deparenthesized = KtPsiUtil.safeDeparenthesize(expression)
|
||||||
|
if (reportConstantTypeMismatch(error, deparenthesized)) return
|
||||||
|
|
||||||
|
val compileTimeConstant = trace[BindingContext.COMPILE_TIME_VALUE, deparenthesized] as? TypedCompileTimeConstant
|
||||||
|
if (compileTimeConstant != null) {
|
||||||
|
val expressionType = trace[BindingContext.EXPRESSION_TYPE_INFO, expression]?.type
|
||||||
|
if (expressionType != null &&
|
||||||
|
!UnsignedTypes.isUnsignedType(compileTimeConstant.type) && UnsignedTypes.isUnsignedType(expressionType)
|
||||||
|
) {
|
||||||
|
// This is a special "hack" to prevent TYPE_MISMATCH
|
||||||
|
// in case of a compile-time constant with signed VS unsigned type
|
||||||
|
// See conversionOfSignedToUnsigned.kt diagnostic test
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
report(typeMismatchDiagnostic.on(deparenthesized, error.upperKotlinType, error.lowerKotlinType))
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun constraintError(error: ConstraintSystemError) {
|
override fun constraintError(error: ConstraintSystemError) {
|
||||||
|
|||||||
Reference in New Issue
Block a user