diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/cfg/JetFlowInformationProvider.java b/compiler/frontend/src/org/jetbrains/jet/lang/cfg/JetFlowInformationProvider.java index 5375b8e65c2..101d9fec9bc 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/cfg/JetFlowInformationProvider.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/cfg/JetFlowInformationProvider.java @@ -124,9 +124,9 @@ public class JetFlowInformationProvider { } public void checkFunction(@Nullable JetType expectedReturnType) { - Set unreachableElements = collectUnreachableCode(); - checkDefiniteReturn(expectedReturnType != null ? expectedReturnType : NO_EXPECTED_TYPE, unreachableElements); - reportUnreachableCode(unreachableElements); + UnreachableCode unreachableCode = collectUnreachableCode(); + checkDefiniteReturn(expectedReturnType != null ? expectedReturnType : NO_EXPECTED_TYPE, unreachableCode); + reportUnreachableCode(unreachableCode); markTailCalls(); } @@ -209,7 +209,7 @@ public class JetFlowInformationProvider { } } - public void checkDefiniteReturn(final @NotNull JetType expectedReturnType, @NotNull final Set unreachableElements) { + public void checkDefiniteReturn(final @NotNull JetType expectedReturnType, @NotNull final UnreachableCode unreachableCode) { assert subroutine instanceof JetDeclarationWithBody; JetDeclarationWithBody function = (JetDeclarationWithBody) subroutine; @@ -236,7 +236,7 @@ public class JetFlowInformationProvider { if (blockBody && !noExpectedType(expectedReturnType) && !KotlinBuiltIns.getInstance().isUnit(expectedReturnType) - && !unreachableElements.contains(element)) { + && !unreachableCode.getElements().contains(element)) { noReturnError[0] = true; } } @@ -247,19 +247,17 @@ public class JetFlowInformationProvider { } } - private void reportUnreachableCode(@NotNull Set unreachableElements) { - // This is needed in order to highlight only '1 < 2' and not '1', '<' and '2' as well - Set rootUnreachableElements = JetPsiUtil.findRootExpressions(unreachableElements); - - for (JetElement element : rootUnreachableElements) { - trace.report(UNREACHABLE_CODE.on(element)); + private void reportUnreachableCode(@NotNull UnreachableCode unreachableCode) { + for (JetElement element : unreachableCode.getElements()) { + trace.report(UNREACHABLE_CODE.on(element, unreachableCode.getUnreachableTextRanges(element))); } } - private Set collectUnreachableCode() { + @NotNull + private UnreachableCode collectUnreachableCode() { + Set reachableElements = Sets.newHashSet(); Set unreachableElements = Sets.newHashSet(); - for (Instruction instruction : pseudocode.getDeadInstructions()) { - if (!PseudocodeUtil.isDeadInAllCopies(instruction)) continue; + for (Instruction instruction : pseudocode.getInstructionsIncludingDeadCode()) { if (!(instruction instanceof JetElementInstruction) || instruction instanceof LoadUnitValueInstruction || instruction instanceof MergeInstruction @@ -275,9 +273,14 @@ public class JetFlowInformationProvider { if (!isJumpElement) continue; } - unreachableElements.add(element); + if (PseudocodeUtil.isDeadInAllCopies(instruction)) { + unreachableElements.add(element); + } + else { + reachableElements.add(element); + } } - return unreachableElements; + return new UnreachableCodeImpl(reachableElements, unreachableElements); } //////////////////////////////////////////////////////////////////////////////// diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/cfg/UnreachableCode.kt b/compiler/frontend/src/org/jetbrains/jet/lang/cfg/UnreachableCode.kt new file mode 100644 index 00000000000..b748efdf36a --- /dev/null +++ b/compiler/frontend/src/org/jetbrains/jet/lang/cfg/UnreachableCode.kt @@ -0,0 +1,119 @@ +/* + * Copyright 2010-2014 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.jet.lang.cfg + +import org.jetbrains.jet.lang.psi.JetElement +import com.intellij.openapi.util.TextRange +import java.util.HashSet +import org.jetbrains.jet.lang.psi.JetPsiUtil +import com.intellij.psi.PsiElement +import com.intellij.psi.PsiElementVisitor +import com.intellij.psi.PsiWhiteSpace +import java.util.ArrayList +import org.jetbrains.jet.lexer.JetTokens +import com.intellij.psi.util.PsiTreeUtil + +trait UnreachableCode { + val elements: Set + fun getUnreachableTextRanges(element: JetElement): List +} + +class UnreachableCodeImpl( + private val reachableElements: Set, + private val unreachableElements: Set +) : UnreachableCode { + + // This is needed in order to highlight only '1 < 2' and not '1', '<' and '2' as well + override val elements = JetPsiUtil.findRootExpressions(unreachableElements) + + override fun getUnreachableTextRanges(element: JetElement): List { + return if (element.hasChildrenInSet(reachableElements)) { + element.getLeavesOrReachableChildren().removeReachableElementsWithMeaninglessSiblings().mergeAdjacentTextRanges() + } + else { + listOf(element.getTextRange()!!) + } + } + + private fun JetElement.hasChildrenInSet(set: Set): Boolean { + return PsiTreeUtil.collectElements(this) { it != this }.any { it in set } + } + + private fun JetElement.getLeavesOrReachableChildren(): List { + val children = ArrayList() + acceptChildren(object : PsiElementVisitor() { + override fun visitElement(element: PsiElement) { + val isReachable = element is JetElement && reachableElements.contains(element) && !element.hasChildrenInSet(unreachableElements) + if (isReachable || element.getChildren().size == 0) { + children.add(element) + } + else { + element.acceptChildren(this) + } + } + }) + return children + } + + fun List.removeReachableElementsWithMeaninglessSiblings(): List { + fun PsiElement.isMeaningless() = this is PsiWhiteSpace || this.getNode()?.getElementType() == JetTokens.COMMA + + val childrenToRemove = HashSet() + fun collectSiblingsIfMeaningless(elementIndex: Int, direction: Int) { + val index = elementIndex + direction + if (index !in 0..(size() - 1)) return + + val element = this[index] + if (element.isMeaningless()) { + childrenToRemove.add(element) + collectSiblingsIfMeaningless(index, direction) + } + } + for ((index, element) in this.withIndices()) { + if (reachableElements.contains(element)) { + childrenToRemove.add(element) + collectSiblingsIfMeaningless(index, -1) + collectSiblingsIfMeaningless(index, 1) + } + } + return this.filter { it !in childrenToRemove } + } + + + private fun List.mergeAdjacentTextRanges(): List { + val result = ArrayList() + val lastRange = fold(null: TextRange?) { + currentTextRange, element -> + + val elementRange = element.getTextRange()!! + if (currentTextRange == null) { + elementRange + } + else if (currentTextRange.getEndOffset() == elementRange.getStartOffset()) { + currentTextRange.union(elementRange) + } + else { + result.add(currentTextRange) + elementRange + } + } + if (lastRange != null) { + result.add(lastRange) + } + return result + } +} diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/diagnostics/AbstractDiagnostic.java b/compiler/frontend/src/org/jetbrains/jet/lang/diagnostics/AbstractDiagnostic.java index 598049b6c5a..8616757045f 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/diagnostics/AbstractDiagnostic.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/diagnostics/AbstractDiagnostic.java @@ -27,6 +27,7 @@ public abstract class AbstractDiagnostic implements Parame private final E psiElement; private final DiagnosticFactoryWithPsiElement factory; private final Severity severity; + private List textRanges; public AbstractDiagnostic(@NotNull E psiElement, @NotNull DiagnosticFactoryWithPsiElement factory, @@ -63,6 +64,9 @@ public abstract class AbstractDiagnostic implements Parame @Override @NotNull public List getTextRanges() { + if (textRanges != null) { + return textRanges; + } return getFactory().getTextRanges(this); } @@ -71,4 +75,10 @@ public abstract class AbstractDiagnostic implements Parame if (!getFactory().isValid(this)) return false; return true; } + + @NotNull + public Diagnostic setTextRanges(@NotNull List textRanges) { + this.textRanges = textRanges; + return this; + } } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/diagnostics/DiagnosticFactoryWithPsiElement.java b/compiler/frontend/src/org/jetbrains/jet/lang/diagnostics/DiagnosticFactoryWithPsiElement.java index 5a01175740d..a015899f523 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/diagnostics/DiagnosticFactoryWithPsiElement.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/diagnostics/DiagnosticFactoryWithPsiElement.java @@ -30,7 +30,7 @@ public abstract class DiagnosticFactoryWithPsiElement getTextRanges(ParametrizedDiagnostic diagnostic) { - return positioningStrategy.mark(diagnostic.getPsiElement()); + return positioningStrategy.markDiagnostic(diagnostic); } protected boolean isValid(ParametrizedDiagnostic diagnostic) { diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/diagnostics/Errors.java b/compiler/frontend/src/org/jetbrains/jet/lang/diagnostics/Errors.java index 3d0df53cdf9..1620da3f528 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/diagnostics/Errors.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/diagnostics/Errors.java @@ -17,9 +17,11 @@ package org.jetbrains.jet.lang.diagnostics; import com.google.common.collect.ImmutableSet; +import com.intellij.openapi.util.TextRange; import com.intellij.psi.PsiElement; import com.intellij.psi.PsiNameIdentifierOwner; import com.intellij.psi.impl.source.tree.LeafPsiElement; +import kotlin.Function1; import org.jetbrains.annotations.NotNull; import org.jetbrains.jet.lang.descriptors.*; import org.jetbrains.jet.lang.psi.*; @@ -446,7 +448,13 @@ public interface Errors { // Control flow / Data flow - DiagnosticFactory0 UNREACHABLE_CODE = DiagnosticFactory0.create(WARNING); + DiagnosticFactory1> UNREACHABLE_CODE = DiagnosticFactory1.create( + WARNING, PositioningStrategies.markTextRangesFromDiagnostic(new Function1>() { + @Override + public List invoke(Diagnostic diagnostic) { + return UNREACHABLE_CODE.cast(diagnostic).getA(); + } + })); DiagnosticFactory0 VARIABLE_WITH_NO_TYPE_NO_INITIALIZER = DiagnosticFactory0.create(ERROR, NAME_IDENTIFIER); diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/diagnostics/PositioningStrategies.java b/compiler/frontend/src/org/jetbrains/jet/lang/diagnostics/PositioningStrategies.java index b472dd4169c..a0e5d07199c 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/diagnostics/PositioningStrategies.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/diagnostics/PositioningStrategies.java @@ -23,6 +23,7 @@ import com.intellij.lang.ASTNode; import com.intellij.openapi.util.TextRange; import com.intellij.psi.PsiElement; import com.intellij.psi.PsiNameIdentifierOwner; +import kotlin.Function1; import org.jetbrains.annotations.NotNull; import org.jetbrains.jet.JetNodeTypes; import org.jetbrains.jet.lang.psi.*; @@ -527,6 +528,18 @@ public class PositioningStrategies { } }; + public static PositioningStrategy markTextRangesFromDiagnostic( + @NotNull final Function1> getTextRanges + ) { + return new PositioningStrategy() { + @NotNull + @Override + public List markDiagnostic(@NotNull ParametrizedDiagnostic diagnostic) { + return getTextRanges.invoke(diagnostic); + } + }; + } + private PositioningStrategies() { } } \ No newline at end of file diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/diagnostics/PositioningStrategy.java b/compiler/frontend/src/org/jetbrains/jet/lang/diagnostics/PositioningStrategy.java index a149ef32b69..16486f78e7a 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/diagnostics/PositioningStrategy.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/diagnostics/PositioningStrategy.java @@ -27,7 +27,12 @@ import java.util.List; public class PositioningStrategy { @NotNull - public List mark(@NotNull E element) { + public List markDiagnostic(@NotNull ParametrizedDiagnostic diagnostic) { + return mark(diagnostic.getPsiElement()); + } + + @NotNull + protected List mark(@NotNull E element) { return markElement(element); } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/diagnostics/rendering/DefaultErrorMessages.java b/compiler/frontend/src/org/jetbrains/jet/lang/diagnostics/rendering/DefaultErrorMessages.java index deace52941b..bb804680559 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/diagnostics/rendering/DefaultErrorMessages.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/diagnostics/rendering/DefaultErrorMessages.java @@ -212,7 +212,7 @@ public class DefaultErrorMessages { MAP.put(INITIALIZATION_USING_BACKING_FIELD_OPEN_SETTER, "Setter of this property can be overridden, so initialization using backing field required", NAME); - MAP.put(UNREACHABLE_CODE, "Unreachable code"); + MAP.put(UNREACHABLE_CODE, "Unreachable code", TO_STRING); MAP.put(MANY_CLASS_OBJECTS, "Only one class object is allowed per class"); MAP.put(CLASS_OBJECT_NOT_ALLOWED, "A class object is not allowed here"); diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/BasicExpressionTypingVisitor.java b/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/BasicExpressionTypingVisitor.java index b15e9a82b6a..71b008af17d 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/BasicExpressionTypingVisitor.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/BasicExpressionTypingVisitor.java @@ -661,7 +661,7 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor { JetType result; if (operationType == JetTokens.PLUSPLUS || operationType == JetTokens.MINUSMINUS) { assert returnType != null : "returnType is null for " + resolutionResults.getResultingDescriptor(); - if (JetTypeChecker.INSTANCE.isSubtypeOf(returnType, KotlinBuiltIns.getInstance().getUnitType())) { + if (KotlinBuiltIns.getInstance().isUnit(returnType)) { result = ErrorUtils.createErrorType(KotlinBuiltIns.getInstance().getUnit().getName().asString()); context.trace.report(INC_DEC_SHOULD_NOT_RETURN_UNIT.on(operationSign)); } diff --git a/compiler/testData/diagnostics/tests/FunctionReturnTypes.kt b/compiler/testData/diagnostics/tests/FunctionReturnTypes.kt index a73b71e57f2..d4e0fbdcfcc 100644 --- a/compiler/testData/diagnostics/tests/FunctionReturnTypes.kt +++ b/compiler/testData/diagnostics/tests/FunctionReturnTypes.kt @@ -1,3 +1,5 @@ +// !DIAGNOSTICS: -UNREACHABLE_CODE + fun none() {} fun unitEmptyInfer() {} @@ -51,7 +53,7 @@ fun blockAndAndMismatch1() : Int { return true && false } fun blockAndAndMismatch2() : Int { - (return true) && (return false) + (return true) && (return false) } fun blockAndAndMismatch3() : Int { @@ -61,7 +63,7 @@ fun blockAndAndMismatch4() : Int { return true || false } fun blockAndAndMismatch5() : Int { - (return true) || (return false) + (return true) || (return false) } fun blockReturnValueTypeMatch1() : Int { return if (1 > 2) 1.0 else 2.0 diff --git a/compiler/testData/diagnostics/tests/controlFlowAnalysis/deadCode/commasAndWhitespaces.kt b/compiler/testData/diagnostics/tests/controlFlowAnalysis/deadCode/commasAndWhitespaces.kt new file mode 100644 index 00000000000..a32de3a361c --- /dev/null +++ b/compiler/testData/diagnostics/tests/controlFlowAnalysis/deadCode/commasAndWhitespaces.kt @@ -0,0 +1,12 @@ +// !DIAGNOSTICS: -UNUSED_PARAMETER + +fun testCommasAndWhitespaces() { + fun bar(i: Int, s: String, x: Any) {} + + bar( 1 , todo() , "" ) +} + +fun todo() = throw Exception() + + + diff --git a/compiler/testData/diagnostics/tests/controlFlowAnalysis/deadCode/deadCallInInvokeCall.kt b/compiler/testData/diagnostics/tests/controlFlowAnalysis/deadCode/deadCallInInvokeCall.kt new file mode 100644 index 00000000000..9285b7122f1 --- /dev/null +++ b/compiler/testData/diagnostics/tests/controlFlowAnalysis/deadCode/deadCallInInvokeCall.kt @@ -0,0 +1,11 @@ +fun testInvoke() { + fun Nothing.invoke() = this + todo()() +} + +fun testInvokeWithLambda() { + fun Nothing.invoke(i: Int, f: () -> Int) = f + todo()(1){ 42 } +} + +fun todo() = throw Exception() \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/controlFlowAnalysis/deadCode/deadCallInReceiver.kt b/compiler/testData/diagnostics/tests/controlFlowAnalysis/deadCode/deadCallInReceiver.kt new file mode 100644 index 00000000000..bce9404313e --- /dev/null +++ b/compiler/testData/diagnostics/tests/controlFlowAnalysis/deadCode/deadCallInReceiver.kt @@ -0,0 +1,11 @@ +fun test11() { + fun Any.bar(i: Int) {} + todo().bar(1) +} + +fun test12() { + fun Any.bar(i: Int) {} + todo()?.bar(1) +} + +fun todo() = throw Exception() \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/UnreachableCode.kt b/compiler/testData/diagnostics/tests/controlFlowAnalysis/deadCode/deadCodeDifferentExamples.kt similarity index 84% rename from compiler/testData/diagnostics/tests/UnreachableCode.kt rename to compiler/testData/diagnostics/tests/controlFlowAnalysis/deadCode/deadCodeDifferentExamples.kt index e79c920e843..627bbd0fd81 100644 --- a/compiler/testData/diagnostics/tests/UnreachableCode.kt +++ b/compiler/testData/diagnostics/tests/controlFlowAnalysis/deadCode/deadCodeDifferentExamples.kt @@ -1,3 +1,4 @@ +// !DIAGNOSTICS: -UNUSED_PARAMETER -UNUSED_EXPRESSION fun t1() : Int{ return 0 @@ -46,7 +47,7 @@ fun t3() : Any { 1 } -fun t4(a : Boolean) : Int { +fun t4(a : Boolean) : Int { do { return 1 } @@ -54,7 +55,7 @@ fun t4(a : Boolean) : Int { 1 } -fun t4break(a : Boolean) : Int { +fun t4break(a : Boolean) : Int { do { break } @@ -109,7 +110,7 @@ fun t7() : Int { 2 } catch (e : Any) { - 2 + 2 } return 1 // this is OK, like in Java } @@ -127,16 +128,16 @@ fun t8() : Int { } fun blockAndAndMismatch() : Boolean { - (return true) || (return false) + (return true) || (return false) return true } fun tf() : Int { - try {return 1} finally{return 1} + try {return 1} finally{return 1} return 1 } -fun failtest(a : Int) : Int { +fun failtest(a : Int) : Int { if (fail() || true) { } @@ -144,8 +145,8 @@ fun failtest(a : Int) : Int { } fun foo(a : Nothing) : Unit { - 1 - a + 1 + a 2 } @@ -161,7 +162,7 @@ fun nullIsNotNothing() : Unit { fail() } -fun returnInWhile(a: Int) { +fun returnInWhile(a: Int) { do {return} while (1 > a) } diff --git a/compiler/testData/diagnostics/tests/controlFlowAnalysis/DeadCode.kt b/compiler/testData/diagnostics/tests/controlFlowAnalysis/deadCode/deadCodeFromDifferentSources.kt similarity index 78% rename from compiler/testData/diagnostics/tests/controlFlowAnalysis/DeadCode.kt rename to compiler/testData/diagnostics/tests/controlFlowAnalysis/deadCode/deadCodeFromDifferentSources.kt index 0cd3fb77b75..63c2571b0ca 100644 --- a/compiler/testData/diagnostics/tests/controlFlowAnalysis/DeadCode.kt +++ b/compiler/testData/diagnostics/tests/controlFlowAnalysis/deadCode/deadCodeFromDifferentSources.kt @@ -1,7 +1,7 @@ package c fun test1() { - val r: Nothing = null!! + val r: Nothing = null!! } fun test2(a: A) { diff --git a/compiler/testData/diagnostics/tests/controlFlowAnalysis/deadCode/deadCodeInArrayAccess.kt b/compiler/testData/diagnostics/tests/controlFlowAnalysis/deadCode/deadCodeInArrayAccess.kt new file mode 100644 index 00000000000..b9109c096c9 --- /dev/null +++ b/compiler/testData/diagnostics/tests/controlFlowAnalysis/deadCode/deadCodeInArrayAccess.kt @@ -0,0 +1,40 @@ +// !DIAGNOSTICS: -UNUSED_PARAMETER + +fun testArrayAccess1(array: Array) { + array[todo()] +} + +fun testArrayAccess2() { + fun Nothing.get(i: Int, s: String) {} + todo()[1, ""] +} + +fun testAraryAccess3() { + fun Nothing.get(n: Nothing) {} + todo()[todo()] +} + +fun testArrayAssignment1(array: Array) { + array[todo()] = 11 +} + +fun testArrayAssignment2(array: Array) { + array[1] = todo() +} + +fun testArrayAssignment3(n: Nothing) { + fun Nothing.set(i: Int, j: Int) {} + n[1] = 2 +} + +fun testArrayAssignment4(n: Nothing) { + fun Nothing.set(i: Int, a: Any) {} + n[1] = todo() +} + +fun testArrayPlusAssign(array: Array) { + fun Any.plusAssign(a: Any) {} + array[1] += todo() +} + +fun todo() = throw Exception() \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/controlFlowAnalysis/deadCode/deadCodeInAssignment.kt b/compiler/testData/diagnostics/tests/controlFlowAnalysis/deadCode/deadCodeInAssignment.kt new file mode 100644 index 00000000000..85e9e23aaf0 --- /dev/null +++ b/compiler/testData/diagnostics/tests/controlFlowAnalysis/deadCode/deadCodeInAssignment.kt @@ -0,0 +1,18 @@ +fun testAssignment() { + var a = 1 + a = todo() +} + +fun testVariableDeclaration() { + val a = todo() +} + +fun testPlusAssign() { + fun Int.plusAssign(i: Int) {} + + var a = 1 + a += todo() +} + + +fun todo() = throw Exception() \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/controlFlowAnalysis/deadCode/deadCodeInBinaryExpressions.kt b/compiler/testData/diagnostics/tests/controlFlowAnalysis/deadCode/deadCodeInBinaryExpressions.kt new file mode 100644 index 00000000000..42b4727af76 --- /dev/null +++ b/compiler/testData/diagnostics/tests/controlFlowAnalysis/deadCode/deadCodeInBinaryExpressions.kt @@ -0,0 +1,39 @@ +fun testBinary1() { + fun Int.times(s: String) {} + + todo() * "" +} +fun testBinary2() { + "1" + todo() +} + +fun testElvis1() { + todo() ?: "" +} + +fun testElvis2(s: String?) { + s ?: todo() + + bar() +} + +fun testAnd1(b: Boolean) { + b && todo() + + bar() +} + +fun testAnd2(b: Boolean) { + todo() && b +} + +fun returnInBinary1(): Boolean { + (return true) && (return false) +} + +fun returnInBinary2(): Boolean { + (return true) || (return false) +} + +fun todo() = throw Exception() +fun bar() {} \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/controlFlowAnalysis/deadCode/deadCodeInCalls.kt b/compiler/testData/diagnostics/tests/controlFlowAnalysis/deadCode/deadCodeInCalls.kt new file mode 100644 index 00000000000..6bc59d6867a --- /dev/null +++ b/compiler/testData/diagnostics/tests/controlFlowAnalysis/deadCode/deadCodeInCalls.kt @@ -0,0 +1,13 @@ +// !DIAGNOSTICS: -UNUSED_PARAMETER + +fun testArgumentInCall() { + fun bar(i: Int, s: String, x: Any) {} + + bar(1, todo(), "") +} + +fun testArgumentInVariableAsFunctionCall(f: (Any) -> Unit) { + f(todo()) +} + +fun todo() = throw Exception() \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/controlFlowAnalysis/deadCode/deadCodeInDeadCode.kt b/compiler/testData/diagnostics/tests/controlFlowAnalysis/deadCode/deadCodeInDeadCode.kt new file mode 100644 index 00000000000..53001d49508 --- /dev/null +++ b/compiler/testData/diagnostics/tests/controlFlowAnalysis/deadCode/deadCodeInDeadCode.kt @@ -0,0 +1,24 @@ +// !DIAGNOSTICS: -UNUSED_PARAMETER + +fun unreachable0() { + return + return todo() +} + +fun unreachable2() { + return + val a = todo() +} + +fun unreachable3() { + return + bar(todo()) +} + +fun unreachable4(array: Array) { + return + array[todo()] +} + +fun bar(a: Any) {} +fun todo() = throw Exception() diff --git a/compiler/testData/diagnostics/tests/controlFlowAnalysis/deadCode/deadCodeInIf.kt b/compiler/testData/diagnostics/tests/controlFlowAnalysis/deadCode/deadCodeInIf.kt new file mode 100644 index 00000000000..283281aecc3 --- /dev/null +++ b/compiler/testData/diagnostics/tests/controlFlowAnalysis/deadCode/deadCodeInIf.kt @@ -0,0 +1,12 @@ +fun testIf() { + if (todo()) 1 else 2 +} + +fun testIf1(b: Boolean) { + if (b) todo() else 1 + + bar() +} + +fun todo() = throw Exception() +fun bar() {} \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/controlFlowAnalysis/deadCode/deadCodeInInnerExpressions.kt b/compiler/testData/diagnostics/tests/controlFlowAnalysis/deadCode/deadCodeInInnerExpressions.kt new file mode 100644 index 00000000000..16f1395f857 --- /dev/null +++ b/compiler/testData/diagnostics/tests/controlFlowAnalysis/deadCode/deadCodeInInnerExpressions.kt @@ -0,0 +1,13 @@ +// !DIAGNOSTICS: -UNUSED_PARAMETER + +fun testCompound() { + fun Nothing.get(i: Int) {} + todo()!![12] +} + +fun testCompound1() { + fun Int.times(s: String): Array = throw Exception() + (todo() * "")[1] +} + +fun todo() = throw Exception() \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/controlFlowAnalysis/deadCode/deadCodeInLocalDeclarations.kt b/compiler/testData/diagnostics/tests/controlFlowAnalysis/deadCode/deadCodeInLocalDeclarations.kt new file mode 100644 index 00000000000..db437307072 --- /dev/null +++ b/compiler/testData/diagnostics/tests/controlFlowAnalysis/deadCode/deadCodeInLocalDeclarations.kt @@ -0,0 +1,36 @@ +// !DIAGNOSTICS: -UNUSED_PARAMETER + +fun testObject() { + object : Foo(todo()) { + fun foo() = 1 + } +} + +fun testObjectExpression() { + val a = object : Foo(todo()) { + fun foo() = 1 + } +} + +fun testObjectExpression1() { + fun bar(i: Int, x: Any) {} + + bar(1, object : Foo(todo()) { + fun foo() = 1 + }) +} + +fun testClassDeclaration() { + class C : Foo(todo()) {} + + bar() +} + +fun testFunctionDefaultArgument() { + fun foo(x: Int = todo()) { bar() } +} + +open class Foo(i: Int) {} + +fun todo() = throw Exception() +fun bar() {} diff --git a/compiler/testData/diagnostics/tests/controlFlowAnalysis/deadCode/deadCodeInLoops.kt b/compiler/testData/diagnostics/tests/controlFlowAnalysis/deadCode/deadCodeInLoops.kt new file mode 100644 index 00000000000..f5f85117c8c --- /dev/null +++ b/compiler/testData/diagnostics/tests/controlFlowAnalysis/deadCode/deadCodeInLoops.kt @@ -0,0 +1,21 @@ +fun testFor() { + fun Nothing.iterator() = (0..1).iterator() + + for (i in todo()) {} +} + +fun testWhile() { + while (todo()) { + } +} + +fun testDoWhile() { + do { + + } while(todo()) + + bar() +} + +fun todo() = throw Exception() +fun bar() {} \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/controlFlowAnalysis/deadCode/deadCodeInReturn.kt b/compiler/testData/diagnostics/tests/controlFlowAnalysis/deadCode/deadCodeInReturn.kt new file mode 100644 index 00000000000..d8574db97a2 --- /dev/null +++ b/compiler/testData/diagnostics/tests/controlFlowAnalysis/deadCode/deadCodeInReturn.kt @@ -0,0 +1,5 @@ +fun testReturn() { + return todo() +} + +fun todo() = throw Exception() \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/controlFlowAnalysis/deadCode/deadCodeInUnaryExpr.kt b/compiler/testData/diagnostics/tests/controlFlowAnalysis/deadCode/deadCodeInUnaryExpr.kt new file mode 100644 index 00000000000..1d158e012d2 --- /dev/null +++ b/compiler/testData/diagnostics/tests/controlFlowAnalysis/deadCode/deadCodeInUnaryExpr.kt @@ -0,0 +1,15 @@ +fun testPrefix() { + fun Any.not() {} + !todo() +} + +fun testPostfixWithCall(n: Nothing) { + fun Nothing.inc(): Nothing = this + n++ +} + +fun testPostfixSpecial() { + todo()!! +} + +fun todo() = throw Exception() \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/controlFlowAnalysis/unreachableCode.kt b/compiler/testData/diagnostics/tests/controlFlowAnalysis/deadCode/deadCodeInWhileFromBreak.kt similarity index 68% rename from compiler/testData/diagnostics/tests/controlFlowAnalysis/unreachableCode.kt rename to compiler/testData/diagnostics/tests/controlFlowAnalysis/deadCode/deadCodeInWhileFromBreak.kt index 431865396f2..978ee032ac0 100644 --- a/compiler/testData/diagnostics/tests/controlFlowAnalysis/unreachableCode.kt +++ b/compiler/testData/diagnostics/tests/controlFlowAnalysis/deadCode/deadCodeInWhileFromBreak.kt @@ -3,20 +3,20 @@ fun bar(a: Any, b: Any) {} fun test(arr: Array) { while (true) { - foo(break) + foo(break) } while (true) { - bar(arr, break) + bar(arr, break) } while (true) { - arr[break] + arr[break] } while (true) { - arr[1] = break + arr[1] = break } while (true) { @@ -32,7 +32,7 @@ fun test(arr: Array) { while (true) { var x = 1 - x = break + x = break } // TODO: bug, should be fixed in CFA @@ -50,6 +50,6 @@ fun test(arr: Array) { } while (true) { - break ?: null + break ?: null } } diff --git a/compiler/testData/diagnostics/tests/controlFlowAnalysis/kt2585_1.kt b/compiler/testData/diagnostics/tests/controlFlowAnalysis/deadCode/kt2585_1.kt similarity index 80% rename from compiler/testData/diagnostics/tests/controlFlowAnalysis/kt2585_1.kt rename to compiler/testData/diagnostics/tests/controlFlowAnalysis/deadCode/kt2585_1.kt index 185066d307b..2bd2e6bd6c6 100644 --- a/compiler/testData/diagnostics/tests/controlFlowAnalysis/kt2585_1.kt +++ b/compiler/testData/diagnostics/tests/controlFlowAnalysis/deadCode/kt2585_1.kt @@ -2,7 +2,7 @@ fun foo(x: String): String { try { - throw RuntimeException() + throw RuntimeException() } finally { try { } catch (e: Exception) { diff --git a/compiler/testData/diagnostics/tests/controlFlowAnalysis/kt2585_2.kt b/compiler/testData/diagnostics/tests/controlFlowAnalysis/deadCode/kt2585_2.kt similarity index 88% rename from compiler/testData/diagnostics/tests/controlFlowAnalysis/kt2585_2.kt rename to compiler/testData/diagnostics/tests/controlFlowAnalysis/deadCode/kt2585_2.kt index 8b6d9f6ed9a..638e2fe6759 100644 --- a/compiler/testData/diagnostics/tests/controlFlowAnalysis/kt2585_2.kt +++ b/compiler/testData/diagnostics/tests/controlFlowAnalysis/deadCode/kt2585_2.kt @@ -2,7 +2,7 @@ fun foo() { try { - throw RuntimeException() + throw RuntimeException() } catch (e: Exception) { return // <- Wrong UNREACHABLE_CODE } finally { diff --git a/compiler/testData/diagnostics/tests/controlFlowAnalysis/kt2585_3.kt b/compiler/testData/diagnostics/tests/controlFlowAnalysis/deadCode/kt2585_3.kt similarity index 78% rename from compiler/testData/diagnostics/tests/controlFlowAnalysis/kt2585_3.kt rename to compiler/testData/diagnostics/tests/controlFlowAnalysis/deadCode/kt2585_3.kt index f2f917ceda4..b2b68a84a96 100644 --- a/compiler/testData/diagnostics/tests/controlFlowAnalysis/kt2585_3.kt +++ b/compiler/testData/diagnostics/tests/controlFlowAnalysis/deadCode/kt2585_3.kt @@ -2,7 +2,7 @@ fun foo(x: String): String { try { - throw RuntimeException() //should be marked as unreachable, but is not + throw RuntimeException() //should be marked as unreachable, but is not } finally { throw NullPointerException() } diff --git a/compiler/testData/diagnostics/tests/controlStructures/kt770.kt351.kt735_StatementType.kt b/compiler/testData/diagnostics/tests/controlStructures/kt770.kt351.kt735_StatementType.kt index 7f5528485b6..0b4e3efab96 100644 --- a/compiler/testData/diagnostics/tests/controlStructures/kt770.kt351.kt735_StatementType.kt +++ b/compiler/testData/diagnostics/tests/controlStructures/kt770.kt351.kt735_StatementType.kt @@ -1,3 +1,4 @@ +// !DIAGNOSTICS: -UNREACHABLE_CODE package kt770_351_735 @@ -120,9 +121,9 @@ fun testStatementInExpressionContext() { val a1: Unit = z = 334 val f = for (i in 1..10) {} if (true) return z = 34 - return while (true) {} + return while (true) {} } fun testStatementInExpressionContext2() { - val a2: Unit = while(true) {} + val a2: Unit = while(true) {} } \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/controlStructures/tryReturnType.kt b/compiler/testData/diagnostics/tests/controlStructures/tryReturnType.kt index a61bf21605b..58f53253516 100644 --- a/compiler/testData/diagnostics/tests/controlStructures/tryReturnType.kt +++ b/compiler/testData/diagnostics/tests/controlStructures/tryReturnType.kt @@ -5,7 +5,7 @@ fun foo() : Int { doSmth() } catch (e: Exception) { - return "" + return "" } finally { return "" diff --git a/compiler/testData/diagnostics/tests/inference/regressions/kt2445.kt b/compiler/testData/diagnostics/tests/inference/regressions/kt2445.kt index 34eb3099f80..2f9e0da3fab 100644 --- a/compiler/testData/diagnostics/tests/inference/regressions/kt2445.kt +++ b/compiler/testData/diagnostics/tests/inference/regressions/kt2445.kt @@ -1,3 +1,4 @@ +// !DIAGNOSTICS: -UNREACHABLE_CODE //KT-2445 Calling method with function with generic parameter causes compile-time exception package a @@ -7,4 +8,4 @@ fun main(args: Array) { } } -fun test(callback: (R) -> Unit):Unit = callback(null!!) \ No newline at end of file +fun test(callback: (R) -> Unit):Unit = callback(null!!) \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/inference/regressions/kt2838.kt b/compiler/testData/diagnostics/tests/inference/regressions/kt2838.kt index 33518f5f228..23ff0757a4b 100644 --- a/compiler/testData/diagnostics/tests/inference/regressions/kt2838.kt +++ b/compiler/testData/diagnostics/tests/inference/regressions/kt2838.kt @@ -1,3 +1,4 @@ +// !DIAGNOSTICS: -UNREACHABLE_CODE //KT-2838 Type inference failed on passing null as a nullable argument package a @@ -9,9 +10,9 @@ fun test(a: Int) { bar(a, null) } fun test1(a: Int) { - foo(a, throw Exception()) + foo(a, throw Exception()) } fun test2(a: Int) { - bar(a, throw Exception()) + bar(a, throw Exception()) } \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/regressions/kt58.kt b/compiler/testData/diagnostics/tests/regressions/kt58.kt index 665fa7ad48e..9ed3897e281 100644 --- a/compiler/testData/diagnostics/tests/regressions/kt58.kt +++ b/compiler/testData/diagnostics/tests/regressions/kt58.kt @@ -17,7 +17,7 @@ fun lock(lock : Lock, body : () -> T) : T { //more tests fun t1() : Int { try { - return 1 + return 1 } finally { return 2 diff --git a/compiler/tests/org/jetbrains/jet/checkers/JetDiagnosticsTestGenerated.java b/compiler/tests/org/jetbrains/jet/checkers/JetDiagnosticsTestGenerated.java index 8d9b77441ed..789dbd81b1e 100644 --- a/compiler/tests/org/jetbrains/jet/checkers/JetDiagnosticsTestGenerated.java +++ b/compiler/tests/org/jetbrains/jet/checkers/JetDiagnosticsTestGenerated.java @@ -469,11 +469,6 @@ public class JetDiagnosticsTestGenerated extends AbstractJetDiagnosticsTest { doTest("compiler/testData/diagnostics/tests/UnitValue.kt"); } - @TestMetadata("UnreachableCode.kt") - public void testUnreachableCode() throws Exception { - doTest("compiler/testData/diagnostics/tests/UnreachableCode.kt"); - } - @TestMetadata("Unresolved.kt") public void testUnresolved() throws Exception { doTest("compiler/testData/diagnostics/tests/Unresolved.kt"); @@ -1239,7 +1234,7 @@ public class JetDiagnosticsTestGenerated extends AbstractJetDiagnosticsTest { } @TestMetadata("compiler/testData/diagnostics/tests/controlFlowAnalysis") - @InnerTestClasses({ControlFlowAnalysis.DefiniteReturn.class}) + @InnerTestClasses({ControlFlowAnalysis.DeadCode.class, ControlFlowAnalysis.DefiniteReturn.class}) public static class ControlFlowAnalysis extends AbstractJetDiagnosticsTest { public void testAllFilesPresentInControlFlowAnalysis() throws Exception { JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.TestsPackage", new File("compiler/testData/diagnostics/tests/controlFlowAnalysis"), Pattern.compile("^(.+)\\.kt$"), true); @@ -1260,11 +1255,6 @@ public class JetDiagnosticsTestGenerated extends AbstractJetDiagnosticsTest { doTest("compiler/testData/diagnostics/tests/controlFlowAnalysis/checkPropertyAccessor.kt"); } - @TestMetadata("DeadCode.kt") - public void testDeadCode() throws Exception { - doTest("compiler/testData/diagnostics/tests/controlFlowAnalysis/DeadCode.kt"); - } - @TestMetadata("definiteReturnInWhen.kt") public void testDefiniteReturnInWhen() throws Exception { doTest("compiler/testData/diagnostics/tests/controlFlowAnalysis/definiteReturnInWhen.kt"); @@ -1340,21 +1330,6 @@ public class JetDiagnosticsTestGenerated extends AbstractJetDiagnosticsTest { doTest("compiler/testData/diagnostics/tests/controlFlowAnalysis/kt2369.kt"); } - @TestMetadata("kt2585_1.kt") - public void testKt2585_1() throws Exception { - doTest("compiler/testData/diagnostics/tests/controlFlowAnalysis/kt2585_1.kt"); - } - - @TestMetadata("kt2585_2.kt") - public void testKt2585_2() throws Exception { - doTest("compiler/testData/diagnostics/tests/controlFlowAnalysis/kt2585_2.kt"); - } - - @TestMetadata("kt2585_3.kt") - public void testKt2585_3() throws Exception { - doTest("compiler/testData/diagnostics/tests/controlFlowAnalysis/kt2585_3.kt"); - } - @TestMetadata("kt2845.kt") public void testKt2845() throws Exception { doTest("compiler/testData/diagnostics/tests/controlFlowAnalysis/kt2845.kt"); @@ -1455,16 +1430,119 @@ public class JetDiagnosticsTestGenerated extends AbstractJetDiagnosticsTest { doTest("compiler/testData/diagnostics/tests/controlFlowAnalysis/UninitializedOrReassignedVariables.kt"); } - @TestMetadata("unreachableCode.kt") - public void testUnreachableCode() throws Exception { - doTest("compiler/testData/diagnostics/tests/controlFlowAnalysis/unreachableCode.kt"); - } - @TestMetadata("varInitializationInIfInCycle.kt") public void testVarInitializationInIfInCycle() throws Exception { doTest("compiler/testData/diagnostics/tests/controlFlowAnalysis/varInitializationInIfInCycle.kt"); } + @TestMetadata("compiler/testData/diagnostics/tests/controlFlowAnalysis/deadCode") + public static class DeadCode extends AbstractJetDiagnosticsTest { + public void testAllFilesPresentInDeadCode() throws Exception { + JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.TestsPackage", new File("compiler/testData/diagnostics/tests/controlFlowAnalysis/deadCode"), Pattern.compile("^(.+)\\.kt$"), true); + } + + @TestMetadata("commasAndWhitespaces.kt") + public void testCommasAndWhitespaces() throws Exception { + doTest("compiler/testData/diagnostics/tests/controlFlowAnalysis/deadCode/commasAndWhitespaces.kt"); + } + + @TestMetadata("deadCallInInvokeCall.kt") + public void testDeadCallInInvokeCall() throws Exception { + doTest("compiler/testData/diagnostics/tests/controlFlowAnalysis/deadCode/deadCallInInvokeCall.kt"); + } + + @TestMetadata("deadCallInReceiver.kt") + public void testDeadCallInReceiver() throws Exception { + doTest("compiler/testData/diagnostics/tests/controlFlowAnalysis/deadCode/deadCallInReceiver.kt"); + } + + @TestMetadata("deadCodeDifferentExamples.kt") + public void testDeadCodeDifferentExamples() throws Exception { + doTest("compiler/testData/diagnostics/tests/controlFlowAnalysis/deadCode/deadCodeDifferentExamples.kt"); + } + + @TestMetadata("deadCodeFromDifferentSources.kt") + public void testDeadCodeFromDifferentSources() throws Exception { + doTest("compiler/testData/diagnostics/tests/controlFlowAnalysis/deadCode/deadCodeFromDifferentSources.kt"); + } + + @TestMetadata("deadCodeInArrayAccess.kt") + public void testDeadCodeInArrayAccess() throws Exception { + doTest("compiler/testData/diagnostics/tests/controlFlowAnalysis/deadCode/deadCodeInArrayAccess.kt"); + } + + @TestMetadata("deadCodeInAssignment.kt") + public void testDeadCodeInAssignment() throws Exception { + doTest("compiler/testData/diagnostics/tests/controlFlowAnalysis/deadCode/deadCodeInAssignment.kt"); + } + + @TestMetadata("deadCodeInBinaryExpressions.kt") + public void testDeadCodeInBinaryExpressions() throws Exception { + doTest("compiler/testData/diagnostics/tests/controlFlowAnalysis/deadCode/deadCodeInBinaryExpressions.kt"); + } + + @TestMetadata("deadCodeInCalls.kt") + public void testDeadCodeInCalls() throws Exception { + doTest("compiler/testData/diagnostics/tests/controlFlowAnalysis/deadCode/deadCodeInCalls.kt"); + } + + @TestMetadata("deadCodeInDeadCode.kt") + public void testDeadCodeInDeadCode() throws Exception { + doTest("compiler/testData/diagnostics/tests/controlFlowAnalysis/deadCode/deadCodeInDeadCode.kt"); + } + + @TestMetadata("deadCodeInIf.kt") + public void testDeadCodeInIf() throws Exception { + doTest("compiler/testData/diagnostics/tests/controlFlowAnalysis/deadCode/deadCodeInIf.kt"); + } + + @TestMetadata("deadCodeInInnerExpressions.kt") + public void testDeadCodeInInnerExpressions() throws Exception { + doTest("compiler/testData/diagnostics/tests/controlFlowAnalysis/deadCode/deadCodeInInnerExpressions.kt"); + } + + @TestMetadata("deadCodeInLocalDeclarations.kt") + public void testDeadCodeInLocalDeclarations() throws Exception { + doTest("compiler/testData/diagnostics/tests/controlFlowAnalysis/deadCode/deadCodeInLocalDeclarations.kt"); + } + + @TestMetadata("deadCodeInLoops.kt") + public void testDeadCodeInLoops() throws Exception { + doTest("compiler/testData/diagnostics/tests/controlFlowAnalysis/deadCode/deadCodeInLoops.kt"); + } + + @TestMetadata("deadCodeInReturn.kt") + public void testDeadCodeInReturn() throws Exception { + doTest("compiler/testData/diagnostics/tests/controlFlowAnalysis/deadCode/deadCodeInReturn.kt"); + } + + @TestMetadata("deadCodeInUnaryExpr.kt") + public void testDeadCodeInUnaryExpr() throws Exception { + doTest("compiler/testData/diagnostics/tests/controlFlowAnalysis/deadCode/deadCodeInUnaryExpr.kt"); + } + + @TestMetadata("deadCodeInWhileFromBreak.kt") + public void testDeadCodeInWhileFromBreak() throws Exception { + doTest("compiler/testData/diagnostics/tests/controlFlowAnalysis/deadCode/deadCodeInWhileFromBreak.kt"); + } + + @TestMetadata("kt2585_1.kt") + public void testKt2585_1() throws Exception { + doTest("compiler/testData/diagnostics/tests/controlFlowAnalysis/deadCode/kt2585_1.kt"); + } + + @TestMetadata("kt2585_2.kt") + public void testKt2585_2() throws Exception { + doTest("compiler/testData/diagnostics/tests/controlFlowAnalysis/deadCode/kt2585_2.kt"); + } + + @TestMetadata("kt2585_3.kt") + public void testKt2585_3() throws Exception { + doTest("compiler/testData/diagnostics/tests/controlFlowAnalysis/deadCode/kt2585_3.kt"); + } + + } + @TestMetadata("compiler/testData/diagnostics/tests/controlFlowAnalysis/definiteReturn") public static class DefiniteReturn extends AbstractJetDiagnosticsTest { public void testAllFilesPresentInDefiniteReturn() throws Exception { @@ -1491,6 +1569,7 @@ public class JetDiagnosticsTestGenerated extends AbstractJetDiagnosticsTest { public static Test innerSuite() { TestSuite suite = new TestSuite("ControlFlowAnalysis"); suite.addTestSuite(ControlFlowAnalysis.class); + suite.addTestSuite(DeadCode.class); suite.addTestSuite(DefiniteReturn.class); return suite; } diff --git a/idea/testData/checker/FunctionReturnTypes.kt b/idea/testData/checker/FunctionReturnTypes.kt index f10d48a1d5d..6ec18678986 100644 --- a/idea/testData/checker/FunctionReturnTypes.kt +++ b/idea/testData/checker/FunctionReturnTypes.kt @@ -48,7 +48,7 @@ fun blockAndAndMismatch1() : Int { return true && false } fun blockAndAndMismatch2() : Int { - (return true) && (return false) + (return true) && (return false) } fun blockAndAndMismatch3() : Int { @@ -58,7 +58,7 @@ fun blockAndAndMismatch4() : Int { return true || false } fun blockAndAndMismatch5() : Int { - (return true) || (return false) + (return true) || (return false) } fun blockReturnValueTypeMatch1() : Int { return if (1 > 2) 1.0 else 2.0 diff --git a/idea/testData/checker/UnreachableCode.kt b/idea/testData/checker/UnreachableCode.kt index a98db2ae881..70599cadac0 100644 --- a/idea/testData/checker/UnreachableCode.kt +++ b/idea/testData/checker/UnreachableCode.kt @@ -126,12 +126,12 @@ fun t8() : Int { } fun blockAndAndMismatch() : Boolean { - (return true) || (return false) + (return true) || (return false) return true } fun tf() : Int { - try {return 1} finally{return 1} + try {return 1} finally{return 1} return 1 }