New J2K: Constructor conversion
This commit is contained in:
committed by
Ilya Kirillov
parent
e83844e941
commit
6793c1d08f
@@ -30,6 +30,7 @@ object ConversionsRunner {
|
||||
AssignmentAsExpressionToAlsoConversion(context).runConversion(it, context)
|
||||
AssignmentStatementValCreationConversion(context).runConversion(it, context)
|
||||
AssignmentStatementOperatorConversion().runConversion(it, context)
|
||||
ConstructorConversion().runConversion(it, context)
|
||||
JavaMethodToKotlinFunctionConversion().runConversion(it, context)
|
||||
LiteralConversion().runConversion(it, context)
|
||||
InnerClassConversion().runConversion(it, context)
|
||||
|
||||
@@ -18,6 +18,8 @@ package org.jetbrains.kotlin.j2k
|
||||
|
||||
import com.intellij.lang.java.JavaLanguage
|
||||
import com.intellij.psi.*
|
||||
import com.intellij.psi.JavaTokenType.SUPER_KEYWORD
|
||||
import com.intellij.psi.JavaTokenType.THIS_KEYWORD
|
||||
import com.intellij.psi.impl.source.tree.ChildRole
|
||||
import com.intellij.psi.impl.source.tree.java.PsiLiteralExpressionImpl
|
||||
import com.intellij.psi.impl.source.tree.java.PsiNewExpressionImpl
|
||||
@@ -129,11 +131,22 @@ class JavaToJKTreeBuilder(var symbolProvider: JKSymbolProvider) {
|
||||
|
||||
fun PsiMethodCallExpression.toJK(): JKExpression {
|
||||
val method = methodExpression as PsiReferenceExpressionImpl
|
||||
val call = JKJavaMethodCallExpressionImpl(symbolProvider.provideSymbol(method), argumentList.toJK())
|
||||
return if (method.findChildByRole(ChildRole.DOT) != null) {
|
||||
JKQualifiedExpressionImpl((method.qualifier as PsiExpression).toJK(), JKJavaQualifierImpl.DOT, call)
|
||||
val referenceNameElement = methodExpression.referenceNameElement
|
||||
val symbol = symbolProvider.provideSymbol<JKMethodSymbol>(method)
|
||||
return if (referenceNameElement is PsiKeyword) {
|
||||
val callee = when (referenceNameElement.tokenType) {
|
||||
SUPER_KEYWORD -> JKSuperExpressionImpl()
|
||||
THIS_KEYWORD -> JKThisExpressionImpl()
|
||||
else -> error("Unknown keyword in callee position")
|
||||
}
|
||||
JKDelegationConstructorCallImpl(symbol, callee, argumentList.toJK())
|
||||
} else {
|
||||
call
|
||||
val call = JKJavaMethodCallExpressionImpl(symbol, argumentList.toJK())
|
||||
if (method.findChildByRole(ChildRole.DOT) != null) {
|
||||
JKQualifiedExpressionImpl((method.qualifier as PsiExpression).toJK(), JKJavaQualifierImpl.DOT, call)
|
||||
} else {
|
||||
call
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -147,22 +147,22 @@ class NewCodeBuilder {
|
||||
printer.printlnWithNoIndent()
|
||||
}
|
||||
|
||||
override fun visitParameter(parameter: JKParameter) {
|
||||
printer.printWithNoIndent(parameter.name.value, ": ")
|
||||
parameter.type.accept(this)
|
||||
if (parameter.initializer !is JKStubExpression) {
|
||||
printer.printWithNoIndent(" = ")
|
||||
parameter.initializer.accept(this)
|
||||
}
|
||||
}
|
||||
|
||||
override fun visitKtFunction(ktFunction: JKKtFunction) {
|
||||
printer.printIndent()
|
||||
ktFunction.modifierList.accept(this)
|
||||
printer.printWithNoIndent(" fun ", ktFunction.name.value, "(")
|
||||
for (parameter in ktFunction.parameters) {
|
||||
if (parameter != ktFunction.parameters.first()) {
|
||||
printer.printWithNoIndent(", ")
|
||||
}
|
||||
printer.printWithNoIndent(parameter.name.value, ": ")
|
||||
parameter.type.accept(this)
|
||||
if (parameter.initializer !is JKStubExpression) {
|
||||
printer.printWithNoIndent(" = ")
|
||||
parameter.initializer.accept(this)
|
||||
}
|
||||
renderList(ktFunction.parameters) {
|
||||
it.accept(this)
|
||||
}
|
||||
|
||||
printer.printWithNoIndent(")", ": ")
|
||||
ktFunction.returnType.accept(this)
|
||||
if (ktFunction.block !== JKBodyStub) {
|
||||
@@ -222,6 +222,14 @@ class NewCodeBuilder {
|
||||
prefixExpression.expression.accept(this)
|
||||
}
|
||||
|
||||
override fun visitThisExpression(thisExpression: JKThisExpression) {
|
||||
printer.printWithNoIndent("this")
|
||||
}
|
||||
|
||||
override fun visitSuperExpression(superExpression: JKSuperExpression) {
|
||||
printer.printWithNoIndent("super")
|
||||
}
|
||||
|
||||
override fun visitPostfixExpression(postfixExpression: JKPostfixExpression) {
|
||||
postfixExpression.expression.accept(this)
|
||||
printer.printWithNoIndent(postfixExpression.operator.operatorText)
|
||||
@@ -350,6 +358,31 @@ class NewCodeBuilder {
|
||||
printer.par(SQUARE) { arrayAccessExpression.indexExpression.accept(this) }
|
||||
}
|
||||
|
||||
override fun visitDelegationConstructorCall(delegationConstructorCall: JKDelegationConstructorCall) {
|
||||
delegationConstructorCall.expression.accept(this)
|
||||
printer.par {
|
||||
delegationConstructorCall.arguments.accept(this)
|
||||
}
|
||||
}
|
||||
|
||||
override fun visitKtConstructor(ktConstructor: JKKtConstructor) {
|
||||
printer.print("constructor")
|
||||
printer.par(ROUND) {
|
||||
renderList(ktConstructor.parameters) {
|
||||
it.accept(this)
|
||||
}
|
||||
}
|
||||
if (ktConstructor.delegationCall !is JKStubExpression) {
|
||||
builder.append(" : ")
|
||||
ktConstructor.delegationCall.accept(this)
|
||||
}
|
||||
if (ktConstructor.block !== JKBodyStub) {
|
||||
printer.block(multiline = true) {
|
||||
ktConstructor.block.accept(this)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private inline fun Printer.indented(block: () -> Unit) {
|
||||
this.pushIndent()
|
||||
block()
|
||||
@@ -383,9 +416,9 @@ class NewCodeBuilder {
|
||||
printer.printWithNoIndent(" }")
|
||||
}
|
||||
|
||||
override fun visitParameter(parameter: JKParameter) {
|
||||
/*override fun visitParameter(parameter: JKParameter) {
|
||||
printer.printWithNoIndent(parameter.name.value)
|
||||
}
|
||||
}*/
|
||||
|
||||
override fun visitKtAssignmentStatement(ktAssignmentStatement: JKKtAssignmentStatement) {
|
||||
ktAssignmentStatement.field.accept(this)
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
/*
|
||||
* 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.j2k.tree.JKElement
|
||||
|
||||
inline fun <reified T : JKElement> JKElement.parentOfType(): T? {
|
||||
return generateSequence(parent) { it.parent }.filterIsInstance<T>().firstOrNull()
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
/*
|
||||
* 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.j2k.tree.*
|
||||
import org.jetbrains.kotlin.j2k.tree.impl.*
|
||||
|
||||
class ConstructorConversion : RecursiveApplicableConversionBase() {
|
||||
override fun applyToElement(element: JKTreeElement): JKTreeElement {
|
||||
if (element !is JKJavaMethod) return recurse(element)
|
||||
val outerClass = element.parentOfType<JKClass>() ?: return recurse(element)
|
||||
if (element.name.value != outerClass.name.value) return recurse(element)
|
||||
|
||||
element.invalidate()
|
||||
val delegationCall = lookupDelegationCall(element.block) ?: JKStubExpressionImpl()
|
||||
|
||||
return JKKtConstructorImpl(element.name, element.parameters, element.block, element.modifierList, delegationCall)
|
||||
}
|
||||
|
||||
private fun lookupDelegationCall(block: JKBlock): JKDelegationConstructorCall? {
|
||||
val firstStatement = block.statements.firstOrNull() ?: return null
|
||||
val expressionStatement = firstStatement as? JKExpressionStatement ?: return null
|
||||
val expression = expressionStatement.expression as? JKDelegationConstructorCall ?: return null
|
||||
block.statements -= expressionStatement
|
||||
expressionStatement.invalidate()
|
||||
return expression
|
||||
}
|
||||
}
|
||||
@@ -327,4 +327,15 @@ class JKInheritanceInfoImpl(implements: List<JKTypeElement>) : JKInheritanceInfo
|
||||
override val inherit: List<JKTypeElement> by children(implements)
|
||||
|
||||
override fun <R, D> accept(visitor: JKVisitor<R, D>, data: D): R = visitor.visitInheritanceInfo(this, data)
|
||||
}
|
||||
}
|
||||
|
||||
class JKDelegationConstructorCallImpl(
|
||||
override val identifier: JKMethodSymbol,
|
||||
expression: JKExpression,
|
||||
arguments: JKExpressionList
|
||||
) : JKBranchElementBase(), JKDelegationConstructorCall {
|
||||
override val expression: JKExpression by child(expression)
|
||||
override val arguments: JKExpressionList by child(arguments)
|
||||
|
||||
override fun <R, D> accept(visitor: JKVisitor<R, D>, data: D): R = visitor.visitDelegationConstructorCall(this, data)
|
||||
}
|
||||
|
||||
@@ -166,4 +166,22 @@ class JKKtAssignmentStatementImpl(
|
||||
override var expression by child(expression)
|
||||
override fun <R, D> accept(visitor: JKVisitor<R, D>, data: D): R = visitor.visitKtAssignmentStatement(this, data)
|
||||
|
||||
}
|
||||
|
||||
class JKKtConstructorImpl(
|
||||
name: JKNameIdentifier,
|
||||
parameters: List<JKParameter>,
|
||||
block: JKBlock,
|
||||
modifierList: JKModifierList,
|
||||
delegationCall: JKExpression
|
||||
) : JKBranchElementBase(), JKKtConstructor {
|
||||
override val returnType: JKTypeElement get() = TODO("!")
|
||||
|
||||
override var name: JKNameIdentifier by child(name)
|
||||
override var parameters: List<JKParameter> by children(parameters)
|
||||
override var block: JKBlock by child(block)
|
||||
override var modifierList: JKModifierList by child(modifierList)
|
||||
override var delegationCall: JKExpression by child(delegationCall)
|
||||
|
||||
override fun <R, D> accept(visitor: JKVisitor<R, D>, data: D): R = visitor.visitKtConstructor(this, data)
|
||||
}
|
||||
@@ -108,7 +108,7 @@ interface JKNameIdentifier : JKIdentifier {
|
||||
|
||||
interface JKExpression : JKTreeElement
|
||||
|
||||
interface JKExpressionStatement : JKStatement {
|
||||
interface JKExpressionStatement : JKBranchElement, JKStatement {
|
||||
val expression: JKExpression
|
||||
}
|
||||
|
||||
@@ -241,4 +241,10 @@ interface JKLambdaExpression : JKExpression {
|
||||
var parameters: List<JKParameter>
|
||||
val returnType: JKTypeElement
|
||||
var statement: JKStatement
|
||||
}
|
||||
|
||||
interface JKDelegationConstructorCall : JKMethodCallExpression {
|
||||
override val identifier: JKMethodSymbol
|
||||
val expression: JKExpression
|
||||
override val arguments: JKExpressionList
|
||||
}
|
||||
@@ -25,7 +25,12 @@ interface JKKtFunction : JKMethod {
|
||||
val block: JKBlock
|
||||
}
|
||||
|
||||
interface JKKtConstructor : JKDeclaration
|
||||
interface JKKtConstructor : JKDeclaration, JKModifierListOwner, JKMethod {
|
||||
override var name: JKNameIdentifier
|
||||
override var parameters: List<JKParameter>
|
||||
var block: JKBlock
|
||||
var delegationCall: JKExpression
|
||||
}
|
||||
|
||||
interface JKKtPrimaryConstructor : JKKtConstructor
|
||||
|
||||
|
||||
@@ -54,6 +54,7 @@ interface JKVisitor<out R, in D> {
|
||||
fun visitIfElseExpression(ifElseExpression: JKIfElseExpression, data: D): R = visitExpression(ifElseExpression, data)
|
||||
fun visitAssignableExpression(assignableExpression: JKAssignableExpression, data: D): R = visitExpression(assignableExpression, data)
|
||||
fun visitLambdaExpression(lambdaExpression: JKLambdaExpression, data: D): R = visitExpression(lambdaExpression, data)
|
||||
fun visitDelegationConstructorCall(delegationConstructorCall: JKDelegationConstructorCall, data: D): R = visitMethodCallExpression(delegationConstructorCall, data)
|
||||
fun visitJavaField(javaField: JKJavaField, data: D): R = visitField(javaField, data)
|
||||
fun visitJavaMethod(javaMethod: JKJavaMethod, data: D): R = visitMethod(javaMethod, data)
|
||||
fun visitJavaMethodCallExpression(javaMethodCallExpression: JKJavaMethodCallExpression, data: D): R = visitMethodCallExpression(javaMethodCallExpression, data)
|
||||
|
||||
@@ -105,6 +105,8 @@ interface JKVisitorVoid : JKVisitor<Unit, Nothing?> {
|
||||
override fun visitAssignableExpression(assignableExpression: JKAssignableExpression, data: Nothing?) = visitAssignableExpression(assignableExpression)
|
||||
fun visitLambdaExpression(lambdaExpression: JKLambdaExpression) = visitExpression(lambdaExpression, null)
|
||||
override fun visitLambdaExpression(lambdaExpression: JKLambdaExpression, data: Nothing?) = visitLambdaExpression(lambdaExpression)
|
||||
fun visitDelegationConstructorCall(delegationConstructorCall: JKDelegationConstructorCall) = visitMethodCallExpression(delegationConstructorCall, null)
|
||||
override fun visitDelegationConstructorCall(delegationConstructorCall: JKDelegationConstructorCall, data: Nothing?) = visitDelegationConstructorCall(delegationConstructorCall)
|
||||
fun visitJavaField(javaField: JKJavaField) = visitField(javaField, null)
|
||||
override fun visitJavaField(javaField: JKJavaField, data: Nothing?) = visitJavaField(javaField)
|
||||
fun visitJavaMethod(javaMethod: JKJavaMethod) = visitMethod(javaMethod, null)
|
||||
|
||||
Reference in New Issue
Block a user