check Nothing type for all expressions not only for calls and simple names
(but excluding statement expressions)
This commit is contained in:
@@ -69,14 +69,14 @@ public class JetControlFlowProcessor {
|
||||
JetDeclarationWithBody declarationWithBody = (JetDeclarationWithBody) subroutine;
|
||||
List<JetParameter> valueParameters = declarationWithBody.getValueParameters();
|
||||
for (JetParameter valueParameter : valueParameters) {
|
||||
valueParameter.accept(cfpVisitor);
|
||||
cfpVisitor.generateInstructions(valueParameter);
|
||||
}
|
||||
JetExpression bodyExpression = declarationWithBody.getBodyExpression();
|
||||
if (bodyExpression != null) {
|
||||
bodyExpression.accept(cfpVisitor);
|
||||
cfpVisitor.generateInstructions(bodyExpression);
|
||||
}
|
||||
} else {
|
||||
subroutine.accept(cfpVisitor);
|
||||
cfpVisitor.generateInstructions(subroutine);
|
||||
}
|
||||
return builder.exitSubroutine(subroutine);
|
||||
}
|
||||
@@ -115,18 +115,15 @@ public class JetControlFlowProcessor {
|
||||
throw new UnsupportedOperationException("[JetControlFlowProcessor] " + element.toString());
|
||||
}
|
||||
};
|
||||
private final JetVisitorVoid patternVisitor = new JetVisitorVoid() {
|
||||
|
||||
@Override
|
||||
public void visitJetElement(@NotNull JetElement element) {
|
||||
throw new UnsupportedOperationException("[JetControlFlowProcessor] " + element.toString());
|
||||
}
|
||||
};
|
||||
|
||||
private CFPVisitor(boolean inCondition) {
|
||||
this.inCondition = inCondition;
|
||||
}
|
||||
|
||||
public void generateInstructions(@Nullable JetElement element) {
|
||||
generateInstructions(element, inCondition);
|
||||
}
|
||||
|
||||
private void generateInstructions(@Nullable JetElement element, boolean inCondition) {
|
||||
if (element == null) return;
|
||||
CFPVisitor visitor;
|
||||
@@ -137,6 +134,22 @@ public class JetControlFlowProcessor {
|
||||
visitor = new CFPVisitor(inCondition);
|
||||
}
|
||||
element.accept(visitor);
|
||||
checkNothingType(element);
|
||||
}
|
||||
|
||||
private void checkNothingType(JetElement element) {
|
||||
if (!(element instanceof JetExpression)) return;
|
||||
JetExpression expression = JetPsiUtil.deparenthesize((JetExpression) element);
|
||||
if (expression instanceof JetStatementExpression || expression instanceof JetTryExpression
|
||||
|| expression instanceof JetThrowExpression || expression instanceof JetFinallySection
|
||||
|| expression instanceof JetIfExpression || expression instanceof JetWhenExpression) return;
|
||||
//noinspection ConstantConditions
|
||||
if (!trace.get(BindingContext.PROCESSED, expression)) return;
|
||||
|
||||
JetType type = trace.getBindingContext().get(BindingContext.EXPRESSION_TYPE, expression);
|
||||
if (type != null && KotlinBuiltIns.getInstance().isNothing(type)) {
|
||||
builder.jumpToError();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -172,12 +185,6 @@ public class JetControlFlowProcessor {
|
||||
@Override
|
||||
public void visitSimpleNameExpression(@NotNull JetSimpleNameExpression expression) {
|
||||
builder.read(expression);
|
||||
if (trace.get(BindingContext.PROCESSED, expression)) {
|
||||
JetType type = trace.getBindingContext().get(BindingContext.EXPRESSION_TYPE, expression);
|
||||
if (type != null && KotlinBuiltIns.getInstance().isNothing(type)) {
|
||||
builder.jumpToError();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -662,12 +669,6 @@ public class JetControlFlowProcessor {
|
||||
generateInstructions(selectorExpression, false);
|
||||
}
|
||||
builder.read(expression);
|
||||
if (trace.get(BindingContext.PROCESSED, expression)) {
|
||||
JetType type = trace.getBindingContext().get(BindingContext.EXPRESSION_TYPE, expression);
|
||||
if (type != null && KotlinBuiltIns.getInstance().isNothing(type)) {
|
||||
builder.jumpToError();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void visitCall(JetCallElement call) {
|
||||
@@ -693,12 +694,6 @@ public class JetControlFlowProcessor {
|
||||
|
||||
generateInstructions(expression.getCalleeExpression(), false);
|
||||
builder.read(expression);
|
||||
if (trace.get(BindingContext.PROCESSED, expression)) {
|
||||
JetType type = trace.getBindingContext().get(BindingContext.EXPRESSION_TYPE, expression);
|
||||
if (type != null && KotlinBuiltIns.getInstance().isNothing(type)) {
|
||||
builder.jumpToError();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
package c
|
||||
|
||||
fun test1() {
|
||||
<!UNREACHABLE_CODE!>val <!UNUSED_VARIABLE!>r<!>: Nothing = null!!<!>
|
||||
}
|
||||
|
||||
fun test2(a: A) {
|
||||
a + a
|
||||
<!UNREACHABLE_CODE!>bar()<!>
|
||||
}
|
||||
|
||||
fun test3() {
|
||||
null!!
|
||||
<!UNREACHABLE_CODE!>bar()<!>
|
||||
}
|
||||
|
||||
fun throwNPE() = null!!
|
||||
|
||||
class A {
|
||||
fun plus(<!UNUSED_PARAMETER!>a<!>: A): Nothing = throw Exception()
|
||||
}
|
||||
|
||||
fun bar() {}
|
||||
@@ -1,3 +1,5 @@
|
||||
// !DIAGNOSTICS: -UNREACHABLE_CODE -UNUSED_PARAMETER
|
||||
// t is unused due to KT-4233
|
||||
trait Tr<T> {
|
||||
var v: T
|
||||
}
|
||||
|
||||
+1
@@ -1,3 +1,4 @@
|
||||
// !DIAGNOSTICS: -UNREACHABLE_CODE
|
||||
trait Tr<T> {
|
||||
var v: T
|
||||
}
|
||||
|
||||
+1
@@ -1,3 +1,4 @@
|
||||
// !DIAGNOSTICS: -UNREACHABLE_CODE
|
||||
trait Tr<T> {
|
||||
var v: T
|
||||
}
|
||||
|
||||
@@ -7,4 +7,5 @@ fun main(args: Array<String>) {
|
||||
}
|
||||
}
|
||||
|
||||
fun test<R>(callback: (R) -> Unit):Unit = callback(null!!)
|
||||
// callback is unused due to KT-4233
|
||||
fun test<R>(<!UNUSED_PARAMETER!>callback<!>: (R) -> Unit):Unit = <!UNREACHABLE_CODE!>callback(null!!)<!>
|
||||
@@ -1402,6 +1402,11 @@ public class JetDiagnosticsTestGenerated extends AbstractDiagnosticsTestWithEage
|
||||
doTest("compiler/testData/diagnostics/tests/controlFlowAnalysis/checkInnerLocalDeclarations.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("DeadCode.kt")
|
||||
public void testDeadCode() throws Exception {
|
||||
doTest("compiler/testData/diagnostics/tests/controlFlowAnalysis/DeadCode.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("kt1001.kt")
|
||||
public void testKt1001() throws Exception {
|
||||
doTest("compiler/testData/diagnostics/tests/controlFlowAnalysis/kt1001.kt");
|
||||
|
||||
Reference in New Issue
Block a user