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 {
|
public void test2dangerousInExpression() throws Exception {
|
||||||
checkFooBoxIsTrue("2dangerousInExpression.kt");
|
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,
|
private static DangerousData doCollectData(@NotNull JetExpression expression,
|
||||||
@NotNull TranslationContext context) {
|
@NotNull TranslationContext context) {
|
||||||
DangerousData data = new DangerousData();
|
DangerousData data = new DangerousData();
|
||||||
FindDangerousVisitor visitor = new FindDangerousVisitor(context.bindingContext());
|
FindDangerousVisitor visitor = new FindDangerousVisitor(context);
|
||||||
expression.accept(visitor, data);
|
expression.accept(visitor, data);
|
||||||
if (!data.exists()) {
|
if (!data.exists()) {
|
||||||
return emptyData();
|
return emptyData();
|
||||||
}
|
}
|
||||||
data.setRootNode(expression);
|
data.setRootNode(expression);
|
||||||
FindPreviousVisitor findPreviousVisitor = new FindPreviousVisitor();
|
FindPreviousVisitor findPreviousVisitor = new FindPreviousVisitor(data);
|
||||||
expression.accept(findPreviousVisitor, data);
|
expression.accept(findPreviousVisitor, data);
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|||||||
+17
-6
@@ -18,7 +18,8 @@ package org.jetbrains.k2js.translate.utils.dangerous;
|
|||||||
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.jet.lang.psi.*;
|
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;
|
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> {
|
public final class FindDangerousVisitor extends JetTreeVisitor<DangerousData> {
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
private final BindingContext bindingContext;
|
private final TranslationContext context;
|
||||||
|
|
||||||
public FindDangerousVisitor(@NotNull BindingContext context) {
|
public FindDangerousVisitor(@NotNull TranslationContext context) {
|
||||||
bindingContext = context;
|
this.context = context;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -65,7 +66,7 @@ public final class FindDangerousVisitor extends JetTreeVisitor<DangerousData> {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Void visitBlockExpression(JetBlockExpression expression, DangerousData data) {
|
public Void visitBlockExpression(JetBlockExpression expression, DangerousData data) {
|
||||||
if (isStatement(bindingContext, expression)) {
|
if (isStatement(context.bindingContext(), expression)) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
else {
|
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) {
|
private boolean expressionFound(@NotNull JetExpression expression, @NotNull DangerousData data) {
|
||||||
if (data.exists()) {
|
if (data.exists()) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (!isStatement(bindingContext, expression)) {
|
if (!isStatement(context.bindingContext(), expression)) {
|
||||||
data.setDangerousNode(expression);
|
data.setDangerousNode(expression);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
+44
-23
@@ -16,21 +16,39 @@
|
|||||||
|
|
||||||
package org.jetbrains.k2js.translate.utils.dangerous;
|
package org.jetbrains.k2js.translate.utils.dangerous;
|
||||||
|
|
||||||
|
import com.google.common.collect.Maps;
|
||||||
import com.intellij.psi.PsiElement;
|
import com.intellij.psi.PsiElement;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.jet.lang.psi.*;
|
import org.jetbrains.jet.lang.psi.*;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Pavel Talanov
|
* @author Pavel Talanov
|
||||||
*/
|
*/
|
||||||
|
//TODO: refactor
|
||||||
public final class FindPreviousVisitor extends JetTreeVisitor<DangerousData> {
|
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
|
@Override
|
||||||
public Void visitJetElement(JetElement element, DangerousData data) {
|
public Void visitJetElement(JetElement element, DangerousData data) {
|
||||||
if (data.getDangerousNode() == element) {
|
if (data.getDangerousNode() == element) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
if (!hasDangerous(element, data)) {
|
if (!hasDangerous(element)) {
|
||||||
addElement(element, data);
|
addElement(element, data);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@@ -52,7 +70,7 @@ public final class FindPreviousVisitor extends JetTreeVisitor<DangerousData> {
|
|||||||
while (current != null) {
|
while (current != null) {
|
||||||
if (current instanceof JetElement) {
|
if (current instanceof JetElement) {
|
||||||
((JetElement)current).accept(this, data);
|
((JetElement)current).accept(this, data);
|
||||||
if (hasDangerous(element, data)) {
|
if (hasDangerous(element)) {
|
||||||
break;
|
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
|
@Override
|
||||||
public Void visitCallExpression(@NotNull JetCallExpression expression, @NotNull DangerousData data) {
|
public Void visitCallExpression(@NotNull JetCallExpression expression, @NotNull DangerousData data) {
|
||||||
if (data.getDangerousNode() == expression) {
|
if (data.getDangerousNode() == expression) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
if (!hasDangerous(expression, data)) {
|
if (!hasDangerous(expression)) {
|
||||||
data.getNodesToBeGeneratedBefore().add(expression);
|
data.getNodesToBeGeneratedBefore().add(expression);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@@ -79,30 +117,13 @@ public final class FindPreviousVisitor extends JetTreeVisitor<DangerousData> {
|
|||||||
JetExpression argumentExpression = argument.getArgumentExpression();
|
JetExpression argumentExpression = argument.getArgumentExpression();
|
||||||
assert argumentExpression != null;
|
assert argumentExpression != null;
|
||||||
argumentExpression.accept(this, data);
|
argumentExpression.accept(this, data);
|
||||||
if (hasDangerous(argumentExpression, data)) {
|
if (hasDangerous(argumentExpression)) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static boolean hasDangerous(@NotNull JetElement element, @NotNull DangerousData data) {
|
private boolean hasDangerous(@NotNull JetElement element) {
|
||||||
HasDangerousVisitor visitor = new HasDangerousVisitor();
|
return hasDangerous.containsKey(element);
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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