New J2K, minor: refactor code builder

This commit is contained in:
Ilya Kirillov
2019-06-27 12:11:49 +03:00
parent 934425e86a
commit 236f62be2a
@@ -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"
) )