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)
|
AssignmentAsExpressionToAlsoConversion(context).runConversion(it, context)
|
||||||
AssignmentStatementValCreationConversion(context).runConversion(it, context)
|
AssignmentStatementValCreationConversion(context).runConversion(it, context)
|
||||||
AssignmentStatementOperatorConversion().runConversion(it, context)
|
AssignmentStatementOperatorConversion().runConversion(it, context)
|
||||||
|
ConstructorConversion().runConversion(it, context)
|
||||||
JavaMethodToKotlinFunctionConversion().runConversion(it, context)
|
JavaMethodToKotlinFunctionConversion().runConversion(it, context)
|
||||||
LiteralConversion().runConversion(it, context)
|
LiteralConversion().runConversion(it, context)
|
||||||
InnerClassConversion().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.lang.java.JavaLanguage
|
||||||
import com.intellij.psi.*
|
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.ChildRole
|
||||||
import com.intellij.psi.impl.source.tree.java.PsiLiteralExpressionImpl
|
import com.intellij.psi.impl.source.tree.java.PsiLiteralExpressionImpl
|
||||||
import com.intellij.psi.impl.source.tree.java.PsiNewExpressionImpl
|
import com.intellij.psi.impl.source.tree.java.PsiNewExpressionImpl
|
||||||
@@ -129,11 +131,22 @@ class JavaToJKTreeBuilder(var symbolProvider: JKSymbolProvider) {
|
|||||||
|
|
||||||
fun PsiMethodCallExpression.toJK(): JKExpression {
|
fun PsiMethodCallExpression.toJK(): JKExpression {
|
||||||
val method = methodExpression as PsiReferenceExpressionImpl
|
val method = methodExpression as PsiReferenceExpressionImpl
|
||||||
val call = JKJavaMethodCallExpressionImpl(symbolProvider.provideSymbol(method), argumentList.toJK())
|
val referenceNameElement = methodExpression.referenceNameElement
|
||||||
return if (method.findChildByRole(ChildRole.DOT) != null) {
|
val symbol = symbolProvider.provideSymbol<JKMethodSymbol>(method)
|
||||||
JKQualifiedExpressionImpl((method.qualifier as PsiExpression).toJK(), JKJavaQualifierImpl.DOT, call)
|
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 {
|
} 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()
|
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) {
|
override fun visitKtFunction(ktFunction: JKKtFunction) {
|
||||||
printer.printIndent()
|
printer.printIndent()
|
||||||
ktFunction.modifierList.accept(this)
|
ktFunction.modifierList.accept(this)
|
||||||
printer.printWithNoIndent(" fun ", ktFunction.name.value, "(")
|
printer.printWithNoIndent(" fun ", ktFunction.name.value, "(")
|
||||||
for (parameter in ktFunction.parameters) {
|
renderList(ktFunction.parameters) {
|
||||||
if (parameter != ktFunction.parameters.first()) {
|
it.accept(this)
|
||||||
printer.printWithNoIndent(", ")
|
|
||||||
}
|
|
||||||
printer.printWithNoIndent(parameter.name.value, ": ")
|
|
||||||
parameter.type.accept(this)
|
|
||||||
if (parameter.initializer !is JKStubExpression) {
|
|
||||||
printer.printWithNoIndent(" = ")
|
|
||||||
parameter.initializer.accept(this)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
printer.printWithNoIndent(")", ": ")
|
printer.printWithNoIndent(")", ": ")
|
||||||
ktFunction.returnType.accept(this)
|
ktFunction.returnType.accept(this)
|
||||||
if (ktFunction.block !== JKBodyStub) {
|
if (ktFunction.block !== JKBodyStub) {
|
||||||
@@ -222,6 +222,14 @@ class NewCodeBuilder {
|
|||||||
prefixExpression.expression.accept(this)
|
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) {
|
override fun visitPostfixExpression(postfixExpression: JKPostfixExpression) {
|
||||||
postfixExpression.expression.accept(this)
|
postfixExpression.expression.accept(this)
|
||||||
printer.printWithNoIndent(postfixExpression.operator.operatorText)
|
printer.printWithNoIndent(postfixExpression.operator.operatorText)
|
||||||
@@ -350,6 +358,31 @@ class NewCodeBuilder {
|
|||||||
printer.par(SQUARE) { arrayAccessExpression.indexExpression.accept(this) }
|
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) {
|
private inline fun Printer.indented(block: () -> Unit) {
|
||||||
this.pushIndent()
|
this.pushIndent()
|
||||||
block()
|
block()
|
||||||
@@ -383,9 +416,9 @@ class NewCodeBuilder {
|
|||||||
printer.printWithNoIndent(" }")
|
printer.printWithNoIndent(" }")
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun visitParameter(parameter: JKParameter) {
|
/*override fun visitParameter(parameter: JKParameter) {
|
||||||
printer.printWithNoIndent(parameter.name.value)
|
printer.printWithNoIndent(parameter.name.value)
|
||||||
}
|
}*/
|
||||||
|
|
||||||
override fun visitKtAssignmentStatement(ktAssignmentStatement: JKKtAssignmentStatement) {
|
override fun visitKtAssignmentStatement(ktAssignmentStatement: JKKtAssignmentStatement) {
|
||||||
ktAssignmentStatement.field.accept(this)
|
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 val inherit: List<JKTypeElement> by children(implements)
|
||||||
|
|
||||||
override fun <R, D> accept(visitor: JKVisitor<R, D>, data: D): R = visitor.visitInheritanceInfo(this, data)
|
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 var expression by child(expression)
|
||||||
override fun <R, D> accept(visitor: JKVisitor<R, D>, data: D): R = visitor.visitKtAssignmentStatement(this, data)
|
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 JKExpression : JKTreeElement
|
||||||
|
|
||||||
interface JKExpressionStatement : JKStatement {
|
interface JKExpressionStatement : JKBranchElement, JKStatement {
|
||||||
val expression: JKExpression
|
val expression: JKExpression
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -241,4 +241,10 @@ interface JKLambdaExpression : JKExpression {
|
|||||||
var parameters: List<JKParameter>
|
var parameters: List<JKParameter>
|
||||||
val returnType: JKTypeElement
|
val returnType: JKTypeElement
|
||||||
var statement: JKStatement
|
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
|
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
|
interface JKKtPrimaryConstructor : JKKtConstructor
|
||||||
|
|
||||||
|
|||||||
@@ -54,6 +54,7 @@ interface JKVisitor<out R, in D> {
|
|||||||
fun visitIfElseExpression(ifElseExpression: JKIfElseExpression, data: D): R = visitExpression(ifElseExpression, data)
|
fun visitIfElseExpression(ifElseExpression: JKIfElseExpression, data: D): R = visitExpression(ifElseExpression, data)
|
||||||
fun visitAssignableExpression(assignableExpression: JKAssignableExpression, data: D): R = visitExpression(assignableExpression, data)
|
fun visitAssignableExpression(assignableExpression: JKAssignableExpression, data: D): R = visitExpression(assignableExpression, data)
|
||||||
fun visitLambdaExpression(lambdaExpression: JKLambdaExpression, data: D): R = visitExpression(lambdaExpression, 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 visitJavaField(javaField: JKJavaField, data: D): R = visitField(javaField, data)
|
||||||
fun visitJavaMethod(javaMethod: JKJavaMethod, data: D): R = visitMethod(javaMethod, data)
|
fun visitJavaMethod(javaMethod: JKJavaMethod, data: D): R = visitMethod(javaMethod, data)
|
||||||
fun visitJavaMethodCallExpression(javaMethodCallExpression: JKJavaMethodCallExpression, data: D): R = visitMethodCallExpression(javaMethodCallExpression, 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)
|
override fun visitAssignableExpression(assignableExpression: JKAssignableExpression, data: Nothing?) = visitAssignableExpression(assignableExpression)
|
||||||
fun visitLambdaExpression(lambdaExpression: JKLambdaExpression) = visitExpression(lambdaExpression, null)
|
fun visitLambdaExpression(lambdaExpression: JKLambdaExpression) = visitExpression(lambdaExpression, null)
|
||||||
override fun visitLambdaExpression(lambdaExpression: JKLambdaExpression, data: Nothing?) = visitLambdaExpression(lambdaExpression)
|
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)
|
fun visitJavaField(javaField: JKJavaField) = visitField(javaField, null)
|
||||||
override fun visitJavaField(javaField: JKJavaField, data: Nothing?) = visitJavaField(javaField)
|
override fun visitJavaField(javaField: JKJavaField, data: Nothing?) = visitJavaField(javaField)
|
||||||
fun visitJavaMethod(javaMethod: JKJavaMethod) = visitMethod(javaMethod, null)
|
fun visitJavaMethod(javaMethod: JKJavaMethod) = visitMethod(javaMethod, null)
|
||||||
|
|||||||
Reference in New Issue
Block a user