New J2K: Implement Array init conversions
This commit is contained in:
@@ -23,6 +23,7 @@ object ConversionsRunner {
|
||||
|
||||
private fun createRootConversion(context: ConversionContext) =
|
||||
batchPipe {
|
||||
+ArrayInitializerConversion(context)
|
||||
+ModalityConversion(context)
|
||||
+ImplicitInitializerConversion()
|
||||
+DefaultArgumentsConversion(context)
|
||||
|
||||
@@ -29,6 +29,7 @@ import org.jetbrains.kotlin.j2k.ast.Nullability
|
||||
import org.jetbrains.kotlin.j2k.tree.*
|
||||
import org.jetbrains.kotlin.j2k.tree.JKLiteralExpression.LiteralType.*
|
||||
import org.jetbrains.kotlin.j2k.tree.impl.*
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
||||
|
||||
|
||||
class JavaToJKTreeBuilder(var symbolProvider: JKSymbolProvider) {
|
||||
@@ -161,27 +162,33 @@ class JavaToJKTreeBuilder(var symbolProvider: JKSymbolProvider) {
|
||||
}
|
||||
|
||||
fun PsiArrayInitializerExpression.toJK(): JKExpression {
|
||||
return JKJavaNewArrayImpl(initializers.map { it.toJK() })
|
||||
return JKJavaNewArrayImpl(
|
||||
initializers.map { it.toJK() },
|
||||
JKTypeElementImpl(type?.toJK().safeAs<JKJavaArrayType>()?.type ?: JKContextType)
|
||||
)
|
||||
}
|
||||
|
||||
fun PsiNewExpression.toJK(): JKExpression {
|
||||
assert(this is PsiNewExpressionImpl)
|
||||
if ((this as PsiNewExpressionImpl).findChildByRole(ChildRole.LBRACKET) != null) {
|
||||
require(this is PsiNewExpressionImpl)
|
||||
if (findChildByRole(ChildRole.LBRACKET) != null) {
|
||||
return arrayInitializer?.toJK() ?: run {
|
||||
val dimensions = mutableListOf<PsiLiteralExpression?>()
|
||||
val dimensions = mutableListOf<PsiExpression?>()
|
||||
var child = firstChild
|
||||
while (child != null) {
|
||||
if (child.node.elementType == JavaTokenType.LBRACKET) {
|
||||
child = child.nextSibling
|
||||
if (child.node.elementType == JavaTokenType.RBRACKET) {
|
||||
dimensions.add(null)
|
||||
dimensions += if (child.node.elementType == JavaTokenType.RBRACKET) {
|
||||
null
|
||||
} else {
|
||||
dimensions.add(child as PsiLiteralExpression?)
|
||||
child as PsiExpression? //TODO
|
||||
}
|
||||
}
|
||||
child = child.nextSibling
|
||||
}
|
||||
JKJavaNewEmptyArrayImpl(dimensions.map { it?.toJK() })
|
||||
JKJavaNewEmptyArrayImpl(
|
||||
dimensions.map { it?.toJK() ?: JKStubExpressionImpl() },
|
||||
JKTypeElementImpl(generateSequence(type?.toJK()) { it.safeAs<JKJavaArrayType>()?.type }.last())
|
||||
)
|
||||
}
|
||||
}
|
||||
val constructedClass = classOrAnonymousClassReference?.resolve()
|
||||
|
||||
@@ -24,7 +24,6 @@ import org.jetbrains.kotlin.j2k.tree.impl.*
|
||||
import org.jetbrains.kotlin.j2k.tree.visitors.JKVisitorVoid
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.utils.Printer
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.firstIsInstanceOrNull
|
||||
|
||||
class NewCodeBuilder {
|
||||
|
||||
@@ -274,6 +273,15 @@ class NewCodeBuilder {
|
||||
|
||||
override fun visitMethodCallExpression(methodCallExpression: JKMethodCallExpression) {
|
||||
printer.printWithNoIndent(FqName(methodCallExpression.identifier.fqName).shortName().asString())
|
||||
if (methodCallExpression.typeArguments.isNotEmpty()) {
|
||||
printer.printWithNoIndent("<")
|
||||
methodCallExpression.typeArguments.firstOrNull()?.accept(this)
|
||||
for (i in 1..methodCallExpression.typeArguments.lastIndex) {
|
||||
printer.printWithNoIndent(", ")
|
||||
methodCallExpression.typeArguments[i].accept(this)
|
||||
}
|
||||
printer.printWithNoIndent(">")
|
||||
}
|
||||
printer.par {
|
||||
methodCallExpression.arguments.accept(this)
|
||||
}
|
||||
@@ -312,7 +320,7 @@ class NewCodeBuilder {
|
||||
}
|
||||
|
||||
printer.printWithNoIndent(" ", localVariable.name.value)
|
||||
if(localVariable.type.type != JKContextType) {
|
||||
if (localVariable.type.type != JKContextType) {
|
||||
printer.printWithNoIndent(": ")
|
||||
localVariable.type.accept(this)
|
||||
}
|
||||
@@ -347,9 +355,7 @@ class NewCodeBuilder {
|
||||
}
|
||||
|
||||
override fun visitTypeElement(typeElement: JKTypeElement) {
|
||||
val type = typeElement.type
|
||||
|
||||
renderType(type)
|
||||
renderType(typeElement.type)
|
||||
}
|
||||
|
||||
override fun visitBlock(block: JKBlock) {
|
||||
|
||||
@@ -0,0 +1,83 @@
|
||||
/*
|
||||
* 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.j2k.conversions
|
||||
|
||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
||||
import org.jetbrains.kotlin.builtins.PrimitiveType
|
||||
import org.jetbrains.kotlin.j2k.ConversionContext
|
||||
import org.jetbrains.kotlin.j2k.ast.Nullability
|
||||
import org.jetbrains.kotlin.j2k.tree.*
|
||||
import org.jetbrains.kotlin.j2k.tree.impl.*
|
||||
import org.jetbrains.kotlin.resolve.CollectionLiteralResolver
|
||||
|
||||
|
||||
class ArrayInitializerConversion(private val context: ConversionContext) : RecursiveApplicableConversionBase() {
|
||||
override fun applyToElement(element: JKTreeElement): JKTreeElement {
|
||||
var newElement = element
|
||||
if (element is JKJavaNewArray) {
|
||||
val arrayType = element.type.type
|
||||
newElement = JKJavaMethodCallExpressionImpl(
|
||||
context.symbolProvider.provideByFqName(
|
||||
if (arrayType is JKJavaPrimitiveType)
|
||||
CollectionLiteralResolver.PRIMITIVE_TYPE_TO_ARRAY[PrimitiveType.valueOf(arrayType.jvmPrimitiveType.name)]!!.asString()
|
||||
else
|
||||
CollectionLiteralResolver.ARRAY_OF_FUNCTION.asString()
|
||||
),
|
||||
JKExpressionListImpl(element.initializer.also { element.initializer = emptyList() })
|
||||
)
|
||||
} else if (element is JKJavaNewEmptyArray) {
|
||||
newElement = buildArrayInitializer(element.initializer.also { element.initializer = emptyList() }, element.type.type)
|
||||
}
|
||||
|
||||
return recurse(newElement)
|
||||
}
|
||||
|
||||
private fun buildArrayInitializer(dimensions: List<JKExpression>, type: JKType): JKExpression {
|
||||
if (dimensions.size == 1) {
|
||||
val methodOrConstructorReference = if (type !is JKJavaPrimitiveType)
|
||||
context.symbolProvider.provideByFqName("kotlin/arrayOfNulls")
|
||||
else
|
||||
JKUnresolvedMethod(arrayFqName(type).replace('/', '.')/*TODO resolve real reference*/)
|
||||
return JKJavaMethodCallExpressionImpl(
|
||||
methodOrConstructorReference,
|
||||
JKExpressionListImpl(dimensions[0]),
|
||||
if (type is JKJavaPrimitiveType) emptyList() else listOf(JKTypeElementImpl(type))
|
||||
)
|
||||
}
|
||||
if (dimensions[1] !is JKStubExpression) {
|
||||
return JKJavaMethodCallExpressionImpl(
|
||||
JKUnresolvedMethod("kotlin.Array"),//TODO resolve real reference
|
||||
JKExpressionListImpl(
|
||||
dimensions[0],
|
||||
JKLambdaExpressionImpl(
|
||||
statement = JKExpressionStatementImpl(buildArrayInitializer(dimensions.subList(1, dimensions.size), type))
|
||||
)
|
||||
)
|
||||
)
|
||||
}
|
||||
var resultType = JKClassTypeImpl(
|
||||
context.symbolProvider.provideByFqName(arrayFqName(type)),
|
||||
if (type is JKJavaPrimitiveType) emptyList() else listOf(type),
|
||||
Nullability.NotNull
|
||||
)
|
||||
for (i in 0 until dimensions.size - 2) {
|
||||
resultType = JKClassTypeImpl(
|
||||
context.symbolProvider.provideByFqName(KotlinBuiltIns.FQ_NAMES.array.asString()),
|
||||
listOf(resultType),
|
||||
Nullability.NotNull
|
||||
)
|
||||
}
|
||||
return JKJavaMethodCallExpressionImpl(
|
||||
context.symbolProvider.provideByFqName("kotlin/arrayOfNulls"),
|
||||
JKExpressionListImpl(dimensions[0]),
|
||||
listOf(JKTypeElementImpl(resultType))
|
||||
)
|
||||
}
|
||||
|
||||
private fun arrayFqName(type: JKType): String = if (type is JKJavaPrimitiveType)
|
||||
PrimitiveType.valueOf(type.jvmPrimitiveType.name).arrayTypeFqName.asString()
|
||||
else KotlinBuiltIns.FQ_NAMES.array.asString()
|
||||
}
|
||||
@@ -94,11 +94,13 @@ sealed class JKJavaQualifierImpl : JKQualifier {
|
||||
|
||||
class JKJavaMethodCallExpressionImpl(
|
||||
override var identifier: JKMethodSymbol,
|
||||
arguments: JKExpressionList
|
||||
arguments: JKExpressionList,
|
||||
typeArguments: List<JKTypeElement> = emptyList()
|
||||
) : JKJavaMethodCallExpression, JKBranchElementBase() {
|
||||
override fun <R, D> accept(visitor: JKVisitor<R, D>, data: D): R = visitor.visitJavaMethodCallExpression(this, data)
|
||||
|
||||
override val arguments: JKExpressionList by child(arguments)
|
||||
override var typeArguments: List<JKTypeElement> by children(typeArguments)
|
||||
}
|
||||
|
||||
class JKJavaNewExpressionImpl(
|
||||
@@ -114,11 +116,15 @@ class JKJavaDefaultNewExpressionImpl(
|
||||
override val classSymbol: JKClassSymbol
|
||||
) : JKJavaDefaultNewExpression, JKElementBase()
|
||||
|
||||
class JKJavaNewEmptyArrayImpl(override var initializer: List<JKLiteralExpression?>) : JKJavaNewEmptyArray, JKElementBase() {
|
||||
class JKJavaNewEmptyArrayImpl(initializer: List<JKExpression>, type: JKTypeElement) : JKJavaNewEmptyArray, JKBranchElementBase() {
|
||||
override val type by child(type)
|
||||
override var initializer by children(initializer)
|
||||
override fun <R, D> accept(visitor: JKVisitor<R, D>, data: D): R = visitor.visitJavaNewEmptyArray(this, data)
|
||||
}
|
||||
|
||||
class JKJavaNewArrayImpl(override var initializer: List<JKExpression>) : JKJavaNewArray, JKElementBase() {
|
||||
class JKJavaNewArrayImpl(initializer: List<JKExpression>, type: JKTypeElement) : JKJavaNewArray, JKBranchElementBase() {
|
||||
override val type by child(type)
|
||||
override var initializer by children(initializer)
|
||||
override fun <R, D> accept(visitor: JKVisitor<R, D>, data: D): R = visitor.visitJavaNewArray(this, data)
|
||||
}
|
||||
|
||||
|
||||
@@ -125,6 +125,8 @@ class JKPostfixExpressionImpl(expression: JKExpression, override var operator: J
|
||||
}
|
||||
|
||||
class JKExpressionListImpl(expressions: List<JKExpression> = emptyList()) : JKExpressionList, JKBranchElementBase() {
|
||||
constructor(vararg expresions: JKExpression) : this(expresions.asList())
|
||||
|
||||
override fun <R, D> accept(visitor: JKVisitor<R, D>, data: D): R = visitor.visitExpressionList(this, data)
|
||||
|
||||
override var expressions by children(expressions)
|
||||
@@ -181,7 +183,7 @@ class JKTypeElementImpl(override val type: JKType) : JKTypeElement, JKElementBas
|
||||
|
||||
class JKClassTypeImpl(
|
||||
override val classReference: JKClassSymbol,
|
||||
override var parameters: List<JKType>,
|
||||
override var parameters: List<JKType> = emptyList(),
|
||||
override val nullability: Nullability = Nullability.Default
|
||||
) : JKClassType
|
||||
|
||||
@@ -331,7 +333,9 @@ class JKMutabilityModifierImpl(override val mutability: Mutability) : JKMutabili
|
||||
}
|
||||
|
||||
class JKLambdaExpressionImpl(
|
||||
parameters: List<JKParameter>, statement: JKStatement, returnType: JKTypeElement = JKTypeElementImpl(JKContextType)
|
||||
parameters: List<JKParameter> = listOf(
|
||||
JKParameterImpl(JKTypeElementImpl(JKJavaVoidType), JKNameIdentifierImpl("it"), JKModifierListImpl())
|
||||
), statement: JKStatement, returnType: JKTypeElement = JKTypeElementImpl(JKContextType)
|
||||
) : JKLambdaExpression, JKBranchElementBase() {
|
||||
override var statement by child(statement)
|
||||
override val returnType by child(returnType)
|
||||
|
||||
@@ -65,11 +65,13 @@ sealed class JKKtQualifierImpl : JKQualifier, JKElementBase() {
|
||||
|
||||
class JKKtCallExpressionImpl(
|
||||
override val identifier: JKMethodSymbol,
|
||||
arguments: JKExpressionList
|
||||
arguments: JKExpressionList,
|
||||
typeArguments: List<JKTypeElement> = emptyList()
|
||||
) : JKKtMethodCallExpression, JKBranchElementBase() {
|
||||
override fun <R, D> accept(visitor: JKVisitor<R, D>, data: D): R = visitor.visitKtMethodCallExpression(this, data)
|
||||
|
||||
override var arguments: JKExpressionList by child(arguments)
|
||||
override var typeArguments: List<JKTypeElement> by children(typeArguments)
|
||||
}
|
||||
|
||||
class JKKtLiteralExpressionImpl(
|
||||
@@ -167,6 +169,7 @@ class JKKtAlsoCallExpressionImpl(
|
||||
)
|
||||
)
|
||||
)
|
||||
override var typeArguments: List<JKTypeElement> by children(emptyList())
|
||||
}
|
||||
|
||||
class JKKtAssignmentStatementImpl(
|
||||
|
||||
@@ -44,11 +44,13 @@ interface JKJavaModifier : JKModifier {
|
||||
}
|
||||
|
||||
interface JKJavaNewEmptyArray : JKExpression {
|
||||
val initializer: List<JKLiteralExpression?>
|
||||
val type: JKTypeElement
|
||||
var initializer: List<JKExpression>
|
||||
}
|
||||
|
||||
interface JKJavaNewArray : JKExpression {
|
||||
val initializer: List<JKExpression>
|
||||
val type: JKTypeElement
|
||||
var initializer: List<JKExpression>
|
||||
}
|
||||
|
||||
interface JKJavaLiteralExpression : JKLiteralExpression
|
||||
|
||||
@@ -146,6 +146,7 @@ interface JKQualifiedExpression : JKExpression, JKAssignableExpression {
|
||||
interface JKMethodCallExpression : JKExpression, JKBranchElement {
|
||||
val identifier: JKMethodSymbol
|
||||
val arguments: JKExpressionList
|
||||
var typeArguments: List<JKTypeElement>
|
||||
}
|
||||
|
||||
interface JKFieldAccessExpression : JKAssignableExpression {
|
||||
|
||||
Reference in New Issue
Block a user