Test for inline dangerous expressions.
Better FindPreviousVisitor#hasDangerous implementation.
This commit is contained in:
@@ -50,4 +50,8 @@ public final class DangerousTest extends SingleFileTranslationTest {
|
||||
public void test2dangerousInExpression() throws Exception {
|
||||
checkFooBoxIsTrue("2dangerousInExpression.kt");
|
||||
}
|
||||
|
||||
public void testDangerousInline() throws Exception {
|
||||
checkFooBoxIsTrue("dangerousInline.kt");
|
||||
}
|
||||
}
|
||||
|
||||
+2
-2
@@ -58,13 +58,13 @@ public class DangerousData {
|
||||
private static DangerousData doCollectData(@NotNull JetExpression expression,
|
||||
@NotNull TranslationContext context) {
|
||||
DangerousData data = new DangerousData();
|
||||
FindDangerousVisitor visitor = new FindDangerousVisitor(context.bindingContext());
|
||||
FindDangerousVisitor visitor = new FindDangerousVisitor(context);
|
||||
expression.accept(visitor, data);
|
||||
if (!data.exists()) {
|
||||
return emptyData();
|
||||
}
|
||||
data.setRootNode(expression);
|
||||
FindPreviousVisitor findPreviousVisitor = new FindPreviousVisitor();
|
||||
FindPreviousVisitor findPreviousVisitor = new FindPreviousVisitor(data);
|
||||
expression.accept(findPreviousVisitor, data);
|
||||
return data;
|
||||
}
|
||||
|
||||
+17
-6
@@ -18,7 +18,8 @@ package org.jetbrains.k2js.translate.utils.dangerous;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.jet.lang.psi.*;
|
||||
import org.jetbrains.jet.lang.resolve.BindingContext;
|
||||
import org.jetbrains.k2js.translate.context.TranslationContext;
|
||||
import org.jetbrains.k2js.translate.reference.InlinedCallExpressionTranslator;
|
||||
|
||||
import static org.jetbrains.k2js.translate.utils.BindingUtils.isStatement;
|
||||
|
||||
@@ -28,10 +29,10 @@ import static org.jetbrains.k2js.translate.utils.BindingUtils.isStatement;
|
||||
public final class FindDangerousVisitor extends JetTreeVisitor<DangerousData> {
|
||||
|
||||
@NotNull
|
||||
private final BindingContext bindingContext;
|
||||
private final TranslationContext context;
|
||||
|
||||
public FindDangerousVisitor(@NotNull BindingContext context) {
|
||||
bindingContext = context;
|
||||
public FindDangerousVisitor(@NotNull TranslationContext context) {
|
||||
this.context = context;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -65,7 +66,7 @@ public final class FindDangerousVisitor extends JetTreeVisitor<DangerousData> {
|
||||
|
||||
@Override
|
||||
public Void visitBlockExpression(JetBlockExpression expression, DangerousData data) {
|
||||
if (isStatement(bindingContext, expression)) {
|
||||
if (isStatement(context.bindingContext(), expression)) {
|
||||
return null;
|
||||
}
|
||||
else {
|
||||
@@ -73,11 +74,21 @@ public final class FindDangerousVisitor extends JetTreeVisitor<DangerousData> {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void visitCallExpression(JetCallExpression expression, DangerousData data) {
|
||||
if (InlinedCallExpressionTranslator.shouldBeInlined(expression, context)) {
|
||||
if (expressionFound(expression, data)) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
return super.visitCallExpression(expression, data);
|
||||
}
|
||||
|
||||
private boolean expressionFound(@NotNull JetExpression expression, @NotNull DangerousData data) {
|
||||
if (data.exists()) {
|
||||
return true;
|
||||
}
|
||||
if (!isStatement(bindingContext, expression)) {
|
||||
if (!isStatement(context.bindingContext(), expression)) {
|
||||
data.setDangerousNode(expression);
|
||||
return true;
|
||||
}
|
||||
|
||||
+44
-23
@@ -16,21 +16,39 @@
|
||||
|
||||
package org.jetbrains.k2js.translate.utils.dangerous;
|
||||
|
||||
import com.google.common.collect.Maps;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.jet.lang.psi.*;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @author Pavel Talanov
|
||||
*/
|
||||
//TODO: refactor
|
||||
public final class FindPreviousVisitor extends JetTreeVisitor<DangerousData> {
|
||||
|
||||
@NotNull
|
||||
private final Map<JetElement, Void> hasDangerous = Maps.newHashMap();
|
||||
|
||||
public FindPreviousVisitor(@NotNull DangerousData data) {
|
||||
JetElement node = data.getDangerousNode();
|
||||
PsiElement last = data.getRootNode().getParent();
|
||||
while (node != last) {
|
||||
hasDangerous.put(node, null);
|
||||
PsiElement parent = node.getParent();
|
||||
assert parent instanceof JetElement;
|
||||
node = (JetElement)parent;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void visitJetElement(JetElement element, DangerousData data) {
|
||||
if (data.getDangerousNode() == element) {
|
||||
return null;
|
||||
}
|
||||
if (!hasDangerous(element, data)) {
|
||||
if (!hasDangerous(element)) {
|
||||
addElement(element, data);
|
||||
}
|
||||
else {
|
||||
@@ -52,7 +70,7 @@ public final class FindPreviousVisitor extends JetTreeVisitor<DangerousData> {
|
||||
while (current != null) {
|
||||
if (current instanceof JetElement) {
|
||||
((JetElement)current).accept(this, data);
|
||||
if (hasDangerous(element, data)) {
|
||||
if (hasDangerous(element)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -60,12 +78,32 @@ public final class FindPreviousVisitor extends JetTreeVisitor<DangerousData> {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void visitPrefixExpression(@NotNull JetPrefixExpression expression, @NotNull DangerousData data) {
|
||||
if (data.getDangerousNode() == expression) {
|
||||
return null;
|
||||
}
|
||||
if (!hasDangerous(expression)) {
|
||||
addElement(expression, data);
|
||||
return null;
|
||||
}
|
||||
else {
|
||||
if (hasDangerous(expression.getBaseExpression())) {
|
||||
return null;
|
||||
}
|
||||
else {
|
||||
//TODO:
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void visitCallExpression(@NotNull JetCallExpression expression, @NotNull DangerousData data) {
|
||||
if (data.getDangerousNode() == expression) {
|
||||
return null;
|
||||
}
|
||||
if (!hasDangerous(expression, data)) {
|
||||
if (!hasDangerous(expression)) {
|
||||
data.getNodesToBeGeneratedBefore().add(expression);
|
||||
}
|
||||
else {
|
||||
@@ -79,30 +117,13 @@ public final class FindPreviousVisitor extends JetTreeVisitor<DangerousData> {
|
||||
JetExpression argumentExpression = argument.getArgumentExpression();
|
||||
assert argumentExpression != null;
|
||||
argumentExpression.accept(this, data);
|
||||
if (hasDangerous(argumentExpression, data)) {
|
||||
if (hasDangerous(argumentExpression)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean hasDangerous(@NotNull JetElement element, @NotNull DangerousData data) {
|
||||
HasDangerousVisitor visitor = new HasDangerousVisitor();
|
||||
element.accept(visitor, data);
|
||||
return visitor.hasDangerous;
|
||||
}
|
||||
|
||||
private static final class HasDangerousVisitor extends JetTreeVisitor<DangerousData> {
|
||||
|
||||
private boolean hasDangerous = false;
|
||||
|
||||
@Override
|
||||
public Void visitJetElement(JetElement element, DangerousData data) {
|
||||
if (element == data.getDangerousNode()) {
|
||||
hasDangerous = true;
|
||||
return null;
|
||||
}
|
||||
element.acceptChildren(this, data);
|
||||
return null;
|
||||
}
|
||||
private boolean hasDangerous(@NotNull JetElement element) {
|
||||
return hasDangerous.containsKey(element);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
package foo
|
||||
|
||||
var i = 0
|
||||
|
||||
inline fun f() = i * 2
|
||||
|
||||
fun box() : Boolean {
|
||||
return (++i + f()) == 3
|
||||
}
|
||||
Reference in New Issue
Block a user