[FE 1.0] Prohibit using non exhaustive if and when in rhs of elvis expression
^KT-44705 ^KT-49349 Fixed
This commit is contained in:
committed by
teamcityserver
parent
06a26a5a74
commit
a2b8493f47
+12
@@ -6289,6 +6289,18 @@ public class DiagnosisCompilerTestFE10TestdataTestGenerated extends AbstractDiag
|
|||||||
runTest("compiler/testData/diagnostics/tests/controlStructures/nestedLoopsWithMultipleLabels.kt");
|
runTest("compiler/testData/diagnostics/tests/controlStructures/nestedLoopsWithMultipleLabels.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("nonExhaustiveIfInElvis_after.kt")
|
||||||
|
public void testNonExhaustiveIfInElvis_after() throws Exception {
|
||||||
|
runTest("compiler/testData/diagnostics/tests/controlStructures/nonExhaustiveIfInElvis_after.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("nonExhaustiveIfInElvis_before.kt")
|
||||||
|
public void testNonExhaustiveIfInElvis_before() throws Exception {
|
||||||
|
runTest("compiler/testData/diagnostics/tests/controlStructures/nonExhaustiveIfInElvis_before.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestMetadata("notAFunctionLabel_after.kt")
|
@TestMetadata("notAFunctionLabel_after.kt")
|
||||||
public void testNotAFunctionLabel_after() throws Exception {
|
public void testNotAFunctionLabel_after() throws Exception {
|
||||||
|
|||||||
+12
@@ -6289,6 +6289,18 @@ public class FirOldFrontendDiagnosticsTestGenerated extends AbstractFirDiagnosti
|
|||||||
runTest("compiler/testData/diagnostics/tests/controlStructures/nestedLoopsWithMultipleLabels.kt");
|
runTest("compiler/testData/diagnostics/tests/controlStructures/nestedLoopsWithMultipleLabels.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("nonExhaustiveIfInElvis_after.kt")
|
||||||
|
public void testNonExhaustiveIfInElvis_after() throws Exception {
|
||||||
|
runTest("compiler/testData/diagnostics/tests/controlStructures/nonExhaustiveIfInElvis_after.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("nonExhaustiveIfInElvis_before.kt")
|
||||||
|
public void testNonExhaustiveIfInElvis_before() throws Exception {
|
||||||
|
runTest("compiler/testData/diagnostics/tests/controlStructures/nonExhaustiveIfInElvis_before.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestMetadata("notAFunctionLabel_after.kt")
|
@TestMetadata("notAFunctionLabel_after.kt")
|
||||||
public void testNotAFunctionLabel_after() throws Exception {
|
public void testNotAFunctionLabel_after() throws Exception {
|
||||||
|
|||||||
+12
@@ -6289,6 +6289,18 @@ public class FirOldFrontendDiagnosticsWithLightTreeTestGenerated extends Abstrac
|
|||||||
runTest("compiler/testData/diagnostics/tests/controlStructures/nestedLoopsWithMultipleLabels.kt");
|
runTest("compiler/testData/diagnostics/tests/controlStructures/nestedLoopsWithMultipleLabels.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("nonExhaustiveIfInElvis_after.kt")
|
||||||
|
public void testNonExhaustiveIfInElvis_after() throws Exception {
|
||||||
|
runTest("compiler/testData/diagnostics/tests/controlStructures/nonExhaustiveIfInElvis_after.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("nonExhaustiveIfInElvis_before.kt")
|
||||||
|
public void testNonExhaustiveIfInElvis_before() throws Exception {
|
||||||
|
runTest("compiler/testData/diagnostics/tests/controlStructures/nonExhaustiveIfInElvis_before.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestMetadata("notAFunctionLabel_after.kt")
|
@TestMetadata("notAFunctionLabel_after.kt")
|
||||||
public void testNotAFunctionLabel_after() throws Exception {
|
public void testNotAFunctionLabel_after() throws Exception {
|
||||||
|
|||||||
+30
-5
@@ -5,6 +5,7 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.cfg
|
package org.jetbrains.kotlin.cfg
|
||||||
|
|
||||||
|
import com.intellij.psi.PsiElement
|
||||||
import com.intellij.psi.util.PsiTreeUtil.getParentOfType
|
import com.intellij.psi.util.PsiTreeUtil.getParentOfType
|
||||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
||||||
import org.jetbrains.kotlin.cfg.TailRecursionKind.*
|
import org.jetbrains.kotlin.cfg.TailRecursionKind.*
|
||||||
@@ -43,14 +44,10 @@ import org.jetbrains.kotlin.resolve.bindingContextUtil.getEnclosingDescriptor
|
|||||||
import org.jetbrains.kotlin.resolve.bindingContextUtil.isUsedAsExpression
|
import org.jetbrains.kotlin.resolve.bindingContextUtil.isUsedAsExpression
|
||||||
import org.jetbrains.kotlin.resolve.bindingContextUtil.isUsedAsResultOfLambda
|
import org.jetbrains.kotlin.resolve.bindingContextUtil.isUsedAsResultOfLambda
|
||||||
import org.jetbrains.kotlin.resolve.bindingContextUtil.isUsedAsStatement
|
import org.jetbrains.kotlin.resolve.bindingContextUtil.isUsedAsStatement
|
||||||
import org.jetbrains.kotlin.resolve.calls.util.getResolvedCall
|
|
||||||
import org.jetbrains.kotlin.resolve.calls.checkers.findDestructuredVariable
|
import org.jetbrains.kotlin.resolve.calls.checkers.findDestructuredVariable
|
||||||
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
|
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
|
||||||
import org.jetbrains.kotlin.resolve.calls.model.VariableAsFunctionResolvedCall
|
import org.jetbrains.kotlin.resolve.calls.model.VariableAsFunctionResolvedCall
|
||||||
import org.jetbrains.kotlin.resolve.calls.util.getDispatchReceiverWithSmartCast
|
import org.jetbrains.kotlin.resolve.calls.util.*
|
||||||
import org.jetbrains.kotlin.resolve.calls.util.hasThisOrNoDispatchReceiver
|
|
||||||
import org.jetbrains.kotlin.resolve.calls.util.FakeCallableDescriptorForObject
|
|
||||||
import org.jetbrains.kotlin.resolve.calls.util.isSingleUnderscore
|
|
||||||
import org.jetbrains.kotlin.resolve.checkers.PlatformDiagnosticSuppressor
|
import org.jetbrains.kotlin.resolve.checkers.PlatformDiagnosticSuppressor
|
||||||
import org.jetbrains.kotlin.resolve.descriptorUtil.isEffectivelyExternal
|
import org.jetbrains.kotlin.resolve.descriptorUtil.isEffectivelyExternal
|
||||||
import org.jetbrains.kotlin.resolve.descriptorUtil.module
|
import org.jetbrains.kotlin.resolve.descriptorUtil.module
|
||||||
@@ -943,6 +940,13 @@ class ControlFlowInformationProviderImpl private constructor(
|
|||||||
} else {
|
} else {
|
||||||
checkImplicitCastOnConditionalExpression(element)
|
checkImplicitCastOnConditionalExpression(element)
|
||||||
}
|
}
|
||||||
|
} else if (!languageVersionSettings.supportsFeature(LanguageFeature.ProhibitNonExhaustiveIfInRhsOfElvis)) {
|
||||||
|
val parent = element.deparenthesizedParent
|
||||||
|
if (parent is KtBinaryExpression) {
|
||||||
|
if (parent.operationToken === KtTokens.ELVIS) {
|
||||||
|
trace.report(INVALID_IF_AS_EXPRESSION_WARNING.on(element.getIfKeyword()))
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1036,6 +1040,18 @@ class ControlFlowInformationProviderImpl private constructor(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (
|
||||||
|
!usedAsExpression &&
|
||||||
|
missingCases.isNotEmpty() &&
|
||||||
|
!languageVersionSettings.supportsFeature(LanguageFeature.ProhibitNonExhaustiveIfInRhsOfElvis)
|
||||||
|
) {
|
||||||
|
val parent = element.deparenthesizedParent
|
||||||
|
if (parent is KtBinaryExpression) {
|
||||||
|
if (parent.operationToken === KtTokens.ELVIS) {
|
||||||
|
trace.report(NO_ELSE_IN_WHEN_WARNING.on(element, missingCases))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1355,4 +1371,13 @@ class ControlFlowInformationProviderImpl private constructor(
|
|||||||
|| diagnosticFactory === UNUSED_ANONYMOUS_PARAMETER
|
|| diagnosticFactory === UNUSED_ANONYMOUS_PARAMETER
|
||||||
|| diagnosticFactory === UNUSED_CHANGED_VALUE
|
|| diagnosticFactory === UNUSED_CHANGED_VALUE
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private val PsiElement.deparenthesizedParent: PsiElement
|
||||||
|
get() {
|
||||||
|
var result = parent
|
||||||
|
while (result is KtParenthesizedExpression || result is KtLabeledExpression || result is KtAnnotatedExpression) {
|
||||||
|
result = result.parent
|
||||||
|
}
|
||||||
|
return result
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -346,7 +346,10 @@ class ControlFlowProcessor(
|
|||||||
builder.jumpOnTrue(afterElvis, expression, builder.getBoundValue(left))
|
builder.jumpOnTrue(afterElvis, expression, builder.getBoundValue(left))
|
||||||
generateInstructions(right)
|
generateInstructions(right)
|
||||||
builder.bindLabel(afterElvis)
|
builder.bindLabel(afterElvis)
|
||||||
mergeValues(listOf(left, right).filterNotNull(), expression)
|
mergeValues(listOfNotNull(left, right), expression)
|
||||||
|
if (right != null && languageVersionSettings?.supportsFeature(LanguageFeature.ProhibitNonExhaustiveIfInRhsOfElvis) == true) {
|
||||||
|
trace.record(USED_AS_EXPRESSION, right, true)
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
if (!generateCall(expression)) {
|
if (!generateCall(expression)) {
|
||||||
generateBothArgumentsAndMark(expression)
|
generateBothArgumentsAndMark(expression)
|
||||||
|
|||||||
@@ -997,6 +997,7 @@ public interface Errors {
|
|||||||
DiagnosticFactory0<KtElement> SENSELESS_NULL_IN_WHEN = DiagnosticFactory0.create(WARNING);
|
DiagnosticFactory0<KtElement> SENSELESS_NULL_IN_WHEN = DiagnosticFactory0.create(WARNING);
|
||||||
|
|
||||||
DiagnosticFactory0<PsiElement> INVALID_IF_AS_EXPRESSION = DiagnosticFactory0.create(ERROR);
|
DiagnosticFactory0<PsiElement> INVALID_IF_AS_EXPRESSION = DiagnosticFactory0.create(ERROR);
|
||||||
|
DiagnosticFactory0<PsiElement> INVALID_IF_AS_EXPRESSION_WARNING = DiagnosticFactory0.create(WARNING);
|
||||||
DiagnosticFactoryForDeprecation0<PsiElement> CONFUSING_BRANCH_CONDITION = DiagnosticFactoryForDeprecation0.create(LanguageFeature.ProhibitConfusingSyntaxInWhenBranches);
|
DiagnosticFactoryForDeprecation0<PsiElement> CONFUSING_BRANCH_CONDITION = DiagnosticFactoryForDeprecation0.create(LanguageFeature.ProhibitConfusingSyntaxInWhenBranches);
|
||||||
|
|
||||||
// Nullability
|
// Nullability
|
||||||
@@ -1079,6 +1080,7 @@ public interface Errors {
|
|||||||
DiagnosticFactory0<KtWhenEntry> ELSE_MISPLACED_IN_WHEN = DiagnosticFactory0.create(ERROR, ELSE_ENTRY);
|
DiagnosticFactory0<KtWhenEntry> ELSE_MISPLACED_IN_WHEN = DiagnosticFactory0.create(ERROR, ELSE_ENTRY);
|
||||||
DiagnosticFactory0<KtWhenEntry> REDUNDANT_ELSE_IN_WHEN = DiagnosticFactory0.create(WARNING, ELSE_ENTRY);
|
DiagnosticFactory0<KtWhenEntry> REDUNDANT_ELSE_IN_WHEN = DiagnosticFactory0.create(WARNING, ELSE_ENTRY);
|
||||||
DiagnosticFactory1<KtWhenExpression, List<WhenMissingCase>> NO_ELSE_IN_WHEN = DiagnosticFactory1.create(ERROR, WHEN_EXPRESSION);
|
DiagnosticFactory1<KtWhenExpression, List<WhenMissingCase>> NO_ELSE_IN_WHEN = DiagnosticFactory1.create(ERROR, WHEN_EXPRESSION);
|
||||||
|
DiagnosticFactory1<KtWhenExpression, List<WhenMissingCase>> NO_ELSE_IN_WHEN_WARNING = DiagnosticFactory1.create(WARNING, WHEN_EXPRESSION);
|
||||||
DiagnosticFactory1<KtWhenExpression, List<WhenMissingCase>> NON_EXHAUSTIVE_WHEN = DiagnosticFactory1.create(WARNING, WHEN_EXPRESSION);
|
DiagnosticFactory1<KtWhenExpression, List<WhenMissingCase>> NON_EXHAUSTIVE_WHEN = DiagnosticFactory1.create(WARNING, WHEN_EXPRESSION);
|
||||||
DiagnosticFactory2<KtWhenExpression, String, List<WhenMissingCase>> NON_EXHAUSTIVE_WHEN_STATEMENT = DiagnosticFactory2.create(WARNING, WHEN_EXPRESSION);
|
DiagnosticFactory2<KtWhenExpression, String, List<WhenMissingCase>> NON_EXHAUSTIVE_WHEN_STATEMENT = DiagnosticFactory2.create(WARNING, WHEN_EXPRESSION);
|
||||||
DiagnosticFactory1<KtWhenExpression, List<WhenMissingCase>>
|
DiagnosticFactory1<KtWhenExpression, List<WhenMissingCase>>
|
||||||
|
|||||||
+2
@@ -632,6 +632,7 @@ public class DefaultErrorMessages {
|
|||||||
MAP.put(ILLEGAL_DECLARATION_IN_WHEN_SUBJECT, "Illegal variable declaration in 'when' subject: {0}. Should be a simple val with an initializer", STRING);
|
MAP.put(ILLEGAL_DECLARATION_IN_WHEN_SUBJECT, "Illegal variable declaration in 'when' subject: {0}. Should be a simple val with an initializer", STRING);
|
||||||
|
|
||||||
MAP.put(NO_ELSE_IN_WHEN, "''when'' expression must be exhaustive, add necessary {0}", RENDER_WHEN_MISSING_CASES);
|
MAP.put(NO_ELSE_IN_WHEN, "''when'' expression must be exhaustive, add necessary {0}", RENDER_WHEN_MISSING_CASES);
|
||||||
|
MAP.put(NO_ELSE_IN_WHEN_WARNING, "''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);
|
MAP.put(NON_EXHAUSTIVE_WHEN, "''when'' expression on enum is recommended to be exhaustive, add {0}", RENDER_WHEN_MISSING_CASES);
|
||||||
MAP.put(NON_EXHAUSTIVE_WHEN_STATEMENT, "Non exhaustive ''when'' statements on {0} will be prohibited in 1.7, add {1}", STRING, RENDER_WHEN_MISSING_CASES);
|
MAP.put(NON_EXHAUSTIVE_WHEN_STATEMENT, "Non exhaustive ''when'' statements on {0} will be prohibited in 1.7, add {1}", STRING, RENDER_WHEN_MISSING_CASES);
|
||||||
MAP.put(NON_EXHAUSTIVE_WHEN_ON_SEALED_CLASS, "''when'' expression on sealed classes is recommended to be exhaustive, add {0}", RENDER_WHEN_MISSING_CASES);
|
MAP.put(NON_EXHAUSTIVE_WHEN_ON_SEALED_CLASS, "''when'' expression on sealed classes is recommended to be exhaustive, add {0}", RENDER_WHEN_MISSING_CASES);
|
||||||
@@ -833,6 +834,7 @@ public class DefaultErrorMessages {
|
|||||||
MAP.put(SENSELESS_NULL_IN_WHEN, "Expression under 'when' is never equal to null");
|
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(INVALID_IF_AS_EXPRESSION, "'if' must have both main and 'else' branches if used as an expression");
|
||||||
|
MAP.put(INVALID_IF_AS_EXPRESSION_WARNING, "'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(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(OVERRIDING_FINAL_MEMBER, "''{0}'' in ''{1}'' is final and cannot be overridden", NAME, NAME);
|
||||||
|
|||||||
@@ -56,8 +56,8 @@ fun g6(): Unit = <!TYPE_MISMATCH!><!NO_ELSE_IN_WHEN!>when<!> { true -> 42 }<!>
|
|||||||
fun foo1(x: String?) {
|
fun foo1(x: String?) {
|
||||||
"" + <!INVALID_IF_AS_EXPRESSION!>if<!> (true) 42
|
"" + <!INVALID_IF_AS_EXPRESSION!>if<!> (true) 42
|
||||||
w@while (true) {
|
w@while (true) {
|
||||||
x ?: if (true) break
|
x ?: <!INVALID_IF_AS_EXPRESSION_WARNING!>if<!> (true) break
|
||||||
x ?: when { true -> break@w }
|
x ?: <!NO_ELSE_IN_WHEN_WARNING!>when<!> { true -> break@w }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+30
@@ -0,0 +1,30 @@
|
|||||||
|
// FIR_IDENTICAL
|
||||||
|
// LANGUAGE: +ProhibitNonExhaustiveIfInRhsOfElvis
|
||||||
|
// DIAGNOSTICS: -USELESS_ELVIS
|
||||||
|
// ISSUE: KT-44705
|
||||||
|
|
||||||
|
fun test_1(x: String?, y: String?) {
|
||||||
|
while (true) {
|
||||||
|
x ?: <!INVALID_IF_AS_EXPRESSION!>if<!> (y == null) break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun test_2(x: String?, y: String?) {
|
||||||
|
while (true) {
|
||||||
|
val z = x ?: <!INVALID_IF_AS_EXPRESSION!>if<!> (y == null) break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun test_3(x: String?, y: String?) {
|
||||||
|
while (true) {
|
||||||
|
x ?: <!NO_ELSE_IN_WHEN!>when<!> { true -> break }
|
||||||
|
x ?: <!NO_ELSE_IN_WHEN!>when<!> (y) { "hello" -> break }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun test_4(x: String?, y: String?) {
|
||||||
|
while (true) {
|
||||||
|
val a = x ?: <!NO_ELSE_IN_WHEN!>when<!> { true -> break }
|
||||||
|
val b = x ?: <!NO_ELSE_IN_WHEN!>when<!> (y) { "hello" -> break }
|
||||||
|
}
|
||||||
|
}
|
||||||
+7
@@ -0,0 +1,7 @@
|
|||||||
|
package
|
||||||
|
|
||||||
|
public fun test_1(/*0*/ x: kotlin.String?, /*1*/ y: kotlin.String?): kotlin.Unit
|
||||||
|
public fun test_2(/*0*/ x: kotlin.String?, /*1*/ y: kotlin.String?): kotlin.Unit
|
||||||
|
public fun test_3(/*0*/ x: kotlin.String?, /*1*/ y: kotlin.String?): kotlin.Unit
|
||||||
|
public fun test_4(/*0*/ x: kotlin.String?, /*1*/ y: kotlin.String?): kotlin.Unit
|
||||||
|
|
||||||
+29
@@ -0,0 +1,29 @@
|
|||||||
|
// LANGUAGE: -ProhibitNonExhaustiveIfInRhsOfElvis
|
||||||
|
// DIAGNOSTICS: -USELESS_ELVIS
|
||||||
|
// ISSUE: KT-44705
|
||||||
|
|
||||||
|
fun test_1(x: String?, y: String?) {
|
||||||
|
while (true) {
|
||||||
|
x ?: <!INVALID_IF_AS_EXPRESSION!>if<!> (y == null) break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun test_2(x: String?, y: String?) {
|
||||||
|
while (true) {
|
||||||
|
val z = x ?: <!INVALID_IF_AS_EXPRESSION!>if<!> (y == null) break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun test_3(x: String?, y: String?) {
|
||||||
|
while (true) {
|
||||||
|
x ?: <!NO_ELSE_IN_WHEN!>when<!> { true -> break }
|
||||||
|
x ?: <!NO_ELSE_IN_WHEN!>when<!> (y) { "hello" -> break }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun test_4(x: String?, y: String?) {
|
||||||
|
while (true) {
|
||||||
|
val a = x ?: <!NO_ELSE_IN_WHEN!>when<!> { true -> break }
|
||||||
|
val b = x ?: <!NO_ELSE_IN_WHEN!>when<!> (y) { "hello" -> break }
|
||||||
|
}
|
||||||
|
}
|
||||||
+29
@@ -0,0 +1,29 @@
|
|||||||
|
// LANGUAGE: -ProhibitNonExhaustiveIfInRhsOfElvis
|
||||||
|
// DIAGNOSTICS: -USELESS_ELVIS
|
||||||
|
// ISSUE: KT-44705
|
||||||
|
|
||||||
|
fun test_1(x: String?, y: String?) {
|
||||||
|
while (true) {
|
||||||
|
x ?: <!INVALID_IF_AS_EXPRESSION_WARNING!>if<!> (y == null) break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun test_2(x: String?, y: String?) {
|
||||||
|
while (true) {
|
||||||
|
val z = x ?: <!INVALID_IF_AS_EXPRESSION!>if<!> (y == null) break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun test_3(x: String?, y: String?) {
|
||||||
|
while (true) {
|
||||||
|
x ?: <!NO_ELSE_IN_WHEN_WARNING!>when<!> { true -> break }
|
||||||
|
x ?: <!NO_ELSE_IN_WHEN_WARNING!>when<!> (y) { "hello" -> break }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun test_4(x: String?, y: String?) {
|
||||||
|
while (true) {
|
||||||
|
val a = x ?: <!NO_ELSE_IN_WHEN!>when<!> { true -> break }
|
||||||
|
val b = x ?: <!NO_ELSE_IN_WHEN!>when<!> (y) { "hello" -> break }
|
||||||
|
}
|
||||||
|
}
|
||||||
+7
@@ -0,0 +1,7 @@
|
|||||||
|
package
|
||||||
|
|
||||||
|
public fun test_1(/*0*/ x: kotlin.String?, /*1*/ y: kotlin.String?): kotlin.Unit
|
||||||
|
public fun test_2(/*0*/ x: kotlin.String?, /*1*/ y: kotlin.String?): kotlin.Unit
|
||||||
|
public fun test_3(/*0*/ x: kotlin.String?, /*1*/ y: kotlin.String?): kotlin.Unit
|
||||||
|
public fun test_4(/*0*/ x: kotlin.String?, /*1*/ y: kotlin.String?): kotlin.Unit
|
||||||
|
|
||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
public fun foo(x: String?, y: String?): Int {
|
public fun foo(x: String?, y: String?): Int {
|
||||||
while (true) {
|
while (true) {
|
||||||
x ?: if (y == null) break
|
x ?: <!INVALID_IF_AS_EXPRESSION_WARNING!>if<!> (y == null) break
|
||||||
// y is nullable if x != null
|
// y is nullable if x != null
|
||||||
y<!UNSAFE_CALL!>.<!>length
|
y<!UNSAFE_CALL!>.<!>length
|
||||||
}
|
}
|
||||||
|
|||||||
Generated
+12
@@ -6295,6 +6295,18 @@ public class DiagnosticTestGenerated extends AbstractDiagnosticTest {
|
|||||||
runTest("compiler/testData/diagnostics/tests/controlStructures/nestedLoopsWithMultipleLabels.kt");
|
runTest("compiler/testData/diagnostics/tests/controlStructures/nestedLoopsWithMultipleLabels.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("nonExhaustiveIfInElvis_after.kt")
|
||||||
|
public void testNonExhaustiveIfInElvis_after() throws Exception {
|
||||||
|
runTest("compiler/testData/diagnostics/tests/controlStructures/nonExhaustiveIfInElvis_after.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("nonExhaustiveIfInElvis_before.kt")
|
||||||
|
public void testNonExhaustiveIfInElvis_before() throws Exception {
|
||||||
|
runTest("compiler/testData/diagnostics/tests/controlStructures/nonExhaustiveIfInElvis_before.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestMetadata("notAFunctionLabel_after.kt")
|
@TestMetadata("notAFunctionLabel_after.kt")
|
||||||
public void testNotAFunctionLabel_after() throws Exception {
|
public void testNotAFunctionLabel_after() throws Exception {
|
||||||
|
|||||||
@@ -235,6 +235,7 @@ enum class LanguageFeature(
|
|||||||
JvmPermittedSubclassesAttributeForSealed(KOTLIN_1_7),
|
JvmPermittedSubclassesAttributeForSealed(KOTLIN_1_7),
|
||||||
ForbidUsingExtensionPropertyTypeParameterInDelegate(KOTLIN_1_7, kind = BUG_FIX),
|
ForbidUsingExtensionPropertyTypeParameterInDelegate(KOTLIN_1_7, kind = BUG_FIX),
|
||||||
ProhibitConfusingSyntaxInWhenBranches(KOTLIN_1_7, kind = BUG_FIX), // KT-48385
|
ProhibitConfusingSyntaxInWhenBranches(KOTLIN_1_7, kind = BUG_FIX), // KT-48385
|
||||||
|
ProhibitNonExhaustiveIfInRhsOfElvis(KOTLIN_1_7, kind = BUG_FIX), // KT-44705
|
||||||
|
|
||||||
// Temporarily disabled, see KT-27084/KT-22379
|
// Temporarily disabled, see KT-27084/KT-22379
|
||||||
SoundSmartcastFromLoopConditionForLoopAssignedVariables(sinceVersion = null, kind = BUG_FIX),
|
SoundSmartcastFromLoopConditionForLoopAssignedVariables(sinceVersion = null, kind = BUG_FIX),
|
||||||
|
|||||||
Reference in New Issue
Block a user