New J2K: Add multiple updaters to Java for loop

This commit is contained in:
Ilya Kirillov
2018-11-27 13:55:40 +03:00
committed by Ilya Kirillov
parent 9532dec452
commit 4b0840beb1
3 changed files with 11 additions and 10 deletions
@@ -44,13 +44,13 @@ class ForConversion(private val context: ConversionContext) : RecursiveApplicabl
} }
private fun createWhileBody(loopStatement: JKJavaForLoopStatement): JKStatement { private fun createWhileBody(loopStatement: JKJavaForLoopStatement): JKStatement {
if (loopStatement.updater is JKEmptyStatement) return loopStatement::body.detached() if (loopStatement.updaters.singleOrNull() is JKEmptyStatement) return loopStatement::body.detached()
val continueStatementConverter = object : RecursiveApplicableConversionBase() { val continueStatementConverter = object : RecursiveApplicableConversionBase() {
override fun applyToElement(element: JKTreeElement): JKTreeElement { override fun applyToElement(element: JKTreeElement): JKTreeElement {
if (element !is JKContinueStatement) return recurse(element) if (element !is JKContinueStatement) return recurse(element)
val elementPsi = element.psi<PsiContinueStatement>()!! val elementPsi = element.psi<PsiContinueStatement>()!!
if (elementPsi.findContinuedStatement()?.toContinuedLoop() != loopStatement.psi<PsiForStatement>()) return recurse(element) if (elementPsi.findContinuedStatement()?.toContinuedLoop() != loopStatement.psi<PsiForStatement>()) return recurse(element)
val statements = listOf(loopStatement.updater, element) val statements = loopStatement.updaters + element
return recurse(JKBlockStatementImpl(JKBlockImpl(statements))) return recurse(JKBlockStatementImpl(JKBlockImpl(statements)))
} }
@@ -72,14 +72,14 @@ class ForConversion(private val context: ConversionContext) : RecursiveApplicabl
val statements = val statements =
if (hasNameConflict) { if (hasNameConflict) {
listOf(continueStatementConverter.applyToElement(body) as JKStatement, loopStatement::updater.detached()) listOf(continueStatementConverter.applyToElement(body) as JKStatement) + loopStatement::updaters.detached()
} else { } else {
body.block::statements.detached() + loopStatement::updater.detached() body.block::statements.detached() + loopStatement::updaters.detached()
} }
return JKBlockStatementImpl(JKBlockImpl(statements)) return JKBlockStatementImpl(JKBlockImpl(statements))
} else { } else {
val statements = val statements =
listOf(continueStatementConverter.applyToElement(body) as JKStatement, loopStatement::updater.detached()) listOf(continueStatementConverter.applyToElement(body) as JKStatement) + loopStatement::updaters.detached()
return JKBlockStatementImpl(JKBlockImpl(statements)) return JKBlockStatementImpl(JKBlockImpl(statements))
} }
} }
@@ -98,7 +98,7 @@ class ForConversion(private val context: ConversionContext) : RecursiveApplicabl
if (left.identifier.target != loopVar) return null if (left.identifier.target != loopVar) return null
val start = loopVar::initializer.detached() val start = loopVar::initializer.detached()
val operationType = val operationType =
(loopStatement.updater as? JKExpressionStatement)?.expression?.isVariableIncrementOrDecrement(loopVar) (loopStatement.updaters.singleOrNull() as? JKExpressionStatement)?.expression?.isVariableIncrementOrDecrement(loopVar)
val reversed = when (operationType?.token?.text) { val reversed = when (operationType?.token?.text) {
"++" -> false "++" -> false
"--" -> true "--" -> true
@@ -233,6 +233,8 @@ class ForConversion(private val context: ConversionContext) : RecursiveApplicabl
private fun indicesByCollectionSize(javaSizeCall: JKQualifiedExpression): JKQualifiedExpression? { private fun indicesByCollectionSize(javaSizeCall: JKQualifiedExpression): JKQualifiedExpression? {
val methodCall = javaSizeCall.selector as? JKMethodCallExpression ?: return null val methodCall = javaSizeCall.selector as? JKMethodCallExpression ?: return null
val receiverType = javaSizeCall.receiver.type(context) as? JKClassType ?: return null
//TODO check if receiver type is Collection //TODO check if receiver type is Collection
if (methodCall.identifier.name == "size" && methodCall.arguments.expressions.isEmpty()) { if (methodCall.identifier.name == "size" && methodCall.arguments.expressions.isEmpty()) {
return toIndicesCall(javaSizeCall) return toIndicesCall(javaSizeCall)
@@ -243,7 +245,6 @@ class ForConversion(private val context: ConversionContext) : RecursiveApplicabl
private fun indicesByArrayLength(javaSizeCall: JKQualifiedExpression): JKQualifiedExpression? { private fun indicesByArrayLength(javaSizeCall: JKQualifiedExpression): JKQualifiedExpression? {
val methodCall = javaSizeCall.selector as? JKFieldAccessExpression ?: return null val methodCall = javaSizeCall.selector as? JKFieldAccessExpression ?: return null
val receiverType = javaSizeCall.receiver.type(context) val receiverType = javaSizeCall.receiver.type(context)
//TODO check if receiver type is kotlin.array
if (methodCall.identifier.name == "length" && receiverType is JKJavaArrayType) { if (methodCall.identifier.name == "length" && receiverType is JKJavaArrayType) {
return toIndicesCall(javaSizeCall) return toIndicesCall(javaSizeCall)
} }
@@ -281,10 +281,10 @@ class JKJavaAssertStatementImpl(condition: JKExpression, description: JKExpressi
override fun <R, D> accept(visitor: JKVisitor<R, D>, data: D): R = visitor.visitJavaAssertStatement(this, data) override fun <R, D> accept(visitor: JKVisitor<R, D>, data: D): R = visitor.visitJavaAssertStatement(this, data)
} }
class JKJavaForLoopStatementImpl(initializer: JKStatement, condition: JKExpression, updater: JKStatement, body: JKStatement) : class JKJavaForLoopStatementImpl(initializer: JKStatement, condition: JKExpression, updaters: List<JKStatement>, body: JKStatement) :
JKJavaForLoopStatement, JKBranchElementBase(), PsiOwner by PsiOwnerImpl() { JKJavaForLoopStatement, JKBranchElementBase(), PsiOwner by PsiOwnerImpl() {
override var body by child(body) override var body by child(body)
override var updater by child(updater) override var updaters by children(updaters)
override var condition by child(condition) override var condition by child(condition)
override var initializer by child(initializer) override var initializer by child(initializer)
@@ -85,7 +85,7 @@ interface JKJavaAssertStatement : JKStatement {
interface JKJavaForLoopStatement : JKLoopStatement { interface JKJavaForLoopStatement : JKLoopStatement {
var initializer: JKStatement var initializer: JKStatement
var condition: JKExpression var condition: JKExpression
var updater: JKStatement var updaters: List<JKStatement>
} }
interface JKJavaInstanceOfExpression : JKExpression { interface JKJavaInstanceOfExpression : JKExpression {