From f9a08ad7709e3bfe23a54c406df7685e6522b4e3 Mon Sep 17 00:00:00 2001 From: Ilya Kirillov Date: Mon, 28 Jan 2019 12:08:37 +0300 Subject: [PATCH] New J2K: Add BoxedTypeOperationsConversion --- .../jetbrains/kotlin/j2k/ConversionsRunner.kt | 1 + .../BoxedTypeOperationsConversion.kt | 63 +++++++++++++++++++ .../org/jetbrains/kotlin/j2k/tree/types.kt | 16 ++++- 3 files changed, 79 insertions(+), 1 deletion(-) create mode 100644 j2k/newSrc/org/jetbrains/kotlin/j2k/conversions/BoxedTypeOperationsConversion.kt diff --git a/j2k/newSrc/org/jetbrains/kotlin/j2k/ConversionsRunner.kt b/j2k/newSrc/org/jetbrains/kotlin/j2k/ConversionsRunner.kt index b24c61e38bf..623d118d653 100644 --- a/j2k/newSrc/org/jetbrains/kotlin/j2k/ConversionsRunner.kt +++ b/j2k/newSrc/org/jetbrains/kotlin/j2k/ConversionsRunner.kt @@ -29,6 +29,7 @@ object ConversionsRunner { +AnnotationClassConversion(context) +AnnotationConversion(context) +ModalityConversion(context) + +BoxedTypeOperationsConversion(context) +AssignmentAsExpressionToAlsoConversion(context) +AssignmentStatementValCreationConversion(context) +AssignmentStatementOperatorConversion() diff --git a/j2k/newSrc/org/jetbrains/kotlin/j2k/conversions/BoxedTypeOperationsConversion.kt b/j2k/newSrc/org/jetbrains/kotlin/j2k/conversions/BoxedTypeOperationsConversion.kt new file mode 100644 index 00000000000..e2637fe152b --- /dev/null +++ b/j2k/newSrc/org/jetbrains/kotlin/j2k/conversions/BoxedTypeOperationsConversion.kt @@ -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() + } +} \ No newline at end of file diff --git a/j2k/newSrc/org/jetbrains/kotlin/j2k/tree/types.kt b/j2k/newSrc/org/jetbrains/kotlin/j2k/tree/types.kt index e8449f22e55..cd1076d46a7 100644 --- a/j2k/newSrc/org/jetbrains/kotlin/j2k/tree/types.kt +++ b/j2k/newSrc/org/jetbrains/kotlin/j2k/tree/types.kt @@ -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