When expression.

Fix object & enum references.
This commit is contained in:
Dmitry Petrov
2016-08-19 13:21:56 +03:00
committed by Dmitry Petrov
parent d6040d8570
commit b96626fd4c
14 changed files with 301 additions and 74 deletions
@@ -19,6 +19,7 @@ package org.jetbrains.kotlin.psi2ir.generators
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.ir.declarations.IrVariable
import org.jetbrains.kotlin.ir.expressions.*
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
@@ -50,6 +51,10 @@ class CallGenerator(val statementGenerator: StatementGenerator) : IrGenerator {
return null
}
return createTemporary(ktExpression, irExpression, nameHint)
}
fun createTemporary(ktExpression: KtExpression, irExpression: IrExpression, nameHint: String?): IrVariable {
val irTmpVar = temporaryVariableFactory.createTemporaryVariable(irExpression, nameHint)
putValue(ktExpression, VariableLValue(irTmpVar))
return irTmpVar
@@ -75,12 +80,16 @@ class CallGenerator(val statementGenerator: StatementGenerator) : IrGenerator {
receiverValues[receiver] = irValue
}
fun putValue(valueArgument: ValueParameterDescriptor, irValue: IrValue) {
valueArgumentValues[valueArgument] = irValue
fun putValue(parameter: ValueParameterDescriptor, irValue: IrValue) {
valueArgumentValues[parameter] = irValue
}
fun valueOf(ktExpression: KtExpression) = expressionValues[ktExpression]?.load()
fun valueOf(receiver: ReceiverValue) = receiverValues[receiver]?.load()
fun valueOf(parameter: ValueParameterDescriptor) = valueArgumentValues[parameter]?.load()
fun generateCall(
ktExpression: KtExpression,
ktElement: KtElement,
resolvedCall: ResolvedCall<out CallableDescriptor>,
operator: IrOperator? = null,
superQualifier: ClassDescriptor? = null
@@ -91,15 +100,15 @@ class CallGenerator(val statementGenerator: StatementGenerator) : IrGenerator {
return when (descriptor) {
is PropertyDescriptor ->
IrGetPropertyExpressionImpl(
ktExpression.startOffset, ktExpression.endOffset,
ktElement.startOffset, ktElement.endOffset,
returnType,
resolvedCall.call.isSafeCall(), descriptor
).apply {
dispatchReceiver = generateReceiver(ktExpression, resolvedCall.dispatchReceiver, descriptor.dispatchReceiverParameter)
extensionReceiver = generateReceiver(ktExpression, resolvedCall.extensionReceiver, descriptor.extensionReceiverParameter)
dispatchReceiver = generateReceiver(ktElement, resolvedCall.dispatchReceiver, descriptor.dispatchReceiverParameter)
extensionReceiver = generateReceiver(ktElement, resolvedCall.extensionReceiver, descriptor.extensionReceiverParameter)
}
is FunctionDescriptor ->
generateFunctionCall(descriptor, ktExpression, returnType, operator, resolvedCall, superQualifier)
generateFunctionCall(descriptor, ktElement, returnType, operator, resolvedCall, superQualifier)
else ->
TODO("Unexpected callable descriptor: $descriptor ${descriptor.javaClass.simpleName}")
}
@@ -121,21 +130,21 @@ class CallGenerator(val statementGenerator: StatementGenerator) : IrGenerator {
private fun generateFunctionCall(
descriptor: FunctionDescriptor,
ktExpression: KtExpression,
ktElement: KtElement,
resultType: KotlinType?,
operator: IrOperator?,
resolvedCall: ResolvedCall<out CallableDescriptor>,
superQualifier: ClassDescriptor?
): IrExpression {
val irCall = IrCallExpressionImpl(
ktExpression.startOffset, ktExpression.endOffset, resultType,
ktElement.startOffset, ktElement.endOffset, resultType,
descriptor, resolvedCall.call.isSafeCall(), operator, superQualifier
)
irCall.dispatchReceiver = generateReceiver(ktExpression, resolvedCall.dispatchReceiver, descriptor.dispatchReceiverParameter)
irCall.extensionReceiver = generateReceiver(ktExpression, resolvedCall.extensionReceiver, descriptor.extensionReceiverParameter)
irCall.dispatchReceiver = generateReceiver(ktElement, resolvedCall.dispatchReceiver, descriptor.dispatchReceiverParameter)
irCall.extensionReceiver = generateReceiver(ktElement, resolvedCall.extensionReceiver, descriptor.extensionReceiverParameter)
return if (resolvedCall.requiresArgumentReordering()) {
generateCallWithArgumentReordering(irCall, ktExpression, resolvedCall, resultType)
generateCallWithArgumentReordering(irCall, ktElement, resolvedCall, resultType)
}
else {
irCall.apply {
@@ -152,7 +161,7 @@ class CallGenerator(val statementGenerator: StatementGenerator) : IrGenerator {
private fun generateCallWithArgumentReordering(
irCall: IrCallExpression,
ktExpression: KtExpression,
ktElement: KtElement,
resolvedCall: ResolvedCall<out CallableDescriptor>,
resultType: KotlinType?
): IrExpression {
@@ -161,8 +170,8 @@ class CallGenerator(val statementGenerator: StatementGenerator) : IrGenerator {
val valueArgumentsInEvaluationOrder = resolvedCall.valueArguments.values
val valueParameters = resolvedCall.resultingDescriptor.valueParameters
val hasResult = isUsedAsExpression(ktExpression)
val irBlock = IrBlockExpressionImpl(ktExpression.startOffset, ktExpression.endOffset, resultType, hasResult,
val hasResult = isUsedAsExpression(ktElement)
val irBlock = IrBlockExpressionImpl(ktElement.startOffset, ktElement.endOffset, resultType, hasResult,
IrOperator.SYNTHETIC_BLOCK)
val valueArgumentsToValueParameters = HashMap<ResolvedValueArgument, ValueParameterDescriptor>()
@@ -189,22 +198,22 @@ class CallGenerator(val statementGenerator: StatementGenerator) : IrGenerator {
return irBlock
}
fun generateReceiver(ktExpression: KtExpression, receiver: ReceiverValue?, receiverParameterDescriptor: ReceiverParameterDescriptor?) =
generateReceiver(ktExpression, receiver, receiverParameterDescriptor?.type)
fun generateReceiver(ktElement: KtElement, receiver: ReceiverValue?, receiverParameterDescriptor: ReceiverParameterDescriptor?) =
generateReceiver(ktElement, receiver, receiverParameterDescriptor?.type)
fun generateReceiver(ktExpression: KtExpression, receiver: ReceiverValue?, expectedType: KotlinType?) =
generateReceiver(ktExpression, receiver)?.toExpectedType(expectedType)
fun generateReceiver(ktElement: KtElement, receiver: ReceiverValue?, expectedType: KotlinType?) =
generateReceiver(ktElement, receiver)?.toExpectedType(expectedType)
fun generateReceiver(ktExpression: KtExpression, receiver: ReceiverValue?): IrExpression? =
fun generateReceiver(ktElement: KtElement, receiver: ReceiverValue?): IrExpression? =
if (receiver == null)
null
else
receiverValues[receiver]?.load() ?: doGenerateReceiver(ktExpression, receiver)
receiverValues[receiver]?.load() ?: doGenerateReceiver(ktElement, receiver)
fun doGenerateReceiver(ktExpression: KtExpression, receiver: ReceiverValue?): IrExpression? =
fun doGenerateReceiver(ktElement: KtElement, receiver: ReceiverValue?): IrExpression? =
when (receiver) {
is ImplicitClassReceiver ->
IrThisExpressionImpl(ktExpression.startOffset, ktExpression.startOffset, receiver.type, receiver.classDescriptor)
IrThisExpressionImpl(ktElement.startOffset, ktElement.startOffset, receiver.type, receiver.classDescriptor)
is ThisClassReceiver ->
(receiver as? ExpressionReceiver)?.expression?.let { receiverExpression ->
IrThisExpressionImpl(receiverExpression.startOffset, receiverExpression.endOffset, receiver.type, receiver.classDescriptor)
@@ -215,7 +224,7 @@ class CallGenerator(val statementGenerator: StatementGenerator) : IrGenerator {
IrGetObjectValueExpressionImpl(receiver.expression.startOffset, receiver.expression.endOffset, receiver.type,
receiver.classQualifier.descriptor)
is ExtensionReceiver ->
IrGetExtensionReceiverExpressionImpl(ktExpression.startOffset, ktExpression.startOffset, receiver.type,
IrGetExtensionReceiverExpressionImpl(ktElement.startOffset, ktElement.startOffset, receiver.type,
receiver.declarationDescriptor.extensionReceiverParameter!!)
null ->
null
@@ -20,6 +20,7 @@ import org.jetbrains.kotlin.descriptors.CallableDescriptor
import org.jetbrains.kotlin.descriptors.ClassDescriptor
import org.jetbrains.kotlin.ir.expressions.IrDummyExpression
import org.jetbrains.kotlin.psi.KtBlockExpression
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
@@ -54,8 +55,8 @@ fun IrGenerator.getExpectedTypeForLastInferredCall(key: KtExpression): KotlinTyp
fun IrGenerator.getInferredTypeWithSmarcastsOrFail(key: KtExpression): KotlinType =
getInferredTypeWithSmartcasts(key) ?: TODO("No type for expression: ${key.text}")
fun IrGenerator.isUsedAsExpression(ktExpression: KtExpression) =
get(BindingContext.USED_AS_EXPRESSION, ktExpression) ?: false
fun IrGenerator.isUsedAsExpression(ktElement: KtElement) =
get(BindingContext.USED_AS_EXPRESSION, ktElement) ?: false
fun IrGenerator.getResolvedCall(key: KtExpression): ResolvedCall<out CallableDescriptor>? =
key.getResolvedCall(context.bindingContext)
@@ -31,8 +31,11 @@ import org.jetbrains.kotlin.psi2ir.toExpectedType
import org.jetbrains.kotlin.resolve.BindingContext
import org.jetbrains.kotlin.resolve.BindingContextUtils
import org.jetbrains.kotlin.resolve.DescriptorUtils
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
import org.jetbrains.kotlin.resolve.calls.model.VariableAsFunctionResolvedCall
import org.jetbrains.kotlin.resolve.calls.util.FakeCallableDescriptorForObject
import org.jetbrains.kotlin.resolve.constants.IntValue
import org.jetbrains.kotlin.resolve.constants.NullValue
import org.jetbrains.kotlin.resolve.constants.StringValue
import org.jetbrains.kotlin.resolve.constants.evaluate.ConstantExpressionEvaluator
import org.jetbrains.kotlin.resolve.descriptorUtil.classValueType
@@ -140,6 +143,8 @@ class StatementGenerator(
IrLiteralExpressionImpl.string(expression.startOffset, expression.endOffset, constantType, constantValue.value)
is IntValue ->
IrLiteralExpressionImpl.int(expression.startOffset, expression.endOffset, constantType, constantValue.value)
is NullValue ->
IrLiteralExpressionImpl.nullLiteral(expression.startOffset, expression.endOffset, constantType)
else ->
TODO("handle other literal types: ${constantValue.type}")
}
@@ -166,40 +171,45 @@ class StatementGenerator(
IrLiteralExpressionImpl.string(entry.startOffset, entry.endOffset, context.builtIns.stringType, entry.text)
override fun visitSimpleNameExpression(expression: KtSimpleNameExpression, data: Nothing?): IrExpression {
val resolvedCall = getResolvedCall(expression)
val resolvedCall = getResolvedCall(expression)!!
if (resolvedCall is VariableAsFunctionResolvedCall) {
TODO("Unexpected VariableAsFunctionResolvedCall")
}
val descriptor = resolvedCall?.resultingDescriptor
val descriptor = resolvedCall.resultingDescriptor
return when (descriptor) {
is ClassDescriptor ->
if (DescriptorUtils.isObject(descriptor))
IrGetObjectValueExpressionImpl(expression.startOffset, expression.endOffset, descriptor.classValueType, descriptor)
else if (DescriptorUtils.isEnumEntry(descriptor))
IrGetEnumValueExpressionImpl(expression.startOffset, expression.endOffset, descriptor.classValueType, descriptor)
else {
val companionObjectDescriptor = descriptor.companionObjectDescriptor
?: error("Class value without companion object: $descriptor")
IrGetObjectValueExpressionImpl(expression.startOffset, expression.endOffset,
descriptor.classValueType,
companionObjectDescriptor)
}
is PropertyDescriptor -> {
CallGenerator(this).generateCall(expression, resolvedCall)
}
is VariableDescriptor ->
IrGetVariableExpressionImpl(expression.startOffset, expression.endOffset, descriptor)
else ->
IrDummyExpression(
expression.startOffset, expression.endOffset, getInferredTypeWithSmartcasts(expression),
expression.getReferencedName() + ": ${descriptor?.name} ${descriptor?.javaClass?.simpleName}"
)
}
return generateExpressionForReferencedDescriptor(descriptor, expression, resolvedCall)
}
private fun generateExpressionForReferencedDescriptor(descriptor: DeclarationDescriptor, expression: KtExpression, resolvedCall: ResolvedCall<*>): IrExpression =
when (descriptor) {
is FakeCallableDescriptorForObject ->
generateExpressionForReferencedDescriptor(descriptor.getReferencedDescriptor(), expression, resolvedCall)
is ClassDescriptor ->
if (DescriptorUtils.isObject(descriptor))
IrGetObjectValueExpressionImpl(expression.startOffset, expression.endOffset, descriptor.classValueType, descriptor)
else if (DescriptorUtils.isEnumEntry(descriptor))
IrGetEnumValueExpressionImpl(expression.startOffset, expression.endOffset, descriptor.classValueType, descriptor)
else {
val companionObjectDescriptor = descriptor.companionObjectDescriptor
?: error("Class value without companion object: $descriptor")
IrGetObjectValueExpressionImpl(expression.startOffset, expression.endOffset,
descriptor.classValueType,
companionObjectDescriptor)
}
is PropertyDescriptor -> {
CallGenerator(this).generateCall(expression, resolvedCall)
}
is VariableDescriptor ->
IrGetVariableExpressionImpl(expression.startOffset, expression.endOffset, descriptor)
else ->
IrDummyExpression(
expression.startOffset, expression.endOffset, getInferredTypeWithSmartcasts(expression),
expression.text + ": ${descriptor.name} ${descriptor.javaClass.simpleName}"
)
}
override fun visitCallExpression(expression: KtCallExpression, data: Nothing?): IrStatement {
val resolvedCall = getResolvedCall(expression) ?: TODO("No resolved call for call expression")
@@ -280,5 +290,6 @@ class StatementGenerator(
return irWhen
}
override fun visitWhenExpression(expression: KtWhenExpression, data: Nothing?): IrStatement =
WhenExpressionGenerator(this).generate(expression)
}
@@ -0,0 +1,115 @@
/*
* 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
import org.jetbrains.kotlin.ir.declarations.IrVariable
import org.jetbrains.kotlin.ir.expressions.*
import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.psi.psiUtil.endOffset
import org.jetbrains.kotlin.psi.psiUtil.startOffset
import org.jetbrains.kotlin.psi2ir.load
import org.jetbrains.kotlin.psi2ir.toExpectedType
import org.jetbrains.kotlin.resolve.BindingContext
class WhenExpressionGenerator(val statementGenerator: StatementGenerator) : IrGenerator {
override val context: GeneratorContext get() = statementGenerator.context
fun generate(expression: KtWhenExpression): IrExpression {
val conditionsGenerator = CallGenerator(statementGenerator)
val irSubject = expression.subjectExpression?.let {
conditionsGenerator.createTemporary(it, statementGenerator.generateExpression(it), "subject")
}
val resultType = getInferredTypeWithSmartcasts(expression)
val irWhen = IrWhenExpressionImpl(expression.startOffset, expression.endOffset, resultType, irSubject)
for (ktEntry in expression.entries) {
if (ktEntry.isElse) {
irWhen.elseExpression = statementGenerator.generateExpression(ktEntry.expression!!).toExpectedType(resultType)
continue
}
val irBranch = IrBranchImpl(ktEntry.startOffset, ktEntry.endOffset)
for (ktCondition in ktEntry.conditions) {
val irCondition =
if (irSubject != null)
generateWhenConditionWithSubject(ktCondition, conditionsGenerator, irSubject)
else
generateWhenConditionNoSubject(ktCondition)
irBranch.addCondition(irCondition)
}
irBranch.result = statementGenerator.generateExpression(ktEntry.expression!!).toExpectedType(resultType)
irWhen.addBranch(irBranch)
}
return irWhen
}
private fun generateWhenConditionNoSubject(ktCondition: KtWhenCondition): IrExpression =
statementGenerator.generateExpression((ktCondition as KtWhenConditionWithExpression).expression!!)
.toExpectedType(context.builtIns.booleanType)
private fun generateWhenConditionWithSubject(
ktCondition: KtWhenCondition,
conditionsGenerator: CallGenerator,
irSubject: IrVariable
): IrExpression {
return when (ktCondition) {
is KtWhenConditionWithExpression ->
generateEqualsCondition(irSubject, ktCondition)
is KtWhenConditionInRange ->
generateInRangeCondition(conditionsGenerator, ktCondition)
is KtWhenConditionIsPattern ->
generateIsPatternCondition(irSubject, ktCondition)
else ->
throw AssertionError("Unexpected 'when' condition: ${ktCondition.text}")
}
}
private fun generateIsPatternCondition(irSubject: IrVariable, ktCondition: KtWhenConditionIsPattern): IrExpression {
val isType = getOrFail(BindingContext.TYPE, ktCondition.typeReference)
return IrTypeOperatorExpressionImpl(
ktCondition.startOffset, ktCondition.endOffset, context.builtIns.booleanType,
IrTypeOperator.INSTANCEOF, isType, irSubject.load()
)
}
private fun generateInRangeCondition(conditionsGenerator: CallGenerator, ktCondition: KtWhenConditionInRange): IrExpression {
val inResolvedCall = getResolvedCall(ktCondition.operationReference)!!
val inOperator = getIrBinaryOperator(ktCondition.operationReference.getReferencedNameElementType())
val irInCall = conditionsGenerator.generateCall(ktCondition, inResolvedCall, inOperator)
return when (inOperator) {
IrOperator.IN -> irInCall
IrOperator.NOT_IN ->
IrUnaryOperatorExpressionImpl(ktCondition.startOffset, ktCondition.endOffset, context.builtIns.booleanType,
IrOperator.EXCL, null, irInCall)
else -> throw AssertionError("Expected 'in' or '!in', got $inOperator")
}
}
private fun generateEqualsCondition(irSubject: IrVariable, ktCondition: KtWhenConditionWithExpression): IrBinaryOperatorExpressionImpl =
IrBinaryOperatorExpressionImpl(
ktCondition.startOffset, ktCondition.endOffset,
context.builtIns.booleanType, IrOperator.EQEQ, null,
irSubject.load(), statementGenerator.generateExpression(ktCondition.expression!!)
)
}
@@ -27,5 +27,4 @@ const val MODULE_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
const val BRANCH_RESULT_SLOT = -1
@@ -58,6 +58,9 @@ class IrLiteralExpressionImpl<out T> (
fun int(startOffset: Int, endOffset: Int, type: KotlinType, value: Int): IrLiteralExpressionImpl<Int> =
IrLiteralExpressionImpl(startOffset, endOffset, type, IrLiteralKind.Int, value)
fun nullLiteral(startOffset: Int, endOffset: Int, type: KotlinType): IrLiteralExpressionImpl<Nothing?> =
IrLiteralExpressionImpl(startOffset, endOffset, type, IrLiteralKind.Null, null)
}
}
@@ -20,6 +20,7 @@ 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 org.jetbrains.kotlin.utils.SmartList
import java.util.*
interface IrWhenExpression : IrExpression {
@@ -31,8 +32,10 @@ interface IrWhenExpression : IrExpression {
}
interface IrBranch : IrElement {
var condition: IrExpression
val conditions: List<IrExpression>
var result: IrExpression
fun addCondition(expression: IrExpression)
}
class IrWhenExpressionImpl(
@@ -44,7 +47,7 @@ class IrWhenExpressionImpl(
startOffset: Int,
endOffset: Int,
type: KotlinType?,
subject: IrVariable
subject: IrVariable?
) : this(startOffset, endOffset, type) {
this.subject = subject
}
@@ -121,19 +124,17 @@ class IrWhenExpressionImpl(
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
addCondition(condition)
}
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)
}
override val conditions: MutableList<IrExpression> = SmartList()
override fun addCondition(expression: IrExpression) {
expression.assertDetached()
expression.setTreeLocation(this, conditions.size)
conditions.add(expression)
}
private var resultImpl: IrExpression? = null
override var result: IrExpression
@@ -147,17 +148,19 @@ class IrBranchImpl(startOffset: Int, endOffset: Int) : IrElementBase(startOffset
override fun getChild(slot: Int): IrElement? =
when (slot) {
BRANCH_CONDITION_SLOT -> condition
BRANCH_RESULT_SLOT -> result
else -> null
else -> conditions.getOrNull(slot)
}
override fun replaceChild(slot: Int, newChild: IrElement) {
when (slot) {
BRANCH_CONDITION_SLOT ->
condition = newChild.assertCast()
BRANCH_RESULT_SLOT ->
result = newChild.assertCast()
in conditions.indices -> {
conditions[slot].detach()
conditions[slot] = newChild.assertCast()
newChild.setTreeLocation(this, slot)
}
}
}
@@ -165,7 +168,7 @@ class IrBranchImpl(startOffset: Int, endOffset: Int) : IrElementBase(startOffset
visitor.visitBranch(this, data)
override fun <D> acceptChildren(visitor: IrElementVisitor<Unit, D>, data: D) {
conditionImpl?.accept(visitor, data)
conditions.forEach { it.accept(visitor, data) }
resultImpl?.accept(visitor, data)
}
}
@@ -77,7 +77,7 @@ class DumpIrTreeVisitor(out: Appendable): IrElementVisitor<Unit, String> {
subject.accept(this, "\$subject:")
}
for (branch in expression.branches) {
branch.condition.accept(this, "if")
branch.conditions.forEach { it.accept(this, "if") }
branch.result.accept(this, "then")
}
expression.elseExpression?.accept(this, "else")
+1 -1
View File
@@ -3,7 +3,7 @@ IrFunction public fun B.test(): kotlin.Unit
BLOCK type=<no-type> hasResult=false operator=null
BLOCK type=<no-type> hasResult=false operator=SYNTHETIC_BLOCK
VAR val tmp0: A
GET_VAR A type=A operator=null
GET_OBJECT A type=A
VAR val x: kotlin.Int
CALL .component1 type=kotlin.Int operator=COMPONENT_N(index=1)
$this: $RECEIVER of: test type=B
+11
View File
@@ -0,0 +1,11 @@
enum class Enum { A }
object A
val a = 0
class Z {
companion object
}
fun test1() = Enum.A
fun test2() = A
fun test3() = a
fun test4() = Z
+27
View File
@@ -0,0 +1,27 @@
IrFile /values.kt
DUMMY Enum
DUMMY A
IrProperty public val a: kotlin.Int = 0 getter=null setter=null
IrExpressionBody
LITERAL Int type=kotlin.Int value='0'
DUMMY Z
IrFunction public fun test1(): Enum
IrExpressionBody
BLOCK type=<no-type> hasResult=false operator=null
RETURN type=<no-type>
GET_ENUM_VALUE A type=Enum
IrFunction public fun test2(): A
IrExpressionBody
BLOCK type=<no-type> hasResult=false operator=null
RETURN type=<no-type>
GET_OBJECT A type=A
IrFunction public fun test3(): kotlin.Int
IrExpressionBody
BLOCK type=<no-type> hasResult=false operator=null
RETURN type=<no-type>
GET_PROPERTY .a type=kotlin.Int operator=null
IrFunction public fun test4(): Z.Companion
IrExpressionBody
BLOCK type=<no-type> hasResult=false operator=null
RETURN type=<no-type>
GET_OBJECT Companion type=Z.Companion
+10
View File
@@ -0,0 +1,10 @@
object A
fun test(x: Any?) =
when (x) {
null -> "null"
A -> "A"
is String -> "String"
in setOf<Nothing>() -> "nothingness?"
else -> "something"
}
+26
View File
@@ -0,0 +1,26 @@
IrFile /when.kt
DUMMY A
IrFunction public fun test(/*0*/ x: kotlin.Any?): kotlin.String
IrExpressionBody
BLOCK type=<no-type> hasResult=false operator=null
RETURN type=<no-type>
WHEN subject=tmp0_subject type=kotlin.String
$subject:: VAR val tmp0_subject: kotlin.Any?
GET_VAR x type=kotlin.Any? operator=null
if: BINARY_OP operator=EQEQ type=kotlin.Boolean related=null
GET_VAR tmp0_subject type=kotlin.Any? operator=null
LITERAL Null type=kotlin.Nothing? value='null'
then: LITERAL String type=kotlin.String value='null'
if: BINARY_OP operator=EQEQ type=kotlin.Boolean related=null
GET_VAR tmp0_subject type=kotlin.Any? operator=null
GET_OBJECT A type=A
then: LITERAL String type=kotlin.String value='A'
if: TYPE_OP operator=INSTANCEOF typeOperand=kotlin.String
GET_VAR tmp0_subject type=kotlin.Any? operator=null
then: LITERAL String type=kotlin.String value='String'
if: CALL .contains type=kotlin.Boolean operator=IN
$receiver: CALL .setOf type=kotlin.collections.Set<kotlin.Nothing> operator=null
element: TYPE_OP operator=IMPLICIT_CAST typeOperand=kotlin.Any
GET_VAR tmp0_subject type=kotlin.Any? operator=null
then: LITERAL String type=kotlin.String value='nothingness?'
else: LITERAL String type=kotlin.String value='something'
@@ -214,4 +214,16 @@ public class IrTextTestCaseGenerated extends AbstractIrTextTestCase {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/ir/irText/typeOperators.kt");
doTest(fileName);
}
@TestMetadata("values.kt")
public void testValues() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/ir/irText/values.kt");
doTest(fileName);
}
@TestMetadata("when.kt")
public void testWhen() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/ir/irText/when.kt");
doTest(fileName);
}
}