psi2ir: Consistently use type unit for statements

These changes allow us to accurately distinguish between statements and
expressions in the IR.

This also fixes the types of non-exhaustive conditional statements.
This commit is contained in:
Steven Schäfer
2019-10-23 15:41:47 +02:00
committed by Dmitry Petrov
parent 0da4b06074
commit af74fd047a
23 changed files with 142 additions and 131 deletions
@@ -599,7 +599,10 @@ class ExpressionCodegen(
SwitchGenerator(expression, data, this).generate()?.let { return it } SwitchGenerator(expression, data, this).generate()?.let { return it }
val endLabel = Label() val endLabel = Label()
val exhaustive = expression.branches.any { it.condition.isTrueConst() } val exhaustive = expression.branches.any { it.condition.isTrueConst() } && !expression.type.isUnit()
assert(exhaustive || expression.type.isUnit()) {
"non-exhaustive conditional should return Unit: ${expression.dump()}"
}
for (branch in expression.branches) { for (branch in expression.branches) {
val elseLabel = Label() val elseLabel = Label()
if (branch.condition.isFalseConst() || branch.condition.isTrueConst()) { if (branch.condition.isFalseConst() || branch.condition.isTrueConst()) {
@@ -614,26 +617,21 @@ class ExpressionCodegen(
} else { } else {
branch.condition.accept(this, data).coerceToBoolean().jumpIfFalse(elseLabel) branch.condition.accept(this, data).coerceToBoolean().jumpIfFalse(elseLabel)
} }
val result = branch.result.accept(this, data).coerce(expression.type).materialized val result = branch.result.accept(this, data)
if (!exhaustive) { if (!exhaustive) {
result.discard() result.discard()
} else if (branch.condition.isTrueConst()) { } else {
// The rest of the expression is dead code. val materializedResult = result.coerce(expression.type).materialized
mv.mark(endLabel) if (branch.condition.isTrueConst()) {
return result // The rest of the expression is dead code.
mv.mark(endLabel)
return materializedResult
}
} }
mv.goTo(endLabel) mv.goTo(endLabel)
mv.mark(elseLabel) mv.mark(elseLabel)
} }
mv.mark(endLabel) mv.mark(endLabel)
// NOTE: using a non-exhaustive if/when as an expression is invalid, so it should theoretically
// always return Unit. However, with the current frontend this is not always the case.
// Most notably, 1. when all branches return/break/continue, the type is Nothing;
// 2. the frontend may sometimes infer Any instead of Unit, probably due to a bug
// (see compiler/testData/codegen/box/controlStructures/ifIncompatibleBranches.kt).
// It should still be safe to produce a soon-to-be-discarded Unit. (What is not ok is
// inserting *any* code here, though, as its line number will be that of the last line
// of the last branch.)
return immaterialUnitValue return immaterialUnitValue
} }
@@ -16,7 +16,6 @@
package org.jetbrains.kotlin.psi2ir.generators package org.jetbrains.kotlin.psi2ir.generators
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET
import org.jetbrains.kotlin.ir.builders.buildStatement import org.jetbrains.kotlin.ir.builders.buildStatement
import org.jetbrains.kotlin.ir.builders.irIfThenMaybeElse import org.jetbrains.kotlin.ir.builders.irIfThenMaybeElse
@@ -38,8 +37,6 @@ import org.jetbrains.kotlin.utils.SmartList
class BranchingExpressionGenerator(statementGenerator: StatementGenerator) : StatementGeneratorExtension(statementGenerator) { class BranchingExpressionGenerator(statementGenerator: StatementGenerator) : StatementGeneratorExtension(statementGenerator) {
fun generateIfExpression(expression: KtIfExpression): IrExpression { fun generateIfExpression(expression: KtIfExpression): IrExpression {
val resultType = getInferredTypeWithImplicitCastsOrFail(expression).toIrType()
var ktLastIf: KtIfExpression = expression var ktLastIf: KtIfExpression = expression
val irBranches = SmartList<IrBranch>() val irBranches = SmartList<IrBranch>()
var irElseBranch: IrExpression? = null var irElseBranch: IrExpression? = null
@@ -61,7 +58,7 @@ class BranchingExpressionGenerator(statementGenerator: StatementGenerator) : Sta
} }
} }
return createIrWhen(expression, irBranches, irElseBranch, resultType) return createIrWhen(expression, irBranches, irElseBranch, getExpressionTypeWithCoercionToUnitOrFail(expression).toIrType())
} }
private fun generateEmptyBlockForMissingBranch(ktLastIf: KtIfExpression) = private fun generateEmptyBlockForMissingBranch(ktLastIf: KtIfExpression) =
@@ -100,16 +97,10 @@ class BranchingExpressionGenerator(statementGenerator: StatementGenerator) : Sta
fun generateWhenExpression(expression: KtWhenExpression): IrExpression { fun generateWhenExpression(expression: KtWhenExpression): IrExpression {
val irSubject = generateWhenSubject(expression) val irSubject = generateWhenSubject(expression)
val inferredType = getInferredTypeWithImplicitCastsOrFail(expression) val irWhen = IrWhenImpl(
expression.startOffsetSkippingComments, expression.endOffset,
val resultType = when { getExpressionTypeWithCoercionToUnitOrFail(expression).toIrType(), IrStatementOrigin.WHEN
// Non-exhaustive when can only be used as statement. )
expression.isExhaustiveWhen() -> inferredType.toIrType()
KotlinBuiltIns.isNothing(inferredType) -> inferredType.toIrType()
else -> context.irBuiltIns.unitType
}
val irWhen = IrWhenImpl(expression.startOffsetSkippingComments, expression.endOffset, resultType, IrStatementOrigin.WHEN)
for (ktEntry in expression.entries) { for (ktEntry in expression.entries) {
if (ktEntry.isElse) { if (ktEntry.isElse) {
@@ -170,12 +161,22 @@ class BranchingExpressionGenerator(statementGenerator: StatementGenerator) : Sta
private fun generateWhenBody(expression: KtWhenExpression, irSubject: IrVariable?, irWhen: IrWhen): IrExpression = private fun generateWhenBody(expression: KtWhenExpression, irSubject: IrVariable?, irWhen: IrWhen): IrExpression =
if (irSubject == null) { if (irSubject == null) {
if (irWhen.branches.isEmpty()) if (irWhen.branches.isEmpty())
IrBlockImpl(expression.startOffsetSkippingComments, expression.endOffset, context.irBuiltIns.unitType, IrStatementOrigin.WHEN) IrBlockImpl(
expression.startOffsetSkippingComments,
expression.endOffset,
context.irBuiltIns.unitType,
IrStatementOrigin.WHEN
)
else else
irWhen irWhen
} else { } else {
if (irWhen.branches.isEmpty()) { if (irWhen.branches.isEmpty()) {
val irBlock = IrBlockImpl(expression.startOffsetSkippingComments, expression.endOffset, context.irBuiltIns.unitType, IrStatementOrigin.WHEN) val irBlock = IrBlockImpl(
expression.startOffsetSkippingComments,
expression.endOffset,
context.irBuiltIns.unitType,
IrStatementOrigin.WHEN
)
irBlock.statements.add(irSubject) irBlock.statements.add(irSubject)
irBlock irBlock
} else { } else {
@@ -173,7 +173,7 @@ class ClassGenerator(
delegatedMembers: List<CallableMemberDescriptor> delegatedMembers: List<CallableMemberDescriptor>
) { ) {
val ktDelegateExpression = ktEntry.delegateExpression!! val ktDelegateExpression = ktEntry.delegateExpression!!
val delegateType = getInferredTypeWithImplicitCastsOrFail(ktDelegateExpression) val delegateType = getTypeInferredByFrontendOrFail(ktDelegateExpression)
val superType = getOrFail(BindingContext.TYPE, ktEntry.typeReference!!) val superType = getOrFail(BindingContext.TYPE, ktEntry.typeReference!!)
val superTypeConstructorDescriptor = superType.constructor.declarationDescriptor val superTypeConstructorDescriptor = superType.constructor.declarationDescriptor
val superClass = superTypeConstructorDescriptor as? ClassDescriptor val superClass = superTypeConstructorDescriptor as? ClassDescriptor
@@ -306,7 +306,7 @@ class DelegatedPropertyGenerator(declarationGenerator: DeclarationGenerator) : D
return if (provideDelegateResolvedCall != null) return if (provideDelegateResolvedCall != null)
provideDelegateResolvedCall.resultingDescriptor.returnType!! provideDelegateResolvedCall.resultingDescriptor.returnType!!
else else
getInferredTypeWithImplicitCastsOrFail(ktDelegate.expression!!) getTypeInferredByFrontendOrFail(ktDelegate.expression!!)
} }
private fun generateInitializerForLocalDelegatedPropertyDelegate( private fun generateInitializerForLocalDelegatedPropertyDelegate(
@@ -66,7 +66,7 @@ class ErrorExpressionGenerator(statementGenerator: StatementGenerator) : Stateme
} }
private fun getErrorExpressionType(ktExpression: KtExpression) = private fun getErrorExpressionType(ktExpression: KtExpression) =
getInferredTypeWithImplicitCasts(ktExpression) ?: ErrorUtils.createErrorType("") getTypeInferredByFrontend(ktExpression) ?: ErrorUtils.createErrorType("")
fun generateErrorSimpleName(ktName: KtSimpleNameExpression): IrExpression = generateErrorExpression(ktName) { fun generateErrorSimpleName(ktName: KtSimpleNameExpression): IrExpression = generateErrorExpression(ktName) {
val type = getErrorExpressionType(ktName).toIrType() val type = getErrorExpressionType(ktName).toIrType()
@@ -21,6 +21,7 @@ import org.jetbrains.kotlin.ir.builders.IrGenerator
import org.jetbrains.kotlin.ir.builders.IrGeneratorWithScope import org.jetbrains.kotlin.ir.builders.IrGeneratorWithScope
import org.jetbrains.kotlin.psi.KtElement import org.jetbrains.kotlin.psi.KtElement
import org.jetbrains.kotlin.psi.KtExpression import org.jetbrains.kotlin.psi.KtExpression
import org.jetbrains.kotlin.resolve.bindingContextUtil.isUsedAsExpression
import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall
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
@@ -44,11 +45,20 @@ fun <K, V : Any> Generator.getOrFail(slice: ReadOnlySlice<K, V>, key: K): V =
inline fun <K, V : Any> Generator.getOrFail(slice: ReadOnlySlice<K, V>, key: K, message: (K) -> String): V = inline fun <K, V : Any> Generator.getOrFail(slice: ReadOnlySlice<K, V>, key: K, message: (K) -> String): V =
context.bindingContext[slice, key] ?: throw RuntimeException(message(key)) context.bindingContext[slice, key] ?: throw RuntimeException(message(key))
fun Generator.getInferredTypeWithImplicitCasts(key: KtExpression): KotlinType? = fun Generator.getTypeInferredByFrontend(key: KtExpression): KotlinType? =
context.bindingContext.getType(key) context.bindingContext.getType(key)
fun Generator.getInferredTypeWithImplicitCastsOrFail(key: KtExpression): KotlinType = fun Generator.getTypeInferredByFrontendOrFail(key: KtExpression): KotlinType =
getInferredTypeWithImplicitCasts(key) ?: throw RuntimeException("No type for expression: ${key.text}") getTypeInferredByFrontend(key) ?: throw RuntimeException("No type for expression: ${key.text}")
fun Generator.getExpressionTypeWithCoercionToUnit(key: KtExpression): KotlinType? =
if (key.isUsedAsExpression(context.bindingContext))
getTypeInferredByFrontend(key)
else
context.builtIns.unitType
fun Generator.getExpressionTypeWithCoercionToUnitOrFail(key: KtExpression): KotlinType =
getExpressionTypeWithCoercionToUnit(key) ?: throw RuntimeException("No type for expression: ${key.text}")
fun Generator.getResolvedCall(key: KtElement): ResolvedCall<out CallableDescriptor>? = fun Generator.getResolvedCall(key: KtElement): ResolvedCall<out CallableDescriptor>? =
key.getResolvedCall(context.bindingContext) key.getResolvedCall(context.bindingContext)
@@ -29,7 +29,7 @@ class LocalClassGenerator(statementGenerator: StatementGenerator) : StatementGen
fun generateObjectLiteral(ktObjectLiteral: KtObjectLiteralExpression): IrStatement { fun generateObjectLiteral(ktObjectLiteral: KtObjectLiteralExpression): IrStatement {
val startOffset = ktObjectLiteral.startOffsetSkippingComments val startOffset = ktObjectLiteral.startOffsetSkippingComments
val endOffset = ktObjectLiteral.endOffset val endOffset = ktObjectLiteral.endOffset
val objectLiteralType = getInferredTypeWithImplicitCastsOrFail(ktObjectLiteral).toIrType() val objectLiteralType = getTypeInferredByFrontendOrFail(ktObjectLiteral).toIrType()
val irBlock = IrBlockImpl(startOffset, endOffset, objectLiteralType, IrStatementOrigin.OBJECT_LITERAL) val irBlock = IrBlockImpl(startOffset, endOffset, objectLiteralType, IrStatementOrigin.OBJECT_LITERAL)
val irClass = DeclarationGenerator(statementGenerator.context).generateClassOrObjectDeclaration(ktObjectLiteral.objectDeclaration) val irClass = DeclarationGenerator(statementGenerator.context).generateClassOrObjectDeclaration(ktObjectLiteral.objectDeclaration)
@@ -28,7 +28,7 @@ class LocalFunctionGenerator(statementGenerator: StatementGenerator) : Statement
fun generateLambda(ktLambda: KtLambdaExpression): IrStatement { fun generateLambda(ktLambda: KtLambdaExpression): IrStatement {
val ktFun = ktLambda.functionLiteral val ktFun = ktLambda.functionLiteral
val lambdaExpressionType = getInferredTypeWithImplicitCastsOrFail(ktLambda).toIrType() val lambdaExpressionType = getTypeInferredByFrontendOrFail(ktLambda).toIrType()
val irLambdaFunction = FunctionGenerator(context).generateLambdaFunctionDeclaration(ktFun) val irLambdaFunction = FunctionGenerator(context).generateLambdaFunctionDeclaration(ktFun)
return IrFunctionExpressionImpl( return IrFunctionExpressionImpl(
@@ -43,7 +43,7 @@ class LocalFunctionGenerator(statementGenerator: StatementGenerator) : Statement
val irFun = generateFunctionDeclaration(ktFun) val irFun = generateFunctionDeclaration(ktFun)
if (ktFun.name != null) return irFun if (ktFun.name != null) return irFun
val funExpressionType = getInferredTypeWithImplicitCastsOrFail(ktFun).toIrType() val funExpressionType = getTypeInferredByFrontendOrFail(ktFun).toIrType()
return IrFunctionExpressionImpl( return IrFunctionExpressionImpl(
ktFun.startOffset, ktFun.endOffset, ktFun.startOffset, ktFun.endOffset,
funExpressionType, funExpressionType,
@@ -37,7 +37,7 @@ class ReflectionReferencesGenerator(statementGenerator: StatementGenerator) : St
fun generateClassLiteral(ktClassLiteral: KtClassLiteralExpression): IrExpression { fun generateClassLiteral(ktClassLiteral: KtClassLiteralExpression): IrExpression {
val ktArgument = ktClassLiteral.receiverExpression!! val ktArgument = ktClassLiteral.receiverExpression!!
val lhs = getOrFail(BindingContext.DOUBLE_COLON_LHS, ktArgument) val lhs = getOrFail(BindingContext.DOUBLE_COLON_LHS, ktArgument)
val resultType = getInferredTypeWithImplicitCastsOrFail(ktClassLiteral).toIrType() val resultType = getTypeInferredByFrontendOrFail(ktClassLiteral).toIrType()
return if (lhs is DoubleColonLHS.Expression && !lhs.isObjectQualifier) { return if (lhs is DoubleColonLHS.Expression && !lhs.isObjectQualifier) {
IrGetClassImpl( IrGetClassImpl(
@@ -69,7 +69,7 @@ class ReflectionReferencesGenerator(statementGenerator: StatementGenerator) : St
).call { dispatchReceiverValue, extensionReceiverValue -> ).call { dispatchReceiverValue, extensionReceiverValue ->
generateCallableReference( generateCallableReference(
ktCallableReference, ktCallableReference,
getInferredTypeWithImplicitCastsOrFail(ktCallableReference), getTypeInferredByFrontendOrFail(ktCallableReference),
callBuilder.descriptor, callBuilder.descriptor,
callBuilder.typeArguments callBuilder.typeArguments
).also { irCallableReference -> ).also { irCallableReference ->
@@ -161,7 +161,7 @@ class StatementGenerator(
val isBlockBody = expression.parent is KtDeclarationWithBody && expression.parent !is KtFunctionLiteral val isBlockBody = expression.parent is KtDeclarationWithBody && expression.parent !is KtFunctionLiteral
if (isBlockBody) throw AssertionError("Use IrBlockBody and corresponding body generator to generate blocks as function bodies") if (isBlockBody) throw AssertionError("Use IrBlockBody and corresponding body generator to generate blocks as function bodies")
val returnType = getInferredTypeWithImplicitCasts(expression) ?: context.builtIns.unitType val returnType = getExpressionTypeWithCoercionToUnitOrFail(expression)
val irBlock = IrBlockImpl(expression.startOffsetSkippingComments, expression.endOffset, returnType.toIrType()) val irBlock = IrBlockImpl(expression.startOffsetSkippingComments, expression.endOffset, returnType.toIrType())
expression.statements.forEach { expression.statements.forEach {
@@ -226,14 +226,14 @@ class StatementGenerator(
context.constantValueGenerator.generateConstantValueAsExpression( context.constantValueGenerator.generateConstantValueAsExpression(
expression.startOffsetSkippingComments, expression.startOffsetSkippingComments,
expression.endOffset, expression.endOffset,
constant.toConstantValue(getInferredTypeWithImplicitCastsOrFail(expression)) constant.toConstantValue(getTypeInferredByFrontendOrFail(expression))
) )
override fun visitStringTemplateExpression(expression: KtStringTemplateExpression, data: Nothing?): IrStatement { override fun visitStringTemplateExpression(expression: KtStringTemplateExpression, data: Nothing?): IrStatement {
val startOffset = expression.startOffsetSkippingComments val startOffset = expression.startOffsetSkippingComments
val endOffset = expression.endOffset val endOffset = expression.endOffset
val resultType = getInferredTypeWithImplicitCastsOrFail(expression).toIrType() val resultType = getTypeInferredByFrontendOrFail(expression).toIrType()
val entries = expression.entries.map { it.genExpr() }.postprocessStringTemplateEntries() val entries = expression.entries.map { it.genExpr() }.postprocessStringTemplateEntries()
return when (entries.size) { return when (entries.size) {
@@ -27,7 +27,7 @@ import org.jetbrains.kotlin.resolve.BindingContext
class TryCatchExpressionGenerator(statementGenerator: StatementGenerator) : StatementGeneratorExtension(statementGenerator) { class TryCatchExpressionGenerator(statementGenerator: StatementGenerator) : StatementGeneratorExtension(statementGenerator) {
fun generateTryCatch(ktTry: KtTryExpression): IrExpression { fun generateTryCatch(ktTry: KtTryExpression): IrExpression {
val resultType = getInferredTypeWithImplicitCastsOrFail(ktTry).toIrType() val resultType = getExpressionTypeWithCoercionToUnitOrFail(ktTry).toIrType()
val irTryCatch = IrTryImpl(ktTry.startOffsetSkippingComments, ktTry.endOffset, resultType) val irTryCatch = IrTryImpl(ktTry.startOffsetSkippingComments, ktTry.endOffset, resultType)
irTryCatch.tryResult = ktTry.tryBlock.genExpr() irTryCatch.tryResult = ktTry.tryBlock.genExpr()
+1 -1
View File
@@ -5,7 +5,7 @@ CONTENT
1 FUN name:toString visibility:public modality:FINAL <> (grade:kotlin.String) returnType:kotlin.String 1 FUN name:toString visibility:public modality:FINAL <> (grade:kotlin.String) returnType:kotlin.String
2 GET_VAR 'grade: kotlin.String declared in <root>.toString' type=kotlin.String origin=null 2 GET_VAR 'grade: kotlin.String declared in <root>.toString' type=kotlin.String origin=null
3 VAR IR_TEMPORARY_VARIABLE name:tmp0_subject type:kotlin.String [val] 3 VAR IR_TEMPORARY_VARIABLE name:tmp0_subject type:kotlin.String [val]
4 WHEN type=kotlin.Nothing origin=WHEN 4 WHEN type=kotlin.Unit origin=WHEN
5 GET_VAR 'val tmp0_subject: kotlin.String [val] declared in <root>.toString' type=kotlin.String origin=null 5 GET_VAR 'val tmp0_subject: kotlin.String [val] declared in <root>.toString' type=kotlin.String origin=null
6 CONST String type=kotlin.String value="A" 6 CONST String type=kotlin.String value="A"
OUTGOING -> BB 1, 5 OUTGOING -> BB 1, 5
@@ -23,15 +23,15 @@ FILE fqName:<root> fileName:/useNextParamInLambda.kt
BLOCK_BODY BLOCK_BODY
VAR name:result type:kotlin.String [var] VAR name:result type:kotlin.String [var]
CONST String type=kotlin.String value="fail" CONST String type=kotlin.String value="fail"
TYPE_OP type=kotlin.Unit origin=IMPLICIT_COERCION_TO_UNIT typeOperand=kotlin.Unit TRY type=kotlin.Unit
TRY type=kotlin.Any try: BLOCK type=kotlin.Unit origin=null
try: BLOCK type=kotlin.String origin=null TYPE_OP type=kotlin.Unit origin=IMPLICIT_COERCION_TO_UNIT typeOperand=kotlin.Unit
CALL 'public final fun f (f1: kotlin.Function0<kotlin.String>, f2: kotlin.Function0<kotlin.String>): kotlin.String declared in <root>' type=kotlin.String origin=null CALL 'public final fun f (f1: kotlin.Function0<kotlin.String>, f2: kotlin.Function0<kotlin.String>): kotlin.String declared in <root>' type=kotlin.String origin=null
CATCH parameter=val e: java.lang.Exception{ kotlin.Exception } [val] declared in <root>.box CATCH parameter=val e: java.lang.Exception{ kotlin.Exception } [val] declared in <root>.box
VAR CATCH_PARAMETER name:e type:java.lang.Exception{ kotlin.Exception } [val] VAR CATCH_PARAMETER name:e type:java.lang.Exception{ kotlin.Exception } [val]
BLOCK type=kotlin.Unit origin=null BLOCK type=kotlin.Unit origin=null
SET_VAR 'var result: kotlin.String [var] declared in <root>.box' type=kotlin.Unit origin=EQ SET_VAR 'var result: kotlin.String [var] declared in <root>.box' type=kotlin.Unit origin=EQ
CONST String type=kotlin.String value="OK" CONST String type=kotlin.String value="OK"
RETURN type=kotlin.Nothing from='public final fun box (): kotlin.String declared in <root>' RETURN type=kotlin.Nothing from='public final fun box (): kotlin.String declared in <root>'
CALL 'public final fun plus (other: kotlin.Any?): kotlin.String declared in kotlin.String' type=kotlin.String origin=PLUS CALL 'public final fun plus (other: kotlin.Any?): kotlin.String declared in kotlin.String' type=kotlin.String origin=PLUS
$this: CALL 'public final fun f (f1: kotlin.Function0<kotlin.String>, f2: kotlin.Function0<kotlin.String>): kotlin.String declared in <root>' type=kotlin.String origin=null $this: CALL 'public final fun f (f1: kotlin.Function0<kotlin.String>, f2: kotlin.Function0<kotlin.String>): kotlin.String declared in <root>' type=kotlin.String origin=null
@@ -23,8 +23,8 @@ FILE fqName:<root> fileName:/breakContinueInWhen.kt
VAR FOR_LOOP_VARIABLE name:x type:kotlin.Int [val] VAR FOR_LOOP_VARIABLE name:x type:kotlin.Int [val]
CALL 'public final fun next (): kotlin.Int declared in kotlin.collections.IntIterator' type=kotlin.Int origin=FOR_LOOP_NEXT CALL 'public final fun next (): kotlin.Int declared in kotlin.collections.IntIterator' type=kotlin.Int origin=FOR_LOOP_NEXT
$this: GET_VAR 'val tmp0_iterator: kotlin.collections.IntIterator [val] declared in <root>.testBreakFor' type=kotlin.collections.IntIterator origin=null $this: GET_VAR 'val tmp0_iterator: kotlin.collections.IntIterator [val] declared in <root>.testBreakFor' type=kotlin.collections.IntIterator origin=null
BLOCK type=kotlin.Nothing origin=null BLOCK type=kotlin.Unit origin=null
WHEN type=kotlin.Nothing origin=WHEN WHEN type=kotlin.Unit origin=WHEN
BRANCH BRANCH
if: CALL 'public final fun greater (arg0: kotlin.Int, arg1: kotlin.Int): kotlin.Boolean declared in kotlin.internal.ir' type=kotlin.Boolean origin=GT if: CALL 'public final fun greater (arg0: kotlin.Int, arg1: kotlin.Int): kotlin.Boolean declared in kotlin.internal.ir' type=kotlin.Boolean origin=GT
arg0: GET_VAR 'var k: kotlin.Int [var] declared in <root>.testBreakFor' type=kotlin.Int origin=null arg0: GET_VAR 'var k: kotlin.Int [var] declared in <root>.testBreakFor' type=kotlin.Int origin=null
@@ -39,7 +39,7 @@ FILE fqName:<root> fileName:/breakContinueInWhen.kt
arg0: GET_VAR 'var k: kotlin.Int [var] declared in <root>.testBreakWhile' type=kotlin.Int origin=null arg0: GET_VAR 'var k: kotlin.Int [var] declared in <root>.testBreakWhile' type=kotlin.Int origin=null
arg1: CONST Int type=kotlin.Int value=10 arg1: CONST Int type=kotlin.Int value=10
body: BLOCK type=kotlin.Unit origin=null body: BLOCK type=kotlin.Unit origin=null
WHEN type=kotlin.Nothing origin=WHEN WHEN type=kotlin.Unit origin=WHEN
BRANCH BRANCH
if: CALL 'public final fun greater (arg0: kotlin.Int, arg1: kotlin.Int): kotlin.Boolean declared in kotlin.internal.ir' type=kotlin.Boolean origin=GT if: CALL 'public final fun greater (arg0: kotlin.Int, arg1: kotlin.Int): kotlin.Boolean declared in kotlin.internal.ir' type=kotlin.Boolean origin=GT
arg0: GET_VAR 'var k: kotlin.Int [var] declared in <root>.testBreakWhile' type=kotlin.Int origin=null arg0: GET_VAR 'var k: kotlin.Int [var] declared in <root>.testBreakWhile' type=kotlin.Int origin=null
@@ -52,7 +52,7 @@ FILE fqName:<root> fileName:/breakContinueInWhen.kt
BLOCK type=kotlin.Unit origin=null BLOCK type=kotlin.Unit origin=null
DO_WHILE label=null origin=DO_WHILE_LOOP DO_WHILE label=null origin=DO_WHILE_LOOP
body: COMPOSITE type=kotlin.Unit origin=null body: COMPOSITE type=kotlin.Unit origin=null
WHEN type=kotlin.Nothing origin=WHEN WHEN type=kotlin.Unit origin=WHEN
BRANCH BRANCH
if: CALL 'public final fun greater (arg0: kotlin.Int, arg1: kotlin.Int): kotlin.Boolean declared in kotlin.internal.ir' type=kotlin.Boolean origin=GT if: CALL 'public final fun greater (arg0: kotlin.Int, arg1: kotlin.Int): kotlin.Boolean declared in kotlin.internal.ir' type=kotlin.Boolean origin=GT
arg0: GET_VAR 'var k: kotlin.Int [var] declared in <root>.testBreakDoWhile' type=kotlin.Int origin=null arg0: GET_VAR 'var k: kotlin.Int [var] declared in <root>.testBreakDoWhile' type=kotlin.Int origin=null
@@ -85,8 +85,8 @@ FILE fqName:<root> fileName:/breakContinueInWhen.kt
VAR FOR_LOOP_VARIABLE name:x type:kotlin.Int [val] VAR FOR_LOOP_VARIABLE name:x type:kotlin.Int [val]
CALL 'public final fun next (): kotlin.Int declared in kotlin.collections.IntIterator' type=kotlin.Int origin=FOR_LOOP_NEXT CALL 'public final fun next (): kotlin.Int declared in kotlin.collections.IntIterator' type=kotlin.Int origin=FOR_LOOP_NEXT
$this: GET_VAR 'val tmp0_iterator: kotlin.collections.IntIterator [val] declared in <root>.testContinueFor' type=kotlin.collections.IntIterator origin=null $this: GET_VAR 'val tmp0_iterator: kotlin.collections.IntIterator [val] declared in <root>.testContinueFor' type=kotlin.collections.IntIterator origin=null
BLOCK type=kotlin.Nothing origin=null BLOCK type=kotlin.Unit origin=null
WHEN type=kotlin.Nothing origin=WHEN WHEN type=kotlin.Unit origin=WHEN
BRANCH BRANCH
if: CALL 'public final fun greater (arg0: kotlin.Int, arg1: kotlin.Int): kotlin.Boolean declared in kotlin.internal.ir' type=kotlin.Boolean origin=GT if: CALL 'public final fun greater (arg0: kotlin.Int, arg1: kotlin.Int): kotlin.Boolean declared in kotlin.internal.ir' type=kotlin.Boolean origin=GT
arg0: GET_VAR 'var k: kotlin.Int [var] declared in <root>.testContinueFor' type=kotlin.Int origin=null arg0: GET_VAR 'var k: kotlin.Int [var] declared in <root>.testContinueFor' type=kotlin.Int origin=null
@@ -101,7 +101,7 @@ FILE fqName:<root> fileName:/breakContinueInWhen.kt
arg0: GET_VAR 'var k: kotlin.Int [var] declared in <root>.testContinueWhile' type=kotlin.Int origin=null arg0: GET_VAR 'var k: kotlin.Int [var] declared in <root>.testContinueWhile' type=kotlin.Int origin=null
arg1: CONST Int type=kotlin.Int value=10 arg1: CONST Int type=kotlin.Int value=10
body: BLOCK type=kotlin.Unit origin=null body: BLOCK type=kotlin.Unit origin=null
WHEN type=kotlin.Nothing origin=WHEN WHEN type=kotlin.Unit origin=WHEN
BRANCH BRANCH
if: CALL 'public final fun greater (arg0: kotlin.Int, arg1: kotlin.Int): kotlin.Boolean declared in kotlin.internal.ir' type=kotlin.Boolean origin=GT if: CALL 'public final fun greater (arg0: kotlin.Int, arg1: kotlin.Int): kotlin.Boolean declared in kotlin.internal.ir' type=kotlin.Boolean origin=GT
arg0: GET_VAR 'var k: kotlin.Int [var] declared in <root>.testContinueWhile' type=kotlin.Int origin=null arg0: GET_VAR 'var k: kotlin.Int [var] declared in <root>.testContinueWhile' type=kotlin.Int origin=null
@@ -122,7 +122,7 @@ FILE fqName:<root> fileName:/breakContinueInWhen.kt
CALL 'public final fun inc (): kotlin.Int declared in kotlin.Int' type=kotlin.Int origin=PREFIX_INCR CALL 'public final fun inc (): kotlin.Int declared in kotlin.Int' type=kotlin.Int origin=PREFIX_INCR
$this: GET_VAR 'var k: kotlin.Int [var] declared in <root>.testContinueDoWhile' type=kotlin.Int origin=PREFIX_INCR $this: GET_VAR 'var k: kotlin.Int [var] declared in <root>.testContinueDoWhile' type=kotlin.Int origin=PREFIX_INCR
GET_VAR 'var k: kotlin.Int [var] declared in <root>.testContinueDoWhile' type=kotlin.Int origin=PREFIX_INCR GET_VAR 'var k: kotlin.Int [var] declared in <root>.testContinueDoWhile' type=kotlin.Int origin=PREFIX_INCR
WHEN type=kotlin.Nothing origin=WHEN WHEN type=kotlin.Unit origin=WHEN
BRANCH BRANCH
if: CALL 'public final fun greater (arg0: kotlin.Int, arg1: kotlin.Int): kotlin.Boolean declared in kotlin.internal.ir' type=kotlin.Boolean origin=GT if: CALL 'public final fun greater (arg0: kotlin.Int, arg1: kotlin.Int): kotlin.Boolean declared in kotlin.internal.ir' type=kotlin.Boolean origin=GT
arg0: GET_VAR 'var k: kotlin.Int [var] declared in <root>.testContinueDoWhile' type=kotlin.Int origin=null arg0: GET_VAR 'var k: kotlin.Int [var] declared in <root>.testContinueDoWhile' type=kotlin.Int origin=null
@@ -9,6 +9,6 @@ FILE fqName:<root> fileName:/catchParameterAccess.kt
$this: GET_VAR 'f: kotlin.Function0<kotlin.Unit> declared in <root>.test' type=kotlin.Function0<kotlin.Unit> origin=VARIABLE_AS_FUNCTION $this: GET_VAR 'f: kotlin.Function0<kotlin.Unit> declared in <root>.test' type=kotlin.Function0<kotlin.Unit> origin=VARIABLE_AS_FUNCTION
CATCH parameter=val e: java.lang.Exception{ kotlin.Exception } [val] declared in <root>.test CATCH parameter=val e: java.lang.Exception{ kotlin.Exception } [val] declared in <root>.test
VAR CATCH_PARAMETER name:e type:java.lang.Exception{ kotlin.Exception } [val] VAR CATCH_PARAMETER name:e type:java.lang.Exception{ kotlin.Exception } [val]
BLOCK type=kotlin.Nothing origin=null BLOCK type=kotlin.Unit origin=null
THROW type=kotlin.Nothing THROW type=kotlin.Nothing
GET_VAR 'val e: java.lang.Exception{ kotlin.Exception } [val] declared in <root>.test' type=java.lang.Exception{ kotlin.Exception } origin=null GET_VAR 'val e: java.lang.Exception{ kotlin.Exception } [val] declared in <root>.test' type=java.lang.Exception{ kotlin.Exception } origin=null
@@ -13,7 +13,7 @@ FILE fqName:<root> fileName:/forWithBreakContinue.kt
VAR FOR_LOOP_VARIABLE name:s type:kotlin.String [val] VAR FOR_LOOP_VARIABLE name:s type:kotlin.String [val]
CALL 'public abstract fun next (): T of kotlin.collections.Iterator declared in kotlin.collections.Iterator' type=kotlin.String origin=FOR_LOOP_NEXT CALL 'public abstract fun next (): T of kotlin.collections.Iterator declared in kotlin.collections.Iterator' type=kotlin.String origin=FOR_LOOP_NEXT
$this: GET_VAR 'val tmp0_iterator: kotlin.collections.Iterator<kotlin.String> [val] declared in <root>.testForBreak1' type=kotlin.collections.Iterator<kotlin.String> origin=null $this: GET_VAR 'val tmp0_iterator: kotlin.collections.Iterator<kotlin.String> [val] declared in <root>.testForBreak1' type=kotlin.collections.Iterator<kotlin.String> origin=null
BLOCK type=kotlin.Nothing origin=null BLOCK type=kotlin.Unit origin=null
BREAK label=null loop.label=null BREAK label=null loop.label=null
FUN name:testForBreak2 visibility:public modality:FINAL <> (ss:kotlin.collections.List<kotlin.String>) returnType:kotlin.Unit FUN name:testForBreak2 visibility:public modality:FINAL <> (ss:kotlin.collections.List<kotlin.String>) returnType:kotlin.Unit
VALUE_PARAMETER name:ss index:0 type:kotlin.collections.List<kotlin.String> VALUE_PARAMETER name:ss index:0 type:kotlin.collections.List<kotlin.String>
@@ -29,7 +29,7 @@ FILE fqName:<root> fileName:/forWithBreakContinue.kt
VAR FOR_LOOP_VARIABLE name:s1 type:kotlin.String [val] VAR FOR_LOOP_VARIABLE name:s1 type:kotlin.String [val]
CALL 'public abstract fun next (): T of kotlin.collections.Iterator declared in kotlin.collections.Iterator' type=kotlin.String origin=FOR_LOOP_NEXT CALL 'public abstract fun next (): T of kotlin.collections.Iterator declared in kotlin.collections.Iterator' type=kotlin.String origin=FOR_LOOP_NEXT
$this: GET_VAR 'val tmp0_iterator: kotlin.collections.Iterator<kotlin.String> [val] declared in <root>.testForBreak2' type=kotlin.collections.Iterator<kotlin.String> origin=null $this: GET_VAR 'val tmp0_iterator: kotlin.collections.Iterator<kotlin.String> [val] declared in <root>.testForBreak2' type=kotlin.collections.Iterator<kotlin.String> origin=null
BLOCK type=kotlin.Nothing origin=null BLOCK type=kotlin.Unit origin=null
BLOCK type=kotlin.Unit origin=FOR_LOOP BLOCK type=kotlin.Unit origin=FOR_LOOP
VAR FOR_LOOP_ITERATOR name:tmp1_iterator type:kotlin.collections.Iterator<kotlin.String> [val] VAR FOR_LOOP_ITERATOR name:tmp1_iterator type:kotlin.collections.Iterator<kotlin.String> [val]
CALL 'public abstract fun iterator (): kotlin.collections.Iterator<E of kotlin.collections.List> declared in kotlin.collections.List' type=kotlin.collections.Iterator<kotlin.String> origin=FOR_LOOP_ITERATOR CALL 'public abstract fun iterator (): kotlin.collections.Iterator<E of kotlin.collections.List> declared in kotlin.collections.List' type=kotlin.collections.Iterator<kotlin.String> origin=FOR_LOOP_ITERATOR
@@ -41,7 +41,7 @@ FILE fqName:<root> fileName:/forWithBreakContinue.kt
VAR FOR_LOOP_VARIABLE name:s2 type:kotlin.String [val] VAR FOR_LOOP_VARIABLE name:s2 type:kotlin.String [val]
CALL 'public abstract fun next (): T of kotlin.collections.Iterator declared in kotlin.collections.Iterator' type=kotlin.String origin=FOR_LOOP_NEXT CALL 'public abstract fun next (): T of kotlin.collections.Iterator declared in kotlin.collections.Iterator' type=kotlin.String origin=FOR_LOOP_NEXT
$this: GET_VAR 'val tmp1_iterator: kotlin.collections.Iterator<kotlin.String> [val] declared in <root>.testForBreak2' type=kotlin.collections.Iterator<kotlin.String> origin=null $this: GET_VAR 'val tmp1_iterator: kotlin.collections.Iterator<kotlin.String> [val] declared in <root>.testForBreak2' type=kotlin.collections.Iterator<kotlin.String> origin=null
BLOCK type=kotlin.Nothing origin=null BLOCK type=kotlin.Unit origin=null
BREAK label=OUTER loop.label=OUTER BREAK label=OUTER loop.label=OUTER
BREAK label=INNER loop.label=INNER BREAK label=INNER loop.label=INNER
BREAK label=null loop.label=INNER BREAK label=null loop.label=INNER
@@ -60,7 +60,7 @@ FILE fqName:<root> fileName:/forWithBreakContinue.kt
VAR FOR_LOOP_VARIABLE name:s type:kotlin.String [val] VAR FOR_LOOP_VARIABLE name:s type:kotlin.String [val]
CALL 'public abstract fun next (): T of kotlin.collections.Iterator declared in kotlin.collections.Iterator' type=kotlin.String origin=FOR_LOOP_NEXT CALL 'public abstract fun next (): T of kotlin.collections.Iterator declared in kotlin.collections.Iterator' type=kotlin.String origin=FOR_LOOP_NEXT
$this: GET_VAR 'val tmp0_iterator: kotlin.collections.Iterator<kotlin.String> [val] declared in <root>.testForContinue1' type=kotlin.collections.Iterator<kotlin.String> origin=null $this: GET_VAR 'val tmp0_iterator: kotlin.collections.Iterator<kotlin.String> [val] declared in <root>.testForContinue1' type=kotlin.collections.Iterator<kotlin.String> origin=null
BLOCK type=kotlin.Nothing origin=null BLOCK type=kotlin.Unit origin=null
CONTINUE label=null loop.label=null CONTINUE label=null loop.label=null
FUN name:testForContinue2 visibility:public modality:FINAL <> (ss:kotlin.collections.List<kotlin.String>) returnType:kotlin.Unit FUN name:testForContinue2 visibility:public modality:FINAL <> (ss:kotlin.collections.List<kotlin.String>) returnType:kotlin.Unit
VALUE_PARAMETER name:ss index:0 type:kotlin.collections.List<kotlin.String> VALUE_PARAMETER name:ss index:0 type:kotlin.collections.List<kotlin.String>
@@ -76,7 +76,7 @@ FILE fqName:<root> fileName:/forWithBreakContinue.kt
VAR FOR_LOOP_VARIABLE name:s1 type:kotlin.String [val] VAR FOR_LOOP_VARIABLE name:s1 type:kotlin.String [val]
CALL 'public abstract fun next (): T of kotlin.collections.Iterator declared in kotlin.collections.Iterator' type=kotlin.String origin=FOR_LOOP_NEXT CALL 'public abstract fun next (): T of kotlin.collections.Iterator declared in kotlin.collections.Iterator' type=kotlin.String origin=FOR_LOOP_NEXT
$this: GET_VAR 'val tmp0_iterator: kotlin.collections.Iterator<kotlin.String> [val] declared in <root>.testForContinue2' type=kotlin.collections.Iterator<kotlin.String> origin=null $this: GET_VAR 'val tmp0_iterator: kotlin.collections.Iterator<kotlin.String> [val] declared in <root>.testForContinue2' type=kotlin.collections.Iterator<kotlin.String> origin=null
BLOCK type=kotlin.Nothing origin=null BLOCK type=kotlin.Unit origin=null
BLOCK type=kotlin.Unit origin=FOR_LOOP BLOCK type=kotlin.Unit origin=FOR_LOOP
VAR FOR_LOOP_ITERATOR name:tmp1_iterator type:kotlin.collections.Iterator<kotlin.String> [val] VAR FOR_LOOP_ITERATOR name:tmp1_iterator type:kotlin.collections.Iterator<kotlin.String> [val]
CALL 'public abstract fun iterator (): kotlin.collections.Iterator<E of kotlin.collections.List> declared in kotlin.collections.List' type=kotlin.collections.Iterator<kotlin.String> origin=FOR_LOOP_ITERATOR CALL 'public abstract fun iterator (): kotlin.collections.Iterator<E of kotlin.collections.List> declared in kotlin.collections.List' type=kotlin.collections.Iterator<kotlin.String> origin=FOR_LOOP_ITERATOR
@@ -88,7 +88,7 @@ FILE fqName:<root> fileName:/forWithBreakContinue.kt
VAR FOR_LOOP_VARIABLE name:s2 type:kotlin.String [val] VAR FOR_LOOP_VARIABLE name:s2 type:kotlin.String [val]
CALL 'public abstract fun next (): T of kotlin.collections.Iterator declared in kotlin.collections.Iterator' type=kotlin.String origin=FOR_LOOP_NEXT CALL 'public abstract fun next (): T of kotlin.collections.Iterator declared in kotlin.collections.Iterator' type=kotlin.String origin=FOR_LOOP_NEXT
$this: GET_VAR 'val tmp1_iterator: kotlin.collections.Iterator<kotlin.String> [val] declared in <root>.testForContinue2' type=kotlin.collections.Iterator<kotlin.String> origin=null $this: GET_VAR 'val tmp1_iterator: kotlin.collections.Iterator<kotlin.String> [val] declared in <root>.testForContinue2' type=kotlin.collections.Iterator<kotlin.String> origin=null
BLOCK type=kotlin.Nothing origin=null BLOCK type=kotlin.Unit origin=null
CONTINUE label=OUTER loop.label=OUTER CONTINUE label=OUTER loop.label=OUTER
CONTINUE label=INNER loop.label=INNER CONTINUE label=INNER loop.label=INNER
CONTINUE label=null loop.label=INNER CONTINUE label=null loop.label=INNER
+16 -16
View File
@@ -36,22 +36,22 @@ FILE fqName:<root> fileName:/ifElseIf.kt
FUN name:testEmptyBranches2 visibility:public modality:FINAL <> (flag:kotlin.Boolean) returnType:kotlin.Unit FUN name:testEmptyBranches2 visibility:public modality:FINAL <> (flag:kotlin.Boolean) returnType:kotlin.Unit
VALUE_PARAMETER name:flag index:0 type:kotlin.Boolean VALUE_PARAMETER name:flag index:0 type:kotlin.Boolean
BLOCK_BODY BLOCK_BODY
TYPE_OP type=kotlin.Unit origin=IMPLICIT_COERCION_TO_UNIT typeOperand=kotlin.Unit WHEN type=kotlin.Unit origin=IF
WHEN type=kotlin.Any origin=IF BRANCH
BRANCH if: GET_VAR 'flag: kotlin.Boolean declared in <root>.testEmptyBranches2' type=kotlin.Boolean origin=null
if: GET_VAR 'flag: kotlin.Boolean declared in <root>.testEmptyBranches2' type=kotlin.Boolean origin=null then: BLOCK type=kotlin.Unit origin=null
then: BLOCK type=kotlin.Unit origin=null BRANCH
BRANCH if: CONST Boolean type=kotlin.Boolean value=true
if: CONST Boolean type=kotlin.Boolean value=true then: TYPE_OP type=kotlin.Unit origin=IMPLICIT_COERCION_TO_UNIT typeOperand=kotlin.Unit
then: CONST Boolean type=kotlin.Boolean value=true CONST Boolean type=kotlin.Boolean value=true
TYPE_OP type=kotlin.Unit origin=IMPLICIT_COERCION_TO_UNIT typeOperand=kotlin.Unit WHEN type=kotlin.Unit origin=IF
WHEN type=kotlin.Any origin=IF BRANCH
BRANCH if: GET_VAR 'flag: kotlin.Boolean declared in <root>.testEmptyBranches2' type=kotlin.Boolean origin=null
if: GET_VAR 'flag: kotlin.Boolean declared in <root>.testEmptyBranches2' type=kotlin.Boolean origin=null then: TYPE_OP type=kotlin.Unit origin=IMPLICIT_COERCION_TO_UNIT typeOperand=kotlin.Unit
then: CONST Boolean type=kotlin.Boolean value=true CONST Boolean type=kotlin.Boolean value=true
BRANCH BRANCH
if: CONST Boolean type=kotlin.Boolean value=true if: CONST Boolean type=kotlin.Boolean value=true
then: BLOCK type=kotlin.Unit origin=null then: BLOCK type=kotlin.Unit origin=null
FUN name:testEmptyBranches3 visibility:public modality:FINAL <> (flag:kotlin.Boolean) returnType:kotlin.Unit FUN name:testEmptyBranches3 visibility:public modality:FINAL <> (flag:kotlin.Boolean) returnType:kotlin.Unit
VALUE_PARAMETER name:flag index:0 type:kotlin.Boolean VALUE_PARAMETER name:flag index:0 type:kotlin.Boolean
BLOCK_BODY BLOCK_BODY
+1 -1
View File
@@ -10,7 +10,7 @@ FILE fqName:<root> fileName:/throw.kt
BRANCH BRANCH
if: TYPE_OP type=kotlin.Boolean origin=INSTANCEOF typeOperand=kotlin.Throwable if: TYPE_OP type=kotlin.Boolean origin=INSTANCEOF typeOperand=kotlin.Throwable
GET_VAR 'a: kotlin.Any declared in <root>.testImplicitCast' type=kotlin.Any origin=null GET_VAR 'a: kotlin.Any declared in <root>.testImplicitCast' type=kotlin.Any origin=null
then: BLOCK type=kotlin.Nothing origin=null then: BLOCK type=kotlin.Unit origin=null
THROW type=kotlin.Nothing THROW type=kotlin.Nothing
TYPE_OP type=kotlin.Throwable origin=IMPLICIT_CAST typeOperand=kotlin.Throwable TYPE_OP type=kotlin.Throwable origin=IMPLICIT_CAST typeOperand=kotlin.Throwable
GET_VAR 'a: kotlin.Any declared in <root>.testImplicitCast' type=kotlin.Any origin=null GET_VAR 'a: kotlin.Any declared in <root>.testImplicitCast' type=kotlin.Any origin=null
+3 -3
View File
@@ -22,7 +22,7 @@ FILE fqName:<root> fileName:/tryCatch.kt
BLOCK type=kotlin.Int origin=null BLOCK type=kotlin.Int origin=null
CALL 'public final fun println (): kotlin.Unit [inline] declared in kotlin.io' type=kotlin.Unit origin=null CALL 'public final fun println (): kotlin.Unit [inline] declared in kotlin.io' type=kotlin.Unit origin=null
CONST Int type=kotlin.Int value=24 CONST Int type=kotlin.Int value=24
finally: TYPE_OP type=kotlin.Unit origin=IMPLICIT_COERCION_TO_UNIT typeOperand=kotlin.Unit finally: BLOCK type=kotlin.Unit origin=null
BLOCK type=kotlin.Int origin=null CALL 'public final fun println (): kotlin.Unit [inline] declared in kotlin.io' type=kotlin.Unit origin=null
CALL 'public final fun println (): kotlin.Unit [inline] declared in kotlin.io' type=kotlin.Unit origin=null TYPE_OP type=kotlin.Unit origin=IMPLICIT_COERCION_TO_UNIT typeOperand=kotlin.Unit
CONST Int type=kotlin.Int value=555 CONST Int type=kotlin.Int value=555
+2 -2
View File
@@ -2,10 +2,10 @@ FILE fqName:<root> fileName:/whenReturn.kt
FUN name:toString visibility:public modality:FINAL <> (grade:kotlin.String) returnType:kotlin.String FUN name:toString visibility:public modality:FINAL <> (grade:kotlin.String) returnType:kotlin.String
VALUE_PARAMETER name:grade index:0 type:kotlin.String VALUE_PARAMETER name:grade index:0 type:kotlin.String
BLOCK_BODY BLOCK_BODY
BLOCK type=kotlin.Nothing origin=WHEN BLOCK type=kotlin.Unit origin=WHEN
VAR IR_TEMPORARY_VARIABLE name:tmp0_subject type:kotlin.String [val] VAR IR_TEMPORARY_VARIABLE name:tmp0_subject type:kotlin.String [val]
GET_VAR 'grade: kotlin.String declared in <root>.toString' type=kotlin.String origin=null GET_VAR 'grade: kotlin.String declared in <root>.toString' type=kotlin.String origin=null
WHEN type=kotlin.Nothing origin=WHEN WHEN type=kotlin.Unit origin=WHEN
BRANCH BRANCH
if: CALL 'public final fun EQEQ (arg0: kotlin.Any?, arg1: kotlin.Any?): kotlin.Boolean declared in kotlin.internal.ir' type=kotlin.Boolean origin=EQEQ if: CALL 'public final fun EQEQ (arg0: kotlin.Any?, arg1: kotlin.Any?): kotlin.Boolean declared in kotlin.internal.ir' type=kotlin.Boolean origin=EQEQ
arg0: GET_VAR 'val tmp0_subject: kotlin.String [val] declared in <root>.toString' type=kotlin.String origin=null arg0: GET_VAR 'val tmp0_subject: kotlin.String [val] declared in <root>.toString' type=kotlin.String origin=null
+2 -2
View File
@@ -10,10 +10,10 @@ FILE fqName:<root> fileName:/whenReturnUnit.kt
block: FUN_EXPR type=kotlin.Function0<kotlin.Unit> origin=LAMBDA block: FUN_EXPR type=kotlin.Function0<kotlin.Unit> origin=LAMBDA
FUN LOCAL_FUNCTION_FOR_LAMBDA name:<anonymous> visibility:local modality:FINAL <> () returnType:kotlin.Unit FUN LOCAL_FUNCTION_FOR_LAMBDA name:<anonymous> visibility:local modality:FINAL <> () returnType:kotlin.Unit
BLOCK_BODY BLOCK_BODY
BLOCK type=kotlin.Nothing origin=WHEN BLOCK type=kotlin.Unit origin=WHEN
VAR IR_TEMPORARY_VARIABLE name:tmp0_subject type:kotlin.Int [val] VAR IR_TEMPORARY_VARIABLE name:tmp0_subject type:kotlin.Int [val]
GET_VAR 'x: kotlin.Int declared in <root>.branch' type=kotlin.Int origin=null GET_VAR 'x: kotlin.Int declared in <root>.branch' type=kotlin.Int origin=null
WHEN type=kotlin.Nothing origin=WHEN WHEN type=kotlin.Unit origin=WHEN
BRANCH BRANCH
if: CALL 'public final fun EQEQ (arg0: kotlin.Any?, arg1: kotlin.Any?): kotlin.Boolean declared in kotlin.internal.ir' type=kotlin.Boolean origin=EQEQ if: CALL 'public final fun EQEQ (arg0: kotlin.Any?, arg1: kotlin.Any?): kotlin.Boolean declared in kotlin.internal.ir' type=kotlin.Boolean origin=EQEQ
arg0: GET_VAR 'val tmp0_subject: kotlin.Int [val] declared in <root>.branch.<anonymous>' type=kotlin.Int origin=null arg0: GET_VAR 'val tmp0_subject: kotlin.Int [val] declared in <root>.branch.<anonymous>' type=kotlin.Int origin=null
@@ -3,23 +3,25 @@ FILE fqName:<root> fileName:/whenUnusedExpression.kt
VALUE_PARAMETER name:b index:0 type:kotlin.Boolean VALUE_PARAMETER name:b index:0 type:kotlin.Boolean
VALUE_PARAMETER name:i index:1 type:kotlin.Int VALUE_PARAMETER name:i index:1 type:kotlin.Int
BLOCK_BODY BLOCK_BODY
TYPE_OP type=kotlin.Unit origin=IMPLICIT_COERCION_TO_UNIT typeOperand=kotlin.Unit WHEN type=kotlin.Unit origin=IF
WHEN type=kotlin.Int? origin=IF BRANCH
BRANCH if: GET_VAR 'b: kotlin.Boolean declared in <root>.test' type=kotlin.Boolean origin=null
if: GET_VAR 'b: kotlin.Boolean declared in <root>.test' type=kotlin.Boolean origin=null then: BLOCK type=kotlin.Unit origin=null
then: BLOCK type=kotlin.Int? origin=null BLOCK type=kotlin.Unit origin=WHEN
BLOCK type=kotlin.Int? origin=WHEN VAR IR_TEMPORARY_VARIABLE name:tmp0_subject type:kotlin.Int [val]
VAR IR_TEMPORARY_VARIABLE name:tmp0_subject type:kotlin.Int [val] GET_VAR 'i: kotlin.Int declared in <root>.test' type=kotlin.Int origin=null
GET_VAR 'i: kotlin.Int declared in <root>.test' type=kotlin.Int origin=null WHEN type=kotlin.Unit origin=WHEN
WHEN type=kotlin.Int? origin=WHEN BRANCH
BRANCH if: CALL 'public final fun EQEQ (arg0: kotlin.Any?, arg1: kotlin.Any?): kotlin.Boolean declared in kotlin.internal.ir' type=kotlin.Boolean origin=EQEQ
if: CALL 'public final fun EQEQ (arg0: kotlin.Any?, arg1: kotlin.Any?): kotlin.Boolean declared in kotlin.internal.ir' type=kotlin.Boolean origin=EQEQ arg0: GET_VAR 'val tmp0_subject: kotlin.Int [val] declared in <root>.test' type=kotlin.Int origin=null
arg0: GET_VAR 'val tmp0_subject: kotlin.Int [val] declared in <root>.test' type=kotlin.Int origin=null arg1: CONST Int type=kotlin.Int value=0
arg1: CONST Int type=kotlin.Int value=0 then: TYPE_OP type=kotlin.Unit origin=IMPLICIT_COERCION_TO_UNIT typeOperand=kotlin.Unit
then: CONST Int type=kotlin.Int value=1 CONST Int type=kotlin.Int value=1
BRANCH BRANCH
if: CONST Boolean type=kotlin.Boolean value=true if: CONST Boolean type=kotlin.Boolean value=true
then: CONST Null type=kotlin.Nothing? value=null then: TYPE_OP type=kotlin.Unit origin=IMPLICIT_COERCION_TO_UNIT typeOperand=kotlin.Unit
BRANCH CONST Null type=kotlin.Nothing? value=null
if: CONST Boolean type=kotlin.Boolean value=true BRANCH
then: CONST Null type=kotlin.Nothing? value=null if: CONST Boolean type=kotlin.Boolean value=true
then: TYPE_OP type=kotlin.Unit origin=IMPLICIT_COERCION_TO_UNIT typeOperand=kotlin.Unit
CONST Null type=kotlin.Nothing? value=null
+9 -9
View File
@@ -12,19 +12,19 @@ FILE fqName:<root> fileName:/kt24114.kt
WHILE label=null origin=WHILE_LOOP WHILE label=null origin=WHILE_LOOP
condition: CONST Boolean type=kotlin.Boolean value=true condition: CONST Boolean type=kotlin.Boolean value=true
body: BLOCK type=kotlin.Unit origin=null body: BLOCK type=kotlin.Unit origin=null
BLOCK type=kotlin.Nothing origin=WHEN BLOCK type=kotlin.Unit origin=WHEN
VAR IR_TEMPORARY_VARIABLE name:tmp0_subject type:kotlin.Int [val] VAR IR_TEMPORARY_VARIABLE name:tmp0_subject type:kotlin.Int [val]
CALL 'public final fun one (): kotlin.Int declared in <root>' type=kotlin.Int origin=null CALL 'public final fun one (): kotlin.Int declared in <root>' type=kotlin.Int origin=null
WHEN type=kotlin.Nothing origin=WHEN WHEN type=kotlin.Unit origin=WHEN
BRANCH BRANCH
if: CALL 'public final fun EQEQ (arg0: kotlin.Any?, arg1: kotlin.Any?): kotlin.Boolean declared in kotlin.internal.ir' type=kotlin.Boolean origin=EQEQ if: CALL 'public final fun EQEQ (arg0: kotlin.Any?, arg1: kotlin.Any?): kotlin.Boolean declared in kotlin.internal.ir' type=kotlin.Boolean origin=EQEQ
arg0: GET_VAR 'val tmp0_subject: kotlin.Int [val] declared in <root>.test1' type=kotlin.Int origin=null arg0: GET_VAR 'val tmp0_subject: kotlin.Int [val] declared in <root>.test1' type=kotlin.Int origin=null
arg1: CONST Int type=kotlin.Int value=1 arg1: CONST Int type=kotlin.Int value=1
then: BLOCK type=kotlin.Nothing origin=null then: BLOCK type=kotlin.Unit origin=null
BLOCK type=kotlin.Nothing origin=WHEN BLOCK type=kotlin.Unit origin=WHEN
VAR IR_TEMPORARY_VARIABLE name:tmp1_subject type:kotlin.Int [val] VAR IR_TEMPORARY_VARIABLE name:tmp1_subject type:kotlin.Int [val]
CALL 'public final fun two (): kotlin.Int declared in <root>' type=kotlin.Int origin=null CALL 'public final fun two (): kotlin.Int declared in <root>' type=kotlin.Int origin=null
WHEN type=kotlin.Nothing origin=WHEN WHEN type=kotlin.Unit origin=WHEN
BRANCH BRANCH
if: CALL 'public final fun EQEQ (arg0: kotlin.Any?, arg1: kotlin.Any?): kotlin.Boolean declared in kotlin.internal.ir' type=kotlin.Boolean origin=EQEQ if: CALL 'public final fun EQEQ (arg0: kotlin.Any?, arg1: kotlin.Any?): kotlin.Boolean declared in kotlin.internal.ir' type=kotlin.Boolean origin=EQEQ
arg0: GET_VAR 'val tmp1_subject: kotlin.Int [val] declared in <root>.test1' type=kotlin.Int origin=null arg0: GET_VAR 'val tmp1_subject: kotlin.Int [val] declared in <root>.test1' type=kotlin.Int origin=null
@@ -40,18 +40,18 @@ FILE fqName:<root> fileName:/kt24114.kt
WHILE label=null origin=WHILE_LOOP WHILE label=null origin=WHILE_LOOP
condition: CONST Boolean type=kotlin.Boolean value=true condition: CONST Boolean type=kotlin.Boolean value=true
body: BLOCK type=kotlin.Unit origin=null body: BLOCK type=kotlin.Unit origin=null
BLOCK type=kotlin.Nothing origin=WHEN BLOCK type=kotlin.Unit origin=WHEN
VAR IR_TEMPORARY_VARIABLE name:tmp0_subject type:kotlin.Int [val] VAR IR_TEMPORARY_VARIABLE name:tmp0_subject type:kotlin.Int [val]
CALL 'public final fun one (): kotlin.Int declared in <root>' type=kotlin.Int origin=null CALL 'public final fun one (): kotlin.Int declared in <root>' type=kotlin.Int origin=null
WHEN type=kotlin.Nothing origin=WHEN WHEN type=kotlin.Unit origin=WHEN
BRANCH BRANCH
if: CALL 'public final fun EQEQ (arg0: kotlin.Any?, arg1: kotlin.Any?): kotlin.Boolean declared in kotlin.internal.ir' type=kotlin.Boolean origin=EQEQ if: CALL 'public final fun EQEQ (arg0: kotlin.Any?, arg1: kotlin.Any?): kotlin.Boolean declared in kotlin.internal.ir' type=kotlin.Boolean origin=EQEQ
arg0: GET_VAR 'val tmp0_subject: kotlin.Int [val] declared in <root>.test2' type=kotlin.Int origin=null arg0: GET_VAR 'val tmp0_subject: kotlin.Int [val] declared in <root>.test2' type=kotlin.Int origin=null
arg1: CONST Int type=kotlin.Int value=1 arg1: CONST Int type=kotlin.Int value=1
then: BLOCK type=kotlin.Nothing origin=WHEN then: BLOCK type=kotlin.Unit origin=WHEN
VAR IR_TEMPORARY_VARIABLE name:tmp1_subject type:kotlin.Int [val] VAR IR_TEMPORARY_VARIABLE name:tmp1_subject type:kotlin.Int [val]
CALL 'public final fun two (): kotlin.Int declared in <root>' type=kotlin.Int origin=null CALL 'public final fun two (): kotlin.Int declared in <root>' type=kotlin.Int origin=null
WHEN type=kotlin.Nothing origin=WHEN WHEN type=kotlin.Unit origin=WHEN
BRANCH BRANCH
if: CALL 'public final fun EQEQ (arg0: kotlin.Any?, arg1: kotlin.Any?): kotlin.Boolean declared in kotlin.internal.ir' type=kotlin.Boolean origin=EQEQ if: CALL 'public final fun EQEQ (arg0: kotlin.Any?, arg1: kotlin.Any?): kotlin.Boolean declared in kotlin.internal.ir' type=kotlin.Boolean origin=EQEQ
arg0: GET_VAR 'val tmp1_subject: kotlin.Int [val] declared in <root>.test2' type=kotlin.Int origin=null arg0: GET_VAR 'val tmp1_subject: kotlin.Int [val] declared in <root>.test2' type=kotlin.Int origin=null