conversions as wrappers; generate !! instead of sure() (for constructor calls only for now)
This commit is contained in:
committed by
Pavel V. Talanov
parent
37ea08c6a2
commit
512e12d26c
@@ -16,6 +16,7 @@
|
|||||||
|
|
||||||
package org.jetbrains.jet.j2k;
|
package org.jetbrains.jet.j2k;
|
||||||
|
|
||||||
|
import com.google.common.collect.ImmutableMap;
|
||||||
import com.google.common.collect.ImmutableSet;
|
import com.google.common.collect.ImmutableSet;
|
||||||
import com.google.common.collect.Sets;
|
import com.google.common.collect.Sets;
|
||||||
import com.intellij.psi.*;
|
import com.intellij.psi.*;
|
||||||
@@ -49,6 +50,24 @@ public class Converter {
|
|||||||
"javax.annotation.Nonnull"
|
"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
|
@NotNull
|
||||||
private Set<String> classIdentifiers = Sets.newHashSet();
|
private Set<String> classIdentifiers = Sets.newHashSet();
|
||||||
|
|
||||||
@@ -695,6 +714,53 @@ public class Converter {
|
|||||||
return modifiersSet;
|
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
|
@NotNull
|
||||||
public List<String> createConversions(@NotNull PsiCallExpression expression) {
|
public List<String> createConversions(@NotNull PsiCallExpression expression) {
|
||||||
PsiExpressionList argumentList = expression.getArgumentList();
|
PsiExpressionList argumentList = expression.getArgumentList();
|
||||||
@@ -787,25 +853,8 @@ public class Converter {
|
|||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
private static String getPrimitiveTypeConversion(@NotNull String type) {
|
private static String getPrimitiveTypeConversion(@NotNull String type) {
|
||||||
Map<String, String> conversions = new HashMap<String, String>();
|
if (PRIMITIVE_TYPE_CONVERSIONS.containsKey(type)) {
|
||||||
conversions.put("byte", BYTE);
|
return "." + PRIMITIVE_TYPE_CONVERSIONS.get(type) + "()";
|
||||||
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) + "()";
|
|
||||||
}
|
}
|
||||||
return "";
|
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
|
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 {
|
public override fun toKotlin() : String {
|
||||||
if (!expression.isEmpty()) {
|
if (!expression.isEmpty()) {
|
||||||
|
|||||||
@@ -41,7 +41,7 @@ public abstract class Expression extends Statement {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean isNullable() {
|
public boolean isNullable() {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -29,7 +29,6 @@ public class NewClassExpression extends Expression {
|
|||||||
private final Element myName;
|
private final Element myName;
|
||||||
private final List<Expression> myArguments;
|
private final List<Expression> myArguments;
|
||||||
private Expression myQualifier;
|
private Expression myQualifier;
|
||||||
private List<String> myConversions;
|
|
||||||
@Nullable
|
@Nullable
|
||||||
private AnonymousClass myAnonymousClass = null;
|
private AnonymousClass myAnonymousClass = null;
|
||||||
|
|
||||||
@@ -37,14 +36,12 @@ public class NewClassExpression extends Expression {
|
|||||||
myName = name;
|
myName = name;
|
||||||
myQualifier = EMPTY_EXPRESSION;
|
myQualifier = EMPTY_EXPRESSION;
|
||||||
myArguments = arguments;
|
myArguments = arguments;
|
||||||
myConversions = AstUtil.createListWithEmptyString(arguments);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public NewClassExpression(@NotNull Expression qualifier, @NotNull Element name, @NotNull List<Expression> 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);
|
this(name, arguments);
|
||||||
myQualifier = qualifier;
|
myQualifier = qualifier;
|
||||||
myConversions = conversions;
|
|
||||||
myAnonymousClass = anonymousClass;
|
myAnonymousClass = anonymousClass;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -53,8 +50,7 @@ public class NewClassExpression extends Expression {
|
|||||||
public String toKotlin() {
|
public String toKotlin() {
|
||||||
final String callOperator = myQualifier.isNullable() ? QUESTDOT : DOT;
|
final String callOperator = myQualifier.isNullable() ? QUESTDOT : DOT;
|
||||||
final String qualifier = myQualifier.isEmpty() ? EMPTY : myQualifier.toKotlin() + callOperator;
|
final String qualifier = myQualifier.isEmpty() ? EMPTY : myQualifier.toKotlin() + callOperator;
|
||||||
List<String> applyConversions = AstUtil.applyConversions(AstUtil.nodesToKotlin(myArguments), myConversions);
|
String appliedArguments = AstUtil.joinNodes(myArguments, COMMA_WITH_SPACE);
|
||||||
String appliedArguments = AstUtil.join(applyConversions, COMMA_WITH_SPACE);
|
|
||||||
return myAnonymousClass != null ?
|
return myAnonymousClass != null ?
|
||||||
"object" + SPACE + ":" + SPACE + qualifier + myName.toKotlin() + "(" + appliedArguments + ")" + myAnonymousClass.toKotlin()
|
"object" + SPACE + ":" + SPACE + qualifier + myName.toKotlin() + "(" + appliedArguments + ")" + myAnonymousClass.toKotlin()
|
||||||
:
|
:
|
||||||
|
|||||||
@@ -276,8 +276,7 @@ public class ExpressionVisitor extends StatementVisitor {
|
|||||||
return new NewClassExpression(
|
return new NewClassExpression(
|
||||||
getConverter().expressionToExpression(expression.getQualifier()),
|
getConverter().expressionToExpression(expression.getQualifier()),
|
||||||
getConverter().elementToElement(classReference),
|
getConverter().elementToElement(classReference),
|
||||||
getConverter().expressionsToExpressionList(arguments),
|
getConverter().argumentsToExpressionList(expression),
|
||||||
getConverter().createConversions(expression),
|
|
||||||
anonymousClass != null ? getConverter().anonymousClassToAnonymousClass(anonymousClass) : null
|
anonymousClass != null ? getConverter().anonymousClassToAnonymousClass(anonymousClass) : null
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,6 +2,6 @@ package demo
|
|||||||
open class Test(i : Int) {
|
open class Test(i : Int) {
|
||||||
open fun test() : Unit {
|
open fun test() : Unit {
|
||||||
var b : Byte = 10
|
var b : Byte = 10
|
||||||
Test((b).toInt())
|
Test(b.toInt())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -14,6 +14,6 @@ open fun putInt(i : Int) : Unit {
|
|||||||
}
|
}
|
||||||
open fun test() : Unit {
|
open fun test() : Unit {
|
||||||
putInt((One.myContainer?.myInt).sure())
|
putInt((One.myContainer?.myInt).sure())
|
||||||
IntContainer((One.myContainer?.myInt).sure())
|
IntContainer(One.myContainer?.myInt!!)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user