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()
|
+StaticInitDeclarationConversion()
|
||||||
+ImplicitInitializerConversion(context)
|
+ImplicitInitializerConversion(context)
|
||||||
+ParameterModificationInMethodCallsConversion(context)
|
+ParameterModificationInMethodCallsConversion(context)
|
||||||
+PrintlnConversion(context)
|
|
||||||
+BlockToRunConversion(context)
|
+BlockToRunConversion(context)
|
||||||
+PrimaryConstructorDetectConversion(context)
|
+PrimaryConstructorDetectConversion(context)
|
||||||
+InsertDefaultPrimaryConstructorConversion(context)
|
+InsertDefaultPrimaryConstructorConversion(context)
|
||||||
|
|||||||
@@ -43,10 +43,17 @@ class BuiltinMembersConversion(private val context: ConversionContext) : Recursi
|
|||||||
private fun JKExpression.getConversion(): Conversion? = when (this) {
|
private fun JKExpression.getConversion(): Conversion? = when (this) {
|
||||||
is JKMethodCallExpression ->
|
is JKMethodCallExpression ->
|
||||||
conversions[identifier.deepestFqName()]?.firstOrNull { conversion ->
|
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 ->
|
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
|
else -> null
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -150,6 +157,7 @@ class BuiltinMembersConversion(private val context: ConversionContext) : Recursi
|
|||||||
val from: SymbolInfo,
|
val from: SymbolInfo,
|
||||||
val to: Info,
|
val to: Info,
|
||||||
val replaceType: ReplaceType = ReplaceType.REPLACE_SELECTOR,
|
val replaceType: ReplaceType = ReplaceType.REPLACE_SELECTOR,
|
||||||
|
val filter: ((JKExpression) -> Boolean)? = null,
|
||||||
val byArgumentsFilter: ((List<JKExpression>) -> Boolean)? = null,
|
val byArgumentsFilter: ((List<JKExpression>) -> Boolean)? = null,
|
||||||
val argumentsProvider: ((JKArgumentList) -> JKArgumentList)? = null,
|
val argumentsProvider: ((JKArgumentList) -> JKArgumentList)? = null,
|
||||||
val actionAfter: ((JKExpression) -> JKExpression)? = null
|
val actionAfter: ((JKExpression) -> JKExpression)? = null
|
||||||
@@ -161,6 +169,9 @@ class BuiltinMembersConversion(private val context: ConversionContext) : Recursi
|
|||||||
private infix fun Conversion.withReplaceType(replaceType: ReplaceType) =
|
private infix fun Conversion.withReplaceType(replaceType: ReplaceType) =
|
||||||
copy(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) =
|
private infix fun Conversion.withByArgumentsFilter(filter: (List<JKExpression>) -> Boolean) =
|
||||||
copy(byArgumentsFilter = filter)
|
copy(byArgumentsFilter = filter)
|
||||||
|
|
||||||
@@ -168,12 +179,20 @@ class BuiltinMembersConversion(private val context: ConversionContext) : Recursi
|
|||||||
copy(argumentsProvider = argumentsProvider)
|
copy(argumentsProvider = argumentsProvider)
|
||||||
|
|
||||||
private infix fun Conversion.andAfter(actionAfter: (JKExpression) -> JKExpression) =
|
private infix fun Conversion.andAfter(actionAfter: (JKExpression) -> JKExpression) =
|
||||||
copy(actionAfter = actionAfter)
|
copy(actionAfter = actionAfter).also { println() }
|
||||||
|
|
||||||
private val conversions: Map<String, List<Conversion>> =
|
private val conversions: Map<String, List<Conversion>> =
|
||||||
listOf(
|
listOf(
|
||||||
Method("java.lang.Integer.intValue") convertTo Method("kotlin.Int.toInt"),//TODO do not list all variants
|
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.lang.Object.getClass") convertTo Field("kotlin.jvm.javaClass"),
|
||||||
|
|
||||||
Method("java.util.Map.entrySet") convertTo Field("kotlin.collections.Map.entries"),
|
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) =
|
private fun JKExpression.callOn(symbol: JKMethodSymbol, vararg arguments: JKExpression) =
|
||||||
callOn(symbol, arguments.map { JKArgumentImpl(it) })
|
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() =
|
private fun JKExpression.castToTypedArray() =
|
||||||
callOn(context.symbolProvider.provideByFqName("kotlin.collections.toTypedArray", multiResolve = true))
|
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