Introduce name hints for temporary variables.
Split IrValue.kt into a subpackage.
This commit is contained in:
committed by
Dmitry Petrov
parent
177acaabf5
commit
888b1685ed
@@ -22,6 +22,8 @@ import org.jetbrains.kotlin.ir.expressions.*
|
||||
import org.jetbrains.kotlin.psi.KtExpression
|
||||
import org.jetbrains.kotlin.psi.psiUtil.endOffset
|
||||
import org.jetbrains.kotlin.psi.psiUtil.startOffset
|
||||
import org.jetbrains.kotlin.psi2ir.generators.values.IrTemporaryVariableValue
|
||||
import org.jetbrains.kotlin.psi2ir.generators.values.IrValue
|
||||
import org.jetbrains.kotlin.psi2ir.toExpectedType
|
||||
import org.jetbrains.kotlin.resolve.calls.callUtil.isSafeCall
|
||||
import org.jetbrains.kotlin.resolve.calls.model.*
|
||||
@@ -151,8 +153,9 @@ class IrCallGenerator(val irStatementGenerator: IrStatementGenerator) : IrGenera
|
||||
|
||||
val temporariesForValueArguments = HashMap<ResolvedValueArgument, Pair<VariableDescriptor, IrExpression>>()
|
||||
for (valueArgument in valueArgumentsInEvaluationOrder) {
|
||||
val irArgument = generateValueArgument(valueArgument, valueArgumentsToValueParameters[valueArgument]!!) ?: continue
|
||||
val irTemporary = temporaryVariableFactory.createTemporaryVariable(irArgument)
|
||||
val valueParameter = valueArgumentsToValueParameters[valueArgument]!!
|
||||
val irArgument = generateValueArgument(valueArgument, valueParameter) ?: continue
|
||||
val irTemporary = temporaryVariableFactory.createTemporaryVariable(irArgument, valueParameter.name.asString())
|
||||
temporariesForValueArguments[valueArgument] = Pair(irTemporary.descriptor, irArgument)
|
||||
irBlock.addStatement(irTemporary)
|
||||
}
|
||||
|
||||
+2
-1
@@ -25,6 +25,7 @@ import org.jetbrains.kotlin.lexer.KtTokens
|
||||
import org.jetbrains.kotlin.psi.KtArrayAccessExpression
|
||||
import org.jetbrains.kotlin.psi.KtBinaryExpression
|
||||
import org.jetbrains.kotlin.psi.KtExpression
|
||||
import org.jetbrains.kotlin.psi2ir.generators.values.*
|
||||
import org.jetbrains.kotlin.resolve.BindingContext
|
||||
import org.jetbrains.kotlin.resolve.calls.callUtil.isSafeCall
|
||||
|
||||
@@ -96,7 +97,7 @@ class IrOperatorExpressionGenerator(val irStatementGenerator: IrStatementGenerat
|
||||
val indexedGetCall = get(BindingContext.INDEXED_LVALUE_GET, ktLeft)
|
||||
val indexedSetCall = get(BindingContext.INDEXED_LVALUE_SET, ktLeft)
|
||||
return IrIndexedLValue(irStatementGenerator, ktLeft, irOperator,
|
||||
irArrayValue, indexExpressions, indexedGetCall, indexedSetCall)
|
||||
irArrayValue, indexExpressions, indexedGetCall, indexedSetCall)
|
||||
}
|
||||
|
||||
val resolvedCall = getResolvedCall(ktLeft) ?: TODO("no resolved call for LHS")
|
||||
|
||||
+1
@@ -26,6 +26,7 @@ import org.jetbrains.kotlin.psi.*
|
||||
import org.jetbrains.kotlin.psi.psiUtil.endOffset
|
||||
import org.jetbrains.kotlin.psi.psiUtil.startOffset
|
||||
import org.jetbrains.kotlin.psi2ir.deparenthesize
|
||||
import org.jetbrains.kotlin.psi2ir.generators.values.IrTemporaryVariableValue
|
||||
import org.jetbrains.kotlin.psi2ir.toExpectedType
|
||||
import org.jetbrains.kotlin.resolve.BindingContext
|
||||
import org.jetbrains.kotlin.resolve.BindingContextUtils
|
||||
|
||||
+1
-1
@@ -35,7 +35,7 @@ class IrTemporaryVariableFactory(val scopeOwner: DeclarationDescriptor) {
|
||||
scopeOwner,
|
||||
Name.identifier(
|
||||
if (nameHint != null)
|
||||
"tmp${nextTemporaryIndex()}\$$nameHint"
|
||||
"tmp${nextTemporaryIndex()}_$nameHint"
|
||||
else
|
||||
"tmp${nextTemporaryIndex()}"
|
||||
),
|
||||
|
||||
+10
-76
@@ -14,87 +14,20 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.psi2ir.generators
|
||||
package org.jetbrains.kotlin.psi2ir.generators.values
|
||||
|
||||
import org.jetbrains.kotlin.descriptors.PropertyDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.VariableDescriptor
|
||||
import org.jetbrains.kotlin.ir.declarations.IrVariable
|
||||
import org.jetbrains.kotlin.ir.expressions.*
|
||||
import org.jetbrains.kotlin.ir.expressions.IrBlockExpression
|
||||
import org.jetbrains.kotlin.ir.expressions.IrBlockExpressionImpl
|
||||
import org.jetbrains.kotlin.ir.expressions.IrExpression
|
||||
import org.jetbrains.kotlin.ir.expressions.IrOperator
|
||||
import org.jetbrains.kotlin.psi.KtArrayAccessExpression
|
||||
import org.jetbrains.kotlin.psi.KtElement
|
||||
import org.jetbrains.kotlin.psi.KtExpression
|
||||
import org.jetbrains.kotlin.psi.psiUtil.endOffset
|
||||
import org.jetbrains.kotlin.psi.psiUtil.startOffset
|
||||
import org.jetbrains.kotlin.psi2ir.createDefaultGetExpression
|
||||
import org.jetbrains.kotlin.psi2ir.toExpectedType
|
||||
import org.jetbrains.kotlin.psi2ir.generators.IrCallGenerator
|
||||
import org.jetbrains.kotlin.psi2ir.generators.IrStatementGenerator
|
||||
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
|
||||
|
||||
interface IrValue {
|
||||
fun load(): IrExpression
|
||||
}
|
||||
|
||||
class IrTemporaryVariableValue(val irVariable: IrVariable) : IrValue {
|
||||
override fun load(): IrExpression =
|
||||
irVariable.createDefaultGetExpression()
|
||||
}
|
||||
|
||||
class IrSingleExpressionValue(val irExpression: IrExpression) : IrValue {
|
||||
override fun load() = irExpression
|
||||
}
|
||||
|
||||
interface IrLValue : IrValue {
|
||||
fun store(irExpression: IrExpression): IrExpression
|
||||
}
|
||||
|
||||
interface IrLValueWithAugmentedStore : IrLValue {
|
||||
fun augmentedStore(operatorCall: ResolvedCall<*>, irRhs: IrExpression): IrExpression
|
||||
}
|
||||
|
||||
class IrVariableLValueValue(
|
||||
val ktElement: KtElement,
|
||||
val irOperator: IrOperator?,
|
||||
val descriptor: VariableDescriptor
|
||||
) : IrLValue {
|
||||
override fun load(): IrExpression =
|
||||
IrGetVariableExpressionImpl(
|
||||
ktElement.startOffset, ktElement.endOffset,
|
||||
descriptor, irOperator
|
||||
)
|
||||
|
||||
override fun store(irExpression: IrExpression): IrExpression =
|
||||
IrSetVariableExpressionImpl(
|
||||
ktElement.startOffset, ktElement.endOffset,
|
||||
descriptor, irExpression.toExpectedType(descriptor.type), irOperator
|
||||
)
|
||||
}
|
||||
|
||||
class IrPropertyLValueValue(
|
||||
val ktElement: KtElement,
|
||||
val irOperator: IrOperator?,
|
||||
val descriptor: PropertyDescriptor,
|
||||
val dispatchReceiver: IrExpression?,
|
||||
val extensionReceiver: IrExpression?,
|
||||
val isSafe: Boolean
|
||||
) : IrLValue {
|
||||
private fun IrPropertyAccessExpression.setReceivers() =
|
||||
apply {
|
||||
dispatchReceiver = this@IrPropertyLValueValue.dispatchReceiver
|
||||
extensionReceiver = this@IrPropertyLValueValue.extensionReceiver
|
||||
}
|
||||
|
||||
override fun load(): IrExpression =
|
||||
IrGetPropertyExpressionImpl(
|
||||
ktElement.startOffset, ktElement.endOffset,
|
||||
descriptor.type, isSafe, descriptor, irOperator
|
||||
).setReceivers()
|
||||
|
||||
override fun store(irExpression: IrExpression): IrExpression =
|
||||
IrSetPropertyExpressionImpl(
|
||||
ktElement.startOffset, ktElement.endOffset,
|
||||
isSafe, descriptor, irExpression.toExpectedType(descriptor.type), irOperator
|
||||
).setReceivers()
|
||||
}
|
||||
|
||||
class IrIndexedLValue(
|
||||
var irStatementGenerator: IrStatementGenerator,
|
||||
val ktArrayAccessExpression: KtArrayAccessExpression,
|
||||
@@ -165,10 +98,11 @@ class IrIndexedLValue(
|
||||
}
|
||||
|
||||
private fun defineContextVariables(irBlock: IrBlockExpression, callGenerator: IrCallGenerator) {
|
||||
irBlock.addStatement(callGenerator.createTemporary(ktArrayAccessExpression.arrayExpression!!, arrayValue.load()))
|
||||
irBlock.addStatement(callGenerator.createTemporary(ktArrayAccessExpression.arrayExpression!!, arrayValue.load(), "array"))
|
||||
|
||||
var index = 0
|
||||
for ((ktIndexExpression, irIndexValue) in indexValues) {
|
||||
irBlock.addStatement(callGenerator.createTemporary(ktIndexExpression, irIndexValue.load()))
|
||||
irBlock.addStatement(callGenerator.createTemporary(ktIndexExpression, irIndexValue.load(), "index${index++}"))
|
||||
}
|
||||
}
|
||||
}
|
||||
+51
@@ -0,0 +1,51 @@
|
||||
/*
|
||||
* Copyright 2010-2016 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.psi2ir.generators.values
|
||||
|
||||
import org.jetbrains.kotlin.descriptors.PropertyDescriptor
|
||||
import org.jetbrains.kotlin.ir.expressions.*
|
||||
import org.jetbrains.kotlin.psi.KtElement
|
||||
import org.jetbrains.kotlin.psi.psiUtil.endOffset
|
||||
import org.jetbrains.kotlin.psi.psiUtil.startOffset
|
||||
import org.jetbrains.kotlin.psi2ir.toExpectedType
|
||||
|
||||
class IrPropertyLValueValue(
|
||||
val ktElement: KtElement,
|
||||
val irOperator: IrOperator?,
|
||||
val descriptor: PropertyDescriptor,
|
||||
val dispatchReceiver: IrExpression?,
|
||||
val extensionReceiver: IrExpression?,
|
||||
val isSafe: Boolean
|
||||
) : IrLValue {
|
||||
private fun IrPropertyAccessExpression.setReceivers() =
|
||||
apply {
|
||||
dispatchReceiver = this@IrPropertyLValueValue.dispatchReceiver
|
||||
extensionReceiver = this@IrPropertyLValueValue.extensionReceiver
|
||||
}
|
||||
|
||||
override fun load(): IrExpression =
|
||||
IrGetPropertyExpressionImpl(
|
||||
ktElement.startOffset, ktElement.endOffset,
|
||||
descriptor.type, isSafe, descriptor, irOperator
|
||||
).setReceivers()
|
||||
|
||||
override fun store(irExpression: IrExpression): IrExpression =
|
||||
IrSetPropertyExpressionImpl(
|
||||
ktElement.startOffset, ktElement.endOffset,
|
||||
isSafe, descriptor, irExpression.toExpectedType(descriptor.type), irOperator
|
||||
).setReceivers()
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
* Copyright 2010-2016 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.psi2ir.generators.values
|
||||
|
||||
import org.jetbrains.kotlin.ir.declarations.IrVariable
|
||||
import org.jetbrains.kotlin.ir.expressions.IrExpression
|
||||
import org.jetbrains.kotlin.psi2ir.createDefaultGetExpression
|
||||
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
|
||||
|
||||
interface IrValue {
|
||||
fun load(): IrExpression
|
||||
}
|
||||
|
||||
class IrTemporaryVariableValue(val irVariable: IrVariable) : IrValue {
|
||||
override fun load(): IrExpression =
|
||||
irVariable.createDefaultGetExpression()
|
||||
}
|
||||
|
||||
class IrSingleExpressionValue(val irExpression: IrExpression) : IrValue {
|
||||
override fun load() = irExpression
|
||||
}
|
||||
|
||||
interface IrLValue : IrValue {
|
||||
fun store(irExpression: IrExpression): IrExpression
|
||||
}
|
||||
|
||||
interface IrLValueWithAugmentedStore : IrLValue {
|
||||
fun augmentedStore(operatorCall: ResolvedCall<*>, irRhs: IrExpression): IrExpression
|
||||
}
|
||||
|
||||
+45
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
* Copyright 2010-2016 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.psi2ir.generators.values
|
||||
|
||||
import org.jetbrains.kotlin.descriptors.VariableDescriptor
|
||||
import org.jetbrains.kotlin.ir.expressions.IrExpression
|
||||
import org.jetbrains.kotlin.ir.expressions.IrGetVariableExpressionImpl
|
||||
import org.jetbrains.kotlin.ir.expressions.IrOperator
|
||||
import org.jetbrains.kotlin.ir.expressions.IrSetVariableExpressionImpl
|
||||
import org.jetbrains.kotlin.psi.KtElement
|
||||
import org.jetbrains.kotlin.psi.psiUtil.endOffset
|
||||
import org.jetbrains.kotlin.psi.psiUtil.startOffset
|
||||
import org.jetbrains.kotlin.psi2ir.toExpectedType
|
||||
|
||||
class IrVariableLValueValue(
|
||||
val ktElement: KtElement,
|
||||
val irOperator: IrOperator?,
|
||||
val descriptor: VariableDescriptor
|
||||
) : IrLValue {
|
||||
override fun load(): IrExpression =
|
||||
IrGetVariableExpressionImpl(
|
||||
ktElement.startOffset, ktElement.endOffset,
|
||||
descriptor, irOperator
|
||||
)
|
||||
|
||||
override fun store(irExpression: IrExpression): IrExpression =
|
||||
IrSetVariableExpressionImpl(
|
||||
ktElement.startOffset, ktElement.endOffset,
|
||||
descriptor, irExpression.toExpectedType(descriptor.type), irOperator
|
||||
)
|
||||
}
|
||||
+4
-4
@@ -5,11 +5,11 @@ IrFile /arrayAssignment.kt
|
||||
VAR val x: kotlin.IntArray
|
||||
CALL .intArrayOf type=kotlin.IntArray operator=
|
||||
elements: DUMMY vararg type=kotlin.Int
|
||||
VAR val tmp0: kotlin.IntArray
|
||||
VAR val tmp0_array: kotlin.IntArray
|
||||
GET_VAR x type=kotlin.IntArray
|
||||
VAR val tmp1: kotlin.Int
|
||||
VAR val tmp1_index0: kotlin.Int
|
||||
LITERAL Int type=kotlin.Int value='1'
|
||||
CALL .set type=kotlin.Unit operator=EQ
|
||||
$this: GET_VAR tmp0 type=kotlin.IntArray
|
||||
index: GET_VAR tmp1 type=kotlin.Int
|
||||
$this: GET_VAR tmp0_array type=kotlin.IntArray
|
||||
index: GET_VAR tmp1_index0 type=kotlin.Int
|
||||
value: LITERAL Int type=kotlin.Int value='0'
|
||||
|
||||
+12
-12
@@ -10,27 +10,27 @@ IrFile /augmentedAssignmentArray.kt
|
||||
BLOCK type=<no-type> hasResult=false isDesugared=false
|
||||
VAR var x: kotlin.IntArray
|
||||
CALL .foo type=kotlin.IntArray operator=
|
||||
VAR val tmp0: kotlin.IntArray
|
||||
VAR val tmp0_array: kotlin.IntArray
|
||||
GET_VAR x type=kotlin.IntArray
|
||||
VAR val tmp1: kotlin.Int
|
||||
VAR val tmp1_index0: kotlin.Int
|
||||
LITERAL Int type=kotlin.Int value='0'
|
||||
CALL .set type=kotlin.Unit operator=PLUSEQ
|
||||
$this: GET_VAR tmp0 type=kotlin.IntArray
|
||||
index: GET_VAR tmp1 type=kotlin.Int
|
||||
$this: GET_VAR tmp0_array type=kotlin.IntArray
|
||||
index: GET_VAR tmp1_index0 type=kotlin.Int
|
||||
value: CALL .plus type=kotlin.Int operator=PLUSEQ
|
||||
$this: CALL .get type=kotlin.Int operator=PLUSEQ
|
||||
$this: GET_VAR tmp0 type=kotlin.IntArray
|
||||
index: GET_VAR tmp1 type=kotlin.Int
|
||||
$this: GET_VAR tmp0_array type=kotlin.IntArray
|
||||
index: GET_VAR tmp1_index0 type=kotlin.Int
|
||||
other: LITERAL Int type=kotlin.Int value='1'
|
||||
VAR val tmp2: kotlin.IntArray
|
||||
VAR val tmp2_array: kotlin.IntArray
|
||||
CALL .foo type=kotlin.IntArray operator=
|
||||
VAR val tmp3: kotlin.Int
|
||||
VAR val tmp3_index0: kotlin.Int
|
||||
LITERAL Int type=kotlin.Int value='0'
|
||||
CALL .set type=kotlin.Unit operator=MULTEQ
|
||||
$this: GET_VAR tmp2 type=kotlin.IntArray
|
||||
index: GET_VAR tmp3 type=kotlin.Int
|
||||
$this: GET_VAR tmp2_array type=kotlin.IntArray
|
||||
index: GET_VAR tmp3_index0 type=kotlin.Int
|
||||
value: CALL .times type=kotlin.Int operator=MULTEQ
|
||||
$this: CALL .get type=kotlin.Int operator=MULTEQ
|
||||
$this: GET_VAR tmp2 type=kotlin.IntArray
|
||||
index: GET_VAR tmp3 type=kotlin.Int
|
||||
$this: GET_VAR tmp2_array type=kotlin.IntArray
|
||||
index: GET_VAR tmp3_index0 type=kotlin.Int
|
||||
other: LITERAL Int type=kotlin.Int value='2'
|
||||
|
||||
@@ -28,10 +28,10 @@ IrFile /callWithReorderedArguments.kt
|
||||
CALL .foo type=kotlin.Unit operator=
|
||||
a: CALL .noReorder1 type=kotlin.Int operator=
|
||||
b: CALL .noReorder2 type=kotlin.Int operator=
|
||||
VAR val tmp0: kotlin.Int
|
||||
VAR val tmp0_b: kotlin.Int
|
||||
CALL .reordered1 type=kotlin.Int operator=
|
||||
VAR val tmp1: kotlin.Int
|
||||
VAR val tmp1_a: kotlin.Int
|
||||
CALL .reordered2 type=kotlin.Int operator=
|
||||
CALL .foo type=kotlin.Unit operator=
|
||||
a: GET_VAR tmp1 type=kotlin.Int
|
||||
b: GET_VAR tmp0 type=kotlin.Int
|
||||
a: GET_VAR tmp1_a type=kotlin.Int
|
||||
b: GET_VAR tmp0_b type=kotlin.Int
|
||||
|
||||
Reference in New Issue
Block a user