New J2K: Add BoxedTypeOperationsConversion

This commit is contained in:
Ilya Kirillov
2019-01-28 12:08:37 +03:00
committed by Ilya Kirillov
parent 8b12a9f723
commit f9a08ad770
3 changed files with 79 additions and 1 deletions
@@ -29,6 +29,7 @@ object ConversionsRunner {
+AnnotationClassConversion(context)
+AnnotationConversion(context)
+ModalityConversion(context)
+BoxedTypeOperationsConversion(context)
+AssignmentAsExpressionToAlsoConversion(context)
+AssignmentStatementValCreationConversion(context)
+AssignmentStatementOperatorConversion()
@@ -0,0 +1,63 @@
/*
* Copyright 2010-2019 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.tree.*
import org.jetbrains.kotlin.j2k.tree.impl.JKExpressionListImpl
import org.jetbrains.kotlin.j2k.tree.impl.JKKtCallExpressionImpl
import org.jetbrains.kotlin.resolve.jvm.JvmPrimitiveType
class BoxedTypeOperationsConversion(private val context: ConversionContext) : RecursiveApplicableConversionBase() {
override fun applyToElement(element: JKTreeElement): JKTreeElement {
return recurse(
when (element) {
is JKMethodCallExpression ->
convertBoxedTypeUnwrapping(element)
is JKJavaNewExpression -> convertCreationOfBoxedType(element)
else -> null
} ?: element
)
}
private fun convertCreationOfBoxedType(newExpression: JKJavaNewExpression): JKExpression? {
if (newExpression.classSymbol.fqName !in boxedTypeFqNames) return null
val singleArgument = newExpression.arguments.expressions.singleOrNull() ?: return null
return singleArgument.detached(newExpression.arguments)
}
private fun convertBoxedTypeUnwrapping(methodCallExpression: JKMethodCallExpression): JKExpression? {
val (boxedJavaType, operationType) =
primitiveTypeUnwrapRegexp.matchEntire(methodCallExpression.identifier.fqName)
?.groupValues
?.let {
it[1] to it[2]
} ?: return null
val primitiveTypeName = boxedTypeToPrimitiveType[boxedJavaType] ?: return null
if (operationType !in primitiveTypeNames) return null
return JKKtCallExpressionImpl(
context.symbolProvider.provideByFqName(
"kotlin.${primitiveTypeName.capitalize()}.to${operationType.capitalize()}"
),
JKExpressionListImpl()
)
}
companion object {
private val boxedTypeFqNames =
primitiveTypes.map { it.wrapperFqName.asString() }
private val boxedTypeToPrimitiveType =
primitiveTypes.map { it.wrapperFqName.asString() to it.javaKeywordName }.toMap()
private val primitiveTypeNames =
primitiveTypes.map { it.javaKeywordName }
private val primitiveTypeUnwrapRegexp =
"""([\w.]+)\.(\w+)Value""".toRegex()
}
}
@@ -22,7 +22,9 @@ import org.jetbrains.kotlin.js.descriptorUtils.getJetTypeFqName
import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.resolve.BindingContext
import org.jetbrains.kotlin.resolve.jvm.JvmPrimitiveType
import org.jetbrains.kotlin.types.KotlinType
import org.jetbrains.kotlin.types.isNullable
import org.jetbrains.kotlin.types.typeUtil.isSubtypeOf
fun JKExpression.type(symbolProvider: JKSymbolProvider): JKType? =
@@ -59,7 +61,7 @@ fun JKExpression.type(symbolProvider: JKSymbolProvider): JKType? =
JKClassTypeImpl(symbol, listOf(classType.type), Nullability.NotNull)
}
is JKKtAnnotationArrayInitializerExpression -> JKNoTypeImpl //TODO
is JKLambdaExpression -> returnType.type
else -> TODO(this::class.java.toString())
}
@@ -291,6 +293,18 @@ fun JKClassSymbol.expectedTypeParametersCount(): Int {
}
}
val primitiveTypes =
listOf(
JvmPrimitiveType.BOOLEAN,
JvmPrimitiveType.CHAR,
JvmPrimitiveType.BYTE,
JvmPrimitiveType.SHORT,
JvmPrimitiveType.INT,
JvmPrimitiveType.FLOAT,
JvmPrimitiveType.LONG,
JvmPrimitiveType.DOUBLE
)
fun JKClassSymbol.isArrayType(): Boolean =
fqName in
JKJavaPrimitiveTypeImpl.KEYWORD_TO_INSTANCE.values