Raw FIR: get rid of array gets, use array sets only for modifications

(a[b] += c etc. cannot be replaced with get/set calls easily)
This commit is contained in:
Mikhail Glukhikh
2019-04-05 13:15:59 +03:00
parent a0c4e2f05f
commit d736a7da6b
11 changed files with 30 additions and 95 deletions
@@ -471,9 +471,21 @@ internal fun KtExpression?.generateAssignment(
}
if (this is KtArrayAccessExpression) {
val arrayExpression = this.arrayExpression
val arraySet = FirArraySetCallImpl(session, psi, value, operation).apply {
for (indexExpression in indexExpressions) {
indexes += indexExpression.convert()
val firArrayExpression = arrayExpression?.convert() ?: FirErrorExpressionImpl(session, arrayExpression, "No array expression")
val arraySet = if (operation != FirOperation.ASSIGN) {
FirArraySetCallImpl(session, psi, value, operation).apply {
for (indexExpression in indexExpressions) {
indexes += indexExpression.convert()
}
}
} else {
return FirFunctionCallImpl(session, psi).apply {
calleeReference = FirSimpleNamedReference(session, psi, OperatorNameConventions.SET)
explicitReceiver = firArrayExpression
for (indexExpression in indexExpressions) {
arguments += indexExpression.convert()
}
arguments += value
}
}
if (arrayExpression is KtSimpleNameExpression) {
@@ -483,10 +495,7 @@ internal fun KtExpression?.generateAssignment(
}
return FirBlockImpl(session, arrayExpression).apply {
val name = Name.special("<array-set>")
statements += generateTemporaryVariable(
session, this@generateAssignment, name,
arrayExpression?.convert() ?: FirErrorExpressionImpl(session, arrayExpression, "No array expression")
)
statements += generateTemporaryVariable(session, this@generateAssignment, name, firArrayExpression)
statements += arraySet.apply { lValue = FirSimpleNamedReference(session, arrayExpression, name) }
}
}
@@ -1251,7 +1251,9 @@ class RawFirBuilder(val session: FirSession, val stubMode: Boolean) {
override fun visitArrayAccessExpression(expression: KtArrayAccessExpression, data: Unit): FirElement {
val arrayExpression = expression.arrayExpression
return FirArrayGetCallImpl(session, expression, arrayExpression.toFirExpression("No array expression")).apply {
return FirFunctionCallImpl(session, expression).apply {
calleeReference = FirSimpleNamedReference(this@RawFirBuilder.session, expression, OperatorNameConventions.GET)
explicitReceiver = arrayExpression.toFirExpression("No array expression")
for (indexExpression in expression.indexExpressions) {
arguments += indexExpression.toFirExpression("Incorrect index expression")
}
@@ -12,5 +12,5 @@ FILE: arrayAccess.kt
}
public? final? fun test(a: IntArray, w: Wrapper): <implicit> {
^test a#[Int(0)].plus#(a#[p#]).plus#(a#[foo#()]).plus#(w#.v#[Int(0)])
^test a#.get#(Int(0)).plus#(a#.get#(p#)).plus#(a#.get#(foo#())).plus#(w#.v#.get#(Int(0)))
}
@@ -1,12 +1,11 @@
FILE: arrayAssignment.kt
public? final? fun test(): kotlin/Unit {
lval x: <implicit> = intArrayOf#(Int(1), Int(2), Int(3))
x#[Int(1)] = Int(0)
x#.set#(Int(1), Int(0))
}
public? final? fun foo(): <implicit> {
^foo Int(1)
}
public? final? fun test2(): kotlin/Unit {
lval <array-set>: <implicit> = intArrayOf#(Int(1), Int(2), Int(3))
<array-set>#[foo#()] = Int(1)
intArrayOf#(Int(1), Int(2), Int(3)).set#(foo#(), Int(1))
}
@@ -58,15 +58,15 @@ FILE: unary.kt
}
public? final? fun test3(arr: Array<Int>): kotlin/Unit {
lval x1: <implicit> = {
lval <unary>: <implicit> = arr#[Int(0)]
arr#[Int(0)] = inc#(<unary>#)
lval <unary>: <implicit> = arr#.get#(Int(0))
arr#.set#(Int(0), inc#(<unary>#))
<unary>#
}
lval x2: <implicit> = {
lval <unary>: <implicit> = arr#[Int(1)]
lval <unary>: <implicit> = arr#.get#(Int(1))
lval <unary-result>: <implicit> = inc#(<unary>#)
arr#[Int(1)] = <unary-result>#
arr#.set#(Int(1), <unary-result>#)
<unary-result>#
}
@@ -80,17 +80,15 @@ FILE: unary.kt
}
public? final? fun test4(y: Y): kotlin/Unit {
lval x1: <implicit> = {
lval <unary>: <implicit> = y#.arr#[Int(0)]
lval <array-set>: <implicit> = y#.arr#
<array-set>#[Int(0)] = inc#(<unary>#)
lval <unary>: <implicit> = y#.arr#.get#(Int(0))
y#.arr#.set#(Int(0), inc#(<unary>#))
<unary>#
}
lval x2: <implicit> = {
lval <unary>: <implicit> = y#.arr#[Int(1)]
lval <unary>: <implicit> = y#.arr#.get#(Int(1))
lval <unary-result>: <implicit> = inc#(<unary>#)
lval <array-set>: <implicit> = y#.arr#
<array-set>#[Int(1)] = <unary-result>#
y#.arr#.set#(Int(1), <unary-result>#)
<unary-result>#
}
@@ -858,14 +858,6 @@ class FirRenderer(builder: StringBuilder) : FirVisitorVoid() {
visitCall(operatorCall)
}
override fun visitArrayGetCall(arrayGetCall: FirArrayGetCall) {
arrayGetCall.annotations.renderAnnotations()
arrayGetCall.array.accept(this)
print("[")
arrayGetCall.arguments.renderSeparated()
print("]")
}
override fun visitComponentCall(componentCall: FirComponentCall) {
componentCall.annotations.renderAnnotations()
componentCall.explicitReceiver.accept(this)
@@ -1,20 +0,0 @@
/*
* Copyright 2010-2019 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.fir.expressions
import org.jetbrains.kotlin.fir.visitors.FirVisitor
interface FirArrayGetCall : FirCall {
val array: FirExpression
override fun <R, D> accept(visitor: FirVisitor<R, D>, data: D): R =
visitor.visitArrayGetCall(this, data)
override fun <R, D> acceptChildren(visitor: FirVisitor<R, D>, data: D) {
array.accept(visitor, data)
super.acceptChildren(visitor, data)
}
}
@@ -1,25 +0,0 @@
/*
* Copyright 2010-2019 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.fir.expressions.impl
import com.intellij.psi.PsiElement
import org.jetbrains.kotlin.fir.FirElement
import org.jetbrains.kotlin.fir.FirSession
import org.jetbrains.kotlin.fir.expressions.FirArrayGetCall
import org.jetbrains.kotlin.fir.expressions.FirExpression
import org.jetbrains.kotlin.fir.transformSingle
import org.jetbrains.kotlin.fir.visitors.FirTransformer
class FirArrayGetCallImpl(
session: FirSession,
psi: PsiElement?,
override var array: FirExpression
) : FirAbstractCall(session, psi), FirArrayGetCall {
override fun <D> transformChildren(transformer: FirTransformer<D>, data: D): FirElement {
array = array.transformSingle(transformer, data)
return super<FirAbstractCall>.transformChildren(transformer, data)
}
}
@@ -200,10 +200,6 @@ abstract class FirTransformer<in D> : FirVisitor<CompositeTransformResult<FirEle
return transformCall(annotationCall, data)
}
open fun transformArrayGetCall(arrayGetCall: FirArrayGetCall, data: D): CompositeTransformResult<FirStatement> {
return transformCall(arrayGetCall, data)
}
open fun transformArrayOfCall(arrayOfCall: FirArrayOfCall, data: D): CompositeTransformResult<FirStatement> {
return transformCall(arrayOfCall, data)
}
@@ -396,10 +392,6 @@ abstract class FirTransformer<in D> : FirVisitor<CompositeTransformResult<FirEle
return transformAnonymousObject(anonymousObject, data)
}
final override fun visitArrayGetCall(arrayGetCall: FirArrayGetCall, data: D): CompositeTransformResult<FirElement> {
return transformArrayGetCall(arrayGetCall, data)
}
final override fun visitArrayOfCall(arrayOfCall: FirArrayOfCall, data: D): CompositeTransformResult<FirElement> {
return transformArrayOfCall(arrayOfCall, data)
}
@@ -200,10 +200,6 @@ abstract class FirVisitor<out R, in D> {
return visitCall(annotationCall, data)
}
open fun visitArrayGetCall(arrayGetCall: FirArrayGetCall, data: D): R {
return visitCall(arrayGetCall, data)
}
open fun visitArrayOfCall(arrayOfCall: FirArrayOfCall, data: D): R {
return visitCall(arrayOfCall, data)
}
@@ -200,10 +200,6 @@ abstract class FirVisitorVoid : FirVisitor<Unit, Nothing?>() {
visitCall(annotationCall, null)
}
open fun visitArrayGetCall(arrayGetCall: FirArrayGetCall) {
visitCall(arrayGetCall, null)
}
open fun visitArrayOfCall(arrayOfCall: FirArrayOfCall) {
visitCall(arrayOfCall, null)
}
@@ -396,10 +392,6 @@ abstract class FirVisitorVoid : FirVisitor<Unit, Nothing?>() {
visitAnonymousObject(anonymousObject)
}
final override fun visitArrayGetCall(arrayGetCall: FirArrayGetCall, data: Nothing?) {
visitArrayGetCall(arrayGetCall)
}
final override fun visitArrayOfCall(arrayOfCall: FirArrayOfCall, data: Nothing?) {
visitArrayOfCall(arrayOfCall)
}