From f14aa2292f8d171ff4c8e12360b120548b287559 Mon Sep 17 00:00:00 2001 From: Ilya Kirillov Date: Tue, 4 Dec 2018 20:45:16 +0300 Subject: [PATCH] New J2K: Implement primitive type case for ImplicitInitializerConversion --- .../jetbrains/kotlin/j2k/ConversionsRunner.kt | 1 + .../kotlin/j2k/JavaToJKTreeBuilder.kt | 9 ++- .../ImplicitInitializerConversion.kt | 22 ++++++-- .../j2k/conversions/LiteralConversion.kt | 8 ++- .../PrimitiveTypesInitializersConversion.kt | 55 +++++++++++++++++++ .../org/jetbrains/kotlin/j2k/tree/types.kt | 33 ++++++++++- 6 files changed, 120 insertions(+), 8 deletions(-) create mode 100644 j2k/newSrc/org/jetbrains/kotlin/j2k/conversions/PrimitiveTypesInitializersConversion.kt diff --git a/j2k/newSrc/org/jetbrains/kotlin/j2k/ConversionsRunner.kt b/j2k/newSrc/org/jetbrains/kotlin/j2k/ConversionsRunner.kt index 2e27961d17b..27a00ded40e 100644 --- a/j2k/newSrc/org/jetbrains/kotlin/j2k/ConversionsRunner.kt +++ b/j2k/newSrc/org/jetbrains/kotlin/j2k/ConversionsRunner.kt @@ -37,6 +37,7 @@ object ConversionsRunner { +ArrayInitializerConversion(context) +TryStatementConversion(context) +ImplicitInitializerConversion() + +PrimitiveTypesInitializersConversion(context) +DefaultArgumentsConversion(context) +FieldToPropertyConversion(context) +PrintlnConversion(context) diff --git a/j2k/newSrc/org/jetbrains/kotlin/j2k/JavaToJKTreeBuilder.kt b/j2k/newSrc/org/jetbrains/kotlin/j2k/JavaToJKTreeBuilder.kt index d1641a18242..a2311ea5e1a 100644 --- a/j2k/newSrc/org/jetbrains/kotlin/j2k/JavaToJKTreeBuilder.kt +++ b/j2k/newSrc/org/jetbrains/kotlin/j2k/JavaToJKTreeBuilder.kt @@ -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 { diff --git a/j2k/newSrc/org/jetbrains/kotlin/j2k/conversions/ImplicitInitializerConversion.kt b/j2k/newSrc/org/jetbrains/kotlin/j2k/conversions/ImplicitInitializerConversion.kt index 786fca2fbc0..3a8c8046548 100644 --- a/j2k/newSrc/org/jetbrains/kotlin/j2k/conversions/ImplicitInitializerConversion.kt +++ b/j2k/newSrc/org/jetbrains/kotlin/j2k/conversions/ImplicitInitializerConversion.kt @@ -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) + } + } \ No newline at end of file diff --git a/j2k/newSrc/org/jetbrains/kotlin/j2k/conversions/LiteralConversion.kt b/j2k/newSrc/org/jetbrains/kotlin/j2k/conversions/LiteralConversion.kt index 6fa3c7b4de1..0a9ca05c047 100644 --- a/j2k/newSrc/org/jetbrains/kotlin/j2k/conversions/LiteralConversion.kt +++ b/j2k/newSrc/org/jetbrains/kotlin/j2k/conversions/LiteralConversion.kt @@ -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 ) } diff --git a/j2k/newSrc/org/jetbrains/kotlin/j2k/conversions/PrimitiveTypesInitializersConversion.kt b/j2k/newSrc/org/jetbrains/kotlin/j2k/conversions/PrimitiveTypesInitializersConversion.kt new file mode 100644 index 00000000000..7e065165ea1 --- /dev/null +++ b/j2k/newSrc/org/jetbrains/kotlin/j2k/conversions/PrimitiveTypesInitializersConversion.kt @@ -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() + ) + ) + } +} \ 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 60652aafed4..72d0f1566ee 100644 --- a/j2k/newSrc/org/jetbrains/kotlin/j2k/tree/types.kt +++ b/j2k/newSrc/org/jetbrains/kotlin/j2k/tree/types.kt @@ -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) -} \ No newline at end of file +} + +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 \ No newline at end of file