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),
|
||||
ReturnStatementInLambdaExpressionConversion(context),
|
||||
BoxedTypeOperationsConversion(context),
|
||||
AssignmentAsExpressionToAlsoConversion(context),
|
||||
AssignmentStatementValCreationConversion(context),
|
||||
AssignmentStatementOperatorConversion(context),
|
||||
AssignmentStatementSimplifyValConversion(context),
|
||||
AssignmentStatementSimplifyAlsoConversion(context),
|
||||
AssignmentStatementSplitAlsoConversion(context),
|
||||
PolyadicExpressionConversion(context),
|
||||
OperatorExpressionConversion(context),
|
||||
AnyWithStringConcatenationConversion(context),
|
||||
AssignmentExpressionUnfoldingConversion(context),
|
||||
AddParenthesisForLineBreaksInBinaryExpression(context),
|
||||
ThrowStatementConversion(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.impl.source.tree.ChildRole
|
||||
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.PsiLabeledStatementImpl
|
||||
import com.intellij.psi.impl.source.tree.java.PsiLiteralExpressionImpl
|
||||
@@ -138,14 +139,17 @@ class JavaToJKTreeBuilder constructor(
|
||||
is PsiConditionalExpression -> JKIfElseExpressionImpl(
|
||||
condition.toJK(), thenExpression.toJK(), elseExpression.toJK()
|
||||
)
|
||||
is PsiPolyadicExpression -> JKJavaPolyadicExpressionImpl(
|
||||
operands.map { it.toJK() },
|
||||
Array(operands.lastIndex) { index ->
|
||||
getTokenBeforeOperand(operands[index + 1])
|
||||
}.map {
|
||||
it?.tokenType?.toJK() ?: throwCanNotConvertError()
|
||||
is PsiPolyadicExpression -> {
|
||||
val token = JKOperatorToken.fromElementType(operationTokenType)
|
||||
val type = type?.toJK() ?: typeFactory.types.nullableAny
|
||||
val jkOperands = operands.map { it.toJK().parenthesizeIfBinaryExpression() }
|
||||
jkOperands.reduce { acc, operand ->
|
||||
JKBinaryExpressionImpl(acc, operand, JKKtOperatorImpl(token, type))
|
||||
}.let { folded ->
|
||||
if (jkOperands.any { it.containsNewLine() }) folded.parenthesize()
|
||||
else folded
|
||||
}
|
||||
)
|
||||
}
|
||||
is PsiArrayInitializerExpression -> toJK()
|
||||
is PsiLambdaExpression -> toJK()
|
||||
is PsiClassObjectAccessExpressionImpl -> toJK()
|
||||
@@ -180,9 +184,9 @@ class JavaToJKTreeBuilder constructor(
|
||||
|
||||
fun PsiAssignmentExpression.toJK(): JKJavaAssignmentExpression {
|
||||
return JKJavaAssignmentExpressionImpl(
|
||||
lExpression.toJK() as JKAssignableExpression,
|
||||
lExpression.toJK(),
|
||||
rExpression.toJK(),
|
||||
operationSign.tokenType.toJK()
|
||||
createOperator(operationSign.tokenType, type)
|
||||
).also {
|
||||
it.assignNonCodeElements(this)
|
||||
}
|
||||
@@ -192,16 +196,22 @@ class JavaToJKTreeBuilder constructor(
|
||||
val token = when (operationSign.tokenType) {
|
||||
JavaTokenType.EQEQ, JavaTokenType.NE ->
|
||||
when {
|
||||
canKeepEqEq(lOperand, rOperand) -> operationSign.tokenType
|
||||
operationSign.tokenType == JavaTokenType.EQEQ -> KtTokens.EQEQEQ
|
||||
else -> KtTokens.EXCLEQEQEQ
|
||||
canKeepEqEq(lOperand, rOperand) -> JKOperatorToken.fromElementType(operationSign.tokenType)
|
||||
operationSign.tokenType == JavaTokenType.EQEQ -> JKOperatorToken.fromElementType(KtTokens.EQEQEQ)
|
||||
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 {
|
||||
@@ -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 {
|
||||
return JKPrefixExpressionImpl(operand.toJK(), operationSign.tokenType.toJK()).also {
|
||||
it.assignNonCodeElements(this)
|
||||
}
|
||||
fun PsiPrefixExpression.toJK(): JKExpression = when (operationSign.tokenType) {
|
||||
JavaTokenType.TILDE -> operand.toJK().callOn(symbolProvider.provideMethodSymbol("kotlin.Int.inv"))
|
||||
else -> JKPrefixExpressionImpl(operand.toJK(), createOperator(operationSign.tokenType, type))
|
||||
}.also {
|
||||
it.assignNonCodeElements(this)
|
||||
}
|
||||
|
||||
fun PsiPostfixExpression.toJK(): JKExpression {
|
||||
return JKPostfixExpressionImpl(operand.toJK(), operationSign.tokenType.toJK()).also {
|
||||
fun PsiPostfixExpression.toJK(): JKExpression =
|
||||
JKPostfixExpressionImpl(operand.toJK(), createOperator(operationSign.tokenType, type)).also {
|
||||
it.assignNonCodeElements(this)
|
||||
}
|
||||
}
|
||||
|
||||
fun PsiLambdaExpression.toJK(): JKExpression {
|
||||
return JKLambdaExpressionImpl(
|
||||
@@ -326,7 +340,7 @@ class JavaToJKTreeBuilder constructor(
|
||||
propertyAccessExpression
|
||||
)
|
||||
else propertyAccessExpression
|
||||
} else propertyAccessExpression.qualified(qualifier) as JKAssignableExpression
|
||||
} else propertyAccessExpression.qualified(qualifier) as JKExpression
|
||||
|
||||
when (if (isExtension) parameterCount - 1 else parameterCount) {
|
||||
0 /* getter */ ->
|
||||
@@ -337,7 +351,7 @@ class JavaToJKTreeBuilder constructor(
|
||||
JKJavaAssignmentExpressionImpl(
|
||||
propertyAccess,
|
||||
argument,
|
||||
JKJavaOperatorImpl.tokenToOperator[JavaTokenType.EQ]!!
|
||||
createOperator(JavaTokenType.EQ, type)//TODO correct type
|
||||
)
|
||||
}
|
||||
else -> throwCanNotConvertError("expected getter or setter call")
|
||||
@@ -513,14 +527,15 @@ class JavaToJKTreeBuilder constructor(
|
||||
val jkExpressions = expressions.map { it.toJK() }
|
||||
return ((parent as? PsiCall)?.resolveMethod()
|
||||
?.let { method ->
|
||||
val lastExpressionType = expressions.lastOrNull()?.type
|
||||
if (jkExpressions.size == method.parameterList.parameters.size
|
||||
&& method.parameterList.parameters.getOrNull(jkExpressions.lastIndex)?.isVarArgs == true
|
||||
&& expressions.lastOrNull()?.type is PsiArrayType
|
||||
&& lastExpressionType is PsiArrayType
|
||||
) {
|
||||
val staredExpression =
|
||||
JKPrefixExpressionImpl(
|
||||
jkExpressions.last(),
|
||||
JKKtSpreadOperator
|
||||
JKKtSpreadOperator(lastExpressionType.toJK())
|
||||
).withNonCodeElementsFrom(jkExpressions.last())
|
||||
jkExpressions.dropLast(1) + staredExpression
|
||||
} else jkExpressions
|
||||
|
||||
@@ -659,6 +659,9 @@ class NewCodeBuilder(context: NewJ2kConverterContext) {
|
||||
}
|
||||
}
|
||||
|
||||
override fun visitKtItExpressionRaw(ktItExpression: JKKtItExpression) {
|
||||
printer.printWithNoIndent("it")
|
||||
}
|
||||
|
||||
override fun visitClassBodyRaw(classBody: JKClassBody) {
|
||||
val declarationsToPrint = classBody.declarations.filterNot { it is JKKtPrimaryConstructor }
|
||||
@@ -818,11 +821,27 @@ class NewCodeBuilder(context: NewJ2kConverterContext) {
|
||||
override fun visitKtAssignmentStatementRaw(ktAssignmentStatement: JKKtAssignmentStatement) {
|
||||
ktAssignmentStatement.field.accept(this)
|
||||
printer.printWithNoIndent(" ")
|
||||
printer.printWithNoIndent(ktAssignmentStatement.operator.token.text)
|
||||
printer.printWithNoIndent(ktAssignmentStatement.token.text)
|
||||
printer.printWithNoIndent(" ")
|
||||
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) {
|
||||
printer.printWithNoIndent("when(")
|
||||
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")
|
||||
val firstArgument = expression.parent.cast<JKQualifiedExpression>()::receiver.detached()
|
||||
val secondArgument = expression.arguments.arguments.first()::value.detached()
|
||||
kotlinBinaryExpression(
|
||||
JKBinaryExpressionImpl(
|
||||
firstArgument,
|
||||
secondArgument,
|
||||
KtTokens.PLUS,
|
||||
typeFactory
|
||||
JKKtOperatorImpl(JKOperatorToken.PLUS, typeFactory.types.possiblyNullString)
|
||||
)
|
||||
} withReplaceType ReplaceType.REPLACE_WITH_QUALIFIER,
|
||||
|
||||
@@ -390,27 +389,26 @@ class BuiltinMembersConversion(context: NewJ2kConverterContext) : RecursiveAppli
|
||||
else expression
|
||||
.also {
|
||||
arguments.arguments = arguments.arguments.dropLast(1)
|
||||
}.let {
|
||||
it.callOn(
|
||||
symbolProvider.provideMethodSymbol("kotlin.collections.dropLastWhile"),
|
||||
}.callOn(
|
||||
symbolProvider.provideMethodSymbol("kotlin.collections.dropLastWhile"),
|
||||
listOf(
|
||||
JKLambdaExpressionImpl(
|
||||
JKFieldAccessExpressionImpl(
|
||||
JKUnresolvedField(//TODO replace with `it` parameter
|
||||
"it",
|
||||
typeFactory
|
||||
)
|
||||
).callOn(symbolProvider.provideMethodSymbol("kotlin.text.isEmpty"))
|
||||
.asStatement(),
|
||||
).callOn(symbolProvider.provideMethodSymbol("kotlin.text.isEmpty")).asStatement(),
|
||||
emptyList()
|
||||
)
|
||||
)
|
||||
}
|
||||
)
|
||||
}
|
||||
else -> expression.also {
|
||||
val lastArgument = arguments.arguments.last().value.copyTreeAndDetach()
|
||||
.callOn(
|
||||
symbolProvider.provideMethodSymbol("kotlin.ranges.coerceAtLeast"),
|
||||
JKKtLiteralExpressionImpl("0", JKLiteralExpression.LiteralType.INT)
|
||||
listOf(JKKtLiteralExpressionImpl("0", JKLiteralExpression.LiteralType.INT))
|
||||
)
|
||||
arguments.arguments = arguments.arguments.dropLast(1) + JKArgumentImpl(lastArgument)
|
||||
}
|
||||
@@ -428,7 +426,7 @@ class BuiltinMembersConversion(context: NewJ2kConverterContext) : RecursiveAppli
|
||||
JKArgumentListImpl(
|
||||
JKLambdaExpressionImpl(
|
||||
JKExpressionStatementImpl(
|
||||
kotlinBinaryExpression(
|
||||
JKBinaryExpressionImpl(
|
||||
JKFieldAccessExpressionImpl(
|
||||
JKUnresolvedField(//TODO replace with `it` parameter
|
||||
"it",
|
||||
@@ -436,8 +434,10 @@ class BuiltinMembersConversion(context: NewJ2kConverterContext) : RecursiveAppli
|
||||
)
|
||||
),
|
||||
JKKtLiteralExpressionImpl("' '", JKLiteralExpression.LiteralType.CHAR),
|
||||
KtTokens.LTEQ,
|
||||
typeFactory
|
||||
JKKtOperatorImpl(
|
||||
JKOperatorToken.LTEQ,
|
||||
typeFactory.types.boolean
|
||||
)
|
||||
)
|
||||
),
|
||||
emptyList()
|
||||
@@ -469,7 +469,7 @@ class BuiltinMembersConversion(context: NewJ2kConverterContext) : RecursiveAppli
|
||||
).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(
|
||||
this,
|
||||
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 =
|
||||
expression.parent
|
||||
?.safeAs<JKQualifiedExpression>()
|
||||
|
||||
@@ -182,11 +182,13 @@ class ForConversion(context: NewJ2kConverterContext) : RecursiveApplicableConver
|
||||
convertBound(bound, 0),
|
||||
context
|
||||
)
|
||||
else -> kotlinBinaryExpression(
|
||||
else -> JKBinaryExpressionImpl(
|
||||
start,
|
||||
convertBound(bound, if (inclusiveComparison) 0 else -1),
|
||||
JKKtSingleValueOperatorToken(KtTokens.RANGE),
|
||||
typeFactory
|
||||
JKKtOperatorImpl(
|
||||
JKOperatorToken.RANGE,
|
||||
typeFactory.types.nullableAny //todo range type
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -199,12 +201,14 @@ class ForConversion(context: NewJ2kConverterContext) : RecursiveApplicableConver
|
||||
return JKKtLiteralExpressionImpl((value + correction).toString(), bound.type)
|
||||
}
|
||||
|
||||
val sign = if (correction > 0) KtTokens.PLUS else KtTokens.MINUS
|
||||
return kotlinBinaryExpression(
|
||||
val sign = if (correction > 0) JKOperatorToken.PLUS else JKOperatorToken.MINUS
|
||||
return JKBinaryExpressionImpl(
|
||||
bound,
|
||||
JKKtLiteralExpressionImpl(abs(correction).toString(), JKLiteralExpression.LiteralType.INT),
|
||||
JKKtSingleValueOperatorToken(sign),
|
||||
typeFactory
|
||||
JKKtOperatorImpl(
|
||||
sign,
|
||||
typeFactory.types.int
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -5,77 +5,27 @@
|
||||
|
||||
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.kotlinBinaryExpression
|
||||
import org.jetbrains.kotlin.nj2k.kotlinPostfixExpression
|
||||
import org.jetbrains.kotlin.nj2k.kotlinPrefixExpression
|
||||
import org.jetbrains.kotlin.nj2k.callOn
|
||||
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 {
|
||||
if (element !is JKOperatorExpression) return recurse(element)
|
||||
val operator = element.operator as? JKJavaOperatorImpl ?: return recurse(element)
|
||||
|
||||
return when (element) {
|
||||
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
|
||||
if (element !is JKBinaryExpression) return recurse(element)
|
||||
if (element.operator.token == JKOperatorToken.PLUS
|
||||
&& element.right.type(typeFactory)?.isStringType() == true
|
||||
&& element.left.type(typeFactory)?.isStringType() == false
|
||||
) {
|
||||
val toStringCall =
|
||||
JKKtCallExpressionImpl(
|
||||
symbolProvider.provideMethodSymbol("kotlin.Any.toString"),
|
||||
JKArgumentListImpl()
|
||||
return recurse(
|
||||
JKBinaryExpressionImpl(
|
||||
element::left.detached().callOn(symbolProvider.provideMethodSymbol("kotlin.Any.toString")),
|
||||
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)
|
||||
}
|
||||
is JKJavaNewExpression -> {
|
||||
val newClassSymbol = element.classSymbol.mapClassSymbol(null)
|
||||
val newClassSymbol = element.classSymbol.mapClassSymbol()
|
||||
return recurse(
|
||||
JKJavaNewExpressionImpl(
|
||||
newClassSymbol,
|
||||
@@ -55,7 +55,6 @@ class TypeMappingConversion(context: NewJ2kConverterContext) : RecursiveApplicab
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private fun JKType.fixRawType(typeElement: JKTypeElement?) =
|
||||
when (typeElement?.parent) {
|
||||
is JKClassLiteralExpression -> this
|
||||
@@ -71,7 +70,7 @@ class TypeMappingConversion(context: NewJ2kConverterContext) : RecursiveApplicab
|
||||
private fun JKType.mapType(typeElement: JKTypeElement?): JKType =
|
||||
when (this) {
|
||||
is JKJavaPrimitiveType -> mapPrimitiveType()
|
||||
is JKClassType -> mapClassType(typeElement)
|
||||
is JKClassType -> mapClassType()
|
||||
is JKJavaVoidType -> typeFactory.types.unit
|
||||
|
||||
is JKJavaArrayType ->
|
||||
@@ -94,18 +93,17 @@ class TypeMappingConversion(context: NewJ2kConverterContext) : RecursiveApplicab
|
||||
else -> this
|
||||
}.fixRawType(typeElement)
|
||||
|
||||
private fun JKClassSymbol.mapClassSymbol(typeElement: JKTypeElement?): JKClassSymbol {
|
||||
private fun JKClassSymbol.mapClassSymbol(): JKClassSymbol {
|
||||
if (this is JKUniverseClassSymbol) return this
|
||||
if (typeElement?.parentOfType<JKInheritanceInfo>() != null) return this
|
||||
val newFqName = kotlinCollectionClassName()
|
||||
?: kotlinStandardType()
|
||||
?: fqName
|
||||
return symbolProvider.provideClassSymbol(newFqName)
|
||||
}
|
||||
|
||||
private fun JKClassType.mapClassType(typeElement: JKTypeElement?): JKClassType =
|
||||
private fun JKClassType.mapClassType(): JKClassType =
|
||||
JKClassTypeImpl(
|
||||
classReference.mapClassSymbol(typeElement),
|
||||
classReference.mapClassSymbol(),
|
||||
parameters.map { it.mapType(null) },
|
||||
nullability
|
||||
)
|
||||
@@ -118,13 +116,8 @@ class TypeMappingConversion(context: NewJ2kConverterContext) : RecursiveApplicab
|
||||
return JavaToKotlinClassMap.mapJavaToKotlin(FqName(fqName))?.asString()
|
||||
}
|
||||
|
||||
private fun JKJavaPrimitiveType.mapPrimitiveType(): JKClassType {
|
||||
val fqName = jvmPrimitiveType.primitiveType.typeFqName
|
||||
return JKClassTypeImpl(
|
||||
symbolProvider.provideClassSymbol(fqName),
|
||||
nullability = Nullability.NotNull
|
||||
)
|
||||
}
|
||||
private fun JKJavaPrimitiveType.mapPrimitiveType(): JKClassType =
|
||||
typeFactory.fromPrimitiveType(this)
|
||||
|
||||
private inline fun <reified T : JKType> T.addTypeParametersToRawProjectionType(typeParameter: JKType): T =
|
||||
if (this is JKClassType && parameters.isEmpty()) {
|
||||
@@ -147,7 +140,6 @@ class TypeMappingConversion(context: NewJ2kConverterContext) : RecursiveApplicab
|
||||
|
||||
companion object {
|
||||
private val ktFunctionRegex = "kotlin\\.jvm\\.functions\\.Function\\d+".toRegex()
|
||||
private fun isKtFunction(fqName: String) =
|
||||
ktFunctionRegex.matches(fqName)
|
||||
private fun isKtFunction(fqName: String) = ktFunctionRegex.matches(fqName)
|
||||
}
|
||||
}
|
||||
@@ -5,67 +5,18 @@
|
||||
|
||||
package org.jetbrains.kotlin.nj2k
|
||||
|
||||
import com.intellij.psi.PsiClass
|
||||
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.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.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.JKTypeParameterType
|
||||
import org.jetbrains.kotlin.psi.KtNamedFunction
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.cast
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.firstIsInstanceOrNull
|
||||
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() =
|
||||
(token as? JKKtSingleValueOperatorToken)?.psiToken in equalsOperators
|
||||
|
||||
@@ -77,98 +28,6 @@ private val equalsOperators =
|
||||
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(
|
||||
from: JKExpression,
|
||||
to: JKExpression,
|
||||
@@ -199,6 +58,8 @@ fun JKExpression.parenthesizeIfBinaryExpression() =
|
||||
else -> this
|
||||
}
|
||||
|
||||
fun JKExpression.parenthesize() = JKParenthesizedExpressionImpl(this)
|
||||
|
||||
fun rangeExpression(
|
||||
from: JKExpression,
|
||||
to: JKExpression,
|
||||
@@ -277,7 +138,7 @@ fun stringLiteral(content: String, typeFactory: JKTypeFactory): JKExpression {
|
||||
val newlineSeparator = if (i == lines.size - 1) "" else "\\n"
|
||||
JKKtLiteralExpressionImpl("\"$line$newlineSeparator\"", JKLiteralExpression.LiteralType.STRING)
|
||||
}.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) =
|
||||
kotlinBinaryExpression(
|
||||
JKBinaryExpressionImpl(
|
||||
left,
|
||||
right,
|
||||
KtTokens.EQEQ,
|
||||
typeFactory
|
||||
JKKtOperatorImpl(
|
||||
JKOperatorToken.EQEQ,
|
||||
typeFactory.types.boolean
|
||||
)
|
||||
)
|
||||
|
||||
fun createCompanion(declarations: List<JKDeclaration>): JKClass =
|
||||
@@ -438,4 +301,19 @@ fun <T : JKExpression> T.nullIfStubExpression(): T? =
|
||||
fun JKExpression.qualified(qualifier: JKExpression?) =
|
||||
if (qualifier != null && qualifier !is JKStubExpression) {
|
||||
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
|
||||
|
||||
import com.intellij.psi.JavaTokenType
|
||||
import com.intellij.psi.tree.IElementType
|
||||
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 {
|
||||
val token: JKOperatorToken
|
||||
val precedence: Int
|
||||
val returnType: JKType
|
||||
}
|
||||
|
||||
interface JKOperatorToken {
|
||||
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 {
|
||||
val operatorName: String
|
||||
}
|
||||
|
||||
interface JKKtOperatorToken : JKOperatorToken
|
||||
interface JKQualifier
|
||||
|
||||
interface JKElement {
|
||||
|
||||
@@ -159,7 +159,7 @@ class JKQualifiedExpressionImpl(
|
||||
class JKExpressionStatementImpl(expression: JKExpression) : JKExpressionStatement(), PsiOwner by PsiOwnerImpl() {
|
||||
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(),
|
||||
|
||||
@@ -92,125 +92,9 @@ class JKJavaLiteralExpressionImpl(
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class JKJavaOperatorToken(val psiToken: IElementType) : JKOperatorToken {
|
||||
override val text: String
|
||||
get() = when (psiToken) {
|
||||
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)
|
||||
}
|
||||
}
|
||||
get() = error("Java token should not be printed, it should be replaces with corresponding Kotlin one")
|
||||
}
|
||||
|
||||
sealed class JKJavaQualifierImpl : JKQualifier {
|
||||
@@ -342,13 +226,13 @@ class JKJavaPolyadicExpressionImpl(operands: List<JKExpression>, override var to
|
||||
}
|
||||
|
||||
class JKJavaAssignmentExpressionImpl(
|
||||
field: JKAssignableExpression,
|
||||
field: JKExpression,
|
||||
expression: JKExpression,
|
||||
override var operator: JKOperator
|
||||
) : JKBranchElementBase(), JKJavaAssignmentExpression, PsiOwner by PsiOwnerImpl() {
|
||||
override fun accept(visitor: JKVisitor) = visitor.visitJavaAssignmentExpression(this)
|
||||
override var field: JKAssignableExpression by child(field)
|
||||
override var expression: JKExpression by child(expression)
|
||||
override var field by child(field)
|
||||
override var expression by child(expression)
|
||||
}
|
||||
|
||||
class JKJavaSwitchStatementImpl(
|
||||
|
||||
@@ -104,64 +104,51 @@ class JKKtLiteralExpressionImpl(
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
object JKKtSpreadOperatorToken : JKKtOperatorToken {
|
||||
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 precedence: Int
|
||||
get() = TODO()
|
||||
}
|
||||
|
||||
class JKKtWordOperatorToken(override val text: String) : JKKtOperatorToken {
|
||||
override val operatorName: String = text
|
||||
class JKKtWordOperatorToken(override val text: String) : JKKtOperatorToken
|
||||
|
||||
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() {
|
||||
constructor(singleValueToken: KtSingleValueToken, returnType: JKType) : this(
|
||||
JKKtSingleValueOperatorToken(singleValueToken),
|
||||
returnType
|
||||
)
|
||||
class JKAssignmentChainLetLinkImpl(
|
||||
receiver: JKExpression,
|
||||
assignmentStatement: JKKtAssignmentStatement,
|
||||
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
|
||||
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)
|
||||
override fun accept(visitor: JKVisitor) = visitor.visitAssignmentChainLetLink(this)
|
||||
}
|
||||
|
||||
class JKKtAssignmentStatementImpl(
|
||||
field: JKAssignableExpression,
|
||||
field: JKExpression,
|
||||
expression: JKExpression,
|
||||
override var operator: JKOperator
|
||||
override var token: JKOperatorToken
|
||||
) : JKKtAssignmentStatement() {
|
||||
override var field: JKAssignableExpression by child(field)
|
||||
override var field: JKExpression by child(field)
|
||||
override var expression by child(expression)
|
||||
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 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 val expression: JKExpression
|
||||
abstract var expression: JKExpression
|
||||
}
|
||||
|
||||
abstract class JKDeclarationStatement : JKStatement() {
|
||||
@@ -315,7 +315,7 @@ interface JKPrefixExpression : JKUnaryExpression
|
||||
|
||||
interface JKPostfixExpression : JKUnaryExpression
|
||||
|
||||
interface JKQualifiedExpression : JKExpression, JKAssignableExpression {
|
||||
interface JKQualifiedExpression : JKExpression {
|
||||
var receiver: JKExpression
|
||||
var operator: JKQualifier
|
||||
var selector: JKExpression
|
||||
@@ -334,11 +334,11 @@ interface JKMethodCallExpression : JKExpression, JKTypeArgumentListOwner, JKBran
|
||||
var arguments: JKArgumentList
|
||||
}
|
||||
|
||||
interface JKFieldAccessExpression : JKAssignableExpression {
|
||||
interface JKFieldAccessExpression : JKExpression {
|
||||
val identifier: JKFieldSymbol
|
||||
}
|
||||
|
||||
interface JKPackageAccessExpression : JKAssignableExpression {
|
||||
interface JKPackageAccessExpression : JKExpression {
|
||||
val identifier: JKPackageSymbol
|
||||
}
|
||||
|
||||
@@ -346,7 +346,7 @@ interface JKClassAccessExpression : JKExpression {
|
||||
val identifier: JKClassSymbol
|
||||
}
|
||||
|
||||
interface JKArrayAccessExpression : JKAssignableExpression {
|
||||
interface JKArrayAccessExpression : JKExpression {
|
||||
var expression: JKExpression
|
||||
var indexExpression: JKExpression
|
||||
}
|
||||
@@ -447,8 +447,6 @@ interface JKIfElseExpression : JKExpression {
|
||||
var elseBranch: JKExpression
|
||||
}
|
||||
|
||||
interface JKAssignableExpression : JKExpression
|
||||
|
||||
interface JKLambdaExpression : JKExpression {
|
||||
var parameters: List<JKParameter>
|
||||
val returnType: JKTypeElement
|
||||
|
||||
@@ -95,7 +95,7 @@ interface JKJavaPolyadicExpression : JKExpression {
|
||||
}
|
||||
|
||||
interface JKJavaAssignmentExpression : JKExpression, JKBranchElement {
|
||||
var field: JKAssignableExpression
|
||||
var field: JKExpression
|
||||
var expression: JKExpression
|
||||
var operator: JKOperator
|
||||
}
|
||||
|
||||
@@ -42,19 +42,24 @@ abstract class JKKtConstructor : JKMethod(), JKOtherModifiersOwner {
|
||||
abstract class JKKtPrimaryConstructor : JKKtConstructor()
|
||||
|
||||
abstract class JKKtAssignmentStatement : JKStatement() {
|
||||
abstract var field: JKAssignableExpression
|
||||
abstract var field: JKExpression
|
||||
abstract var expression: JKExpression
|
||||
abstract var operator: JKOperator
|
||||
abstract var token: JKOperatorToken
|
||||
}
|
||||
|
||||
interface JKKtCall : JKMethodCallExpression
|
||||
|
||||
interface JKKtMethodCallExpression : JKMethodCallExpression
|
||||
|
||||
interface JKKtAlsoCallExpression : JKKtMethodCallExpression {
|
||||
var statement: JKStatement
|
||||
interface JKKtAssignmentChainLink : JKExpression {
|
||||
val receiver: JKExpression
|
||||
val assignmentStatement: JKKtAssignmentStatement
|
||||
val field: JKExpression
|
||||
}
|
||||
|
||||
interface JKAssignmentChainAlsoLink : JKKtAssignmentChainLink
|
||||
interface JKAssignmentChainLetLink : JKKtAssignmentChainLink
|
||||
|
||||
interface JKKtLiteralExpression : JKLiteralExpression
|
||||
|
||||
abstract class JKKtWhenStatement : JKStatement() {
|
||||
@@ -108,4 +113,8 @@ interface JKKtTryCatchSection : JKTreeElement {
|
||||
|
||||
interface JKKtAnnotationArrayInitializerExpression : JKExpression, JKBranchElement {
|
||||
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 =
|
||||
also { it.takeNonCodeElementsFrom(other) }
|
||||
|
||||
inline fun <reified T : JKNonCodeElementsListOwner> List<T>.withNonCodeElementsFrom(other: JKNonCodeElementsListOwner): List<T> =
|
||||
also {
|
||||
if (isNotEmpty()) {
|
||||
it.first().leftNonCodeElements += other.leftNonCodeElements
|
||||
it.last().rightNonCodeElements += other.rightNonCodeElements
|
||||
}
|
||||
}
|
||||
|
||||
fun JKNonCodeElementsListOwner.clearNonCodeElements() {
|
||||
leftNonCodeElements = emptyList()
|
||||
rightNonCodeElements = emptyList()
|
||||
|
||||
@@ -11,16 +11,11 @@ import com.intellij.psi.PsiClassType
|
||||
import com.intellij.psi.PsiType
|
||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
||||
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.util.getJavaClassDescriptor
|
||||
import org.jetbrains.kotlin.idea.refactoring.fqName.getKotlinFqName
|
||||
import org.jetbrains.kotlin.j2k.ast.Nullability
|
||||
import org.jetbrains.kotlin.nj2k.JKSymbolProvider
|
||||
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.types.*
|
||||
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.jvm.JvmPrimitiveType
|
||||
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
|
||||
|
||||
fun JKExpression.type(typeFactory: JKTypeFactory): JKType? =
|
||||
@@ -73,6 +66,10 @@ fun JKExpression.type(typeFactory: JKTypeFactory): JKType? =
|
||||
is JKLabeledStatement ->
|
||||
statement.safeAs<JKExpressionStatement>()?.expression?.type(typeFactory)
|
||||
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())
|
||||
}
|
||||
|
||||
@@ -82,33 +79,20 @@ fun JKType.asTypeElement() =
|
||||
fun JKClassSymbol.asType(nullability: Nullability = Nullability.Default): JKClassType =
|
||||
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
|
||||
get() {
|
||||
val fqName = safeAs<PsiClassType>()?.resolve()?.getKotlinFqName() ?: return false
|
||||
return functionalTypeRegex.matches(fqName.asString())
|
||||
}
|
||||
|
||||
|
||||
private val functionalTypeRegex = """(kotlin\.jvm\.functions|kotlin)\.Function[\d+]""".toRegex()
|
||||
|
||||
|
||||
fun KtTypeReference.toJK(typeFactory: JKTypeFactory): JKType? =
|
||||
analyze(BodyResolveMode.PARTIAL)
|
||||
.get(BindingContext.TYPE, this)
|
||||
?.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) =
|
||||
jvmPrimitiveTypesPriority.getValue(this.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 =
|
||||
transform(this) ?: when (this) {
|
||||
is JKTypeParameterTypeImpl -> this
|
||||
|
||||
@@ -75,7 +75,7 @@ abstract class JKVisitor {
|
||||
open fun visitIfStatement(ifStatement: JKIfStatement) = visitStatement(ifStatement)
|
||||
open fun visitIfElseStatement(ifElseStatement: JKIfElseStatement) = visitIfStatement(ifElseStatement)
|
||||
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 visitDelegationConstructorCall(delegationConstructorCall: JKDelegationConstructorCall) = visitMethodCallExpression(delegationConstructorCall)
|
||||
open fun visitLabel(label: JKLabel) = visitTreeElement(label)
|
||||
@@ -85,7 +85,7 @@ abstract class JKVisitor {
|
||||
open fun visitLabeledStatement(labeledStatement: JKLabeledStatement) = visitExpression(labeledStatement)
|
||||
open fun visitEmptyStatement(emptyStatement: JKEmptyStatement) = visitStatement(emptyStatement)
|
||||
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 visitEnumConstant(enumConstant: JKEnumConstant) = visitVariable(enumConstant)
|
||||
open fun visitForInStatement(forInStatement: JKForInStatement) = visitStatement(forInStatement)
|
||||
@@ -128,7 +128,9 @@ abstract class JKVisitor {
|
||||
open fun visitKtAssignmentStatement(ktAssignmentStatement: JKKtAssignmentStatement) = visitStatement(ktAssignmentStatement)
|
||||
open fun visitKtCall(ktCall: JKKtCall) = visitMethodCallExpression(ktCall)
|
||||
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 visitKtWhenStatement(ktWhenStatement: JKKtWhenStatement) = visitStatement(ktWhenStatement)
|
||||
open fun visitKtWhenCase(ktWhenCase: JKKtWhenCase) = visitTreeElement(ktWhenCase)
|
||||
@@ -142,4 +144,5 @@ abstract class JKVisitor {
|
||||
open fun visitKtTryExpression(ktTryExpression: JKKtTryExpression) = visitExpression(ktTryExpression)
|
||||
open fun visitKtTryCatchSection(ktTryCatchSection: JKKtTryCatchSection) = visitTreeElement(ktTryCatchSection)
|
||||
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)
|
||||
|
||||
override fun visitAssignableExpression(assignableExpression: JKAssignableExpression) {
|
||||
override fun visitAssignableExpression(assignableExpression: JKExpression) {
|
||||
printLeftNonCodeElements(assignableExpression)
|
||||
visitAssignableExpressionRaw(assignableExpression)
|
||||
printRightNonCodeElements(assignableExpression)
|
||||
}
|
||||
|
||||
open fun visitAssignableExpressionRaw(assignableExpression: JKAssignableExpression) = visitExpressionRaw(assignableExpression)
|
||||
open fun visitAssignableExpressionRaw(assignableExpression: JKExpression) = visitExpressionRaw(assignableExpression)
|
||||
|
||||
override fun visitLambdaExpression(lambdaExpression: JKLambdaExpression) {
|
||||
printLeftNonCodeElements(lambdaExpression)
|
||||
@@ -668,7 +668,7 @@ abstract class JKVisitorWithCommentsPrinting : JKVisitor() {
|
||||
printRightNonCodeElements(typeParameter)
|
||||
}
|
||||
|
||||
open fun visitTypeParameterRaw(typeParameter: JKTypeParameter) = visitTreeElementRaw(typeParameter)
|
||||
open fun visitTypeParameterRaw(typeParameter: JKTypeParameter) = visitDeclarationRaw(typeParameter)
|
||||
|
||||
override fun visitTypeParameterListOwner(typeParameterListOwner: JKTypeParameterListOwner) {
|
||||
printLeftNonCodeElements(typeParameterListOwner)
|
||||
@@ -1006,13 +1006,29 @@ abstract class JKVisitorWithCommentsPrinting : JKVisitor() {
|
||||
|
||||
open fun visitKtMethodCallExpressionRaw(ktMethodCallExpression: JKKtMethodCallExpression) = visitMethodCallExpressionRaw(ktMethodCallExpression)
|
||||
|
||||
override fun visitKtAlsoCallExpression(ktAlsoCallExpression: JKKtAlsoCallExpression) {
|
||||
printLeftNonCodeElements(ktAlsoCallExpression)
|
||||
visitKtAlsoCallExpressionRaw(ktAlsoCallExpression)
|
||||
printRightNonCodeElements(ktAlsoCallExpression)
|
||||
override fun visitKtAssignmentChainLink(ktAssignmentChainLink: JKKtAssignmentChainLink) {
|
||||
printLeftNonCodeElements(ktAssignmentChainLink)
|
||||
visitKtAssignmentChainLinkRaw(ktAssignmentChainLink)
|
||||
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) {
|
||||
printLeftNonCodeElements(ktLiteralExpression)
|
||||
@@ -1117,4 +1133,12 @@ abstract class JKVisitorWithCommentsPrinting : JKVisitor() {
|
||||
}
|
||||
|
||||
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.js.descriptorUtils.getJetTypeFqName
|
||||
import org.jetbrains.kotlin.js.resolve.diagnostics.findPsi
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.name.FqNameUnsafe
|
||||
import org.jetbrains.kotlin.nj2k.JKSymbolProvider
|
||||
import org.jetbrains.kotlin.nj2k.symbols.JKClassSymbol
|
||||
import org.jetbrains.kotlin.nj2k.symbols.JKTypeParameterSymbol
|
||||
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.resolve.jvm.JvmPrimitiveType
|
||||
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 {
|
||||
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 {
|
||||
private val value: String? = null
|
||||
|
||||
fun test(): String {
|
||||
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
|
||||
|
||||
class Test {
|
||||
internal var list: List<List<Int>> = ArrayList()
|
||||
internal var list: List<MutableList<Int>> = ArrayList()
|
||||
fun test() {
|
||||
list[0].add(1)
|
||||
}
|
||||
|
||||
+25
@@ -412,6 +412,16 @@ public class NewJavaToKotlinConverterSingleFileTestGenerated extends AbstractNew
|
||||
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")
|
||||
public void testBitOperationPriority() throws Exception {
|
||||
runTest("nj2k/testData/newJ2k/assignmentExpression/bitOperationPriority.java");
|
||||
@@ -422,11 +432,26 @@ public class NewJavaToKotlinConverterSingleFileTestGenerated extends AbstractNew
|
||||
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")
|
||||
public void testDivideAssign() throws Exception {
|
||||
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")
|
||||
public void testMinusAssign() throws Exception {
|
||||
runTest("nj2k/testData/newJ2k/assignmentExpression/minusAssign.java");
|
||||
|
||||
Reference in New Issue
Block a user