diff --git a/compiler/frontend/src/org/jetbrains/kotlin/psi/KtPsiUtil.java b/compiler/frontend/src/org/jetbrains/kotlin/psi/KtPsiUtil.java
index fb956277628..cdcb56420e0 100644
--- a/compiler/frontend/src/org/jetbrains/kotlin/psi/KtPsiUtil.java
+++ b/compiler/frontend/src/org/jetbrains/kotlin/psi/KtPsiUtil.java
@@ -316,7 +316,7 @@ public class KtPsiUtil {
return isBooleanConstant(condition) && condition.getNode().findChildByType(KtTokens.FALSE_KEYWORD) != null;
}
- private static boolean isBooleanConstant(@Nullable KtExpression condition) {
+ public static boolean isBooleanConstant(@Nullable KtExpression condition) {
return condition != null && condition.getNode().getElementType() == KtNodeTypes.BOOLEAN_CONSTANT;
}
diff --git a/idea/resources/inspectionDescriptions/NullableBooleanElvis.html b/idea/resources/inspectionDescriptions/NullableBooleanElvis.html
new file mode 100644
index 00000000000..2841a5be336
--- /dev/null
+++ b/idea/resources/inspectionDescriptions/NullableBooleanElvis.html
@@ -0,0 +1,5 @@
+
+
+This inspection reports when equality check should be used instead of elvis
+
+
\ No newline at end of file
diff --git a/idea/resources/intentionDescriptions/NullableBooleanEqualityCheckToElvisIntention/after.kt.template b/idea/resources/intentionDescriptions/NullableBooleanEqualityCheckToElvisIntention/after.kt.template
new file mode 100644
index 00000000000..5dd81877af8
--- /dev/null
+++ b/idea/resources/intentionDescriptions/NullableBooleanEqualityCheckToElvisIntention/after.kt.template
@@ -0,0 +1,3 @@
+val v: Boolean?
+
+if (v ?: false)
\ No newline at end of file
diff --git a/idea/resources/intentionDescriptions/NullableBooleanEqualityCheckToElvisIntention/before.kt.template b/idea/resources/intentionDescriptions/NullableBooleanEqualityCheckToElvisIntention/before.kt.template
new file mode 100644
index 00000000000..2cc7d1acf5c
--- /dev/null
+++ b/idea/resources/intentionDescriptions/NullableBooleanEqualityCheckToElvisIntention/before.kt.template
@@ -0,0 +1,3 @@
+val v: Boolean?
+
+if (v == true)
\ No newline at end of file
diff --git a/idea/resources/intentionDescriptions/NullableBooleanEqualityCheckToElvisIntention/description.html b/idea/resources/intentionDescriptions/NullableBooleanEqualityCheckToElvisIntention/description.html
new file mode 100644
index 00000000000..0195ffaa1da
--- /dev/null
+++ b/idea/resources/intentionDescriptions/NullableBooleanEqualityCheckToElvisIntention/description.html
@@ -0,0 +1,5 @@
+
+
+Converts nullable boolean equality check to elvis operator
+
+
\ No newline at end of file
diff --git a/idea/src/META-INF/plugin.xml b/idea/src/META-INF/plugin.xml
index 6f214933ebc..7156181e4df 100644
--- a/idea/src/META-INF/plugin.xml
+++ b/idea/src/META-INF/plugin.xml
@@ -1590,6 +1590,11 @@
Kotlin
+
+ org.jetbrains.kotlin.idea.intentions.NullableBooleanEqualityCheckToElvisIntention
+ Kotlin
+
+
+
+
diff --git a/idea/src/org/jetbrains/kotlin/idea/inspections/NullableBooleanElvisInspection.kt b/idea/src/org/jetbrains/kotlin/idea/inspections/NullableBooleanElvisInspection.kt
new file mode 100644
index 00000000000..ad3bec2d180
--- /dev/null
+++ b/idea/src/org/jetbrains/kotlin/idea/inspections/NullableBooleanElvisInspection.kt
@@ -0,0 +1,88 @@
+/*
+ * Copyright 2010-2017 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.jetbrains.kotlin.idea.inspections
+
+import com.intellij.codeInsight.FileModificationService
+import com.intellij.codeInspection.*
+import com.intellij.codeInspection.ProblemHighlightType.GENERIC_ERROR_OR_WARNING
+import com.intellij.codeInspection.ProblemHighlightType.INFORMATION
+import com.intellij.openapi.project.Project
+import com.intellij.psi.util.PsiTreeUtil
+import org.jetbrains.kotlin.idea.caches.resolve.analyze
+import org.jetbrains.kotlin.idea.core.replaced
+import org.jetbrains.kotlin.idea.intentions.SimplifyNegatedBinaryExpressionIntention
+import org.jetbrains.kotlin.lexer.KtTokens
+import org.jetbrains.kotlin.psi.*
+import org.jetbrains.kotlin.psi.psiUtil.getParentOfType
+import org.jetbrains.kotlin.psi.psiUtil.parentsWithSelf
+import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
+import org.jetbrains.kotlin.types.TypeUtils
+import org.jetbrains.kotlin.types.typeUtil.isBooleanOrNullableBoolean
+
+class NullableBooleanElvisInspection : AbstractKotlinInspection(), CleanupLocalInspectionTool {
+ override fun buildVisitor(holder: ProblemsHolder, isOnTheFly: Boolean, session: LocalInspectionToolSession) =
+ object : KtVisitorVoid() {
+ override fun visitBinaryExpression(expression: KtBinaryExpression) {
+ if (expression.operationToken != KtTokens.ELVIS) return
+ val lhs = expression.left ?: return
+ val rhs = expression.right ?: return
+ if (!KtPsiUtil.isBooleanConstant(rhs)) return
+ val lhsType = lhs.analyze(BodyResolveMode.PARTIAL).getType(lhs) ?: return
+ if (TypeUtils.isNullableType(lhsType) && lhsType.isBooleanOrNullableBoolean()) {
+ val parentIfOrWhile = PsiTreeUtil.getParentOfType(
+ expression, KtIfExpression::class.java, KtWhileExpressionBase::class.java)
+ val condition = when (parentIfOrWhile) {
+ is KtIfExpression -> parentIfOrWhile.condition
+ is KtWhileExpressionBase -> parentIfOrWhile.condition
+ else -> null
+ }
+ val highlightType =
+ if (condition != null && condition in expression.parentsWithSelf) GENERIC_ERROR_OR_WARNING else INFORMATION
+
+ holder.registerProblem(expression,
+ "Equality check can be used instead of elvis",
+ highlightType,
+ ReplaceWithEqualityCheckFix())
+ }
+ }
+ }
+
+ private class ReplaceWithEqualityCheckFix : LocalQuickFix {
+ override fun getName() = "Replace with equality check"
+ override fun getFamilyName() = name
+
+ override fun applyFix(project: Project, descriptor: ProblemDescriptor) {
+ val element = descriptor.psiElement as? KtBinaryExpression ?: return
+ if (!FileModificationService.getInstance().preparePsiElementForWrite(element)) return
+ if (element.operationToken != KtTokens.ELVIS) return
+ val constPart = element.right as? KtConstantExpression ?: return
+ val exprPart = element.left ?: return
+
+ val constValue = if (KtPsiUtil.isTrueConstant(constPart)) true else if (KtPsiUtil.isFalseConstant(constPart)) false else return
+ val equalityCheckExpression = element.replaced(KtPsiFactory(constPart).buildExpression {
+ appendExpression(exprPart)
+ appendFixedText(if (constValue) " != false" else " == true")
+ })
+ val prefixExpression = equalityCheckExpression.getParentOfType(strict = true) ?: return
+ val simplifier = SimplifyNegatedBinaryExpressionIntention()
+ if (simplifier.isApplicableTo(prefixExpression)) {
+ simplifier.applyTo(prefixExpression, null)
+ }
+ }
+ }
+}
+
diff --git a/idea/src/org/jetbrains/kotlin/idea/intentions/NullableBooleanEqualityCheckToElvisIntention.kt b/idea/src/org/jetbrains/kotlin/idea/intentions/NullableBooleanEqualityCheckToElvisIntention.kt
new file mode 100644
index 00000000000..749a01fe0fd
--- /dev/null
+++ b/idea/src/org/jetbrains/kotlin/idea/intentions/NullableBooleanEqualityCheckToElvisIntention.kt
@@ -0,0 +1,56 @@
+/*
+ * Copyright 2010-2017 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.jetbrains.kotlin.idea.intentions
+
+import com.intellij.openapi.editor.Editor
+import org.jetbrains.kotlin.idea.caches.resolve.analyze
+import org.jetbrains.kotlin.idea.core.replaced
+import org.jetbrains.kotlin.lexer.KtTokens
+import org.jetbrains.kotlin.psi.*
+import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
+import org.jetbrains.kotlin.types.TypeUtils
+import org.jetbrains.kotlin.types.typeUtil.isBooleanOrNullableBoolean
+
+class NullableBooleanEqualityCheckToElvisIntention : SelfTargetingIntention(
+ KtBinaryExpression::class.java, "Convert Boolean? == const to elvis"
+) {
+ override fun isApplicableTo(element: KtBinaryExpression, caretOffset: Int): Boolean {
+ if (element.operationToken != KtTokens.EQEQ && element.operationToken != KtTokens.EXCLEQ) return false
+ val lhs = element.left ?: return false
+ val rhs = element.right ?: return false
+ return isApplicable(lhs, rhs) || isApplicable(rhs, lhs)
+ }
+
+ private fun isApplicable(lhs: KtExpression, rhs: KtExpression): Boolean {
+ if (!KtPsiUtil.isBooleanConstant(rhs)) return false
+
+ val lhsType = lhs.analyze(BodyResolveMode.PARTIAL).getType(lhs) ?: return false
+ return TypeUtils.isNullableType(lhsType) && lhsType.isBooleanOrNullableBoolean()
+ }
+
+ override fun applyTo(element: KtBinaryExpression, editor: Editor?) {
+ val equality = element.operationToken == KtTokens.EQEQ
+ val constPart = element.left as? KtConstantExpression ?:
+ element.right as? KtConstantExpression ?: return
+ val exprPart = (if (element.right == constPart) element.left else element.right) ?: return
+ val constValue = if (KtPsiUtil.isTrueConstant(constPart)) true else if (KtPsiUtil.isFalseConstant(constPart)) false else return
+
+ val factory = KtPsiFactory(constPart)
+ val elvis = factory.createExpressionByPattern("$0 ?: ${!constValue}", exprPart)
+ element.replaced(if (constValue == equality) elvis else factory.createExpressionByPattern("!($0)", elvis))
+ }
+}
\ No newline at end of file
diff --git a/idea/testData/inspections/nullableBooleanElvis/inspectionData/expected.xml b/idea/testData/inspections/nullableBooleanElvis/inspectionData/expected.xml
new file mode 100644
index 00000000000..ed949048701
--- /dev/null
+++ b/idea/testData/inspections/nullableBooleanElvis/inspectionData/expected.xml
@@ -0,0 +1,51 @@
+
+
+ test.kt
+ 4
+ light_idea_test_case
+
+ Equality check can be used instead of elvis
+ Equality check can be used instead of elvis
+
+
+ test.kt
+ 7
+ light_idea_test_case
+
+ Equality check can be used instead of elvis
+ Equality check can be used instead of elvis
+
+
+ test.kt
+ 10
+ light_idea_test_case
+
+ Equality check can be used instead of elvis
+ Equality check can be used instead of elvis
+
+
+ test.kt
+ 10
+ light_idea_test_case
+
+ Equality check can be used instead of elvis
+ Equality check can be used instead of elvis
+
+
+ test.kt
+ 13
+ light_idea_test_case
+
+ Equality check can be used instead of elvis
+ Equality check can be used instead of elvis
+
+
+ test.kt
+ 14
+ light_idea_test_case
+
+ Equality check can be used instead of elvis
+ Equality check can be used instead of elvis
+
+
+
\ No newline at end of file
diff --git a/idea/testData/inspections/nullableBooleanElvis/inspectionData/inspections.test b/idea/testData/inspections/nullableBooleanElvis/inspectionData/inspections.test
new file mode 100644
index 00000000000..5dcbb97fe50
--- /dev/null
+++ b/idea/testData/inspections/nullableBooleanElvis/inspectionData/inspections.test
@@ -0,0 +1 @@
+// INSPECTION_CLASS: org.jetbrains.kotlin.idea.inspections.NullableBooleanElvisInspection
\ No newline at end of file
diff --git a/idea/testData/inspections/nullableBooleanElvis/test.kt b/idea/testData/inspections/nullableBooleanElvis/test.kt
new file mode 100644
index 00000000000..2d976b1dc7c
--- /dev/null
+++ b/idea/testData/inspections/nullableBooleanElvis/test.kt
@@ -0,0 +1,15 @@
+fun foo() {
+ var a: Boolean? = null
+ var b: Boolean? = null
+ if (a ?: false) {
+
+ }
+ if (!(a ?: false)) {
+
+ }
+ if (a ?: false || !(b ?: true)) {
+
+ }
+ val x = a ?: false
+ val y = !(b ?: true)
+}
\ No newline at end of file
diff --git a/idea/testData/inspectionsLocal/nullableBooleanElvis/.inspection b/idea/testData/inspectionsLocal/nullableBooleanElvis/.inspection
new file mode 100644
index 00000000000..4cb1205e8d8
--- /dev/null
+++ b/idea/testData/inspectionsLocal/nullableBooleanElvis/.inspection
@@ -0,0 +1 @@
+org.jetbrains.kotlin.idea.inspections.NullableBooleanElvisInspection
\ No newline at end of file
diff --git a/idea/testData/inspectionsLocal/nullableBooleanElvis/inIf.kt b/idea/testData/inspectionsLocal/nullableBooleanElvis/inIf.kt
new file mode 100644
index 00000000000..42f23e832d5
--- /dev/null
+++ b/idea/testData/inspectionsLocal/nullableBooleanElvis/inIf.kt
@@ -0,0 +1,6 @@
+fun foo() {
+ var a: Boolean? = null
+ if (a ?: false) {
+
+ }
+}
\ No newline at end of file
diff --git a/idea/testData/inspectionsLocal/nullableBooleanElvis/inIf.kt.after b/idea/testData/inspectionsLocal/nullableBooleanElvis/inIf.kt.after
new file mode 100644
index 00000000000..dc884151d2b
--- /dev/null
+++ b/idea/testData/inspectionsLocal/nullableBooleanElvis/inIf.kt.after
@@ -0,0 +1,6 @@
+fun foo() {
+ var a: Boolean? = null
+ if (a == true) {
+
+ }
+}
\ No newline at end of file
diff --git a/idea/testData/inspectionsLocal/nullableBooleanElvis/inIf2.kt b/idea/testData/inspectionsLocal/nullableBooleanElvis/inIf2.kt
new file mode 100644
index 00000000000..1e07483db95
--- /dev/null
+++ b/idea/testData/inspectionsLocal/nullableBooleanElvis/inIf2.kt
@@ -0,0 +1,6 @@
+fun foo() {
+ var a: Boolean? = null
+ if (!(a ?: false)) {
+
+ }
+}
\ No newline at end of file
diff --git a/idea/testData/inspectionsLocal/nullableBooleanElvis/inIf2.kt.after b/idea/testData/inspectionsLocal/nullableBooleanElvis/inIf2.kt.after
new file mode 100644
index 00000000000..2040cc4dc53
--- /dev/null
+++ b/idea/testData/inspectionsLocal/nullableBooleanElvis/inIf2.kt.after
@@ -0,0 +1,6 @@
+fun foo() {
+ var a: Boolean? = null
+ if (a != true) {
+
+ }
+}
\ No newline at end of file
diff --git a/idea/testData/inspectionsLocal/nullableBooleanElvis/inIf3.kt b/idea/testData/inspectionsLocal/nullableBooleanElvis/inIf3.kt
new file mode 100644
index 00000000000..c3bdf002460
--- /dev/null
+++ b/idea/testData/inspectionsLocal/nullableBooleanElvis/inIf3.kt
@@ -0,0 +1,7 @@
+fun foo() {
+ var a: Boolean? = null
+ var b: Boolean? = null
+ if (a ?: false || !(b ?: true)) {
+
+ }
+}
\ No newline at end of file
diff --git a/idea/testData/inspectionsLocal/nullableBooleanElvis/inIf3.kt.after b/idea/testData/inspectionsLocal/nullableBooleanElvis/inIf3.kt.after
new file mode 100644
index 00000000000..82e2343f55d
--- /dev/null
+++ b/idea/testData/inspectionsLocal/nullableBooleanElvis/inIf3.kt.after
@@ -0,0 +1,7 @@
+fun foo() {
+ var a: Boolean? = null
+ var b: Boolean? = null
+ if (a ?: false || b == false) {
+
+ }
+}
\ No newline at end of file
diff --git a/idea/testData/inspectionsLocal/nullableBooleanElvis/notInIf.kt b/idea/testData/inspectionsLocal/nullableBooleanElvis/notInIf.kt
new file mode 100644
index 00000000000..759ad185a07
--- /dev/null
+++ b/idea/testData/inspectionsLocal/nullableBooleanElvis/notInIf.kt
@@ -0,0 +1,4 @@
+fun foo() {
+ var a: Boolean? = null
+ val x = a ?: false
+}
\ No newline at end of file
diff --git a/idea/testData/inspectionsLocal/nullableBooleanElvis/notInIf.kt.after b/idea/testData/inspectionsLocal/nullableBooleanElvis/notInIf.kt.after
new file mode 100644
index 00000000000..902dddf9085
--- /dev/null
+++ b/idea/testData/inspectionsLocal/nullableBooleanElvis/notInIf.kt.after
@@ -0,0 +1,4 @@
+fun foo() {
+ var a: Boolean? = null
+ val x = a == true
+}
\ No newline at end of file
diff --git a/idea/testData/inspectionsLocal/nullableBooleanElvis/notInIfWithTrue.kt b/idea/testData/inspectionsLocal/nullableBooleanElvis/notInIfWithTrue.kt
new file mode 100644
index 00000000000..05daebfe2a3
--- /dev/null
+++ b/idea/testData/inspectionsLocal/nullableBooleanElvis/notInIfWithTrue.kt
@@ -0,0 +1,4 @@
+fun foo() {
+ var b: Boolean? = null
+ val x = !(b ?: true)
+}
\ No newline at end of file
diff --git a/idea/testData/inspectionsLocal/nullableBooleanElvis/notInIfWithTrue.kt.after b/idea/testData/inspectionsLocal/nullableBooleanElvis/notInIfWithTrue.kt.after
new file mode 100644
index 00000000000..baf5d809161
--- /dev/null
+++ b/idea/testData/inspectionsLocal/nullableBooleanElvis/notInIfWithTrue.kt.after
@@ -0,0 +1,4 @@
+fun foo() {
+ var b: Boolean? = null
+ val x = b == false
+}
\ No newline at end of file
diff --git a/idea/testData/intentions/nullableBooleanEqualityCheckToElvis/.intention b/idea/testData/intentions/nullableBooleanEqualityCheckToElvis/.intention
new file mode 100644
index 00000000000..4e9fcfbe25c
--- /dev/null
+++ b/idea/testData/intentions/nullableBooleanEqualityCheckToElvis/.intention
@@ -0,0 +1 @@
+org.jetbrains.kotlin.idea.intentions.NullableBooleanEqualityCheckToElvisIntention
\ No newline at end of file
diff --git a/idea/testData/intentions/nullableBooleanEqualityCheckToElvis/eqFalse.kt b/idea/testData/intentions/nullableBooleanEqualityCheckToElvis/eqFalse.kt
new file mode 100644
index 00000000000..a400a74df2e
--- /dev/null
+++ b/idea/testData/intentions/nullableBooleanEqualityCheckToElvis/eqFalse.kt
@@ -0,0 +1,6 @@
+fun foo() {
+ val a: Boolean? = null
+ if (a == false) {
+
+ }
+}
diff --git a/idea/testData/intentions/nullableBooleanEqualityCheckToElvis/eqFalse.kt.after b/idea/testData/intentions/nullableBooleanEqualityCheckToElvis/eqFalse.kt.after
new file mode 100644
index 00000000000..11e856f753d
--- /dev/null
+++ b/idea/testData/intentions/nullableBooleanEqualityCheckToElvis/eqFalse.kt.after
@@ -0,0 +1,6 @@
+fun foo() {
+ val a: Boolean? = null
+ if (!(a ?: true)) {
+
+ }
+}
diff --git a/idea/testData/intentions/nullableBooleanEqualityCheckToElvis/eqTrue.kt b/idea/testData/intentions/nullableBooleanEqualityCheckToElvis/eqTrue.kt
new file mode 100644
index 00000000000..3be273cc031
--- /dev/null
+++ b/idea/testData/intentions/nullableBooleanEqualityCheckToElvis/eqTrue.kt
@@ -0,0 +1,6 @@
+fun foo() {
+ val a: Boolean? = null
+ if (a == true) {
+
+ }
+}
diff --git a/idea/testData/intentions/nullableBooleanEqualityCheckToElvis/eqTrue.kt.after b/idea/testData/intentions/nullableBooleanEqualityCheckToElvis/eqTrue.kt.after
new file mode 100644
index 00000000000..7e76e26f0f9
--- /dev/null
+++ b/idea/testData/intentions/nullableBooleanEqualityCheckToElvis/eqTrue.kt.after
@@ -0,0 +1,6 @@
+fun foo() {
+ val a: Boolean? = null
+ if (a ?: false) {
+
+ }
+}
diff --git a/idea/testData/intentions/nullableBooleanEqualityCheckToElvis/flexible.kt b/idea/testData/intentions/nullableBooleanEqualityCheckToElvis/flexible.kt
new file mode 100644
index 00000000000..1567dce405d
--- /dev/null
+++ b/idea/testData/intentions/nullableBooleanEqualityCheckToElvis/flexible.kt
@@ -0,0 +1,4 @@
+fun foo() {
+ val a = java.lang.Boolean.valueOf("true")
+ if (a == true) {}
+}
\ No newline at end of file
diff --git a/idea/testData/intentions/nullableBooleanEqualityCheckToElvis/flexible.kt.after b/idea/testData/intentions/nullableBooleanEqualityCheckToElvis/flexible.kt.after
new file mode 100644
index 00000000000..e7dc6966133
--- /dev/null
+++ b/idea/testData/intentions/nullableBooleanEqualityCheckToElvis/flexible.kt.after
@@ -0,0 +1,4 @@
+fun foo() {
+ val a = java.lang.Boolean.valueOf("true")
+ if (a ?: false) {}
+}
\ No newline at end of file
diff --git a/idea/testData/intentions/nullableBooleanEqualityCheckToElvis/notEqFalse.kt b/idea/testData/intentions/nullableBooleanEqualityCheckToElvis/notEqFalse.kt
new file mode 100644
index 00000000000..27c05f9c11a
--- /dev/null
+++ b/idea/testData/intentions/nullableBooleanEqualityCheckToElvis/notEqFalse.kt
@@ -0,0 +1,6 @@
+fun foo() {
+ val a: Boolean? = null
+ if (a != false) {
+
+ }
+}
diff --git a/idea/testData/intentions/nullableBooleanEqualityCheckToElvis/notEqFalse.kt.after b/idea/testData/intentions/nullableBooleanEqualityCheckToElvis/notEqFalse.kt.after
new file mode 100644
index 00000000000..e1f61c56844
--- /dev/null
+++ b/idea/testData/intentions/nullableBooleanEqualityCheckToElvis/notEqFalse.kt.after
@@ -0,0 +1,6 @@
+fun foo() {
+ val a: Boolean? = null
+ if (a ?: true) {
+
+ }
+}
diff --git a/idea/testData/intentions/nullableBooleanEqualityCheckToElvis/notEqTrue.kt b/idea/testData/intentions/nullableBooleanEqualityCheckToElvis/notEqTrue.kt
new file mode 100644
index 00000000000..03efa2876a7
--- /dev/null
+++ b/idea/testData/intentions/nullableBooleanEqualityCheckToElvis/notEqTrue.kt
@@ -0,0 +1,6 @@
+fun foo() {
+ val a: Boolean? = null
+ if (a != true) {
+
+ }
+}
diff --git a/idea/testData/intentions/nullableBooleanEqualityCheckToElvis/notEqTrue.kt.after b/idea/testData/intentions/nullableBooleanEqualityCheckToElvis/notEqTrue.kt.after
new file mode 100644
index 00000000000..d2136a2048b
--- /dev/null
+++ b/idea/testData/intentions/nullableBooleanEqualityCheckToElvis/notEqTrue.kt.after
@@ -0,0 +1,6 @@
+fun foo() {
+ val a: Boolean? = null
+ if (!(a ?: false)) {
+
+ }
+}
diff --git a/idea/tests/org/jetbrains/kotlin/idea/codeInsight/InspectionTestGenerated.java b/idea/tests/org/jetbrains/kotlin/idea/codeInsight/InspectionTestGenerated.java
index 672712b26b7..1b071259d52 100644
--- a/idea/tests/org/jetbrains/kotlin/idea/codeInsight/InspectionTestGenerated.java
+++ b/idea/tests/org/jetbrains/kotlin/idea/codeInsight/InspectionTestGenerated.java
@@ -227,6 +227,12 @@ public class InspectionTestGenerated extends AbstractInspectionTest {
doTest(fileName);
}
+ @TestMetadata("nullableBooleanElvis/inspectionData/inspections.test")
+ public void testNullableBooleanElvis_inspectionData_Inspections_test() throws Exception {
+ String fileName = KotlinTestUtils.navigationMetadata("idea/testData/inspections/nullableBooleanElvis/inspectionData/inspections.test");
+ doTest(fileName);
+ }
+
@TestMetadata("overridingDeprecatedMember/inspectionData/inspections.test")
public void testOverridingDeprecatedMember_inspectionData_Inspections_test() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/inspections/overridingDeprecatedMember/inspectionData/inspections.test");
diff --git a/idea/tests/org/jetbrains/kotlin/idea/inspections/LocalInspectionTestGenerated.java b/idea/tests/org/jetbrains/kotlin/idea/inspections/LocalInspectionTestGenerated.java
index de450b941ea..067700e7d90 100644
--- a/idea/tests/org/jetbrains/kotlin/idea/inspections/LocalInspectionTestGenerated.java
+++ b/idea/tests/org/jetbrains/kotlin/idea/inspections/LocalInspectionTestGenerated.java
@@ -147,6 +147,45 @@ public class LocalInspectionTestGenerated extends AbstractLocalInspectionTest {
}
}
+ @TestMetadata("idea/testData/inspectionsLocal/nullableBooleanElvis")
+ @TestDataPath("$PROJECT_ROOT")
+ @RunWith(JUnit3RunnerWithInners.class)
+ public static class NullableBooleanElvis extends AbstractLocalInspectionTest {
+ public void testAllFilesPresentInNullableBooleanElvis() throws Exception {
+ KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/testData/inspectionsLocal/nullableBooleanElvis"), Pattern.compile("^([\\w\\-_]+)\\.kt$"), TargetBackend.ANY, true);
+ }
+
+ @TestMetadata("inIf.kt")
+ public void testInIf() throws Exception {
+ String fileName = KotlinTestUtils.navigationMetadata("idea/testData/inspectionsLocal/nullableBooleanElvis/inIf.kt");
+ doTest(fileName);
+ }
+
+ @TestMetadata("inIf2.kt")
+ public void testInIf2() throws Exception {
+ String fileName = KotlinTestUtils.navigationMetadata("idea/testData/inspectionsLocal/nullableBooleanElvis/inIf2.kt");
+ doTest(fileName);
+ }
+
+ @TestMetadata("inIf3.kt")
+ public void testInIf3() throws Exception {
+ String fileName = KotlinTestUtils.navigationMetadata("idea/testData/inspectionsLocal/nullableBooleanElvis/inIf3.kt");
+ doTest(fileName);
+ }
+
+ @TestMetadata("notInIf.kt")
+ public void testNotInIf() throws Exception {
+ String fileName = KotlinTestUtils.navigationMetadata("idea/testData/inspectionsLocal/nullableBooleanElvis/notInIf.kt");
+ doTest(fileName);
+ }
+
+ @TestMetadata("notInIfWithTrue.kt")
+ public void testNotInIfWithTrue() throws Exception {
+ String fileName = KotlinTestUtils.navigationMetadata("idea/testData/inspectionsLocal/nullableBooleanElvis/notInIfWithTrue.kt");
+ doTest(fileName);
+ }
+ }
+
@TestMetadata("idea/testData/inspectionsLocal/removeToStringInStringTemplate")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)
diff --git a/idea/tests/org/jetbrains/kotlin/idea/intentions/IntentionTestGenerated.java b/idea/tests/org/jetbrains/kotlin/idea/intentions/IntentionTestGenerated.java
index 0f982eeb5e9..2f951911a8e 100644
--- a/idea/tests/org/jetbrains/kotlin/idea/intentions/IntentionTestGenerated.java
+++ b/idea/tests/org/jetbrains/kotlin/idea/intentions/IntentionTestGenerated.java
@@ -11868,6 +11868,45 @@ public class IntentionTestGenerated extends AbstractIntentionTest {
}
}
+ @TestMetadata("idea/testData/intentions/nullableBooleanEqualityCheckToElvis")
+ @TestDataPath("$PROJECT_ROOT")
+ @RunWith(JUnit3RunnerWithInners.class)
+ public static class NullableBooleanEqualityCheckToElvis extends AbstractIntentionTest {
+ public void testAllFilesPresentInNullableBooleanEqualityCheckToElvis() throws Exception {
+ KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/testData/intentions/nullableBooleanEqualityCheckToElvis"), Pattern.compile("^([\\w\\-_]+)\\.kt$"), TargetBackend.ANY, true);
+ }
+
+ @TestMetadata("eqFalse.kt")
+ public void testEqFalse() throws Exception {
+ String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/nullableBooleanEqualityCheckToElvis/eqFalse.kt");
+ doTest(fileName);
+ }
+
+ @TestMetadata("eqTrue.kt")
+ public void testEqTrue() throws Exception {
+ String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/nullableBooleanEqualityCheckToElvis/eqTrue.kt");
+ doTest(fileName);
+ }
+
+ @TestMetadata("flexible.kt")
+ public void testFlexible() throws Exception {
+ String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/nullableBooleanEqualityCheckToElvis/flexible.kt");
+ doTest(fileName);
+ }
+
+ @TestMetadata("notEqFalse.kt")
+ public void testNotEqFalse() throws Exception {
+ String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/nullableBooleanEqualityCheckToElvis/notEqFalse.kt");
+ doTest(fileName);
+ }
+
+ @TestMetadata("notEqTrue.kt")
+ public void testNotEqTrue() throws Exception {
+ String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/nullableBooleanEqualityCheckToElvis/notEqTrue.kt");
+ doTest(fileName);
+ }
+ }
+
@TestMetadata("idea/testData/intentions/objectLiteralToLambda")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)