New J2K: rework Java code formatting collecting
#KT-33687 fixed
This commit is contained in:
@@ -0,0 +1,107 @@
|
||||
/*
|
||||
* Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* 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.nj2k
|
||||
|
||||
import com.intellij.psi.PsiComment
|
||||
import com.intellij.psi.PsiElement
|
||||
import com.intellij.psi.PsiKeyword
|
||||
import com.intellij.psi.PsiWhiteSpace
|
||||
import com.intellij.psi.javadoc.PsiDocComment
|
||||
import org.jetbrains.kotlin.idea.j2k.IdeaDocCommentConverter
|
||||
import org.jetbrains.kotlin.nj2k.tree.JKComment
|
||||
import org.jetbrains.kotlin.nj2k.tree.JKFormattingOwner
|
||||
|
||||
class FormattingCollector {
|
||||
private val commentCache = mutableMapOf<PsiElement, JKComment>()
|
||||
|
||||
fun takeFormattingFrom(
|
||||
element: JKFormattingOwner,
|
||||
psi: PsiElement?,
|
||||
saveLineBreaks: Boolean,
|
||||
takeTrailingComments: Boolean,
|
||||
takeLeadingComments: Boolean
|
||||
) {
|
||||
if (psi == null) return
|
||||
val (leftTokens, rightTokens) = psi.collectComments(takeTrailingComments, takeLeadingComments)
|
||||
element.trailingComments += leftTokens
|
||||
element.leadingComments += rightTokens
|
||||
if (saveLineBreaks) {
|
||||
element.hasLeadingLineBreak = psi.hasLineBreakAfter()
|
||||
element.hasTrailingLineBreak = psi.hasLineBreakBefore()
|
||||
}
|
||||
}
|
||||
|
||||
fun takeLineBreaksFrom(element: JKFormattingOwner, psi: PsiElement?) {
|
||||
if (psi == null) return
|
||||
element.hasLeadingLineBreak = psi.hasLineBreakAfter()
|
||||
element.hasTrailingLineBreak = psi.hasLineBreakBefore()
|
||||
}
|
||||
|
||||
private fun PsiElement.asComment(): JKComment? {
|
||||
if (this in commentCache) return commentCache.getValue(this)
|
||||
val token = when (this) {
|
||||
is PsiDocComment -> JKComment(
|
||||
IdeaDocCommentConverter.convertDocComment(
|
||||
this
|
||||
)
|
||||
)
|
||||
is PsiComment -> JKComment(text)
|
||||
else -> null
|
||||
} ?: return null
|
||||
commentCache[this] = token
|
||||
return token
|
||||
}
|
||||
|
||||
private fun Sequence<PsiElement>.toComments(): List<JKComment> =
|
||||
takeWhile { it is PsiComment || it is PsiWhiteSpace || it.text == ";" }
|
||||
.mapNotNull { it.asComment() }
|
||||
.toList()
|
||||
|
||||
fun PsiElement.leadingCommentsWithParent(): Sequence<JKComment> {
|
||||
val innerElements = leadingComments()
|
||||
return (if (innerElements.lastOrNull()?.nextSibling == null && this is PsiKeyword)
|
||||
innerElements + parent?.leadingComments().orEmpty()
|
||||
else innerElements).mapNotNull { it.asComment() }
|
||||
}
|
||||
|
||||
private fun PsiElement.trailingCommentsWithParent(): Sequence<JKComment> {
|
||||
val innerElements = trailingComments()
|
||||
return (if (innerElements.firstOrNull()?.prevSibling == null && this is PsiKeyword)
|
||||
innerElements + parent?.trailingComments().orEmpty()
|
||||
else innerElements).mapNotNull { it.asComment() }
|
||||
}
|
||||
|
||||
private fun PsiElement.isNonCodeElement() =
|
||||
this is PsiComment || this is PsiWhiteSpace || textMatches(";") || textLength == 0
|
||||
|
||||
private fun PsiElement.leadingComments() =
|
||||
generateSequence(nextSibling) { it.nextSibling }
|
||||
.takeWhile { it.isNonCodeElement() }
|
||||
|
||||
private fun PsiElement.trailingComments() =
|
||||
generateSequence(prevSibling) { it.prevSibling }
|
||||
.takeWhile { it.isNonCodeElement() }
|
||||
|
||||
private fun PsiElement.hasLineBreakBefore() = trailingComments().any { it is PsiWhiteSpace && it.textContains('\n') }
|
||||
private fun PsiElement.hasLineBreakAfter() = leadingComments().any { it is PsiWhiteSpace && it.textContains('\n') }
|
||||
|
||||
private fun PsiElement.collectComments(
|
||||
takeTrailingComments: Boolean,
|
||||
takeLeadingComments: Boolean
|
||||
): Pair<List<JKComment>, List<JKComment>> {
|
||||
val leftInnerTokens = children.asSequence().toComments().asReversed()
|
||||
val rightInnerTokens = when {
|
||||
children.isEmpty() -> emptyList()
|
||||
else -> generateSequence(children.last()) { it.prevSibling }
|
||||
.toComments()
|
||||
.asReversed()
|
||||
}
|
||||
|
||||
val leftComments = (leftInnerTokens + if (takeTrailingComments) trailingCommentsWithParent() else emptySequence()).asReversed()
|
||||
val rightComments = rightInnerTokens + if (takeLeadingComments) leadingCommentsWithParent() else emptySequence()
|
||||
return leftComments to rightComments
|
||||
}
|
||||
}
|
||||
@@ -35,13 +35,11 @@ import org.jetbrains.kotlin.asJava.elements.KtLightElement
|
||||
import org.jetbrains.kotlin.asJava.elements.KtLightField
|
||||
import org.jetbrains.kotlin.asJava.elements.KtLightMethod
|
||||
import org.jetbrains.kotlin.idea.caches.lightClasses.KtLightClassForDecompiledDeclaration
|
||||
import org.jetbrains.kotlin.idea.j2k.IdeaDocCommentConverter
|
||||
import org.jetbrains.kotlin.idea.j2k.content
|
||||
import org.jetbrains.kotlin.idea.refactoring.fqName.getKotlinFqName
|
||||
import org.jetbrains.kotlin.j2k.ReferenceSearcher
|
||||
import org.jetbrains.kotlin.j2k.ast.Nullability
|
||||
import org.jetbrains.kotlin.lexer.KtTokens
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.nj2k.symbols.*
|
||||
import org.jetbrains.kotlin.nj2k.tree.*
|
||||
import org.jetbrains.kotlin.nj2k.tree.JKLiteralExpression.LiteralType.*
|
||||
@@ -52,7 +50,6 @@ import org.jetbrains.kotlin.psi.psiUtil.collectDescendantsOfType
|
||||
import org.jetbrains.kotlin.psi.psiUtil.getStrictParentOfType
|
||||
import org.jetbrains.kotlin.psi.psiUtil.isExtensionDeclaration
|
||||
import org.jetbrains.kotlin.utils.KotlinExceptionWithAttachments
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.cast
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
||||
|
||||
|
||||
@@ -68,11 +65,36 @@ class JavaToJKTreeBuilder constructor(
|
||||
}
|
||||
|
||||
private val expressionTreeMapper = ExpressionTreeMapper()
|
||||
|
||||
private val referenceSearcher: ReferenceSearcher = converterServices.oldServices.referenceSearcher
|
||||
|
||||
private val declarationMapper = DeclarationMapper(expressionTreeMapper)
|
||||
|
||||
private val formattingCollector = FormattingCollector()
|
||||
|
||||
// we don't want to capture comments of previous declaration/statement
|
||||
private fun PsiElement.takeLeadingCommentsNeeded() =
|
||||
this !is PsiMember && this !is PsiStatement
|
||||
|
||||
private fun <T : JKFormattingOwner> T.withFormattingFrom(
|
||||
psi: PsiElement?,
|
||||
assignLineBreaks: Boolean = false,
|
||||
takeTrailingComments: Boolean = true,
|
||||
takeLeadingComments: Boolean = psi?.takeLeadingCommentsNeeded() ?: false
|
||||
): T = with(formattingCollector) {
|
||||
takeFormattingFrom(this@withFormattingFrom, psi, assignLineBreaks, takeTrailingComments, takeLeadingComments)
|
||||
this@withFormattingFrom
|
||||
}
|
||||
|
||||
private fun <O : JKFormattingOwner> O.withLineBreaksFrom(psi: PsiElement?) = with(formattingCollector) {
|
||||
takeLineBreaksFrom(this@withLineBreaksFrom, psi)
|
||||
this@withLineBreaksFrom
|
||||
}
|
||||
|
||||
private fun <O : JKFormattingOwner> O.withLeadingCommentsWithParent(psi: PsiElement?) = with(formattingCollector) {
|
||||
if (psi == null) return@with this@withLeadingCommentsWithParent
|
||||
this@withLeadingCommentsWithParent.leadingComments += psi.leadingCommentsWithParent()
|
||||
return this@withLeadingCommentsWithParent
|
||||
}
|
||||
|
||||
private fun PsiJavaFile.toJK(): JKFile =
|
||||
JKFile(
|
||||
packageStatement?.toJK() ?: JKPackageDeclaration(JKNameIdentifier("")),
|
||||
@@ -83,15 +105,15 @@ class JavaToJKTreeBuilder constructor(
|
||||
private fun PsiImportList?.toJK(saveImports: Boolean): JKImportList =
|
||||
JKImportList(this?.allImportStatements?.mapNotNull { it.toJK(saveImports) }.orEmpty()).also { importList ->
|
||||
val innerComments = this?.collectDescendantsOfType<PsiComment>()?.map { comment ->
|
||||
JKCommentElement(comment.text)
|
||||
JKComment(comment.text)
|
||||
}.orEmpty()
|
||||
importList.leftNonCodeElements += innerComments
|
||||
importList.trailingComments += innerComments
|
||||
}
|
||||
|
||||
private fun PsiPackageStatement.toJK(): JKPackageDeclaration =
|
||||
JKPackageDeclaration(JKNameIdentifier(packageName))
|
||||
.also {
|
||||
it.assignNonCodeElements(this)
|
||||
it.withFormattingFrom(this)
|
||||
symbolProvider.provideUniverseSymbol(this, it)
|
||||
}
|
||||
|
||||
@@ -118,14 +140,14 @@ class JavaToJKTreeBuilder constructor(
|
||||
|
||||
return JKImportStatement(JKNameIdentifier(name))
|
||||
.also {
|
||||
it.assignNonCodeElements(this)
|
||||
it.withFormattingFrom(this)
|
||||
}
|
||||
}
|
||||
|
||||
private fun PsiIdentifier?.toJK(): JKNameIdentifier =
|
||||
this?.let {
|
||||
JKNameIdentifier(it.text).also {
|
||||
it.assignNonCodeElements(this)
|
||||
it.withFormattingFrom(this)
|
||||
}
|
||||
} ?: JKNameIdentifier("")
|
||||
|
||||
@@ -165,7 +187,7 @@ class JavaToJKTreeBuilder constructor(
|
||||
is PsiPolyadicExpression -> {
|
||||
val token = JKOperatorToken.fromElementType(operationTokenType)
|
||||
val type = type?.toJK() ?: typeFactory.types.nullableAny
|
||||
val jkOperands = operands.map { it.toJK().parenthesizeIfBinaryExpression() }
|
||||
val jkOperands = operands.map { it.toJK().withLineBreaksFrom(it).parenthesizeIfBinaryExpression() }
|
||||
jkOperands.reduce { acc, operand ->
|
||||
JKBinaryExpression(acc, operand, JKKtOperatorImpl(token, type))
|
||||
}.let { folded ->
|
||||
@@ -180,7 +202,7 @@ class JavaToJKTreeBuilder constructor(
|
||||
}.also {
|
||||
if (this != null) {
|
||||
(it as PsiOwner).psi = this
|
||||
it.assignNonCodeElements(this)
|
||||
it.withFormattingFrom(this)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -195,14 +217,14 @@ class JavaToJKTreeBuilder constructor(
|
||||
else -> JKClassLiteralExpression.ClassLiteralType.JAVA_CLASS
|
||||
}
|
||||
).also {
|
||||
it.assignNonCodeElements(this)
|
||||
it.withFormattingFrom(this)
|
||||
}
|
||||
}
|
||||
|
||||
fun PsiInstanceOfExpression.toJK(): JKIsExpression =
|
||||
JKIsExpression(operand.toJK(), JKTypeElement(checkType?.type?.toJK() ?: JKNoType))
|
||||
.also {
|
||||
it.assignNonCodeElements(this)
|
||||
it.withFormattingFrom(this)
|
||||
}
|
||||
|
||||
fun PsiAssignmentExpression.toJK(): JKJavaAssignmentExpression {
|
||||
@@ -211,7 +233,7 @@ class JavaToJKTreeBuilder constructor(
|
||||
rExpression.toJK(),
|
||||
createOperator(operationSign.tokenType, type)
|
||||
).also {
|
||||
it.assignNonCodeElements(this)
|
||||
it.withFormattingFrom(this)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -226,14 +248,14 @@ class JavaToJKTreeBuilder constructor(
|
||||
else -> JKOperatorToken.fromElementType(operationSign.tokenType)
|
||||
}
|
||||
return JKBinaryExpression(
|
||||
lOperand.toJK(),
|
||||
rOperand.toJK(),
|
||||
lOperand.toJK().withLineBreaksFrom(lOperand),
|
||||
rOperand.toJK().withLineBreaksFrom(rOperand),
|
||||
JKKtOperatorImpl(
|
||||
token,
|
||||
type?.toJK() ?: typeFactory.types.nullableAny
|
||||
)
|
||||
).also {
|
||||
it.assignNonCodeElements(this)
|
||||
it.withFormattingFrom(this)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -252,7 +274,7 @@ class JavaToJKTreeBuilder constructor(
|
||||
JavaTokenType.DOUBLE_LITERAL -> JKLiteralExpression(text, DOUBLE)
|
||||
else -> throwCanNotConvertError("Unknown literal element type: $literalElementType")
|
||||
}.also {
|
||||
it.assignNonCodeElements(this)
|
||||
it.withFormattingFrom(this)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -266,12 +288,12 @@ class JavaToJKTreeBuilder constructor(
|
||||
JavaTokenType.TILDE -> operand.toJK().callOn(symbolProvider.provideMethodSymbol("kotlin.Int.inv"))
|
||||
else -> JKPrefixExpression(operand.toJK(), createOperator(operationSign.tokenType, type))
|
||||
}.also {
|
||||
it.assignNonCodeElements(this)
|
||||
it.withFormattingFrom(this)
|
||||
}
|
||||
|
||||
fun PsiPostfixExpression.toJK(): JKExpression =
|
||||
JKPostfixExpression(operand.toJK(), createOperator(operationSign.tokenType, type)).also {
|
||||
it.assignNonCodeElements(this)
|
||||
it.withFormattingFrom(this)
|
||||
}
|
||||
|
||||
fun PsiLambdaExpression.toJK(): JKExpression {
|
||||
@@ -286,7 +308,7 @@ class JavaToJKTreeBuilder constructor(
|
||||
with(declarationMapper) { parameterList.parameters.map { it.toJK() } },
|
||||
functionalType()
|
||||
).also {
|
||||
it.assignNonCodeElements(this)
|
||||
it.withFormattingFrom(this)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -309,7 +331,7 @@ class JavaToJKTreeBuilder constructor(
|
||||
fun PsiMethodCallExpression.toJK(): JKExpression {
|
||||
val arguments = argumentList
|
||||
val typeArguments = getExplicitTypeArguments().toJK()
|
||||
val qualifier = methodExpression.qualifierExpression?.toJK()
|
||||
val qualifier = methodExpression.qualifierExpression?.toJK()?.withLineBreaksFrom(methodExpression.qualifierExpression)
|
||||
val target = methodExpression.resolve()
|
||||
val symbol = target?.let {
|
||||
symbolProvider.provideDirectSymbol(it)
|
||||
@@ -397,7 +419,7 @@ class JavaToJKTreeBuilder constructor(
|
||||
JKFieldAccessExpression(symbol).qualified(qualifier)
|
||||
else -> throwCanNotConvertError("unexpected symbol ${symbol::class}")
|
||||
}.also {
|
||||
it.assignNonCodeElements(this)
|
||||
it.withFormattingFrom(this)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -447,16 +469,16 @@ class JavaToJKTreeBuilder constructor(
|
||||
is JKPackageSymbol -> JKPackageAccessExpression(symbol)
|
||||
else -> throwCanNotConvertError("unexpected symbol ${symbol::class}")
|
||||
}.qualified(qualifierExpression?.toJK()).also {
|
||||
it.assignNonCodeElements(this)
|
||||
it.withFormattingFrom(this)
|
||||
}
|
||||
}
|
||||
|
||||
fun PsiArrayInitializerExpression.toJK(): JKExpression {
|
||||
return JKJavaNewArray(
|
||||
initializers.map { it.toJK() },
|
||||
initializers.map { it.toJK().withLineBreaksFrom(it) },
|
||||
JKTypeElement(type?.toJK().safeAs<JKJavaArrayType>()?.type ?: JKContextType)
|
||||
).also {
|
||||
it.assignNonCodeElements(this)
|
||||
it.withFormattingFrom(this)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -479,7 +501,7 @@ class JavaToJKTreeBuilder constructor(
|
||||
child = child.nextSibling
|
||||
}
|
||||
JKJavaNewEmptyArray(
|
||||
dimensions.map { it?.toJK() ?: JKStubExpression() },
|
||||
dimensions.map { it?.toJK()?.withLineBreaksFrom(it) ?: JKStubExpression() },
|
||||
JKTypeElement(generateSequence(type?.toJK()) { it.safeAs<JKJavaArrayType>()?.type }.last())
|
||||
).also {
|
||||
it.psi = this
|
||||
@@ -515,7 +537,7 @@ class JavaToJKTreeBuilder constructor(
|
||||
fun PsiReferenceParameterList.toJK(): JKTypeArgumentList =
|
||||
JKTypeArgumentList(typeArguments.map { JKTypeElement(it.toJK()) })
|
||||
.also {
|
||||
it.assignNonCodeElements(this)
|
||||
it.withFormattingFrom(this)
|
||||
}
|
||||
|
||||
|
||||
@@ -525,7 +547,7 @@ class JavaToJKTreeBuilder constructor(
|
||||
symbolProvider.provideMethodSymbol("kotlin.Array.get"),
|
||||
arguments = listOf(indexExpression?.toJK() ?: JKStubExpression())
|
||||
).also {
|
||||
it.assignNonCodeElements(this)
|
||||
it.withFormattingFrom(this)
|
||||
}
|
||||
|
||||
|
||||
@@ -534,19 +556,19 @@ class JavaToJKTreeBuilder constructor(
|
||||
operand?.toJK() ?: throwCanNotConvertError(),
|
||||
(castType?.type?.toJK() ?: JKNoType).asTypeElement()
|
||||
).also {
|
||||
it.assignNonCodeElements(this)
|
||||
it.withFormattingFrom(this)
|
||||
}
|
||||
}
|
||||
|
||||
fun PsiParenthesizedExpression.toJK(): JKExpression {
|
||||
return JKParenthesizedExpression(expression.toJK())
|
||||
.also {
|
||||
it.assignNonCodeElements(this)
|
||||
it.withFormattingFrom(this)
|
||||
}
|
||||
}
|
||||
|
||||
fun PsiExpressionList.toJK(): JKArgumentList {
|
||||
val jkExpressions = expressions.map { it.toJK() }
|
||||
val jkExpressions = expressions.map { it.toJK().withLineBreaksFrom(it) }
|
||||
return ((parent as? PsiCall)?.resolveMethod()
|
||||
?.let { method ->
|
||||
val lastExpressionType = expressions.lastOrNull()?.type
|
||||
@@ -558,13 +580,17 @@ class JavaToJKTreeBuilder constructor(
|
||||
JKPrefixExpression(
|
||||
jkExpressions.last(),
|
||||
JKKtSpreadOperator(lastExpressionType.toJK())
|
||||
).withNonCodeElementsFrom(jkExpressions.last())
|
||||
).withFormattingFrom(jkExpressions.last())
|
||||
staredExpression.expression.also {
|
||||
it.hasLeadingLineBreak = false
|
||||
it.hasTrailingLineBreak = false
|
||||
}
|
||||
jkExpressions.dropLast(1) + staredExpression
|
||||
} else jkExpressions
|
||||
} ?: jkExpressions)
|
||||
.toArgumentList()
|
||||
.also {
|
||||
it.assignNonCodeElements(this)
|
||||
it.withFormattingFrom(this)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -575,7 +601,7 @@ class JavaToJKTreeBuilder constructor(
|
||||
fun PsiTypeParameterList.toJK(): JKTypeParameterList =
|
||||
JKTypeParameterList(typeParameters.map { it.toJK() })
|
||||
.also {
|
||||
it.assignNonCodeElements(this)
|
||||
it.withFormattingFrom(this)
|
||||
}
|
||||
|
||||
fun PsiTypeParameter.toJK(): JKTypeParameter =
|
||||
@@ -584,7 +610,7 @@ class JavaToJKTreeBuilder constructor(
|
||||
extendsListTypes.map { JKTypeElement(it.toJK()) }
|
||||
).also {
|
||||
symbolProvider.provideUniverseSymbol(this, it)
|
||||
it.assignNonCodeElements(this)
|
||||
it.withFormattingFrom(this)
|
||||
}
|
||||
|
||||
fun PsiClass.toJK(): JKClass =
|
||||
@@ -601,7 +627,7 @@ class JavaToJKTreeBuilder constructor(
|
||||
).also { klass ->
|
||||
klass.psi = this
|
||||
symbolProvider.provideUniverseSymbol(this, klass)
|
||||
klass.assignNonCodeElements(this)
|
||||
klass.withFormattingFrom(this)
|
||||
}
|
||||
|
||||
|
||||
@@ -611,7 +637,7 @@ class JavaToJKTreeBuilder constructor(
|
||||
return JKInheritanceInfo(extensionType, implTypes)
|
||||
.also {
|
||||
if (implementsList != null) {
|
||||
it.assignNonCodeElements(implementsList!!)
|
||||
it.withFormattingFrom(implementsList!!)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -630,15 +656,21 @@ class JavaToJKTreeBuilder constructor(
|
||||
}
|
||||
}
|
||||
).also {
|
||||
it.leftBrace.assignNonCodeElements(lBrace)
|
||||
it.rightBrace.assignNonCodeElements(rBrace)
|
||||
it.leftBrace.withFormattingFrom(
|
||||
lBrace,
|
||||
takeLeadingComments = false
|
||||
) // do not capture comments which belongs to following declarations
|
||||
it.rightBrace.withFormattingFrom(rBrace)
|
||||
it.declarations.lastOrNull()?.let { lastMember ->
|
||||
lastMember.withLeadingCommentsWithParent(lastMember.psi)
|
||||
}
|
||||
}
|
||||
|
||||
fun PsiClassInitializer.toJK(): JKDeclaration = when {
|
||||
hasModifier(JvmModifier.STATIC) -> JKJavaStaticInitDeclaration(body.toJK())
|
||||
else -> JKKtInitDeclaration(body.toJK())
|
||||
}.also {
|
||||
it.assignNonCodeElements(this)
|
||||
it.withFormattingFrom(this)
|
||||
}
|
||||
|
||||
|
||||
@@ -658,12 +690,12 @@ class JavaToJKTreeBuilder constructor(
|
||||
).also {
|
||||
symbolProvider.provideUniverseSymbol(this, it)
|
||||
it.psi = this
|
||||
it.assignNonCodeElements(this)
|
||||
it.withFormattingFrom(this)
|
||||
}
|
||||
|
||||
|
||||
fun PsiMember.modality() =
|
||||
modality { ast, psi -> ast.assignNonCodeElements(psi) }
|
||||
modality { ast, psi -> ast.withFormattingFrom(psi) }
|
||||
|
||||
fun PsiMember.otherModifiers() =
|
||||
modifierList?.children?.mapNotNull { child ->
|
||||
@@ -678,17 +710,17 @@ class JavaToJKTreeBuilder constructor(
|
||||
|
||||
else -> null
|
||||
}?.let {
|
||||
JKOtherModifierElement(it).withAssignedNonCodeElements(child)
|
||||
JKOtherModifierElement(it).withFormattingFrom(child)
|
||||
}
|
||||
}.orEmpty()
|
||||
|
||||
|
||||
private fun PsiMember.visibility(): JKVisibilityModifierElement =
|
||||
visibility(referenceSearcher) { ast, psi -> ast.assignNonCodeElements(psi) }
|
||||
visibility(referenceSearcher) { ast, psi -> ast.withFormattingFrom(psi) }
|
||||
|
||||
fun PsiField.toJK(): JKField {
|
||||
return JKField(
|
||||
JKTypeElement(type.toJK()).withAssignedNonCodeElements(typeElement),
|
||||
JKTypeElement(type.toJK()).withFormattingFrom(typeElement),
|
||||
nameIdentifier.toJK(),
|
||||
with(expressionTreeMapper) { initializer.toJK() },
|
||||
annotationList(this),
|
||||
@@ -699,7 +731,7 @@ class JavaToJKTreeBuilder constructor(
|
||||
).also {
|
||||
symbolProvider.provideUniverseSymbol(this, it)
|
||||
it.psi = this
|
||||
it.assignNonCodeElements(this)
|
||||
it.withFormattingFrom(this)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -735,7 +767,7 @@ class JavaToJKTreeBuilder constructor(
|
||||
}
|
||||
}
|
||||
).also {
|
||||
it.assignNonCodeElements(this)
|
||||
it.withFormattingFrom(this)
|
||||
}
|
||||
|
||||
fun PsiDocComment.deprecatedAnnotation(): JKAnnotation? =
|
||||
@@ -756,7 +788,7 @@ class JavaToJKTreeBuilder constructor(
|
||||
JKKtAnnotationArrayInitializerExpression(initializers.map { it.toJK() })
|
||||
else -> throwCanNotConvertError()
|
||||
}.also {
|
||||
it.assignNonCodeElements(this)
|
||||
it.withFormattingFrom(this)
|
||||
}
|
||||
|
||||
fun PsiAnnotationMethod.toJK(): JKJavaAnnotationMethod =
|
||||
@@ -773,7 +805,7 @@ class JavaToJKTreeBuilder constructor(
|
||||
).also {
|
||||
it.psi = this
|
||||
symbolProvider.provideUniverseSymbol(this, it)
|
||||
it.assignNonCodeElements(this)
|
||||
it.withFormattingFrom(this)
|
||||
}
|
||||
|
||||
|
||||
@@ -784,7 +816,7 @@ class JavaToJKTreeBuilder constructor(
|
||||
?: JKJavaVoidType.takeIf { isConstructor }
|
||||
?: JKNoType),
|
||||
nameIdentifier.toJK(),
|
||||
parameterList.parameters.map { it.toJK() },
|
||||
parameterList.parameters.map { it.toJK().withLineBreaksFrom(it) },
|
||||
body?.toJK() ?: JKBodyStub,
|
||||
typeParameterList?.toJK() ?: JKTypeParameterList(),
|
||||
annotationList(this),
|
||||
@@ -798,10 +830,10 @@ class JavaToJKTreeBuilder constructor(
|
||||
parameterList.node
|
||||
?.safeAs<CompositeElement>()
|
||||
?.also {
|
||||
jkMethod.leftParen.assignNonCodeElements(it.findChildByRoleAsPsiElement(ChildRole.LPARENTH))
|
||||
jkMethod.rightParen.assignNonCodeElements(it.findChildByRoleAsPsiElement(ChildRole.RPARENTH))
|
||||
jkMethod.leftParen.withFormattingFrom(it.findChildByRoleAsPsiElement(ChildRole.LPARENTH))
|
||||
jkMethod.rightParen.withFormattingFrom(it.findChildByRoleAsPsiElement(ChildRole.RPARENTH))
|
||||
}
|
||||
}.withAssignedNonCodeElements(this)
|
||||
}.withFormattingFrom(this)
|
||||
}
|
||||
|
||||
fun PsiParameter.toJK(): JKParameter {
|
||||
@@ -817,22 +849,22 @@ class JavaToJKTreeBuilder constructor(
|
||||
).also {
|
||||
symbolProvider.provideUniverseSymbol(this, it)
|
||||
it.psi = this
|
||||
it.assignNonCodeElements(this)
|
||||
it.withFormattingFrom(this)
|
||||
}
|
||||
}
|
||||
|
||||
fun PsiCodeBlock.toJK(): JKBlock =
|
||||
JKBlockImpl(statements.map { it.toJK() })
|
||||
.withAssignedNonCodeElements(this)
|
||||
.withFormattingFrom(this)
|
||||
.also {
|
||||
it.leftBrace.assignNonCodeElements(lBrace)
|
||||
it.rightBrace.assignNonCodeElements(rBrace)
|
||||
it.leftBrace.withFormattingFrom(lBrace)
|
||||
it.rightBrace.withFormattingFrom(rBrace)
|
||||
}
|
||||
|
||||
|
||||
fun PsiLocalVariable.toJK(): JKLocalVariable =
|
||||
JKLocalVariable(
|
||||
JKTypeElement(type.toJK()).withAssignedNonCodeElements(typeElement),
|
||||
JKTypeElement(type.toJK()).withFormattingFrom(typeElement),
|
||||
nameIdentifier.toJK(),
|
||||
with(expressionTreeMapper) { initializer.toJK() },
|
||||
JKMutabilityModifierElement(
|
||||
@@ -844,7 +876,7 @@ class JavaToJKTreeBuilder constructor(
|
||||
symbolProvider.provideUniverseSymbol(this, i)
|
||||
i.psi = this
|
||||
}.also {
|
||||
it.assignNonCodeElements(this)
|
||||
it.withFormattingFrom(this)
|
||||
}
|
||||
|
||||
fun PsiStatement?.toJK(): JKStatement {
|
||||
@@ -903,7 +935,7 @@ class JavaToJKTreeBuilder constructor(
|
||||
with(expressionTreeMapper) { statement.caseValue.toJK() },
|
||||
emptyList()
|
||||
)
|
||||
}.withAssignedNonCodeElements(statement)
|
||||
}.withFormattingFrom(statement)
|
||||
else ->
|
||||
cases.lastOrNull()?.also { it.statements = it.statements + statement.toJK() }
|
||||
?: run {
|
||||
@@ -947,7 +979,7 @@ class JavaToJKTreeBuilder constructor(
|
||||
}.also {
|
||||
if (this != null) {
|
||||
(it as PsiOwner).psi = this
|
||||
it.assignNonCodeElements(this)
|
||||
it.withFormattingFrom(this)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -958,7 +990,7 @@ class JavaToJKTreeBuilder constructor(
|
||||
catchBlock?.toJK() ?: JKBodyStub
|
||||
).also {
|
||||
it.psi = this
|
||||
it.assignNonCodeElements(this)
|
||||
it.withFormattingFrom(this)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -989,77 +1021,6 @@ class JavaToJKTreeBuilder constructor(
|
||||
else -> null
|
||||
}?.let { JKTreeRoot(it) }
|
||||
|
||||
private val tokenCache = mutableMapOf<PsiElement, JKNonCodeElement>()
|
||||
|
||||
private fun PsiElement.collectNonCodeElements(): Pair<List<JKNonCodeElement>, List<JKNonCodeElement>> {
|
||||
fun PsiElement.toToken(): JKNonCodeElement? {
|
||||
if (this in tokenCache) return tokenCache.getValue(this)
|
||||
val token = when {
|
||||
this is PsiDocComment ->
|
||||
JKCommentElement(IdeaDocCommentConverter.convertDocComment(this))
|
||||
this is PsiComment -> JKCommentElement(text)
|
||||
this is PsiWhiteSpace -> JKSpaceElement(text)
|
||||
text == ";" -> null
|
||||
text == "" -> null
|
||||
else -> null
|
||||
} ?: return null
|
||||
tokenCache[this] = token
|
||||
return token
|
||||
}
|
||||
|
||||
fun Sequence<PsiElement>.toNonCodeElements(): List<JKNonCodeElement> =
|
||||
takeWhile { it is PsiComment || it is PsiWhiteSpace || it.text == ";" }
|
||||
.mapNotNull { it.toToken() }
|
||||
.toList()
|
||||
|
||||
fun PsiElement.isNonCodeElement() =
|
||||
this is PsiComment || this is PsiWhiteSpace || text == ";" || text == ""
|
||||
|
||||
fun PsiElement.nextNonCodeElements() =
|
||||
generateSequence(nextSibling) { it.nextSibling }
|
||||
.takeWhile { it.isNonCodeElement() }
|
||||
|
||||
fun PsiElement.prevNonCodeElements() =
|
||||
generateSequence(prevSibling) { it.prevSibling }
|
||||
.takeWhile { it.isNonCodeElement() }
|
||||
|
||||
|
||||
fun PsiElement.nextNonCodeElementsWithParent(): Sequence<JKNonCodeElement> {
|
||||
val innerElements = nextNonCodeElements()
|
||||
return (if (innerElements.lastOrNull()?.nextSibling == null && this is PsiKeyword)
|
||||
innerElements + parent?.nextNonCodeElements().orEmpty()
|
||||
else innerElements).mapNotNull { it.toToken() }
|
||||
}
|
||||
|
||||
fun PsiElement.prevNonCodeElementsWithParent(): Sequence<JKNonCodeElement> {
|
||||
val innerElements = prevNonCodeElements()
|
||||
return (if (innerElements.firstOrNull()?.prevSibling == null && this is PsiKeyword)
|
||||
innerElements + parent?.prevNonCodeElements().orEmpty()
|
||||
else innerElements).mapNotNull { it.toToken() }
|
||||
}
|
||||
|
||||
|
||||
val leftInnerTokens = children.asSequence().toNonCodeElements().reversed()
|
||||
val rightInnerTokens =
|
||||
if (children.isEmpty()) emptyList()
|
||||
else generateSequence(children.last()) { it.prevSibling }
|
||||
.toNonCodeElements()
|
||||
.reversed()
|
||||
|
||||
|
||||
return (leftInnerTokens + prevNonCodeElementsWithParent()).reversed() to
|
||||
(rightInnerTokens + nextNonCodeElementsWithParent())
|
||||
}
|
||||
|
||||
private fun JKNonCodeElementsListOwner.assignNonCodeElements(psi: PsiElement?) {
|
||||
if (psi == null) return
|
||||
val (leftTokens, rightTokens) = psi.collectNonCodeElements()
|
||||
this.leftNonCodeElements += leftTokens
|
||||
this.rightNonCodeElements += rightTokens
|
||||
}
|
||||
|
||||
private inline fun <reified T : JKNonCodeElementsListOwner> T.withAssignedNonCodeElements(psi: PsiElement?): T =
|
||||
also { it.assignNonCodeElements(psi) }
|
||||
|
||||
private fun PsiElement.throwCanNotConvertError(message: String? = null): Nothing {
|
||||
throw KotlinExceptionWithAttachments("Cannot convert the following Java element ${this::class}" + message?.let { " due to `$it`" })
|
||||
|
||||
@@ -29,49 +29,50 @@ class NewCodeBuilder(context: NewJ2kConverterContext) {
|
||||
}
|
||||
|
||||
inner class Visitor : JKVisitorWithCommentsPrinting() {
|
||||
private val printedTokens = mutableSetOf<JKNonCodeElement>()
|
||||
private val printedTokens = mutableSetOf<JKComment>()
|
||||
|
||||
//TODO move to ast transformation phase
|
||||
private fun JKNonCodeElement.shouldBeDropped(): Boolean =
|
||||
this is JKCommentElement && text.startsWith("//noinspection")
|
||||
private fun JKComment.shouldBeDropped(): Boolean =
|
||||
text.startsWith("//noinspection")
|
||||
|
||||
private fun JKNonCodeElement.createText() =
|
||||
private fun JKComment.createText() =
|
||||
if (this !in printedTokens) {
|
||||
printedTokens += this
|
||||
text
|
||||
} else ""
|
||||
} else null
|
||||
|
||||
|
||||
private fun List<JKNonCodeElement>.createText(): String {
|
||||
val text = filterNot { it.shouldBeDropped() }.joinToString("") { token -> token.createText() }
|
||||
val needNewLine = text.lastIndexOf('\n') < text.lastIndexOf("//")
|
||||
return text + "\n".takeIf { needNewLine }.orEmpty()
|
||||
private fun List<JKComment>.createText(): String = buildString {
|
||||
var needNewLine = false
|
||||
for (comment in this@createText) {
|
||||
if (comment.shouldBeDropped()) continue
|
||||
val text = comment.createText() ?: continue
|
||||
if (needNewLine) appendln() else append(' ')
|
||||
append(text)
|
||||
needNewLine = text.startsWith("//") || '\n' in text
|
||||
}
|
||||
}
|
||||
|
||||
private fun JKNonCodeElementsListOwner.needPreserveSpacesAfterLastComment() =
|
||||
this is JKArgument
|
||||
|| this is JKParameter
|
||||
|| safeAs<JKTreeElement>()?.parent is JKArgument
|
||||
|| safeAs<JKTreeElement>()?.parent is JKBinaryExpression
|
||||
|| safeAs<JKTreeElement>()?.parent is JKQualifiedExpression
|
||||
private fun String.hasNoLineBreakAfterSingleLineComment() = lastIndexOf('\n') < lastIndexOf("//")
|
||||
|
||||
override fun printLeftNonCodeElements(element: JKNonCodeElementsListOwner) {
|
||||
val text = element.leftNonCodeElements
|
||||
.let {
|
||||
if (element.needPreserveSpacesAfterLastComment()) it
|
||||
else it.dropWhile { it is JKSpaceElement }
|
||||
}.createText()
|
||||
override fun printLeftNonCodeElements(element: JKFormattingOwner) {
|
||||
val text = element.trailingComments.createText()
|
||||
printer.printWithNoIndent(text)
|
||||
|
||||
val addNewLine = element.hasTrailingLineBreak
|
||||
|| element is JKDeclaration && element.trailingComments.isNotEmpty() // add new line between comment & declaration
|
||||
|| text.hasNoLineBreakAfterSingleLineComment()
|
||||
|
||||
if (addNewLine) printer.println()
|
||||
}
|
||||
|
||||
|
||||
override fun printRightNonCodeElements(element: JKNonCodeElementsListOwner) {
|
||||
val text = element.rightNonCodeElements
|
||||
.let {
|
||||
if (element.needPreserveSpacesAfterLastComment()) it
|
||||
else it.dropLastWhile { it is JKSpaceElement }
|
||||
}.createText()
|
||||
override fun printRightNonCodeElements(element: JKFormattingOwner) {
|
||||
val text = element.leadingComments.createText()
|
||||
printer.printWithNoIndent(text)
|
||||
|
||||
val addNewLine = element.hasLeadingLineBreak || text.hasNoLineBreakAfterSingleLineComment()
|
||||
if (addNewLine) printer.println()
|
||||
}
|
||||
|
||||
private fun renderTokenElement(tokenElement: JKTokenElement) {
|
||||
|
||||
+2
-4
@@ -13,15 +13,13 @@ class AddParenthesisForLineBreaksInBinaryExpression(override val context: NewJ2k
|
||||
override fun applyToElement(element: JKTreeElement): JKTreeElement {
|
||||
if (element !is JKBinaryExpression) return recurse(element)
|
||||
if (element.parent is JKBinaryExpression) return recurse(element)
|
||||
if (element.left.rightNonCodeElements.any {
|
||||
it is JKSpaceElement && '\n' in it.text
|
||||
}) {
|
||||
if (element.left.hasLeadingLineBreak) {
|
||||
return JKParenthesizedExpression(
|
||||
JKBinaryExpression(
|
||||
element::left.detached(),
|
||||
element::right.detached(),
|
||||
element.operator
|
||||
).withNonCodeElementsFrom(element)
|
||||
).withFormattingFrom(element)
|
||||
)
|
||||
}
|
||||
return recurse(element)
|
||||
|
||||
@@ -7,7 +7,6 @@ package org.jetbrains.kotlin.nj2k.conversions
|
||||
|
||||
import org.jetbrains.kotlin.j2k.ast.Nullability
|
||||
import org.jetbrains.kotlin.nj2k.NewJ2kConverterContext
|
||||
import org.jetbrains.kotlin.nj2k.modality
|
||||
import org.jetbrains.kotlin.nj2k.toExpression
|
||||
import org.jetbrains.kotlin.nj2k.tree.*
|
||||
|
||||
@@ -58,11 +57,11 @@ class AnnotationClassConversion(context: NewJ2kConverterContext) : RecursiveAppl
|
||||
JKKtAnnotationArrayInitializerExpression(initializer)
|
||||
} else initializer
|
||||
).also { parameter ->
|
||||
if (leftNonCodeElements.any { it is JKCommentElement }) {
|
||||
parameter.leftNonCodeElements += leftNonCodeElements
|
||||
if (trailingComments.any { it is JKComment }) {
|
||||
parameter.trailingComments += trailingComments
|
||||
}
|
||||
if (rightNonCodeElements.any { it is JKCommentElement }) {
|
||||
parameter.rightNonCodeElements += rightNonCodeElements
|
||||
if (leadingComments.any { it is JKComment }) {
|
||||
parameter.leadingComments += leadingComments
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+6
-6
@@ -34,14 +34,14 @@ class AssignmentExpressionUnfoldingConversion(context: NewJ2kConverterContext) :
|
||||
val assignment = statement.expression as JKJavaAssignmentExpression
|
||||
newStatements += assignment
|
||||
.unfoldToStatementsList(assignmentTarget = null)
|
||||
.withNonCodeElementsFrom(statement)
|
||||
.withFormattingFrom(statement)
|
||||
}
|
||||
statement is JKDeclarationStatement && statement.containsAssignment() -> {
|
||||
val variable = statement.declaredStatements.single() as JKVariable
|
||||
val assignment = variable.initializer as JKJavaAssignmentExpression
|
||||
newStatements += assignment
|
||||
.unfoldToStatementsList(variable.detached(statement))
|
||||
.withNonCodeElementsFrom(statement)
|
||||
.withFormattingFrom(statement)
|
||||
}
|
||||
else -> {
|
||||
newStatements += statement
|
||||
@@ -62,7 +62,7 @@ class AssignmentExpressionUnfoldingConversion(context: NewJ2kConverterContext) :
|
||||
assignment::expression.detached(),
|
||||
assignment.operator
|
||||
)
|
||||
}.withNonCodeElementsFrom(this)
|
||||
}.withFormattingFrom(this)
|
||||
}
|
||||
|
||||
private fun JKExpressionStatement.canBeConvertedToBlock() = when (val parent = parent) {
|
||||
@@ -73,7 +73,7 @@ class AssignmentExpressionUnfoldingConversion(context: NewJ2kConverterContext) :
|
||||
}
|
||||
|
||||
private fun JKJavaAssignmentExpression.convertAssignments() =
|
||||
unfoldToExpressionsChain().withNonCodeElementsFrom(this)
|
||||
unfoldToExpressionsChain().withFormattingFrom(this)
|
||||
|
||||
private fun JKDeclarationStatement.containsAssignment() =
|
||||
declaredStatements.singleOrNull()?.safeAs<JKVariable>()?.initializer is JKJavaAssignmentExpression
|
||||
@@ -118,7 +118,7 @@ class AssignmentExpressionUnfoldingConversion(context: NewJ2kConverterContext) :
|
||||
this::field.detached(),
|
||||
JKKtItExpression(operator.returnType),
|
||||
operator
|
||||
).withNonCodeElementsFrom(this)
|
||||
).withFormattingFrom(this)
|
||||
return when {
|
||||
operator.isSimpleToken() ->
|
||||
JKAssignmentChainAlsoLink(receiver, assignment, field.copyTreeAndDetach())
|
||||
@@ -129,7 +129,7 @@ class AssignmentExpressionUnfoldingConversion(context: NewJ2kConverterContext) :
|
||||
|
||||
private fun JKJavaAssignmentExpression.toDeclarationChainLink(expression: JKExpression) =
|
||||
createKtAssignmentStatement(this::field.detached(), expression, this.operator)
|
||||
.withNonCodeElementsFrom(this)
|
||||
.withFormattingFrom(this)
|
||||
|
||||
private fun createKtAssignmentStatement(
|
||||
field: JKExpression,
|
||||
|
||||
@@ -27,7 +27,7 @@ class BlockToRunConversion(context: NewJ2kConverterContext) : RecursiveApplicabl
|
||||
symbolProvider.provideMethodSymbol("kotlin.run"),
|
||||
JKArgumentList(lambda)
|
||||
)
|
||||
return recurse(JKExpressionStatement(call).withNonCodeElementsFrom(element))
|
||||
return recurse(JKExpressionStatement(call).withFormattingFrom(element))
|
||||
}
|
||||
|
||||
}
|
||||
@@ -43,7 +43,7 @@ class BoxedTypeOperationsConversion(context: NewJ2kConverterContext) : Recursive
|
||||
"kotlin.${primitiveTypeName.capitalize()}.to${operationType.capitalize()}"
|
||||
),
|
||||
JKArgumentList()
|
||||
).withNonCodeElementsFrom(methodCallExpression)
|
||||
).withFormattingFrom(methodCallExpression)
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
||||
@@ -33,11 +33,11 @@ class BuiltinMembersConversion(context: NewJ2kConverterContext) : RecursiveAppli
|
||||
val newSelector = conversion.createBuilder().build(selector)
|
||||
|
||||
if (this is JKQualifiedExpression && conversion.replaceType == ReplaceType.REPLACE_WITH_QUALIFIER) {
|
||||
newSelector.rightNonCodeElements += receiver.leftNonCodeElements
|
||||
newSelector.rightNonCodeElements += receiver.leftNonCodeElements
|
||||
newSelector.rightNonCodeElements += receiver.rightNonCodeElements
|
||||
newSelector.rightNonCodeElements += selector.leftNonCodeElements
|
||||
newSelector.rightNonCodeElements += selector.rightNonCodeElements
|
||||
newSelector.leadingComments += receiver.trailingComments
|
||||
newSelector.leadingComments += receiver.trailingComments
|
||||
newSelector.leadingComments += receiver.leadingComments
|
||||
newSelector.leadingComments += selector.trailingComments
|
||||
newSelector.leadingComments += selector.leadingComments
|
||||
}
|
||||
|
||||
return when (conversion.replaceType) {
|
||||
@@ -93,19 +93,19 @@ class BuiltinMembersConversion(context: NewJ2kConverterContext) : RecursiveAppli
|
||||
symbolProvider.provideMethodSymbol(fqName),
|
||||
argumentsProvider(from::arguments.detached()),
|
||||
from::typeArgumentList.detached()
|
||||
).withNonCodeElementsFrom(from)
|
||||
).withFormattingFrom(from)
|
||||
is JKFieldAccessExpression ->
|
||||
JKCallExpressionImpl(
|
||||
symbolProvider.provideMethodSymbol(fqName),
|
||||
JKArgumentList(),
|
||||
JKTypeArgumentList()
|
||||
).withNonCodeElementsFrom(from)
|
||||
).withFormattingFrom(from)
|
||||
is JKNewExpression ->
|
||||
JKCallExpressionImpl(
|
||||
symbolProvider.provideMethodSymbol(fqName),
|
||||
argumentsProvider(from::arguments.detached()),
|
||||
JKTypeArgumentList()
|
||||
).withNonCodeElementsFrom(from)
|
||||
).withFormattingFrom(from)
|
||||
else -> error("Bad conversion")
|
||||
}
|
||||
}
|
||||
@@ -118,11 +118,11 @@ class BuiltinMembersConversion(context: NewJ2kConverterContext) : RecursiveAppli
|
||||
is JKCallExpression ->
|
||||
JKFieldAccessExpression(
|
||||
symbolProvider.provideFieldSymbol(fqName)
|
||||
).withNonCodeElementsFrom(from)
|
||||
).withFormattingFrom(from)
|
||||
is JKFieldAccessExpression ->
|
||||
JKFieldAccessExpression(
|
||||
symbolProvider.provideFieldSymbol(fqName)
|
||||
).withNonCodeElementsFrom(from)
|
||||
).withFormattingFrom(from)
|
||||
else -> error("Bad conversion")
|
||||
}
|
||||
}
|
||||
@@ -141,7 +141,7 @@ class BuiltinMembersConversion(context: NewJ2kConverterContext) : RecursiveAppli
|
||||
JKArgumentList(arguments.drop(1)),
|
||||
from::typeArgumentList.detached()
|
||||
)
|
||||
).withNonCodeElementsFrom(from)
|
||||
).withFormattingFrom(from)
|
||||
}
|
||||
else -> error("Bad conversion")
|
||||
}
|
||||
@@ -354,7 +354,7 @@ class BuiltinMembersConversion(context: NewJ2kConverterContext) : RecursiveAppli
|
||||
JKArgumentList(
|
||||
detachedArguments.drop(1) + JKNamedArgument(
|
||||
detachedArguments.first()::value.detached().also {
|
||||
it.clearNonCodeElements()
|
||||
it.clearFormatting()
|
||||
},
|
||||
JKNameIdentifier("ignoreCase")
|
||||
)
|
||||
|
||||
@@ -53,7 +53,7 @@ class ClassToObjectPromotionConversion(context: NewJ2kConverterContext) : Recurs
|
||||
element.otherModifierElements,
|
||||
element.visibilityElement,
|
||||
JKModalityModifierElement(Modality.FINAL)
|
||||
).withNonCodeElementsFrom(element)
|
||||
).withFormattingFrom(element)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,7 +29,7 @@ class ConstructorConversion(context: NewJ2kConverterContext) : RecursiveApplicab
|
||||
element.modalityElement
|
||||
).also {
|
||||
symbolProvider.transferSymbol(it, element)
|
||||
}.withNonCodeElementsFrom(element)
|
||||
}.withFormattingFrom(element)
|
||||
}
|
||||
|
||||
private fun lookupDelegationCall(block: JKBlock): JKDelegationConstructorCall? {
|
||||
|
||||
@@ -108,7 +108,7 @@ class DefaultArgumentsConversion(context: NewJ2kConverterContext) : RecursiveApp
|
||||
parameter.initializer = remapParameterSymbol(defaultValue) as JKExpression
|
||||
}
|
||||
element.declarations -= method
|
||||
calledMethod.withNonCodeElementsFrom(method)
|
||||
calledMethod.withFormattingFrom(method)
|
||||
}
|
||||
if (element.parentOfType<JKClass>()?.classKind != JKClass.ClassKind.ANNOTATION) {
|
||||
for (method in element.declarations) {
|
||||
|
||||
@@ -27,8 +27,8 @@ class ForConversion(context: NewJ2kConverterContext) : RecursiveApplicableConver
|
||||
override fun applyToElement(element: JKTreeElement): JKTreeElement {
|
||||
if (element !is JKJavaForLoopStatement) return recurse(element)
|
||||
|
||||
convertToForeach(element)?.also { return recurse(it.withNonCodeElementsFrom(element)) }
|
||||
convertToWhile(element)?.also { return recurse(it.withNonCodeElementsFrom(element)) }
|
||||
convertToForeach(element)?.also { return recurse(it.withFormattingFrom(element)) }
|
||||
convertToWhile(element)?.also { return recurse(it.withFormattingFrom(element)) }
|
||||
|
||||
return recurse(element)
|
||||
}
|
||||
|
||||
@@ -23,25 +23,25 @@ class JavaModifiersConversion(context: NewJ2kConverterContext) : RecursiveApplic
|
||||
element.elementByModifier(OtherModifier.VOLATILE)?.also { modifierElement ->
|
||||
element.otherModifierElements -= modifierElement
|
||||
element.annotationList.annotations +=
|
||||
jvmAnnotation("Volatile", symbolProvider).withNonCodeElementsFrom(modifierElement)
|
||||
jvmAnnotation("Volatile", symbolProvider).withFormattingFrom(modifierElement)
|
||||
}
|
||||
|
||||
element.elementByModifier(OtherModifier.TRANSIENT)?.also { modifierElement ->
|
||||
element.otherModifierElements -= modifierElement
|
||||
element.annotationList.annotations +=
|
||||
jvmAnnotation("Transient", symbolProvider).withNonCodeElementsFrom(modifierElement)
|
||||
jvmAnnotation("Transient", symbolProvider).withFormattingFrom(modifierElement)
|
||||
}
|
||||
|
||||
element.elementByModifier(OtherModifier.STRICTFP)?.also { modifierElement ->
|
||||
element.otherModifierElements -= modifierElement
|
||||
element.annotationList.annotations +=
|
||||
jvmAnnotation("Strictfp", symbolProvider).withNonCodeElementsFrom(modifierElement)
|
||||
jvmAnnotation("Strictfp", symbolProvider).withFormattingFrom(modifierElement)
|
||||
}
|
||||
|
||||
element.elementByModifier(OtherModifier.SYNCHRONIZED)?.also { modifierElement ->
|
||||
element.otherModifierElements -= modifierElement
|
||||
element.annotationList.annotations +=
|
||||
jvmAnnotation("Synchronized", symbolProvider).withNonCodeElementsFrom(modifierElement)
|
||||
jvmAnnotation("Synchronized", symbolProvider).withFormattingFrom(modifierElement)
|
||||
}
|
||||
|
||||
element.elementByModifier(OtherModifier.NATIVE)?.also { modifierElement ->
|
||||
|
||||
@@ -14,8 +14,8 @@ class NonCodeElementsConversion(context: NewJ2kConverterContext) : RecursiveAppl
|
||||
override fun applyToElement(element: JKTreeElement): JKTreeElement {
|
||||
when (element) {
|
||||
is JKClass -> {
|
||||
element.name.rightNonCodeElements += element.inheritance.leftNonCodeElements
|
||||
element.inheritance.leftNonCodeElements.clear()
|
||||
element.name.leadingComments += element.inheritance.trailingComments
|
||||
element.inheritance.trailingComments.clear()
|
||||
}
|
||||
}
|
||||
return recurse(element)
|
||||
|
||||
+4
-4
@@ -32,10 +32,10 @@ class PrimaryConstructorDetectConversion(context: NewJ2kConverterContext) : Recu
|
||||
primaryConstructorCandidate.invalidate()
|
||||
if (primaryConstructorCandidate.block.statements.isNotEmpty()) {
|
||||
val initDeclaration = JKKtInitDeclaration(primaryConstructorCandidate.block)
|
||||
.withNonCodeElementsFrom(primaryConstructorCandidate)
|
||||
primaryConstructorCandidate.clearNonCodeElements()
|
||||
.withFormattingFrom(primaryConstructorCandidate)
|
||||
primaryConstructorCandidate.clearFormatting()
|
||||
primaryConstructorCandidate.forEachModifier { modifierElement ->
|
||||
modifierElement.clearNonCodeElements()
|
||||
modifierElement.clearFormatting()
|
||||
}
|
||||
element.classBody.declarations =
|
||||
element.classBody.declarations.replace(primaryConstructorCandidate, initDeclaration)
|
||||
@@ -52,7 +52,7 @@ class PrimaryConstructorDetectConversion(context: NewJ2kConverterContext) : Recu
|
||||
primaryConstructorCandidate.otherModifierElements,
|
||||
primaryConstructorCandidate.visibilityElement,
|
||||
primaryConstructorCandidate.modalityElement
|
||||
).withNonCodeElementsFrom(primaryConstructorCandidate)
|
||||
).withFormattingFrom(primaryConstructorCandidate)
|
||||
|
||||
symbolProvider.transferSymbol(primaryConstructor, primaryConstructorCandidate)
|
||||
|
||||
|
||||
+1
-1
@@ -24,7 +24,7 @@ class RemoveRedundantQualifiersForCallsConversion(context: NewJ2kConverterContex
|
||||
}
|
||||
if (needRemoveQualifier) {
|
||||
element.invalidate()
|
||||
return recurse(element.selector.withNonCodeElementsFrom(element.receiver).withNonCodeElementsFrom(element))
|
||||
return recurse(element.selector.withFormattingFrom(element.receiver).withFormattingFrom(element))
|
||||
}
|
||||
return recurse(element)
|
||||
}
|
||||
|
||||
@@ -34,5 +34,5 @@ class StaticInitDeclarationConversion(context : NewJ2kConverterContext) : Recurs
|
||||
}
|
||||
|
||||
private fun JKJavaStaticInitDeclaration.toKtInitDeclaration() =
|
||||
JKKtInitDeclaration(::block.detached()).withNonCodeElementsFrom(this)
|
||||
JKKtInitDeclaration(::block.detached()).withFormattingFrom(this)
|
||||
}
|
||||
@@ -48,7 +48,7 @@ class SwitchStatementConversion(context: NewJ2kConverterContext) : RecursiveAppl
|
||||
statement.block.statements
|
||||
.takeWhile { !isSwitchBreak(it) }
|
||||
.map { it.copyTreeAndDetach() }
|
||||
).withNonCodeElementsFrom(statement)
|
||||
).withFormattingFrom(statement)
|
||||
isSwitchBreak(statement) -> null
|
||||
else -> statement.copyTreeAndDetach()
|
||||
}
|
||||
|
||||
@@ -24,7 +24,7 @@ class SynchronizedStatementConversion(context: NewJ2kConverterContext) : Recursi
|
||||
element.lockExpression,
|
||||
lambdaBody
|
||||
)
|
||||
).withNonCodeElementsFrom(element)
|
||||
).withFormattingFrom(element)
|
||||
return recurse(JKExpressionStatement(synchronizedCall))
|
||||
}
|
||||
|
||||
|
||||
@@ -29,7 +29,7 @@ class TryStatementConversion(context: NewJ2kConverterContext) : RecursiveApplica
|
||||
tryStatement::finallyBlock.detached(),
|
||||
tryStatement.catchSections.flatMap(::convertCatchSection)
|
||||
)
|
||||
).withNonCodeElementsFrom(tryStatement)
|
||||
).withFormattingFrom(tryStatement)
|
||||
|
||||
private fun convertTryStatementWithResources(tryStatement: JKJavaTryStatement): JKStatement {
|
||||
val body =
|
||||
@@ -44,7 +44,7 @@ class TryStatementConversion(context: NewJ2kConverterContext) : RecursiveApplica
|
||||
tryStatement::finallyBlock.detached(),
|
||||
tryStatement.catchSections.flatMap(::convertCatchSection)
|
||||
)
|
||||
).withNonCodeElementsFrom(tryStatement)
|
||||
).withFormattingFrom(tryStatement)
|
||||
} else body
|
||||
}
|
||||
|
||||
@@ -77,7 +77,7 @@ class TryStatementConversion(context: NewJ2kConverterContext) : RecursiveApplica
|
||||
JKKtTryCatchSection(
|
||||
parameter,
|
||||
javaCatchSection.block.copyTreeAndDetach()
|
||||
).withNonCodeElementsFrom(javaCatchSection)
|
||||
).withFormattingFrom(javaCatchSection)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -37,7 +37,7 @@ class TypeMappingConversion(
|
||||
element::typeArgumentList.detached().fixTypeArguments(newClassSymbol),
|
||||
element::classBody.detached(),
|
||||
element.isAnonymousClass
|
||||
).withNonCodeElementsFrom(element)
|
||||
).withFormattingFrom(element)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -45,7 +45,7 @@ fun canKeepEqEq(left: PsiExpression, right: PsiExpression?): Boolean {
|
||||
|
||||
internal fun PsiMember.visibility(
|
||||
referenceSearcher: ReferenceSearcher,
|
||||
assignNonCodeElements: ((JKNonCodeElementsListOwner, PsiElement) -> Unit)?
|
||||
assignNonCodeElements: ((JKFormattingOwner, PsiElement) -> Unit)?
|
||||
): JKVisibilityModifierElement =
|
||||
modifierList?.children?.mapNotNull { child ->
|
||||
if (child !is PsiKeyword) return@mapNotNull null
|
||||
@@ -64,7 +64,7 @@ internal fun PsiMember.visibility(
|
||||
}?.firstOrNull() ?: JKVisibilityModifierElement(Visibility.INTERNAL)
|
||||
|
||||
|
||||
fun PsiMember.modality(assignNonCodeElements: ((JKNonCodeElementsListOwner, PsiElement) -> Unit)?) =
|
||||
fun PsiMember.modality(assignNonCodeElements: ((JKFormattingOwner, PsiElement) -> Unit)?) =
|
||||
modifierList?.children?.mapNotNull { child ->
|
||||
if (child !is PsiKeyword) return@mapNotNull null
|
||||
when (child.text) {
|
||||
|
||||
@@ -46,9 +46,11 @@ private class JKListChild<T : JKElement>(val value: Int) : ReadWriteProperty<JKT
|
||||
}
|
||||
|
||||
|
||||
abstract class JKTreeElement : JKElement, JKNonCodeElementsListOwner, Cloneable {
|
||||
override val leftNonCodeElements: MutableList<JKNonCodeElement> = mutableListOf()
|
||||
override val rightNonCodeElements: MutableList<JKNonCodeElement> = mutableListOf()
|
||||
abstract class JKTreeElement : JKElement, JKFormattingOwner, Cloneable {
|
||||
override val trailingComments: MutableList<JKComment> = mutableListOf()
|
||||
override val leadingComments: MutableList<JKComment> = mutableListOf()
|
||||
override var hasTrailingLineBreak = false
|
||||
override var hasLeadingLineBreak = false
|
||||
|
||||
override var parent: JKElement? = null
|
||||
|
||||
@@ -149,11 +151,11 @@ interface PsiOwner {
|
||||
|
||||
class PsiOwnerImpl(override var psi: PsiElement? = null) : PsiOwner
|
||||
|
||||
interface JKTypeArgumentListOwner : JKNonCodeElementsListOwner {
|
||||
interface JKTypeArgumentListOwner : JKFormattingOwner {
|
||||
var typeArgumentList: JKTypeArgumentList
|
||||
}
|
||||
|
||||
interface JKTypeParameterListOwner : JKNonCodeElementsListOwner {
|
||||
interface JKTypeParameterListOwner : JKFormattingOwner {
|
||||
var typeParameterList: JKTypeParameterList
|
||||
}
|
||||
|
||||
|
||||
@@ -40,8 +40,10 @@ abstract class JKBlock : JKTreeElement() {
|
||||
|
||||
|
||||
object JKBodyStub : JKBlock() {
|
||||
override val leftNonCodeElements: MutableList<JKNonCodeElement> = mutableListOf()
|
||||
override val rightNonCodeElements: MutableList<JKNonCodeElement> = mutableListOf()
|
||||
override val trailingComments: MutableList<JKComment> = mutableListOf()
|
||||
override val leadingComments: MutableList<JKComment> = mutableListOf()
|
||||
override var hasTrailingLineBreak = false
|
||||
override var hasLeadingLineBreak = false
|
||||
|
||||
override fun copy(): JKTreeElement = this
|
||||
|
||||
@@ -172,7 +174,7 @@ class JKNameIdentifier(val value: String) : JKTreeElement() {
|
||||
}
|
||||
|
||||
|
||||
interface JKAnnotationListOwner : JKNonCodeElementsListOwner {
|
||||
interface JKAnnotationListOwner : JKFormattingOwner {
|
||||
var annotationList: JKAnnotationList
|
||||
}
|
||||
|
||||
|
||||
@@ -26,8 +26,8 @@ class JKBinaryExpression(
|
||||
right: JKExpression,
|
||||
override var operator: JKOperator
|
||||
) : JKOperatorExpression() {
|
||||
var right by child(right)
|
||||
var left by child(left)
|
||||
var right by child(right)
|
||||
|
||||
override fun accept(visitor: JKVisitor) = visitor.visitBinaryExpression(this)
|
||||
}
|
||||
|
||||
@@ -0,0 +1,58 @@
|
||||
/*
|
||||
* Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* 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.nj2k.tree
|
||||
|
||||
import org.jetbrains.kotlin.utils.SmartList
|
||||
|
||||
|
||||
class JKComment(val text: String) {
|
||||
val isSingleline
|
||||
get() = text.startsWith("//")
|
||||
}
|
||||
|
||||
class JKTokenElementImpl(override val text: String) : JKTokenElement {
|
||||
override val trailingComments: MutableList<JKComment> = SmartList()
|
||||
override val leadingComments: MutableList<JKComment> = SmartList()
|
||||
override var hasTrailingLineBreak: Boolean = false
|
||||
override var hasLeadingLineBreak: Boolean = false
|
||||
}
|
||||
|
||||
interface JKFormattingOwner {
|
||||
val trailingComments: MutableList<JKComment>
|
||||
val leadingComments: MutableList<JKComment>
|
||||
var hasTrailingLineBreak: Boolean
|
||||
var hasLeadingLineBreak: Boolean
|
||||
}
|
||||
|
||||
inline fun <reified T : JKFormattingOwner> T.withFormattingFrom(other: JKFormattingOwner): T = also {
|
||||
trailingComments += other.trailingComments
|
||||
leadingComments += other.leadingComments
|
||||
hasTrailingLineBreak = other.hasTrailingLineBreak
|
||||
hasLeadingLineBreak = other.hasLeadingLineBreak
|
||||
}
|
||||
|
||||
inline fun <reified T : JKFormattingOwner> List<T>.withFormattingFrom(other: JKFormattingOwner): List<T> = also {
|
||||
if (isNotEmpty()) {
|
||||
it.first().trailingComments += other.trailingComments
|
||||
it.first().hasTrailingLineBreak = other.hasTrailingLineBreak
|
||||
it.last().leadingComments += other.leadingComments
|
||||
it.last().hasLeadingLineBreak = other.hasLeadingLineBreak
|
||||
}
|
||||
}
|
||||
|
||||
fun JKFormattingOwner.clearFormatting() {
|
||||
trailingComments.clear()
|
||||
leadingComments.clear()
|
||||
hasTrailingLineBreak = false
|
||||
hasLeadingLineBreak = false
|
||||
}
|
||||
|
||||
interface JKTokenElement : JKFormattingOwner {
|
||||
val text: String
|
||||
}
|
||||
|
||||
fun JKFormattingOwner.containsNewLine(): Boolean =
|
||||
hasTrailingLineBreak || hasLeadingLineBreak
|
||||
@@ -98,7 +98,7 @@ enum class Mutability(override val text: String) : Modifier {
|
||||
UNKNOWN("var")
|
||||
}
|
||||
|
||||
interface JKModifiersListOwner : JKNonCodeElementsListOwner
|
||||
interface JKModifiersListOwner : JKFormattingOwner
|
||||
|
||||
fun JKOtherModifiersOwner.elementByModifier(modifier: OtherModifier): JKOtherModifierElement? =
|
||||
otherModifierElements.firstOrNull { it.otherModifier == modifier }
|
||||
|
||||
@@ -1,56 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* 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.nj2k.tree
|
||||
|
||||
import org.jetbrains.kotlin.utils.SmartList
|
||||
|
||||
|
||||
interface JKNonCodeElement {
|
||||
val text: String
|
||||
}
|
||||
|
||||
class JKSpaceElement(override val text: String) : JKNonCodeElement
|
||||
class JKCommentElement(override val text: String) : JKNonCodeElement
|
||||
|
||||
class JKTokenElementImpl(override val text: String) : JKTokenElement {
|
||||
override val leftNonCodeElements: MutableList<JKNonCodeElement> = SmartList()
|
||||
override val rightNonCodeElements: MutableList<JKNonCodeElement> = SmartList()
|
||||
}
|
||||
|
||||
interface JKNonCodeElementsListOwner {
|
||||
val leftNonCodeElements: MutableList<JKNonCodeElement>
|
||||
val rightNonCodeElements: MutableList<JKNonCodeElement>
|
||||
}
|
||||
|
||||
fun JKNonCodeElementsListOwner.takeNonCodeElementsFrom(other: JKNonCodeElementsListOwner) {
|
||||
leftNonCodeElements += other.leftNonCodeElements
|
||||
rightNonCodeElements += other.rightNonCodeElements
|
||||
}
|
||||
|
||||
inline fun <reified T : JKNonCodeElementsListOwner> T.withNonCodeElementsFrom(other: JKNonCodeElementsListOwner): T =
|
||||
also { it.takeNonCodeElementsFrom(other) }
|
||||
|
||||
inline fun <reified T : JKNonCodeElementsListOwner> List<T>.withNonCodeElementsFrom(other: JKNonCodeElementsListOwner): List<T> =
|
||||
also {
|
||||
if (isNotEmpty()) {
|
||||
it.first().leftNonCodeElements += other.leftNonCodeElements
|
||||
it.last().rightNonCodeElements += other.rightNonCodeElements
|
||||
}
|
||||
}
|
||||
|
||||
fun JKNonCodeElementsListOwner.clearNonCodeElements() {
|
||||
leftNonCodeElements.clear()
|
||||
rightNonCodeElements.clear()
|
||||
}
|
||||
|
||||
interface JKTokenElement : JKNonCodeElementsListOwner {
|
||||
val text: String
|
||||
}
|
||||
|
||||
fun JKNonCodeElementsListOwner.containsNewLine(): Boolean =
|
||||
(leftNonCodeElements + rightNonCodeElements).any {
|
||||
it is JKSpaceElement && '\n' in it.text
|
||||
}
|
||||
@@ -102,7 +102,7 @@ fun <R : JKTreeElement> applyRecursive(
|
||||
|
||||
|
||||
inline fun <reified T : JKTreeElement> T.copyTree(): T =
|
||||
copy().withNonCodeElementsFrom(this) as T
|
||||
copy().withFormattingFrom(this) as T
|
||||
|
||||
inline fun <reified T : JKTreeElement> T.copyTreeAndDetach(): T =
|
||||
copyTree().also {
|
||||
|
||||
@@ -3,8 +3,8 @@ package org.jetbrains.kotlin.nj2k.tree.visitors
|
||||
import org.jetbrains.kotlin.nj2k.tree.*
|
||||
|
||||
abstract class JKVisitorWithCommentsPrinting : JKVisitor() {
|
||||
abstract fun printLeftNonCodeElements(element: JKNonCodeElementsListOwner)
|
||||
abstract fun printRightNonCodeElements(element: JKNonCodeElementsListOwner)
|
||||
abstract fun printLeftNonCodeElements(element: JKFormattingOwner)
|
||||
abstract fun printRightNonCodeElements(element: JKFormattingOwner)
|
||||
|
||||
override fun visitTreeElement(treeElement: JKTreeElement) {
|
||||
printLeftNonCodeElements(treeElement)
|
||||
|
||||
@@ -1 +1 @@
|
||||
/*pre*/ 5 /*operand '5'*/ shl /*left shift*/ 16 /*operand '16'*/ or (/*or*/ 1 /*operand '1'*/ shr /*right shift*/ 8 /*operand '8'*/) or /*or*/ 0 /*operand '0'*/ /*post comment*/
|
||||
/*pre*/5 /*operand '5'*/ shl /*left shift*/16 /*operand '16'*/ or ( /*or*/1 /*operand '1'*/ shr /*right shift*/8 /*operand '8'*/) or /*or*/0 /*operand '0'*/ /*post comment*/
|
||||
+9
-11
@@ -3,19 +3,17 @@
|
||||
package foo
|
||||
|
||||
internal class A {
|
||||
fun /* nothing to return */ foo(/* no parameters at all */) {
|
||||
// let declare a variable
|
||||
// with 2 comments before
|
||||
|
||||
val /*int*/ a /* it's a */ = 2 /* it's 2 */ + 1 /* it's 1 */ // variable a declared
|
||||
fun /* nothing to return */foo( /* no parameters at all */) { // let declare a variable
|
||||
// with 2 comments before
|
||||
val /*int*/a /* it's a */ = 2 /* it's 2 */ + 1 /* it's 1 */ // variable a declared
|
||||
} // end of foo
|
||||
|
||||
fun /* we return int*/ foo( /*int*/ p: Int/* parameter p */): Int { /* body is empty */
|
||||
fun /* we return int*/foo( /*int*/p: Int /* parameter p */): Int { /* body is empty */
|
||||
}
|
||||
|
||||
private/*it's private*/ val field = 0
|
||||
/*it's public*/ fun foo(s: String?): Char {}
|
||||
protected/*it's protected*/ fun foo(c: Char) {}
|
||||
private /*it's private*/ val field = 0
|
||||
/*it's public*/ fun foo(s: String?): Char {}
|
||||
protected /*it's protected*/ fun foo(c: Char) {}
|
||||
/**
|
||||
* Method description.
|
||||
* Multi-line method description.
|
||||
@@ -28,7 +26,7 @@ internal class A {
|
||||
*/
|
||||
fun foo(param1: String?, param2: String?, param3: String?) {}
|
||||
|
||||
companion object {
|
||||
/*it's public*/ /*and static*/ /*and final*/ const val C = 1
|
||||
companion object { /*it's public*/ /*and static*/ /*and final*/
|
||||
const val C = 1
|
||||
}
|
||||
}
|
||||
@@ -5,10 +5,7 @@ internal class A // end of primary constructor body
|
||||
// this is a secondary constructor 2
|
||||
constructor(s: String) : this(s.length) {} // end of secondary constructor 2 body
|
||||
|
||||
|
||||
// this is a primary constructor
|
||||
|
||||
|
||||
// this is a primary constructor
|
||||
// this is a secondary constructor 1
|
||||
|
||||
|
||||
@@ -18,7 +15,7 @@ internal class A // end of primary constructor body
|
||||
internal class B // end of constructor body
|
||||
(private val x: Int) {
|
||||
fun foo() {}
|
||||
// this constructor will disappear
|
||||
// this constructor will disappear
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -3,4 +3,5 @@ internal class C(// field p1
|
||||
/**
|
||||
* Field myP2
|
||||
*/
|
||||
private val myP2: Int, /* Field p3 */var p3: Int)
|
||||
private val myP2: Int, /* Field p3 */
|
||||
var p3: Int)
|
||||
+3
-3
@@ -1,14 +1,12 @@
|
||||
internal class A(// comment for field2 setter
|
||||
// comment for field2 getter
|
||||
var field2 // comment for field2
|
||||
: Int) {
|
||||
: Int) { // Comment for field1
|
||||
/**
|
||||
* Comment for field1 setter
|
||||
*/
|
||||
// Comment for field1 getter
|
||||
// Comment for field1
|
||||
var field1 = 0
|
||||
|
||||
// comment for field3 setter
|
||||
// comment for field3 getter
|
||||
// comment before field3
|
||||
@@ -22,4 +20,6 @@ internal class A(// comment for field2 setter
|
||||
var property: Int
|
||||
get() = 1
|
||||
set(value) {}
|
||||
|
||||
|
||||
}
|
||||
@@ -1,3 +1,2 @@
|
||||
class Nya /*comment before*/
|
||||
/* comment after*/ // and after again
|
||||
(/*1*//*3*/ /*4*/private val i: Int)
|
||||
class Nya /*comment before*/ /* comment after*/ // and after again
|
||||
(/*1*/ /*3*/ /*4*/private val i: Int)
|
||||
@@ -1,29 +1,16 @@
|
||||
internal class F {
|
||||
|
||||
//c1
|
||||
|
||||
/*c2*///c3
|
||||
|
||||
|
||||
internal class F { //c3
|
||||
//c4
|
||||
|
||||
fun f2() {}
|
||||
|
||||
fun f3() {}
|
||||
fun f4() {}
|
||||
|
||||
//c5
|
||||
|
||||
companion object {
|
||||
|
||||
companion object { //c1
|
||||
/*c2*/
|
||||
fun f1() {}
|
||||
|
||||
|
||||
var i = 0
|
||||
|
||||
|
||||
fun f5() {}
|
||||
|
||||
//c6
|
||||
//c5
|
||||
fun f5() {} //c6
|
||||
}
|
||||
|
||||
}
|
||||
+5
-13
@@ -1,17 +1,12 @@
|
||||
// This is an end-of-line comment
|
||||
|
||||
/*
|
||||
This is a block comment
|
||||
*/
|
||||
|
||||
|
||||
/*doc comment of class*/
|
||||
//one line comment of class
|
||||
//another one
|
||||
/*another doc*/
|
||||
internal class C {
|
||||
// This is a class comment
|
||||
|
||||
internal class C { // This is a class comment
|
||||
|
||||
/**
|
||||
* This is a field doc comment.
|
||||
@@ -21,8 +16,7 @@ internal class C {
|
||||
/**
|
||||
* This is a function doc comment.
|
||||
*/
|
||||
fun foo() {
|
||||
/* This is a function comment */
|
||||
fun foo() { /* This is a function comment */
|
||||
}
|
||||
|
||||
//simple one line comment for function
|
||||
@@ -43,8 +37,6 @@ internal class C {
|
||||
/** of
|
||||
*/
|
||||
//
|
||||
|
||||
|
||||
/**
|
||||
* different
|
||||
*/
|
||||
@@ -55,13 +47,13 @@ internal class C {
|
||||
/** of
|
||||
*/
|
||||
//
|
||||
|
||||
|
||||
/**
|
||||
* different
|
||||
*/
|
||||
//comments
|
||||
var l = 0
|
||||
/*two*/ /*comments*//*line*/
|
||||
/*two*/
|
||||
/*comments*/
|
||||
/*line*/
|
||||
var z = 0
|
||||
}
|
||||
+3
-6
@@ -5,10 +5,6 @@ class TestMutltipleCtorsWithJavadoc
|
||||
*/(private val x: String?) {
|
||||
private var y: String? = null
|
||||
|
||||
// ---
|
||||
// Constructors
|
||||
//
|
||||
|
||||
/**
|
||||
* Javadoc for 2nd ctor
|
||||
* @param x
|
||||
@@ -17,6 +13,7 @@ class TestMutltipleCtorsWithJavadoc
|
||||
constructor(x: String?, y: String?) : this(x) {
|
||||
this.y = y
|
||||
}
|
||||
|
||||
|
||||
// ---
|
||||
// Constructors
|
||||
//
|
||||
}
|
||||
+4
-4
@@ -3,12 +3,12 @@ import java.util.stream.Collectors
|
||||
|
||||
internal class Test {
|
||||
fun main(lst: List<Int>) {
|
||||
val newLst = /*before list*/ lst/*after list*/.stream/*before stream*/()/* after stream*/
|
||||
val newLst = /*before list*/lst /*after list*/.stream /*before stream*/() /* after stream*/
|
||||
.filter { x: Int -> x > 10 }
|
||||
.map { x: Int -> x + 2 }/*some comment*/.distinct/*another comment*/()/* one more comment */.sorted()/*another one comment*/
|
||||
.map { x: Int -> x + 2 } /*some comment*/.distinct /*another comment*/() /* one more comment */.sorted() /*another one comment*/
|
||||
.sorted(Comparator.naturalOrder())
|
||||
.peek { x: Int? -> println(x) }.limit(1)
|
||||
.skip(42)/*skipped*/
|
||||
/*collecting one*/.collect/*collecting two */(Collectors.toList())/* cool */
|
||||
.skip(42) /*skipped*/ /*collecting one*/
|
||||
.collect /*collecting two */(Collectors.toList()) /* cool */
|
||||
}
|
||||
}
|
||||
@@ -87,7 +87,6 @@ class A {
|
||||
int limit = 5;
|
||||
useSplit(s.split("\\s+", limit));
|
||||
*/
|
||||
*/
|
||||
s.trim();
|
||||
s.concat(" another");
|
||||
|
||||
|
||||
@@ -8,8 +8,6 @@ internal class A {
|
||||
fun constructors() {
|
||||
String()
|
||||
// TODO: new String("original");
|
||||
|
||||
|
||||
String(charArrayOf('a', 'b', 'c'))
|
||||
String(charArrayOf('b', 'd'), 1, 1)
|
||||
String(intArrayOf(32, 65, 127), 0, 3)
|
||||
@@ -88,8 +86,7 @@ internal class A {
|
||||
useSplit(s.split("\\s+", 2));
|
||||
int limit = 5;
|
||||
useSplit(s.split("\\s+", limit));
|
||||
*/
|
||||
s.trim { it <= ' ' }
|
||||
*/s.trim { it <= ' ' }
|
||||
"$s another"
|
||||
s.toByteArray()
|
||||
s.toByteArray(Charset.forName("utf-8"))
|
||||
@@ -121,8 +118,7 @@ internal class A {
|
||||
}
|
||||
|
||||
fun unsupportedMethods() {
|
||||
val s = "test string"
|
||||
/* TODO:
|
||||
val s = "test string" /* TODO:
|
||||
s.indexOf(32);
|
||||
s.indexOf(32, 2);
|
||||
s.lastIndexOf(32);
|
||||
|
||||
Reference in New Issue
Block a user