[NI] Report special error message on constant expression type mismatch.
This commit is contained in:
committed by
Stanislav Erokhin
parent
5afd3e72d6
commit
f5c59b1343
+19
@@ -21,6 +21,8 @@ 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.Call
|
||||||
|
import org.jetbrains.kotlin.psi.KtConstantExpression
|
||||||
|
import org.jetbrains.kotlin.psi.KtExpression
|
||||||
import org.jetbrains.kotlin.psi.KtPsiUtil
|
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
|
||||||
@@ -32,9 +34,13 @@ import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowValueFactory
|
|||||||
import org.jetbrains.kotlin.resolve.calls.smartcasts.SmartCastManager
|
import org.jetbrains.kotlin.resolve.calls.smartcasts.SmartCastManager
|
||||||
import org.jetbrains.kotlin.resolve.calls.tasks.TracingStrategy
|
import org.jetbrains.kotlin.resolve.calls.tasks.TracingStrategy
|
||||||
import org.jetbrains.kotlin.resolve.calls.tower.*
|
import org.jetbrains.kotlin.resolve.calls.tower.*
|
||||||
|
import org.jetbrains.kotlin.resolve.constants.CompileTimeConstantChecker
|
||||||
|
import org.jetbrains.kotlin.resolve.constants.evaluate.ConstantExpressionEvaluator
|
||||||
|
import org.jetbrains.kotlin.resolve.descriptorUtil.builtIns
|
||||||
import org.jetbrains.kotlin.resolve.scopes.receivers.ExpressionReceiver
|
import org.jetbrains.kotlin.resolve.scopes.receivers.ExpressionReceiver
|
||||||
|
|
||||||
class DiagnosticReporterByTrackingStrategy(
|
class DiagnosticReporterByTrackingStrategy(
|
||||||
|
val constantExpressionEvaluator: ConstantExpressionEvaluator,
|
||||||
val context: BasicCallResolutionContext,
|
val context: BasicCallResolutionContext,
|
||||||
val trace: BindingTrace,
|
val trace: BindingTrace,
|
||||||
val psiKotlinCall: PSIKotlinCall
|
val psiKotlinCall: PSIKotlinCall
|
||||||
@@ -137,6 +143,7 @@ class DiagnosticReporterByTrackingStrategy(
|
|||||||
val constraintError = diagnostic as NewConstraintError
|
val constraintError = diagnostic as NewConstraintError
|
||||||
(constraintError.position as? ArgumentConstraintPosition)?.let {
|
(constraintError.position as? ArgumentConstraintPosition)?.let {
|
||||||
val expression = it.argument.psiExpression ?: return
|
val expression = it.argument.psiExpression ?: return
|
||||||
|
if (reportConstantTypeMismatch(constraintError, expression)) return
|
||||||
trace.report(Errors.TYPE_MISMATCH.on(expression, constraintError.upperType, constraintError.lowerType))
|
trace.report(Errors.TYPE_MISMATCH.on(expression, constraintError.upperType, constraintError.lowerType))
|
||||||
}
|
}
|
||||||
(constraintError.position as? ExplicitTypeParameterConstraintPosition)?.let {
|
(constraintError.position as? ExplicitTypeParameterConstraintPosition)?.let {
|
||||||
@@ -153,4 +160,16 @@ class DiagnosticReporterByTrackingStrategy(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun reportConstantTypeMismatch(constraintError: NewConstraintError, expression: KtExpression): Boolean {
|
||||||
|
if (expression is KtConstantExpression) {
|
||||||
|
val builtIns = context.scope.ownerDescriptor.builtIns
|
||||||
|
val constantValue = constantExpressionEvaluator.evaluateToConstantValue(expression, trace, context.expectedType)
|
||||||
|
val hasConstantTypeError = CompileTimeConstantChecker(context, builtIns, true)
|
||||||
|
.checkConstantExpressionType(constantValue, expression, constraintError.upperType)
|
||||||
|
if (hasConstantTypeError) return true
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
+7
-3
@@ -25,7 +25,9 @@ import org.jetbrains.kotlin.psi.KtPsiUtil
|
|||||||
import org.jetbrains.kotlin.psi.ValueArgument
|
import org.jetbrains.kotlin.psi.ValueArgument
|
||||||
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.*
|
import org.jetbrains.kotlin.resolve.calls.ArgumentTypeResolver
|
||||||
|
import org.jetbrains.kotlin.resolve.calls.DiagnosticReporterByTrackingStrategy
|
||||||
|
import org.jetbrains.kotlin.resolve.calls.REPORT_MISSING_NEW_INFERENCE_DIAGNOSTIC
|
||||||
import org.jetbrains.kotlin.resolve.calls.callResolverUtil.getEffectiveExpectedType
|
import org.jetbrains.kotlin.resolve.calls.callResolverUtil.getEffectiveExpectedType
|
||||||
import org.jetbrains.kotlin.resolve.calls.callUtil.isFakeElement
|
import org.jetbrains.kotlin.resolve.calls.callUtil.isFakeElement
|
||||||
import org.jetbrains.kotlin.resolve.calls.checkers.CallChecker
|
import org.jetbrains.kotlin.resolve.calls.checkers.CallChecker
|
||||||
@@ -36,6 +38,7 @@ import org.jetbrains.kotlin.resolve.calls.model.*
|
|||||||
import org.jetbrains.kotlin.resolve.calls.results.ResolutionStatus
|
import org.jetbrains.kotlin.resolve.calls.results.ResolutionStatus
|
||||||
import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowInfo
|
import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowInfo
|
||||||
import org.jetbrains.kotlin.resolve.calls.tasks.ExplicitReceiverKind
|
import org.jetbrains.kotlin.resolve.calls.tasks.ExplicitReceiverKind
|
||||||
|
import org.jetbrains.kotlin.resolve.constants.evaluate.ConstantExpressionEvaluator
|
||||||
import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue
|
import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue
|
||||||
import org.jetbrains.kotlin.types.KotlinType
|
import org.jetbrains.kotlin.types.KotlinType
|
||||||
import org.jetbrains.kotlin.types.TypeUtils
|
import org.jetbrains.kotlin.types.TypeUtils
|
||||||
@@ -49,7 +52,8 @@ class KotlinToResolvedCallTransformer(
|
|||||||
private val callCheckers: Iterable<CallChecker>,
|
private val callCheckers: Iterable<CallChecker>,
|
||||||
private val languageFeatureSettings: LanguageVersionSettings,
|
private val languageFeatureSettings: LanguageVersionSettings,
|
||||||
private val dataFlowAnalyzer: DataFlowAnalyzer,
|
private val dataFlowAnalyzer: DataFlowAnalyzer,
|
||||||
private val argumentTypeResolver: ArgumentTypeResolver
|
private val argumentTypeResolver: ArgumentTypeResolver,
|
||||||
|
private val constantExpressionEvaluator: ConstantExpressionEvaluator
|
||||||
) {
|
) {
|
||||||
|
|
||||||
fun <D : CallableDescriptor> transformAndReport(
|
fun <D : CallableDescriptor> transformAndReport(
|
||||||
@@ -185,7 +189,7 @@ class KotlinToResolvedCallTransformer(
|
|||||||
reported = true
|
reported = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
val diagnosticReporter = DiagnosticReporterByTrackingStrategy(context, reportTrackedTrace, completedCall.kotlinCall.psiKotlinCall)
|
val diagnosticReporter = DiagnosticReporterByTrackingStrategy(constantExpressionEvaluator, context, reportTrackedTrace, completedCall.kotlinCall.psiKotlinCall)
|
||||||
|
|
||||||
for (diagnostic in completedCall.resolutionStatus.diagnostics) {
|
for (diagnostic in completedCall.resolutionStatus.diagnostics) {
|
||||||
reported = false
|
reported = false
|
||||||
|
|||||||
Reference in New Issue
Block a user