From aea06bf9803af3f74c043a469b70e0319869e7b9 Mon Sep 17 00:00:00 2001 From: Sergey Ignatov Date: Mon, 12 Dec 2011 13:33:25 +0400 Subject: [PATCH] KT-794 Support autoboxing primitive return types --- src/org/jetbrains/jet/j2k/Converter.java | 12 ++++++++-- .../jet/j2k/ast/ReturnStatement.java | 9 ++++++- src/org/jetbrains/jet/j2k/util/AstUtil.java | 24 +++++++++++++++---- .../jet/j2k/visitors/ExpressionVisitor.java | 20 +++++++--------- .../jet/j2k/visitors/StatementVisitor.java | 13 +++++++++- testData/ast/issues/file/kt-794-mixed.jav | 11 +++++++++ testData/ast/issues/file/kt-794-mixed.kt | 9 +++++++ testData/ast/issues/file/kt-794.jav | 6 +++++ testData/ast/issues/file/kt-794.kt | 6 +++++ 9 files changed, 89 insertions(+), 21 deletions(-) create mode 100644 testData/ast/issues/file/kt-794-mixed.jav create mode 100644 testData/ast/issues/file/kt-794-mixed.kt create mode 100644 testData/ast/issues/file/kt-794.jav create mode 100644 testData/ast/issues/file/kt-794.kt diff --git a/src/org/jetbrains/jet/j2k/Converter.java b/src/org/jetbrains/jet/j2k/Converter.java index 05ff2772777..8842561b6fd 100644 --- a/src/org/jetbrains/jet/j2k/Converter.java +++ b/src/org/jetbrains/jet/j2k/Converter.java @@ -25,8 +25,9 @@ public class Converter { add("javax.annotation.Nonnull"); } }; - private static Set ourClassIdentifiers = new HashSet(); - private static final Dispatcher ourDispatcher = new Dispatcher(); + @NotNull private static Set ourClassIdentifiers = new HashSet(); + @NotNull private static final Dispatcher ourDispatcher = new Dispatcher(); + @Nullable private static PsiType ourMethodReturnType = null; public static void setClassIdentifiers(Set identifiers) { ourClassIdentifiers = identifiers; @@ -36,6 +37,11 @@ public class Converter { return new HashSet(ourClassIdentifiers); } + @Nullable + public static PsiType getMethodReturnType() { + return ourMethodReturnType; + } + public static void clearClassIdentifiers() { ourClassIdentifiers.clear(); } @@ -300,6 +306,8 @@ public class Converter { else ourDispatcher.setExpressionVisitor(new ExpressionVisitor()); + ourMethodReturnType = method.getReturnType(); + final IdentifierImpl identifier = new IdentifierImpl(method.getName()); final Type returnType = typeToType(method.getReturnType(), isNotNull(method.getModifierList())); final Block body = blockToBlock(method.getBody(), notEmpty); diff --git a/src/org/jetbrains/jet/j2k/ast/ReturnStatement.java b/src/org/jetbrains/jet/j2k/ast/ReturnStatement.java index b4040c3d824..bf2e7ca6579 100644 --- a/src/org/jetbrains/jet/j2k/ast/ReturnStatement.java +++ b/src/org/jetbrains/jet/j2k/ast/ReturnStatement.java @@ -1,20 +1,27 @@ package org.jetbrains.jet.j2k.ast; import org.jetbrains.annotations.NotNull; +import org.jetbrains.jet.j2k.util.AstUtil; /** * @author ignatov */ public class ReturnStatement extends Statement { private final Expression myExpression; + private String myConversion = EMPTY; public ReturnStatement(Expression expression) { myExpression = expression; } + public ReturnStatement(final Expression expression, final String conversion) { + this(expression); + myConversion = conversion; + } + @NotNull @Override public String toKotlin() { - return "return" + SPACE + myExpression.toKotlin(); + return "return" + SPACE + AstUtil.applyConversionForOneItem(myExpression.toKotlin(), myConversion); } } diff --git a/src/org/jetbrains/jet/j2k/util/AstUtil.java b/src/org/jetbrains/jet/j2k/util/AstUtil.java index a814767880a..3c96203ab94 100644 --- a/src/org/jetbrains/jet/j2k/util/AstUtil.java +++ b/src/org/jetbrains/jet/j2k/util/AstUtil.java @@ -1,10 +1,12 @@ package org.jetbrains.jet.j2k.util; +import org.jetbrains.annotations.NotNull; import org.jetbrains.jet.j2k.ast.Expression; import org.jetbrains.jet.j2k.ast.INode; import java.util.LinkedList; import java.util.List; +import java.util.Map; /** * @author ignatov @@ -53,15 +55,27 @@ public class AstUtil { return conversions; } - public static List applyConversions(List first, List second) { + @NotNull + public static List applyConversions(@NotNull List first, @NotNull List second) { List result = new LinkedList(); assert first.size() == second.size() : "Lists must have the same size."; for (int i = 0; i < first.size(); i++) { - if (second.get(i).isEmpty()) - result.add(first.get(i)); - else - result.add("(" + first.get(i) + ")" + second.get(i)); + result.add(applyConversionForOneItem(first.get(i), second.get(i))); } return result; } + + @NotNull + public static String applyConversionForOneItem(@NotNull String f, @NotNull String s) { + if (s.isEmpty()) + return f; + else + return "(" + f + ")" + s; + } + + public static T getOrElse(Map map, T e, T orElse) { + if (map.containsKey(e)) + return map.get(e); + return orElse; + } } diff --git a/src/org/jetbrains/jet/j2k/visitors/ExpressionVisitor.java b/src/org/jetbrains/jet/j2k/visitors/ExpressionVisitor.java index 9a587d8c4ad..73179a332c0 100644 --- a/src/org/jetbrains/jet/j2k/visitors/ExpressionVisitor.java +++ b/src/org/jetbrains/jet/j2k/visitors/ExpressionVisitor.java @@ -6,6 +6,7 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.jet.j2k.Converter; import org.jetbrains.jet.j2k.ast.*; +import org.jetbrains.jet.j2k.util.AstUtil; import java.util.*; @@ -231,7 +232,9 @@ public class ExpressionVisitor extends StatementVisitor { } } - private static boolean isConversionNeeded(final PsiType actual, final PsiType expected) { + static boolean isConversionNeeded(@Nullable final PsiType actual,@Nullable final PsiType expected) { + if (actual == null || expected == null) + return false; Map typeMap = new HashMap(); typeMap.put("java.lang.Byte", "byte"); typeMap.put("java.lang.Short", "short"); @@ -242,20 +245,13 @@ public class ExpressionVisitor extends StatementVisitor { typeMap.put("java.lang.Character", "char"); String expectedStr = expected.getCanonicalText(); String actualStr = actual.getCanonicalText(); - boolean o1 = getOrElse(typeMap, actualStr, "").equals(expectedStr); - boolean o2 = getOrElse(typeMap, expectedStr, "").equals(actualStr); + boolean o1 = AstUtil.getOrElse(typeMap, actualStr, "").equals(expectedStr); + boolean o2 = AstUtil.getOrElse(typeMap, expectedStr, "").equals(actualStr); return !actualStr.equals(expectedStr) && (!(o1 ^ o2)); } - - - private static T getOrElse(Map map, T e, T orElse) { - if (map.containsKey(e)) - return map.get(e); - return orElse; - } - - private static String getPrimitiveTypeConversion(String type) { + @NotNull + static String getPrimitiveTypeConversion(@NotNull String type) { Map conversions = new HashMap(); conversions.put("byte", "byt"); conversions.put("short", "sht"); diff --git a/src/org/jetbrains/jet/j2k/visitors/StatementVisitor.java b/src/org/jetbrains/jet/j2k/visitors/StatementVisitor.java index 0e3561722c9..d97185146e8 100644 --- a/src/org/jetbrains/jet/j2k/visitors/StatementVisitor.java +++ b/src/org/jetbrains/jet/j2k/visitors/StatementVisitor.java @@ -6,6 +6,7 @@ import com.intellij.psi.tree.IElementType; import com.intellij.psi.util.PsiUtil; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import org.jetbrains.jet.j2k.Converter; import org.jetbrains.jet.j2k.ast.*; import java.util.Arrays; @@ -14,6 +15,8 @@ import java.util.LinkedList; import java.util.List; import static org.jetbrains.jet.j2k.Converter.*; +import static org.jetbrains.jet.j2k.visitors.ExpressionVisitor.getPrimitiveTypeConversion; +import static org.jetbrains.jet.j2k.visitors.ExpressionVisitor.isConversionNeeded; /** * @author ignatov @@ -332,8 +335,16 @@ public class StatementVisitor extends ElementVisitor { @Override public void visitReturnStatement(PsiReturnStatement statement) { super.visitReturnStatement(statement); + PsiExpression returnValue = statement.getReturnValue(); + String conversion = ""; + + PsiType methodReturnType = Converter.getMethodReturnType(); + if (returnValue != null && methodReturnType != null && isConversionNeeded(returnValue.getType(), methodReturnType)) { + conversion = getPrimitiveTypeConversion(methodReturnType.getCanonicalText()); + } myResult = new ReturnStatement( - expressionToExpression(statement.getReturnValue()) + expressionToExpression(returnValue), + conversion ); } } diff --git a/testData/ast/issues/file/kt-794-mixed.jav b/testData/ast/issues/file/kt-794-mixed.jav new file mode 100644 index 00000000000..d64b41aa5a8 --- /dev/null +++ b/testData/ast/issues/file/kt-794-mixed.jav @@ -0,0 +1,11 @@ +package demo; + +class Test { + Integer getInteger(Integer i) { + return i; + } + + void test() { + int i = getInteger(10); + } +} \ No newline at end of file diff --git a/testData/ast/issues/file/kt-794-mixed.kt b/testData/ast/issues/file/kt-794-mixed.kt new file mode 100644 index 00000000000..5e6ec805f77 --- /dev/null +++ b/testData/ast/issues/file/kt-794-mixed.kt @@ -0,0 +1,9 @@ +namespace demo +open class Test() { +open fun getInteger(i : Int?) : Int? { +return i +} +open fun test() : Unit { +var i : Int = getInteger(10) +} +} \ No newline at end of file diff --git a/testData/ast/issues/file/kt-794.jav b/testData/ast/issues/file/kt-794.jav new file mode 100644 index 00000000000..5458bce32ca --- /dev/null +++ b/testData/ast/issues/file/kt-794.jav @@ -0,0 +1,6 @@ +class Test { + int getInt() { + byte b = 10; + return b; + } +} \ No newline at end of file diff --git a/testData/ast/issues/file/kt-794.kt b/testData/ast/issues/file/kt-794.kt new file mode 100644 index 00000000000..2cc75b06dc2 --- /dev/null +++ b/testData/ast/issues/file/kt-794.kt @@ -0,0 +1,6 @@ +open class Test() { +open fun getInt() : Int { +var b : Byte = 10 +return (b).int +} +} \ No newline at end of file