Recovery in qualified expressions

This commit is contained in:
Andrey Breslav
2013-12-02 21:49:40 +04:00
parent 5908211fbf
commit 09a1736ab6
4 changed files with 53 additions and 4 deletions
@@ -17,6 +17,7 @@
package org.jetbrains.jet.lang.cfg;
import com.google.common.collect.Lists;
import com.intellij.openapi.util.Ref;
import com.intellij.psi.PsiElement;
import com.intellij.psi.tree.IElementType;
import org.jetbrains.annotations.NotNull;
@@ -78,7 +79,7 @@ public class JetControlFlowProcessor {
private Pseudocode generate(@NotNull JetElement subroutine) {
builder.enterSubroutine(subroutine);
CFPVisitor cfpVisitor = new CFPVisitor(false);
CFPVisitor cfpVisitor = new CFPVisitor(builder, false);
if (subroutine instanceof JetDeclarationWithBody) {
JetDeclarationWithBody declarationWithBody = (JetDeclarationWithBody) subroutine;
List<JetParameter> valueParameters = declarationWithBody.getValueParameters();
@@ -104,6 +105,8 @@ public class JetControlFlowProcessor {
private class CFPVisitor extends JetVisitorVoid {
private final JetControlFlowBuilder builder;
private final boolean inCondition;
private final JetVisitorVoid conditionVisitor = new JetVisitorVoid() {
@@ -130,7 +133,8 @@ public class JetControlFlowProcessor {
}
};
private CFPVisitor(boolean inCondition) {
private CFPVisitor(@NotNull JetControlFlowBuilder builder, boolean inCondition) {
this.builder = builder;
this.inCondition = inCondition;
}
@@ -145,7 +149,7 @@ public class JetControlFlowProcessor {
visitor = this;
}
else {
visitor = new CFPVisitor(inCondition);
visitor = new CFPVisitor(builder, inCondition);
}
element.accept(visitor);
checkNothingType(element);
@@ -702,7 +706,25 @@ public class JetControlFlowProcessor {
public void visitQualifiedExpression(@NotNull JetQualifiedExpression expression) {
JetExpression selectorExpression = expression.getSelectorExpression();
if (selectorExpression != null) {
generateInstructions(selectorExpression, false);
final Ref<Boolean> error = new Ref<Boolean>(false);
JetControlFlowBuilderAdapter adapter = new JetControlFlowBuilderAdapter() {
@NotNull
@Override
protected JetControlFlowBuilder getDelegateBuilder() {
return builder;
}
@Override
public void compilationError(@NotNull JetElement element, @NotNull String message) {
error.set(true);
super.compilationError(element, message);
}
};
new CFPVisitor(adapter, inCondition).generateInstructions(selectorExpression, false);
if (error.get()) {
generateInstructions(expression.getReceiverExpression(), false);
}
}
}
@@ -0,0 +1,19 @@
== test ==
fun test(a: Any) {
a.foo()
}
---------------------
L0:
<START> NEXT:[v(a: Any)] PREV:[]
v(a: Any) NEXT:[w(a)] PREV:[<START>]
w(a) NEXT:[error(foo, No resolved call)] PREV:[v(a: Any)]
error(foo, No resolved call) NEXT:[error(foo, No resolved call)] PREV:[w(a)]
error(foo, No resolved call) NEXT:[r(a)] PREV:[error(foo, No resolved call)]
r(a) NEXT:[<END>] PREV:[error(foo, No resolved call)]
L1:
<END> NEXT:[<SINK>] PREV:[r(a)]
error:
<ERROR> NEXT:[<SINK>] PREV:[]
sink:
<SINK> NEXT:[] PREV:[<ERROR>, <END>]
=====================
+3
View File
@@ -0,0 +1,3 @@
fun test(a: Any) {
a.foo()
}
@@ -161,4 +161,9 @@ public class ControlFlowTestGenerated extends AbstractControlFlowTest {
doTest("compiler/testData/cfg/ShortFunction.kt");
}
@TestMetadata("unresolved.kt")
public void testUnresolved() throws Exception {
doTest("compiler/testData/cfg/unresolved.kt");
}
}