From ddee0deeca55d7f8b7a62076d2435c8d75c9835d Mon Sep 17 00:00:00 2001 From: Ilya Kirillov Date: Fri, 29 Mar 2019 15:03:56 +0300 Subject: [PATCH] New J2K: Move println conversion functionality to BuiltinMembersConversion --- .../kotlin/nj2k/ConversionsRunner.kt | 1 - .../conversions/BuiltinMembersConversion.kt | 38 ++++++++++++-- .../nj2k/conversions/PrintlnConversion.kt | 49 ------------------- 3 files changed, 35 insertions(+), 53 deletions(-) delete mode 100644 nj2k/src/org/jetbrains/kotlin/nj2k/conversions/PrintlnConversion.kt diff --git a/nj2k/src/org/jetbrains/kotlin/nj2k/ConversionsRunner.kt b/nj2k/src/org/jetbrains/kotlin/nj2k/ConversionsRunner.kt index f072fa85524..963bf8ae579 100644 --- a/nj2k/src/org/jetbrains/kotlin/nj2k/ConversionsRunner.kt +++ b/nj2k/src/org/jetbrains/kotlin/nj2k/ConversionsRunner.kt @@ -54,7 +54,6 @@ object ConversionsRunner { +StaticInitDeclarationConversion() +ImplicitInitializerConversion(context) +ParameterModificationInMethodCallsConversion(context) - +PrintlnConversion(context) +BlockToRunConversion(context) +PrimaryConstructorDetectConversion(context) +InsertDefaultPrimaryConstructorConversion(context) diff --git a/nj2k/src/org/jetbrains/kotlin/nj2k/conversions/BuiltinMembersConversion.kt b/nj2k/src/org/jetbrains/kotlin/nj2k/conversions/BuiltinMembersConversion.kt index 85b67da9c1b..d0783bcaa4f 100644 --- a/nj2k/src/org/jetbrains/kotlin/nj2k/conversions/BuiltinMembersConversion.kt +++ b/nj2k/src/org/jetbrains/kotlin/nj2k/conversions/BuiltinMembersConversion.kt @@ -43,10 +43,17 @@ class BuiltinMembersConversion(private val context: ConversionContext) : Recursi private fun JKExpression.getConversion(): Conversion? = when (this) { is JKMethodCallExpression -> conversions[identifier.deepestFqName()]?.firstOrNull { conversion -> - conversion.from is Method && conversion.byArgumentsFilter?.invoke(arguments.arguments.map { it.value }) ?: true + if (conversion.from !is Method) return@firstOrNull false + if (conversion.filter?.invoke(this) == false) return@firstOrNull false + if (conversion.byArgumentsFilter?.invoke(arguments.arguments.map { it.value }) == false) return@firstOrNull false + true } is JKFieldAccessExpression -> - conversions[identifier.deepestFqName()]?.firstOrNull { conversion -> conversion.from is Field } + conversions[identifier.deepestFqName()]?.firstOrNull { conversion -> + if (conversion.from !is Field) return@firstOrNull false + if (conversion.filter?.invoke(this) == false) return@firstOrNull false + true + } else -> null } @@ -150,6 +157,7 @@ class BuiltinMembersConversion(private val context: ConversionContext) : Recursi val from: SymbolInfo, val to: Info, val replaceType: ReplaceType = ReplaceType.REPLACE_SELECTOR, + val filter: ((JKExpression) -> Boolean)? = null, val byArgumentsFilter: ((List) -> Boolean)? = null, val argumentsProvider: ((JKArgumentList) -> JKArgumentList)? = null, val actionAfter: ((JKExpression) -> JKExpression)? = null @@ -161,6 +169,9 @@ class BuiltinMembersConversion(private val context: ConversionContext) : Recursi private infix fun Conversion.withReplaceType(replaceType: ReplaceType) = copy(replaceType = replaceType) + private infix fun Conversion.withFilter(filter: (JKExpression) -> Boolean) = + copy(filter = filter) + private infix fun Conversion.withByArgumentsFilter(filter: (List) -> Boolean) = copy(byArgumentsFilter = filter) @@ -168,12 +179,20 @@ class BuiltinMembersConversion(private val context: ConversionContext) : Recursi copy(argumentsProvider = argumentsProvider) private infix fun Conversion.andAfter(actionAfter: (JKExpression) -> JKExpression) = - copy(actionAfter = actionAfter) + copy(actionAfter = actionAfter).also { println() } private val conversions: Map> = listOf( Method("java.lang.Integer.intValue") convertTo Method("kotlin.Int.toInt"),//TODO do not list all variants + Method("java.io.PrintStream.println") convertTo Method("kotlin.io.println") + withReplaceType ReplaceType.FULL_REPLACE + withFilter ::isSystemOutCall, + + Method("java.io.PrintStream.print") convertTo Method("kotlin.io.print") + withReplaceType ReplaceType.FULL_REPLACE + withFilter ::isSystemOutCall, + Method("java.lang.Object.getClass") convertTo Field("kotlin.jvm.javaClass"), Method("java.util.Map.entrySet") convertTo Field("kotlin.collections.Map.entries"), @@ -378,6 +397,19 @@ class BuiltinMembersConversion(private val context: ConversionContext) : Recursi private fun JKExpression.callOn(symbol: JKMethodSymbol, vararg arguments: JKExpression) = callOn(symbol, arguments.map { JKArgumentImpl(it) }) + private fun isSystemOutCall(expression: JKExpression): Boolean = + expression.parent + ?.safeAs() + ?.receiver + ?.let { receiver -> + when (receiver) { + is JKFieldAccessExpression -> receiver + is JKQualifiedExpression -> receiver.selector as? JKFieldAccessExpression + else -> null + } + }?.identifier + ?.deepestFqName() == "java.lang.System.out" + private fun JKExpression.castToTypedArray() = callOn(context.symbolProvider.provideByFqName("kotlin.collections.toTypedArray", multiResolve = true)) diff --git a/nj2k/src/org/jetbrains/kotlin/nj2k/conversions/PrintlnConversion.kt b/nj2k/src/org/jetbrains/kotlin/nj2k/conversions/PrintlnConversion.kt deleted file mode 100644 index 58b5412b722..00000000000 --- a/nj2k/src/org/jetbrains/kotlin/nj2k/conversions/PrintlnConversion.kt +++ /dev/null @@ -1,49 +0,0 @@ -/* - * 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.nj2k.conversions - -import org.jetbrains.kotlin.name.ClassId -import org.jetbrains.kotlin.nj2k.ConversionContext -import org.jetbrains.kotlin.nj2k.tree.* -import org.jetbrains.kotlin.nj2k.tree.impl.JKKtCallExpressionImpl -import org.jetbrains.kotlin.nj2k.tree.impl.JKMethodSymbol -import org.jetbrains.kotlin.nj2k.tree.impl.psi - -// TODO: Full special methods conversion -class PrintlnConversion(private val context: ConversionContext) : RecursiveApplicableConversionBase() { - override fun applyToElement(element: JKTreeElement): JKTreeElement { - return if (element is JKQualifiedExpression) { - recurse(processQualified(element)) - } else { - recurse(element) - } - } - - private fun processQualified(element: JKQualifiedExpression): JKExpression { - val receiver = element.receiver as? JKQualifiedExpression ?: return element - val classReference = receiver.receiver as? JKClassAccessExpression ?: return element - if (classReference.identifier.fqName != "java.lang.System") return element - val fieldReference = receiver.selector as? JKFieldAccessExpression ?: return element - if (fieldReference.identifier.name != "out") return element - val selector = element.selector as? JKMethodCallExpression ?: return element - val functionName = selector.identifier.name - if (functionName != "println" && functionName != "print") return element - - val contextElement = element.parentOfType() ?: return element - val targetElements = multiResolveFqName(ClassId.fromString("kotlin/io/$functionName"), contextElement.psi!!) - if (targetElements.isEmpty()) return element - selector.invalidate() - - - return JKKtCallExpressionImpl( - context.symbolProvider.provideDirectSymbol(targetElements.first()) as JKMethodSymbol, - selector.arguments - ).withNonCodeElementsFrom(element).also { - it.leftNonCodeElements += element.receiver.commentsFromInside() - } - } - -} \ No newline at end of file