New J2K: Move println conversion functionality to BuiltinMembersConversion
This commit is contained in:
committed by
Ilya Kirillov
parent
ce666295f7
commit
ddee0deeca
@@ -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()
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user