Compiler warning on identical enum constant / is type entries #KT-4829 Fixed
This commit is contained in:
@@ -1202,6 +1202,7 @@ class ControlFlowProcessor(private val trace: BindingTrace) {
|
||||
builder.bindLabel(doneLabel)
|
||||
|
||||
mergeValues(branches, expression)
|
||||
WhenChecker.checkDuplicatedLabels(expression, trace)
|
||||
}
|
||||
|
||||
override fun visitObjectLiteralExpression(expression: KtObjectLiteralExpression) {
|
||||
|
||||
@@ -37,6 +37,8 @@ import org.jetbrains.kotlin.types.TypeUtils
|
||||
import org.jetbrains.kotlin.resolve.DescriptorUtils.isEnumClass
|
||||
import org.jetbrains.kotlin.resolve.DescriptorUtils.isEnumEntry
|
||||
import org.jetbrains.kotlin.resolve.bindingContextUtil.isUsedAsExpression
|
||||
import org.jetbrains.kotlin.resolve.constants.CompileTimeConstant
|
||||
import org.jetbrains.kotlin.resolve.constants.evaluate.ConstantExpressionEvaluator
|
||||
import java.util.*
|
||||
|
||||
interface WhenMissingCase {
|
||||
@@ -333,6 +335,46 @@ object WhenChecker {
|
||||
fun containsNullCase(expression: KtWhenExpression, context: BindingContext) =
|
||||
WhenOnNullableExhaustivenessChecker.getMissingCases(expression, context, true).isEmpty()
|
||||
|
||||
fun checkDuplicatedLabels(expression: KtWhenExpression, trace: BindingTrace) {
|
||||
if (expression.subjectExpression == null) return
|
||||
|
||||
val checkedTypes = HashSet<Pair<KotlinType, Boolean>>()
|
||||
val checkedConstants = HashSet<CompileTimeConstant<*>>()
|
||||
for (entry in expression.entries) {
|
||||
if (entry.isElse) continue
|
||||
|
||||
conditions@ for (condition in entry.conditions) {
|
||||
when (condition) {
|
||||
is KtWhenConditionWithExpression -> {
|
||||
val constantExpression = condition.expression ?: continue@conditions
|
||||
val constant = ConstantExpressionEvaluator.getConstant(
|
||||
constantExpression, trace.bindingContext) ?: continue@conditions
|
||||
if (checkedConstants.contains(constant)) {
|
||||
trace.report(Errors.DUPLICATE_LABEL_IN_WHEN.on(constantExpression))
|
||||
}
|
||||
else {
|
||||
checkedConstants.add(constant)
|
||||
}
|
||||
|
||||
}
|
||||
is KtWhenConditionIsPattern -> {
|
||||
val typeReference = condition.typeReference ?: continue@conditions
|
||||
val type = trace.get(BindingContext.TYPE, typeReference) ?: continue@conditions
|
||||
val typeWithIsNegation = type to condition.isNegated
|
||||
if (checkedTypes.contains(typeWithIsNegation)) {
|
||||
trace.report(Errors.DUPLICATE_LABEL_IN_WHEN.on(typeReference))
|
||||
}
|
||||
else {
|
||||
checkedTypes.add(typeWithIsNegation)
|
||||
}
|
||||
}
|
||||
else -> {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
fun checkDeprecatedWhenSyntax(trace: BindingTrace, expression: KtWhenExpression) {
|
||||
if (expression.subjectExpression != null) return
|
||||
|
||||
|
||||
@@ -728,6 +728,7 @@ public interface Errors {
|
||||
DiagnosticFactory1<KtWhenExpression, List<WhenMissingCase>> NO_ELSE_IN_WHEN = DiagnosticFactory1.create(ERROR, WHEN_EXPRESSION);
|
||||
DiagnosticFactory1<KtWhenExpression, List<WhenMissingCase>> NON_EXHAUSTIVE_WHEN = DiagnosticFactory1.create(WARNING, WHEN_EXPRESSION);
|
||||
DiagnosticFactory0<PsiElement> COMMA_IN_WHEN_CONDITION_WITHOUT_ARGUMENT = DiagnosticFactory0.create(ERROR);
|
||||
DiagnosticFactory0<PsiElement> DUPLICATE_LABEL_IN_WHEN = DiagnosticFactory0.create(WARNING);
|
||||
|
||||
// Type mismatch
|
||||
|
||||
|
||||
+1
@@ -430,6 +430,7 @@ public class DefaultErrorMessages {
|
||||
|
||||
MAP.put(ELSE_MISPLACED_IN_WHEN, "'else' entry must be the last one in a when-expression");
|
||||
MAP.put(COMMA_IN_WHEN_CONDITION_WITHOUT_ARGUMENT, "Deprecated syntax. Use '||' instead of commas in when-condition for 'when' without argument");
|
||||
MAP.put(DUPLICATE_LABEL_IN_WHEN, "Duplicate label in when");
|
||||
|
||||
MAP.put(NO_ELSE_IN_WHEN, "''when'' expression must be exhaustive, add necessary {0}", RENDER_WHEN_MISSING_CASES);
|
||||
MAP.put(NON_EXHAUSTIVE_WHEN, "''when'' expression on enum is recommended to be exhaustive, add {0}", RENDER_WHEN_MISSING_CASES);
|
||||
|
||||
Reference in New Issue
Block a user