diff --git a/compiler/frontend.java/src/org/jetbrains/kotlin/load/kotlin/KotlinJvmCheckerProvider.kt b/compiler/frontend.java/src/org/jetbrains/kotlin/load/kotlin/KotlinJvmCheckerProvider.kt index ecd7f28db26..4e967fb69ee 100644 --- a/compiler/frontend.java/src/org/jetbrains/kotlin/load/kotlin/KotlinJvmCheckerProvider.kt +++ b/compiler/frontend.java/src/org/jetbrains/kotlin/load/kotlin/KotlinJvmCheckerProvider.kt @@ -268,7 +268,7 @@ public class JavaNullabilityWarningsChecker : AdditionalTypeChecker { DataFlowValueFactory.createDataFlowValue(baseExpression, baseExpressionType, c), c ) { - c.trace.report(Errors.USELESS_ELVIS.on(expression.getOperationReference(), baseExpressionType)) + c.trace.report(Errors.USELESS_ELVIS.on(expression, baseExpressionType)) } } JetTokens.EQEQ, diff --git a/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/Errors.java b/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/Errors.java index 6f0684cd419..527d299c3c3 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/Errors.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/Errors.java @@ -558,7 +558,7 @@ public interface Errors { DiagnosticFactory1 UNNECESSARY_SAFE_CALL = DiagnosticFactory1.create(WARNING); DiagnosticFactory1 UNNECESSARY_NOT_NULL_ASSERTION = DiagnosticFactory1.create(WARNING); - DiagnosticFactory1 USELESS_ELVIS = DiagnosticFactory1.create(WARNING); + DiagnosticFactory1 USELESS_ELVIS = DiagnosticFactory1.create(WARNING, PositioningStrategies.USELESS_ELVIS); // Compile-time values @@ -688,7 +688,7 @@ public interface Errors { INVISIBLE_MEMBER, INVISIBLE_MEMBER_FROM_INLINE, INVISIBLE_REFERENCE, INVISIBLE_SETTER); ImmutableSet> UNUSED_ELEMENT_DIAGNOSTICS = ImmutableSet.of( UNUSED_VARIABLE, UNUSED_PARAMETER, ASSIGNED_BUT_NEVER_ACCESSED_VARIABLE, VARIABLE_WITH_REDUNDANT_INITIALIZER, - UNUSED_FUNCTION_LITERAL, USELESS_CAST, UNUSED_VALUE); + UNUSED_FUNCTION_LITERAL, USELESS_CAST, UNUSED_VALUE, USELESS_ELVIS); ImmutableSet> TYPE_INFERENCE_ERRORS = ImmutableSet.of( TYPE_INFERENCE_NO_INFORMATION_FOR_PARAMETER, TYPE_INFERENCE_CONFLICTING_SUBSTITUTIONS, TYPE_INFERENCE_TYPE_CONSTRUCTOR_MISMATCH, TYPE_INFERENCE_UPPER_BOUND_VIOLATED, TYPE_INFERENCE_EXPECTED_TYPE_MISMATCH); diff --git a/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/PositioningStrategies.kt b/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/PositioningStrategies.kt index 9380a554768..058f602ad83 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/PositioningStrategies.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/PositioningStrategies.kt @@ -447,4 +447,10 @@ public object PositioningStrategies { return listOf(TextRange(element.getLeft()!!.startOffset, element.getOperationReference().endOffset)) } } + + public val USELESS_ELVIS: PositioningStrategy = object: PositioningStrategy() { + override fun mark(element: JetBinaryExpression): List { + return listOf(TextRange(element.getOperationReference().startOffset, element.endOffset)) + } + } } diff --git a/compiler/frontend/src/org/jetbrains/kotlin/types/expressions/BasicExpressionTypingVisitor.java b/compiler/frontend/src/org/jetbrains/kotlin/types/expressions/BasicExpressionTypingVisitor.java index 4d44f934821..ba8fb580732 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/types/expressions/BasicExpressionTypingVisitor.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/types/expressions/BasicExpressionTypingVisitor.java @@ -1276,7 +1276,7 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor { assert leftTypeInfo != null : "Left expression was not processed: " + expression; JetType leftType = leftTypeInfo.getType(); if (leftType != null && isKnownToBeNotNull(left, leftType, context)) { - context.trace.report(USELESS_ELVIS.on(left, leftType)); + context.trace.report(USELESS_ELVIS.on(expression, leftType)); } JetTypeInfo rightTypeInfo = BindingContextUtils.getRecordedTypeInfo(right, context.trace.getBindingContext()); assert rightTypeInfo != null : "Right expression was not processed: " + expression; diff --git a/compiler/testData/diagnostics/tests/controlFlowAnalysis/deadCode/deadCodeInBinaryExpressions.kt b/compiler/testData/diagnostics/tests/controlFlowAnalysis/deadCode/deadCodeInBinaryExpressions.kt index 42b4727af76..35a6a6393a9 100644 --- a/compiler/testData/diagnostics/tests/controlFlowAnalysis/deadCode/deadCodeInBinaryExpressions.kt +++ b/compiler/testData/diagnostics/tests/controlFlowAnalysis/deadCode/deadCodeInBinaryExpressions.kt @@ -8,7 +8,7 @@ fun testBinary2() { } fun testElvis1() { - todo() ?: "" + todo() ?: "" } fun testElvis2(s: String?) { diff --git a/compiler/testData/diagnostics/tests/controlFlowAnalysis/deadCode/deadCodeInWhileFromBreak.kt b/compiler/testData/diagnostics/tests/controlFlowAnalysis/deadCode/deadCodeInWhileFromBreak.kt index 978ee032ac0..99e4390cf1b 100644 --- a/compiler/testData/diagnostics/tests/controlFlowAnalysis/deadCode/deadCodeInWhileFromBreak.kt +++ b/compiler/testData/diagnostics/tests/controlFlowAnalysis/deadCode/deadCodeInWhileFromBreak.kt @@ -50,6 +50,6 @@ fun test(arr: Array) { } while (true) { - break ?: null + break ?: null } } diff --git a/compiler/testData/diagnostics/tests/dataFlowInfoTraversal/Elvis.kt b/compiler/testData/diagnostics/tests/dataFlowInfoTraversal/Elvis.kt index 1e62b47c1a6..95478d5add4 100644 --- a/compiler/testData/diagnostics/tests/dataFlowInfoTraversal/Elvis.kt +++ b/compiler/testData/diagnostics/tests/dataFlowInfoTraversal/Elvis.kt @@ -4,6 +4,6 @@ fun foo() { val x: Int? = null bar(x ?: 0) - if (x != null) bar(x ?: x) + if (x != null) bar(x ?: x) bar(x) } \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/nullableTypes/uselessElvis.kt b/compiler/testData/diagnostics/tests/nullableTypes/uselessElvis.kt index 257a5594aed..12e6a1af108 100644 --- a/compiler/testData/diagnostics/tests/nullableTypes/uselessElvis.kt +++ b/compiler/testData/diagnostics/tests/nullableTypes/uselessElvis.kt @@ -5,12 +5,12 @@ fun test1(t: Any?): Any { } fun test2(t: Any?): Any { - return t as T ?: "" + return t as T ?: "" } fun test3(t: Any?): Any { if (t != null) { - return t ?: "" + return t ?: "" } return 1 diff --git a/compiler/testData/diagnostics/tests/platformTypes/nullabilityWarnings/elvis.kt b/compiler/testData/diagnostics/tests/platformTypes/nullabilityWarnings/elvis.kt index cd62522080d..7ec695beb29 100644 --- a/compiler/testData/diagnostics/tests/platformTypes/nullabilityWarnings/elvis.kt +++ b/compiler/testData/diagnostics/tests/platformTypes/nullabilityWarnings/elvis.kt @@ -25,21 +25,21 @@ fun test() { // platform type with no annotation val platformJ = J.staticJ - val v0 = platformNN ?: J() - platformNN ?: J() + val v0 = platformNN ?: J() + platformNN ?: J() platformN ?: J() platformJ ?: J() if (platformNN != null) { - platformNN ?: J() + platformNN ?: J() } if (platformN != null) { - platformN ?: J() + platformN ?: J() } if (platformJ != null) { - platformJ ?: J() + platformJ ?: J() } } diff --git a/compiler/testData/diagnostics/tests/platformTypes/nullabilityWarnings/uselessElvisInCall.kt b/compiler/testData/diagnostics/tests/platformTypes/nullabilityWarnings/uselessElvisInCall.kt index 888940952c7..230514a1596 100644 --- a/compiler/testData/diagnostics/tests/platformTypes/nullabilityWarnings/uselessElvisInCall.kt +++ b/compiler/testData/diagnostics/tests/platformTypes/nullabilityWarnings/uselessElvisInCall.kt @@ -18,10 +18,10 @@ fun test() { // @NotNull platform type val platformNN = J.staticNN - foo(platformNN ?: "") + foo(platformNN ?: "") val bar = Bar() - bar(platformNN ?: "") + bar(platformNN ?: "") } fun foo(a: Any) {} diff --git a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/highlighter/JetPsiChecker.kt b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/highlighter/JetPsiChecker.kt index cd33537b839..a6fb627e03b 100644 --- a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/highlighter/JetPsiChecker.kt +++ b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/highlighter/JetPsiChecker.kt @@ -96,7 +96,7 @@ public open class JetPsiChecker : Annotator, HighlightRangeExtension { assert(diagnostic.getPsiElement() == element) - var textRanges = diagnostic.getTextRanges() + val textRanges = diagnostic.getTextRanges() val factory = diagnostic.getFactory() when (diagnostic.getSeverity()) { Severity.ERROR -> { diff --git a/idea/src/org/jetbrains/kotlin/idea/quickfix/RemoveRightPartOfBinaryExpressionFix.java b/idea/src/org/jetbrains/kotlin/idea/quickfix/RemoveRightPartOfBinaryExpressionFix.java index eb5f034a51d..768926bf027 100644 --- a/idea/src/org/jetbrains/kotlin/idea/quickfix/RemoveRightPartOfBinaryExpressionFix.java +++ b/idea/src/org/jetbrains/kotlin/idea/quickfix/RemoveRightPartOfBinaryExpressionFix.java @@ -85,8 +85,7 @@ public class RemoveRightPartOfBinaryExpressionFix exten return new JetSingleIntentionActionFactory() { @Override public JetIntentionAction createAction(Diagnostic diagnostic) { - JetBinaryExpression expression = QuickFixUtil.getParentElementOfType(diagnostic, JetBinaryExpression.class); - if (expression == null) return null; + JetBinaryExpression expression = (JetBinaryExpression) diagnostic.getPsiElement(); return new RemoveRightPartOfBinaryExpressionFix(expression, JetBundle.message("remove.elvis.operator")); } }; diff --git a/idea/testData/quickfix/expressions/uselessElvis.kt b/idea/testData/quickfix/expressions/uselessElvis.kt index 3f046028f6c..8582c561c5a 100644 --- a/idea/testData/quickfix/expressions/uselessElvis.kt +++ b/idea/testData/quickfix/expressions/uselessElvis.kt @@ -1,4 +1,4 @@ // "Remove elvis operator" "true" fun foo(a: String) { - val b : String = a ?: "s" + val b : String = a ?: "s" } diff --git a/idea/testData/quickfix/expressions/uselessElvis.kt.after b/idea/testData/quickfix/expressions/uselessElvis.kt.after index e76b3b56841..584775cddcd 100644 --- a/idea/testData/quickfix/expressions/uselessElvis.kt.after +++ b/idea/testData/quickfix/expressions/uselessElvis.kt.after @@ -1,4 +1,4 @@ // "Remove elvis operator" "true" fun foo(a: String) { - val b : String = a + val b : String = a }