New J2K: Add FunctionAsAnonymousObjectToLambdaConversion & ReturnStatementInLambdaExpressionConversion conversions
This commit is contained in:
committed by
Ilya Kirillov
parent
a659fcd6af
commit
ef89a249f2
@@ -29,6 +29,8 @@ object ConversionsRunner {
|
||||
+AnnotationClassConversion(context)
|
||||
+AnnotationConversion(context)
|
||||
+ModalityConversion(context)
|
||||
+FunctionAsAnonymousObjectToLambdaConversion()
|
||||
+ReturnStatementInLambdaExpressionConversion()
|
||||
+BoxedTypeOperationsConversion(context)
|
||||
+AssignmentAsExpressionToAlsoConversion(context)
|
||||
+AssignmentStatementValCreationConversion(context)
|
||||
|
||||
@@ -695,7 +695,9 @@ class NewCodeBuilder {
|
||||
}
|
||||
|
||||
override fun visitReturnStatement(returnStatement: JKReturnStatement) {
|
||||
printer.print("return ")
|
||||
printer.print("return")
|
||||
returnStatement.label.accept(this)
|
||||
printer.print(" ")
|
||||
returnStatement.expression.accept(this)
|
||||
}
|
||||
|
||||
|
||||
+37
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
* Copyright 2010-2019 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.nj2k.tree.*
|
||||
import org.jetbrains.kotlin.nj2k.tree.impl.JKBlockStatementImpl
|
||||
import org.jetbrains.kotlin.nj2k.tree.impl.JKClassSymbol
|
||||
import org.jetbrains.kotlin.nj2k.tree.impl.JKLambdaExpressionImpl
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
||||
|
||||
class FunctionAsAnonymousObjectToLambdaConversion : RecursiveApplicableConversionBase() {
|
||||
override fun applyToElement(element: JKTreeElement): JKTreeElement {
|
||||
if (element !is JKJavaNewExpression) return recurse(element)
|
||||
if (element.isAnonymousClass()
|
||||
&& element.classSymbol.isKtFunction()
|
||||
) {
|
||||
val invokeFunction = element.classBody.declarations.singleOrNull()
|
||||
?.safeAs<JKMethod>()
|
||||
?.takeIf { it.name.value == "invoke" }
|
||||
?: return recurse(element)
|
||||
return recurse(
|
||||
JKLambdaExpressionImpl(
|
||||
JKBlockStatementImpl(invokeFunction::block.detached()),
|
||||
invokeFunction::parameters.detached()
|
||||
)
|
||||
)
|
||||
}
|
||||
return recurse(element)
|
||||
}
|
||||
|
||||
private fun JKClassSymbol.isKtFunction() =
|
||||
fqName.matches("""kotlin\.Function(\d+)""".toRegex())
|
||||
|| fqName.matches("""kotlin\.jvm\.functions\.Function(\d+)""".toRegex())
|
||||
}
|
||||
+74
@@ -0,0 +1,74 @@
|
||||
/*
|
||||
* Copyright 2010-2019 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.nj2k.asStatement
|
||||
import org.jetbrains.kotlin.nj2k.copyTreeAndDetach
|
||||
import org.jetbrains.kotlin.nj2k.tree.*
|
||||
import org.jetbrains.kotlin.nj2k.tree.impl.JKLabelTextImpl
|
||||
import org.jetbrains.kotlin.nj2k.tree.impl.JKLabeledStatementImpl
|
||||
import org.jetbrains.kotlin.nj2k.tree.impl.JKNameIdentifierImpl
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
||||
|
||||
class ReturnStatementInLambdaExpressionConversion : RecursiveApplicableConversionBase() {
|
||||
companion object {
|
||||
const val DEFAULT_LABEL_NAME = "label"
|
||||
}
|
||||
|
||||
override fun applyToElement(element: JKTreeElement): JKTreeElement {
|
||||
if (element !is JKLambdaExpression) return recurse(element)
|
||||
val statement = element.statement
|
||||
if (statement is JKReturnStatement) {
|
||||
element.statement = statement::expression.detached().asStatement()
|
||||
return recurse(element)
|
||||
}
|
||||
if (statement is JKBlockStatement) {
|
||||
val statements = statement.block.statements
|
||||
val last = statements.lastOrNull()
|
||||
if (last is JKReturnStatement) {
|
||||
statement.block.statements -= last
|
||||
statement.block.statements += last::expression.detached().asStatement()
|
||||
}
|
||||
}
|
||||
val parentMethodName = element.parent?.parent?.parent.safeAs<JKMethodCallExpression>()?.identifier?.name
|
||||
if (parentMethodName == null) {
|
||||
val atLeastOneReturnStatementExists = applyLabelToAllReturnStatements(statement, element, DEFAULT_LABEL_NAME)
|
||||
return if (atLeastOneReturnStatementExists) {
|
||||
JKLabeledStatementImpl(
|
||||
recurse(element.copyTreeAndDetach()).asStatement(),
|
||||
listOf(JKNameIdentifierImpl(DEFAULT_LABEL_NAME))
|
||||
)
|
||||
} else recurse(element)
|
||||
}
|
||||
applyLabelToAllReturnStatements(statement, element, parentMethodName)
|
||||
return recurse(element)
|
||||
}
|
||||
|
||||
|
||||
private fun applyLabelToAllReturnStatements(
|
||||
statement: JKStatement,
|
||||
lambdaExpression: JKLambdaExpression,
|
||||
label: String
|
||||
): Boolean {
|
||||
var atLeastOneReturnStatementExists = false
|
||||
fun addLabelToReturnStatement(returnStatement: JKReturnStatement) {
|
||||
if (returnStatement.label is JKLabelEmpty && returnStatement.parentOfType<JKLambdaExpression>() == lambdaExpression) {
|
||||
atLeastOneReturnStatementExists = true
|
||||
returnStatement.label = JKLabelTextImpl(JKNameIdentifierImpl(label))
|
||||
}
|
||||
}
|
||||
|
||||
fun fixAllReturnStatements(element: JKTreeElement): JKTreeElement {
|
||||
if (element !is JKReturnStatement) return applyRecursive(element, ::fixAllReturnStatements)
|
||||
addLabelToReturnStatement(element)
|
||||
return applyRecursive(element, ::fixAllReturnStatements)
|
||||
}
|
||||
|
||||
|
||||
applyRecursive(statement, ::fixAllReturnStatements)
|
||||
return atLeastOneReturnStatementExists
|
||||
}
|
||||
}
|
||||
@@ -269,7 +269,7 @@ object JKJavaVoidType : JKType {
|
||||
set(it) {}
|
||||
}
|
||||
|
||||
class JKJavaArrayTypeImpl(override val type: JKType, override var nullability: Nullability = Nullability.Default) : JKJavaArrayType {
|
||||
data class JKJavaArrayTypeImpl(override val type: JKType, override var nullability: Nullability = Nullability.Default) : JKJavaArrayType {
|
||||
}
|
||||
|
||||
class JKJavaDisjunctionTypeImpl(
|
||||
@@ -277,10 +277,14 @@ class JKJavaDisjunctionTypeImpl(
|
||||
override val nullability: Nullability = Nullability.Default
|
||||
) : JKJavaDisjunctionType
|
||||
|
||||
class JKReturnStatementImpl(expression: JKExpression) : JKBranchElementBase(), JKReturnStatement, PsiOwner by PsiOwnerImpl() {
|
||||
class JKReturnStatementImpl(
|
||||
expression: JKExpression,
|
||||
label: JKLabel = JKLabelEmptyImpl()
|
||||
) : JKBranchElementBase(), JKReturnStatement, PsiOwner by PsiOwnerImpl() {
|
||||
override fun <R, D> accept(visitor: JKVisitor<R, D>, data: D): R = visitor.visitReturnStatement(this, data)
|
||||
|
||||
override val expression by child(expression)
|
||||
override var label by child(label)
|
||||
}
|
||||
|
||||
class JKJavaAssertStatementImpl(condition: JKExpression, description: JKExpression) : JKJavaAssertStatement, JKBranchElementBase(), PsiOwner by PsiOwnerImpl() {
|
||||
|
||||
@@ -63,6 +63,7 @@ interface JKJavaLiteralExpression : JKLiteralExpression
|
||||
|
||||
interface JKReturnStatement : JKStatement {
|
||||
val expression: JKExpression
|
||||
var label: JKLabel
|
||||
}
|
||||
|
||||
interface JKJavaAssertStatement : JKStatement {
|
||||
|
||||
Reference in New Issue
Block a user