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