[FE 1.0] Support proper DUPLICATE_LABEL_IN_WHEN reporting for deprecated complex boolean expressions
^KT-50385 ^KT-39883
This commit is contained in:
committed by
teamcity
parent
eb753eac83
commit
8a58e98530
@@ -33,6 +33,7 @@ import org.jetbrains.kotlin.cfg.pseudocode.instructions.eval.InstructionWithValu
|
||||
import org.jetbrains.kotlin.cfg.pseudocode.instructions.eval.MagicKind
|
||||
import org.jetbrains.kotlin.config.LanguageFeature
|
||||
import org.jetbrains.kotlin.config.LanguageVersionSettings
|
||||
import org.jetbrains.kotlin.config.LanguageVersionSettingsImpl
|
||||
import org.jetbrains.kotlin.contracts.description.EventOccurrencesRange
|
||||
import org.jetbrains.kotlin.contracts.description.canBeRevisited
|
||||
import org.jetbrains.kotlin.contracts.description.isDefinitelyVisited
|
||||
@@ -1321,7 +1322,11 @@ class ControlFlowProcessor(
|
||||
builder.bindLabel(doneLabel)
|
||||
|
||||
mergeValues(branches, expression)
|
||||
WhenChecker.checkDuplicatedLabels(expression, trace)
|
||||
WhenChecker.checkDuplicatedLabels(
|
||||
expression,
|
||||
trace,
|
||||
languageVersionSettings ?: LanguageVersionSettingsImpl.DEFAULT
|
||||
)
|
||||
}
|
||||
|
||||
override fun visitObjectLiteralExpression(expression: KtObjectLiteralExpression) {
|
||||
|
||||
@@ -18,6 +18,8 @@ package org.jetbrains.kotlin.cfg
|
||||
|
||||
import com.intellij.psi.PsiElement
|
||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
||||
import org.jetbrains.kotlin.config.LanguageFeature
|
||||
import org.jetbrains.kotlin.config.LanguageVersionSettings
|
||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.ClassKind
|
||||
import org.jetbrains.kotlin.descriptors.Modality
|
||||
@@ -357,7 +359,11 @@ object WhenChecker {
|
||||
fun containsNullCase(expression: KtWhenExpression, context: BindingContext) =
|
||||
WhenOnNullableExhaustivenessChecker.getMissingCases(expression, context, true).isEmpty()
|
||||
|
||||
fun checkDuplicatedLabels(expression: KtWhenExpression, trace: BindingTrace) {
|
||||
fun checkDuplicatedLabels(
|
||||
expression: KtWhenExpression,
|
||||
trace: BindingTrace,
|
||||
languageVersionSettings: LanguageVersionSettings,
|
||||
) {
|
||||
if (expression.subjectExpression == null) return
|
||||
|
||||
val checkedTypes = HashSet<Pair<KotlinType, Boolean>>()
|
||||
@@ -407,7 +413,7 @@ object WhenChecker {
|
||||
}
|
||||
false -> {
|
||||
// already found bad constant in previous branches
|
||||
val isTrivial = constant.isTrivial()
|
||||
val isTrivial = constant.isTrivial(constantExpression, languageVersionSettings)
|
||||
if (isTrivial) {
|
||||
// this constant is trivial -> report on first non trivial constant
|
||||
val reportOn = notTrivialBranches.remove(constant)!!
|
||||
@@ -420,7 +426,7 @@ object WhenChecker {
|
||||
}
|
||||
null -> {
|
||||
// met constant for a first time
|
||||
val isTrivial = constant.isTrivial()
|
||||
val isTrivial = constant.isTrivial(constantExpression, languageVersionSettings)
|
||||
checkedConstants[constant] = isTrivial
|
||||
if (!isTrivial) {
|
||||
notTrivialBranches[constant] = constantExpression
|
||||
@@ -446,8 +452,15 @@ object WhenChecker {
|
||||
}
|
||||
}
|
||||
|
||||
private fun CompileTimeConstant<*>.isTrivial(): Boolean {
|
||||
return !usesVariableAsConstant
|
||||
private fun CompileTimeConstant<*>.isTrivial(
|
||||
expression: KtExpression,
|
||||
languageVersionSettings: LanguageVersionSettings
|
||||
): Boolean {
|
||||
if (usesVariableAsConstant) return false
|
||||
if (!languageVersionSettings.supportsFeature(LanguageFeature.ProhibitSimplificationOfNonTrivialConstBooleanExpressions)) {
|
||||
return !ConstantExpressionEvaluator.isComplexBooleanConstant(expression, this)
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
fun checkDeprecatedWhenSyntax(trace: BindingTrace, expression: KtWhenExpression) {
|
||||
|
||||
+15
-6
@@ -51,7 +51,6 @@ import org.jetbrains.kotlin.types.isError
|
||||
import org.jetbrains.kotlin.types.typeUtil.isBoolean
|
||||
import org.jetbrains.kotlin.types.typeUtil.isSubtypeOf
|
||||
import org.jetbrains.kotlin.util.OperatorNameConventions
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.runIf
|
||||
import java.math.BigInteger
|
||||
import java.util.*
|
||||
|
||||
@@ -369,6 +368,17 @@ class ConstantExpressionEvaluator(
|
||||
KotlinBuiltIns.isArray(type) -> isTypeParameterOrArrayOfTypeParameter(type.arguments.singleOrNull()?.type)
|
||||
else -> type.constructor.declarationDescriptor is TypeParameterDescriptor
|
||||
}
|
||||
|
||||
fun isComplexBooleanConstant(
|
||||
expression: KtExpression,
|
||||
constant: CompileTimeConstant<*>
|
||||
): Boolean {
|
||||
if (constant.isError) return false
|
||||
val constantValue = constant.toConstantValue(constant.moduleDescriptor.builtIns.booleanType)
|
||||
if (!constantValue.getType(constant.moduleDescriptor).isBoolean()) return false
|
||||
if (expression is KtConstantExpression || constant.parameters.usesVariableAsConstant) return false
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -409,15 +419,13 @@ private class ConstantExpressionEvaluatorVisitor(
|
||||
return null
|
||||
}
|
||||
|
||||
@Suppress("warnings")
|
||||
private fun shouldSkipComplexBooleanValue(
|
||||
expression: KtExpression,
|
||||
constant: CompileTimeConstant<*>
|
||||
): Boolean {
|
||||
if (constant.isError) return false
|
||||
val constantValue = constant.toConstantValue(builtIns.booleanType)
|
||||
if (!constantValue.getType(constantExpressionEvaluator.module).isBoolean()) return false
|
||||
if (expression is KtConstantExpression || constant.parameters.usesVariableAsConstant) return false
|
||||
if (!ConstantExpressionEvaluator.isComplexBooleanConstant(expression, constant)) {
|
||||
return false
|
||||
}
|
||||
|
||||
if (languageVersionSettings.supportsFeature(LanguageFeature.ProhibitSimplificationOfNonTrivialConstBooleanExpressions)) {
|
||||
return true
|
||||
@@ -430,6 +438,7 @@ private class ConstantExpressionEvaluatorVisitor(
|
||||
parent is KtWhenConditionWithExpression ||
|
||||
parent is KtContainerNode && (parent.parent is KtWhileExpression || parent.parent is KtDoWhileExpression)
|
||||
) {
|
||||
val constantValue = constant.toConstantValue(builtIns.booleanType)
|
||||
trace.report(Errors.NON_TRIVIAL_BOOLEAN_CONSTANT.on(expression, constantValue.value as Boolean))
|
||||
}
|
||||
return false
|
||||
|
||||
Reference in New Issue
Block a user