conversions as wrappers; generate !! instead of sure() (for constructor calls only for now)

This commit is contained in:
Dmitry Jemerov
2012-05-24 21:03:24 +02:00
committed by Pavel V. Talanov
parent 37ea08c6a2
commit 512e12d26c
8 changed files with 83 additions and 31 deletions
+68 -19
View File
@@ -16,6 +16,7 @@
package org.jetbrains.jet.j2k;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Sets;
import com.intellij.psi.*;
@@ -49,6 +50,24 @@ public class Converter {
"javax.annotation.Nonnull"
);
private static final Map<String, String> PRIMITIVE_TYPE_CONVERSIONS = ImmutableMap.<String, String>builder()
.put("byte", BYTE)
.put("short", SHORT)
.put("int", INT)
.put("long", LONG)
.put("float", FLOAT)
.put("double", DOUBLE)
.put("char", CHAR)
.put(JAVA_LANG_BYTE, BYTE)
.put(JAVA_LANG_SHORT, SHORT)
.put(JAVA_LANG_INTEGER, INT)
.put(JAVA_LANG_LONG, LONG)
.put(JAVA_LANG_FLOAT, FLOAT)
.put(JAVA_LANG_DOUBLE, DOUBLE)
.put(JAVA_LANG_CHARACTER, CHAR)
.build();
@NotNull
private Set<String> classIdentifiers = Sets.newHashSet();
@@ -695,6 +714,53 @@ public class Converter {
return modifiersSet;
}
public List<Expression> argumentsToExpressionList(@NotNull PsiCallExpression expression) {
PsiExpressionList argumentList = expression.getArgumentList();
PsiExpression[] arguments = argumentList != null ? argumentList.getExpressions() : PsiExpression.EMPTY_ARRAY;
List<Expression> result = new ArrayList<Expression>();
PsiMethod resolved = expression.resolveMethod();
List<PsiType> expectedTypes = new ArrayList<PsiType>();
if (resolved != null) {
for (PsiParameter p : resolved.getParameterList().getParameters())
expectedTypes.add(p.getType());
}
// TODO handle varargs correctly
if (arguments.length == expectedTypes.size()) {
for (int i = 0; i < expectedTypes.size(); i++)
result.add(expressionToExpression(arguments[i], expectedTypes.get(i)));
}
else {
for (PsiExpression argument : arguments) {
result.add(expressionToExpression(argument));
}
}
return result;
}
public Expression expressionToExpression(PsiExpression argument, PsiType expectedType) {
Expression expression = expressionToExpression(argument);
PsiType actualType = argument.getType();
boolean isPrimitiveTypeOrNull = actualType == null || actualType instanceof PsiPrimitiveType;
boolean isRef = (argument instanceof PsiReferenceExpression && ((PsiReferenceExpression) argument).isQualified() || argument instanceof PsiMethodCallExpression);
if (isPrimitiveTypeOrNull && isRef && expression.isNullable()) {
expression = new BangBangExpression(expression);
}
if (actualType != null) {
if (isConversionNeeded(actualType, expectedType)) {
String conversion = PRIMITIVE_TYPE_CONVERSIONS.get(expectedType.getCanonicalText());
if (conversion != null) {
expression = new DummyMethodCallExpression(expression, conversion, (IdentifierImpl) Identifier.EMPTY_IDENTIFIER);
}
}
}
return expression;
}
@NotNull
public List<String> createConversions(@NotNull PsiCallExpression expression) {
PsiExpressionList argumentList = expression.getArgumentList();
@@ -787,25 +853,8 @@ public class Converter {
@NotNull
private static String getPrimitiveTypeConversion(@NotNull String type) {
Map<String, String> conversions = new HashMap<String, String>();
conversions.put("byte", BYTE);
conversions.put("short", SHORT);
conversions.put("int", INT);
conversions.put("long", LONG);
conversions.put("float", FLOAT);
conversions.put("double", DOUBLE);
conversions.put("char", CHAR);
conversions.put(JAVA_LANG_BYTE, BYTE);
conversions.put(JAVA_LANG_SHORT, SHORT);
conversions.put(JAVA_LANG_INTEGER, INT);
conversions.put(JAVA_LANG_LONG, LONG);
conversions.put(JAVA_LANG_FLOAT, FLOAT);
conversions.put(JAVA_LANG_DOUBLE, DOUBLE);
conversions.put(JAVA_LANG_CHARACTER, CHAR);
if (conversions.containsKey(type)) {
return "." + conversions.get(type) + "()";
if (PRIMITIVE_TYPE_CONVERSIONS.containsKey(type)) {
return "." + PRIMITIVE_TYPE_CONVERSIONS.get(type) + "()";
}
return "";
}
@@ -0,0 +1,5 @@
package org.jetbrains.jet.j2k.ast
public class BangBangExpression(val expr: Expression): Expression() {
public override fun toKotlin(): String = expr.toKotlin() + "!!"
}
@@ -8,7 +8,10 @@ public open class CallChainExpression(val expression : Expression, val identifie
return INode.Kind.CALL_CHAIN
}
public override fun isNullable() : Boolean = identifier.isNullable()
public override fun isNullable() : Boolean {
if (!expression.isEmpty() && expression.isNullable()) return true
return identifier.isNullable()
}
public override fun toKotlin() : String {
if (!expression.isEmpty()) {
@@ -41,7 +41,7 @@ public abstract class Expression extends Statement {
}
}
boolean isNullable() {
public boolean isNullable() {
return false;
}
}
@@ -29,7 +29,6 @@ public class NewClassExpression extends Expression {
private final Element myName;
private final List<Expression> myArguments;
private Expression myQualifier;
private List<String> myConversions;
@Nullable
private AnonymousClass myAnonymousClass = null;
@@ -37,14 +36,12 @@ public class NewClassExpression extends Expression {
myName = name;
myQualifier = EMPTY_EXPRESSION;
myArguments = arguments;
myConversions = AstUtil.createListWithEmptyString(arguments);
}
public NewClassExpression(@NotNull Expression qualifier, @NotNull Element name, @NotNull List<Expression> arguments,
@NotNull List<String> conversions, @Nullable AnonymousClass anonymousClass) {
@Nullable AnonymousClass anonymousClass) {
this(name, arguments);
myQualifier = qualifier;
myConversions = conversions;
myAnonymousClass = anonymousClass;
}
@@ -53,8 +50,7 @@ public class NewClassExpression extends Expression {
public String toKotlin() {
final String callOperator = myQualifier.isNullable() ? QUESTDOT : DOT;
final String qualifier = myQualifier.isEmpty() ? EMPTY : myQualifier.toKotlin() + callOperator;
List<String> applyConversions = AstUtil.applyConversions(AstUtil.nodesToKotlin(myArguments), myConversions);
String appliedArguments = AstUtil.join(applyConversions, COMMA_WITH_SPACE);
String appliedArguments = AstUtil.joinNodes(myArguments, COMMA_WITH_SPACE);
return myAnonymousClass != null ?
"object" + SPACE + ":" + SPACE + qualifier + myName.toKotlin() + "(" + appliedArguments + ")" + myAnonymousClass.toKotlin()
:
@@ -276,8 +276,7 @@ public class ExpressionVisitor extends StatementVisitor {
return new NewClassExpression(
getConverter().expressionToExpression(expression.getQualifier()),
getConverter().elementToElement(classReference),
getConverter().expressionsToExpressionList(arguments),
getConverter().createConversions(expression),
getConverter().argumentsToExpressionList(expression),
anonymousClass != null ? getConverter().anonymousClassToAnonymousClass(anonymousClass) : null
);
}
+1 -1
View File
@@ -2,6 +2,6 @@ package demo
open class Test(i : Int) {
open fun test() : Unit {
var b : Byte = 10
Test((b).toInt())
Test(b.toInt())
}
}
+1 -1
View File
@@ -14,6 +14,6 @@ open fun putInt(i : Int) : Unit {
}
open fun test() : Unit {
putInt((One.myContainer?.myInt).sure())
IntContainer((One.myContainer?.myInt).sure())
IntContainer(One.myContainer?.myInt!!)
}
}