New J2K: do not recalculate types for binary & unary expressions and rewrite assignment expressions conversion
#KT-33679 fixed
This commit is contained in:
@@ -31,14 +31,8 @@ object ConversionsRunner {
|
|||||||
FunctionAsAnonymousObjectToLambdaConversion(context),
|
FunctionAsAnonymousObjectToLambdaConversion(context),
|
||||||
ReturnStatementInLambdaExpressionConversion(context),
|
ReturnStatementInLambdaExpressionConversion(context),
|
||||||
BoxedTypeOperationsConversion(context),
|
BoxedTypeOperationsConversion(context),
|
||||||
AssignmentAsExpressionToAlsoConversion(context),
|
AnyWithStringConcatenationConversion(context),
|
||||||
AssignmentStatementValCreationConversion(context),
|
AssignmentExpressionUnfoldingConversion(context),
|
||||||
AssignmentStatementOperatorConversion(context),
|
|
||||||
AssignmentStatementSimplifyValConversion(context),
|
|
||||||
AssignmentStatementSimplifyAlsoConversion(context),
|
|
||||||
AssignmentStatementSplitAlsoConversion(context),
|
|
||||||
PolyadicExpressionConversion(context),
|
|
||||||
OperatorExpressionConversion(context),
|
|
||||||
AddParenthesisForLineBreaksInBinaryExpression(context),
|
AddParenthesisForLineBreaksInBinaryExpression(context),
|
||||||
ThrowStatementConversion(context),
|
ThrowStatementConversion(context),
|
||||||
ArrayInitializerConversion(context),
|
ArrayInitializerConversion(context),
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ import com.intellij.psi.JavaTokenType.SUPER_KEYWORD
|
|||||||
import com.intellij.psi.JavaTokenType.THIS_KEYWORD
|
import com.intellij.psi.JavaTokenType.THIS_KEYWORD
|
||||||
import com.intellij.psi.impl.source.tree.ChildRole
|
import com.intellij.psi.impl.source.tree.ChildRole
|
||||||
import com.intellij.psi.impl.source.tree.CompositeElement
|
import com.intellij.psi.impl.source.tree.CompositeElement
|
||||||
|
import com.intellij.psi.impl.source.tree.ElementType
|
||||||
import com.intellij.psi.impl.source.tree.java.PsiClassObjectAccessExpressionImpl
|
import com.intellij.psi.impl.source.tree.java.PsiClassObjectAccessExpressionImpl
|
||||||
import com.intellij.psi.impl.source.tree.java.PsiLabeledStatementImpl
|
import com.intellij.psi.impl.source.tree.java.PsiLabeledStatementImpl
|
||||||
import com.intellij.psi.impl.source.tree.java.PsiLiteralExpressionImpl
|
import com.intellij.psi.impl.source.tree.java.PsiLiteralExpressionImpl
|
||||||
@@ -138,14 +139,17 @@ class JavaToJKTreeBuilder constructor(
|
|||||||
is PsiConditionalExpression -> JKIfElseExpressionImpl(
|
is PsiConditionalExpression -> JKIfElseExpressionImpl(
|
||||||
condition.toJK(), thenExpression.toJK(), elseExpression.toJK()
|
condition.toJK(), thenExpression.toJK(), elseExpression.toJK()
|
||||||
)
|
)
|
||||||
is PsiPolyadicExpression -> JKJavaPolyadicExpressionImpl(
|
is PsiPolyadicExpression -> {
|
||||||
operands.map { it.toJK() },
|
val token = JKOperatorToken.fromElementType(operationTokenType)
|
||||||
Array(operands.lastIndex) { index ->
|
val type = type?.toJK() ?: typeFactory.types.nullableAny
|
||||||
getTokenBeforeOperand(operands[index + 1])
|
val jkOperands = operands.map { it.toJK().parenthesizeIfBinaryExpression() }
|
||||||
}.map {
|
jkOperands.reduce { acc, operand ->
|
||||||
it?.tokenType?.toJK() ?: throwCanNotConvertError()
|
JKBinaryExpressionImpl(acc, operand, JKKtOperatorImpl(token, type))
|
||||||
|
}.let { folded ->
|
||||||
|
if (jkOperands.any { it.containsNewLine() }) folded.parenthesize()
|
||||||
|
else folded
|
||||||
}
|
}
|
||||||
)
|
}
|
||||||
is PsiArrayInitializerExpression -> toJK()
|
is PsiArrayInitializerExpression -> toJK()
|
||||||
is PsiLambdaExpression -> toJK()
|
is PsiLambdaExpression -> toJK()
|
||||||
is PsiClassObjectAccessExpressionImpl -> toJK()
|
is PsiClassObjectAccessExpressionImpl -> toJK()
|
||||||
@@ -180,9 +184,9 @@ class JavaToJKTreeBuilder constructor(
|
|||||||
|
|
||||||
fun PsiAssignmentExpression.toJK(): JKJavaAssignmentExpression {
|
fun PsiAssignmentExpression.toJK(): JKJavaAssignmentExpression {
|
||||||
return JKJavaAssignmentExpressionImpl(
|
return JKJavaAssignmentExpressionImpl(
|
||||||
lExpression.toJK() as JKAssignableExpression,
|
lExpression.toJK(),
|
||||||
rExpression.toJK(),
|
rExpression.toJK(),
|
||||||
operationSign.tokenType.toJK()
|
createOperator(operationSign.tokenType, type)
|
||||||
).also {
|
).also {
|
||||||
it.assignNonCodeElements(this)
|
it.assignNonCodeElements(this)
|
||||||
}
|
}
|
||||||
@@ -192,16 +196,22 @@ class JavaToJKTreeBuilder constructor(
|
|||||||
val token = when (operationSign.tokenType) {
|
val token = when (operationSign.tokenType) {
|
||||||
JavaTokenType.EQEQ, JavaTokenType.NE ->
|
JavaTokenType.EQEQ, JavaTokenType.NE ->
|
||||||
when {
|
when {
|
||||||
canKeepEqEq(lOperand, rOperand) -> operationSign.tokenType
|
canKeepEqEq(lOperand, rOperand) -> JKOperatorToken.fromElementType(operationSign.tokenType)
|
||||||
operationSign.tokenType == JavaTokenType.EQEQ -> KtTokens.EQEQEQ
|
operationSign.tokenType == JavaTokenType.EQEQ -> JKOperatorToken.fromElementType(KtTokens.EQEQEQ)
|
||||||
else -> KtTokens.EXCLEQEQEQ
|
else -> JKOperatorToken.fromElementType(KtTokens.EXCLEQEQEQ)
|
||||||
}
|
}
|
||||||
else -> operationSign.tokenType
|
else -> JKOperatorToken.fromElementType(operationSign.tokenType)
|
||||||
|
}
|
||||||
|
return JKBinaryExpressionImpl(
|
||||||
|
lOperand.toJK(),
|
||||||
|
rOperand.toJK(),
|
||||||
|
JKKtOperatorImpl(
|
||||||
|
token,
|
||||||
|
type?.toJK() ?: typeFactory.types.nullableAny
|
||||||
|
)
|
||||||
|
).also {
|
||||||
|
it.assignNonCodeElements(this)
|
||||||
}
|
}
|
||||||
return JKBinaryExpressionImpl(lOperand.toJK(), rOperand.toJK(), token.toJK())
|
|
||||||
.also {
|
|
||||||
it.assignNonCodeElements(this)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun PsiLiteralExpression.toJK(): JKLiteralExpression {
|
fun PsiLiteralExpression.toJK(): JKLiteralExpression {
|
||||||
@@ -223,19 +233,23 @@ class JavaToJKTreeBuilder constructor(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun IElementType.toJK(): JKOperator = JKJavaOperatorImpl.tokenToOperator[this] ?: error("Unsupported token-type: $this")
|
private fun createOperator(elementType: IElementType, type: PsiType?) =
|
||||||
|
JKKtOperatorImpl(
|
||||||
|
JKOperatorToken.fromElementType(elementType),
|
||||||
|
type?.toJK() ?: typeFactory.types.nullableAny
|
||||||
|
)
|
||||||
|
|
||||||
fun PsiPrefixExpression.toJK(): JKExpression {
|
fun PsiPrefixExpression.toJK(): JKExpression = when (operationSign.tokenType) {
|
||||||
return JKPrefixExpressionImpl(operand.toJK(), operationSign.tokenType.toJK()).also {
|
JavaTokenType.TILDE -> operand.toJK().callOn(symbolProvider.provideMethodSymbol("kotlin.Int.inv"))
|
||||||
it.assignNonCodeElements(this)
|
else -> JKPrefixExpressionImpl(operand.toJK(), createOperator(operationSign.tokenType, type))
|
||||||
}
|
}.also {
|
||||||
|
it.assignNonCodeElements(this)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun PsiPostfixExpression.toJK(): JKExpression {
|
fun PsiPostfixExpression.toJK(): JKExpression =
|
||||||
return JKPostfixExpressionImpl(operand.toJK(), operationSign.tokenType.toJK()).also {
|
JKPostfixExpressionImpl(operand.toJK(), createOperator(operationSign.tokenType, type)).also {
|
||||||
it.assignNonCodeElements(this)
|
it.assignNonCodeElements(this)
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
fun PsiLambdaExpression.toJK(): JKExpression {
|
fun PsiLambdaExpression.toJK(): JKExpression {
|
||||||
return JKLambdaExpressionImpl(
|
return JKLambdaExpressionImpl(
|
||||||
@@ -326,7 +340,7 @@ class JavaToJKTreeBuilder constructor(
|
|||||||
propertyAccessExpression
|
propertyAccessExpression
|
||||||
)
|
)
|
||||||
else propertyAccessExpression
|
else propertyAccessExpression
|
||||||
} else propertyAccessExpression.qualified(qualifier) as JKAssignableExpression
|
} else propertyAccessExpression.qualified(qualifier) as JKExpression
|
||||||
|
|
||||||
when (if (isExtension) parameterCount - 1 else parameterCount) {
|
when (if (isExtension) parameterCount - 1 else parameterCount) {
|
||||||
0 /* getter */ ->
|
0 /* getter */ ->
|
||||||
@@ -337,7 +351,7 @@ class JavaToJKTreeBuilder constructor(
|
|||||||
JKJavaAssignmentExpressionImpl(
|
JKJavaAssignmentExpressionImpl(
|
||||||
propertyAccess,
|
propertyAccess,
|
||||||
argument,
|
argument,
|
||||||
JKJavaOperatorImpl.tokenToOperator[JavaTokenType.EQ]!!
|
createOperator(JavaTokenType.EQ, type)//TODO correct type
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
else -> throwCanNotConvertError("expected getter or setter call")
|
else -> throwCanNotConvertError("expected getter or setter call")
|
||||||
@@ -513,14 +527,15 @@ class JavaToJKTreeBuilder constructor(
|
|||||||
val jkExpressions = expressions.map { it.toJK() }
|
val jkExpressions = expressions.map { it.toJK() }
|
||||||
return ((parent as? PsiCall)?.resolveMethod()
|
return ((parent as? PsiCall)?.resolveMethod()
|
||||||
?.let { method ->
|
?.let { method ->
|
||||||
|
val lastExpressionType = expressions.lastOrNull()?.type
|
||||||
if (jkExpressions.size == method.parameterList.parameters.size
|
if (jkExpressions.size == method.parameterList.parameters.size
|
||||||
&& method.parameterList.parameters.getOrNull(jkExpressions.lastIndex)?.isVarArgs == true
|
&& method.parameterList.parameters.getOrNull(jkExpressions.lastIndex)?.isVarArgs == true
|
||||||
&& expressions.lastOrNull()?.type is PsiArrayType
|
&& lastExpressionType is PsiArrayType
|
||||||
) {
|
) {
|
||||||
val staredExpression =
|
val staredExpression =
|
||||||
JKPrefixExpressionImpl(
|
JKPrefixExpressionImpl(
|
||||||
jkExpressions.last(),
|
jkExpressions.last(),
|
||||||
JKKtSpreadOperator
|
JKKtSpreadOperator(lastExpressionType.toJK())
|
||||||
).withNonCodeElementsFrom(jkExpressions.last())
|
).withNonCodeElementsFrom(jkExpressions.last())
|
||||||
jkExpressions.dropLast(1) + staredExpression
|
jkExpressions.dropLast(1) + staredExpression
|
||||||
} else jkExpressions
|
} else jkExpressions
|
||||||
|
|||||||
@@ -659,6 +659,9 @@ class NewCodeBuilder(context: NewJ2kConverterContext) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun visitKtItExpressionRaw(ktItExpression: JKKtItExpression) {
|
||||||
|
printer.printWithNoIndent("it")
|
||||||
|
}
|
||||||
|
|
||||||
override fun visitClassBodyRaw(classBody: JKClassBody) {
|
override fun visitClassBodyRaw(classBody: JKClassBody) {
|
||||||
val declarationsToPrint = classBody.declarations.filterNot { it is JKKtPrimaryConstructor }
|
val declarationsToPrint = classBody.declarations.filterNot { it is JKKtPrimaryConstructor }
|
||||||
@@ -818,11 +821,27 @@ class NewCodeBuilder(context: NewJ2kConverterContext) {
|
|||||||
override fun visitKtAssignmentStatementRaw(ktAssignmentStatement: JKKtAssignmentStatement) {
|
override fun visitKtAssignmentStatementRaw(ktAssignmentStatement: JKKtAssignmentStatement) {
|
||||||
ktAssignmentStatement.field.accept(this)
|
ktAssignmentStatement.field.accept(this)
|
||||||
printer.printWithNoIndent(" ")
|
printer.printWithNoIndent(" ")
|
||||||
printer.printWithNoIndent(ktAssignmentStatement.operator.token.text)
|
printer.printWithNoIndent(ktAssignmentStatement.token.text)
|
||||||
printer.printWithNoIndent(" ")
|
printer.printWithNoIndent(" ")
|
||||||
ktAssignmentStatement.expression.accept(this)
|
ktAssignmentStatement.expression.accept(this)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun visitAssignmentChainAlsoLinkRaw(assignmentChainAlsoLink: JKAssignmentChainAlsoLink) {
|
||||||
|
assignmentChainAlsoLink.receiver.accept(this)
|
||||||
|
printer.printWithNoIndent(".also({ ")
|
||||||
|
assignmentChainAlsoLink.assignmentStatement.accept(this)
|
||||||
|
printer.printWithNoIndent(" })")
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun visitAssignmentChainLetLinkRaw(assignmentChainLetLink: JKAssignmentChainLetLink) {
|
||||||
|
assignmentChainLetLink.receiver.accept(this)
|
||||||
|
printer.printWithNoIndent(".let({ ")
|
||||||
|
assignmentChainLetLink.assignmentStatement.accept(this)
|
||||||
|
printer.printWithNoIndent("; ")
|
||||||
|
assignmentChainLetLink.field.accept(this)
|
||||||
|
printer.printWithNoIndent(" })")
|
||||||
|
}
|
||||||
|
|
||||||
override fun visitKtWhenStatementRaw(ktWhenStatement: JKKtWhenStatement) {
|
override fun visitKtWhenStatementRaw(ktWhenStatement: JKKtWhenStatement) {
|
||||||
printer.printWithNoIndent("when(")
|
printer.printWithNoIndent("when(")
|
||||||
ktWhenStatement.expression.accept(this)
|
ktWhenStatement.expression.accept(this)
|
||||||
|
|||||||
-42
@@ -1,42 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2010-2018 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.conversions
|
|
||||||
|
|
||||||
import org.jetbrains.kotlin.nj2k.NewJ2kConverterContext
|
|
||||||
import org.jetbrains.kotlin.nj2k.tree.JKBlockStatement
|
|
||||||
import org.jetbrains.kotlin.nj2k.tree.JKJavaAssignmentExpression
|
|
||||||
import org.jetbrains.kotlin.nj2k.tree.JKKtAssignmentStatement
|
|
||||||
import org.jetbrains.kotlin.nj2k.tree.JKTreeElement
|
|
||||||
import org.jetbrains.kotlin.nj2k.tree.impl.*
|
|
||||||
import org.jetbrains.kotlin.utils.addToStdlib.cast
|
|
||||||
|
|
||||||
class AssignmentAsExpressionToAlsoConversion(context: NewJ2kConverterContext) : RecursiveApplicableConversionBase(context) {
|
|
||||||
override fun applyToElement(element: JKTreeElement): JKTreeElement {
|
|
||||||
if (element !is JKJavaAssignmentExpression) return recurse(element)
|
|
||||||
element.invalidate()
|
|
||||||
|
|
||||||
val alsoExpression = JKKtAlsoCallExpressionImpl(
|
|
||||||
JKBlockStatementImpl(
|
|
||||||
JKBlockImpl(listOf(JKKtAssignmentStatementImpl(element.field, JKStubExpressionImpl(), element.operator)))
|
|
||||||
), symbolProvider.provideMethodSymbol("kotlin.also")
|
|
||||||
).also {
|
|
||||||
it.statement.cast<JKBlockStatement>().block.statements.first().cast<JKKtAssignmentStatement>().expression =
|
|
||||||
JKFieldAccessExpressionImpl(
|
|
||||||
symbolProvider.provideUniverseSymbol(
|
|
||||||
JKParameterImpl(JKTypeElementImpl(JKContextType), JKNameIdentifierImpl("it"))
|
|
||||||
)
|
|
||||||
)//TODO introduce symbol
|
|
||||||
}
|
|
||||||
|
|
||||||
return recurse(
|
|
||||||
JKQualifiedExpressionImpl(
|
|
||||||
element.expression,
|
|
||||||
JKKtQualifierImpl.DOT,
|
|
||||||
alsoExpression
|
|
||||||
)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
+178
@@ -0,0 +1,178 @@
|
|||||||
|
/*
|
||||||
|
* 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.conversions
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.nj2k.NewJ2kConverterContext
|
||||||
|
import org.jetbrains.kotlin.nj2k.copyTreeAndDetach
|
||||||
|
import org.jetbrains.kotlin.nj2k.tree.*
|
||||||
|
import org.jetbrains.kotlin.nj2k.tree.impl.*
|
||||||
|
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
||||||
|
|
||||||
|
class AssignmentExpressionUnfoldingConversion(context: NewJ2kConverterContext) : RecursiveApplicableConversionBase(context) {
|
||||||
|
override fun applyToElement(element: JKTreeElement): JKTreeElement {
|
||||||
|
val unfolded = when (element) {
|
||||||
|
is JKBlock -> element.convertAssignments()
|
||||||
|
is JKExpressionStatement -> element.convertAssignments()
|
||||||
|
is JKJavaAssignmentExpression -> element.convertAssignments()
|
||||||
|
else -> null
|
||||||
|
} ?: return recurse(element)
|
||||||
|
|
||||||
|
return recurse(unfolded)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private fun JKBlock.convertAssignments(): JKBlock? {
|
||||||
|
val hasAssignments = statements.any { it.containsAssignment() }
|
||||||
|
if (!hasAssignments) return null
|
||||||
|
|
||||||
|
val newStatements = mutableListOf<JKStatement>()
|
||||||
|
for (statement in statements) {
|
||||||
|
when {
|
||||||
|
statement is JKExpressionStatement && statement.expression is JKJavaAssignmentExpression -> {
|
||||||
|
val assignment = statement.expression as JKJavaAssignmentExpression
|
||||||
|
newStatements += assignment
|
||||||
|
.unfoldToStatementsList(assignmentTarget = null)
|
||||||
|
.withNonCodeElementsFrom(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)
|
||||||
|
}
|
||||||
|
else -> {
|
||||||
|
newStatements += statement
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
statements = newStatements
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun JKExpressionStatement.convertAssignments(): JKStatement? {
|
||||||
|
val assignment = expression as? JKJavaAssignmentExpression ?: return null
|
||||||
|
return when {
|
||||||
|
canBeConvertedToBlock() && assignment.expression is JKJavaAssignmentExpression ->
|
||||||
|
JKBlockStatementImpl(JKBlockImpl(assignment.unfoldToStatementsList(assignmentTarget = null)))
|
||||||
|
else -> createKtAssignmentStatement(
|
||||||
|
assignment::field.detached(),
|
||||||
|
assignment::expression.detached(),
|
||||||
|
assignment.operator
|
||||||
|
)
|
||||||
|
}.withNonCodeElementsFrom(this)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun JKExpressionStatement.canBeConvertedToBlock() = when (val parent = parent) {
|
||||||
|
is JKLoopStatement -> parent.body == this
|
||||||
|
is JKIfElseStatement -> parent.thenBranch == this || parent.elseBranch == this
|
||||||
|
is JKIfStatement -> parent.thenBranch == this
|
||||||
|
is JKJavaSwitchCase -> true
|
||||||
|
else -> false
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun JKJavaAssignmentExpression.convertAssignments() =
|
||||||
|
unfoldToExpressionsChain().withNonCodeElementsFrom(this)
|
||||||
|
|
||||||
|
private fun JKDeclarationStatement.containsAssignment() =
|
||||||
|
declaredStatements.singleOrNull()?.safeAs<JKVariable>()?.initializer is JKJavaAssignmentExpression
|
||||||
|
|
||||||
|
private fun JKStatement.containsAssignment() = when (this) {
|
||||||
|
is JKExpressionStatement -> expression is JKJavaAssignmentExpression
|
||||||
|
is JKDeclarationStatement -> containsAssignment()
|
||||||
|
else -> false
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun JKJavaAssignmentExpression.unfold() = generateSequence(this) { assignment ->
|
||||||
|
assignment.expression as? JKJavaAssignmentExpression
|
||||||
|
}.toList().asReversed()
|
||||||
|
|
||||||
|
private fun JKJavaAssignmentExpression.unfoldToExpressionsChain(): JKExpression {
|
||||||
|
val links = unfold()
|
||||||
|
val first = links.first()
|
||||||
|
return links.subList(1, links.size)
|
||||||
|
.fold(first.toExpressionChainLink(first::expression.detached())) { state, assignment ->
|
||||||
|
assignment.toExpressionChainLink(state)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun JKJavaAssignmentExpression.unfoldToStatementsList(assignmentTarget: JKVariable?): List<JKStatement> {
|
||||||
|
val links = unfold()
|
||||||
|
val first = links.first()
|
||||||
|
val statements = links.subList(1, links.size)
|
||||||
|
.foldIndexed(listOf(first.toDeclarationChainLink(first::expression.detached()))) { index, list, assignment ->
|
||||||
|
list + assignment.toDeclarationChainLink(links[index].field.copyTreeAndDetach())
|
||||||
|
}
|
||||||
|
return when (assignmentTarget) {
|
||||||
|
null -> statements
|
||||||
|
else -> {
|
||||||
|
assignmentTarget.initializer = statements.last().field.copyTreeAndDetach()
|
||||||
|
statements + JKDeclarationStatementImpl(listOf(assignmentTarget))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun JKJavaAssignmentExpression.toExpressionChainLink(receiver: JKExpression): JKExpression {
|
||||||
|
val assignment = createKtAssignmentStatement(
|
||||||
|
this::field.detached(),
|
||||||
|
JKKtItExpressionImpl(operator.returnType),
|
||||||
|
operator
|
||||||
|
).withNonCodeElementsFrom(this)
|
||||||
|
return when {
|
||||||
|
operator.isSimpleToken() ->
|
||||||
|
JKAssignmentChainAlsoLinkImpl(receiver, assignment, field.copyTreeAndDetach())
|
||||||
|
else ->
|
||||||
|
JKAssignmentChainLetLinkImpl(receiver, assignment, field.copyTreeAndDetach())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun JKJavaAssignmentExpression.toDeclarationChainLink(expression: JKExpression) =
|
||||||
|
createKtAssignmentStatement(this::field.detached(), expression, this.operator)
|
||||||
|
.withNonCodeElementsFrom(this)
|
||||||
|
|
||||||
|
private fun createKtAssignmentStatement(
|
||||||
|
field: JKExpression,
|
||||||
|
expression: JKExpression,
|
||||||
|
operator: JKOperator
|
||||||
|
) = when {
|
||||||
|
operator.isOnlyJavaToken() ->
|
||||||
|
JKKtAssignmentStatementImpl(
|
||||||
|
field,
|
||||||
|
JKBinaryExpressionImpl(
|
||||||
|
field.copyTreeAndDetach(),
|
||||||
|
expression,
|
||||||
|
JKKtOperatorImpl(
|
||||||
|
onlyJavaAssignTokensToKotlinOnes[operator.token]!!,
|
||||||
|
operator.returnType
|
||||||
|
)
|
||||||
|
),
|
||||||
|
JKOperatorToken.EQ
|
||||||
|
)
|
||||||
|
else -> JKKtAssignmentStatementImpl(field, expression, operator.token)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun JKOperator.isSimpleToken() = when {
|
||||||
|
isOnlyJavaToken() -> false
|
||||||
|
token == JKOperatorToken.PLUSEQ
|
||||||
|
|| token == JKOperatorToken.MINUSEQ
|
||||||
|
|| token == JKOperatorToken.MULTEQ
|
||||||
|
|| token == JKOperatorToken.DIVEQ -> false
|
||||||
|
else -> true
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun JKOperator.isOnlyJavaToken() = token in onlyJavaAssignTokensToKotlinOnes
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
private val onlyJavaAssignTokensToKotlinOnes = mapOf(
|
||||||
|
JKOperatorToken.ANDEQ to JKOperatorToken.AND,
|
||||||
|
JKOperatorToken.OREQ to JKOperatorToken.OR,
|
||||||
|
JKOperatorToken.XOREQ to JKOperatorToken.XOR,
|
||||||
|
JKOperatorToken.LTLTEQ to JKOperatorToken.SHL,
|
||||||
|
JKOperatorToken.GTGTEQ to JKOperatorToken.SHR,
|
||||||
|
JKOperatorToken.GTGTGTEQ to JKOperatorToken.USHR
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
-45
@@ -1,45 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2010-2018 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.conversions
|
|
||||||
|
|
||||||
import com.intellij.psi.JavaTokenType
|
|
||||||
import org.jetbrains.kotlin.nj2k.NewJ2kConverterContext
|
|
||||||
import org.jetbrains.kotlin.nj2k.copyTreeAndDetach
|
|
||||||
import org.jetbrains.kotlin.nj2k.tree.JKKtAssignmentStatement
|
|
||||||
import org.jetbrains.kotlin.nj2k.tree.JKTreeElement
|
|
||||||
import org.jetbrains.kotlin.nj2k.tree.impl.JKBinaryExpressionImpl
|
|
||||||
import org.jetbrains.kotlin.nj2k.tree.impl.JKJavaOperatorImpl
|
|
||||||
import org.jetbrains.kotlin.nj2k.tree.impl.JKJavaOperatorToken
|
|
||||||
|
|
||||||
class AssignmentStatementOperatorConversion(context : NewJ2kConverterContext) : RecursiveApplicableConversionBase(context) {
|
|
||||||
override fun applyToElement(element: JKTreeElement): JKTreeElement {
|
|
||||||
if (element !is JKKtAssignmentStatement) return recurse(element)
|
|
||||||
val operator = element.operator as? JKJavaOperatorImpl ?: return recurse(element)
|
|
||||||
operator.token.correspondingBinaryOperation()
|
|
||||||
?.apply {
|
|
||||||
val expression = element.expression.copyTreeAndDetach()
|
|
||||||
element.expression =
|
|
||||||
JKBinaryExpressionImpl(
|
|
||||||
element.field.copyTreeAndDetach(),
|
|
||||||
expression,
|
|
||||||
this
|
|
||||||
)
|
|
||||||
element.operator = JKJavaOperatorImpl.tokenToOperator[JavaTokenType.EQ]!!
|
|
||||||
}
|
|
||||||
return recurse(element)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun JKJavaOperatorToken.correspondingBinaryOperation() =
|
|
||||||
when (psiToken) {
|
|
||||||
JavaTokenType.OREQ -> JavaTokenType.OR
|
|
||||||
JavaTokenType.ANDEQ -> JavaTokenType.AND
|
|
||||||
JavaTokenType.LTLTEQ -> JavaTokenType.LTLT
|
|
||||||
JavaTokenType.GTGTEQ -> JavaTokenType.GTGT
|
|
||||||
JavaTokenType.GTGTGTEQ -> JavaTokenType.GTGTGT
|
|
||||||
JavaTokenType.XOREQ -> JavaTokenType.XOR
|
|
||||||
else -> null
|
|
||||||
}?.let { JKJavaOperatorImpl.tokenToOperator[it] }
|
|
||||||
}
|
|
||||||
-30
@@ -1,30 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2010-2018 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.conversions
|
|
||||||
|
|
||||||
import org.jetbrains.kotlin.nj2k.NewJ2kConverterContext
|
|
||||||
import org.jetbrains.kotlin.nj2k.tree.*
|
|
||||||
import org.jetbrains.kotlin.nj2k.tree.impl.JKExpressionStatementImpl
|
|
||||||
import org.jetbrains.kotlin.nj2k.tree.impl.JKStubExpressionImpl
|
|
||||||
|
|
||||||
class AssignmentStatementSimplifyAlsoConversion(context : NewJ2kConverterContext) : RecursiveApplicableConversionBase(context) {
|
|
||||||
override fun applyToElement(element: JKTreeElement): JKTreeElement {
|
|
||||||
if (element !is JKExpressionStatement) return recurse(element)
|
|
||||||
val qualifiedExpression = element.expression as? JKQualifiedExpression ?: return recurse(element)
|
|
||||||
val alsoCall = qualifiedExpression.selector as? JKKtAlsoCallExpression ?: return recurse(element)
|
|
||||||
return recurse(if (alsoCall.statement !is JKBlockStatement) alsoCall.statement.also {
|
|
||||||
alsoCall.statement = JKExpressionStatementImpl(JKStubExpressionImpl())
|
|
||||||
inlineVal(it, qualifiedExpression.receiver.also { qualifiedExpression.receiver = JKStubExpressionImpl() })
|
|
||||||
} else element)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun inlineVal(statement: JKStatement, expression: JKExpression) {
|
|
||||||
if (statement is JKKtAssignmentStatement) {
|
|
||||||
(statement.expression as? JKBinaryExpression)?.right = expression
|
|
||||||
if (statement.expression !is JKBinaryExpression) statement.expression = expression
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
-46
@@ -1,46 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2010-2018 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.conversions
|
|
||||||
|
|
||||||
import org.jetbrains.kotlin.nj2k.NewJ2kConverterContext
|
|
||||||
import org.jetbrains.kotlin.nj2k.tree.*
|
|
||||||
import org.jetbrains.kotlin.nj2k.tree.impl.JKStubExpressionImpl
|
|
||||||
|
|
||||||
class AssignmentStatementSimplifyValConversion(context : NewJ2kConverterContext) : RecursiveApplicableConversionBase(context) {
|
|
||||||
override fun applyToElement(element: JKTreeElement): JKTreeElement {
|
|
||||||
if (element !is JKKtAlsoCallExpression) return recurse(element)
|
|
||||||
val codeBlock = (element.statement as? JKBlockStatement)?.block ?: return recurse(element)
|
|
||||||
if (codeBlock.statements.size > 1) {
|
|
||||||
val assignment = codeBlock.statements[1] as? JKKtAssignmentStatement ?: return recurse(element)
|
|
||||||
val declaration = codeBlock.statements[0] as? JKDeclarationStatement ?: return recurse(element)
|
|
||||||
when (declaration.declaredStatements.size) {
|
|
||||||
1 -> if (assignment.expression !is JKBinaryExpression) {
|
|
||||||
codeBlock.statements = listOf(assignment)
|
|
||||||
(assignment.field as JKQualifiedExpression).receiver = declaration.extractInitializerByIndex(0)
|
|
||||||
} else {
|
|
||||||
|
|
||||||
}
|
|
||||||
2 -> if (assignment.expression !is JKBinaryExpression) {
|
|
||||||
codeBlock.statements = listOf(assignment)
|
|
||||||
val arrayAccess = assignment.field as JKArrayAccessExpression
|
|
||||||
arrayAccess.expression = declaration.extractInitializerByIndex(0)
|
|
||||||
arrayAccess.indexExpression = declaration.extractInitializerByIndex(1)
|
|
||||||
} else {
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (codeBlock.statements.size == 1) {
|
|
||||||
element.statement = codeBlock.statements.first().also { codeBlock.statements = emptyList() }
|
|
||||||
}
|
|
||||||
return recurse(element)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun JKDeclarationStatement.extractInitializerByIndex(i: Int): JKExpression {
|
|
||||||
val variable = (declaredStatements[i] as JKLocalVariable)
|
|
||||||
return variable.initializer.also { variable.initializer = JKStubExpressionImpl() }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
-79
@@ -1,79 +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.conversions
|
|
||||||
|
|
||||||
import org.jetbrains.kotlin.nj2k.NewJ2kConverterContext
|
|
||||||
import org.jetbrains.kotlin.nj2k.copyTreeAndDetach
|
|
||||||
import org.jetbrains.kotlin.nj2k.tree.*
|
|
||||||
import org.jetbrains.kotlin.nj2k.tree.impl.*
|
|
||||||
|
|
||||||
class AssignmentStatementSplitAlsoConversion(context: NewJ2kConverterContext) : RecursiveApplicableConversionBase(context) {
|
|
||||||
override fun applyToElement(element: JKTreeElement): JKTreeElement {
|
|
||||||
return recurse(
|
|
||||||
when (element) {
|
|
||||||
is JKBlock -> element.splitAssignmentExpressions()
|
|
||||||
is JKStatement ->
|
|
||||||
element.splitAsAssignmentExpressions()?.let { JKBlockStatementImpl(JKBlockImpl(it)) }
|
|
||||||
else -> null
|
|
||||||
} ?: element)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun JKBlock.splitAssignmentExpressions(): JKBlock? {
|
|
||||||
val newStatements = statements.map { it.splitAsAssignmentExpressions() ?: listOf(it) }
|
|
||||||
return if (newStatements.any { it.size > 1 }) {
|
|
||||||
JKBlockImpl(
|
|
||||||
newStatements.flatMap { statements ->
|
|
||||||
if (statements.size == 1) statements.map { it.detached(this) }
|
|
||||||
else statements
|
|
||||||
}
|
|
||||||
).withNonCodeElementsFrom(this)
|
|
||||||
} else null
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun JKStatement.splitAsAssignmentExpressions(): List<JKStatement>? {
|
|
||||||
val expression = when (this) {
|
|
||||||
is JKKtAssignmentStatement -> expression
|
|
||||||
is JKDeclarationStatementImpl -> (declaredStatements.singleOrNull() as? JKLocalVariableImpl)?.initializer
|
|
||||||
else -> null
|
|
||||||
} ?: return null
|
|
||||||
|
|
||||||
val qualifiedExpression = expression as? JKQualifiedExpression ?: return null
|
|
||||||
val alsoCall = qualifiedExpression.selector as? JKKtAlsoCallExpression ?: return null
|
|
||||||
val innerAssignmentStatement = alsoCall.statement as? JKKtAssignmentStatement ?: return null
|
|
||||||
|
|
||||||
val secondAssignment = when (this) {
|
|
||||||
is JKKtAssignmentStatement ->
|
|
||||||
JKKtAssignmentStatementImpl(
|
|
||||||
::field.detached(),
|
|
||||||
innerAssignmentStatement.field.copyTreeAndDetach(),
|
|
||||||
operator
|
|
||||||
)
|
|
||||||
is JKDeclarationStatement -> {
|
|
||||||
val variable = declaredStatements.single() as JKLocalVariableImpl
|
|
||||||
JKDeclarationStatementImpl(
|
|
||||||
listOf(
|
|
||||||
JKLocalVariableImpl(
|
|
||||||
variable::type.detached(),
|
|
||||||
variable::name.detached(),
|
|
||||||
innerAssignmentStatement.field.copyTreeAndDetach(),
|
|
||||||
variable::mutabilityElement.detached()
|
|
||||||
).withNonCodeElementsFrom(variable)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
else -> error("expression should be either JKKtAssignmentStatement or JKDeclarationStatementImpl")
|
|
||||||
}
|
|
||||||
|
|
||||||
return listOf(
|
|
||||||
JKKtAssignmentStatementImpl(
|
|
||||||
innerAssignmentStatement::field.detached(),
|
|
||||||
qualifiedExpression::receiver.detached(),
|
|
||||||
innerAssignmentStatement.operator
|
|
||||||
),
|
|
||||||
secondAssignment.withNonCodeElementsFrom(this)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
-67
@@ -1,67 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2010-2018 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.conversions
|
|
||||||
|
|
||||||
import org.jetbrains.kotlin.nj2k.NewJ2kConverterContext
|
|
||||||
import org.jetbrains.kotlin.nj2k.tree.*
|
|
||||||
import org.jetbrains.kotlin.nj2k.tree.impl.*
|
|
||||||
|
|
||||||
class AssignmentStatementValCreationConversion(context: NewJ2kConverterContext) : RecursiveApplicableConversionBase(context) {
|
|
||||||
override fun applyToElement(element: JKTreeElement): JKTreeElement {
|
|
||||||
if (element !is JKKtAlsoCallExpression) return recurse(element)
|
|
||||||
val codeBlock = (element.statement as? JKBlockStatement)?.block ?: return recurse(element)
|
|
||||||
val assignableExpr = (codeBlock.statements.first() as? JKKtAssignmentStatement)?.field ?: return recurse(element)
|
|
||||||
when (assignableExpr) {
|
|
||||||
is JKArrayAccessExpression -> {
|
|
||||||
val ex1 = assignableExpr.expression
|
|
||||||
val ex2 = assignableExpr.indexExpression
|
|
||||||
assignableExpr.expression = JKStubExpressionImpl()
|
|
||||||
assignableExpr.indexExpression = JKStubExpressionImpl()
|
|
||||||
codeBlock.statements = listOf(
|
|
||||||
JKDeclarationStatementImpl(
|
|
||||||
listOf(
|
|
||||||
JKLocalVariableImpl(
|
|
||||||
JKTypeElementImpl(JKJavaVoidType/*TODO*/),
|
|
||||||
JKNameIdentifierImpl("arr"),
|
|
||||||
ex1,
|
|
||||||
JKMutabilityModifierElementImpl(Mutability.IMMUTABLE)
|
|
||||||
).also {
|
|
||||||
assignableExpr.expression = JKFieldAccessExpressionImpl(symbolProvider.provideUniverseSymbol(it))
|
|
||||||
}, JKLocalVariableImpl(
|
|
||||||
JKTypeElementImpl(JKJavaVoidType/*TODO*/),
|
|
||||||
JKNameIdentifierImpl("i"),
|
|
||||||
ex2,
|
|
||||||
JKMutabilityModifierElementImpl(Mutability.UNKNOWN)
|
|
||||||
).also {
|
|
||||||
assignableExpr.indexExpression =
|
|
||||||
JKFieldAccessExpressionImpl(symbolProvider.provideUniverseSymbol(it))
|
|
||||||
}
|
|
||||||
)
|
|
||||||
)
|
|
||||||
) + codeBlock.statements
|
|
||||||
}
|
|
||||||
is JKQualifiedExpression -> {
|
|
||||||
val ex = assignableExpr.receiver
|
|
||||||
assignableExpr.receiver = JKStubExpressionImpl()
|
|
||||||
codeBlock.statements = listOf(
|
|
||||||
JKDeclarationStatementImpl(
|
|
||||||
listOf(
|
|
||||||
JKLocalVariableImpl(
|
|
||||||
JKTypeElementImpl(JKJavaVoidType/*TODO*/),
|
|
||||||
JKNameIdentifierImpl("arg"),
|
|
||||||
ex,
|
|
||||||
JKMutabilityModifierElementImpl(Mutability.UNKNOWN)
|
|
||||||
).also {
|
|
||||||
assignableExpr.receiver = JKFieldAccessExpressionImpl(symbolProvider.provideUniverseSymbol(it))
|
|
||||||
}
|
|
||||||
)
|
|
||||||
)
|
|
||||||
) + codeBlock.statements
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return recurse(element)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -366,11 +366,10 @@ class BuiltinMembersConversion(context: NewJ2kConverterContext) : RecursiveAppli
|
|||||||
if (expression !is JKMethodCallExpression) error("Expression should be JKMethodCallExpression")
|
if (expression !is JKMethodCallExpression) error("Expression should be JKMethodCallExpression")
|
||||||
val firstArgument = expression.parent.cast<JKQualifiedExpression>()::receiver.detached()
|
val firstArgument = expression.parent.cast<JKQualifiedExpression>()::receiver.detached()
|
||||||
val secondArgument = expression.arguments.arguments.first()::value.detached()
|
val secondArgument = expression.arguments.arguments.first()::value.detached()
|
||||||
kotlinBinaryExpression(
|
JKBinaryExpressionImpl(
|
||||||
firstArgument,
|
firstArgument,
|
||||||
secondArgument,
|
secondArgument,
|
||||||
KtTokens.PLUS,
|
JKKtOperatorImpl(JKOperatorToken.PLUS, typeFactory.types.possiblyNullString)
|
||||||
typeFactory
|
|
||||||
)
|
)
|
||||||
} withReplaceType ReplaceType.REPLACE_WITH_QUALIFIER,
|
} withReplaceType ReplaceType.REPLACE_WITH_QUALIFIER,
|
||||||
|
|
||||||
@@ -390,27 +389,26 @@ class BuiltinMembersConversion(context: NewJ2kConverterContext) : RecursiveAppli
|
|||||||
else expression
|
else expression
|
||||||
.also {
|
.also {
|
||||||
arguments.arguments = arguments.arguments.dropLast(1)
|
arguments.arguments = arguments.arguments.dropLast(1)
|
||||||
}.let {
|
}.callOn(
|
||||||
it.callOn(
|
symbolProvider.provideMethodSymbol("kotlin.collections.dropLastWhile"),
|
||||||
symbolProvider.provideMethodSymbol("kotlin.collections.dropLastWhile"),
|
listOf(
|
||||||
JKLambdaExpressionImpl(
|
JKLambdaExpressionImpl(
|
||||||
JKFieldAccessExpressionImpl(
|
JKFieldAccessExpressionImpl(
|
||||||
JKUnresolvedField(//TODO replace with `it` parameter
|
JKUnresolvedField(//TODO replace with `it` parameter
|
||||||
"it",
|
"it",
|
||||||
typeFactory
|
typeFactory
|
||||||
)
|
)
|
||||||
).callOn(symbolProvider.provideMethodSymbol("kotlin.text.isEmpty"))
|
).callOn(symbolProvider.provideMethodSymbol("kotlin.text.isEmpty")).asStatement(),
|
||||||
.asStatement(),
|
|
||||||
emptyList()
|
emptyList()
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
}
|
)
|
||||||
}
|
}
|
||||||
else -> expression.also {
|
else -> expression.also {
|
||||||
val lastArgument = arguments.arguments.last().value.copyTreeAndDetach()
|
val lastArgument = arguments.arguments.last().value.copyTreeAndDetach()
|
||||||
.callOn(
|
.callOn(
|
||||||
symbolProvider.provideMethodSymbol("kotlin.ranges.coerceAtLeast"),
|
symbolProvider.provideMethodSymbol("kotlin.ranges.coerceAtLeast"),
|
||||||
JKKtLiteralExpressionImpl("0", JKLiteralExpression.LiteralType.INT)
|
listOf(JKKtLiteralExpressionImpl("0", JKLiteralExpression.LiteralType.INT))
|
||||||
)
|
)
|
||||||
arguments.arguments = arguments.arguments.dropLast(1) + JKArgumentImpl(lastArgument)
|
arguments.arguments = arguments.arguments.dropLast(1) + JKArgumentImpl(lastArgument)
|
||||||
}
|
}
|
||||||
@@ -428,7 +426,7 @@ class BuiltinMembersConversion(context: NewJ2kConverterContext) : RecursiveAppli
|
|||||||
JKArgumentListImpl(
|
JKArgumentListImpl(
|
||||||
JKLambdaExpressionImpl(
|
JKLambdaExpressionImpl(
|
||||||
JKExpressionStatementImpl(
|
JKExpressionStatementImpl(
|
||||||
kotlinBinaryExpression(
|
JKBinaryExpressionImpl(
|
||||||
JKFieldAccessExpressionImpl(
|
JKFieldAccessExpressionImpl(
|
||||||
JKUnresolvedField(//TODO replace with `it` parameter
|
JKUnresolvedField(//TODO replace with `it` parameter
|
||||||
"it",
|
"it",
|
||||||
@@ -436,8 +434,10 @@ class BuiltinMembersConversion(context: NewJ2kConverterContext) : RecursiveAppli
|
|||||||
)
|
)
|
||||||
),
|
),
|
||||||
JKKtLiteralExpressionImpl("' '", JKLiteralExpression.LiteralType.CHAR),
|
JKKtLiteralExpressionImpl("' '", JKLiteralExpression.LiteralType.CHAR),
|
||||||
KtTokens.LTEQ,
|
JKKtOperatorImpl(
|
||||||
typeFactory
|
JKOperatorToken.LTEQ,
|
||||||
|
typeFactory.types.boolean
|
||||||
|
)
|
||||||
)
|
)
|
||||||
),
|
),
|
||||||
emptyList()
|
emptyList()
|
||||||
@@ -469,7 +469,7 @@ class BuiltinMembersConversion(context: NewJ2kConverterContext) : RecursiveAppli
|
|||||||
).groupBy { it.from.fqName }
|
).groupBy { it.from.fqName }
|
||||||
|
|
||||||
|
|
||||||
private fun JKExpression.callOn(symbol: JKMethodSymbol, arguments: List<JKArgument> = emptyList()) =
|
private fun JKExpression. callOn(symbol: JKMethodSymbol, arguments: List<JKArgument> = emptyList()) =
|
||||||
JKQualifiedExpressionImpl(
|
JKQualifiedExpressionImpl(
|
||||||
this,
|
this,
|
||||||
JKKtQualifierImpl.DOT,
|
JKKtQualifierImpl.DOT,
|
||||||
@@ -480,12 +480,6 @@ class BuiltinMembersConversion(context: NewJ2kConverterContext) : RecursiveAppli
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
private fun JKExpression.callOn(symbol: JKMethodSymbol, vararg arguments: JKArgument) =
|
|
||||||
callOn(symbol, arguments.toList())
|
|
||||||
|
|
||||||
private fun JKExpression.callOn(symbol: JKMethodSymbol, vararg arguments: JKExpression) =
|
|
||||||
callOn(symbol, arguments.map { JKArgumentImpl(it) })
|
|
||||||
|
|
||||||
private fun isSystemOutCall(expression: JKExpression): Boolean =
|
private fun isSystemOutCall(expression: JKExpression): Boolean =
|
||||||
expression.parent
|
expression.parent
|
||||||
?.safeAs<JKQualifiedExpression>()
|
?.safeAs<JKQualifiedExpression>()
|
||||||
|
|||||||
@@ -182,11 +182,13 @@ class ForConversion(context: NewJ2kConverterContext) : RecursiveApplicableConver
|
|||||||
convertBound(bound, 0),
|
convertBound(bound, 0),
|
||||||
context
|
context
|
||||||
)
|
)
|
||||||
else -> kotlinBinaryExpression(
|
else -> JKBinaryExpressionImpl(
|
||||||
start,
|
start,
|
||||||
convertBound(bound, if (inclusiveComparison) 0 else -1),
|
convertBound(bound, if (inclusiveComparison) 0 else -1),
|
||||||
JKKtSingleValueOperatorToken(KtTokens.RANGE),
|
JKKtOperatorImpl(
|
||||||
typeFactory
|
JKOperatorToken.RANGE,
|
||||||
|
typeFactory.types.nullableAny //todo range type
|
||||||
|
)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -199,12 +201,14 @@ class ForConversion(context: NewJ2kConverterContext) : RecursiveApplicableConver
|
|||||||
return JKKtLiteralExpressionImpl((value + correction).toString(), bound.type)
|
return JKKtLiteralExpressionImpl((value + correction).toString(), bound.type)
|
||||||
}
|
}
|
||||||
|
|
||||||
val sign = if (correction > 0) KtTokens.PLUS else KtTokens.MINUS
|
val sign = if (correction > 0) JKOperatorToken.PLUS else JKOperatorToken.MINUS
|
||||||
return kotlinBinaryExpression(
|
return JKBinaryExpressionImpl(
|
||||||
bound,
|
bound,
|
||||||
JKKtLiteralExpressionImpl(abs(correction).toString(), JKLiteralExpression.LiteralType.INT),
|
JKKtLiteralExpressionImpl(abs(correction).toString(), JKLiteralExpression.LiteralType.INT),
|
||||||
JKKtSingleValueOperatorToken(sign),
|
JKKtOperatorImpl(
|
||||||
typeFactory
|
sign,
|
||||||
|
typeFactory.types.int
|
||||||
|
)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -5,77 +5,27 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.nj2k.conversions
|
package org.jetbrains.kotlin.nj2k.conversions
|
||||||
|
|
||||||
import com.intellij.psi.JavaTokenType
|
|
||||||
import org.jetbrains.kotlin.lexer.KtTokens
|
|
||||||
import org.jetbrains.kotlin.nj2k.NewJ2kConverterContext
|
import org.jetbrains.kotlin.nj2k.NewJ2kConverterContext
|
||||||
import org.jetbrains.kotlin.nj2k.kotlinBinaryExpression
|
import org.jetbrains.kotlin.nj2k.callOn
|
||||||
import org.jetbrains.kotlin.nj2k.kotlinPostfixExpression
|
|
||||||
import org.jetbrains.kotlin.nj2k.kotlinPrefixExpression
|
|
||||||
import org.jetbrains.kotlin.nj2k.tree.*
|
import org.jetbrains.kotlin.nj2k.tree.*
|
||||||
import org.jetbrains.kotlin.nj2k.tree.impl.*
|
import org.jetbrains.kotlin.nj2k.tree.impl.JKBinaryExpressionImpl
|
||||||
|
|
||||||
|
|
||||||
class OperatorExpressionConversion(context: NewJ2kConverterContext) : RecursiveApplicableConversionBase(context) {
|
class AnyWithStringConcatenationConversion(context: NewJ2kConverterContext) : RecursiveApplicableConversionBase(context) {
|
||||||
override fun applyToElement(element: JKTreeElement): JKTreeElement {
|
override fun applyToElement(element: JKTreeElement): JKTreeElement {
|
||||||
if (element !is JKOperatorExpression) return recurse(element)
|
if (element !is JKBinaryExpression) return recurse(element)
|
||||||
val operator = element.operator as? JKJavaOperatorImpl ?: return recurse(element)
|
if (element.operator.token == JKOperatorToken.PLUS
|
||||||
|
&& element.right.type(typeFactory)?.isStringType() == true
|
||||||
return when (element) {
|
&& element.left.type(typeFactory)?.isStringType() == false
|
||||||
is JKBinaryExpression -> {
|
|
||||||
val operatorToken = operator.token.toKtToken()
|
|
||||||
val left = applyToElement(element::left.detached()) as JKExpression
|
|
||||||
val right = applyToElement(element::right.detached()) as JKExpression
|
|
||||||
recurse(convertBinaryExpression(left, right, operatorToken).withNonCodeElementsFrom(element))
|
|
||||||
}
|
|
||||||
is JKPrefixExpression -> {
|
|
||||||
val operand = applyToElement(element::expression.detached()) as JKExpression
|
|
||||||
recurse(convertPrefixExpression(operand, operator))
|
|
||||||
}
|
|
||||||
is JKPostfixExpression -> {
|
|
||||||
val operatorToken = operator.token.toKtToken()
|
|
||||||
val operand = applyToElement(element::expression.detached()) as JKExpression
|
|
||||||
recurse(kotlinPostfixExpression(operand, operatorToken, typeFactory))
|
|
||||||
}
|
|
||||||
else -> TODO(element.javaClass.toString())
|
|
||||||
}.withNonCodeElementsFrom(element)
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private fun convertPrefixExpression(operand: JKExpression, javaOperator: JKJavaOperatorImpl) =
|
|
||||||
convertTildeExpression(operand, javaOperator)
|
|
||||||
?: kotlinPrefixExpression(operand, javaOperator.token.toKtToken(), typeFactory)
|
|
||||||
|
|
||||||
private fun convertTildeExpression(operand: JKExpression, javaOperator: JKJavaOperatorImpl): JKExpression? =
|
|
||||||
if (javaOperator.token.psiToken == JavaTokenType.TILDE) {
|
|
||||||
val invCall =
|
|
||||||
JKKtCallExpressionImpl(
|
|
||||||
symbolProvider.provideMethodSymbol("kotlin.Int.inv"),//TODO check if Long
|
|
||||||
JKArgumentListImpl()
|
|
||||||
)
|
|
||||||
JKQualifiedExpressionImpl(
|
|
||||||
JKParenthesizedExpressionImpl(operand),
|
|
||||||
JKKtQualifierImpl.DOT,
|
|
||||||
invCall
|
|
||||||
)
|
|
||||||
} else null
|
|
||||||
|
|
||||||
private fun convertBinaryExpression(left: JKExpression, right: JKExpression, token: JKKtOperatorToken): JKBinaryExpression =
|
|
||||||
convertStringImplicitConcatenation(left, right, token)
|
|
||||||
?: kotlinBinaryExpression(left, right, token, typeFactory)
|
|
||||||
|
|
||||||
|
|
||||||
private fun convertStringImplicitConcatenation(left: JKExpression, right: JKExpression, token: JKKtOperatorToken): JKBinaryExpression? =
|
|
||||||
if (token is JKKtSingleValueOperatorToken
|
|
||||||
&& token.psiToken == KtTokens.PLUS
|
|
||||||
&& right.type(typeFactory)?.isStringType() == true
|
|
||||||
&& left.type(typeFactory)?.isStringType() == false
|
|
||||||
) {
|
) {
|
||||||
val toStringCall =
|
return recurse(
|
||||||
JKKtCallExpressionImpl(
|
JKBinaryExpressionImpl(
|
||||||
symbolProvider.provideMethodSymbol("kotlin.Any.toString"),
|
element::left.detached().callOn(symbolProvider.provideMethodSymbol("kotlin.Any.toString")),
|
||||||
JKArgumentListImpl()
|
element::right.detached(),
|
||||||
|
element.operator
|
||||||
)
|
)
|
||||||
val qualifiedCall = JKQualifiedExpressionImpl(left, JKKtQualifierImpl.DOT, toStringCall)
|
)
|
||||||
kotlinBinaryExpression(qualifiedCall, right, KtTokens.PLUS, typeFactory)
|
}
|
||||||
} else null
|
return recurse(element)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -1,39 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2010-2018 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.conversions
|
|
||||||
|
|
||||||
import org.jetbrains.kotlin.nj2k.NewJ2kConverterContext
|
|
||||||
import org.jetbrains.kotlin.nj2k.parenthesizeIfBinaryExpression
|
|
||||||
import org.jetbrains.kotlin.nj2k.tree.*
|
|
||||||
import org.jetbrains.kotlin.nj2k.tree.impl.JKBinaryExpressionImpl
|
|
||||||
import org.jetbrains.kotlin.nj2k.tree.impl.JKParenthesizedExpressionImpl
|
|
||||||
|
|
||||||
|
|
||||||
class PolyadicExpressionConversion(context : NewJ2kConverterContext) : RecursiveApplicableConversionBase(context) {
|
|
||||||
override fun applyToElement(element: JKTreeElement): JKTreeElement {
|
|
||||||
if (element !is JKJavaPolyadicExpression) return recurse(element)
|
|
||||||
val needParenthesis = element.operands.any { it.containsNewLine() }
|
|
||||||
val parenthesisedOperands = element::operands.detached().map { it.parenthesizeIfBinaryExpression() }
|
|
||||||
val polyadic = convertPolyadic(parenthesisedOperands, element.tokens)
|
|
||||||
|
|
||||||
return recurse(
|
|
||||||
if (needParenthesis) JKParenthesizedExpressionImpl(polyadic)
|
|
||||||
else polyadic
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun convertPolyadic(operands: List<JKExpression>, operators: List<JKOperator>): JKExpression {
|
|
||||||
return if (operators.isEmpty())
|
|
||||||
operands.first()
|
|
||||||
else {
|
|
||||||
val operator = operators.maxBy { it.precedence }!!
|
|
||||||
val index = operators.indexOf(operator)
|
|
||||||
val left = convertPolyadic(operands.subList(0, index + 1), operators.subList(0, index))
|
|
||||||
val right = convertPolyadic(operands.subList(index + 1, operands.size), operators.subList(index + 1, operators.size))
|
|
||||||
JKBinaryExpressionImpl(left, right, operator)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -25,7 +25,7 @@ class TypeMappingConversion(context: NewJ2kConverterContext) : RecursiveApplicab
|
|||||||
element.type = element.type.mapType(element)
|
element.type = element.type.mapType(element)
|
||||||
}
|
}
|
||||||
is JKJavaNewExpression -> {
|
is JKJavaNewExpression -> {
|
||||||
val newClassSymbol = element.classSymbol.mapClassSymbol(null)
|
val newClassSymbol = element.classSymbol.mapClassSymbol()
|
||||||
return recurse(
|
return recurse(
|
||||||
JKJavaNewExpressionImpl(
|
JKJavaNewExpressionImpl(
|
||||||
newClassSymbol,
|
newClassSymbol,
|
||||||
@@ -55,7 +55,6 @@ class TypeMappingConversion(context: NewJ2kConverterContext) : RecursiveApplicab
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private fun JKType.fixRawType(typeElement: JKTypeElement?) =
|
private fun JKType.fixRawType(typeElement: JKTypeElement?) =
|
||||||
when (typeElement?.parent) {
|
when (typeElement?.parent) {
|
||||||
is JKClassLiteralExpression -> this
|
is JKClassLiteralExpression -> this
|
||||||
@@ -71,7 +70,7 @@ class TypeMappingConversion(context: NewJ2kConverterContext) : RecursiveApplicab
|
|||||||
private fun JKType.mapType(typeElement: JKTypeElement?): JKType =
|
private fun JKType.mapType(typeElement: JKTypeElement?): JKType =
|
||||||
when (this) {
|
when (this) {
|
||||||
is JKJavaPrimitiveType -> mapPrimitiveType()
|
is JKJavaPrimitiveType -> mapPrimitiveType()
|
||||||
is JKClassType -> mapClassType(typeElement)
|
is JKClassType -> mapClassType()
|
||||||
is JKJavaVoidType -> typeFactory.types.unit
|
is JKJavaVoidType -> typeFactory.types.unit
|
||||||
|
|
||||||
is JKJavaArrayType ->
|
is JKJavaArrayType ->
|
||||||
@@ -94,18 +93,17 @@ class TypeMappingConversion(context: NewJ2kConverterContext) : RecursiveApplicab
|
|||||||
else -> this
|
else -> this
|
||||||
}.fixRawType(typeElement)
|
}.fixRawType(typeElement)
|
||||||
|
|
||||||
private fun JKClassSymbol.mapClassSymbol(typeElement: JKTypeElement?): JKClassSymbol {
|
private fun JKClassSymbol.mapClassSymbol(): JKClassSymbol {
|
||||||
if (this is JKUniverseClassSymbol) return this
|
if (this is JKUniverseClassSymbol) return this
|
||||||
if (typeElement?.parentOfType<JKInheritanceInfo>() != null) return this
|
|
||||||
val newFqName = kotlinCollectionClassName()
|
val newFqName = kotlinCollectionClassName()
|
||||||
?: kotlinStandardType()
|
?: kotlinStandardType()
|
||||||
?: fqName
|
?: fqName
|
||||||
return symbolProvider.provideClassSymbol(newFqName)
|
return symbolProvider.provideClassSymbol(newFqName)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun JKClassType.mapClassType(typeElement: JKTypeElement?): JKClassType =
|
private fun JKClassType.mapClassType(): JKClassType =
|
||||||
JKClassTypeImpl(
|
JKClassTypeImpl(
|
||||||
classReference.mapClassSymbol(typeElement),
|
classReference.mapClassSymbol(),
|
||||||
parameters.map { it.mapType(null) },
|
parameters.map { it.mapType(null) },
|
||||||
nullability
|
nullability
|
||||||
)
|
)
|
||||||
@@ -118,13 +116,8 @@ class TypeMappingConversion(context: NewJ2kConverterContext) : RecursiveApplicab
|
|||||||
return JavaToKotlinClassMap.mapJavaToKotlin(FqName(fqName))?.asString()
|
return JavaToKotlinClassMap.mapJavaToKotlin(FqName(fqName))?.asString()
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun JKJavaPrimitiveType.mapPrimitiveType(): JKClassType {
|
private fun JKJavaPrimitiveType.mapPrimitiveType(): JKClassType =
|
||||||
val fqName = jvmPrimitiveType.primitiveType.typeFqName
|
typeFactory.fromPrimitiveType(this)
|
||||||
return JKClassTypeImpl(
|
|
||||||
symbolProvider.provideClassSymbol(fqName),
|
|
||||||
nullability = Nullability.NotNull
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
private inline fun <reified T : JKType> T.addTypeParametersToRawProjectionType(typeParameter: JKType): T =
|
private inline fun <reified T : JKType> T.addTypeParametersToRawProjectionType(typeParameter: JKType): T =
|
||||||
if (this is JKClassType && parameters.isEmpty()) {
|
if (this is JKClassType && parameters.isEmpty()) {
|
||||||
@@ -147,7 +140,6 @@ class TypeMappingConversion(context: NewJ2kConverterContext) : RecursiveApplicab
|
|||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
private val ktFunctionRegex = "kotlin\\.jvm\\.functions\\.Function\\d+".toRegex()
|
private val ktFunctionRegex = "kotlin\\.jvm\\.functions\\.Function\\d+".toRegex()
|
||||||
private fun isKtFunction(fqName: String) =
|
private fun isKtFunction(fqName: String) = ktFunctionRegex.matches(fqName)
|
||||||
ktFunctionRegex.matches(fqName)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -5,67 +5,18 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.nj2k
|
package org.jetbrains.kotlin.nj2k
|
||||||
|
|
||||||
import com.intellij.psi.PsiClass
|
|
||||||
import com.intellij.psi.tree.TokenSet
|
import com.intellij.psi.tree.TokenSet
|
||||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
|
||||||
import org.jetbrains.kotlin.lexer.KtSingleValueToken
|
|
||||||
import org.jetbrains.kotlin.lexer.KtTokens
|
import org.jetbrains.kotlin.lexer.KtTokens
|
||||||
import org.jetbrains.kotlin.nj2k.conversions.RecursiveApplicableConversionBase
|
import org.jetbrains.kotlin.nj2k.conversions.RecursiveApplicableConversionBase
|
||||||
import org.jetbrains.kotlin.nj2k.symbols.*
|
import org.jetbrains.kotlin.nj2k.symbols.JKMethodSymbol
|
||||||
|
import org.jetbrains.kotlin.nj2k.symbols.JKUnresolvedMethod
|
||||||
import org.jetbrains.kotlin.nj2k.tree.*
|
import org.jetbrains.kotlin.nj2k.tree.*
|
||||||
import org.jetbrains.kotlin.nj2k.tree.impl.*
|
import org.jetbrains.kotlin.nj2k.tree.impl.*
|
||||||
import org.jetbrains.kotlin.nj2k.types.JKClassType
|
|
||||||
import org.jetbrains.kotlin.nj2k.types.JKJavaPrimitiveType
|
|
||||||
import org.jetbrains.kotlin.nj2k.types.JKTypeFactory
|
import org.jetbrains.kotlin.nj2k.types.JKTypeFactory
|
||||||
import org.jetbrains.kotlin.nj2k.types.JKTypeParameterType
|
|
||||||
import org.jetbrains.kotlin.psi.KtNamedFunction
|
|
||||||
import org.jetbrains.kotlin.utils.addToStdlib.cast
|
import org.jetbrains.kotlin.utils.addToStdlib.cast
|
||||||
import org.jetbrains.kotlin.utils.addToStdlib.firstIsInstanceOrNull
|
import org.jetbrains.kotlin.utils.addToStdlib.firstIsInstanceOrNull
|
||||||
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
||||||
|
|
||||||
private fun JKType.classSymbol(typeFactory: JKTypeFactory) = when (this) {
|
|
||||||
is JKClassType -> classReference
|
|
||||||
is JKJavaPrimitiveType -> typeFactory.fromPrimitiveType(this).classReference
|
|
||||||
else -> null
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun JKKtOperatorToken.arithmeticMethodType(
|
|
||||||
leftType: JKType,
|
|
||||||
rightType: JKType,
|
|
||||||
typeFactory: JKTypeFactory
|
|
||||||
): JKType? {
|
|
||||||
val symbolProvider = typeFactory.symbolProvider
|
|
||||||
|
|
||||||
fun PsiClass.methodReturnType() =
|
|
||||||
allMethods
|
|
||||||
.filter { it.name == operatorName }
|
|
||||||
.firstOrNull {
|
|
||||||
it.parameterList.parameters.singleOrNull()?.takeIf { parameter ->
|
|
||||||
val type = typeFactory.fromPsiType(parameter.type)
|
|
||||||
if (type !is JKTypeParameterType) rightType.isSubtypeOf(type, typeFactory)
|
|
||||||
else true//TODO check for type bounds
|
|
||||||
} != null
|
|
||||||
}?.returnType?.let { typeFactory.fromPsiType(it) }
|
|
||||||
|
|
||||||
val classSymbol =
|
|
||||||
if (leftType.isStringType()) symbolProvider.provideClassSymbol(KotlinBuiltIns.FQ_NAMES.string.toSafe())
|
|
||||||
else leftType.classSymbol(typeFactory)
|
|
||||||
|
|
||||||
return when (classSymbol) {
|
|
||||||
is JKMultiverseKtClassSymbol ->
|
|
||||||
classSymbol.target.declarations
|
|
||||||
.asSequence()
|
|
||||||
.filterIsInstance<KtNamedFunction>()
|
|
||||||
.filter { it.name == operatorName }
|
|
||||||
.mapNotNull { symbolProvider.provideDirectSymbol(it) as? JKMethodSymbol }
|
|
||||||
.firstOrNull { it.parameterTypes?.singleOrNull()?.takeIf { rightType.isSubtypeOf(it, typeFactory) } != null }
|
|
||||||
?.returnType
|
|
||||||
is JKUniverseClassSymbol -> classSymbol.target.psi<PsiClass>()?.methodReturnType()
|
|
||||||
is JKMultiverseClassSymbol -> classSymbol.target.methodReturnType()
|
|
||||||
else -> null
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fun JKOperator.isEquals() =
|
fun JKOperator.isEquals() =
|
||||||
(token as? JKKtSingleValueOperatorToken)?.psiToken in equalsOperators
|
(token as? JKKtSingleValueOperatorToken)?.psiToken in equalsOperators
|
||||||
|
|
||||||
@@ -77,98 +28,6 @@ private val equalsOperators =
|
|||||||
KtTokens.EXCLEQ
|
KtTokens.EXCLEQ
|
||||||
)
|
)
|
||||||
|
|
||||||
private val lessGreaterOperators =
|
|
||||||
TokenSet.create(
|
|
||||||
KtTokens.LT,
|
|
||||||
KtTokens.GT,
|
|
||||||
KtTokens.LTEQ,
|
|
||||||
KtTokens.GTEQ
|
|
||||||
)
|
|
||||||
|
|
||||||
private val comparisonOperators =
|
|
||||||
TokenSet.orSet(
|
|
||||||
lessGreaterOperators,
|
|
||||||
equalsOperators
|
|
||||||
)
|
|
||||||
|
|
||||||
private val booleanOperators =
|
|
||||||
TokenSet.orSet(
|
|
||||||
comparisonOperators,
|
|
||||||
TokenSet.create(
|
|
||||||
KtTokens.ANDAND,
|
|
||||||
KtTokens.OROR
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
private val arithmeticOperators = TokenSet.create(
|
|
||||||
KtTokens.MUL,
|
|
||||||
KtTokens.PLUS,
|
|
||||||
KtTokens.MINUS,
|
|
||||||
KtTokens.DIV,
|
|
||||||
KtTokens.PERC
|
|
||||||
)
|
|
||||||
|
|
||||||
private fun JKKtOperatorToken.defaultReturnType(leftType: JKType?): JKType? {
|
|
||||||
if (this is JKKtSingleValueOperatorToken && psiToken in arithmeticOperators) return leftType
|
|
||||||
return null
|
|
||||||
}
|
|
||||||
|
|
||||||
fun kotlinBinaryExpression(
|
|
||||||
left: JKExpression,
|
|
||||||
right: JKExpression,
|
|
||||||
token: JKKtOperatorToken,
|
|
||||||
typeFactory: JKTypeFactory
|
|
||||||
): JKBinaryExpression {
|
|
||||||
val symbolProvider = typeFactory.symbolProvider
|
|
||||||
val returnType =
|
|
||||||
when {
|
|
||||||
token is JKKtSingleValueOperatorToken && token.psiToken in booleanOperators ->
|
|
||||||
JKClassTypeImpl(symbolProvider.provideClassSymbol(KotlinBuiltIns.FQ_NAMES._boolean.toSafe()))
|
|
||||||
else -> {
|
|
||||||
val leftType = left.type(typeFactory)
|
|
||||||
val rightType = right.type(typeFactory)
|
|
||||||
leftType?.let { l ->
|
|
||||||
rightType?.let { r ->
|
|
||||||
token.arithmeticMethodType(l, r, typeFactory)
|
|
||||||
}
|
|
||||||
} ?: token.defaultReturnType(leftType)
|
|
||||||
?: typeFactory.types.nothing
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return JKBinaryExpressionImpl(left, right, JKKtOperatorImpl(token, returnType))
|
|
||||||
}
|
|
||||||
|
|
||||||
fun kotlinBinaryExpression(
|
|
||||||
left: JKExpression,
|
|
||||||
right: JKExpression,
|
|
||||||
token: KtSingleValueToken,
|
|
||||||
typeFactory: JKTypeFactory
|
|
||||||
): JKBinaryExpression =
|
|
||||||
kotlinBinaryExpression(
|
|
||||||
left,
|
|
||||||
right,
|
|
||||||
JKKtSingleValueOperatorToken(token),
|
|
||||||
typeFactory
|
|
||||||
)
|
|
||||||
|
|
||||||
fun kotlinPrefixExpression(
|
|
||||||
operand: JKExpression,
|
|
||||||
token: JKKtOperatorToken,
|
|
||||||
typeFactory: JKTypeFactory
|
|
||||||
): JKPrefixExpression {
|
|
||||||
val operandType = operand.type(typeFactory) ?: JKNoTypeImpl
|
|
||||||
return JKPrefixExpressionImpl(operand, JKKtOperatorImpl(token, operandType))
|
|
||||||
}
|
|
||||||
|
|
||||||
fun kotlinPostfixExpression(
|
|
||||||
operand: JKExpression,
|
|
||||||
token: JKKtOperatorToken,
|
|
||||||
typeFactory: JKTypeFactory
|
|
||||||
): JKPostfixExpression {
|
|
||||||
val operandType = operand.type(typeFactory) ?: JKNoTypeImpl
|
|
||||||
return JKPostfixExpressionImpl(operand, JKKtOperatorImpl(token, operandType))
|
|
||||||
}
|
|
||||||
|
|
||||||
fun untilToExpression(
|
fun untilToExpression(
|
||||||
from: JKExpression,
|
from: JKExpression,
|
||||||
to: JKExpression,
|
to: JKExpression,
|
||||||
@@ -199,6 +58,8 @@ fun JKExpression.parenthesizeIfBinaryExpression() =
|
|||||||
else -> this
|
else -> this
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun JKExpression.parenthesize() = JKParenthesizedExpressionImpl(this)
|
||||||
|
|
||||||
fun rangeExpression(
|
fun rangeExpression(
|
||||||
from: JKExpression,
|
from: JKExpression,
|
||||||
to: JKExpression,
|
to: JKExpression,
|
||||||
@@ -277,7 +138,7 @@ fun stringLiteral(content: String, typeFactory: JKTypeFactory): JKExpression {
|
|||||||
val newlineSeparator = if (i == lines.size - 1) "" else "\\n"
|
val newlineSeparator = if (i == lines.size - 1) "" else "\\n"
|
||||||
JKKtLiteralExpressionImpl("\"$line$newlineSeparator\"", JKLiteralExpression.LiteralType.STRING)
|
JKKtLiteralExpressionImpl("\"$line$newlineSeparator\"", JKLiteralExpression.LiteralType.STRING)
|
||||||
}.reduce { acc: JKExpression, literalExpression: JKKtLiteralExpression ->
|
}.reduce { acc: JKExpression, literalExpression: JKKtLiteralExpression ->
|
||||||
kotlinBinaryExpression(acc, literalExpression, JKKtSingleValueOperatorToken(KtTokens.PLUS), typeFactory)
|
JKBinaryExpressionImpl(acc, literalExpression, JKKtOperatorImpl(JKOperatorToken.PLUS, typeFactory.types.string))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -320,11 +181,13 @@ fun JKVariable.hasWritableUsages(scope: JKTreeElement, context: NewJ2kConverterC
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun equalsExpression(left: JKExpression, right: JKExpression, typeFactory: JKTypeFactory) =
|
fun equalsExpression(left: JKExpression, right: JKExpression, typeFactory: JKTypeFactory) =
|
||||||
kotlinBinaryExpression(
|
JKBinaryExpressionImpl(
|
||||||
left,
|
left,
|
||||||
right,
|
right,
|
||||||
KtTokens.EQEQ,
|
JKKtOperatorImpl(
|
||||||
typeFactory
|
JKOperatorToken.EQEQ,
|
||||||
|
typeFactory.types.boolean
|
||||||
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
fun createCompanion(declarations: List<JKDeclaration>): JKClass =
|
fun createCompanion(declarations: List<JKDeclaration>): JKClass =
|
||||||
@@ -438,4 +301,19 @@ fun <T : JKExpression> T.nullIfStubExpression(): T? =
|
|||||||
fun JKExpression.qualified(qualifier: JKExpression?) =
|
fun JKExpression.qualified(qualifier: JKExpression?) =
|
||||||
if (qualifier != null && qualifier !is JKStubExpression) {
|
if (qualifier != null && qualifier !is JKStubExpression) {
|
||||||
JKQualifiedExpressionImpl(qualifier, JKJavaQualifierImpl.DOT, this)
|
JKQualifiedExpressionImpl(qualifier, JKJavaQualifierImpl.DOT, this)
|
||||||
} else this
|
} else this
|
||||||
|
|
||||||
|
fun JKExpression.callOn(
|
||||||
|
symbol: JKMethodSymbol,
|
||||||
|
arguments: List<JKExpression> = emptyList(),
|
||||||
|
typeArguments: List<JKTypeElement> = emptyList()
|
||||||
|
) = JKQualifiedExpressionImpl(
|
||||||
|
this,
|
||||||
|
JKKtQualifierImpl.DOT,
|
||||||
|
JKKtCallExpressionImpl(
|
||||||
|
symbol,
|
||||||
|
JKArgumentListImpl(arguments.map { JKArgumentImpl(it) }),
|
||||||
|
JKTypeArgumentListImpl(typeArguments)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -5,21 +5,119 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.nj2k.tree
|
package org.jetbrains.kotlin.nj2k.tree
|
||||||
|
|
||||||
|
import com.intellij.psi.JavaTokenType
|
||||||
|
import com.intellij.psi.tree.IElementType
|
||||||
import org.jetbrains.kotlin.j2k.ast.Nullability
|
import org.jetbrains.kotlin.j2k.ast.Nullability
|
||||||
|
import org.jetbrains.kotlin.lexer.KtTokens
|
||||||
|
import org.jetbrains.kotlin.nj2k.tree.impl.JKJavaOperatorToken
|
||||||
|
import org.jetbrains.kotlin.nj2k.tree.impl.JKKtSingleValueOperatorToken
|
||||||
|
import org.jetbrains.kotlin.nj2k.tree.impl.JKKtWordOperatorToken
|
||||||
|
|
||||||
interface JKOperator {
|
interface JKOperator {
|
||||||
val token: JKOperatorToken
|
val token: JKOperatorToken
|
||||||
val precedence: Int
|
val returnType: JKType
|
||||||
}
|
}
|
||||||
|
|
||||||
interface JKOperatorToken {
|
interface JKOperatorToken {
|
||||||
val text: String
|
val text: String
|
||||||
|
|
||||||
|
@Suppress("MemberVisibilityCanBePrivate", "SpellCheckingInspection")
|
||||||
|
companion object {
|
||||||
|
fun fromElementType(elementType: IElementType) = elementTypeToToken.getValue(elementType)
|
||||||
|
|
||||||
|
val RANGE = JKKtSingleValueOperatorToken(KtTokens.RANGE)
|
||||||
|
|
||||||
|
val DIV = JKKtSingleValueOperatorToken(KtTokens.DIV)
|
||||||
|
val MINUS = JKKtSingleValueOperatorToken(KtTokens.MINUS)
|
||||||
|
val ANDAND = JKKtSingleValueOperatorToken(KtTokens.ANDAND)
|
||||||
|
val OROR = JKKtSingleValueOperatorToken(KtTokens.OROR)
|
||||||
|
val PLUS = JKKtSingleValueOperatorToken(KtTokens.PLUS)
|
||||||
|
val MUL = JKKtSingleValueOperatorToken(KtTokens.MUL)
|
||||||
|
val GT = JKKtSingleValueOperatorToken(KtTokens.GT)
|
||||||
|
val GTEQ = JKKtSingleValueOperatorToken(KtTokens.GTEQ)
|
||||||
|
val LT = JKKtSingleValueOperatorToken(KtTokens.LT)
|
||||||
|
val LTEQ = JKKtSingleValueOperatorToken(KtTokens.LTEQ)
|
||||||
|
val PERC = JKKtSingleValueOperatorToken(KtTokens.PERC)
|
||||||
|
val EQ = JKKtSingleValueOperatorToken(KtTokens.EQ)
|
||||||
|
val EQEQ = JKKtSingleValueOperatorToken(KtTokens.EQEQ)
|
||||||
|
val EXCLEQ = JKKtSingleValueOperatorToken(KtTokens.EXCLEQ)
|
||||||
|
|
||||||
|
val PLUSEQ = JKKtSingleValueOperatorToken(KtTokens.PLUSEQ)
|
||||||
|
val MINUSEQ = JKKtSingleValueOperatorToken(KtTokens.MINUSEQ)
|
||||||
|
val DIVEQ = JKKtSingleValueOperatorToken(KtTokens.DIVEQ)
|
||||||
|
val MULTEQ = JKKtSingleValueOperatorToken(KtTokens.MULTEQ)
|
||||||
|
val PERCEQ = JKKtSingleValueOperatorToken(KtTokens.PERCEQ)
|
||||||
|
|
||||||
|
|
||||||
|
val PLUSPLUS = JKKtSingleValueOperatorToken(KtTokens.PLUSPLUS)
|
||||||
|
val MINUSMINUS = JKKtSingleValueOperatorToken(KtTokens.MINUSMINUS)
|
||||||
|
val EXCL = JKKtSingleValueOperatorToken(KtTokens.EXCL)
|
||||||
|
val EQEQEQ = JKKtSingleValueOperatorToken(KtTokens.EQEQEQ)
|
||||||
|
val EXCLEQEQEQ = JKKtSingleValueOperatorToken(KtTokens.EXCLEQEQEQ)
|
||||||
|
|
||||||
|
val AND = JKKtWordOperatorToken("and")
|
||||||
|
val OR = JKKtWordOperatorToken("or")
|
||||||
|
val XOR = JKKtWordOperatorToken("xor")
|
||||||
|
val USHR = JKKtWordOperatorToken("ushr")
|
||||||
|
val SHR = JKKtWordOperatorToken("shr")
|
||||||
|
val SHL = JKKtWordOperatorToken("shl")
|
||||||
|
|
||||||
|
val ANDEQ = JKJavaOperatorToken(JavaTokenType.ANDEQ)
|
||||||
|
val OREQ = JKJavaOperatorToken(JavaTokenType.OREQ)
|
||||||
|
val XOREQ = JKJavaOperatorToken(JavaTokenType.XOREQ)
|
||||||
|
val LTLTEQ = JKJavaOperatorToken(JavaTokenType.LTLTEQ)
|
||||||
|
val GTGTEQ = JKJavaOperatorToken(JavaTokenType.GTGTEQ)
|
||||||
|
val GTGTGTEQ = JKJavaOperatorToken(JavaTokenType.GTGTGTEQ)
|
||||||
|
|
||||||
|
|
||||||
|
private val elementTypeToToken: Map<IElementType, JKOperatorToken> = mapOf(
|
||||||
|
JavaTokenType.DIV to DIV,
|
||||||
|
JavaTokenType.MINUS to MINUS,
|
||||||
|
JavaTokenType.ANDAND to ANDAND,
|
||||||
|
JavaTokenType.OROR to OROR,
|
||||||
|
JavaTokenType.PLUS to PLUS,
|
||||||
|
JavaTokenType.ASTERISK to MUL,
|
||||||
|
JavaTokenType.GT to GT,
|
||||||
|
JavaTokenType.GE to GTEQ,
|
||||||
|
JavaTokenType.LT to LT,
|
||||||
|
JavaTokenType.LE to LTEQ,
|
||||||
|
JavaTokenType.PERC to PERC,
|
||||||
|
|
||||||
|
JavaTokenType.EQ to EQ,
|
||||||
|
JavaTokenType.EQEQ to EQEQ,
|
||||||
|
JavaTokenType.NE to EXCLEQ,
|
||||||
|
|
||||||
|
JavaTokenType.PLUSEQ to PLUSEQ,
|
||||||
|
JavaTokenType.MINUSEQ to MINUSEQ,
|
||||||
|
JavaTokenType.DIVEQ to DIVEQ,
|
||||||
|
JavaTokenType.ASTERISKEQ to MULTEQ,
|
||||||
|
|
||||||
|
JavaTokenType.PLUSPLUS to PLUSPLUS,
|
||||||
|
JavaTokenType.MINUSMINUS to MINUSMINUS,
|
||||||
|
JavaTokenType.EXCL to EXCL,
|
||||||
|
|
||||||
|
KtTokens.EQEQEQ to EQEQEQ,
|
||||||
|
KtTokens.EXCLEQEQEQ to EXCLEQEQEQ,
|
||||||
|
|
||||||
|
JavaTokenType.AND to AND,
|
||||||
|
JavaTokenType.OR to OR,
|
||||||
|
JavaTokenType.XOR to XOR,
|
||||||
|
JavaTokenType.GTGTGT to USHR,
|
||||||
|
JavaTokenType.GTGT to SHR,
|
||||||
|
JavaTokenType.LTLT to SHL,
|
||||||
|
|
||||||
|
JavaTokenType.ANDEQ to ANDEQ,
|
||||||
|
JavaTokenType.OREQ to OREQ,
|
||||||
|
JavaTokenType.XOREQ to XOREQ,
|
||||||
|
JavaTokenType.PERCEQ to PERCEQ,
|
||||||
|
JavaTokenType.LTLTEQ to LTLTEQ,
|
||||||
|
JavaTokenType.GTGTEQ to GTGTEQ,
|
||||||
|
JavaTokenType.GTGTGTEQ to GTGTGTEQ
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
interface JKKtOperatorToken : JKOperatorToken {
|
interface JKKtOperatorToken : JKOperatorToken
|
||||||
val operatorName: String
|
|
||||||
}
|
|
||||||
|
|
||||||
interface JKQualifier
|
interface JKQualifier
|
||||||
|
|
||||||
interface JKElement {
|
interface JKElement {
|
||||||
|
|||||||
@@ -159,7 +159,7 @@ class JKQualifiedExpressionImpl(
|
|||||||
class JKExpressionStatementImpl(expression: JKExpression) : JKExpressionStatement(), PsiOwner by PsiOwnerImpl() {
|
class JKExpressionStatementImpl(expression: JKExpression) : JKExpressionStatement(), PsiOwner by PsiOwnerImpl() {
|
||||||
override fun accept(visitor: JKVisitor) = visitor.visitExpressionStatement(this)
|
override fun accept(visitor: JKVisitor) = visitor.visitExpressionStatement(this)
|
||||||
|
|
||||||
override val expression: JKExpression by child(expression)
|
override var expression: JKExpression by child(expression)
|
||||||
}
|
}
|
||||||
|
|
||||||
class JKDeclarationStatementImpl(declaredStatements: List<JKDeclaration>) : JKDeclarationStatement(),
|
class JKDeclarationStatementImpl(declaredStatements: List<JKDeclaration>) : JKDeclarationStatement(),
|
||||||
|
|||||||
@@ -92,125 +92,9 @@ class JKJavaLiteralExpressionImpl(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
class JKJavaOperatorToken(val psiToken: IElementType) : JKOperatorToken {
|
class JKJavaOperatorToken(val psiToken: IElementType) : JKOperatorToken {
|
||||||
override val text: String
|
override val text: String
|
||||||
get() = when (psiToken) {
|
get() = error("Java token should not be printed, it should be replaces with corresponding Kotlin one")
|
||||||
JavaTokenType.EQ -> "="
|
|
||||||
JavaTokenType.EQEQ -> "=="
|
|
||||||
JavaTokenType.NE -> "!="
|
|
||||||
JavaTokenType.ANDAND -> "&&"
|
|
||||||
JavaTokenType.OROR -> "||"
|
|
||||||
JavaTokenType.GT -> ">"
|
|
||||||
JavaTokenType.LT -> "<"
|
|
||||||
JavaTokenType.GE -> ">="
|
|
||||||
JavaTokenType.LE -> "<="
|
|
||||||
JavaTokenType.EXCL -> "!"
|
|
||||||
JavaTokenType.PLUS -> "+"
|
|
||||||
JavaTokenType.MINUS -> "-"
|
|
||||||
JavaTokenType.ASTERISK -> "*"
|
|
||||||
JavaTokenType.DIV -> "/"
|
|
||||||
JavaTokenType.PERC -> "%"
|
|
||||||
JavaTokenType.PLUSEQ -> "+="
|
|
||||||
JavaTokenType.MINUSEQ -> "-="
|
|
||||||
JavaTokenType.ASTERISKEQ -> "*="
|
|
||||||
JavaTokenType.DIVEQ -> "/="
|
|
||||||
JavaTokenType.PERCEQ -> "%="
|
|
||||||
JavaTokenType.GTGT -> "shr"
|
|
||||||
JavaTokenType.LTLT -> "shl"
|
|
||||||
JavaTokenType.XOR -> "xor"
|
|
||||||
JavaTokenType.AND -> "and"
|
|
||||||
JavaTokenType.OR -> "or"
|
|
||||||
JavaTokenType.GTGTGT -> "ushr"
|
|
||||||
JavaTokenType.GTGTEQ -> "shr"
|
|
||||||
JavaTokenType.LTLTEQ -> "shl"
|
|
||||||
JavaTokenType.XOREQ -> "xor"
|
|
||||||
JavaTokenType.ANDEQ -> "and"
|
|
||||||
JavaTokenType.OREQ -> "or"
|
|
||||||
JavaTokenType.GTGTGTEQ -> "ushr"
|
|
||||||
JavaTokenType.PLUSPLUS -> "++"
|
|
||||||
JavaTokenType.MINUSMINUS -> "--"
|
|
||||||
JavaTokenType.TILDE -> "~"
|
|
||||||
else -> TODO(psiToken.toString())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fun JKJavaOperatorToken.toKtToken(): JKKtOperatorToken =
|
|
||||||
when (this.psiToken) {
|
|
||||||
JavaTokenType.DIV -> JKKtSingleValueOperatorToken(KtTokens.DIV)
|
|
||||||
JavaTokenType.MINUS -> JKKtSingleValueOperatorToken(KtTokens.MINUS)
|
|
||||||
JavaTokenType.ANDAND -> JKKtSingleValueOperatorToken(KtTokens.ANDAND)
|
|
||||||
JavaTokenType.OROR -> JKKtSingleValueOperatorToken(KtTokens.OROR)
|
|
||||||
JavaTokenType.PLUS -> JKKtSingleValueOperatorToken(KtTokens.PLUS)
|
|
||||||
JavaTokenType.ASTERISK -> JKKtSingleValueOperatorToken(KtTokens.MUL)
|
|
||||||
JavaTokenType.GT -> JKKtSingleValueOperatorToken(KtTokens.GT)
|
|
||||||
JavaTokenType.GE -> JKKtSingleValueOperatorToken(KtTokens.GTEQ)
|
|
||||||
JavaTokenType.LT -> JKKtSingleValueOperatorToken(KtTokens.LT)
|
|
||||||
JavaTokenType.LE -> JKKtSingleValueOperatorToken(KtTokens.LTEQ)
|
|
||||||
JavaTokenType.PERC -> JKKtSingleValueOperatorToken(KtTokens.PERC)
|
|
||||||
|
|
||||||
JavaTokenType.EQ -> JKKtSingleValueOperatorToken(KtTokens.EQ)
|
|
||||||
JavaTokenType.EQEQ -> JKKtSingleValueOperatorToken(KtTokens.EQEQ)
|
|
||||||
JavaTokenType.NE -> JKKtSingleValueOperatorToken(KtTokens.EXCLEQ)
|
|
||||||
JavaTokenType.PLUSEQ -> JKKtSingleValueOperatorToken(KtTokens.PLUSEQ)
|
|
||||||
JavaTokenType.MINUSEQ -> JKKtSingleValueOperatorToken(KtTokens.MINUSEQ)
|
|
||||||
JavaTokenType.PLUSPLUS -> JKKtSingleValueOperatorToken(KtTokens.PLUSPLUS)
|
|
||||||
JavaTokenType.MINUSMINUS -> JKKtSingleValueOperatorToken(KtTokens.MINUSMINUS)
|
|
||||||
JavaTokenType.EXCL -> JKKtSingleValueOperatorToken(KtTokens.EXCL)
|
|
||||||
|
|
||||||
KtTokens.EQEQEQ -> JKKtSingleValueOperatorToken(KtTokens.EQEQEQ)
|
|
||||||
KtTokens.EXCLEQEQEQ -> JKKtSingleValueOperatorToken(KtTokens.EXCLEQEQEQ)
|
|
||||||
|
|
||||||
JavaTokenType.AND -> JKKtWordOperatorToken("and")
|
|
||||||
JavaTokenType.OR -> JKKtWordOperatorToken("or")
|
|
||||||
JavaTokenType.XOR -> JKKtWordOperatorToken("xor")
|
|
||||||
JavaTokenType.GTGTGT -> JKKtWordOperatorToken("ushr")
|
|
||||||
JavaTokenType.GTGT -> JKKtWordOperatorToken("shr")
|
|
||||||
JavaTokenType.LTLT -> JKKtWordOperatorToken("shl")
|
|
||||||
|
|
||||||
JavaTokenType.OREQ -> JKKtWordOperatorToken("or")
|
|
||||||
JavaTokenType.ANDEQ -> JKKtWordOperatorToken("and")
|
|
||||||
JavaTokenType.LTLTEQ -> JKKtWordOperatorToken("shl")
|
|
||||||
JavaTokenType.GTGTEQ -> JKKtWordOperatorToken("shr")
|
|
||||||
JavaTokenType.GTGTGTEQ -> JKKtWordOperatorToken("ushr")
|
|
||||||
JavaTokenType.XOREQ -> JKKtWordOperatorToken("xor")
|
|
||||||
|
|
||||||
else -> TODO(this.psiToken.toString())
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
class JKJavaOperatorImpl private constructor(psiToken: IElementType) : JKOperator {
|
|
||||||
override val token: JKJavaOperatorToken = JKJavaOperatorToken(psiToken)
|
|
||||||
|
|
||||||
override val precedence: Int
|
|
||||||
get() = when (token.psiToken) {
|
|
||||||
JavaTokenType.ASTERISK, JavaTokenType.DIV, JavaTokenType.PERC -> 3
|
|
||||||
JavaTokenType.PLUS, JavaTokenType.MINUS -> 4
|
|
||||||
KtTokens.ELVIS -> 7
|
|
||||||
JavaTokenType.GT, JavaTokenType.LT, JavaTokenType.GE, JavaTokenType.LE -> 9
|
|
||||||
JavaTokenType.EQEQ, JavaTokenType.NE, KtTokens.EQEQEQ, KtTokens.EXCLEQEQEQ -> 10
|
|
||||||
JavaTokenType.ANDAND -> 11
|
|
||||||
JavaTokenType.OROR -> 12
|
|
||||||
JavaTokenType.GTGTGT, JavaTokenType.GTGT, JavaTokenType.LTLT -> 7
|
|
||||||
else -> 6 /* simple name */
|
|
||||||
}
|
|
||||||
|
|
||||||
// override val priority: Int
|
|
||||||
// get() = when (token.psiToken) {
|
|
||||||
// JavaTokenType.ASTERISK, JavaTokenType.DIV, JavaTokenType.PERC -> 12
|
|
||||||
// JavaTokenType.PLUS, JavaTokenType.MINUS -> 11
|
|
||||||
// JavaTokenType.GTGTGT, JavaTokenType.GTGT, JavaTokenType.LTLT -> 10
|
|
||||||
// JavaTokenType.GT, JavaTokenType.LT, JavaTokenType.GE, JavaTokenType.LE -> 9
|
|
||||||
// JavaTokenType.EQEQ, JavaTokenType.NE, KtTokens.EQEQEQ, KtTokens.EXCLEQEQEQ ->
|
|
||||||
// }
|
|
||||||
|
|
||||||
companion object {
|
|
||||||
val tokenToOperator =
|
|
||||||
(OPERATION_BIT_SET.types + arrayOf(KtTokens.EQEQEQ, KtTokens.EXCLEQEQEQ))
|
|
||||||
.associate {
|
|
||||||
it to JKJavaOperatorImpl(it)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
sealed class JKJavaQualifierImpl : JKQualifier {
|
sealed class JKJavaQualifierImpl : JKQualifier {
|
||||||
@@ -342,13 +226,13 @@ class JKJavaPolyadicExpressionImpl(operands: List<JKExpression>, override var to
|
|||||||
}
|
}
|
||||||
|
|
||||||
class JKJavaAssignmentExpressionImpl(
|
class JKJavaAssignmentExpressionImpl(
|
||||||
field: JKAssignableExpression,
|
field: JKExpression,
|
||||||
expression: JKExpression,
|
expression: JKExpression,
|
||||||
override var operator: JKOperator
|
override var operator: JKOperator
|
||||||
) : JKBranchElementBase(), JKJavaAssignmentExpression, PsiOwner by PsiOwnerImpl() {
|
) : JKBranchElementBase(), JKJavaAssignmentExpression, PsiOwner by PsiOwnerImpl() {
|
||||||
override fun accept(visitor: JKVisitor) = visitor.visitJavaAssignmentExpression(this)
|
override fun accept(visitor: JKVisitor) = visitor.visitJavaAssignmentExpression(this)
|
||||||
override var field: JKAssignableExpression by child(field)
|
override var field by child(field)
|
||||||
override var expression: JKExpression by child(expression)
|
override var expression by child(expression)
|
||||||
}
|
}
|
||||||
|
|
||||||
class JKJavaSwitchStatementImpl(
|
class JKJavaSwitchStatementImpl(
|
||||||
|
|||||||
@@ -104,64 +104,51 @@ class JKKtLiteralExpressionImpl(
|
|||||||
}
|
}
|
||||||
|
|
||||||
class JKKtSingleValueOperatorToken(val psiToken: KtSingleValueToken) : JKKtOperatorToken {
|
class JKKtSingleValueOperatorToken(val psiToken: KtSingleValueToken) : JKKtOperatorToken {
|
||||||
override val operatorName: String
|
|
||||||
get() = OperatorConventions.getNameForOperationSymbol(psiToken, true, true)?.identifier
|
|
||||||
?: OperatorConventions.BOOLEAN_OPERATIONS[psiToken]?.identifier
|
|
||||||
?: TODO(psiToken.value)
|
|
||||||
override val text: String = psiToken.value
|
override val text: String = psiToken.value
|
||||||
}
|
}
|
||||||
|
|
||||||
object JKKtSpreadOperatorToken : JKKtOperatorToken {
|
object JKKtSpreadOperatorToken : JKKtOperatorToken {
|
||||||
override val text: String = "*"
|
override val text: String = "*"
|
||||||
override val operatorName: String = "*"
|
|
||||||
}
|
}
|
||||||
|
|
||||||
object JKKtSpreadOperator : JKOperator {
|
class JKKtSpreadOperator(override val returnType: JKType) : JKOperator {
|
||||||
override val token: JKOperatorToken = JKKtSpreadOperatorToken
|
override val token: JKOperatorToken = JKKtSpreadOperatorToken
|
||||||
override val precedence: Int
|
|
||||||
get() = TODO()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class JKKtWordOperatorToken(override val text: String) : JKKtOperatorToken {
|
class JKKtWordOperatorToken(override val text: String) : JKKtOperatorToken
|
||||||
override val operatorName: String = text
|
|
||||||
|
class JKKtOperatorImpl(override val token: JKOperatorToken, override val returnType: JKType) : JKOperator
|
||||||
|
|
||||||
|
class JKAssignmentChainAlsoLinkImpl(
|
||||||
|
receiver: JKExpression,
|
||||||
|
assignmentStatement: JKKtAssignmentStatement,
|
||||||
|
field: JKExpression
|
||||||
|
) : JKAssignmentChainAlsoLink, JKBranchElementBase() {
|
||||||
|
override val receiver by child(receiver)
|
||||||
|
override val assignmentStatement by child(assignmentStatement)
|
||||||
|
override val field by child(field)
|
||||||
|
|
||||||
|
override fun accept(visitor: JKVisitor) = visitor.visitAssignmentChainAlsoLink(this)
|
||||||
}
|
}
|
||||||
|
|
||||||
class JKKtOperatorImpl(override val token: JKKtOperatorToken, val returnType: JKType) : JKOperator, JKElementBase() {
|
class JKAssignmentChainLetLinkImpl(
|
||||||
constructor(singleValueToken: KtSingleValueToken, returnType: JKType) : this(
|
receiver: JKExpression,
|
||||||
JKKtSingleValueOperatorToken(singleValueToken),
|
assignmentStatement: JKKtAssignmentStatement,
|
||||||
returnType
|
field: JKExpression
|
||||||
)
|
) : JKAssignmentChainLetLink, JKBranchElementBase() {
|
||||||
|
override val receiver by child(receiver)
|
||||||
|
override val assignmentStatement by child(assignmentStatement)
|
||||||
|
override val field by child(field)
|
||||||
|
|
||||||
override val precedence: Int
|
override fun accept(visitor: JKVisitor) = visitor.visitAssignmentChainLetLink(this)
|
||||||
get() = TODO("not implemented") //To change initializer of created properties use File | Settings | File Templates.
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
class JKKtAlsoCallExpressionImpl(
|
|
||||||
statement: JKStatement,
|
|
||||||
override val identifier: JKMethodSymbol,
|
|
||||||
typeArgumentList: JKTypeArgumentList = JKTypeArgumentListImpl()
|
|
||||||
) : JKKtAlsoCallExpression, JKBranchElementBase() {
|
|
||||||
override fun accept(visitor: JKVisitor) = visitor.visitKtAlsoCallExpression(this)
|
|
||||||
override var statement
|
|
||||||
get() = arguments.arguments.first().value.cast<JKLambdaExpressionImpl>().statement
|
|
||||||
set(it) {
|
|
||||||
arguments.arguments.first().value.cast<JKLambdaExpressionImpl>().statement = it
|
|
||||||
}
|
|
||||||
override var arguments: JKArgumentList by child(
|
|
||||||
JKArgumentListImpl(
|
|
||||||
JKLambdaExpressionImpl(statement, emptyList())
|
|
||||||
)
|
|
||||||
)
|
|
||||||
override var typeArgumentList: JKTypeArgumentList by child(typeArgumentList)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class JKKtAssignmentStatementImpl(
|
class JKKtAssignmentStatementImpl(
|
||||||
field: JKAssignableExpression,
|
field: JKExpression,
|
||||||
expression: JKExpression,
|
expression: JKExpression,
|
||||||
override var operator: JKOperator
|
override var token: JKOperatorToken
|
||||||
) : JKKtAssignmentStatement() {
|
) : JKKtAssignmentStatement() {
|
||||||
override var field: JKAssignableExpression by child(field)
|
override var field: JKExpression by child(field)
|
||||||
override var expression by child(expression)
|
override var expression by child(expression)
|
||||||
override fun accept(visitor: JKVisitor) = visitor.visitKtAssignmentStatement(this)
|
override fun accept(visitor: JKVisitor) = visitor.visitKtAssignmentStatement(this)
|
||||||
|
|
||||||
@@ -320,4 +307,8 @@ class JKKtEmptyGetterOrSetterImpl : JKKtEmptyGetterOrSetter, JKBranchElementBase
|
|||||||
override var visibilityElement by child(JKVisibilityModifierElementImpl(Visibility.PUBLIC))
|
override var visibilityElement by child(JKVisibilityModifierElementImpl(Visibility.PUBLIC))
|
||||||
|
|
||||||
override fun accept(visitor: JKVisitor) = visitor.visitKtEmptyGetterOrSetter(this)
|
override fun accept(visitor: JKVisitor) = visitor.visitKtEmptyGetterOrSetter(this)
|
||||||
|
}
|
||||||
|
|
||||||
|
class JKKtItExpressionImpl(override val type: JKType) : JKKtItExpression, JKBranchElementBase() {
|
||||||
|
override fun accept(visitor: JKVisitor) = visitor.visitKtItExpression(this)
|
||||||
}
|
}
|
||||||
@@ -290,7 +290,7 @@ interface JKMethodReferenceExpression : JKExpression, PsiOwner {
|
|||||||
}
|
}
|
||||||
|
|
||||||
abstract class JKExpressionStatement : JKStatement() {
|
abstract class JKExpressionStatement : JKStatement() {
|
||||||
abstract val expression: JKExpression
|
abstract var expression: JKExpression
|
||||||
}
|
}
|
||||||
|
|
||||||
abstract class JKDeclarationStatement : JKStatement() {
|
abstract class JKDeclarationStatement : JKStatement() {
|
||||||
@@ -315,7 +315,7 @@ interface JKPrefixExpression : JKUnaryExpression
|
|||||||
|
|
||||||
interface JKPostfixExpression : JKUnaryExpression
|
interface JKPostfixExpression : JKUnaryExpression
|
||||||
|
|
||||||
interface JKQualifiedExpression : JKExpression, JKAssignableExpression {
|
interface JKQualifiedExpression : JKExpression {
|
||||||
var receiver: JKExpression
|
var receiver: JKExpression
|
||||||
var operator: JKQualifier
|
var operator: JKQualifier
|
||||||
var selector: JKExpression
|
var selector: JKExpression
|
||||||
@@ -334,11 +334,11 @@ interface JKMethodCallExpression : JKExpression, JKTypeArgumentListOwner, JKBran
|
|||||||
var arguments: JKArgumentList
|
var arguments: JKArgumentList
|
||||||
}
|
}
|
||||||
|
|
||||||
interface JKFieldAccessExpression : JKAssignableExpression {
|
interface JKFieldAccessExpression : JKExpression {
|
||||||
val identifier: JKFieldSymbol
|
val identifier: JKFieldSymbol
|
||||||
}
|
}
|
||||||
|
|
||||||
interface JKPackageAccessExpression : JKAssignableExpression {
|
interface JKPackageAccessExpression : JKExpression {
|
||||||
val identifier: JKPackageSymbol
|
val identifier: JKPackageSymbol
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -346,7 +346,7 @@ interface JKClassAccessExpression : JKExpression {
|
|||||||
val identifier: JKClassSymbol
|
val identifier: JKClassSymbol
|
||||||
}
|
}
|
||||||
|
|
||||||
interface JKArrayAccessExpression : JKAssignableExpression {
|
interface JKArrayAccessExpression : JKExpression {
|
||||||
var expression: JKExpression
|
var expression: JKExpression
|
||||||
var indexExpression: JKExpression
|
var indexExpression: JKExpression
|
||||||
}
|
}
|
||||||
@@ -447,8 +447,6 @@ interface JKIfElseExpression : JKExpression {
|
|||||||
var elseBranch: JKExpression
|
var elseBranch: JKExpression
|
||||||
}
|
}
|
||||||
|
|
||||||
interface JKAssignableExpression : JKExpression
|
|
||||||
|
|
||||||
interface JKLambdaExpression : JKExpression {
|
interface JKLambdaExpression : JKExpression {
|
||||||
var parameters: List<JKParameter>
|
var parameters: List<JKParameter>
|
||||||
val returnType: JKTypeElement
|
val returnType: JKTypeElement
|
||||||
|
|||||||
@@ -95,7 +95,7 @@ interface JKJavaPolyadicExpression : JKExpression {
|
|||||||
}
|
}
|
||||||
|
|
||||||
interface JKJavaAssignmentExpression : JKExpression, JKBranchElement {
|
interface JKJavaAssignmentExpression : JKExpression, JKBranchElement {
|
||||||
var field: JKAssignableExpression
|
var field: JKExpression
|
||||||
var expression: JKExpression
|
var expression: JKExpression
|
||||||
var operator: JKOperator
|
var operator: JKOperator
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -42,19 +42,24 @@ abstract class JKKtConstructor : JKMethod(), JKOtherModifiersOwner {
|
|||||||
abstract class JKKtPrimaryConstructor : JKKtConstructor()
|
abstract class JKKtPrimaryConstructor : JKKtConstructor()
|
||||||
|
|
||||||
abstract class JKKtAssignmentStatement : JKStatement() {
|
abstract class JKKtAssignmentStatement : JKStatement() {
|
||||||
abstract var field: JKAssignableExpression
|
abstract var field: JKExpression
|
||||||
abstract var expression: JKExpression
|
abstract var expression: JKExpression
|
||||||
abstract var operator: JKOperator
|
abstract var token: JKOperatorToken
|
||||||
}
|
}
|
||||||
|
|
||||||
interface JKKtCall : JKMethodCallExpression
|
interface JKKtCall : JKMethodCallExpression
|
||||||
|
|
||||||
interface JKKtMethodCallExpression : JKMethodCallExpression
|
interface JKKtMethodCallExpression : JKMethodCallExpression
|
||||||
|
|
||||||
interface JKKtAlsoCallExpression : JKKtMethodCallExpression {
|
interface JKKtAssignmentChainLink : JKExpression {
|
||||||
var statement: JKStatement
|
val receiver: JKExpression
|
||||||
|
val assignmentStatement: JKKtAssignmentStatement
|
||||||
|
val field: JKExpression
|
||||||
}
|
}
|
||||||
|
|
||||||
|
interface JKAssignmentChainAlsoLink : JKKtAssignmentChainLink
|
||||||
|
interface JKAssignmentChainLetLink : JKKtAssignmentChainLink
|
||||||
|
|
||||||
interface JKKtLiteralExpression : JKLiteralExpression
|
interface JKKtLiteralExpression : JKLiteralExpression
|
||||||
|
|
||||||
abstract class JKKtWhenStatement : JKStatement() {
|
abstract class JKKtWhenStatement : JKStatement() {
|
||||||
@@ -108,4 +113,8 @@ interface JKKtTryCatchSection : JKTreeElement {
|
|||||||
|
|
||||||
interface JKKtAnnotationArrayInitializerExpression : JKExpression, JKBranchElement {
|
interface JKKtAnnotationArrayInitializerExpression : JKExpression, JKBranchElement {
|
||||||
val initializers: List<JKAnnotationMemberValue>
|
val initializers: List<JKAnnotationMemberValue>
|
||||||
|
}
|
||||||
|
|
||||||
|
interface JKKtItExpression : JKExpression {
|
||||||
|
val type: JKType
|
||||||
}
|
}
|
||||||
@@ -53,6 +53,14 @@ fun JKTreeElement.commentsFromInside(): List<JKCommentElement> {
|
|||||||
inline fun <reified T : JKNonCodeElementsListOwner> T.withNonCodeElementsFrom(other: JKNonCodeElementsListOwner): T =
|
inline fun <reified T : JKNonCodeElementsListOwner> T.withNonCodeElementsFrom(other: JKNonCodeElementsListOwner): T =
|
||||||
also { it.takeNonCodeElementsFrom(other) }
|
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() {
|
fun JKNonCodeElementsListOwner.clearNonCodeElements() {
|
||||||
leftNonCodeElements = emptyList()
|
leftNonCodeElements = emptyList()
|
||||||
rightNonCodeElements = emptyList()
|
rightNonCodeElements = emptyList()
|
||||||
|
|||||||
@@ -11,16 +11,11 @@ import com.intellij.psi.PsiClassType
|
|||||||
import com.intellij.psi.PsiType
|
import com.intellij.psi.PsiType
|
||||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
||||||
import org.jetbrains.kotlin.builtins.PrimitiveType
|
import org.jetbrains.kotlin.builtins.PrimitiveType
|
||||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
|
||||||
import org.jetbrains.kotlin.idea.caches.resolve.analyze
|
import org.jetbrains.kotlin.idea.caches.resolve.analyze
|
||||||
import org.jetbrains.kotlin.idea.caches.resolve.util.getJavaClassDescriptor
|
|
||||||
import org.jetbrains.kotlin.idea.refactoring.fqName.getKotlinFqName
|
import org.jetbrains.kotlin.idea.refactoring.fqName.getKotlinFqName
|
||||||
import org.jetbrains.kotlin.j2k.ast.Nullability
|
import org.jetbrains.kotlin.j2k.ast.Nullability
|
||||||
import org.jetbrains.kotlin.nj2k.JKSymbolProvider
|
import org.jetbrains.kotlin.nj2k.JKSymbolProvider
|
||||||
import org.jetbrains.kotlin.nj2k.symbols.JKClassSymbol
|
import org.jetbrains.kotlin.nj2k.symbols.JKClassSymbol
|
||||||
import org.jetbrains.kotlin.nj2k.symbols.JKMultiverseClassSymbol
|
|
||||||
import org.jetbrains.kotlin.nj2k.symbols.JKMultiverseKtClassSymbol
|
|
||||||
import org.jetbrains.kotlin.nj2k.symbols.JKUniverseClassSymbol
|
|
||||||
import org.jetbrains.kotlin.nj2k.tree.impl.*
|
import org.jetbrains.kotlin.nj2k.tree.impl.*
|
||||||
import org.jetbrains.kotlin.nj2k.types.*
|
import org.jetbrains.kotlin.nj2k.types.*
|
||||||
import org.jetbrains.kotlin.psi.KtClass
|
import org.jetbrains.kotlin.psi.KtClass
|
||||||
@@ -28,8 +23,6 @@ import org.jetbrains.kotlin.psi.KtTypeReference
|
|||||||
import org.jetbrains.kotlin.resolve.BindingContext
|
import org.jetbrains.kotlin.resolve.BindingContext
|
||||||
import org.jetbrains.kotlin.resolve.jvm.JvmPrimitiveType
|
import org.jetbrains.kotlin.resolve.jvm.JvmPrimitiveType
|
||||||
import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
|
import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
|
||||||
import org.jetbrains.kotlin.types.KotlinType
|
|
||||||
import org.jetbrains.kotlin.types.typeUtil.isSubtypeOf
|
|
||||||
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
||||||
|
|
||||||
fun JKExpression.type(typeFactory: JKTypeFactory): JKType? =
|
fun JKExpression.type(typeFactory: JKTypeFactory): JKType? =
|
||||||
@@ -73,6 +66,10 @@ fun JKExpression.type(typeFactory: JKTypeFactory): JKType? =
|
|||||||
is JKLabeledStatement ->
|
is JKLabeledStatement ->
|
||||||
statement.safeAs<JKExpressionStatement>()?.expression?.type(typeFactory)
|
statement.safeAs<JKExpressionStatement>()?.expression?.type(typeFactory)
|
||||||
is JKMethodReferenceExpression -> JKNoTypeImpl //TODO
|
is JKMethodReferenceExpression -> JKNoTypeImpl //TODO
|
||||||
|
is JKAssignmentChainAlsoLink -> receiver.type(typeFactory)
|
||||||
|
is JKAssignmentChainLetLink -> field.type(typeFactory)
|
||||||
|
is JKKtAssignmentStatement -> typeFactory.types.unit
|
||||||
|
is JKKtItExpression -> type
|
||||||
else -> TODO(this::class.java.toString())
|
else -> TODO(this::class.java.toString())
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -82,33 +79,20 @@ fun JKType.asTypeElement() =
|
|||||||
fun JKClassSymbol.asType(nullability: Nullability = Nullability.Default): JKClassType =
|
fun JKClassSymbol.asType(nullability: Nullability = Nullability.Default): JKClassType =
|
||||||
JKClassTypeImpl(this, emptyList(), nullability)
|
JKClassTypeImpl(this, emptyList(), nullability)
|
||||||
|
|
||||||
fun JKType.isSubtypeOf(other: JKType, typeFactory: JKTypeFactory): Boolean =
|
|
||||||
other.toKtType(typeFactory)
|
|
||||||
?.let { otherType -> this.toKtType(typeFactory)?.isSubtypeOf(otherType) } == true
|
|
||||||
|
|
||||||
|
|
||||||
val PsiType.isKotlinFunctionalType: Boolean
|
val PsiType.isKotlinFunctionalType: Boolean
|
||||||
get() {
|
get() {
|
||||||
val fqName = safeAs<PsiClassType>()?.resolve()?.getKotlinFqName() ?: return false
|
val fqName = safeAs<PsiClassType>()?.resolve()?.getKotlinFqName() ?: return false
|
||||||
return functionalTypeRegex.matches(fqName.asString())
|
return functionalTypeRegex.matches(fqName.asString())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private val functionalTypeRegex = """(kotlin\.jvm\.functions|kotlin)\.Function[\d+]""".toRegex()
|
private val functionalTypeRegex = """(kotlin\.jvm\.functions|kotlin)\.Function[\d+]""".toRegex()
|
||||||
|
|
||||||
|
|
||||||
fun KtTypeReference.toJK(typeFactory: JKTypeFactory): JKType? =
|
fun KtTypeReference.toJK(typeFactory: JKTypeFactory): JKType? =
|
||||||
analyze(BodyResolveMode.PARTIAL)
|
analyze(BodyResolveMode.PARTIAL)
|
||||||
.get(BindingContext.TYPE, this)
|
.get(BindingContext.TYPE, this)
|
||||||
?.let { typeFactory.fromKotlinType(it) }
|
?.let { typeFactory.fromKotlinType(it) }
|
||||||
|
|
||||||
|
|
||||||
fun JKType.toKtType(typeFactory: JKTypeFactory): KotlinType? = when (this) {
|
|
||||||
is JKClassType -> classReference.toKtType()
|
|
||||||
is JKJavaPrimitiveType -> typeFactory.fromPrimitiveType(this).toKtType(typeFactory)
|
|
||||||
else -> null
|
|
||||||
}
|
|
||||||
|
|
||||||
infix fun JKJavaPrimitiveType.isStrongerThan(other: JKJavaPrimitiveType) =
|
infix fun JKJavaPrimitiveType.isStrongerThan(other: JKJavaPrimitiveType) =
|
||||||
jvmPrimitiveTypesPriority.getValue(this.jvmPrimitiveType.primitiveType) >
|
jvmPrimitiveTypesPriority.getValue(this.jvmPrimitiveType.primitiveType) >
|
||||||
jvmPrimitiveTypesPriority.getValue(other.jvmPrimitiveType.primitiveType)
|
jvmPrimitiveTypesPriority.getValue(other.jvmPrimitiveType.primitiveType)
|
||||||
@@ -126,21 +110,6 @@ private val jvmPrimitiveTypesPriority =
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
fun JKClassSymbol.toKtType(): KotlinType? {
|
|
||||||
val classDescriptor = when (this) {
|
|
||||||
is JKMultiverseKtClassSymbol -> {
|
|
||||||
val bindingContext = target.analyze()
|
|
||||||
bindingContext[BindingContext.DECLARATION_TO_DESCRIPTOR, target] as ClassDescriptor
|
|
||||||
}
|
|
||||||
is JKMultiverseClassSymbol ->
|
|
||||||
target.getJavaClassDescriptor()
|
|
||||||
is JKUniverseClassSymbol ->
|
|
||||||
target.psi<PsiClass>()?.getJavaClassDescriptor()//TODO null in case of a fake package
|
|
||||||
else -> TODO(this::class.java.toString())
|
|
||||||
}
|
|
||||||
return classDescriptor?.defaultType
|
|
||||||
}
|
|
||||||
|
|
||||||
fun JKType.applyRecursive(transform: (JKType) -> JKType?): JKType =
|
fun JKType.applyRecursive(transform: (JKType) -> JKType?): JKType =
|
||||||
transform(this) ?: when (this) {
|
transform(this) ?: when (this) {
|
||||||
is JKTypeParameterTypeImpl -> this
|
is JKTypeParameterTypeImpl -> this
|
||||||
|
|||||||
@@ -75,7 +75,7 @@ abstract class JKVisitor {
|
|||||||
open fun visitIfStatement(ifStatement: JKIfStatement) = visitStatement(ifStatement)
|
open fun visitIfStatement(ifStatement: JKIfStatement) = visitStatement(ifStatement)
|
||||||
open fun visitIfElseStatement(ifElseStatement: JKIfElseStatement) = visitIfStatement(ifElseStatement)
|
open fun visitIfElseStatement(ifElseStatement: JKIfElseStatement) = visitIfStatement(ifElseStatement)
|
||||||
open fun visitIfElseExpression(ifElseExpression: JKIfElseExpression) = visitExpression(ifElseExpression)
|
open fun visitIfElseExpression(ifElseExpression: JKIfElseExpression) = visitExpression(ifElseExpression)
|
||||||
open fun visitAssignableExpression(assignableExpression: JKAssignableExpression) = visitExpression(assignableExpression)
|
open fun visitAssignableExpression(assignableExpression: JKExpression) = visitExpression(assignableExpression)
|
||||||
open fun visitLambdaExpression(lambdaExpression: JKLambdaExpression) = visitExpression(lambdaExpression)
|
open fun visitLambdaExpression(lambdaExpression: JKLambdaExpression) = visitExpression(lambdaExpression)
|
||||||
open fun visitDelegationConstructorCall(delegationConstructorCall: JKDelegationConstructorCall) = visitMethodCallExpression(delegationConstructorCall)
|
open fun visitDelegationConstructorCall(delegationConstructorCall: JKDelegationConstructorCall) = visitMethodCallExpression(delegationConstructorCall)
|
||||||
open fun visitLabel(label: JKLabel) = visitTreeElement(label)
|
open fun visitLabel(label: JKLabel) = visitTreeElement(label)
|
||||||
@@ -85,7 +85,7 @@ abstract class JKVisitor {
|
|||||||
open fun visitLabeledStatement(labeledStatement: JKLabeledStatement) = visitExpression(labeledStatement)
|
open fun visitLabeledStatement(labeledStatement: JKLabeledStatement) = visitExpression(labeledStatement)
|
||||||
open fun visitEmptyStatement(emptyStatement: JKEmptyStatement) = visitStatement(emptyStatement)
|
open fun visitEmptyStatement(emptyStatement: JKEmptyStatement) = visitStatement(emptyStatement)
|
||||||
open fun visitTypeParameterList(typeParameterList: JKTypeParameterList) = visitTreeElement(typeParameterList)
|
open fun visitTypeParameterList(typeParameterList: JKTypeParameterList) = visitTreeElement(typeParameterList)
|
||||||
open fun visitTypeParameter(typeParameter: JKTypeParameter) = visitTreeElement(typeParameter)
|
open fun visitTypeParameter(typeParameter: JKTypeParameter) = visitDeclaration(typeParameter)
|
||||||
open fun visitTypeParameterListOwner(typeParameterListOwner: JKTypeParameterListOwner) = visitTreeElement(typeParameterListOwner)
|
open fun visitTypeParameterListOwner(typeParameterListOwner: JKTypeParameterListOwner) = visitTreeElement(typeParameterListOwner)
|
||||||
open fun visitEnumConstant(enumConstant: JKEnumConstant) = visitVariable(enumConstant)
|
open fun visitEnumConstant(enumConstant: JKEnumConstant) = visitVariable(enumConstant)
|
||||||
open fun visitForInStatement(forInStatement: JKForInStatement) = visitStatement(forInStatement)
|
open fun visitForInStatement(forInStatement: JKForInStatement) = visitStatement(forInStatement)
|
||||||
@@ -128,7 +128,9 @@ abstract class JKVisitor {
|
|||||||
open fun visitKtAssignmentStatement(ktAssignmentStatement: JKKtAssignmentStatement) = visitStatement(ktAssignmentStatement)
|
open fun visitKtAssignmentStatement(ktAssignmentStatement: JKKtAssignmentStatement) = visitStatement(ktAssignmentStatement)
|
||||||
open fun visitKtCall(ktCall: JKKtCall) = visitMethodCallExpression(ktCall)
|
open fun visitKtCall(ktCall: JKKtCall) = visitMethodCallExpression(ktCall)
|
||||||
open fun visitKtMethodCallExpression(ktMethodCallExpression: JKKtMethodCallExpression) = visitMethodCallExpression(ktMethodCallExpression)
|
open fun visitKtMethodCallExpression(ktMethodCallExpression: JKKtMethodCallExpression) = visitMethodCallExpression(ktMethodCallExpression)
|
||||||
open fun visitKtAlsoCallExpression(ktAlsoCallExpression: JKKtAlsoCallExpression) = visitKtMethodCallExpression(ktAlsoCallExpression)
|
open fun visitKtAssignmentChainLink(ktAssignmentChainLink: JKKtAssignmentChainLink) = visitExpression(ktAssignmentChainLink)
|
||||||
|
open fun visitAssignmentChainAlsoLink(assignmentChainAlsoLink: JKAssignmentChainAlsoLink) = visitKtAssignmentChainLink(assignmentChainAlsoLink)
|
||||||
|
open fun visitAssignmentChainLetLink(assignmentChainLetLink: JKAssignmentChainLetLink) = visitKtAssignmentChainLink(assignmentChainLetLink)
|
||||||
open fun visitKtLiteralExpression(ktLiteralExpression: JKKtLiteralExpression) = visitLiteralExpression(ktLiteralExpression)
|
open fun visitKtLiteralExpression(ktLiteralExpression: JKKtLiteralExpression) = visitLiteralExpression(ktLiteralExpression)
|
||||||
open fun visitKtWhenStatement(ktWhenStatement: JKKtWhenStatement) = visitStatement(ktWhenStatement)
|
open fun visitKtWhenStatement(ktWhenStatement: JKKtWhenStatement) = visitStatement(ktWhenStatement)
|
||||||
open fun visitKtWhenCase(ktWhenCase: JKKtWhenCase) = visitTreeElement(ktWhenCase)
|
open fun visitKtWhenCase(ktWhenCase: JKKtWhenCase) = visitTreeElement(ktWhenCase)
|
||||||
@@ -142,4 +144,5 @@ abstract class JKVisitor {
|
|||||||
open fun visitKtTryExpression(ktTryExpression: JKKtTryExpression) = visitExpression(ktTryExpression)
|
open fun visitKtTryExpression(ktTryExpression: JKKtTryExpression) = visitExpression(ktTryExpression)
|
||||||
open fun visitKtTryCatchSection(ktTryCatchSection: JKKtTryCatchSection) = visitTreeElement(ktTryCatchSection)
|
open fun visitKtTryCatchSection(ktTryCatchSection: JKKtTryCatchSection) = visitTreeElement(ktTryCatchSection)
|
||||||
open fun visitKtAnnotationArrayInitializerExpression(ktAnnotationArrayInitializerExpression: JKKtAnnotationArrayInitializerExpression) = visitExpression(ktAnnotationArrayInitializerExpression)
|
open fun visitKtAnnotationArrayInitializerExpression(ktAnnotationArrayInitializerExpression: JKKtAnnotationArrayInitializerExpression) = visitExpression(ktAnnotationArrayInitializerExpression)
|
||||||
|
open fun visitKtItExpression(ktItExpression: JKKtItExpression) = visitExpression(ktItExpression)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -582,13 +582,13 @@ abstract class JKVisitorWithCommentsPrinting : JKVisitor() {
|
|||||||
|
|
||||||
open fun visitIfElseExpressionRaw(ifElseExpression: JKIfElseExpression) = visitExpressionRaw(ifElseExpression)
|
open fun visitIfElseExpressionRaw(ifElseExpression: JKIfElseExpression) = visitExpressionRaw(ifElseExpression)
|
||||||
|
|
||||||
override fun visitAssignableExpression(assignableExpression: JKAssignableExpression) {
|
override fun visitAssignableExpression(assignableExpression: JKExpression) {
|
||||||
printLeftNonCodeElements(assignableExpression)
|
printLeftNonCodeElements(assignableExpression)
|
||||||
visitAssignableExpressionRaw(assignableExpression)
|
visitAssignableExpressionRaw(assignableExpression)
|
||||||
printRightNonCodeElements(assignableExpression)
|
printRightNonCodeElements(assignableExpression)
|
||||||
}
|
}
|
||||||
|
|
||||||
open fun visitAssignableExpressionRaw(assignableExpression: JKAssignableExpression) = visitExpressionRaw(assignableExpression)
|
open fun visitAssignableExpressionRaw(assignableExpression: JKExpression) = visitExpressionRaw(assignableExpression)
|
||||||
|
|
||||||
override fun visitLambdaExpression(lambdaExpression: JKLambdaExpression) {
|
override fun visitLambdaExpression(lambdaExpression: JKLambdaExpression) {
|
||||||
printLeftNonCodeElements(lambdaExpression)
|
printLeftNonCodeElements(lambdaExpression)
|
||||||
@@ -668,7 +668,7 @@ abstract class JKVisitorWithCommentsPrinting : JKVisitor() {
|
|||||||
printRightNonCodeElements(typeParameter)
|
printRightNonCodeElements(typeParameter)
|
||||||
}
|
}
|
||||||
|
|
||||||
open fun visitTypeParameterRaw(typeParameter: JKTypeParameter) = visitTreeElementRaw(typeParameter)
|
open fun visitTypeParameterRaw(typeParameter: JKTypeParameter) = visitDeclarationRaw(typeParameter)
|
||||||
|
|
||||||
override fun visitTypeParameterListOwner(typeParameterListOwner: JKTypeParameterListOwner) {
|
override fun visitTypeParameterListOwner(typeParameterListOwner: JKTypeParameterListOwner) {
|
||||||
printLeftNonCodeElements(typeParameterListOwner)
|
printLeftNonCodeElements(typeParameterListOwner)
|
||||||
@@ -1006,13 +1006,29 @@ abstract class JKVisitorWithCommentsPrinting : JKVisitor() {
|
|||||||
|
|
||||||
open fun visitKtMethodCallExpressionRaw(ktMethodCallExpression: JKKtMethodCallExpression) = visitMethodCallExpressionRaw(ktMethodCallExpression)
|
open fun visitKtMethodCallExpressionRaw(ktMethodCallExpression: JKKtMethodCallExpression) = visitMethodCallExpressionRaw(ktMethodCallExpression)
|
||||||
|
|
||||||
override fun visitKtAlsoCallExpression(ktAlsoCallExpression: JKKtAlsoCallExpression) {
|
override fun visitKtAssignmentChainLink(ktAssignmentChainLink: JKKtAssignmentChainLink) {
|
||||||
printLeftNonCodeElements(ktAlsoCallExpression)
|
printLeftNonCodeElements(ktAssignmentChainLink)
|
||||||
visitKtAlsoCallExpressionRaw(ktAlsoCallExpression)
|
visitKtAssignmentChainLinkRaw(ktAssignmentChainLink)
|
||||||
printRightNonCodeElements(ktAlsoCallExpression)
|
printRightNonCodeElements(ktAssignmentChainLink)
|
||||||
}
|
}
|
||||||
|
|
||||||
open fun visitKtAlsoCallExpressionRaw(ktAlsoCallExpression: JKKtAlsoCallExpression) = visitKtMethodCallExpressionRaw(ktAlsoCallExpression)
|
open fun visitKtAssignmentChainLinkRaw(ktAssignmentChainLink: JKKtAssignmentChainLink) = visitExpressionRaw(ktAssignmentChainLink)
|
||||||
|
|
||||||
|
override fun visitAssignmentChainAlsoLink(assignmentChainAlsoLink: JKAssignmentChainAlsoLink) {
|
||||||
|
printLeftNonCodeElements(assignmentChainAlsoLink)
|
||||||
|
visitAssignmentChainAlsoLinkRaw(assignmentChainAlsoLink)
|
||||||
|
printRightNonCodeElements(assignmentChainAlsoLink)
|
||||||
|
}
|
||||||
|
|
||||||
|
open fun visitAssignmentChainAlsoLinkRaw(assignmentChainAlsoLink: JKAssignmentChainAlsoLink) = visitKtAssignmentChainLinkRaw(assignmentChainAlsoLink)
|
||||||
|
|
||||||
|
override fun visitAssignmentChainLetLink(assignmentChainLetLink: JKAssignmentChainLetLink) {
|
||||||
|
printLeftNonCodeElements(assignmentChainLetLink)
|
||||||
|
visitAssignmentChainLetLinkRaw(assignmentChainLetLink)
|
||||||
|
printRightNonCodeElements(assignmentChainLetLink)
|
||||||
|
}
|
||||||
|
|
||||||
|
open fun visitAssignmentChainLetLinkRaw(assignmentChainLetLink: JKAssignmentChainLetLink) = visitKtAssignmentChainLinkRaw(assignmentChainLetLink)
|
||||||
|
|
||||||
override fun visitKtLiteralExpression(ktLiteralExpression: JKKtLiteralExpression) {
|
override fun visitKtLiteralExpression(ktLiteralExpression: JKKtLiteralExpression) {
|
||||||
printLeftNonCodeElements(ktLiteralExpression)
|
printLeftNonCodeElements(ktLiteralExpression)
|
||||||
@@ -1117,4 +1133,12 @@ abstract class JKVisitorWithCommentsPrinting : JKVisitor() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
open fun visitKtAnnotationArrayInitializerExpressionRaw(ktAnnotationArrayInitializerExpression: JKKtAnnotationArrayInitializerExpression) = visitExpressionRaw(ktAnnotationArrayInitializerExpression)
|
open fun visitKtAnnotationArrayInitializerExpressionRaw(ktAnnotationArrayInitializerExpression: JKKtAnnotationArrayInitializerExpression) = visitExpressionRaw(ktAnnotationArrayInitializerExpression)
|
||||||
|
|
||||||
|
override fun visitKtItExpression(ktItExpression: JKKtItExpression) {
|
||||||
|
printLeftNonCodeElements(ktItExpression)
|
||||||
|
visitKtItExpressionRaw(ktItExpression)
|
||||||
|
printRightNonCodeElements(ktItExpression)
|
||||||
|
}
|
||||||
|
|
||||||
|
open fun visitKtItExpressionRaw(ktItExpression: JKKtItExpression) = visitExpressionRaw(ktItExpression)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,11 +11,15 @@ import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor
|
|||||||
import org.jetbrains.kotlin.j2k.ast.Nullability
|
import org.jetbrains.kotlin.j2k.ast.Nullability
|
||||||
import org.jetbrains.kotlin.js.descriptorUtils.getJetTypeFqName
|
import org.jetbrains.kotlin.js.descriptorUtils.getJetTypeFqName
|
||||||
import org.jetbrains.kotlin.js.resolve.diagnostics.findPsi
|
import org.jetbrains.kotlin.js.resolve.diagnostics.findPsi
|
||||||
|
import org.jetbrains.kotlin.name.FqName
|
||||||
import org.jetbrains.kotlin.name.FqNameUnsafe
|
import org.jetbrains.kotlin.name.FqNameUnsafe
|
||||||
import org.jetbrains.kotlin.nj2k.JKSymbolProvider
|
import org.jetbrains.kotlin.nj2k.JKSymbolProvider
|
||||||
import org.jetbrains.kotlin.nj2k.symbols.JKClassSymbol
|
import org.jetbrains.kotlin.nj2k.symbols.JKClassSymbol
|
||||||
import org.jetbrains.kotlin.nj2k.symbols.JKTypeParameterSymbol
|
import org.jetbrains.kotlin.nj2k.symbols.JKTypeParameterSymbol
|
||||||
import org.jetbrains.kotlin.nj2k.symbols.JKUnresolvedClassSymbol
|
import org.jetbrains.kotlin.nj2k.symbols.JKUnresolvedClassSymbol
|
||||||
|
import org.jetbrains.kotlin.nj2k.tree.JKClass
|
||||||
|
import org.jetbrains.kotlin.nj2k.tree.JKType
|
||||||
|
import org.jetbrains.kotlin.nj2k.tree.impl.*
|
||||||
import org.jetbrains.kotlin.psi.KtTypeParameter
|
import org.jetbrains.kotlin.psi.KtTypeParameter
|
||||||
import org.jetbrains.kotlin.resolve.jvm.JvmPrimitiveType
|
import org.jetbrains.kotlin.resolve.jvm.JvmPrimitiveType
|
||||||
import org.jetbrains.kotlin.types.KotlinType
|
import org.jetbrains.kotlin.types.KotlinType
|
||||||
|
|||||||
@@ -0,0 +1,19 @@
|
|||||||
|
class Test {
|
||||||
|
public static void main(String[] args) {
|
||||||
|
int a = 0;
|
||||||
|
int b = 0;
|
||||||
|
int c = 0;
|
||||||
|
int d = 0;
|
||||||
|
int e = 0;
|
||||||
|
|
||||||
|
a = b += c = d *= e;
|
||||||
|
//-----
|
||||||
|
a = b;
|
||||||
|
//-----
|
||||||
|
a += b;
|
||||||
|
//-----
|
||||||
|
a += b = c;
|
||||||
|
//-----
|
||||||
|
a = b += c;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,32 @@
|
|||||||
|
internal object Test {
|
||||||
|
@JvmStatic
|
||||||
|
fun main(args: Array<String>) {
|
||||||
|
var a = 0
|
||||||
|
var b = 0
|
||||||
|
var c = 0
|
||||||
|
var d = 0
|
||||||
|
val e = 0
|
||||||
|
d *= e
|
||||||
|
c = d
|
||||||
|
b += c
|
||||||
|
a = b
|
||||||
|
//-----
|
||||||
|
|
||||||
|
|
||||||
|
a = b
|
||||||
|
//-----
|
||||||
|
|
||||||
|
|
||||||
|
a += b
|
||||||
|
//-----
|
||||||
|
|
||||||
|
|
||||||
|
b = c
|
||||||
|
a += b
|
||||||
|
//-----
|
||||||
|
|
||||||
|
|
||||||
|
b += c
|
||||||
|
a = b
|
||||||
|
}
|
||||||
|
}
|
||||||
+19
@@ -0,0 +1,19 @@
|
|||||||
|
class Test {
|
||||||
|
public static void main(String[] args) {
|
||||||
|
int a = 0;
|
||||||
|
int b = 0;
|
||||||
|
int c = 0;
|
||||||
|
int d = 0;
|
||||||
|
int e = 0;
|
||||||
|
|
||||||
|
a = b += (c) = ((d *= e));
|
||||||
|
//-----
|
||||||
|
a = (((b)));
|
||||||
|
//-----
|
||||||
|
a += (b);
|
||||||
|
//-----
|
||||||
|
a += b = (c);
|
||||||
|
//-----
|
||||||
|
a = ((b) += (c));
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,30 @@
|
|||||||
|
internal object Test {
|
||||||
|
@JvmStatic
|
||||||
|
fun main(args: Array<String>) {
|
||||||
|
var a = 0
|
||||||
|
var b = 0
|
||||||
|
var c = 0
|
||||||
|
var d = 0
|
||||||
|
val e = 0
|
||||||
|
c = e.let { d *= it; d }
|
||||||
|
b += c
|
||||||
|
a = b
|
||||||
|
//-----
|
||||||
|
|
||||||
|
|
||||||
|
a = b
|
||||||
|
//-----
|
||||||
|
|
||||||
|
|
||||||
|
a += b
|
||||||
|
//-----
|
||||||
|
|
||||||
|
|
||||||
|
b = c
|
||||||
|
a += b
|
||||||
|
//-----
|
||||||
|
|
||||||
|
|
||||||
|
a = c.let { b += it; b }
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1 +1 @@
|
|||||||
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*/
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
class Test {
|
||||||
|
public static void main(String[] args) {
|
||||||
|
int a = 0;
|
||||||
|
int b = 0;
|
||||||
|
int c = 0;
|
||||||
|
int d = 0;
|
||||||
|
int e = 0;
|
||||||
|
//-----
|
||||||
|
int f = a = b += c = d *= e;
|
||||||
|
//-----
|
||||||
|
int g = a;
|
||||||
|
//-----
|
||||||
|
int h = a = b;
|
||||||
|
//-----
|
||||||
|
int i = a += b;
|
||||||
|
//-----
|
||||||
|
int j = a += b = c;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,35 @@
|
|||||||
|
internal object Test {
|
||||||
|
@JvmStatic
|
||||||
|
fun main(args: Array<String>) {
|
||||||
|
var a = 0
|
||||||
|
var b = 0
|
||||||
|
var c = 0
|
||||||
|
var d = 0
|
||||||
|
val e = 0
|
||||||
|
//-----
|
||||||
|
|
||||||
|
d *= e
|
||||||
|
c = d
|
||||||
|
b += c
|
||||||
|
a = b
|
||||||
|
val f = a
|
||||||
|
//-----
|
||||||
|
val g = a
|
||||||
|
//-----
|
||||||
|
|
||||||
|
|
||||||
|
a = b
|
||||||
|
val h = a
|
||||||
|
//-----
|
||||||
|
|
||||||
|
|
||||||
|
a += b
|
||||||
|
val i = a
|
||||||
|
//-----
|
||||||
|
|
||||||
|
|
||||||
|
b = c
|
||||||
|
a += b
|
||||||
|
val j = a
|
||||||
|
}
|
||||||
|
}
|
||||||
+14
@@ -0,0 +1,14 @@
|
|||||||
|
class Test {
|
||||||
|
public static void main(String[] args) {
|
||||||
|
boolean a = true;
|
||||||
|
boolean b = true;
|
||||||
|
boolean c = true;
|
||||||
|
boolean d = true;
|
||||||
|
boolean e = true;
|
||||||
|
|
||||||
|
if (a = b |= (c) = ((d &= e))) ;
|
||||||
|
while ((((((a = b)))))) ;
|
||||||
|
do {
|
||||||
|
} while ((((a) ^= (b))));
|
||||||
|
}
|
||||||
|
}
|
||||||
+14
@@ -0,0 +1,14 @@
|
|||||||
|
internal object Test {
|
||||||
|
@JvmStatic
|
||||||
|
fun main(args: Array<String>) {
|
||||||
|
var a = true
|
||||||
|
var b = true
|
||||||
|
var c = true
|
||||||
|
var d = true
|
||||||
|
val e = true
|
||||||
|
if (e.let { d = d and it; d }.also { c = it }.let { b = b or it; b }.also { a = it });
|
||||||
|
while (b.also { a = it });
|
||||||
|
do {
|
||||||
|
} while (b.let { a = a xor it; a })
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
class Test {
|
||||||
|
public static void main(String[] args) {
|
||||||
|
boolean a = true;
|
||||||
|
boolean b = true;
|
||||||
|
boolean c = true;
|
||||||
|
boolean d = true;
|
||||||
|
boolean e = true;
|
||||||
|
|
||||||
|
if (a = b |= c = d &= e) ;
|
||||||
|
while (a = b) ;
|
||||||
|
do {} while (a ^= b);
|
||||||
|
System.out.println(a &= b = c);
|
||||||
|
System.out.println(a = b != c);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
internal object Test {
|
||||||
|
@JvmStatic
|
||||||
|
fun main(args: Array<String>) {
|
||||||
|
var a = true
|
||||||
|
var b = true
|
||||||
|
var c = true
|
||||||
|
var d = true
|
||||||
|
val e = true
|
||||||
|
if (e.let { d = d and it; d }.also { c = it }.let { b = b or it; b }.also { a = it });
|
||||||
|
while (b.also { a = it });
|
||||||
|
do {
|
||||||
|
} while (b.let { a = a xor it; a })
|
||||||
|
println(c.also { b = it }.let { a = a and it; a })
|
||||||
|
println(b != c.also { a = it })
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1 +1,3 @@
|
|||||||
class Nya /*comment before*/(/*1*//*3*/ /*4*/private val i: Int)
|
class Nya /*comment before*/
|
||||||
|
/* comment after*/ // and after again
|
||||||
|
(/*1*//*3*/ /*4*/private val i: Int)
|
||||||
+1
-1
@@ -2,6 +2,6 @@ import java.util.stream.Collectors
|
|||||||
|
|
||||||
internal class JavaCode {
|
internal class JavaCode {
|
||||||
fun toJSON(collection: Collection<Int>): String {
|
fun toJSON(collection: Collection<Int>): String {
|
||||||
return "[" + collection.stream().map { obj: Int -> obj.toString() }.collect(Collectors.joining(", ")).toString() + "]"
|
return "[" + collection.stream().map { obj: Int -> obj.toString() }.collect(Collectors.joining(", ")) + "]"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,6 +1,5 @@
|
|||||||
class CharToString {
|
class CharToString {
|
||||||
private val value: String? = null
|
private val value: String? = null
|
||||||
|
|
||||||
fun test(): String {
|
fun test(): String {
|
||||||
return '"'.toString() + value + '"'
|
return '"'.toString() + value + '"'
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,17 +0,0 @@
|
|||||||
import java.util.Iterator;
|
|
||||||
|
|
||||||
public class TestMutableIterator implements Iterator<String> {
|
|
||||||
@Override
|
|
||||||
public boolean hasNext() {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String next() {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void remove() {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
import java.util.ArrayList
|
import java.util.ArrayList
|
||||||
|
|
||||||
class Test {
|
class Test {
|
||||||
internal var list: List<List<Int>> = ArrayList()
|
internal var list: List<MutableList<Int>> = ArrayList()
|
||||||
fun test() {
|
fun test() {
|
||||||
list[0].add(1)
|
list[0].add(1)
|
||||||
}
|
}
|
||||||
|
|||||||
+25
@@ -412,6 +412,16 @@ public class NewJavaToKotlinConverterSingleFileTestGenerated extends AbstractNew
|
|||||||
runTest("nj2k/testData/newJ2k/assignmentExpression/assignmentAsExpression.java");
|
runTest("nj2k/testData/newJ2k/assignmentExpression/assignmentAsExpression.java");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("assignmentsChain.java")
|
||||||
|
public void testAssignmentsChain() throws Exception {
|
||||||
|
runTest("nj2k/testData/newJ2k/assignmentExpression/assignmentsChain.java");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("assignmentsChainWithParenthesis.java")
|
||||||
|
public void testAssignmentsChainWithParenthesis() throws Exception {
|
||||||
|
runTest("nj2k/testData/newJ2k/assignmentExpression/assignmentsChainWithParenthesis.java");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("bitOperationPriority.java")
|
@TestMetadata("bitOperationPriority.java")
|
||||||
public void testBitOperationPriority() throws Exception {
|
public void testBitOperationPriority() throws Exception {
|
||||||
runTest("nj2k/testData/newJ2k/assignmentExpression/bitOperationPriority.java");
|
runTest("nj2k/testData/newJ2k/assignmentExpression/bitOperationPriority.java");
|
||||||
@@ -422,11 +432,26 @@ public class NewJavaToKotlinConverterSingleFileTestGenerated extends AbstractNew
|
|||||||
runTest("nj2k/testData/newJ2k/assignmentExpression/bitOperationPriorityComments.java");
|
runTest("nj2k/testData/newJ2k/assignmentExpression/bitOperationPriorityComments.java");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("declarationAssignmentsChain.java")
|
||||||
|
public void testDeclarationAssignmentsChain() throws Exception {
|
||||||
|
runTest("nj2k/testData/newJ2k/assignmentExpression/declarationAssignmentsChain.java");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("divideAssign.java")
|
@TestMetadata("divideAssign.java")
|
||||||
public void testDivideAssign() throws Exception {
|
public void testDivideAssign() throws Exception {
|
||||||
runTest("nj2k/testData/newJ2k/assignmentExpression/divideAssign.java");
|
runTest("nj2k/testData/newJ2k/assignmentExpression/divideAssign.java");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("expressionAssignmentWithParentheses.java")
|
||||||
|
public void testExpressionAssignmentWithParentheses() throws Exception {
|
||||||
|
runTest("nj2k/testData/newJ2k/assignmentExpression/expressionAssignmentWithParentheses.java");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("inExpressionAssignmentsChain.java")
|
||||||
|
public void testInExpressionAssignmentsChain() throws Exception {
|
||||||
|
runTest("nj2k/testData/newJ2k/assignmentExpression/inExpressionAssignmentsChain.java");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("minusAssign.java")
|
@TestMetadata("minusAssign.java")
|
||||||
public void testMinusAssign() throws Exception {
|
public void testMinusAssign() throws Exception {
|
||||||
runTest("nj2k/testData/newJ2k/assignmentExpression/minusAssign.java");
|
runTest("nj2k/testData/newJ2k/assignmentExpression/minusAssign.java");
|
||||||
|
|||||||
Reference in New Issue
Block a user