New J2K: Add ParameterModificationInMethodCallsConversion
This commit is contained in:
committed by
Ilya Kirillov
parent
aa173783aa
commit
be90db7fca
+33
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
* Copyright 2010-2018 JetBrains s.r.o. 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.j2k.conversions
|
||||
|
||||
import org.jetbrains.kotlin.j2k.ConversionContext
|
||||
import org.jetbrains.kotlin.j2k.asAssignmentFromTarget
|
||||
import org.jetbrains.kotlin.j2k.findUsages
|
||||
import org.jetbrains.kotlin.j2k.hasWritableUsages
|
||||
import org.jetbrains.kotlin.j2k.tree.*
|
||||
import org.jetbrains.kotlin.j2k.tree.impl.*
|
||||
|
||||
|
||||
class ParameterModificationInMethodCallsConversion(private val context: ConversionContext) : RecursiveApplicableConversionBase() {
|
||||
override fun applyToElement(element: JKTreeElement): JKTreeElement {
|
||||
if (element !is JKMethod) return recurse(element)
|
||||
val newVariables =
|
||||
element.parameters.mapNotNull { parameter ->
|
||||
if (parameter.hasWritableUsages(element.block, context)) {
|
||||
JKLocalVariableImpl(
|
||||
JKTypeElementImpl(parameter.type.type),
|
||||
JKNameIdentifierImpl(parameter.name.value),
|
||||
JKFieldAccessExpressionImpl(context.symbolProvider.provideUniverseSymbol(parameter)),
|
||||
Mutability.MUTABLE
|
||||
)
|
||||
} else null
|
||||
}
|
||||
element.block.statements = listOf(JKDeclarationStatementImpl(newVariables)) + element.block.statements
|
||||
return recurse(element)
|
||||
}
|
||||
}
|
||||
@@ -8,6 +8,7 @@ package org.jetbrains.kotlin.j2k
|
||||
import com.intellij.psi.PsiElement
|
||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
||||
import org.jetbrains.kotlin.j2k.ast.Nullability
|
||||
import org.jetbrains.kotlin.j2k.conversions.RecursiveApplicableConversionBase
|
||||
import org.jetbrains.kotlin.j2k.conversions.multiResolveFqName
|
||||
import org.jetbrains.kotlin.j2k.conversions.resolveFqName
|
||||
import org.jetbrains.kotlin.j2k.tree.*
|
||||
@@ -220,3 +221,41 @@ fun throwAnnotation(throws: List<JKType>, symbolProvider: JKSymbolProvider) =
|
||||
}
|
||||
)
|
||||
)
|
||||
|
||||
fun JKVariable.findUsages(scope: JKTreeElement, context: ConversionContext): List<JKFieldAccessExpression> {
|
||||
val symbol = context.symbolProvider.provideUniverseSymbol(this)
|
||||
val usages = mutableListOf<JKFieldAccessExpression>()
|
||||
val searcher = object : RecursiveApplicableConversionBase() {
|
||||
override fun applyToElement(element: JKTreeElement): JKTreeElement {
|
||||
if (element is JKExpression) {
|
||||
element.unboxFieldReference()?.also {
|
||||
if (it.identifier == symbol) {
|
||||
usages += it
|
||||
}
|
||||
}
|
||||
}
|
||||
return recurse(element)
|
||||
}
|
||||
}
|
||||
searcher.runConversion(scope, context)
|
||||
return usages
|
||||
}
|
||||
|
||||
fun JKExpression.unboxFieldReference(): JKFieldAccessExpression? = when {
|
||||
this is JKFieldAccessExpression -> this
|
||||
this is JKQualifiedExpression && receiver is JKThisExpression -> selector as? JKFieldAccessExpression
|
||||
else -> null
|
||||
}
|
||||
|
||||
fun JKFieldAccessExpression.asAssignmentFromTarget(): JKKtAssignmentStatement? =
|
||||
(parent as? JKKtAssignmentStatement)
|
||||
?.takeIf { it.field == this }
|
||||
|
||||
fun JKFieldAccessExpression.isInDecrementOrIncrement(): Boolean =
|
||||
(parent as? JKUnaryExpression)?.operator?.token?.text in listOf("++", "--")
|
||||
|
||||
fun JKVariable.hasWritableUsages(scope: JKTreeElement, context: ConversionContext): Boolean =
|
||||
findUsages(scope, context).any {
|
||||
it.asAssignmentFromTarget() != null
|
||||
|| it.isInDecrementOrIncrement()
|
||||
}
|
||||
Reference in New Issue
Block a user