Refactoring.
'if' expressions (represented as 'when' without subject).
This commit is contained in:
committed by
Dmitry Petrov
parent
1ddf889d8a
commit
5709826096
@@ -16,6 +16,7 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.psi2ir
|
package org.jetbrains.kotlin.psi2ir
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
||||||
import org.jetbrains.kotlin.ir.declarations.IrVariable
|
import org.jetbrains.kotlin.ir.declarations.IrVariable
|
||||||
import org.jetbrains.kotlin.ir.expressions.*
|
import org.jetbrains.kotlin.ir.expressions.*
|
||||||
import org.jetbrains.kotlin.types.KotlinType
|
import org.jetbrains.kotlin.types.KotlinType
|
||||||
@@ -24,6 +25,8 @@ import org.jetbrains.kotlin.types.isNullabilityFlexible
|
|||||||
|
|
||||||
fun IrExpression.toExpectedType(expectedType: KotlinType?): IrExpression {
|
fun IrExpression.toExpectedType(expectedType: KotlinType?): IrExpression {
|
||||||
if (expectedType == null) return this
|
if (expectedType == null) return this
|
||||||
|
if (KotlinBuiltIns.isUnit(expectedType)) return this // TODO expose coercion to Unit in IR?
|
||||||
|
|
||||||
val valueType = type ?: throw AssertionError("expectedType != null, valueType == null: $this")
|
val valueType = type ?: throw AssertionError("expectedType != null, valueType == null: $this")
|
||||||
|
|
||||||
if (valueType.isNullabilityFlexible() && !expectedType.isMarkedNullable) {
|
if (valueType.isNullabilityFlexible() && !expectedType.isMarkedNullable) {
|
||||||
|
|||||||
@@ -20,8 +20,8 @@ import org.jetbrains.kotlin.descriptors.ModuleDescriptor
|
|||||||
import org.jetbrains.kotlin.ir.IrElement
|
import org.jetbrains.kotlin.ir.IrElement
|
||||||
import org.jetbrains.kotlin.ir.declarations.IrModule
|
import org.jetbrains.kotlin.ir.declarations.IrModule
|
||||||
import org.jetbrains.kotlin.psi.KtFile
|
import org.jetbrains.kotlin.psi.KtFile
|
||||||
import org.jetbrains.kotlin.psi2ir.generators.IrGeneratorContext
|
import org.jetbrains.kotlin.psi2ir.generators.GeneratorContext
|
||||||
import org.jetbrains.kotlin.psi2ir.generators.IrModuleGenerator
|
import org.jetbrains.kotlin.psi2ir.generators.ModuleGenerator
|
||||||
import org.jetbrains.kotlin.psi2ir.transformations.foldStringConcatenation
|
import org.jetbrains.kotlin.psi2ir.transformations.foldStringConcatenation
|
||||||
import org.jetbrains.kotlin.psi2ir.transformations.inlineDesugaredBlocks
|
import org.jetbrains.kotlin.psi2ir.transformations.inlineDesugaredBlocks
|
||||||
import org.jetbrains.kotlin.resolve.BindingContext
|
import org.jetbrains.kotlin.resolve.BindingContext
|
||||||
@@ -33,8 +33,8 @@ class Psi2IrTranslator(val configuration: Configuration = Configuration()) {
|
|||||||
)
|
)
|
||||||
|
|
||||||
fun generateModule(moduleDescriptor: ModuleDescriptor, ktFiles: List<KtFile>, bindingContext: BindingContext): IrModule {
|
fun generateModule(moduleDescriptor: ModuleDescriptor, ktFiles: List<KtFile>, bindingContext: BindingContext): IrModule {
|
||||||
val irGeneratorContext = IrGeneratorContext(moduleDescriptor, bindingContext)
|
val irGeneratorContext = GeneratorContext(moduleDescriptor, bindingContext)
|
||||||
val irModule = IrModuleGenerator(irGeneratorContext).generateModule(ktFiles)
|
val irModule = ModuleGenerator(irGeneratorContext).generateModule(ktFiles)
|
||||||
postprocess(irModule)
|
postprocess(irModule)
|
||||||
return irModule
|
return irModule
|
||||||
}
|
}
|
||||||
|
|||||||
+9
-9
@@ -22,7 +22,7 @@ import org.jetbrains.kotlin.ir.expressions.*
|
|||||||
import org.jetbrains.kotlin.psi.KtExpression
|
import org.jetbrains.kotlin.psi.KtExpression
|
||||||
import org.jetbrains.kotlin.psi.psiUtil.endOffset
|
import org.jetbrains.kotlin.psi.psiUtil.endOffset
|
||||||
import org.jetbrains.kotlin.psi.psiUtil.startOffset
|
import org.jetbrains.kotlin.psi.psiUtil.startOffset
|
||||||
import org.jetbrains.kotlin.psi2ir.generators.values.IrVariableLValue
|
import org.jetbrains.kotlin.psi2ir.generators.values.VariableLValue
|
||||||
import org.jetbrains.kotlin.psi2ir.generators.values.IrValue
|
import org.jetbrains.kotlin.psi2ir.generators.values.IrValue
|
||||||
import org.jetbrains.kotlin.psi2ir.generators.values.createRematerializableValue
|
import org.jetbrains.kotlin.psi2ir.generators.values.createRematerializableValue
|
||||||
import org.jetbrains.kotlin.psi2ir.toExpectedType
|
import org.jetbrains.kotlin.psi2ir.toExpectedType
|
||||||
@@ -32,12 +32,12 @@ import org.jetbrains.kotlin.resolve.scopes.receivers.*
|
|||||||
import org.jetbrains.kotlin.types.KotlinType
|
import org.jetbrains.kotlin.types.KotlinType
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
|
||||||
class IrCallGenerator(val irStatementGenerator: IrStatementGenerator) : IrGenerator {
|
class CallGenerator(val statementGenerator: StatementGenerator) : IrGenerator {
|
||||||
override val context: IrGeneratorContext get() =
|
override val context: GeneratorContext get() =
|
||||||
irStatementGenerator.context
|
statementGenerator.context
|
||||||
|
|
||||||
private val temporaryVariableFactory: IrTemporaryVariableFactory get() =
|
private val temporaryVariableFactory: TemporaryVariableFactory get() =
|
||||||
irStatementGenerator.temporaryVariableFactory
|
statementGenerator.temporaryVariableFactory
|
||||||
|
|
||||||
private val expressionValues = HashMap<KtExpression, IrValue>()
|
private val expressionValues = HashMap<KtExpression, IrValue>()
|
||||||
private val receiverValues = HashMap<ReceiverValue, IrValue>()
|
private val receiverValues = HashMap<ReceiverValue, IrValue>()
|
||||||
@@ -51,7 +51,7 @@ class IrCallGenerator(val irStatementGenerator: IrStatementGenerator) : IrGenera
|
|||||||
}
|
}
|
||||||
|
|
||||||
val irTmpVar = temporaryVariableFactory.createTemporaryVariable(irExpression, nameHint)
|
val irTmpVar = temporaryVariableFactory.createTemporaryVariable(irExpression, nameHint)
|
||||||
putValue(ktExpression, IrVariableLValue(irTmpVar))
|
putValue(ktExpression, VariableLValue(irTmpVar))
|
||||||
return irTmpVar
|
return irTmpVar
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -63,7 +63,7 @@ class IrCallGenerator(val irStatementGenerator: IrStatementGenerator) : IrGenera
|
|||||||
}
|
}
|
||||||
|
|
||||||
val irTmpVar = temporaryVariableFactory.createTemporaryVariable(irExpression, valueParameterDescriptor.name.asString())
|
val irTmpVar = temporaryVariableFactory.createTemporaryVariable(irExpression, valueParameterDescriptor.name.asString())
|
||||||
putValue(valueParameterDescriptor, IrVariableLValue(irTmpVar))
|
putValue(valueParameterDescriptor, VariableLValue(irTmpVar))
|
||||||
return irTmpVar
|
return irTmpVar
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -249,6 +249,6 @@ class IrCallGenerator(val irStatementGenerator: IrStatementGenerator) : IrGenera
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun generateExpression(ktExpression: KtExpression): IrExpression =
|
private fun generateExpression(ktExpression: KtExpression): IrExpression =
|
||||||
expressionValues[ktExpression]?.load() ?: irStatementGenerator.generateExpression(ktExpression)
|
expressionValues[ktExpression]?.load() ?: statementGenerator.generateExpression(ktExpression)
|
||||||
|
|
||||||
}
|
}
|
||||||
+2
-2
@@ -28,7 +28,7 @@ import org.jetbrains.kotlin.utils.SmartList
|
|||||||
import org.jetbrains.kotlin.utils.addIfNotNull
|
import org.jetbrains.kotlin.utils.addIfNotNull
|
||||||
import org.jetbrains.kotlin.utils.addToStdlib.singletonList
|
import org.jetbrains.kotlin.utils.addToStdlib.singletonList
|
||||||
|
|
||||||
class IrDeclarationGenerator(override val context: IrGeneratorContext) : IrGenerator {
|
class DeclarationGenerator(override val context: GeneratorContext) : IrGenerator {
|
||||||
fun generateAnnotationEntries(annotationEntries: List<KtAnnotationEntry>) {
|
fun generateAnnotationEntries(annotationEntries: List<KtAnnotationEntry>) {
|
||||||
// TODO create IrAnnotation's for each KtAnnotationEntry
|
// TODO create IrAnnotation's for each KtAnnotationEntry
|
||||||
}
|
}
|
||||||
@@ -140,7 +140,7 @@ class IrDeclarationGenerator(override val context: IrGeneratorContext) : IrGener
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun generateExpressionWithinContext(ktExpression: KtExpression, scopeOwner: DeclarationDescriptor): IrExpression =
|
private fun generateExpressionWithinContext(ktExpression: KtExpression, scopeOwner: DeclarationDescriptor): IrExpression =
|
||||||
IrStatementGenerator(context, scopeOwner, IrTemporaryVariableFactory(scopeOwner))
|
StatementGenerator(context, scopeOwner, TemporaryVariableFactory(scopeOwner))
|
||||||
.generateExpression(ktExpression)
|
.generateExpression(ktExpression)
|
||||||
.toExpectedType(getExpectedTypeForLastInferredCall(ktExpression))
|
.toExpectedType(getExpectedTypeForLastInferredCall(ktExpression))
|
||||||
|
|
||||||
+1
-1
@@ -33,7 +33,7 @@ import org.jetbrains.kotlin.types.typeUtil.makeNullable
|
|||||||
import org.jetbrains.kotlin.util.slicedMap.ReadOnlySlice
|
import org.jetbrains.kotlin.util.slicedMap.ReadOnlySlice
|
||||||
|
|
||||||
interface IrGenerator {
|
interface IrGenerator {
|
||||||
val context: IrGeneratorContext
|
val context: GeneratorContext
|
||||||
}
|
}
|
||||||
|
|
||||||
fun <K, V : Any> IrGenerator.get(slice: ReadOnlySlice<K, V>, key: K): V? =
|
fun <K, V : Any> IrGenerator.get(slice: ReadOnlySlice<K, V>, key: K): V? =
|
||||||
+1
-1
@@ -23,7 +23,7 @@ import org.jetbrains.kotlin.psi.KtFile
|
|||||||
import org.jetbrains.kotlin.psi2ir.PsiSourceManager
|
import org.jetbrains.kotlin.psi2ir.PsiSourceManager
|
||||||
import org.jetbrains.kotlin.resolve.BindingContext
|
import org.jetbrains.kotlin.resolve.BindingContext
|
||||||
|
|
||||||
class IrGeneratorContext(
|
class GeneratorContext(
|
||||||
val moduleDescriptor: ModuleDescriptor,
|
val moduleDescriptor: ModuleDescriptor,
|
||||||
val bindingContext: BindingContext
|
val bindingContext: BindingContext
|
||||||
) {
|
) {
|
||||||
+2
-2
@@ -20,9 +20,9 @@ import org.jetbrains.kotlin.ir.declarations.*
|
|||||||
import org.jetbrains.kotlin.psi.KtFile
|
import org.jetbrains.kotlin.psi.KtFile
|
||||||
import org.jetbrains.kotlin.resolve.BindingContext
|
import org.jetbrains.kotlin.resolve.BindingContext
|
||||||
|
|
||||||
class IrModuleGenerator(override val context: IrGeneratorContext) : IrGenerator {
|
class ModuleGenerator(override val context: GeneratorContext) : IrGenerator {
|
||||||
fun generateModule(ktFiles: List<KtFile>): IrModule {
|
fun generateModule(ktFiles: List<KtFile>): IrModule {
|
||||||
val irDeclarationGenerator = IrDeclarationGenerator(context)
|
val irDeclarationGenerator = DeclarationGenerator(context)
|
||||||
|
|
||||||
val irModule = IrModuleImpl(context.moduleDescriptor)
|
val irModule = IrModuleImpl(context.moduleDescriptor)
|
||||||
for (ktFile in ktFiles) {
|
for (ktFile in ktFiles) {
|
||||||
+30
-28
@@ -20,12 +20,10 @@ import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
|||||||
import org.jetbrains.kotlin.descriptors.CallableDescriptor
|
import org.jetbrains.kotlin.descriptors.CallableDescriptor
|
||||||
import org.jetbrains.kotlin.descriptors.PropertyDescriptor
|
import org.jetbrains.kotlin.descriptors.PropertyDescriptor
|
||||||
import org.jetbrains.kotlin.descriptors.impl.LocalVariableDescriptor
|
import org.jetbrains.kotlin.descriptors.impl.LocalVariableDescriptor
|
||||||
|
import org.jetbrains.kotlin.ir.IrStatement
|
||||||
import org.jetbrains.kotlin.ir.expressions.*
|
import org.jetbrains.kotlin.ir.expressions.*
|
||||||
import org.jetbrains.kotlin.lexer.KtTokens
|
import org.jetbrains.kotlin.lexer.KtTokens
|
||||||
import org.jetbrains.kotlin.psi.KtArrayAccessExpression
|
import org.jetbrains.kotlin.psi.*
|
||||||
import org.jetbrains.kotlin.psi.KtBinaryExpression
|
|
||||||
import org.jetbrains.kotlin.psi.KtExpression
|
|
||||||
import org.jetbrains.kotlin.psi.KtPrefixExpression
|
|
||||||
import org.jetbrains.kotlin.psi.psiUtil.endOffset
|
import org.jetbrains.kotlin.psi.psiUtil.endOffset
|
||||||
import org.jetbrains.kotlin.psi.psiUtil.startOffset
|
import org.jetbrains.kotlin.psi.psiUtil.startOffset
|
||||||
import org.jetbrains.kotlin.psi2ir.generators.values.*
|
import org.jetbrains.kotlin.psi2ir.generators.values.*
|
||||||
@@ -36,8 +34,8 @@ import org.jetbrains.kotlin.resolve.calls.callUtil.isSafeCall
|
|||||||
import org.jetbrains.kotlin.types.typeUtil.makeNullable
|
import org.jetbrains.kotlin.types.typeUtil.makeNullable
|
||||||
|
|
||||||
|
|
||||||
class IrOperatorExpressionGenerator(val irStatementGenerator: IrStatementGenerator): IrGenerator {
|
class OperatorExpressionGenerator(val statementGenerator: StatementGenerator): IrGenerator {
|
||||||
override val context: IrGeneratorContext get() = irStatementGenerator.context
|
override val context: GeneratorContext get() = statementGenerator.context
|
||||||
|
|
||||||
fun generatePrefixExpression(expression: KtPrefixExpression): IrExpression {
|
fun generatePrefixExpression(expression: KtPrefixExpression): IrExpression {
|
||||||
val ktOperator = expression.operationReference.getReferencedNameElementType()
|
val ktOperator = expression.operationReference.getReferencedNameElementType()
|
||||||
@@ -50,6 +48,10 @@ class IrOperatorExpressionGenerator(val irStatementGenerator: IrStatementGenerat
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun generatePostfixExpression(expression: KtPostfixExpression): IrExpression {
|
||||||
|
TODO("not implemented")
|
||||||
|
}
|
||||||
|
|
||||||
fun generateBinaryExpression(expression: KtBinaryExpression): IrExpression {
|
fun generateBinaryExpression(expression: KtBinaryExpression): IrExpression {
|
||||||
val ktOperator = expression.operationReference.getReferencedNameElementType()
|
val ktOperator = expression.operationReference.getReferencedNameElementType()
|
||||||
if (ktOperator == KtTokens.IDENTIFIER) {
|
if (ktOperator == KtTokens.IDENTIFIER) {
|
||||||
@@ -77,8 +79,8 @@ class IrOperatorExpressionGenerator(val irStatementGenerator: IrStatementGenerat
|
|||||||
// TODO desugar '?:' to 'if'?
|
// TODO desugar '?:' to 'if'?
|
||||||
val specialCallForElvis = getResolvedCall(expression)!!
|
val specialCallForElvis = getResolvedCall(expression)!!
|
||||||
val returnType = specialCallForElvis.resultingDescriptor.returnType!!
|
val returnType = specialCallForElvis.resultingDescriptor.returnType!!
|
||||||
val irArgument0 = irStatementGenerator.generateExpression(expression.left!!).toExpectedType(returnType.makeNullable())
|
val irArgument0 = statementGenerator.generateExpression(expression.left!!).toExpectedType(returnType.makeNullable())
|
||||||
val irArgument1 = irStatementGenerator.generateExpression(expression.right!!).toExpectedType(returnType)
|
val irArgument1 = statementGenerator.generateExpression(expression.right!!).toExpectedType(returnType)
|
||||||
return IrBinaryOperatorExpressionImpl(
|
return IrBinaryOperatorExpressionImpl(
|
||||||
expression.startOffset, expression.endOffset, returnType,
|
expression.startOffset, expression.endOffset, returnType,
|
||||||
IrOperator.ELVIS, null, irArgument0, irArgument1
|
IrOperator.ELVIS, null, irArgument0, irArgument1
|
||||||
@@ -86,8 +88,8 @@ class IrOperatorExpressionGenerator(val irStatementGenerator: IrStatementGenerat
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun generateBinaryBooleanOperator(expression: KtBinaryExpression, irOperator: IrBinaryOperator): IrExpression {
|
private fun generateBinaryBooleanOperator(expression: KtBinaryExpression, irOperator: IrBinaryOperator): IrExpression {
|
||||||
val irArgument0 = irStatementGenerator.generateExpression(expression.left!!).toExpectedType(context.builtIns.booleanType)
|
val irArgument0 = statementGenerator.generateExpression(expression.left!!).toExpectedType(context.builtIns.booleanType)
|
||||||
val irArgument1 = irStatementGenerator.generateExpression(expression.right!!).toExpectedType(context.builtIns.booleanType)
|
val irArgument1 = statementGenerator.generateExpression(expression.right!!).toExpectedType(context.builtIns.booleanType)
|
||||||
return IrBinaryOperatorExpressionImpl(
|
return IrBinaryOperatorExpressionImpl(
|
||||||
expression.startOffset, expression.endOffset, context.builtIns.booleanType,
|
expression.startOffset, expression.endOffset, context.builtIns.booleanType,
|
||||||
irOperator, getResolvedCall(expression)?.resultingDescriptor, irArgument0, irArgument1
|
irOperator, getResolvedCall(expression)?.resultingDescriptor, irArgument0, irArgument1
|
||||||
@@ -97,7 +99,7 @@ class IrOperatorExpressionGenerator(val irStatementGenerator: IrStatementGenerat
|
|||||||
private fun generateInOperator(expression: KtBinaryExpression, irOperator: IrOperator): IrExpression {
|
private fun generateInOperator(expression: KtBinaryExpression, irOperator: IrOperator): IrExpression {
|
||||||
val operatorCall = getResolvedCall(expression)!!
|
val operatorCall = getResolvedCall(expression)!!
|
||||||
|
|
||||||
val irOperatorCall = IrCallGenerator(irStatementGenerator).generateCall(expression, operatorCall, irOperator)
|
val irOperatorCall = CallGenerator(statementGenerator).generateCall(expression, operatorCall, irOperator)
|
||||||
|
|
||||||
return if (irOperator == IrOperator.IN)
|
return if (irOperator == IrOperator.IN)
|
||||||
irOperatorCall
|
irOperatorCall
|
||||||
@@ -107,8 +109,8 @@ class IrOperatorExpressionGenerator(val irStatementGenerator: IrStatementGenerat
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun generateIdentityOperator(expression: KtBinaryExpression, irOperator: IrBinaryOperator): IrExpression {
|
private fun generateIdentityOperator(expression: KtBinaryExpression, irOperator: IrBinaryOperator): IrExpression {
|
||||||
val irArgument0 = irStatementGenerator.generateExpression(expression.left!!)
|
val irArgument0 = statementGenerator.generateExpression(expression.left!!)
|
||||||
val irArgument1 = irStatementGenerator.generateExpression(expression.right!!)
|
val irArgument1 = statementGenerator.generateExpression(expression.right!!)
|
||||||
return IrBinaryOperatorExpressionImpl(
|
return IrBinaryOperatorExpressionImpl(
|
||||||
expression.startOffset, expression.endOffset, context.builtIns.booleanType,
|
expression.startOffset, expression.endOffset, context.builtIns.booleanType,
|
||||||
irOperator, null, irArgument0, irArgument1
|
irOperator, null, irArgument0, irArgument1
|
||||||
@@ -119,7 +121,7 @@ class IrOperatorExpressionGenerator(val irStatementGenerator: IrStatementGenerat
|
|||||||
val relatedCall = getResolvedCall(expression)!!
|
val relatedCall = getResolvedCall(expression)!!
|
||||||
val relatedDescriptor = relatedCall.resultingDescriptor
|
val relatedDescriptor = relatedCall.resultingDescriptor
|
||||||
|
|
||||||
val irCallGenerator = IrCallGenerator(irStatementGenerator)
|
val irCallGenerator = CallGenerator(statementGenerator)
|
||||||
|
|
||||||
// NB special typing rules for equality operators: both arguments are nullable
|
// NB special typing rules for equality operators: both arguments are nullable
|
||||||
|
|
||||||
@@ -144,7 +146,7 @@ class IrOperatorExpressionGenerator(val irStatementGenerator: IrStatementGenerat
|
|||||||
val compareToCall = getResolvedCall(expression)!!
|
val compareToCall = getResolvedCall(expression)!!
|
||||||
val compareToDescriptor = compareToCall.resultingDescriptor
|
val compareToDescriptor = compareToCall.resultingDescriptor
|
||||||
|
|
||||||
val irCallGenerator = IrCallGenerator(irStatementGenerator)
|
val irCallGenerator = CallGenerator(statementGenerator)
|
||||||
|
|
||||||
return if (shouldKeepComparisonAsBinaryOperation(compareToDescriptor)) {
|
return if (shouldKeepComparisonAsBinaryOperation(compareToDescriptor)) {
|
||||||
val irArgument0 = irCallGenerator.generateReceiver(expression.left!!, compareToCall.dispatchReceiver, compareToDescriptor.dispatchReceiverParameter!!)!!
|
val irArgument0 = irCallGenerator.generateReceiver(expression.left!!, compareToCall.dispatchReceiver, compareToDescriptor.dispatchReceiverParameter!!)!!
|
||||||
@@ -172,7 +174,7 @@ class IrOperatorExpressionGenerator(val irStatementGenerator: IrStatementGenerat
|
|||||||
|
|
||||||
private fun generateBinaryOperatorWithConventionalCall(expression: KtBinaryExpression, irOperator: IrOperator?): IrExpression {
|
private fun generateBinaryOperatorWithConventionalCall(expression: KtBinaryExpression, irOperator: IrOperator?): IrExpression {
|
||||||
val operatorCall = getResolvedCall(expression)!!
|
val operatorCall = getResolvedCall(expression)!!
|
||||||
return IrCallGenerator(irStatementGenerator).generateCall(expression, operatorCall, irOperator)
|
return CallGenerator(statementGenerator).generateCall(expression, operatorCall, irOperator)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun generatePrefixIncrementDecrementOperator(expression: KtPrefixExpression, irOperator: IrOperator): IrExpression {
|
private fun generatePrefixIncrementDecrementOperator(expression: KtPrefixExpression, irOperator: IrOperator): IrExpression {
|
||||||
@@ -184,10 +186,10 @@ class IrOperatorExpressionGenerator(val irStatementGenerator: IrStatementGenerat
|
|||||||
return irLValue.prefixAugmentedStore(operatorCall, irOperator)
|
return irLValue.prefixAugmentedStore(operatorCall, irOperator)
|
||||||
}
|
}
|
||||||
|
|
||||||
val opCallGenerator = IrCallGenerator(irStatementGenerator).apply { putValue(ktBaseExpression, irLValue) }
|
val opCallGenerator = CallGenerator(statementGenerator).apply { putValue(ktBaseExpression, irLValue) }
|
||||||
val irBlock = IrBlockExpressionImpl(expression.startOffset, expression.endOffset, irLValue.type, true, irOperator)
|
val irBlock = IrBlockExpressionImpl(expression.startOffset, expression.endOffset, irLValue.type, true, irOperator)
|
||||||
val irOpCall = opCallGenerator.generateCall(expression, operatorCall, irOperator)
|
val irOpCall = opCallGenerator.generateCall(expression, operatorCall, irOperator)
|
||||||
val irTmp = irStatementGenerator.temporaryVariableFactory.createTemporaryVariable(irOpCall)
|
val irTmp = statementGenerator.temporaryVariableFactory.createTemporaryVariable(irOpCall)
|
||||||
irBlock.addStatement(irTmp)
|
irBlock.addStatement(irTmp)
|
||||||
irBlock.addStatement(irLValue.store(irTmp.load()))
|
irBlock.addStatement(irLValue.store(irTmp.load()))
|
||||||
irBlock.addStatement(irTmp.load())
|
irBlock.addStatement(irTmp.load())
|
||||||
@@ -202,10 +204,10 @@ class IrOperatorExpressionGenerator(val irStatementGenerator: IrStatementGenerat
|
|||||||
val isSimpleAssignment = get(BindingContext.VARIABLE_REASSIGNMENT, expression) ?: false
|
val isSimpleAssignment = get(BindingContext.VARIABLE_REASSIGNMENT, expression) ?: false
|
||||||
|
|
||||||
if (isSimpleAssignment && irLValue is IrLValueWithAugmentedStore) {
|
if (isSimpleAssignment && irLValue is IrLValueWithAugmentedStore) {
|
||||||
return irLValue.augmentedStore(operatorCall, irOperator, irStatementGenerator.generateExpression(expression.right!!))
|
return irLValue.augmentedStore(operatorCall, irOperator, statementGenerator.generateExpression(expression.right!!))
|
||||||
}
|
}
|
||||||
|
|
||||||
val opCallGenerator = IrCallGenerator(irStatementGenerator).apply { putValue(ktLeft, irLValue) }
|
val opCallGenerator = CallGenerator(statementGenerator).apply { putValue(ktLeft, irLValue) }
|
||||||
val irOpCall = opCallGenerator.generateCall(expression, operatorCall, irOperator)
|
val irOpCall = opCallGenerator.generateCall(expression, operatorCall, irOperator)
|
||||||
|
|
||||||
return if (isSimpleAssignment) {
|
return if (isSimpleAssignment) {
|
||||||
@@ -222,20 +224,20 @@ class IrOperatorExpressionGenerator(val irStatementGenerator: IrStatementGenerat
|
|||||||
val ktLeft = expression.left!!
|
val ktLeft = expression.left!!
|
||||||
val ktRight = expression.right!!
|
val ktRight = expression.right!!
|
||||||
val irLValue = generateLValue(ktLeft, IrOperator.EQ)
|
val irLValue = generateLValue(ktLeft, IrOperator.EQ)
|
||||||
return irLValue.store(irStatementGenerator.generateExpression(ktRight))
|
return irLValue.store(statementGenerator.generateExpression(ktRight))
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun generateLValue(ktLeft: KtExpression, irOperator: IrOperator?): IrLValue {
|
private fun generateLValue(ktLeft: KtExpression, irOperator: IrOperator?): IrLValue {
|
||||||
if (ktLeft is KtArrayAccessExpression) {
|
if (ktLeft is KtArrayAccessExpression) {
|
||||||
val irArrayValue = irStatementGenerator.generateExpression(ktLeft.arrayExpression!!)
|
val irArrayValue = statementGenerator.generateExpression(ktLeft.arrayExpression!!)
|
||||||
val indexExpressions = ktLeft.indexExpressions.map { it to irStatementGenerator.generateExpression(it) }
|
val indexExpressions = ktLeft.indexExpressions.map { it to statementGenerator.generateExpression(it) }
|
||||||
val indexedGetCall = get(BindingContext.INDEXED_LVALUE_GET, ktLeft)
|
val indexedGetCall = get(BindingContext.INDEXED_LVALUE_GET, ktLeft)
|
||||||
val indexedSetCall = get(BindingContext.INDEXED_LVALUE_SET, ktLeft)
|
val indexedSetCall = get(BindingContext.INDEXED_LVALUE_SET, ktLeft)
|
||||||
val type = indexedGetCall?.run { resultingDescriptor.returnType }
|
val type = indexedGetCall?.run { resultingDescriptor.returnType }
|
||||||
?: indexedSetCall?.run { resultingDescriptor.valueParameters.last().type }
|
?: indexedSetCall?.run { resultingDescriptor.valueParameters.last().type }
|
||||||
?: throw AssertionError("Either 'get' or 'set' call should be present for an indexed LValue: ${ktLeft.text}")
|
?: throw AssertionError("Either 'get' or 'set' call should be present for an indexed LValue: ${ktLeft.text}")
|
||||||
return IrIndexedLValue(irStatementGenerator, ktLeft, irOperator,
|
return IndexedLValue(statementGenerator, ktLeft, irOperator,
|
||||||
irArrayValue, type, indexExpressions, indexedGetCall, indexedSetCall)
|
irArrayValue, type, indexExpressions, indexedGetCall, indexedSetCall)
|
||||||
}
|
}
|
||||||
|
|
||||||
val resolvedCall = getResolvedCall(ktLeft) ?: TODO("no resolved call for LHS")
|
val resolvedCall = getResolvedCall(ktLeft) ?: TODO("no resolved call for LHS")
|
||||||
@@ -246,10 +248,10 @@ class IrOperatorExpressionGenerator(val irStatementGenerator: IrStatementGenerat
|
|||||||
if (descriptor.isDelegated)
|
if (descriptor.isDelegated)
|
||||||
TODO("Delegated local variable")
|
TODO("Delegated local variable")
|
||||||
else
|
else
|
||||||
IrVariableLValue(ktLeft.startOffset, ktLeft.endOffset, descriptor, irOperator)
|
VariableLValue(ktLeft.startOffset, ktLeft.endOffset, descriptor, irOperator)
|
||||||
is PropertyDescriptor ->
|
is PropertyDescriptor ->
|
||||||
IrCallGenerator(irStatementGenerator).run {
|
CallGenerator(statementGenerator).run {
|
||||||
IrPropertyLValue(
|
PropertyLValue(
|
||||||
ktLeft, irOperator, descriptor,
|
ktLeft, irOperator, descriptor,
|
||||||
generateReceiver(ktLeft, resolvedCall.dispatchReceiver, descriptor.dispatchReceiverParameter),
|
generateReceiver(ktLeft, resolvedCall.dispatchReceiver, descriptor.dispatchReceiverParameter),
|
||||||
generateReceiver(ktLeft, resolvedCall.extensionReceiver, descriptor.extensionReceiverParameter),
|
generateReceiver(ktLeft, resolvedCall.extensionReceiver, descriptor.extensionReceiverParameter),
|
||||||
+41
-11
@@ -26,7 +26,7 @@ import org.jetbrains.kotlin.psi.*
|
|||||||
import org.jetbrains.kotlin.psi.psiUtil.endOffset
|
import org.jetbrains.kotlin.psi.psiUtil.endOffset
|
||||||
import org.jetbrains.kotlin.psi.psiUtil.startOffset
|
import org.jetbrains.kotlin.psi.psiUtil.startOffset
|
||||||
import org.jetbrains.kotlin.psi2ir.deparenthesize
|
import org.jetbrains.kotlin.psi2ir.deparenthesize
|
||||||
import org.jetbrains.kotlin.psi2ir.generators.values.IrVariableLValue
|
import org.jetbrains.kotlin.psi2ir.generators.values.VariableLValue
|
||||||
import org.jetbrains.kotlin.psi2ir.toExpectedType
|
import org.jetbrains.kotlin.psi2ir.toExpectedType
|
||||||
import org.jetbrains.kotlin.resolve.BindingContext
|
import org.jetbrains.kotlin.resolve.BindingContext
|
||||||
import org.jetbrains.kotlin.resolve.BindingContextUtils
|
import org.jetbrains.kotlin.resolve.BindingContextUtils
|
||||||
@@ -38,17 +38,17 @@ import org.jetbrains.kotlin.resolve.constants.evaluate.ConstantExpressionEvaluat
|
|||||||
import org.jetbrains.kotlin.resolve.descriptorUtil.classValueType
|
import org.jetbrains.kotlin.resolve.descriptorUtil.classValueType
|
||||||
import org.jetbrains.kotlin.types.expressions.ExpressionTypingUtils
|
import org.jetbrains.kotlin.types.expressions.ExpressionTypingUtils
|
||||||
|
|
||||||
class IrStatementGenerator(
|
class StatementGenerator(
|
||||||
override val context: IrGeneratorContext,
|
override val context: GeneratorContext,
|
||||||
val scopeOwner: DeclarationDescriptor,
|
val scopeOwner: DeclarationDescriptor,
|
||||||
val temporaryVariableFactory: IrTemporaryVariableFactory
|
val temporaryVariableFactory: TemporaryVariableFactory
|
||||||
) : KtVisitor<IrStatement, Nothing?>(), IrGenerator {
|
) : KtVisitor<IrStatement, Nothing?>(), IrGenerator {
|
||||||
|
|
||||||
fun generateExpression(ktExpression: KtExpression): IrExpression =
|
fun generateExpression(ktExpression: KtExpression): IrExpression =
|
||||||
ktExpression.genExpr()
|
ktExpression.genExpr()
|
||||||
|
|
||||||
private fun KtElement.genStmt(): IrStatement =
|
private fun KtElement.genStmt(): IrStatement =
|
||||||
deparenthesize().accept(this@IrStatementGenerator, null)
|
deparenthesize().accept(this@StatementGenerator, null)
|
||||||
|
|
||||||
private fun KtElement.genExpr(): IrExpression =
|
private fun KtElement.genExpr(): IrExpression =
|
||||||
genStmt().assertCast()
|
genStmt().assertCast()
|
||||||
@@ -77,8 +77,8 @@ class IrStatementGenerator(
|
|||||||
val irTmpInitializer = temporaryVariableFactory.createTemporaryVariable(ktInitializer.genExpr())
|
val irTmpInitializer = temporaryVariableFactory.createTemporaryVariable(ktInitializer.genExpr())
|
||||||
irBlock.addStatement(irTmpInitializer)
|
irBlock.addStatement(irTmpInitializer)
|
||||||
|
|
||||||
val irCallGenerator = IrCallGenerator(this)
|
val irCallGenerator = CallGenerator(this)
|
||||||
irCallGenerator.putValue(ktInitializer, IrVariableLValue(irTmpInitializer))
|
irCallGenerator.putValue(ktInitializer, VariableLValue(irTmpInitializer))
|
||||||
|
|
||||||
for ((index, ktEntry) in multiDeclaration.entries.withIndex()) {
|
for ((index, ktEntry) in multiDeclaration.entries.withIndex()) {
|
||||||
val componentResolvedCall = getOrFail(BindingContext.COMPONENT_RESOLVED_CALL, ktEntry)
|
val componentResolvedCall = getOrFail(BindingContext.COMPONENT_RESOLVED_CALL, ktEntry)
|
||||||
@@ -188,7 +188,7 @@ class IrStatementGenerator(
|
|||||||
companionObjectDescriptor)
|
companionObjectDescriptor)
|
||||||
}
|
}
|
||||||
is PropertyDescriptor -> {
|
is PropertyDescriptor -> {
|
||||||
IrCallGenerator(this).generateCall(expression, resolvedCall)
|
CallGenerator(this).generateCall(expression, resolvedCall)
|
||||||
}
|
}
|
||||||
is VariableDescriptor ->
|
is VariableDescriptor ->
|
||||||
IrGetVariableExpressionImpl(expression.startOffset, expression.endOffset, descriptor)
|
IrGetVariableExpressionImpl(expression.startOffset, expression.endOffset, descriptor)
|
||||||
@@ -207,7 +207,7 @@ class IrStatementGenerator(
|
|||||||
TODO("VariableAsFunctionResolvedCall = variable call + invoke call")
|
TODO("VariableAsFunctionResolvedCall = variable call + invoke call")
|
||||||
}
|
}
|
||||||
|
|
||||||
return IrCallGenerator(this).generateCall(expression, resolvedCall)
|
return CallGenerator(this).generateCall(expression, resolvedCall)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun visitDotQualifiedExpression(expression: KtDotQualifiedExpression, data: Nothing?): IrStatement =
|
override fun visitDotQualifiedExpression(expression: KtDotQualifiedExpression, data: Nothing?): IrStatement =
|
||||||
@@ -239,8 +239,38 @@ class IrStatementGenerator(
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun visitBinaryExpression(expression: KtBinaryExpression, data: Nothing?): IrStatement =
|
override fun visitBinaryExpression(expression: KtBinaryExpression, data: Nothing?): IrStatement =
|
||||||
IrOperatorExpressionGenerator(this).generateBinaryExpression(expression)
|
OperatorExpressionGenerator(this).generateBinaryExpression(expression)
|
||||||
|
|
||||||
override fun visitPrefixExpression(expression: KtPrefixExpression, data: Nothing?): IrStatement =
|
override fun visitPrefixExpression(expression: KtPrefixExpression, data: Nothing?): IrStatement =
|
||||||
IrOperatorExpressionGenerator(this).generatePrefixExpression(expression)
|
OperatorExpressionGenerator(this).generatePrefixExpression(expression)
|
||||||
|
|
||||||
|
override fun visitPostfixExpression(expression: KtPostfixExpression, data: Nothing?): IrStatement =
|
||||||
|
OperatorExpressionGenerator(this).generatePostfixExpression(expression)
|
||||||
|
|
||||||
|
override fun visitIfExpression(expression: KtIfExpression, data: Nothing?): IrStatement {
|
||||||
|
val resultType = getInferredTypeWithSmartcasts(expression)
|
||||||
|
val irWhen = IrWhenExpressionImpl(expression.startOffset, expression.endOffset, resultType)
|
||||||
|
|
||||||
|
var ktBranch: KtIfExpression? = expression
|
||||||
|
branches@while (ktBranch != null) {
|
||||||
|
val irBranch = IrBranchImpl(ktBranch.startOffset, ktBranch.endOffset,
|
||||||
|
ktBranch.condition!!.genExpr().toExpectedType(context.builtIns.booleanType),
|
||||||
|
ktBranch.then!!.genExpr().toExpectedType(resultType))
|
||||||
|
irWhen.addBranch(irBranch)
|
||||||
|
|
||||||
|
val ktElse = ktBranch.`else`
|
||||||
|
|
||||||
|
ktBranch = when (ktElse) {
|
||||||
|
is KtIfExpression -> ktElse
|
||||||
|
null ->
|
||||||
|
break@branches
|
||||||
|
else -> {
|
||||||
|
irWhen.elseExpression = ktElse.genExpr().toExpectedType(resultType)
|
||||||
|
break@branches
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return irWhen
|
||||||
|
}
|
||||||
}
|
}
|
||||||
+1
-1
@@ -26,7 +26,7 @@ import org.jetbrains.kotlin.ir.expressions.IrExpression
|
|||||||
import org.jetbrains.kotlin.name.Name
|
import org.jetbrains.kotlin.name.Name
|
||||||
import org.jetbrains.kotlin.types.KotlinType
|
import org.jetbrains.kotlin.types.KotlinType
|
||||||
|
|
||||||
class IrTemporaryVariableFactory(val scopeOwner: DeclarationDescriptor) {
|
class TemporaryVariableFactory(val scopeOwner: DeclarationDescriptor) {
|
||||||
private var lastTemporaryIndex = 0
|
private var lastTemporaryIndex = 0
|
||||||
private fun nextTemporaryIndex() = lastTemporaryIndex++
|
private fun nextTemporaryIndex() = lastTemporaryIndex++
|
||||||
|
|
||||||
+12
-12
@@ -22,13 +22,13 @@ import org.jetbrains.kotlin.psi.KtExpression
|
|||||||
import org.jetbrains.kotlin.psi.psiUtil.endOffset
|
import org.jetbrains.kotlin.psi.psiUtil.endOffset
|
||||||
import org.jetbrains.kotlin.psi.psiUtil.startOffset
|
import org.jetbrains.kotlin.psi.psiUtil.startOffset
|
||||||
import org.jetbrains.kotlin.psi2ir.load
|
import org.jetbrains.kotlin.psi2ir.load
|
||||||
import org.jetbrains.kotlin.psi2ir.generators.IrCallGenerator
|
import org.jetbrains.kotlin.psi2ir.generators.CallGenerator
|
||||||
import org.jetbrains.kotlin.psi2ir.generators.IrStatementGenerator
|
import org.jetbrains.kotlin.psi2ir.generators.StatementGenerator
|
||||||
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
|
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
|
||||||
import org.jetbrains.kotlin.types.KotlinType
|
import org.jetbrains.kotlin.types.KotlinType
|
||||||
|
|
||||||
class IrIndexedLValue(
|
class IndexedLValue(
|
||||||
var irStatementGenerator: IrStatementGenerator,
|
var statementGenerator: StatementGenerator,
|
||||||
val ktArrayAccessExpression: KtArrayAccessExpression,
|
val ktArrayAccessExpression: KtArrayAccessExpression,
|
||||||
val irOperator: IrOperator?,
|
val irOperator: IrOperator?,
|
||||||
val irArray: IrExpression,
|
val irArray: IrExpression,
|
||||||
@@ -50,7 +50,7 @@ class IrIndexedLValue(
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun generateGetOrSetCallAsDesugaredBlock(call: ResolvedCall<*>, irArgument: IrExpression? = null): IrExpression {
|
private fun generateGetOrSetCallAsDesugaredBlock(call: ResolvedCall<*>, irArgument: IrExpression? = null): IrExpression {
|
||||||
val callGenerator = IrCallGenerator(irStatementGenerator)
|
val callGenerator = CallGenerator(statementGenerator)
|
||||||
setupCallGeneratorContext(callGenerator)
|
setupCallGeneratorContext(callGenerator)
|
||||||
|
|
||||||
if (irArgument != null) {
|
if (irArgument != null) {
|
||||||
@@ -64,19 +64,19 @@ class IrIndexedLValue(
|
|||||||
if (indexedGetCall == null) throw AssertionError("Indexed LValue has no 'get' call: ${ktArrayAccessExpression.text}")
|
if (indexedGetCall == null) throw AssertionError("Indexed LValue has no 'get' call: ${ktArrayAccessExpression.text}")
|
||||||
if (indexedSetCall == null) throw AssertionError("Indexed LValue has no 'set' call: ${ktArrayAccessExpression.text}")
|
if (indexedSetCall == null) throw AssertionError("Indexed LValue has no 'set' call: ${ktArrayAccessExpression.text}")
|
||||||
|
|
||||||
val callGenerator = IrCallGenerator(irStatementGenerator)
|
val callGenerator = CallGenerator(statementGenerator)
|
||||||
|
|
||||||
val irBlock = createDesugaredBlockWithTemporaries(indexedSetCall, callGenerator, true, irOperator)
|
val irBlock = createDesugaredBlockWithTemporaries(indexedSetCall, callGenerator, true, irOperator)
|
||||||
|
|
||||||
val operatorCallReceiver = operatorCall.extensionReceiver ?: operatorCall.dispatchReceiver
|
val operatorCallReceiver = operatorCall.extensionReceiver ?: operatorCall.dispatchReceiver
|
||||||
callGenerator.putValue(operatorCallReceiver!!,
|
callGenerator.putValue(operatorCallReceiver!!,
|
||||||
IrSingleExpressionValue(callGenerator.generateCall(ktArrayAccessExpression, indexedGetCall, irOperator)))
|
IrSingleExpressionValue(callGenerator.generateCall(ktArrayAccessExpression, indexedGetCall, irOperator)))
|
||||||
val irTmp = irStatementGenerator.temporaryVariableFactory.createTemporaryVariable(
|
val irTmp = statementGenerator.temporaryVariableFactory.createTemporaryVariable(
|
||||||
callGenerator.generateCall(ktArrayAccessExpression, operatorCall, irOperator))
|
callGenerator.generateCall(ktArrayAccessExpression, operatorCall, irOperator))
|
||||||
irBlock.addStatement(irTmp)
|
irBlock.addStatement(irTmp)
|
||||||
|
|
||||||
callGenerator.putValue(indexedSetCall.resultingDescriptor.valueParameters.last(),
|
callGenerator.putValue(indexedSetCall.resultingDescriptor.valueParameters.last(),
|
||||||
IrVariableLValue(irTmp))
|
VariableLValue(irTmp))
|
||||||
|
|
||||||
irBlock.addStatement(callGenerator.generateCall(ktArrayAccessExpression, indexedSetCall, irOperator))
|
irBlock.addStatement(callGenerator.generateCall(ktArrayAccessExpression, indexedSetCall, irOperator))
|
||||||
|
|
||||||
@@ -89,7 +89,7 @@ class IrIndexedLValue(
|
|||||||
if (indexedGetCall == null) throw AssertionError("Indexed LValue has no 'get' call: ${ktArrayAccessExpression.text}")
|
if (indexedGetCall == null) throw AssertionError("Indexed LValue has no 'get' call: ${ktArrayAccessExpression.text}")
|
||||||
if (indexedSetCall == null) throw AssertionError("Indexed LValue has no 'set' call: ${ktArrayAccessExpression.text}")
|
if (indexedSetCall == null) throw AssertionError("Indexed LValue has no 'set' call: ${ktArrayAccessExpression.text}")
|
||||||
|
|
||||||
val callGenerator = IrCallGenerator(irStatementGenerator)
|
val callGenerator = CallGenerator(statementGenerator)
|
||||||
|
|
||||||
val irBlock = createDesugaredBlockWithTemporaries(indexedSetCall, callGenerator, false, irOperator)
|
val irBlock = createDesugaredBlockWithTemporaries(indexedSetCall, callGenerator, false, irOperator)
|
||||||
|
|
||||||
@@ -109,7 +109,7 @@ class IrIndexedLValue(
|
|||||||
|
|
||||||
private fun createDesugaredBlockWithTemporaries(
|
private fun createDesugaredBlockWithTemporaries(
|
||||||
call: ResolvedCall<*>,
|
call: ResolvedCall<*>,
|
||||||
callGenerator: IrCallGenerator,
|
callGenerator: CallGenerator,
|
||||||
hasResult: Boolean,
|
hasResult: Boolean,
|
||||||
operator: IrOperator?
|
operator: IrOperator?
|
||||||
): IrBlockExpressionImpl {
|
): IrBlockExpressionImpl {
|
||||||
@@ -124,7 +124,7 @@ class IrIndexedLValue(
|
|||||||
hasResult, operator)
|
hasResult, operator)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun defineTemporaryVariables(irBlock: IrBlockExpression, callGenerator: IrCallGenerator) {
|
private fun defineTemporaryVariables(irBlock: IrBlockExpression, callGenerator: CallGenerator) {
|
||||||
irBlock.addIfNotNull(callGenerator.introduceTemporary(ktArrayAccessExpression.arrayExpression!!, irArray, "array"))
|
irBlock.addIfNotNull(callGenerator.introduceTemporary(ktArrayAccessExpression.arrayExpression!!, irArray, "array"))
|
||||||
|
|
||||||
var index = 0
|
var index = 0
|
||||||
@@ -133,7 +133,7 @@ class IrIndexedLValue(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun setupCallGeneratorContext(callGenerator: IrCallGenerator) {
|
private fun setupCallGeneratorContext(callGenerator: CallGenerator) {
|
||||||
callGenerator.putValue(ktArrayAccessExpression.arrayExpression!!, IrSingleExpressionValue(irArray))
|
callGenerator.putValue(ktArrayAccessExpression.arrayExpression!!, IrSingleExpressionValue(irArray))
|
||||||
|
|
||||||
for ((ktIndexExpression, irIndexValue) in indexValues) {
|
for ((ktIndexExpression, irIndexValue) in indexValues) {
|
||||||
+3
-3
@@ -24,7 +24,7 @@ import org.jetbrains.kotlin.psi.psiUtil.startOffset
|
|||||||
import org.jetbrains.kotlin.psi2ir.toExpectedType
|
import org.jetbrains.kotlin.psi2ir.toExpectedType
|
||||||
import org.jetbrains.kotlin.types.KotlinType
|
import org.jetbrains.kotlin.types.KotlinType
|
||||||
|
|
||||||
class IrPropertyLValue(
|
class PropertyLValue(
|
||||||
val ktElement: KtElement,
|
val ktElement: KtElement,
|
||||||
val irOperator: IrOperator?,
|
val irOperator: IrOperator?,
|
||||||
val descriptor: PropertyDescriptor,
|
val descriptor: PropertyDescriptor,
|
||||||
@@ -37,8 +37,8 @@ class IrPropertyLValue(
|
|||||||
|
|
||||||
private fun IrPropertyAccessExpression.setReceivers() =
|
private fun IrPropertyAccessExpression.setReceivers() =
|
||||||
apply {
|
apply {
|
||||||
dispatchReceiver = this@IrPropertyLValue.dispatchReceiver
|
dispatchReceiver = this@PropertyLValue.dispatchReceiver
|
||||||
extensionReceiver = this@IrPropertyLValue.extensionReceiver
|
extensionReceiver = this@PropertyLValue.extensionReceiver
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun load(): IrExpression =
|
override fun load(): IrExpression =
|
||||||
+1
-1
@@ -25,7 +25,7 @@ import org.jetbrains.kotlin.ir.expressions.IrSetVariableExpressionImpl
|
|||||||
import org.jetbrains.kotlin.psi2ir.toExpectedType
|
import org.jetbrains.kotlin.psi2ir.toExpectedType
|
||||||
import org.jetbrains.kotlin.types.KotlinType
|
import org.jetbrains.kotlin.types.KotlinType
|
||||||
|
|
||||||
class IrVariableLValue(
|
class VariableLValue(
|
||||||
val startOffset: Int,
|
val startOffset: Int,
|
||||||
val endOffset: Int,
|
val endOffset: Int,
|
||||||
val descriptor: VariableDescriptor,
|
val descriptor: VariableDescriptor,
|
||||||
@@ -16,7 +16,6 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.ir
|
package org.jetbrains.kotlin.ir
|
||||||
|
|
||||||
const val CHILD_DECLARATION_SLOT = 0
|
|
||||||
const val DETACHED_SLOT = Int.MIN_VALUE
|
const val DETACHED_SLOT = Int.MIN_VALUE
|
||||||
const val CHILD_EXPRESSION_SLOT = 0
|
const val CHILD_EXPRESSION_SLOT = 0
|
||||||
const val ARGUMENT0_SLOT = 0
|
const val ARGUMENT0_SLOT = 0
|
||||||
@@ -25,4 +24,8 @@ const val DISPATCH_RECEIVER_SLOT = -1
|
|||||||
const val EXTENSION_RECEIVER_SLOT = -2
|
const val EXTENSION_RECEIVER_SLOT = -2
|
||||||
const val FUNCTION_BODY_SLOT = 0
|
const val FUNCTION_BODY_SLOT = 0
|
||||||
const val MODULE_SLOT = 0
|
const val MODULE_SLOT = 0
|
||||||
const val INITIALIZER_SLOT = 0
|
const val INITIALIZER_SLOT = 0
|
||||||
|
const val WHEN_SUBJECT_VARIABLE_SLOT = -1
|
||||||
|
const val WHEN_ELSE_EXPRESSION_SLOT = -2
|
||||||
|
const val BRANCH_CONDITION_SLOT = -1
|
||||||
|
const val BRANCH_RESULT_SLOT = -2
|
||||||
@@ -16,10 +16,7 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.ir.expressions
|
package org.jetbrains.kotlin.ir.expressions
|
||||||
|
|
||||||
import org.jetbrains.kotlin.ir.IrElement
|
import org.jetbrains.kotlin.ir.*
|
||||||
import org.jetbrains.kotlin.ir.IrStatement
|
|
||||||
import org.jetbrains.kotlin.ir.assertCast
|
|
||||||
import org.jetbrains.kotlin.ir.assertDetached
|
|
||||||
import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
|
import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
|
||||||
import org.jetbrains.kotlin.types.KotlinType
|
import org.jetbrains.kotlin.types.KotlinType
|
||||||
import java.util.*
|
import java.util.*
|
||||||
@@ -56,8 +53,11 @@ class IrBlockExpressionImpl(
|
|||||||
statements.getOrNull(slot)
|
statements.getOrNull(slot)
|
||||||
|
|
||||||
override fun replaceChild(slot: Int, newChild: IrElement) {
|
override fun replaceChild(slot: Int, newChild: IrElement) {
|
||||||
|
newChild.assertDetached()
|
||||||
if (0 <= slot && slot < statements.size) {
|
if (0 <= slot && slot < statements.size) {
|
||||||
|
statements[slot].detach()
|
||||||
statements[slot] = newChild.assertCast()
|
statements[slot] = newChild.assertCast()
|
||||||
|
newChild.setTreeLocation(this, slot)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,171 @@
|
|||||||
|
/*
|
||||||
|
* 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.ir.expressions
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.ir.*
|
||||||
|
import org.jetbrains.kotlin.ir.declarations.IrVariable
|
||||||
|
import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
|
||||||
|
import org.jetbrains.kotlin.types.KotlinType
|
||||||
|
import java.util.*
|
||||||
|
|
||||||
|
interface IrWhenExpression : IrExpression {
|
||||||
|
var subject: IrVariable?
|
||||||
|
val branches: List<IrBranch>
|
||||||
|
var elseExpression: IrExpression?
|
||||||
|
|
||||||
|
fun addBranch(branch: IrBranch)
|
||||||
|
}
|
||||||
|
|
||||||
|
interface IrBranch : IrElement {
|
||||||
|
var condition: IrExpression
|
||||||
|
var result: IrExpression
|
||||||
|
}
|
||||||
|
|
||||||
|
class IrWhenExpressionImpl(
|
||||||
|
startOffset: Int,
|
||||||
|
endOffset: Int,
|
||||||
|
type: KotlinType?
|
||||||
|
) : IrExpressionBase(startOffset, endOffset, type), IrWhenExpression {
|
||||||
|
constructor(
|
||||||
|
startOffset: Int,
|
||||||
|
endOffset: Int,
|
||||||
|
type: KotlinType?,
|
||||||
|
subject: IrVariable
|
||||||
|
) : this(startOffset, endOffset, type) {
|
||||||
|
this.subject = subject
|
||||||
|
}
|
||||||
|
|
||||||
|
override var subject: IrVariable? = null
|
||||||
|
set(value) {
|
||||||
|
value?.assertDetached()
|
||||||
|
subject?.detach()
|
||||||
|
field = value
|
||||||
|
field?.setTreeLocation(this, WHEN_SUBJECT_VARIABLE_SLOT)
|
||||||
|
}
|
||||||
|
|
||||||
|
override val branches: MutableList<IrBranch> = ArrayList()
|
||||||
|
|
||||||
|
override var elseExpression: IrExpression? = null
|
||||||
|
set(value) {
|
||||||
|
value?.assertDetached()
|
||||||
|
subject?.detach()
|
||||||
|
field = value
|
||||||
|
field?.setTreeLocation(this, WHEN_ELSE_EXPRESSION_SLOT)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun addBranch(branch: IrBranch) {
|
||||||
|
branch.assertDetached()
|
||||||
|
branch.setTreeLocation(this, branches.size)
|
||||||
|
branches.add(branch)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getChild(slot: Int): IrElement? =
|
||||||
|
when (slot) {
|
||||||
|
WHEN_SUBJECT_VARIABLE_SLOT -> subject
|
||||||
|
WHEN_ELSE_EXPRESSION_SLOT -> elseExpression
|
||||||
|
else -> branches.getOrNull(slot)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun replaceChild(slot: Int, newChild: IrElement) {
|
||||||
|
newChild.assertDetached()
|
||||||
|
when (slot) {
|
||||||
|
WHEN_SUBJECT_VARIABLE_SLOT ->
|
||||||
|
subject = newChild.assertCast()
|
||||||
|
WHEN_ELSE_EXPRESSION_SLOT ->
|
||||||
|
elseExpression = newChild.assertCast()
|
||||||
|
in branches.indices -> {
|
||||||
|
branches[slot].detach()
|
||||||
|
branches[slot] = newChild.assertCast()
|
||||||
|
newChild.setTreeLocation(this, slot)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun <R, D> accept(visitor: IrElementVisitor<R, D>, data: D): R =
|
||||||
|
visitor.visitWhenExpression(this, data)
|
||||||
|
|
||||||
|
override fun <D> acceptChildren(visitor: IrElementVisitor<Unit, D>, data: D) {
|
||||||
|
subject?.accept(visitor, data)
|
||||||
|
branches.forEach { it.accept(visitor, data) }
|
||||||
|
elseExpression?.accept(visitor, data)
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
fun ifThen(startOffset: Int, endOffset: Int, type: KotlinType?, condition: IrExpression, thenExpression: IrExpression) =
|
||||||
|
IrWhenExpressionImpl(startOffset, endOffset, type).apply {
|
||||||
|
addBranch(IrBranchImpl(startOffset, endOffset, condition, thenExpression))
|
||||||
|
}
|
||||||
|
|
||||||
|
fun ifThenElse(startOffset: Int, endOffset: Int, type: KotlinType?,
|
||||||
|
condition: IrExpression, thenExpression: IrExpression, elseExpression: IrExpression) =
|
||||||
|
IrWhenExpressionImpl(startOffset, endOffset, type).apply {
|
||||||
|
addBranch(IrBranchImpl(startOffset, endOffset, condition, thenExpression))
|
||||||
|
this.elseExpression = elseExpression
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class IrBranchImpl(startOffset: Int, endOffset: Int) : IrElementBase(startOffset, endOffset), IrBranch {
|
||||||
|
constructor(startOffset: Int, endOffset: Int, condition: IrExpression, result: IrExpression) : this(startOffset, endOffset) {
|
||||||
|
this.condition = condition
|
||||||
|
this.result = result
|
||||||
|
}
|
||||||
|
|
||||||
|
private var conditionImpl: IrExpression? = null
|
||||||
|
override var condition: IrExpression
|
||||||
|
get() = conditionImpl!!
|
||||||
|
set(value) {
|
||||||
|
value.assertDetached()
|
||||||
|
conditionImpl?.detach()
|
||||||
|
conditionImpl = value
|
||||||
|
value.setTreeLocation(this, BRANCH_CONDITION_SLOT)
|
||||||
|
}
|
||||||
|
|
||||||
|
private var resultImpl: IrExpression? = null
|
||||||
|
override var result: IrExpression
|
||||||
|
get() = resultImpl!!
|
||||||
|
set(value) {
|
||||||
|
value.assertDetached()
|
||||||
|
resultImpl?.detach()
|
||||||
|
resultImpl = value
|
||||||
|
value.setTreeLocation(this, BRANCH_RESULT_SLOT)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getChild(slot: Int): IrElement? =
|
||||||
|
when (slot) {
|
||||||
|
BRANCH_CONDITION_SLOT -> condition
|
||||||
|
BRANCH_RESULT_SLOT -> result
|
||||||
|
else -> null
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun replaceChild(slot: Int, newChild: IrElement) {
|
||||||
|
when (slot) {
|
||||||
|
BRANCH_CONDITION_SLOT ->
|
||||||
|
condition = newChild.assertCast()
|
||||||
|
BRANCH_RESULT_SLOT ->
|
||||||
|
result = newChild.assertCast()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun <R, D> accept(visitor: IrElementVisitor<R, D>, data: D): R =
|
||||||
|
visitor.visitBranch(this, data)
|
||||||
|
|
||||||
|
override fun <D> acceptChildren(visitor: IrElementVisitor<Unit, D>, data: D) {
|
||||||
|
conditionImpl?.accept(visitor, data)
|
||||||
|
resultImpl?.accept(visitor, data)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -22,6 +22,7 @@ import org.jetbrains.kotlin.ir.declarations.IrFile
|
|||||||
import org.jetbrains.kotlin.ir.expressions.IrCallExpression
|
import org.jetbrains.kotlin.ir.expressions.IrCallExpression
|
||||||
import org.jetbrains.kotlin.ir.expressions.IrGetPropertyExpression
|
import org.jetbrains.kotlin.ir.expressions.IrGetPropertyExpression
|
||||||
import org.jetbrains.kotlin.ir.expressions.IrSetPropertyExpression
|
import org.jetbrains.kotlin.ir.expressions.IrSetPropertyExpression
|
||||||
|
import org.jetbrains.kotlin.ir.expressions.IrWhenExpression
|
||||||
import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
|
import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
|
||||||
import org.jetbrains.kotlin.utils.Printer
|
import org.jetbrains.kotlin.utils.Printer
|
||||||
|
|
||||||
@@ -70,6 +71,19 @@ class DumpIrTreeVisitor(out: Appendable): IrElementVisitor<Unit, String> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun visitWhenExpression(expression: IrWhenExpression, data: String) {
|
||||||
|
expression.dumpLabeledElementWith(data) {
|
||||||
|
expression.subject?.let { subject ->
|
||||||
|
subject.accept(this, "\$subject:")
|
||||||
|
}
|
||||||
|
for (branch in expression.branches) {
|
||||||
|
branch.condition.accept(this, "if")
|
||||||
|
branch.result.accept(this, "then")
|
||||||
|
}
|
||||||
|
expression.elseExpression?.accept(this, "else")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private inline fun IrElement.dumpLabeledElementWith(label: String, body: () -> Unit) {
|
private inline fun IrElement.dumpLabeledElementWith(label: String, body: () -> Unit) {
|
||||||
printer.println(accept(elementRenderer, null).withLabel(label))
|
printer.println(accept(elementRenderer, null).withLabel(label))
|
||||||
indented(body)
|
indented(body)
|
||||||
|
|||||||
@@ -112,9 +112,14 @@ class RenderIrElementVisitor : IrElementVisitor<String, Nothing?> {
|
|||||||
override fun visitStringConcatenation(expression: IrStringConcatenationExpression, data: Nothing?): String =
|
override fun visitStringConcatenation(expression: IrStringConcatenationExpression, data: Nothing?): String =
|
||||||
"STRING_CONCATENATION type=${expression.renderType()}"
|
"STRING_CONCATENATION type=${expression.renderType()}"
|
||||||
|
|
||||||
override fun visitTypeOperatorExpression(expression: IrTypeOperatorExpression, data: Nothing?): String {
|
override fun visitTypeOperatorExpression(expression: IrTypeOperatorExpression, data: Nothing?): String =
|
||||||
return "TYPE_OP operator=${expression.operator} typeOperand=${expression.typeOperand.render()}"
|
"TYPE_OP operator=${expression.operator} typeOperand=${expression.typeOperand.render()}"
|
||||||
}
|
|
||||||
|
override fun visitWhenExpression(expression: IrWhenExpression, data: Nothing?): String =
|
||||||
|
"WHEN subject=${expression.subject?.descriptor?.name} type=${expression.type.render()}"
|
||||||
|
|
||||||
|
override fun visitBranch(branch: IrBranch, data: Nothing?): String =
|
||||||
|
"BRANCH"
|
||||||
|
|
||||||
override fun visitDummyDeclaration(declaration: IrDummyDeclaration, data: Nothing?): String =
|
override fun visitDummyDeclaration(declaration: IrDummyDeclaration, data: Nothing?): String =
|
||||||
"DUMMY ${declaration.descriptor.name}"
|
"DUMMY ${declaration.descriptor.name}"
|
||||||
|
|||||||
@@ -63,8 +63,10 @@ interface IrElementVisitor<out R, in D> {
|
|||||||
fun visitBinaryOperator(expression: IrBinaryOperatorExpression, data: D) = visitOperatorExpression(expression, data)
|
fun visitBinaryOperator(expression: IrBinaryOperatorExpression, data: D) = visitOperatorExpression(expression, data)
|
||||||
fun visitTypeOperatorExpression(expression: IrTypeOperatorExpression, data: D) = visitExpression(expression, data)
|
fun visitTypeOperatorExpression(expression: IrTypeOperatorExpression, data: D) = visitExpression(expression, data)
|
||||||
|
|
||||||
|
fun visitWhenExpression(expression: IrWhenExpression, data: D) = visitExpression(expression, data)
|
||||||
|
fun visitBranch(branch: IrBranch, data: D): R = visitElement(branch, data)
|
||||||
|
|
||||||
// NB Use it only for testing purposes; will be removed as soon as all Kotlin expression types are covered
|
// NB Use it only for testing purposes; will be removed as soon as all Kotlin expression types are covered
|
||||||
fun visitDummyDeclaration(declaration: IrDummyDeclaration, data: D) = visitDeclaration(declaration, data)
|
fun visitDummyDeclaration(declaration: IrDummyDeclaration, data: D) = visitDeclaration(declaration, data)
|
||||||
fun visitDummyExpression(expression: IrDummyExpression, data: D) = visitExpression(expression, data)
|
fun visitDummyExpression(expression: IrDummyExpression, data: D) = visitExpression(expression, data)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
+8
-2
@@ -16,8 +16,14 @@ IrFile /elvis.kt
|
|||||||
IrFunction public fun test3(/*0*/ a: kotlin.Any?, /*1*/ b: kotlin.Any?): kotlin.String
|
IrFunction public fun test3(/*0*/ a: kotlin.Any?, /*1*/ b: kotlin.Any?): kotlin.String
|
||||||
IrExpressionBody
|
IrExpressionBody
|
||||||
BLOCK type=<no-type> hasResult=false operator=null
|
BLOCK type=<no-type> hasResult=false operator=null
|
||||||
DUMMY KtIfExpression type=kotlin.Unit
|
WHEN subject=null type=kotlin.Unit
|
||||||
DUMMY KtIfExpression type=kotlin.Unit
|
if: DUMMY KtIsExpression type=kotlin.Boolean
|
||||||
|
then: RETURN type=<no-type>
|
||||||
|
LITERAL String type=kotlin.String value=''
|
||||||
|
WHEN subject=null type=kotlin.Unit
|
||||||
|
if: DUMMY KtIsExpression type=kotlin.Boolean
|
||||||
|
then: RETURN type=<no-type>
|
||||||
|
LITERAL String type=kotlin.String value=''
|
||||||
RETURN type=<no-type>
|
RETURN type=<no-type>
|
||||||
BINARY_OP operator=ELVIS type=kotlin.String related=null
|
BINARY_OP operator=ELVIS type=kotlin.String related=null
|
||||||
TYPE_OP operator=IMPLICIT_CAST typeOperand=kotlin.String?
|
TYPE_OP operator=IMPLICIT_CAST typeOperand=kotlin.String?
|
||||||
|
|||||||
+4
@@ -0,0 +1,4 @@
|
|||||||
|
fun test(i: Int) =
|
||||||
|
if (i > 0) 1
|
||||||
|
else if (i < 0) -1
|
||||||
|
else 0
|
||||||
+15
@@ -0,0 +1,15 @@
|
|||||||
|
IrFile /ifElseIf.kt
|
||||||
|
IrFunction public fun test(/*0*/ i: kotlin.Int): kotlin.Int
|
||||||
|
IrExpressionBody
|
||||||
|
BLOCK type=<no-type> hasResult=false operator=null
|
||||||
|
RETURN type=<no-type>
|
||||||
|
WHEN subject=null type=kotlin.Int
|
||||||
|
if: BINARY_OP operator=GT type=kotlin.Boolean related=public open override /*1*/ fun compareTo(/*0*/ other: kotlin.Int): kotlin.Int
|
||||||
|
GET_VAR i type=kotlin.Int operator=null
|
||||||
|
LITERAL Int type=kotlin.Int value='0'
|
||||||
|
then: LITERAL Int type=kotlin.Int value='1'
|
||||||
|
if: BINARY_OP operator=LT type=kotlin.Boolean related=public open override /*1*/ fun compareTo(/*0*/ other: kotlin.Int): kotlin.Int
|
||||||
|
GET_VAR i type=kotlin.Int operator=null
|
||||||
|
LITERAL Int type=kotlin.Int value='0'
|
||||||
|
then: DUMMY MINUS type=kotlin.Int
|
||||||
|
else: LITERAL Int type=kotlin.Int value='0'
|
||||||
+11
-3
@@ -18,7 +18,9 @@ IrFile /smartCasts.kt
|
|||||||
IrFunction public fun test1(/*0*/ x: kotlin.Any): kotlin.Unit
|
IrFunction public fun test1(/*0*/ x: kotlin.Any): kotlin.Unit
|
||||||
IrExpressionBody
|
IrExpressionBody
|
||||||
BLOCK type=<no-type> hasResult=false operator=null
|
BLOCK type=<no-type> hasResult=false operator=null
|
||||||
DUMMY KtIfExpression type=kotlin.Unit
|
WHEN subject=null type=kotlin.Unit
|
||||||
|
if: DUMMY KtIsExpression type=kotlin.Boolean
|
||||||
|
then: RETURN type=<no-type>
|
||||||
CALL .println type=kotlin.Unit operator=null
|
CALL .println type=kotlin.Unit operator=null
|
||||||
message: GET_PROPERTY .length type=kotlin.Int operator=null
|
message: GET_PROPERTY .length type=kotlin.Int operator=null
|
||||||
$this: TYPE_OP operator=IMPLICIT_CAST typeOperand=kotlin.String
|
$this: TYPE_OP operator=IMPLICIT_CAST typeOperand=kotlin.String
|
||||||
@@ -37,7 +39,10 @@ IrFile /smartCasts.kt
|
|||||||
IrFunction public fun test2(/*0*/ x: kotlin.Any): kotlin.String
|
IrFunction public fun test2(/*0*/ x: kotlin.Any): kotlin.String
|
||||||
IrExpressionBody
|
IrExpressionBody
|
||||||
BLOCK type=<no-type> hasResult=false operator=null
|
BLOCK type=<no-type> hasResult=false operator=null
|
||||||
DUMMY KtIfExpression type=kotlin.Unit
|
WHEN subject=null type=kotlin.Unit
|
||||||
|
if: DUMMY KtIsExpression type=kotlin.Boolean
|
||||||
|
then: RETURN type=<no-type>
|
||||||
|
LITERAL String type=kotlin.String value=''
|
||||||
RETURN type=<no-type>
|
RETURN type=<no-type>
|
||||||
CALL .overloaded type=kotlin.String operator=null
|
CALL .overloaded type=kotlin.String operator=null
|
||||||
s: TYPE_OP operator=IMPLICIT_CAST typeOperand=kotlin.String
|
s: TYPE_OP operator=IMPLICIT_CAST typeOperand=kotlin.String
|
||||||
@@ -45,7 +50,10 @@ IrFile /smartCasts.kt
|
|||||||
IrFunction public fun test3(/*0*/ x: kotlin.Any): kotlin.String
|
IrFunction public fun test3(/*0*/ x: kotlin.Any): kotlin.String
|
||||||
IrExpressionBody
|
IrExpressionBody
|
||||||
BLOCK type=<no-type> hasResult=false operator=null
|
BLOCK type=<no-type> hasResult=false operator=null
|
||||||
DUMMY KtIfExpression type=kotlin.Unit
|
WHEN subject=null type=kotlin.Unit
|
||||||
|
if: DUMMY KtIsExpression type=kotlin.Boolean
|
||||||
|
then: RETURN type=<no-type>
|
||||||
|
LITERAL String type=kotlin.String value=''
|
||||||
RETURN type=<no-type>
|
RETURN type=<no-type>
|
||||||
TYPE_OP operator=IMPLICIT_CAST typeOperand=kotlin.String
|
TYPE_OP operator=IMPLICIT_CAST typeOperand=kotlin.String
|
||||||
GET_VAR x type=kotlin.Any operator=null
|
GET_VAR x type=kotlin.Any operator=null
|
||||||
|
|||||||
@@ -14,7 +14,9 @@ IrFile /smartCastsWithDestructuring.kt
|
|||||||
IrFunction public fun test(/*0*/ x: I1): kotlin.Unit
|
IrFunction public fun test(/*0*/ x: I1): kotlin.Unit
|
||||||
IrExpressionBody
|
IrExpressionBody
|
||||||
BLOCK type=<no-type> hasResult=false operator=null
|
BLOCK type=<no-type> hasResult=false operator=null
|
||||||
DUMMY KtIfExpression type=kotlin.Unit
|
WHEN subject=null type=kotlin.Unit
|
||||||
|
if: DUMMY KtIsExpression type=kotlin.Boolean
|
||||||
|
then: RETURN type=<no-type>
|
||||||
BLOCK type=<no-type> hasResult=false operator=SYNTHETIC_BLOCK
|
BLOCK type=<no-type> hasResult=false operator=SYNTHETIC_BLOCK
|
||||||
VAR val tmp0: I1
|
VAR val tmp0: I1
|
||||||
GET_VAR x type=I1 operator=null
|
GET_VAR x type=I1 operator=null
|
||||||
|
|||||||
@@ -137,6 +137,12 @@ public class IrTextTestCaseGenerated extends AbstractIrTextTestCase {
|
|||||||
doTest(fileName);
|
doTest(fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("ifElseIf.kt")
|
||||||
|
public void testIfElseIf() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/ir/irText/ifElseIf.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("implicitCastOnPlatformType.kt")
|
@TestMetadata("implicitCastOnPlatformType.kt")
|
||||||
public void testImplicitCastOnPlatformType() throws Exception {
|
public void testImplicitCastOnPlatformType() throws Exception {
|
||||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/ir/irText/implicitCastOnPlatformType.kt");
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/ir/irText/implicitCastOnPlatformType.kt");
|
||||||
|
|||||||
Reference in New Issue
Block a user