Java to Kotlin converter: better and more correct code
This commit is contained in:
@@ -136,3 +136,6 @@ fun PsiModifierListOwner.accessModifier(): String = when {
|
||||
}
|
||||
|
||||
fun PsiMethod.isMainMethod(): Boolean = PsiMethodUtil.isMainMethod(this)
|
||||
|
||||
fun <T: Any> List<T>.singleOrNull2(): T? = if (size == 1) this[0] else null
|
||||
fun <T: Any> Array<T>.singleOrNull2(): T? = if (size == 1) this[0] else null
|
||||
|
||||
@@ -24,6 +24,7 @@ import java.util.ArrayList
|
||||
import org.jetbrains.jet.j2k.hasWriteAccesses
|
||||
import org.jetbrains.jet.j2k.isInSingleLine
|
||||
import com.intellij.psi.tree.IElementType
|
||||
import org.jetbrains.jet.j2k.singleOrNull2
|
||||
|
||||
open class StatementVisitor(public val converter: Converter) : JavaElementVisitor() {
|
||||
public var result: Statement = Statement.Empty
|
||||
@@ -102,12 +103,11 @@ open class StatementVisitor(public val converter: Converter) : JavaElementVisito
|
||||
val condition = statement.getCondition()
|
||||
val body = statement.getBody()
|
||||
|
||||
if (initialization is PsiDeclarationStatement && initialization.getFirstChild()!!.getNextSibling() == null) {
|
||||
val loopVar = initialization.getFirstChild() as? PsiLocalVariable
|
||||
if (initialization is PsiDeclarationStatement) {
|
||||
val loopVar = initialization.getDeclaredElements().singleOrNull2() as? PsiLocalVariable
|
||||
if (loopVar != null
|
||||
&& !loopVar.hasWriteAccesses(body)
|
||||
&& !loopVar.hasWriteAccesses(condition)
|
||||
&& loopVar.countWriteAccesses(update) == 1
|
||||
&& condition is PsiBinaryExpression) {
|
||||
val operationTokenType = condition.getOperationTokenType()
|
||||
val lowerBound = condition.getLOperand()
|
||||
@@ -117,10 +117,8 @@ open class StatementVisitor(public val converter: Converter) : JavaElementVisito
|
||||
lowerBound.resolve() == loopVar &&
|
||||
upperBound != null) {
|
||||
val start = loopVar.getInitializer()
|
||||
if (start != null
|
||||
&& update != null
|
||||
&& update.getChildren().size == 1
|
||||
&& update.getChildren().single().isPlusPlusExpression()) {
|
||||
if (start != null &&
|
||||
(update as? PsiExpressionStatement)?.getExpression()?.isVariablePlusPlus(loopVar) ?: false) {
|
||||
val range = forIterationRange(start, upperBound, operationTokenType).assignNoPrototype()
|
||||
val explicitType = if (converter.settings.specifyLocalVariableTypeByDefault) PrimitiveType(Identifier("Int").assignNoPrototype()).assignNoPrototype() else null
|
||||
result = ForeachStatement(loopVar.declarationIdentifier(), explicitType, range, convertStatementOrBlock(body), statement.isInSingleLine())
|
||||
@@ -173,6 +171,16 @@ open class StatementVisitor(public val converter: Converter) : JavaElementVisito
|
||||
}
|
||||
}
|
||||
|
||||
private fun PsiElement.isVariablePlusPlus(variable: PsiVariable): Boolean {
|
||||
//TODO: simplify code when KT-5453 fixed
|
||||
val pair = when (this) {
|
||||
is PsiPostfixExpression -> getOperationTokenType() to getOperand()
|
||||
is PsiPrefixExpression -> getOperationTokenType() to getOperand()
|
||||
else -> return false
|
||||
}
|
||||
return pair.first == JavaTokenType.PLUSPLUS && (pair.second as? PsiReferenceExpression)?.resolve() == variable
|
||||
}
|
||||
|
||||
private fun forIterationRange(start: PsiExpression, upperBound: PsiExpression, comparisonTokenType: IElementType): Expression {
|
||||
if (start is PsiLiteralExpression
|
||||
&& start.getValue() == 0
|
||||
@@ -337,11 +345,6 @@ open class StatementVisitor(public val converter: Converter) : JavaElementVisito
|
||||
result = Statement.Empty
|
||||
}
|
||||
|
||||
private fun PsiElement.isPlusPlusExpression(): Boolean {
|
||||
return (this is PsiPostfixExpression && this.getOperationTokenType() == JavaTokenType.PLUSPLUS) ||
|
||||
(this is PsiPrefixExpression && this.getOperationTokenType() == JavaTokenType.PLUSPLUS)
|
||||
}
|
||||
|
||||
private fun convertStatementOrBlock(statement: PsiStatement?): Statement {
|
||||
return if (statement is PsiBlockStatement)
|
||||
converter.convertBlock(statement.getCodeBlock())
|
||||
|
||||
@@ -20,6 +20,7 @@ import com.intellij.psi.*
|
||||
import org.jetbrains.jet.j2k.ast.*
|
||||
import org.jetbrains.jet.j2k.Converter
|
||||
import java.util.ArrayList
|
||||
import org.jetbrains.jet.j2k.singleOrNull2
|
||||
|
||||
class SwitchConverter(private val converter: Converter) {
|
||||
public fun convert(statement: PsiSwitchStatement): WhenStatement
|
||||
@@ -113,6 +114,4 @@ class SwitchConverter(private val converter: Converter) {
|
||||
}
|
||||
|
||||
private fun isSwitchBreak(statement: PsiStatement) = statement is PsiBreakStatement && statement.getLabelIdentifier() == null
|
||||
|
||||
private fun <T: Any> List<T>.singleOrNull2(): T? = if (size == 1) this[0] else null
|
||||
}
|
||||
Reference in New Issue
Block a user