PSI: Make JetPostfixExpression.getBaseExpression() nullable

#KT-7761 Fixed
This commit is contained in:
Alexey Sedunov
2015-05-19 14:06:00 +03:00
parent 14d1d8e1dc
commit b1f1360081
12 changed files with 158 additions and 11 deletions
@@ -223,7 +223,7 @@ public class JavaNullabilityWarningsChecker : AdditionalTypeChecker {
when (expression) {
is JetPostfixExpression ->
if (expression.getOperationToken() == JetTokens.EXCLEXCL) {
val baseExpression = expression.getBaseExpression()
val baseExpression = expression.getBaseExpression() ?: return
val baseExpressionType = c.trace.getType(baseExpression) ?: return
doIfNotNull(
DataFlowValueFactory.createDataFlowValue(baseExpression, baseExpressionType, c),
@@ -17,7 +17,9 @@
package org.jetbrains.kotlin.psi;
import com.intellij.lang.ASTNode;
import com.intellij.psi.util.PsiTreeUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
public class JetPostfixExpression extends JetUnaryExpression {
public JetPostfixExpression(@NotNull ASTNode node) {
@@ -25,11 +27,9 @@ public class JetPostfixExpression extends JetUnaryExpression {
}
@Override
@NotNull
@Nullable @IfNotParsed
public JetExpression getBaseExpression() {
JetExpression answer = findChildByClass(JetExpression.class);
assert answer != null;
return answer;
return PsiTreeUtil.getPrevSiblingOfType(getOperationReference(), JetExpression.class);
}
@Override
@@ -0,0 +1,81 @@
== UnitIncDec ==
class UnitIncDec() {
fun inc() : Unit {}
fun dec() : Unit {}
}
---------------------
L0:
1 <START>
L1:
<END> NEXT:[<SINK>]
error:
<ERROR> PREV:[]
sink:
<SINK> PREV:[<ERROR>, <END>]
=====================
== inc ==
fun inc() : Unit {}
---------------------
L0:
1 <START>
2 mark({})
read (Unit)
L1:
1 <END> NEXT:[<SINK>]
error:
<ERROR> PREV:[]
sink:
<SINK> PREV:[<ERROR>, <END>]
=====================
== dec ==
fun dec() : Unit {}
---------------------
L0:
1 <START>
2 mark({})
read (Unit)
L1:
1 <END> NEXT:[<SINK>]
error:
<ERROR> PREV:[]
sink:
<SINK> PREV:[<ERROR>, <END>]
=====================
== testUnitIncDec ==
fun testUnitIncDec() {
var x = UnitIncDec()
x = <warning>x<error>++</error></warning>
}
---------------------
L0:
1 <START>
2 mark({ var x = UnitIncDec() x = <warning>x<error>++</error></warning> })
v(var x = UnitIncDec())
mark(UnitIncDec())
call(UnitIncDec(), <init>) -> <v0>
w(x|<v0>)
mark(<warning>)
magic[UNRESOLVED_CALL](<warning>) -> <v1>
mark(<warning>x<)
call(<warning>x<, <ERROR FUNCTION>|<v1>) -> <v2>
magic[VALUE_CONSUMER](>++|!<v3>) -> <v4>
mark(<warning>x<error>++)
call(<warning>x<error>++, <ERROR FUNCTION>|<v2>) -> <v5>
mark(/error>)
magic[UNRESOLVED_CALL](/error>) -> <v6>
magic[VALUE_CONSUMER](/error>|<v6>) -> <v7>
mark(<warning>x<error>++</error>)
call(<warning>x<error>++</error>, <ERROR FUNCTION>|<v5>) -> <v8>
mark(/warning>)
magic[UNRESOLVED_CALL](/warning>) -> <v9>
magic[VALUE_CONSUMER](/warning>|<v9>) -> <v10>
mark(<warning>x<error>++</error></warning>)
call(<warning>x<error>++</error></warning>, <ERROR FUNCTION>|<v8>) -> <v11>
w(x|<v11>)
L1:
1 <END> NEXT:[<SINK>]
error:
<ERROR> PREV:[]
sink:
<SINK> PREV:[<ERROR>, <END>]
=====================
+9
View File
@@ -0,0 +1,9 @@
class UnitIncDec() {
fun inc() : Unit {}
fun dec() : Unit {}
}
fun testUnitIncDec() {
var x = UnitIncDec()
x = <warning>x<error>++</error></warning>
}
+36
View File
@@ -0,0 +1,36 @@
== UnitIncDec ==
class UnitIncDec() {
fun inc() : Unit {}
fun dec() : Unit {}
}
---------------------
=====================
== inc ==
fun inc() : Unit {}
---------------------
=====================
== dec ==
fun dec() : Unit {}
---------------------
=====================
== testUnitIncDec ==
fun testUnitIncDec() {
var x = UnitIncDec()
x = <warning>x<error>++</error></warning>
}
---------------------
<v10>: * NEW: magic[VALUE_CONSUMER](/warning>|<v9>) -> <v10>
<v4>: * NEW: magic[VALUE_CONSUMER](>++|!<v3>) -> <v4>
<v7>: * NEW: magic[VALUE_CONSUMER](/error>|<v6>) -> <v7>
UnitIncDec() <v0>: UnitIncDec NEW: call(UnitIncDec(), <init>) -> <v0>
<warning> <v1>: * NEW: magic[UNRESOLVED_CALL](<warning>) -> <v1>
<warning>x< <v2>: * NEW: call(<warning>x<, <ERROR FUNCTION>|<v1>) -> <v2>
>++ !<v3>: *
<warning>x<error>++ <v5>: * NEW: call(<warning>x<error>++, <ERROR FUNCTION>|<v2>) -> <v5>
/error> <v6>: * NEW: magic[UNRESOLVED_CALL](/error>) -> <v6>
<warning>x<error>++</error> <v8>: * NEW: call(<warning>x<error>++</error>, <ERROR FUNCTION>|<v5>) -> <v8>
/warning> <v9>: * NEW: magic[UNRESOLVED_CALL](/warning>) -> <v9>
<warning>x<error>++</error></warning> <v11>: UnitIncDec NEW: call(<warning>x<error>++</error></warning>, <ERROR FUNCTION>|<v8>) -> <v11>
x = <warning>x<error>++</error></warning> !<v12>: *
{ var x = UnitIncDec() x = <warning>x<error>++</error></warning> } !<v12>: * COPY
=====================
@@ -144,6 +144,12 @@ public class ControlFlowTestGenerated extends AbstractControlFlowTest {
String fileName = JetTestUtils.navigationMetadata("compiler/testData/cfg/bugs/jumpToOuterScope.kt");
doTest(fileName);
}
@TestMetadata("kt7761.kt")
public void testKt7761() throws Exception {
String fileName = JetTestUtils.navigationMetadata("compiler/testData/cfg/bugs/kt7761.kt");
doTest(fileName);
}
}
@TestMetadata("compiler/testData/cfg/controlStructures")
@@ -146,6 +146,12 @@ public class PseudoValueTestGenerated extends AbstractPseudoValueTest {
String fileName = JetTestUtils.navigationMetadata("compiler/testData/cfg/bugs/jumpToOuterScope.kt");
doTest(fileName);
}
@TestMetadata("kt7761.kt")
public void testKt7761() throws Exception {
String fileName = JetTestUtils.navigationMetadata("compiler/testData/cfg/bugs/kt7761.kt");
doTest(fileName);
}
}
@TestMetadata("compiler/testData/cfg/controlStructures")