New J2K: Move println conversion functionality to BuiltinMembersConversion

This commit is contained in:
Ilya Kirillov
2019-03-29 15:03:56 +03:00
committed by Ilya Kirillov
parent ce666295f7
commit ddee0deeca
3 changed files with 35 additions and 53 deletions
@@ -54,7 +54,6 @@ object ConversionsRunner {
+StaticInitDeclarationConversion()
+ImplicitInitializerConversion(context)
+ParameterModificationInMethodCallsConversion(context)
+PrintlnConversion(context)
+BlockToRunConversion(context)
+PrimaryConstructorDetectConversion(context)
+InsertDefaultPrimaryConstructorConversion(context)
@@ -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<JKExpression>) -> 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<JKExpression>) -> 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<String, List<Conversion>> =
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<JKQualifiedExpression>()
?.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))
@@ -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<JKClass>() ?: 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()
}
}
}