New J2K: Implement primitive type case for ImplicitInitializerConversion

This commit is contained in:
Ilya Kirillov
2018-12-04 20:45:16 +03:00
committed by Ilya Kirillov
parent fb3c7e87a1
commit f14aa2292f
6 changed files with 120 additions and 8 deletions
@@ -37,6 +37,7 @@ object ConversionsRunner {
+ArrayInitializerConversion(context)
+TryStatementConversion(context)
+ImplicitInitializerConversion()
+PrimitiveTypesInitializersConversion(context)
+DefaultArgumentsConversion(context)
+FieldToPropertyConversion(context)
+PrintlnConversion(context)
@@ -135,7 +135,14 @@ class JavaToJKTreeBuilder(var symbolProvider: JKSymbolProvider) {
fun PsiJavaToken.toJK(): JKOperator = JKJavaOperatorImpl.tokenToOperator[tokenType] ?: error("Unsupported token-type: $tokenType")
fun PsiPrefixExpression.toJK(): JKExpression {
return JKPrefixExpressionImpl(operand.toJK(), operationSign.toJK())
return JKPrefixExpressionImpl(operand.toJK(), operationSign.toJK()).let {
if (it.operator.token.text in listOf("+", "-") && it.expression is JKLiteralExpression) {
JKJavaLiteralExpressionImpl(
it.operator.token.text + (it.expression as JKLiteralExpression).literal,
(it.expression as JKLiteralExpression).type
)
} else it
}
}
fun PsiPostfixExpression.toJK(): JKExpression {
@@ -6,8 +6,7 @@
package org.jetbrains.kotlin.j2k.conversions
import org.jetbrains.kotlin.j2k.tree.*
import org.jetbrains.kotlin.j2k.tree.impl.JKNullLiteral
import org.jetbrains.kotlin.j2k.tree.impl.JKUnresolvedClassType
import org.jetbrains.kotlin.j2k.tree.impl.*
class ImplicitInitializerConversion : RecursiveApplicableConversionBase() {
override fun applyToElement(element: JKTreeElement): JKTreeElement {
@@ -15,9 +14,24 @@ class ImplicitInitializerConversion : RecursiveApplicableConversionBase() {
if (element.initializer !is JKStubExpression) return recurse(element)
if (element.type.type is JKClassType || element.type.type is JKUnresolvedClassType) element.initializer = JKNullLiteral()
val fieldType = element.type.type
val newInitializer = when (fieldType) {
is JKClassType, is JKUnresolvedClassType -> JKNullLiteral()
is JKJavaPrimitiveType -> createPrimitiveTypeInitializer(fieldType)
else -> null
}
newInitializer?.also {
element.initializer = it
}
return element
}
fun createPrimitiveTypeInitializer(primitiveType: JKJavaPrimitiveType): JKJavaLiteralExpression =
when (primitiveType) {
is JKJavaPrimitiveTypeImpl.BOOLEAN ->
JKJavaLiteralExpressionImpl("false", JKLiteralExpression.LiteralType.BOOLEAN)
else ->
JKJavaLiteralExpressionImpl("0", JKLiteralExpression.LiteralType.INT)
}
}
@@ -31,6 +31,8 @@ class LiteralConversion : RecursiveApplicableConversionBase() {
text
.replace("d", "", true)
.replace(".e", "e", true)
.replace(".f", "", true)
.replace("f", "", true)
if (!newText.contains(".") && !newText.contains("e", true))
newText += "."
@@ -47,7 +49,11 @@ class LiteralConversion : RecursiveApplicableConversionBase() {
return JKKtLiteralExpressionImpl(
text.replace(".f", "f", true)
.replace("F", "f")
.replace(".e", "e", true),
.replace(".e", "e", true)
.let {
if (!it.endsWith("f")) "${it}f"
else it
},
FLOAT
)
}
@@ -0,0 +1,55 @@
/*
* Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
* that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.j2k.conversions
import org.jetbrains.kotlin.j2k.ConversionContext
import org.jetbrains.kotlin.j2k.copyTree
import org.jetbrains.kotlin.j2k.copyTreeAndDetach
import org.jetbrains.kotlin.j2k.tree.*
import org.jetbrains.kotlin.j2k.tree.impl.*
class PrimitiveTypesInitializersConversion(private val context: ConversionContext) : RecursiveApplicableConversionBase() {
override fun applyToElement(element: JKTreeElement): JKTreeElement {
if (element !is JKJavaField) return recurse(element)
val literalInitializer = element.initializer as? JKJavaLiteralExpression ?: return recurse(element)
val literalType = literalInitializer.type.toPrimitiveType() ?: return recurse(element)
val fieldType = element.type.type as? JKJavaPrimitiveType ?: return recurse(element)
createPrimitiveTypeInitializer(literalInitializer.copyTreeAndDetach(), literalType, fieldType)?.also {
element.initializer = it
}
return element
}
private fun createPrimitiveTypeInitializer(
literal: JKJavaLiteralExpression,
literalType: JKJavaPrimitiveType,
fieldType: JKJavaPrimitiveType
): JKExpression? {
if (literalType == fieldType) return null
if (literalType == JKJavaPrimitiveTypeImpl.INT
&& fieldType == JKJavaPrimitiveTypeImpl.LONG
) return null
if (literalType.isNumberType() && fieldType.isNumberType()) {
return JKJavaLiteralExpressionImpl(
literal.literal,
fieldType.toLiteralType() ?: JKLiteralExpression.LiteralType.INT
)
}
val conversionFunctionName = "to${fieldType.jvmPrimitiveType.javaKeywordName.capitalize()}"
return JKQualifiedExpressionImpl(
literal,
JKKtQualifierImpl.DOT,
JKJavaMethodCallExpressionImpl(
context.symbolProvider.provideByFqName("kotlin.$conversionFunctionName"),
JKExpressionListImpl()
)
)
}
}
@@ -6,7 +6,6 @@
package org.jetbrains.kotlin.j2k.tree
import com.intellij.psi.*
import com.intellij.util.reverse
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
import org.jetbrains.kotlin.descriptors.ClassDescriptor
import org.jetbrains.kotlin.idea.caches.resolve.analyze
@@ -164,4 +163,34 @@ fun JKType.isCollectionType(symbolProvider: JKSymbolProvider): Boolean {
if (this !is JKClassType) return false
val collectionType = JKClassTypeImpl(symbolProvider.provideByFqName("java.util.Collection"), emptyList())
return this.isSubtypeOf(collectionType, symbolProvider)
}
}
fun JKLiteralExpression.LiteralType.toPrimitiveType(): JKJavaPrimitiveType? =
when (this) {
JKLiteralExpression.LiteralType.CHAR -> JKJavaPrimitiveTypeImpl.CHAR
JKLiteralExpression.LiteralType.BOOLEAN -> JKJavaPrimitiveTypeImpl.BOOLEAN
JKLiteralExpression.LiteralType.INT -> JKJavaPrimitiveTypeImpl.INT
JKLiteralExpression.LiteralType.LONG -> JKJavaPrimitiveTypeImpl.LONG
JKLiteralExpression.LiteralType.FLOAT -> JKJavaPrimitiveTypeImpl.FLOAT
JKLiteralExpression.LiteralType.DOUBLE -> JKJavaPrimitiveTypeImpl.DOUBLE
JKLiteralExpression.LiteralType.STRING -> null
JKLiteralExpression.LiteralType.NULL -> null
}
fun JKJavaPrimitiveType.toLiteralType(): JKLiteralExpression.LiteralType? =
when (this) {
JKJavaPrimitiveTypeImpl.CHAR -> JKLiteralExpression.LiteralType.CHAR
JKJavaPrimitiveTypeImpl.BOOLEAN -> JKLiteralExpression.LiteralType.BOOLEAN
JKJavaPrimitiveTypeImpl.INT -> JKLiteralExpression.LiteralType.INT
JKJavaPrimitiveTypeImpl.LONG -> JKLiteralExpression.LiteralType.LONG
JKJavaPrimitiveTypeImpl.CHAR -> JKLiteralExpression.LiteralType.CHAR
JKJavaPrimitiveTypeImpl.DOUBLE -> JKLiteralExpression.LiteralType.DOUBLE
JKJavaPrimitiveTypeImpl.FLOAT -> JKLiteralExpression.LiteralType.FLOAT
else -> null
}
fun JKJavaPrimitiveType.isNumberType() =
this == JKJavaPrimitiveTypeImpl.INT ||
this == JKJavaPrimitiveTypeImpl.LONG ||
this == JKJavaPrimitiveTypeImpl.FLOAT ||
this == JKJavaPrimitiveTypeImpl.DOUBLE