New J2K: Add JKElement.detached function

This commit is contained in:
Ilya Kirillov
2018-11-01 13:09:54 +03:00
committed by Ilya Kirillov
parent 753070b6c7
commit 1851239e7e
5 changed files with 35 additions and 26 deletions
@@ -30,7 +30,7 @@ class FieldInitializersInPrimaryFromParamsConversion : TransformerBasedConversio
(it as? JKField)?.name?.value == fieldTarget.name.value
} as? JKField ?: continue
if (!fieldDeclaration.type.type.equalsByName(parameter.type.type)) continue//TODO better way to compare types??
parameter.modifierList = fieldDeclaration.modifierList.also { it.detach(it.parent!!) }
parameter.modifierList = fieldDeclaration::modifierList.detached()
containingClass.declarationList -= fieldDeclaration
if (parameter.name.value != fieldTarget.name.value) {
@@ -42,7 +42,7 @@ class FieldInitializersInPrimaryFromParamsConversion : TransformerBasedConversio
}
ktPrimaryConstructor.block.statements -= removedStatements
if (ktPrimaryConstructor.block.statements.isNotEmpty()) {
ktPrimaryConstructor.block.detach(ktPrimaryConstructor)
ktPrimaryConstructor::block.detached()
containingClass.getOrCreateInitDeclaration().block = ktPrimaryConstructor.block
}
}
@@ -29,7 +29,7 @@ class ForConversion(private val context: ConversionContext) : RecursiveApplicabl
private fun convertToWhile(loopStatement: JKJavaForLoopStatement): JKStatement? {
val whileBody = createWhileBody(loopStatement)
val condition =
if (loopStatement.condition !is JKStubExpression) loopStatement.condition.detached()
if (loopStatement.condition !is JKStubExpression) loopStatement::condition.detached()
else JKKtLiteralExpressionImpl("true", JKLiteralExpression.LiteralType.BOOLEAN)
val whileStatement = JKWhileStatementImpl(condition, whileBody)
@@ -37,7 +37,7 @@ class ForConversion(private val context: ConversionContext) : RecursiveApplicabl
//TODO check for error conflict
return JKKtConvertedFromForLoopSyntheticWhileStatementImpl(
loopStatement.initializer.detached(),
loopStatement::initializer.detached(),
JKWhileStatementImpl(condition, whileBody)
)
}
@@ -55,7 +55,7 @@ class ForConversion(private val context: ConversionContext) : RecursiveApplicabl
}
val body = loopStatement.body
val body = loopStatement::body.detached()
if (body is JKBlockStatement) {
val initializer = loopStatement.initializer
@@ -70,15 +70,16 @@ class ForConversion(private val context: ConversionContext) : RecursiveApplicabl
val statements =
if (hasNameConflict) {
listOf(continueStatementConverter.applyToElement(body) as JKStatement, loopStatement.updater)
listOf(continueStatementConverter.applyToElement(body) as JKStatement, loopStatement::updater.detached())
} else {
body.block.statements + loopStatement.updater
body.block::statements.detached() + loopStatement::updater.detached()
}
return JKBlockStatementImpl(JKBlockImpl(statements.map { it.detached() }))
return JKBlockStatementImpl(JKBlockImpl(statements))
} else {
val statements =
listOf(continueStatementConverter.applyToElement(body) as JKStatement, loopStatement::updater.detached())
return JKBlockStatementImpl(JKBlockImpl(statements.map { it.detached() }))
return JKBlockStatementImpl(JKBlockImpl(statements))
}
}
@@ -91,10 +92,10 @@ class ForConversion(private val context: ConversionContext) : RecursiveApplicabl
&& !loopVarPsi.hasWriteAccesses(referenceSearcher, loopStatement.condition.psi())
) {
val left = condition.left as? JKFieldAccessExpression ?: return null
val right = condition.right
val right = condition::right.detached()
if (right.psi<PsiExpression>()?.type in listOf(PsiType.DOUBLE, PsiType.FLOAT, PsiType.CHAR)) return null
if (left.identifier.target != loopVar) return null
val start = loopVar.initializer
val start = loopVar::initializer.detached()
val operationType =
(loopStatement.updater as? JKExpressionStatement)?.expression?.isVariableIncrementOrDecrement(loopVar)
val reversed = when ((operationType as? JKJavaOperatorImpl)?.token?.psiToken) {
@@ -116,9 +117,9 @@ class ForConversion(private val context: ConversionContext) : RecursiveApplicabl
// JKJavaPrimitiveTypeImpl.INT
// else null
return JKKtForInStatementImpl(
loopVar.name.detached(),
range.detached(),
loopStatement.body.detached()
loopVar::name.detached(),
range,
loopStatement::body.detached()
)
}
@@ -141,8 +142,6 @@ class ForConversion(private val context: ConversionContext) : RecursiveApplicabl
psiContext: PsiElement
): JKExpression {
indicesIterationRange(start, bound, reversed, inclusiveComparison)?.also { return it }
if (start.parent != null) start.detach(start.parent!!)
if (bound.parent != null) bound.detach(bound.parent!!)
return when {
reversed -> downToExpression(
start,
@@ -215,7 +214,7 @@ class ForConversion(private val context: ConversionContext) : RecursiveApplicabl
multiResolveFqName(ClassId.fromString("kotlin/collections/reversed"), psiContext).first()
) as JKMethodSymbol
JKQualifiedExpressionImpl(
indices.detached(),
indices,
JKKtQualifierImpl.DOT,
JKJavaMethodCallExpressionImpl(reversedSymbol, JKExpressionListImpl())
)
@@ -6,10 +6,7 @@
package org.jetbrains.kotlin.j2k.conversions
import com.intellij.psi.PsiClass
import org.jetbrains.kotlin.j2k.tree.JKBinaryExpression
import org.jetbrains.kotlin.j2k.tree.JKClassType
import org.jetbrains.kotlin.j2k.tree.JKJavaInstanceOfExpression
import org.jetbrains.kotlin.j2k.tree.JKTreeElement
import org.jetbrains.kotlin.j2k.tree.*
import org.jetbrains.kotlin.j2k.tree.impl.*
import org.jetbrains.kotlin.psi.KtClass
@@ -35,6 +32,6 @@ class InstanceOfConversion : RecursiveApplicableConversionBase() {
)
} else checkingType
return recurse(JKKtIsExpressionImpl(element.expression.also { it.detach(it.parent!!) }, JKTypeElementImpl(type)))
return recurse(JKKtIsExpressionImpl(element::expression.detached(), JKTypeElementImpl(type)))
}
}
@@ -51,7 +51,5 @@ fun rangeExpression(
val symbol = conversionContext.symbolProvider.provideDirectSymbol(
multiResolveFqName(ClassId.fromString("kotlin/ranges/$operatorName"), psiContext).first()
) as JKMethodSymbol
if (from.parent != null) from.detach(from.parent!!)
if (to.parent != null) to.detach(to.parent!!)
return JKKtOperatorExpressionImpl(from, symbol, to)
}
@@ -19,6 +19,8 @@ package org.jetbrains.kotlin.j2k.tree
import org.jetbrains.kotlin.j2k.ast.Nullability
import org.jetbrains.kotlin.j2k.tree.impl.JKClassSymbol
import org.jetbrains.kotlin.resolve.jvm.JvmPrimitiveType
import kotlin.reflect.KProperty0
import kotlin.jvm.internal.CallableReference
interface JKOperator {
val token: JKOperatorToken
@@ -91,5 +93,18 @@ inline fun <reified T> JKElement.getParentOfType(): T? {
}
}
fun <T : JKElement> T.detached() =
also { if (parent != null) detach(parent!!) }
private fun <T : JKElement> KProperty0<Any>.detach(element: T) {
if (element.parent == null) return
// TODO: Fix when KT-16818 is implemented
val boundReceiver = (this as CallableReference).boundReceiver
require(boundReceiver != CallableReference.NO_RECEIVER)
require(boundReceiver is JKElement)
element.detach(boundReceiver)
}
fun <T : JKElement> KProperty0<T>.detached(): T =
get().also { detach(it) }
fun <T : JKElement> KProperty0<List<T>>.detached(): List<T> =
get().also { list -> list.forEach { detach(it) } }