[FE 1.0] Prohibit confusing syntax inside when branches
^KT-48385 Fixed
This commit is contained in:
committed by
teamcityserver
parent
653fc85461
commit
1513e739c6
@@ -997,6 +997,7 @@ public interface Errors {
|
||||
DiagnosticFactory0<KtElement> SENSELESS_NULL_IN_WHEN = DiagnosticFactory0.create(WARNING);
|
||||
|
||||
DiagnosticFactory0<PsiElement> INVALID_IF_AS_EXPRESSION = DiagnosticFactory0.create(ERROR);
|
||||
DiagnosticFactoryForDeprecation0<PsiElement> CONFUSING_BRANCH_CONDITION = DiagnosticFactoryForDeprecation0.create(LanguageFeature.ProhibitConfusingSyntaxInWhenBranches);
|
||||
|
||||
// Nullability
|
||||
|
||||
|
||||
+1
@@ -833,6 +833,7 @@ public class DefaultErrorMessages {
|
||||
MAP.put(SENSELESS_NULL_IN_WHEN, "Expression under 'when' is never equal to null");
|
||||
|
||||
MAP.put(INVALID_IF_AS_EXPRESSION, "'if' must have both main and 'else' branches if used as an expression");
|
||||
MAP.put(CONFUSING_BRANCH_CONDITION, "The logical expressions may be understood ambiguously in when with subject branches. Please wrap it with parenthesis");
|
||||
|
||||
MAP.put(OVERRIDING_FINAL_MEMBER, "''{0}'' in ''{1}'' is final and cannot be overridden", NAME, NAME);
|
||||
MAP.put(CANNOT_WEAKEN_ACCESS_PRIVILEGE, "Cannot weaken access privilege ''{0}'' for ''{1}'' in ''{2}''", VISIBILITY, NAME, NAME);
|
||||
|
||||
+51
@@ -0,0 +1,51 @@
|
||||
/*
|
||||
* Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.resolve.checkers
|
||||
|
||||
import com.intellij.psi.tree.TokenSet
|
||||
import org.jetbrains.kotlin.config.LanguageVersionSettings
|
||||
import org.jetbrains.kotlin.diagnostics.Errors.CONFUSING_BRANCH_CONDITION
|
||||
import org.jetbrains.kotlin.lexer.KtTokens.*
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
import org.jetbrains.kotlin.resolve.BindingTrace
|
||||
|
||||
object ConfusingWhenBranchSyntaxChecker {
|
||||
private val prohibitedTokens = TokenSet.create(
|
||||
IN_KEYWORD, NOT_IN,
|
||||
LT, LTEQ, GT, GTEQ,
|
||||
EQEQ, EXCLEQ, EQEQEQ, EXCLEQEQEQ,
|
||||
ANDAND, OROR
|
||||
)
|
||||
|
||||
fun check(whenExpression: KtWhenExpression, languageVersionSettings: LanguageVersionSettings, trace: BindingTrace) {
|
||||
if (whenExpression.subjectExpression == null && whenExpression.subjectVariable == null) return
|
||||
for (entry in whenExpression.entries) {
|
||||
for (condition in entry.conditions) {
|
||||
checkCondition(condition, languageVersionSettings, trace)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun checkCondition(condition: KtWhenCondition, languageVersionSettings: LanguageVersionSettings, trace: BindingTrace) {
|
||||
when (condition) {
|
||||
is KtWhenConditionWithExpression -> checkConditionExpression(condition.expression, languageVersionSettings, trace)
|
||||
is KtWhenConditionInRange -> checkConditionExpression(condition.rangeExpression, languageVersionSettings, trace)
|
||||
}
|
||||
}
|
||||
|
||||
private fun checkConditionExpression(rawExpression: KtExpression?, languageVersionSettings: LanguageVersionSettings, trace: BindingTrace) {
|
||||
if (rawExpression == null) return
|
||||
if (rawExpression is KtParenthesizedExpression) return
|
||||
val shouldReport = when (val expression = KtPsiUtil.safeDeparenthesize(rawExpression)) {
|
||||
is KtIsExpression -> true
|
||||
is KtBinaryExpression -> expression.operationToken in prohibitedTokens
|
||||
else -> false
|
||||
}
|
||||
if (shouldReport) {
|
||||
trace.report(CONFUSING_BRANCH_CONDITION.on(languageVersionSettings, rawExpression))
|
||||
}
|
||||
}
|
||||
}
|
||||
+3
@@ -32,6 +32,7 @@ import org.jetbrains.kotlin.resolve.calls.checkers.RttiOperation
|
||||
import org.jetbrains.kotlin.resolve.calls.context.ContextDependency.INDEPENDENT
|
||||
import org.jetbrains.kotlin.resolve.calls.smartcasts.*
|
||||
import org.jetbrains.kotlin.resolve.calls.util.CallMaker
|
||||
import org.jetbrains.kotlin.resolve.checkers.ConfusingWhenBranchSyntaxChecker
|
||||
import org.jetbrains.kotlin.resolve.checkers.PrimitiveNumericComparisonCallChecker
|
||||
import org.jetbrains.kotlin.resolve.scopes.LexicalScope
|
||||
import org.jetbrains.kotlin.resolve.scopes.LexicalScopeKind
|
||||
@@ -249,6 +250,8 @@ class PatternMatchingTypingVisitor internal constructor(facade: ExpressionTyping
|
||||
val branchesType = branchesTypeInfo.type ?: return noTypeInfo(resultDataFlowInfo)
|
||||
val resultType = components.dataFlowAnalyzer.checkType(branchesType, expression, contextWithExpectedType)
|
||||
|
||||
ConfusingWhenBranchSyntaxChecker.check(expression, contextWithExpectedType.languageVersionSettings, trace)
|
||||
|
||||
return createTypeInfo(resultType, resultDataFlowInfo, branchesTypeInfo.jumpOutPossible, contextWithExpectedType.dataFlowInfo)
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user