New J2K, minor: refactor code builder
This commit is contained in:
@@ -18,7 +18,6 @@ package org.jetbrains.kotlin.nj2k
|
|||||||
|
|
||||||
import org.jetbrains.kotlin.j2k.ast.Nullability
|
import org.jetbrains.kotlin.j2k.ast.Nullability
|
||||||
import org.jetbrains.kotlin.name.FqName
|
import org.jetbrains.kotlin.name.FqName
|
||||||
import org.jetbrains.kotlin.nj2k.NewCodeBuilder.ParenthesisKind.*
|
|
||||||
import org.jetbrains.kotlin.nj2k.conversions.parentOfType
|
import org.jetbrains.kotlin.nj2k.conversions.parentOfType
|
||||||
import org.jetbrains.kotlin.nj2k.tree.*
|
import org.jetbrains.kotlin.nj2k.tree.*
|
||||||
import org.jetbrains.kotlin.nj2k.tree.impl.*
|
import org.jetbrains.kotlin.nj2k.tree.impl.*
|
||||||
@@ -29,8 +28,8 @@ import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
|||||||
|
|
||||||
class NewCodeBuilder(context: NewJ2kConverterContext) {
|
class NewCodeBuilder(context: NewJ2kConverterContext) {
|
||||||
private val elementInfoStorage = context.elementsInfoStorage
|
private val elementInfoStorage = context.elementsInfoStorage
|
||||||
val builder = StringBuilder()
|
private val builder = StringBuilder()
|
||||||
val printer = Printer(builder)
|
private val printer = JKPrinter(builder, elementInfoStorage)
|
||||||
|
|
||||||
private fun classKindString(kind: JKClass.ClassKind): String = when (kind) {
|
private fun classKindString(kind: JKClass.ClassKind): String = when (kind) {
|
||||||
JKClass.ClassKind.ANNOTATION -> "annotation class"
|
JKClass.ClassKind.ANNOTATION -> "annotation class"
|
||||||
@@ -109,7 +108,7 @@ class NewCodeBuilder(context: NewJ2kConverterContext) {
|
|||||||
typeParameter.name to bound
|
typeParameter.name to bound
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
renderList(typeParametersWithBoudnds) { (name, bound) ->
|
printer.renderList(typeParametersWithBoudnds) { (name, bound) ->
|
||||||
name.accept(this)
|
name.accept(this)
|
||||||
printer.printWithNoIndent(" : ")
|
printer.printWithNoIndent(" : ")
|
||||||
bound.accept(this)
|
bound.accept(this)
|
||||||
@@ -170,7 +169,7 @@ class NewCodeBuilder(context: NewJ2kConverterContext) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun visitClassAccessExpressionRaw(classAccessExpression: JKClassAccessExpression) {
|
override fun visitClassAccessExpressionRaw(classAccessExpression: JKClassAccessExpression) {
|
||||||
renderClassSymbol(classAccessExpression.identifier, classAccessExpression)
|
printer.renderClassSymbol(classAccessExpression.identifier, classAccessExpression)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun visitFileRaw(file: JKFile) {
|
override fun visitFileRaw(file: JKFile) {
|
||||||
@@ -181,10 +180,6 @@ class NewCodeBuilder(context: NewJ2kConverterContext) {
|
|||||||
file.declarationList.forEach { it.accept(this) }
|
file.declarationList.forEach { it.accept(this) }
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun String.escapedAsQualifiedName(): String =
|
|
||||||
split('.')
|
|
||||||
.map { it.escaped() }
|
|
||||||
.joinToString(".") { it }
|
|
||||||
|
|
||||||
override fun visitPackageDeclarationRaw(packageDeclaration: JKPackageDeclaration) {
|
override fun visitPackageDeclarationRaw(packageDeclaration: JKPackageDeclaration) {
|
||||||
printer.printWithNoIndent("package ")
|
printer.printWithNoIndent("package ")
|
||||||
@@ -217,7 +212,7 @@ class NewCodeBuilder(context: NewJ2kConverterContext) {
|
|||||||
val hasOverrideModifier = modifiersList.safeAs<JKOtherModifiersOwner>()
|
val hasOverrideModifier = modifiersList.safeAs<JKOtherModifiersOwner>()
|
||||||
?.otherModifierElements
|
?.otherModifierElements
|
||||||
?.any { it.otherModifier == OtherModifier.OVERRIDE } == true
|
?.any { it.otherModifier == OtherModifier.OVERRIDE } == true
|
||||||
renderList(modifiersList.modifierElements(), " ") { modifierElement ->
|
printer.renderList(modifiersList.modifierElements(), " ") { modifierElement ->
|
||||||
if (modifierElement.modifier == Modality.FINAL || modifierElement.modifier == Visibility.PUBLIC) {
|
if (modifierElement.modifier == Modality.FINAL || modifierElement.modifier == Visibility.PUBLIC) {
|
||||||
if (hasOverrideModifier) {
|
if (hasOverrideModifier) {
|
||||||
modifierElement.accept(this)
|
modifierElement.accept(this)
|
||||||
@@ -231,18 +226,6 @@ class NewCodeBuilder(context: NewJ2kConverterContext) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private inline fun <T> renderList(list: List<T>, separator: String = ", ", renderElement: (T) -> Unit) =
|
|
||||||
renderList(list, { printer.printWithNoIndent(separator) }, renderElement)
|
|
||||||
|
|
||||||
private inline fun <T> renderList(list: List<T>, separator: () -> Unit, renderElement: (T) -> Unit) {
|
|
||||||
val (head, tail) = list.headTail()
|
|
||||||
head?.let(renderElement) ?: return
|
|
||||||
tail?.forEach {
|
|
||||||
separator()
|
|
||||||
renderElement(it)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun visitClassRaw(klass: JKClass) {
|
override fun visitClassRaw(klass: JKClass) {
|
||||||
klass.annotationList.accept(this)
|
klass.annotationList.accept(this)
|
||||||
if (klass.annotationList.annotations.isNotEmpty()) {
|
if (klass.annotationList.annotations.isNotEmpty()) {
|
||||||
@@ -277,10 +260,10 @@ class NewCodeBuilder(context: NewJ2kConverterContext) {
|
|||||||
val extendTypes = inheritanceInfo.extends.map { it.type.updateNullability(Nullability.NotNull) }
|
val extendTypes = inheritanceInfo.extends.map { it.type.updateNullability(Nullability.NotNull) }
|
||||||
val implementTypes = inheritanceInfo.implements.map { it.type.updateNullability(Nullability.NotNull) }
|
val implementTypes = inheritanceInfo.implements.map { it.type.updateNullability(Nullability.NotNull) }
|
||||||
if (isInInterface) {
|
if (isInInterface) {
|
||||||
renderList(extendTypes) { renderType(it, null) }
|
printer.renderList(extendTypes) { printer.renderType(it, null) }
|
||||||
} else {
|
} else {
|
||||||
extendTypes.singleOrNull()?.also { superType ->
|
extendTypes.singleOrNull()?.also { superType ->
|
||||||
renderType(superType, null)
|
printer.renderType(superType, null)
|
||||||
val primaryConstructor = parentClass.primaryConstructor()
|
val primaryConstructor = parentClass.primaryConstructor()
|
||||||
val delegationCall =
|
val delegationCall =
|
||||||
primaryConstructor
|
primaryConstructor
|
||||||
@@ -297,19 +280,19 @@ class NewCodeBuilder(context: NewJ2kConverterContext) {
|
|||||||
if (implementTypes.isNotEmpty() && extendTypes.size == 1) {
|
if (implementTypes.isNotEmpty() && extendTypes.size == 1) {
|
||||||
printer.printWithNoIndent(", ")
|
printer.printWithNoIndent(", ")
|
||||||
}
|
}
|
||||||
renderList(implementTypes) { renderType(it, null) }
|
printer.renderList(implementTypes) { printer.renderType(it, null) }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private fun renderEnumConstants(enumConstants: List<JKEnumConstant>) {
|
private fun renderEnumConstants(enumConstants: List<JKEnumConstant>) {
|
||||||
renderList(enumConstants) {
|
printer.renderList(enumConstants) {
|
||||||
it.accept(this)
|
it.accept(this)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun renderNonEnumClassDeclarations(declarations: List<JKDeclaration>) {
|
private fun renderNonEnumClassDeclarations(declarations: List<JKDeclaration>) {
|
||||||
renderList(declarations, { printer.println() }) {
|
printer.renderList(declarations, { printer.println() }) {
|
||||||
it.accept(this)
|
it.accept(this)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -394,7 +377,7 @@ class NewCodeBuilder(context: NewJ2kConverterContext) {
|
|||||||
|
|
||||||
override fun visitKtAnnotationArrayInitializerExpressionRaw(ktAnnotationArrayInitializerExpression: JKKtAnnotationArrayInitializerExpression) {
|
override fun visitKtAnnotationArrayInitializerExpressionRaw(ktAnnotationArrayInitializerExpression: JKKtAnnotationArrayInitializerExpression) {
|
||||||
printer.print("[")
|
printer.print("[")
|
||||||
renderList(ktAnnotationArrayInitializerExpression.initializers) {
|
printer.renderList(ktAnnotationArrayInitializerExpression.initializers) {
|
||||||
it.accept(this)
|
it.accept(this)
|
||||||
}
|
}
|
||||||
printer.print("]")
|
printer.print("]")
|
||||||
@@ -423,7 +406,7 @@ class NewCodeBuilder(context: NewJ2kConverterContext) {
|
|||||||
}
|
}
|
||||||
ktFunction.name.accept(this)
|
ktFunction.name.accept(this)
|
||||||
renderTokenElement(ktFunction.leftParen)
|
renderTokenElement(ktFunction.leftParen)
|
||||||
renderList(ktFunction.parameters) {
|
printer.renderList(ktFunction.parameters) {
|
||||||
it.accept(this)
|
it.accept(this)
|
||||||
}
|
}
|
||||||
renderTokenElement(ktFunction.rightParen)
|
renderTokenElement(ktFunction.rightParen)
|
||||||
@@ -492,8 +475,8 @@ class NewCodeBuilder(context: NewJ2kConverterContext) {
|
|||||||
|
|
||||||
override fun visitTypeParameterListRaw(typeParameterList: JKTypeParameterList) {
|
override fun visitTypeParameterListRaw(typeParameterList: JKTypeParameterList) {
|
||||||
if (typeParameterList.typeParameters.isNotEmpty()) {
|
if (typeParameterList.typeParameters.isNotEmpty()) {
|
||||||
printer.par(ANGLE) {
|
printer.par(ParenthesisKind.ANGLE) {
|
||||||
renderList(typeParameterList.typeParameters) {
|
printer.renderList(typeParameterList.typeParameters) {
|
||||||
it.accept(this)
|
it.accept(this)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -573,12 +556,12 @@ class NewCodeBuilder(context: NewJ2kConverterContext) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun visitExpressionListRaw(expressionList: JKExpressionList) {
|
override fun visitExpressionListRaw(expressionList: JKExpressionList) {
|
||||||
renderList(expressionList.expressions) { it.accept(this) }
|
printer.renderList(expressionList.expressions) { it.accept(this) }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
override fun visitArgumentListRaw(argumentList: JKArgumentList) {
|
override fun visitArgumentListRaw(argumentList: JKArgumentList) {
|
||||||
renderList(argumentList.arguments) { it.accept(this) }
|
printer.renderList(argumentList.arguments) { it.accept(this) }
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun visitArgumentRaw(argument: JKArgument) {
|
override fun visitArgumentRaw(argument: JKArgument) {
|
||||||
@@ -601,8 +584,8 @@ class NewCodeBuilder(context: NewJ2kConverterContext) {
|
|||||||
|
|
||||||
override fun visitTypeArgumentListRaw(typeArgumentList: JKTypeArgumentList) {
|
override fun visitTypeArgumentListRaw(typeArgumentList: JKTypeArgumentList) {
|
||||||
if (typeArgumentList.typeArguments.isNotEmpty()) {
|
if (typeArgumentList.typeArguments.isNotEmpty()) {
|
||||||
printer.par(ANGLE) {
|
printer.par(ParenthesisKind.ANGLE) {
|
||||||
renderList(typeArgumentList.typeArguments) {
|
printer.renderList(typeArgumentList.typeArguments) {
|
||||||
it.accept(this)
|
it.accept(this)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -616,7 +599,7 @@ class NewCodeBuilder(context: NewJ2kConverterContext) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun visitDeclarationStatementRaw(declarationStatement: JKDeclarationStatement) {
|
override fun visitDeclarationStatementRaw(declarationStatement: JKDeclarationStatement) {
|
||||||
renderList(declarationStatement.declaredStatements, { printer.println() }) {
|
printer.renderList(declarationStatement.declaredStatements, { printer.println() }) {
|
||||||
it.accept(this)
|
it.accept(this)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -669,59 +652,14 @@ class NewCodeBuilder(context: NewJ2kConverterContext) {
|
|||||||
ktConvertedFromForLoopSyntheticWhileStatement.whileStatement.accept(this)
|
ktConvertedFromForLoopSyntheticWhileStatement.whileStatement.accept(this)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun JKClassSymbol.needFqName(): Boolean =
|
|
||||||
fqName !in mappedToKotlinFqNames
|
|
||||||
|
|
||||||
private fun renderType(type: JKType, owner: JKTreeElement?) {
|
|
||||||
if (type is JKNoTypeImpl) return
|
|
||||||
elementInfoStorage.getOrCreateInfoForElement(type).let {
|
|
||||||
printer.print(it.render())
|
|
||||||
}
|
|
||||||
when (type) {
|
|
||||||
is JKClassType -> {
|
|
||||||
renderClassSymbol(type.classReference, owner)
|
|
||||||
}
|
|
||||||
is JKContextType -> return
|
|
||||||
is JKStarProjectionType ->
|
|
||||||
printer.printWithNoIndent("*")
|
|
||||||
is JKTypeParameterType ->
|
|
||||||
printer.printWithNoIndent(type.name)
|
|
||||||
is JKVarianceTypeParameterType -> {
|
|
||||||
when (type.variance) {
|
|
||||||
JKVarianceTypeParameterType.Variance.IN -> printer.printWithNoIndent("in ")
|
|
||||||
JKVarianceTypeParameterType.Variance.OUT -> printer.printWithNoIndent("out ")
|
|
||||||
}
|
|
||||||
renderType(type.boundType, null)
|
|
||||||
}
|
|
||||||
else -> printer.printWithNoIndent("Unit /* TODO: ${type::class} */")
|
|
||||||
}
|
|
||||||
if (type is JKParametrizedType && type.parameters.isNotEmpty()) {
|
|
||||||
printer.par(ANGLE) {
|
|
||||||
renderList(type.parameters, renderElement = { renderType(it, null) })
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (type.nullability == Nullability.Nullable) {
|
|
||||||
printer.printWithNoIndent("?")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun renderClassSymbol(classSymbol: JKClassSymbol, owner: JKTreeElement?) {
|
|
||||||
val needFqName = classSymbol.needFqName() && owner?.isSelectorOfQualifiedExpression() != true
|
|
||||||
val displayName = if (needFqName) classSymbol.getDisplayName() else classSymbol.name
|
|
||||||
printer.printWithNoIndent(displayName.escapedAsQualifiedName())
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun JKTreeElement.isSelectorOfQualifiedExpression() =
|
|
||||||
parent?.safeAs<JKQualifiedExpression>()?.selector == this
|
|
||||||
|
|
||||||
override fun visitJavaNewExpressionRaw(javaNewExpression: JKJavaNewExpression) {
|
override fun visitJavaNewExpressionRaw(javaNewExpression: JKJavaNewExpression) {
|
||||||
if (javaNewExpression.isAnonymousClass()) {
|
if (javaNewExpression.isAnonymousClass()) {
|
||||||
printer.printWithNoIndent("object : ")
|
printer.printWithNoIndent("object : ")
|
||||||
}
|
}
|
||||||
renderClassSymbol(javaNewExpression.classSymbol, javaNewExpression)
|
printer.renderClassSymbol(javaNewExpression.classSymbol, javaNewExpression)
|
||||||
javaNewExpression.typeArgumentList.accept(this)
|
javaNewExpression.typeArgumentList.accept(this)
|
||||||
if (!javaNewExpression.classSymbol.isInterface() || javaNewExpression.arguments.arguments.isNotEmpty()) {
|
if (!javaNewExpression.classSymbol.isInterface() || javaNewExpression.arguments.arguments.isNotEmpty()) {
|
||||||
printer.par(ROUND) {
|
printer.par(ParenthesisKind.ROUND) {
|
||||||
javaNewExpression.arguments.accept(this)
|
javaNewExpression.arguments.accept(this)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -752,19 +690,19 @@ class NewCodeBuilder(context: NewJ2kConverterContext) {
|
|||||||
override fun visitEmptyClassBodyRaw(emptyClassBody: JKEmptyClassBody) {}
|
override fun visitEmptyClassBodyRaw(emptyClassBody: JKEmptyClassBody) {}
|
||||||
|
|
||||||
override fun visitTypeElementRaw(typeElement: JKTypeElement) {
|
override fun visitTypeElementRaw(typeElement: JKTypeElement) {
|
||||||
renderType(typeElement.type, typeElement)
|
printer.renderType(typeElement.type, typeElement)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun visitBlockRaw(block: JKBlock) {
|
override fun visitBlockRaw(block: JKBlock) {
|
||||||
renderTokenElement(block.leftBrace)
|
renderTokenElement(block.leftBrace)
|
||||||
renderList(block.statements, { printer.println() }) {
|
printer.renderList(block.statements, { printer.println() }) {
|
||||||
it.accept(this)
|
it.accept(this)
|
||||||
}
|
}
|
||||||
renderTokenElement(block.rightBrace)
|
renderTokenElement(block.rightBrace)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun visitBlockStatementWithoutBracketsRaw(blockStatementWithoutBrackets: JKBlockStatementWithoutBrackets) {
|
override fun visitBlockStatementWithoutBracketsRaw(blockStatementWithoutBrackets: JKBlockStatementWithoutBrackets) {
|
||||||
renderList(blockStatementWithoutBrackets.statements, { printer.println() }) {
|
printer.renderList(blockStatementWithoutBrackets.statements, { printer.println() }) {
|
||||||
it.accept(this)
|
it.accept(this)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -786,7 +724,7 @@ class NewCodeBuilder(context: NewJ2kConverterContext) {
|
|||||||
|
|
||||||
override fun visitArrayAccessExpressionRaw(arrayAccessExpression: JKArrayAccessExpression) {
|
override fun visitArrayAccessExpressionRaw(arrayAccessExpression: JKArrayAccessExpression) {
|
||||||
arrayAccessExpression.expression.accept(this)
|
arrayAccessExpression.expression.accept(this)
|
||||||
printer.par(SQUARE) { arrayAccessExpression.indexExpression.accept(this) }
|
printer.par(ParenthesisKind.SQUARE) { arrayAccessExpression.indexExpression.accept(this) }
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun visitPackageAccessExpressionRaw(packageAccessExpression: JKPackageAccessExpression) {
|
override fun visitPackageAccessExpressionRaw(packageAccessExpression: JKPackageAccessExpression) {
|
||||||
@@ -813,8 +751,8 @@ class NewCodeBuilder(context: NewJ2kConverterContext) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun renderParameterList(parameters: List<JKParameter>) {
|
private fun renderParameterList(parameters: List<JKParameter>) {
|
||||||
printer.par(ROUND) {
|
printer.par(ParenthesisKind.ROUND) {
|
||||||
renderList(parameters) {
|
printer.renderList(parameters) {
|
||||||
it.accept(this)
|
it.accept(this)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -850,27 +788,9 @@ class NewCodeBuilder(context: NewJ2kConverterContext) {
|
|||||||
override fun visitBodyStub(bodyStub: JKBodyStub) {
|
override fun visitBodyStub(bodyStub: JKBodyStub) {
|
||||||
}
|
}
|
||||||
|
|
||||||
private inline fun Printer.indented(block: () -> Unit) {
|
|
||||||
this.pushIndent()
|
|
||||||
block()
|
|
||||||
this.popIndent()
|
|
||||||
}
|
|
||||||
|
|
||||||
private inline fun Printer.block(multiline: Boolean = false, crossinline body: () -> Unit) {
|
|
||||||
par(CURVED) {
|
|
||||||
indented(body)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private inline fun Printer.par(kind: ParenthesisKind = ParenthesisKind.ROUND, body: () -> Unit) {
|
|
||||||
this.printWithNoIndent(kind.open)
|
|
||||||
body()
|
|
||||||
this.printWithNoIndent(kind.close)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun visitLambdaExpressionRaw(lambdaExpression: JKLambdaExpression) {
|
override fun visitLambdaExpressionRaw(lambdaExpression: JKLambdaExpression) {
|
||||||
val printLambda = {
|
val printLambda = {
|
||||||
printer.par(CURVED) {
|
printer.par(ParenthesisKind.CURVED) {
|
||||||
if (lambdaExpression.statement.statements.size > 1)
|
if (lambdaExpression.statement.statements.size > 1)
|
||||||
printer.println()
|
printer.println()
|
||||||
lambdaExpression.parameters.firstOrNull()?.accept(this)
|
lambdaExpression.parameters.firstOrNull()?.accept(this)
|
||||||
@@ -881,7 +801,7 @@ class NewCodeBuilder(context: NewJ2kConverterContext) {
|
|||||||
|
|
||||||
val statement = lambdaExpression.statement
|
val statement = lambdaExpression.statement
|
||||||
if (statement is JKBlockStatement) {
|
if (statement is JKBlockStatement) {
|
||||||
renderList(statement.block.statements, { printer.println() }) { it.accept(this) }
|
printer.renderList(statement.block.statements, { printer.println() }) { it.accept(this) }
|
||||||
} else {
|
} else {
|
||||||
statement.accept(this)
|
statement.accept(this)
|
||||||
}
|
}
|
||||||
@@ -890,14 +810,12 @@ class NewCodeBuilder(context: NewJ2kConverterContext) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (lambdaExpression.functionalType.present()) {
|
if (lambdaExpression.functionalType.present()) {
|
||||||
renderType(lambdaExpression.functionalType.type, lambdaExpression)
|
printer.renderType(lambdaExpression.functionalType.type, lambdaExpression)
|
||||||
printer.printWithNoIndent(" ")
|
printer.printWithNoIndent(" ")
|
||||||
printer.par(ROUND, printLambda)
|
printer.par(ParenthesisKind.ROUND, printLambda)
|
||||||
} else {
|
} else {
|
||||||
printLambda()
|
printLambda()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun visitBlockStatementRaw(blockStatement: JKBlockStatement) {
|
override fun visitBlockStatementRaw(blockStatement: JKBlockStatement) {
|
||||||
@@ -917,14 +835,14 @@ class NewCodeBuilder(context: NewJ2kConverterContext) {
|
|||||||
ktWhenStatement.expression.accept(this)
|
ktWhenStatement.expression.accept(this)
|
||||||
printer.printWithNoIndent(")")
|
printer.printWithNoIndent(")")
|
||||||
printer.block(multiline = true) {
|
printer.block(multiline = true) {
|
||||||
renderList(ktWhenStatement.cases, { printer.printlnWithNoIndent() }) {
|
printer.renderList(ktWhenStatement.cases, { printer.printlnWithNoIndent() }) {
|
||||||
it.accept(this)
|
it.accept(this)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun visitAnnotationListRaw(annotationList: JKAnnotationList) {
|
override fun visitAnnotationListRaw(annotationList: JKAnnotationList) {
|
||||||
renderList(annotationList.annotations, " ") {
|
printer.renderList(annotationList.annotations, " ") {
|
||||||
it.accept(this)
|
it.accept(this)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -934,7 +852,7 @@ class NewCodeBuilder(context: NewJ2kConverterContext) {
|
|||||||
printer.printWithNoIndent(annotation.classSymbol.fqName.escapedAsQualifiedName())
|
printer.printWithNoIndent(annotation.classSymbol.fqName.escapedAsQualifiedName())
|
||||||
if (annotation.arguments.isNotEmpty()) {
|
if (annotation.arguments.isNotEmpty()) {
|
||||||
printer.par {
|
printer.par {
|
||||||
renderList(annotation.arguments) { it.accept(this) }
|
printer.renderList(annotation.arguments) { it.accept(this) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -953,7 +871,7 @@ class NewCodeBuilder(context: NewJ2kConverterContext) {
|
|||||||
if (classLiteralExpression.literalType == JKClassLiteralExpression.LiteralType.JAVA_VOID_TYPE) {
|
if (classLiteralExpression.literalType == JKClassLiteralExpression.LiteralType.JAVA_VOID_TYPE) {
|
||||||
printer.printWithNoIndent("Void.TYPE")
|
printer.printWithNoIndent("Void.TYPE")
|
||||||
} else {
|
} else {
|
||||||
renderType(classLiteralExpression.classType.type, classLiteralExpression)
|
printer.renderType(classLiteralExpression.classType.type, classLiteralExpression)
|
||||||
printer.printWithNoIndent("::")
|
printer.printWithNoIndent("::")
|
||||||
when (classLiteralExpression.literalType) {
|
when (classLiteralExpression.literalType) {
|
||||||
JKClassLiteralExpression.LiteralType.KOTLIN_CLASS -> printer.printWithNoIndent("class")
|
JKClassLiteralExpression.LiteralType.KOTLIN_CLASS -> printer.printWithNoIndent("class")
|
||||||
@@ -966,7 +884,7 @@ class NewCodeBuilder(context: NewJ2kConverterContext) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun visitKtWhenCaseRaw(ktWhenCase: JKKtWhenCase) {
|
override fun visitKtWhenCaseRaw(ktWhenCase: JKKtWhenCase) {
|
||||||
renderList(ktWhenCase.labels, ", ") {
|
printer.renderList(ktWhenCase.labels, ", ") {
|
||||||
it.accept(this)
|
it.accept(this)
|
||||||
}
|
}
|
||||||
printer.printWithNoIndent(" -> ")
|
printer.printWithNoIndent(" -> ")
|
||||||
@@ -982,10 +900,6 @@ class NewCodeBuilder(context: NewJ2kConverterContext) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private enum class ParenthesisKind(val open: String, val close: String) {
|
|
||||||
ROUND("(", ")"), SQUARE("[", "]"), CURVED("{", "}"), CURVED_MULTILINE("{\n", "}\n"), INLINE_COMMENT("/*", "*/"), ANGLE("<", ">")
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
fun printCodeOut(root: JKTreeElement): String {
|
fun printCodeOut(root: JKTreeElement): String {
|
||||||
Visitor().also { root.accept(it) }
|
Visitor().also { root.accept(it) }
|
||||||
@@ -993,6 +907,103 @@ class NewCodeBuilder(context: NewJ2kConverterContext) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
enum class ParenthesisKind(val open: String, val close: String) {
|
||||||
|
ROUND("(", ")"),
|
||||||
|
SQUARE("[", "]"),
|
||||||
|
CURVED("{", "}"),
|
||||||
|
CURVED_MULTILINE("{\n", "}\n"),
|
||||||
|
INLINE_COMMENT("/*", "*/"),
|
||||||
|
ANGLE("<", ">")
|
||||||
|
}
|
||||||
|
|
||||||
|
private class JKPrinter(
|
||||||
|
stringBuilder: StringBuilder,
|
||||||
|
private val elementInfoStorage: JKElementInfoStorage
|
||||||
|
) : Printer(stringBuilder) {
|
||||||
|
|
||||||
|
inline fun indented(block: () -> Unit) {
|
||||||
|
this.pushIndent()
|
||||||
|
block()
|
||||||
|
this.popIndent()
|
||||||
|
}
|
||||||
|
|
||||||
|
inline fun block(multiline: Boolean = false, crossinline body: () -> Unit) {
|
||||||
|
par(ParenthesisKind.CURVED) {
|
||||||
|
indented(body)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
inline fun par(kind: ParenthesisKind = ParenthesisKind.ROUND, body: () -> Unit) {
|
||||||
|
printWithNoIndent(kind.open)
|
||||||
|
body()
|
||||||
|
printWithNoIndent(kind.close)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun JKClassSymbol.needFqName(): Boolean =
|
||||||
|
fqName !in mappedToKotlinFqNames
|
||||||
|
|
||||||
|
|
||||||
|
fun renderType(type: JKType, owner: JKTreeElement?) {
|
||||||
|
if (type is JKNoTypeImpl) return
|
||||||
|
elementInfoStorage.getOrCreateInfoForElement(type).let {
|
||||||
|
print(it.render())
|
||||||
|
}
|
||||||
|
when (type) {
|
||||||
|
is JKClassType -> {
|
||||||
|
renderClassSymbol(type.classReference, owner)
|
||||||
|
}
|
||||||
|
is JKContextType -> return
|
||||||
|
is JKStarProjectionType ->
|
||||||
|
printWithNoIndent("*")
|
||||||
|
is JKTypeParameterType ->
|
||||||
|
printWithNoIndent(type.name)
|
||||||
|
is JKVarianceTypeParameterType -> {
|
||||||
|
when (type.variance) {
|
||||||
|
JKVarianceTypeParameterType.Variance.IN -> printWithNoIndent("in ")
|
||||||
|
JKVarianceTypeParameterType.Variance.OUT -> printWithNoIndent("out ")
|
||||||
|
}
|
||||||
|
renderType(type.boundType, null)
|
||||||
|
}
|
||||||
|
else -> printWithNoIndent("Unit /* TODO: ${type::class} */")
|
||||||
|
}
|
||||||
|
if (type is JKParametrizedType && type.parameters.isNotEmpty()) {
|
||||||
|
par(ParenthesisKind.ANGLE) {
|
||||||
|
renderList(type.parameters, renderElement = { renderType(it, null) })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (type.nullability == Nullability.Nullable) {
|
||||||
|
printWithNoIndent("?")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun renderClassSymbol(classSymbol: JKClassSymbol, owner: JKTreeElement?) {
|
||||||
|
val needFqName = classSymbol.needFqName() && owner?.isSelectorOfQualifiedExpression() != true
|
||||||
|
val displayName = if (needFqName) classSymbol.getDisplayName() else classSymbol.name
|
||||||
|
printWithNoIndent(displayName.escapedAsQualifiedName())
|
||||||
|
}
|
||||||
|
|
||||||
|
inline fun <T> renderList(list: List<T>, separator: String = ", ", renderElement: (T) -> Unit) =
|
||||||
|
renderList(list, { printWithNoIndent(separator) }, renderElement)
|
||||||
|
|
||||||
|
inline fun <T> renderList(list: List<T>, separator: () -> Unit, renderElement: (T) -> Unit) {
|
||||||
|
val (head, tail) = list.headTail()
|
||||||
|
head?.let(renderElement) ?: return
|
||||||
|
tail?.forEach {
|
||||||
|
separator()
|
||||||
|
renderElement(it)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun JKTreeElement.isSelectorOfQualifiedExpression() =
|
||||||
|
parent?.safeAs<JKQualifiedExpression>()?.selector == this
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private fun String.escapedAsQualifiedName(): String =
|
||||||
|
split('.')
|
||||||
|
.map { it.escaped() }
|
||||||
|
.joinToString(".") { it }
|
||||||
|
|
||||||
private fun <T> List<T>.headTail(): Pair<T?, List<T>?> {
|
private fun <T> List<T>.headTail(): Pair<T?, List<T>?> {
|
||||||
val head = this.firstOrNull()
|
val head = this.firstOrNull()
|
||||||
val tail = if (size <= 1) null else subList(1, size)
|
val tail = if (size <= 1) null else subList(1, size)
|
||||||
@@ -1008,3 +1019,4 @@ private val mappedToKotlinFqNames =
|
|||||||
"java.util.LinkedHashSet",
|
"java.util.LinkedHashSet",
|
||||||
"java.util.HashSet"
|
"java.util.HashSet"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user