diff --git a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/Psi2IrTranslator.kt b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/Psi2IrTranslator.kt index e2b4f6ae714..9bf1aee401b 100644 --- a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/Psi2IrTranslator.kt +++ b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/Psi2IrTranslator.kt @@ -21,30 +21,18 @@ import org.jetbrains.kotlin.ir.declarations.IrModule import org.jetbrains.kotlin.psi.KtFile import org.jetbrains.kotlin.psi2ir.generators.GeneratorContext import org.jetbrains.kotlin.psi2ir.generators.ModuleGenerator -import org.jetbrains.kotlin.psi2ir.transformations.foldStringConcatenation -import org.jetbrains.kotlin.psi2ir.transformations.inlineDesugaredBlocks -import org.jetbrains.kotlin.psi2ir.transformations.inlineSafeCallChains import org.jetbrains.kotlin.psi2ir.transformations.insertImplicitCasts import org.jetbrains.kotlin.resolve.BindingContext -class Psi2IrTranslator(val configuration: Configuration = Configuration()) { - class Configuration( - val shouldInlineDesugaredBlocks: Boolean = false, - val shouldFoldStringConcatenation: Boolean = true, - val shouldInlineSafeCallChains: Boolean = true - ) - +class Psi2IrTranslator() { fun generateModule(moduleDescriptor: ModuleDescriptor, ktFiles: List, bindingContext: BindingContext): IrModule { val context = GeneratorContext(moduleDescriptor, bindingContext) val irModule = ModuleGenerator(context).generateModule(ktFiles) - postprocess(irModule, context) + postprocess(irModule) return irModule } - private fun postprocess(irModule: IrModule, context: GeneratorContext) { - insertImplicitCasts(irModule.irBuiltins.builtIns, irModule) - if (configuration.shouldInlineDesugaredBlocks) inlineDesugaredBlocks(irModule) - if (configuration.shouldFoldStringConcatenation) foldStringConcatenation(irModule) - if (configuration.shouldInlineSafeCallChains) inlineSafeCallChains(context, irModule) + private fun postprocess(irModule: IrModule) { + insertImplicitCasts(irModule.descriptor.builtIns, irModule) } } diff --git a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/CallGenerator.kt b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/CallGenerator.kt index a2b1430cddb..14d6404ef1d 100644 --- a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/CallGenerator.kt +++ b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/CallGenerator.kt @@ -24,11 +24,7 @@ import org.jetbrains.kotlin.ir.expressions.* import org.jetbrains.kotlin.psi.KtElement import org.jetbrains.kotlin.psi.psiUtil.endOffset import org.jetbrains.kotlin.psi.psiUtil.startOffset -import org.jetbrains.kotlin.psi2ir.intermediate.CallBuilder -import org.jetbrains.kotlin.psi2ir.intermediate.getValueArgumentsInParameterOrder -import org.jetbrains.kotlin.psi2ir.intermediate.isValueArgumentReorderingRequired -import org.jetbrains.kotlin.psi2ir.intermediate.IntermediateValue -import org.jetbrains.kotlin.psi2ir.intermediate.createRematerializableOrTemporary +import org.jetbrains.kotlin.psi2ir.intermediate.* import org.jetbrains.kotlin.resolve.calls.model.ResolvedValueArgument import org.jetbrains.kotlin.types.KotlinType import java.util.* @@ -63,7 +59,9 @@ class CallGenerator(statementGenerator: StatementGenerator): StatementGeneratorE call: CallBuilder ): IrExpression { return call.callReceiver.call { dispatchReceiverValue, extensionReceiverValue -> - IrGetterCallImpl(startOffset, endOffset, descriptor.getter!!, + val getter = descriptor.getter ?: + throw AssertionError("No getter for property $descriptor") + IrGetterCallImpl(startOffset, endOffset, getter, dispatchReceiverValue?.load(), extensionReceiverValue?.load(), IrOperator.GET_PROPERTY, @@ -126,7 +124,7 @@ class CallGenerator(statementGenerator: StatementGenerator): StatementGeneratorE for (valueArgument in valueArgumentsInEvaluationOrder) { val valueParameter = valueArgumentsToValueParameters[valueArgument]!! val irArgument = call.getValueArgument(valueParameter) ?: continue - val irArgumentValue = createRematerializableOrTemporary(scope, irArgument, irBlock, valueParameter.name.asString()) + val irArgumentValue = scope.createTemporaryVariableInBlock(irArgument, irBlock, valueParameter.name.asString()) irArgumentValues[valueParameter] = irArgumentValue } diff --git a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/OperatorExpressionGenerator.kt b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/OperatorExpressionGenerator.kt index 31a990a96a6..3fd26b4c47a 100644 --- a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/OperatorExpressionGenerator.kt +++ b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/OperatorExpressionGenerator.kt @@ -22,7 +22,7 @@ import org.jetbrains.kotlin.lexer.KtTokens import org.jetbrains.kotlin.psi.* import org.jetbrains.kotlin.psi.psiUtil.endOffset import org.jetbrains.kotlin.psi.psiUtil.startOffset -import org.jetbrains.kotlin.psi2ir.intermediate.createRematerializableOrTemporary +import org.jetbrains.kotlin.psi2ir.intermediate.createTemporaryVariableInBlock import org.jetbrains.kotlin.resolve.BindingContext import org.jetbrains.kotlin.types.typeUtil.makeNotNullable import org.jetbrains.kotlin.types.typeUtil.makeNullable @@ -112,7 +112,7 @@ class OperatorExpressionGenerator(statementGenerator: StatementGenerator) : Stat val irArgument1 = statementGenerator.generateExpression(expression.right!!) val irBlock = IrBlockImpl(expression.startOffset, expression.endOffset, returnType, IrOperator.ELVIS) - val irArgument0Value = createRematerializableOrTemporary(scope, irArgument0, irBlock, "elvis_lhs") + val irArgument0Value = scope.createTemporaryVariableInBlock(irArgument0, irBlock, "elvis_lhs") irBlock.addStatement(IrIfThenElseImpl( expression.startOffset, expression.endOffset, returnType, context.equalsNull(expression.startOffset, expression.endOffset, irArgument0Value.load()), @@ -222,19 +222,14 @@ class OperatorExpressionGenerator(statementGenerator: StatementGenerator) : Stat val resultType = irArgument.type.makeNotNullable() val irBlock = IrBlockImpl(ktOperator.startOffset, ktOperator.endOffset, resultType, irOperator) - val argumentValue = createRematerializableOrTemporary(scope, irArgument, irBlock, "notnull") + val argumentValue = scope.createTemporaryVariableInBlock(irArgument, irBlock, "notnull") val irIfThenElse = IrIfThenElseImpl(ktOperator.startOffset, ktOperator.endOffset, resultType, context.equalsNull(ktOperator.startOffset, ktOperator.endOffset, argumentValue.load()), context.throwNpe(ktOperator.startOffset, ktOperator.endOffset, irOperator), argumentValue.load()) - return if (irBlock.statements.isEmpty()) { - irIfThenElse - } - else { - irBlock.addStatement(irIfThenElse) - irBlock - } + irBlock.addStatement(irIfThenElse) + return irBlock } private fun generatePrefixOperatorAsCall(expression: KtPrefixExpression, irOperator: IrOperator): IrExpression { diff --git a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/StatementGenerator.kt b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/StatementGenerator.kt index 7501babbb30..f44508521ca 100644 --- a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/StatementGenerator.kt +++ b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/StatementGenerator.kt @@ -27,7 +27,7 @@ import org.jetbrains.kotlin.psi.psiUtil.endOffset import org.jetbrains.kotlin.psi.psiUtil.startOffset import org.jetbrains.kotlin.psi2ir.deparenthesize import org.jetbrains.kotlin.psi2ir.intermediate.IntermediateValue -import org.jetbrains.kotlin.psi2ir.intermediate.createRematerializableOrTemporary +import org.jetbrains.kotlin.psi2ir.intermediate.createTemporaryVariableInBlock import org.jetbrains.kotlin.psi2ir.intermediate.setExplicitReceiverValue import org.jetbrains.kotlin.resolve.BindingContext import org.jetbrains.kotlin.resolve.BindingContextUtils @@ -81,7 +81,7 @@ class StatementGenerator( val irBlock = IrBlockImpl(multiDeclaration.startOffset, multiDeclaration.endOffset, context.builtIns.unitType, IrOperator.DESTRUCTURING_DECLARATION) val ktInitializer = multiDeclaration.initializer!! - val containerValue = createRematerializableOrTemporary(scope, ktInitializer.genExpr(), irBlock, "container") + val containerValue = scope.createTemporaryVariableInBlock(ktInitializer.genExpr(), irBlock, "container") declareComponentVariablesInBlock(multiDeclaration, irBlock, containerValue) diff --git a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/intermediate/ArrayAccessAssignmentReceiver.kt b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/intermediate/ArrayAccessAssignmentReceiver.kt index 75eb076dd8b..1f53e3987fc 100644 --- a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/intermediate/ArrayAccessAssignmentReceiver.kt +++ b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/intermediate/ArrayAccessAssignmentReceiver.kt @@ -40,10 +40,10 @@ class ArrayAccessAssignmentReceiver( val resultType = if (hasResult) type else callGenerator.context.builtIns.unitType val irBlock = IrBlockImpl(startOffset, endOffset, resultType, operator) - val irArrayValue = createRematerializableOrTemporary(callGenerator.scope, irArray, irBlock, "array") + val irArrayValue = callGenerator.scope.createTemporaryVariableInBlock(irArray, irBlock, "array") val irIndexValues = irIndices.mapIndexed { i, irIndex -> - createRematerializableOrTemporary(callGenerator.scope, irIndex, irBlock, "index$i") + callGenerator.scope.createTemporaryVariableInBlock(irIndex, irBlock, "index$i") } indexedGetCall?.fillArrayAndIndexArguments(irArrayValue, irIndexValues) diff --git a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/intermediate/RematerializableValue.kt b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/intermediate/RematerializableValue.kt index 57b2d3f3fd0..50531a4df8f 100644 --- a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/intermediate/RematerializableValue.kt +++ b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/intermediate/RematerializableValue.kt @@ -16,8 +16,9 @@ package org.jetbrains.kotlin.psi2ir.intermediate -import org.jetbrains.kotlin.ir.declarations.IrVariable -import org.jetbrains.kotlin.ir.expressions.* +import org.jetbrains.kotlin.ir.expressions.IrBlockImpl +import org.jetbrains.kotlin.ir.expressions.IrExpression +import org.jetbrains.kotlin.ir.expressions.IrExpressionWithCopy import org.jetbrains.kotlin.psi2ir.generators.Scope import org.jetbrains.kotlin.types.KotlinType @@ -27,26 +28,8 @@ class RematerializableValue(val irExpression: IrExpressionWithCopy) : Intermedia override fun load(): IrExpression = irExpression.copy() } -fun createRematerializableValue(irExpression: IrExpression): IntermediateValue? = - (irExpression as? IrExpressionWithCopy)?.let { RematerializableValue(it) } - -inline fun createRematerializableOrTemporary( - scope: Scope, - irExpression: IrExpression, - nameHint: String? = null, - addVariable: (IrVariable) -> Unit -): IntermediateValue { - val rematerializable = createRematerializableValue(irExpression) - if (rematerializable != null) { - return rematerializable - } - - val temporaryVariable = scope.createTemporaryVariable(irExpression, nameHint) - addVariable(temporaryVariable) +fun Scope.createTemporaryVariableInBlock(irExpression: IrExpression, block: IrBlockImpl, nameHint: String? = null): IntermediateValue { + val temporaryVariable = createTemporaryVariable(irExpression, nameHint) + block.addStatement(temporaryVariable) return VariableLValue(temporaryVariable) -} - -fun createRematerializableOrTemporary(scope: Scope, irExpression: IrExpression, block: IrBlockImpl, nameHint: String? = null): IntermediateValue = - createRematerializableOrTemporary(scope, irExpression, nameHint) { - block.addStatement(it) - } \ No newline at end of file +} \ No newline at end of file diff --git a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/intermediate/SimplePropertyLValue.kt b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/intermediate/SimplePropertyLValue.kt index 70b6d261da9..e5755e229fe 100644 --- a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/intermediate/SimplePropertyLValue.kt +++ b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/intermediate/SimplePropertyLValue.kt @@ -62,21 +62,9 @@ class SimplePropertyLValue( return callReceiver.call { dispatchReceiverValue, extensionReceiverValue -> val variablesForReceivers = SmartList() - val tmpDispatchReceiverValue = dispatchReceiverValue?.load()?.let { - createRematerializableOrTemporary(scope, it, "this") { - irVar -> variablesForReceivers.add(irVar) - } - } - - val tmpExtensionReceiverValue = extensionReceiverValue?.load()?.let { - createRematerializableOrTemporary(scope, it, "receiver") { - irVar -> variablesForReceivers.add(irVar) - } - } - val irResultExpression = withLValue( SimplePropertyLValue(scope, startOffset, endOffset, irOperator, descriptor, - SimpleCallReceiver(tmpDispatchReceiverValue, tmpExtensionReceiverValue), + SimpleCallReceiver(dispatchReceiverValue, extensionReceiverValue), superQualifier) ) diff --git a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/transformations/InlineSafeCallChains.kt b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/transformations/InlineSafeCallChains.kt deleted file mode 100644 index e6df95df146..00000000000 --- a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/transformations/InlineSafeCallChains.kt +++ /dev/null @@ -1,119 +0,0 @@ -/* - * 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.transformations - -import org.jetbrains.kotlin.ir.IrElement -import org.jetbrains.kotlin.ir.declarations.IrVariable -import org.jetbrains.kotlin.ir.detach -import org.jetbrains.kotlin.ir.expressions.* -import org.jetbrains.kotlin.ir.replaceWith -import org.jetbrains.kotlin.ir.visitors.IrElementVisitor -import org.jetbrains.kotlin.psi2ir.containsNull -import org.jetbrains.kotlin.psi2ir.defaultLoad -import org.jetbrains.kotlin.psi2ir.generators.GeneratorContext -import org.jetbrains.kotlin.psi2ir.generators.constNull -import org.jetbrains.kotlin.psi2ir.generators.equalsNull -import org.jetbrains.kotlin.psi2ir.intermediate.OnceExpressionValue -import org.jetbrains.kotlin.psi2ir.intermediate.createRematerializableValue - -fun inlineSafeCallChains(context: GeneratorContext, element: IrElement) { - element.accept(InlineSafeCallChains(context), null) - element.accept(InlineSafeCallStableReceiverValues(context), null) -} - -class InlineSafeCallChains(val context: GeneratorContext) : IrElementVisitor { - override fun visitElement(element: IrElement, data: Nothing?) { - element.acceptChildren(this, data) - } - - override fun visitBlock(expression: IrBlock, data: Nothing?) { - expression.acceptChildren(this, data) - - if (expression.operator == IrOperator.SAFE_CALL) { - val safeCall = getSafeCallInfo(expression) ?: return - val innerSafeCall = (safeCall.receiverValue as? IrBlock)?.let { getSafeCallInfo(it) } ?: return - rewriteSafeCallChain(safeCall, innerSafeCall) - } - } - - private fun rewriteSafeCallChain(outer: SafeCallInfo, inner: SafeCallInfo) { - val innerNestedCallReturnType = inner.nestedCall.type - if (innerNestedCallReturnType.containsNull()) return - - outer.root.replaceWith { - val newBlock = IrBlockImpl(it.startOffset, it.endOffset, it.type, IrOperator.SAFE_CALL) - newBlock.addStatement(inner.receiverVariable.detach()) - - val replaceWithValue = OnceExpressionValue(inner.nestedCall.detach()) - outer.nestedCall.acceptChildren(ReplaceTemporaryVariable(outer.receiverVariable, replaceWithValue), null) - newBlock.addStatement(IrIfThenElseImpl( - it.startOffset, it.endOffset, it.type, - context.equalsNull(it.startOffset, it.endOffset, inner.receiverVariable.defaultLoad()), - context.constNull(it.startOffset, it.endOffset), - outer.nestedCall.detach(), - IrOperator.SAFE_CALL)) - - newBlock - } - } - - -} - -internal class SafeCallInfo(val root: IrBlock, val receiverVariable: IrVariable, val ifThenElse: IrWhen, val nestedCall: IrExpression) { - val receiverValue = receiverVariable.initializer!! -} - -internal fun getSafeCallInfo(block: IrBlock): SafeCallInfo? { - if (block.operator != IrOperator.SAFE_CALL) return null - val receiverVariable = block.statements[0] as? IrVariable ?: return null - if (receiverVariable.initializer == null) return null - val irWhen = (block.statements[1] as? IrWhen) ?: return null - val nestedCall = irWhen.elseBranch ?: return null - return SafeCallInfo(block, receiverVariable, irWhen, nestedCall) -} - -class InlineSafeCallStableReceiverValues(val context: GeneratorContext) : IrElementVisitor { - override fun visitElement(element: IrElement, data: Nothing?) { - element.acceptChildren(this, data) - } - - override fun visitBlock(expression: IrBlock, data: Nothing?) { - expression.acceptChildren(this, data) - - if (expression.operator == IrOperator.SAFE_CALL) { - val safeCall = getSafeCallInfo(expression) ?: return - if (isOkToInlineReceiverValue(safeCall.receiverValue)) { - expression.replaceWith { - val replaceWithValue = createRematerializableValue(safeCall.receiverValue) ?: return - safeCall.ifThenElse.acceptChildren(ReplaceTemporaryVariable(safeCall.receiverVariable, replaceWithValue), null) - safeCall.ifThenElse.detach() - } - } - } - } - - private fun isOkToInlineReceiverValue(receiverValue: IrExpression): Boolean { - return if (receiverValue is IrGetVariable) { - !receiverValue.descriptor.isVar - } - else { - // For now, IrExpressionWithCopy has stable instances only. - receiverValue is IrExpressionWithCopy - } - } -} \ No newline at end of file diff --git a/compiler/testData/ir/irText/expressions/arrayAugmentedAssignment1.txt b/compiler/testData/ir/irText/expressions/arrayAugmentedAssignment1.txt index a8845de09ed..8da6ce0eb1b 100644 --- a/compiler/testData/ir/irText/expressions/arrayAugmentedAssignment1.txt +++ b/compiler/testData/ir/irText/expressions/arrayAugmentedAssignment1.txt @@ -24,13 +24,17 @@ FILE /arrayAugmentedAssignment1.kt VAR var x: kotlin.IntArray CALL .foo type=kotlin.IntArray operator=null BLOCK type=kotlin.Unit operator=PLUSEQ + VAR val tmp0_array: kotlin.IntArray + GET_VAR x type=kotlin.IntArray operator=null + VAR val tmp1_index0: kotlin.Int + CONST Int type=kotlin.Int value='0' CALL .set type=kotlin.Unit operator=PLUSEQ - $this: GET_VAR x type=kotlin.IntArray operator=null - index: CONST Int type=kotlin.Int value='0' + $this: GET_VAR tmp0_array type=kotlin.IntArray operator=null + index: GET_VAR tmp1_index0 type=kotlin.Int operator=null value: CALL .plus type=kotlin.Int operator=PLUSEQ $this: CALL .get type=kotlin.Int operator=PLUSEQ - $this: GET_VAR x type=kotlin.IntArray operator=null - index: CONST Int type=kotlin.Int value='0' + $this: GET_VAR tmp0_array type=kotlin.IntArray operator=null + index: GET_VAR tmp1_index0 type=kotlin.Int operator=null other: CONST Int type=kotlin.Int value='1' FUN public fun testCall(): kotlin.Unit BLOCK_BODY @@ -53,13 +57,15 @@ FILE /arrayAugmentedAssignment1.kt VAR val tmp0_array: kotlin.IntArray CALL . type=kotlin.IntArray operator=GET_PROPERTY $this: GET_VAR c type=C operator=null - VAR val tmp1: kotlin.Int + VAR val tmp1_index0: kotlin.Int + CONST Int type=kotlin.Int value='0' + VAR val tmp2: kotlin.Int CALL .get type=kotlin.Int operator=POSTFIX_INCR $this: GET_VAR tmp0_array type=kotlin.IntArray operator=null - index: CONST Int type=kotlin.Int value='0' + index: GET_VAR tmp1_index0 type=kotlin.Int operator=null CALL .set type=kotlin.Unit operator=POSTFIX_INCR $this: GET_VAR tmp0_array type=kotlin.IntArray operator=null - index: CONST Int type=kotlin.Int value='0' + index: GET_VAR tmp1_index0 type=kotlin.Int operator=null value: CALL .inc type=kotlin.Int operator=POSTFIX_INCR - $this: GET_VAR tmp1 type=kotlin.Int operator=null - GET_VAR tmp1 type=kotlin.Int operator=null + $this: GET_VAR tmp2 type=kotlin.Int operator=null + GET_VAR tmp2 type=kotlin.Int operator=null diff --git a/compiler/testData/ir/irText/expressions/arrayAugmentedAssignment2.txt b/compiler/testData/ir/irText/expressions/arrayAugmentedAssignment2.txt index 63377c643ae..4a8db302dda 100644 --- a/compiler/testData/ir/irText/expressions/arrayAugmentedAssignment2.txt +++ b/compiler/testData/ir/irText/expressions/arrayAugmentedAssignment2.txt @@ -6,12 +6,16 @@ FILE /arrayAugmentedAssignment2.kt FUN public fun IB.test(/*0*/ a: IA): kotlin.Unit BLOCK_BODY BLOCK type=kotlin.Unit operator=PLUSEQ + VAR val tmp0_array: IA + GET_VAR a type=IA operator=null + VAR val tmp1_index0: kotlin.String + CONST String type=kotlin.String value='' CALL .set type=kotlin.Unit operator=PLUSEQ $this: $RECEIVER of: test type=IB - $receiver: GET_VAR a type=IA operator=null - index: CONST String type=kotlin.String value='' + $receiver: GET_VAR tmp0_array type=IA operator=null + index: GET_VAR tmp1_index0 type=kotlin.String operator=null value: CALL .plus type=kotlin.Int operator=PLUSEQ $this: CALL .get type=kotlin.Int operator=PLUSEQ - $this: GET_VAR a type=IA operator=null - index: CONST String type=kotlin.String value='' + $this: GET_VAR tmp0_array type=IA operator=null + index: GET_VAR tmp1_index0 type=kotlin.String operator=null other: CONST Int type=kotlin.Int value='42' diff --git a/compiler/testData/ir/irText/expressions/bangbang.txt b/compiler/testData/ir/irText/expressions/bangbang.txt index 8b7d77ffbea..26c9abd5655 100644 --- a/compiler/testData/ir/irText/expressions/bangbang.txt +++ b/compiler/testData/ir/irText/expressions/bangbang.txt @@ -2,24 +2,30 @@ FILE /bangbang.kt FUN public fun test1(/*0*/ a: kotlin.Any?): kotlin.Any BLOCK_BODY RETURN type=kotlin.Nothing from=test1 - WHEN type=kotlin.Any operator=null - if: CALL .EQEQ type=kotlin.Boolean operator=EQEQ - arg0: GET_VAR a type=kotlin.Any? operator=null - arg1: CONST Null type=kotlin.Nothing? value='null' - then: CALL .THROW_NPE type=kotlin.Nothing operator=EXCLEXCL - else: GET_VAR a type=kotlin.Any? operator=null + BLOCK type=kotlin.Any operator=EXCLEXCL + VAR val tmp0_notnull: kotlin.Any? + GET_VAR a type=kotlin.Any? operator=null + WHEN type=kotlin.Any operator=null + if: CALL .EQEQ type=kotlin.Boolean operator=EQEQ + arg0: GET_VAR tmp0_notnull type=kotlin.Any? operator=null + arg1: CONST Null type=kotlin.Nothing? value='null' + then: CALL .THROW_NPE type=kotlin.Nothing operator=EXCLEXCL + else: GET_VAR tmp0_notnull type=kotlin.Any? operator=null FUN public fun test2(/*0*/ a: kotlin.Any?): kotlin.Int BLOCK_BODY RETURN type=kotlin.Nothing from=test2 BLOCK type=kotlin.Int operator=EXCLEXCL VAR val tmp1_notnull: kotlin.Int? - WHEN type=kotlin.Int? operator=SAFE_CALL - if: CALL .EQEQ type=kotlin.Boolean operator=EQEQ - arg0: GET_VAR a type=kotlin.Any? operator=null - arg1: CONST Null type=kotlin.Nothing? value='null' - then: CONST Null type=kotlin.Nothing? value='null' - else: CALL .hashCode type=kotlin.Int operator=null - $this: GET_VAR a type=kotlin.Any? operator=null + BLOCK type=kotlin.Int? operator=SAFE_CALL + VAR val tmp0_safe_receiver: kotlin.Any? + GET_VAR a type=kotlin.Any? operator=null + WHEN type=kotlin.Int? operator=SAFE_CALL + if: CALL .EQEQ type=kotlin.Boolean operator=EQEQ + arg0: GET_VAR tmp0_safe_receiver type=kotlin.Any? operator=null + arg1: CONST Null type=kotlin.Nothing? value='null' + then: CONST Null type=kotlin.Nothing? value='null' + else: CALL .hashCode type=kotlin.Int operator=null + $this: GET_VAR tmp0_safe_receiver type=kotlin.Any? operator=null WHEN type=kotlin.Int operator=null if: CALL .EQEQ type=kotlin.Boolean operator=EQEQ arg0: GET_VAR tmp1_notnull type=kotlin.Int? operator=null diff --git a/compiler/testData/ir/irText/expressions/callWithReorderedArguments.txt b/compiler/testData/ir/irText/expressions/callWithReorderedArguments.txt index 4fa28a95f6c..831e0263542 100644 --- a/compiler/testData/ir/irText/expressions/callWithReorderedArguments.txt +++ b/compiler/testData/ir/irText/expressions/callWithReorderedArguments.txt @@ -31,8 +31,10 @@ FILE /callWithReorderedArguments.kt a: GET_VAR tmp1_a type=kotlin.Int operator=null b: GET_VAR tmp0_b type=kotlin.Int operator=null BLOCK type=kotlin.Unit operator=ARGUMENTS_REORDERING_FOR_CALL - VAR val tmp2_a: kotlin.Int + VAR val tmp2_b: kotlin.Int + CONST Int type=kotlin.Int value='1' + VAR val tmp3_a: kotlin.Int CALL .reordered2 type=kotlin.Int operator=null CALL .foo type=kotlin.Unit operator=null - a: GET_VAR tmp2_a type=kotlin.Int operator=null - b: CONST Int type=kotlin.Int value='1' + a: GET_VAR tmp3_a type=kotlin.Int operator=null + b: GET_VAR tmp2_b type=kotlin.Int operator=null diff --git a/compiler/testData/ir/irText/expressions/chainOfSafeCalls.txt b/compiler/testData/ir/irText/expressions/chainOfSafeCalls.txt index f5ae42ea77e..1fc2accf9ba 100644 --- a/compiler/testData/ir/irText/expressions/chainOfSafeCalls.txt +++ b/compiler/testData/ir/irText/expressions/chainOfSafeCalls.txt @@ -14,20 +14,39 @@ FILE /chainOfSafeCalls.kt BLOCK_BODY RETURN type=kotlin.Nothing from=test BLOCK type=C? operator=SAFE_CALL - VAR val tmp2_safe_receiver: C? - WHEN type=C? operator=SAFE_CALL - if: CALL .EQEQ type=kotlin.Boolean operator=EQEQ - arg0: GET_VAR nc type=C? operator=null - arg1: CONST Null type=kotlin.Nothing? value='null' - then: CONST Null type=kotlin.Nothing? value='null' - else: CALL .bar type=C? operator=null - $this: CALL .foo type=C operator=null - $this: GET_VAR nc type=C? operator=null + VAR val tmp3_safe_receiver: C? + BLOCK type=C? operator=SAFE_CALL + VAR val tmp2_safe_receiver: C? + BLOCK type=C? operator=SAFE_CALL + VAR val tmp1_safe_receiver: C? + BLOCK type=C? operator=SAFE_CALL + VAR val tmp0_safe_receiver: C? + GET_VAR nc type=C? operator=null + WHEN type=C? operator=SAFE_CALL + if: CALL .EQEQ type=kotlin.Boolean operator=EQEQ + arg0: GET_VAR tmp0_safe_receiver type=C? operator=null + arg1: CONST Null type=kotlin.Nothing? value='null' + then: CONST Null type=kotlin.Nothing? value='null' + else: CALL .foo type=C operator=null + $this: GET_VAR tmp0_safe_receiver type=C? operator=null + WHEN type=C? operator=SAFE_CALL + if: CALL .EQEQ type=kotlin.Boolean operator=EQEQ + arg0: GET_VAR tmp1_safe_receiver type=C? operator=null + arg1: CONST Null type=kotlin.Nothing? value='null' + then: CONST Null type=kotlin.Nothing? value='null' + else: CALL .bar type=C? operator=null + $this: GET_VAR tmp1_safe_receiver type=C? operator=null + WHEN type=C? operator=SAFE_CALL + if: CALL .EQEQ type=kotlin.Boolean operator=EQEQ + arg0: GET_VAR tmp2_safe_receiver type=C? operator=null + arg1: CONST Null type=kotlin.Nothing? value='null' + then: CONST Null type=kotlin.Nothing? value='null' + else: CALL .foo type=C operator=null + $this: GET_VAR tmp2_safe_receiver type=C? operator=null WHEN type=C? operator=SAFE_CALL if: CALL .EQEQ type=kotlin.Boolean operator=EQEQ - arg0: GET_VAR tmp2_safe_receiver type=C? operator=null + arg0: GET_VAR tmp3_safe_receiver type=C? operator=null arg1: CONST Null type=kotlin.Nothing? value='null' then: CONST Null type=kotlin.Nothing? value='null' else: CALL .foo type=C operator=null - $this: CALL .foo type=C operator=null - $this: GET_VAR tmp2_safe_receiver type=C? operator=null + $this: GET_VAR tmp3_safe_receiver type=C? operator=null diff --git a/compiler/testData/ir/irText/expressions/dotQualified.txt b/compiler/testData/ir/irText/expressions/dotQualified.txt index 2d5329a2033..1ab545792a9 100644 --- a/compiler/testData/ir/irText/expressions/dotQualified.txt +++ b/compiler/testData/ir/irText/expressions/dotQualified.txt @@ -7,10 +7,13 @@ FILE /dotQualified.kt FUN public fun lengthN(/*0*/ s: kotlin.String?): kotlin.Int? BLOCK_BODY RETURN type=kotlin.Nothing from=lengthN - WHEN type=kotlin.Int? operator=SAFE_CALL - if: CALL .EQEQ type=kotlin.Boolean operator=EQEQ - arg0: GET_VAR s type=kotlin.String? operator=null - arg1: CONST Null type=kotlin.Nothing? value='null' - then: CONST Null type=kotlin.Nothing? value='null' - else: CALL . type=kotlin.Int operator=GET_PROPERTY - $this: GET_VAR s type=kotlin.String? operator=null + BLOCK type=kotlin.Int? operator=SAFE_CALL + VAR val tmp0_safe_receiver: kotlin.String? + GET_VAR s type=kotlin.String? operator=null + WHEN type=kotlin.Int? operator=SAFE_CALL + if: CALL .EQEQ type=kotlin.Boolean operator=EQEQ + arg0: GET_VAR tmp0_safe_receiver type=kotlin.String? operator=null + arg1: CONST Null type=kotlin.Nothing? value='null' + then: CONST Null type=kotlin.Nothing? value='null' + else: CALL . type=kotlin.Int operator=GET_PROPERTY + $this: GET_VAR tmp0_safe_receiver type=kotlin.String? operator=null diff --git a/compiler/testData/ir/irText/expressions/elvis.txt b/compiler/testData/ir/irText/expressions/elvis.txt index 14522aee904..ffe31af0994 100644 --- a/compiler/testData/ir/irText/expressions/elvis.txt +++ b/compiler/testData/ir/irText/expressions/elvis.txt @@ -10,22 +10,26 @@ FILE /elvis.kt BLOCK_BODY RETURN type=kotlin.Nothing from=test1 BLOCK type=kotlin.Any operator=ELVIS + VAR val tmp0_elvis_lhs: kotlin.Any? + GET_VAR a type=kotlin.Any? operator=null WHEN type=kotlin.Any operator=null if: CALL .EQEQ type=kotlin.Boolean operator=EQEQ - arg0: GET_VAR a type=kotlin.Any? operator=null + arg0: GET_VAR tmp0_elvis_lhs type=kotlin.Any? operator=null arg1: CONST Null type=kotlin.Nothing? value='null' then: GET_VAR b type=kotlin.Any operator=null - else: GET_VAR a type=kotlin.Any? operator=null + else: GET_VAR tmp0_elvis_lhs type=kotlin.Any? operator=null FUN public fun test2(/*0*/ a: kotlin.String?, /*1*/ b: kotlin.Any): kotlin.Any BLOCK_BODY RETURN type=kotlin.Nothing from=test2 BLOCK type=kotlin.Any operator=ELVIS + VAR val tmp0_elvis_lhs: kotlin.String? + GET_VAR a type=kotlin.String? operator=null WHEN type=kotlin.Any operator=null if: CALL .EQEQ type=kotlin.Boolean operator=EQEQ - arg0: GET_VAR a type=kotlin.String? operator=null + arg0: GET_VAR tmp0_elvis_lhs type=kotlin.String? operator=null arg1: CONST Null type=kotlin.Nothing? value='null' then: GET_VAR b type=kotlin.Any operator=null - else: GET_VAR a type=kotlin.String? operator=null + else: GET_VAR tmp0_elvis_lhs type=kotlin.String? operator=null FUN public fun test3(/*0*/ a: kotlin.Any?, /*1*/ b: kotlin.Any?): kotlin.String BLOCK_BODY WHEN type=kotlin.Unit operator=IF @@ -40,14 +44,16 @@ FILE /elvis.kt CONST String type=kotlin.String value='' RETURN type=kotlin.Nothing from=test3 BLOCK type=kotlin.String operator=ELVIS + VAR val tmp0_elvis_lhs: kotlin.Any? + GET_VAR a type=kotlin.Any? operator=null WHEN type=kotlin.String operator=null if: CALL .EQEQ type=kotlin.Boolean operator=EQEQ - arg0: GET_VAR a type=kotlin.Any? operator=null + arg0: GET_VAR tmp0_elvis_lhs type=kotlin.Any? operator=null arg1: CONST Null type=kotlin.Nothing? value='null' then: TYPE_OP operator=IMPLICIT_CAST typeOperand=kotlin.String GET_VAR b type=kotlin.Any? operator=null else: TYPE_OP operator=IMPLICIT_CAST typeOperand=kotlin.String - GET_VAR a type=kotlin.Any? operator=null + GET_VAR tmp0_elvis_lhs type=kotlin.Any? operator=null FUN public fun test4(/*0*/ x: kotlin.Any): kotlin.Any BLOCK_BODY RETURN type=kotlin.Nothing from=test4 diff --git a/compiler/testData/ir/irText/expressions/incrementDecrement.txt b/compiler/testData/ir/irText/expressions/incrementDecrement.txt index 469601a4e60..5591d2dd75d 100644 --- a/compiler/testData/ir/irText/expressions/incrementDecrement.txt +++ b/compiler/testData/ir/irText/expressions/incrementDecrement.txt @@ -91,57 +91,65 @@ FILE /incrementDecrement.kt BLOCK type=kotlin.Int operator=PREFIX_INCR VAR val tmp0_array: kotlin.IntArray CALL . type=kotlin.IntArray operator=GET_PROPERTY - VAR val tmp1: kotlin.Int + VAR val tmp1_index0: kotlin.Int + CONST Int type=kotlin.Int value='0' + VAR val tmp2: kotlin.Int CALL .inc type=kotlin.Int operator=PREFIX_INCR $this: CALL .get type=kotlin.Int operator=PREFIX_INCR $this: GET_VAR tmp0_array type=kotlin.IntArray operator=null - index: CONST Int type=kotlin.Int value='0' + index: GET_VAR tmp1_index0 type=kotlin.Int operator=null CALL .set type=kotlin.Unit operator=PREFIX_INCR $this: GET_VAR tmp0_array type=kotlin.IntArray operator=null - index: CONST Int type=kotlin.Int value='0' - value: GET_VAR tmp1 type=kotlin.Int operator=null - GET_VAR tmp1 type=kotlin.Int operator=null + index: GET_VAR tmp1_index0 type=kotlin.Int operator=null + value: GET_VAR tmp2 type=kotlin.Int operator=null + GET_VAR tmp2 type=kotlin.Int operator=null VAR val a2: kotlin.Int BLOCK type=kotlin.Int operator=PREFIX_DECR - VAR val tmp2_array: kotlin.IntArray + VAR val tmp3_array: kotlin.IntArray CALL . type=kotlin.IntArray operator=GET_PROPERTY - VAR val tmp3: kotlin.Int + VAR val tmp4_index0: kotlin.Int + CONST Int type=kotlin.Int value='0' + VAR val tmp5: kotlin.Int CALL .dec type=kotlin.Int operator=PREFIX_DECR $this: CALL .get type=kotlin.Int operator=PREFIX_DECR - $this: GET_VAR tmp2_array type=kotlin.IntArray operator=null - index: CONST Int type=kotlin.Int value='0' + $this: GET_VAR tmp3_array type=kotlin.IntArray operator=null + index: GET_VAR tmp4_index0 type=kotlin.Int operator=null CALL .set type=kotlin.Unit operator=PREFIX_DECR - $this: GET_VAR tmp2_array type=kotlin.IntArray operator=null - index: CONST Int type=kotlin.Int value='0' - value: GET_VAR tmp3 type=kotlin.Int operator=null - GET_VAR tmp3 type=kotlin.Int operator=null + $this: GET_VAR tmp3_array type=kotlin.IntArray operator=null + index: GET_VAR tmp4_index0 type=kotlin.Int operator=null + value: GET_VAR tmp5 type=kotlin.Int operator=null + GET_VAR tmp5 type=kotlin.Int operator=null FUN public fun testArrayPostfix(): kotlin.Unit BLOCK_BODY VAR val a1: kotlin.Int BLOCK type=kotlin.Int operator=POSTFIX_INCR VAR val tmp0_array: kotlin.IntArray CALL . type=kotlin.IntArray operator=GET_PROPERTY - VAR val tmp1: kotlin.Int + VAR val tmp1_index0: kotlin.Int + CONST Int type=kotlin.Int value='0' + VAR val tmp2: kotlin.Int CALL .get type=kotlin.Int operator=POSTFIX_INCR $this: GET_VAR tmp0_array type=kotlin.IntArray operator=null - index: CONST Int type=kotlin.Int value='0' + index: GET_VAR tmp1_index0 type=kotlin.Int operator=null CALL .set type=kotlin.Unit operator=POSTFIX_INCR $this: GET_VAR tmp0_array type=kotlin.IntArray operator=null - index: CONST Int type=kotlin.Int value='0' + index: GET_VAR tmp1_index0 type=kotlin.Int operator=null value: CALL .inc type=kotlin.Int operator=POSTFIX_INCR - $this: GET_VAR tmp1 type=kotlin.Int operator=null - GET_VAR tmp1 type=kotlin.Int operator=null + $this: GET_VAR tmp2 type=kotlin.Int operator=null + GET_VAR tmp2 type=kotlin.Int operator=null VAR val a2: kotlin.Int BLOCK type=kotlin.Int operator=POSTFIX_DECR - VAR val tmp2_array: kotlin.IntArray + VAR val tmp3_array: kotlin.IntArray CALL . type=kotlin.IntArray operator=GET_PROPERTY - VAR val tmp3: kotlin.Int + VAR val tmp4_index0: kotlin.Int + CONST Int type=kotlin.Int value='0' + VAR val tmp5: kotlin.Int CALL .get type=kotlin.Int operator=POSTFIX_DECR - $this: GET_VAR tmp2_array type=kotlin.IntArray operator=null - index: CONST Int type=kotlin.Int value='0' + $this: GET_VAR tmp3_array type=kotlin.IntArray operator=null + index: GET_VAR tmp4_index0 type=kotlin.Int operator=null CALL .set type=kotlin.Unit operator=POSTFIX_DECR - $this: GET_VAR tmp2_array type=kotlin.IntArray operator=null - index: CONST Int type=kotlin.Int value='0' + $this: GET_VAR tmp3_array type=kotlin.IntArray operator=null + index: GET_VAR tmp4_index0 type=kotlin.Int operator=null value: CALL .dec type=kotlin.Int operator=POSTFIX_DECR - $this: GET_VAR tmp3 type=kotlin.Int operator=null - GET_VAR tmp3 type=kotlin.Int operator=null + $this: GET_VAR tmp5 type=kotlin.Int operator=null + GET_VAR tmp5 type=kotlin.Int operator=null diff --git a/compiler/testData/ir/irText/expressions/jvmStaticFieldReference.kt b/compiler/testData/ir/irText/expressions/jvmStaticFieldReference.kt new file mode 100644 index 00000000000..c71fc436e76 --- /dev/null +++ b/compiler/testData/ir/irText/expressions/jvmStaticFieldReference.kt @@ -0,0 +1,3 @@ +fun test1() { +// System.out.println("test1") +} \ No newline at end of file diff --git a/compiler/testData/ir/irText/expressions/safeCallWithIncrementDecrement.txt b/compiler/testData/ir/irText/expressions/safeCallWithIncrementDecrement.txt index ccd740ddb31..a2545426a9c 100644 --- a/compiler/testData/ir/irText/expressions/safeCallWithIncrementDecrement.txt +++ b/compiler/testData/ir/irText/expressions/safeCallWithIncrementDecrement.txt @@ -12,13 +12,16 @@ FILE /safeCallWithIncrementDecrement.kt FUN public operator fun kotlin.Int?.inc(): kotlin.Int? BLOCK_BODY RETURN type=kotlin.Nothing from=inc - WHEN type=kotlin.Int? operator=SAFE_CALL - if: CALL .EQEQ type=kotlin.Boolean operator=EQEQ - arg0: $RECEIVER of: inc type=kotlin.Int? - arg1: CONST Null type=kotlin.Nothing? value='null' - then: CONST Null type=kotlin.Nothing? value='null' - else: CALL .inc type=kotlin.Int operator=null - $this: $RECEIVER of: inc type=kotlin.Int? + BLOCK type=kotlin.Int? operator=SAFE_CALL + VAR val tmp0_safe_receiver: kotlin.Int? + $RECEIVER of: inc type=kotlin.Int? + WHEN type=kotlin.Int? operator=SAFE_CALL + if: CALL .EQEQ type=kotlin.Boolean operator=EQEQ + arg0: GET_VAR tmp0_safe_receiver type=kotlin.Int? operator=null + arg1: CONST Null type=kotlin.Nothing? value='null' + then: CONST Null type=kotlin.Nothing? value='null' + else: CALL .inc type=kotlin.Int operator=null + $this: GET_VAR tmp0_safe_receiver type=kotlin.Int? operator=null FUN public operator fun kotlin.Int?.get(/*0*/ index: kotlin.Int): kotlin.Int BLOCK_BODY RETURN type=kotlin.Nothing from=get @@ -27,38 +30,46 @@ FILE /safeCallWithIncrementDecrement.kt BLOCK_BODY FUN public fun testProperty(/*0*/ nc: test.C?): kotlin.Unit BLOCK_BODY - WHEN type=kotlin.Int? operator=SAFE_CALL - if: CALL .EQEQ type=kotlin.Boolean operator=EQEQ - arg0: GET_VAR nc type=test.C? operator=null - arg1: CONST Null type=kotlin.Nothing? value='null' - then: CONST Null type=kotlin.Nothing? value='null' - else: BLOCK type=kotlin.Int operator=POSTFIX_INCR - VAR val tmp1: kotlin.Int - CALL . type=kotlin.Int operator=POSTFIX_INCR - $this: GET_VAR nc type=test.C? operator=null - CALL . type=kotlin.Unit operator=POSTFIX_INCR - $this: GET_VAR nc type=test.C? operator=null - value: CALL .inc type=kotlin.Int? operator=POSTFIX_INCR - $receiver: GET_VAR tmp1 type=kotlin.Int operator=null - GET_VAR tmp1 type=kotlin.Int operator=null + BLOCK type=kotlin.Int? operator=SAFE_CALL + VAR val tmp0_safe_receiver: test.C? + GET_VAR nc type=test.C? operator=null + WHEN type=kotlin.Int? operator=SAFE_CALL + if: CALL .EQEQ type=kotlin.Boolean operator=EQEQ + arg0: GET_VAR tmp0_safe_receiver type=test.C? operator=null + arg1: CONST Null type=kotlin.Nothing? value='null' + then: CONST Null type=kotlin.Nothing? value='null' + else: BLOCK type=kotlin.Int operator=POSTFIX_INCR + VAR val tmp1: kotlin.Int + CALL . type=kotlin.Int operator=POSTFIX_INCR + $this: GET_VAR tmp0_safe_receiver type=test.C? operator=null + CALL . type=kotlin.Unit operator=POSTFIX_INCR + $this: GET_VAR tmp0_safe_receiver type=test.C? operator=null + value: CALL .inc type=kotlin.Int? operator=POSTFIX_INCR + $receiver: GET_VAR tmp1 type=kotlin.Int operator=null + GET_VAR tmp1 type=kotlin.Int operator=null FUN public fun testArrayAccess(/*0*/ nc: test.C?): kotlin.Unit BLOCK_BODY BLOCK type=kotlin.Int operator=POSTFIX_INCR VAR val tmp3_array: kotlin.Int? - WHEN type=kotlin.Int? operator=SAFE_CALL - if: CALL .EQEQ type=kotlin.Boolean operator=EQEQ - arg0: GET_VAR nc type=test.C? operator=null - arg1: CONST Null type=kotlin.Nothing? value='null' - then: CONST Null type=kotlin.Nothing? value='null' - else: CALL . type=kotlin.Int operator=GET_PROPERTY - $this: GET_VAR nc type=test.C? operator=null - VAR val tmp4: kotlin.Int + BLOCK type=kotlin.Int? operator=SAFE_CALL + VAR val tmp0_safe_receiver: test.C? + GET_VAR nc type=test.C? operator=null + WHEN type=kotlin.Int? operator=SAFE_CALL + if: CALL .EQEQ type=kotlin.Boolean operator=EQEQ + arg0: GET_VAR tmp0_safe_receiver type=test.C? operator=null + arg1: CONST Null type=kotlin.Nothing? value='null' + then: CONST Null type=kotlin.Nothing? value='null' + else: CALL . type=kotlin.Int operator=GET_PROPERTY + $this: GET_VAR tmp0_safe_receiver type=test.C? operator=null + VAR val tmp4_index0: kotlin.Int + CONST Int type=kotlin.Int value='0' + VAR val tmp5: kotlin.Int CALL .get type=kotlin.Int operator=POSTFIX_INCR $receiver: GET_VAR tmp3_array type=kotlin.Int? operator=null - index: CONST Int type=kotlin.Int value='0' + index: GET_VAR tmp4_index0 type=kotlin.Int operator=null CALL .set type=kotlin.Unit operator=POSTFIX_INCR $receiver: GET_VAR tmp3_array type=kotlin.Int? operator=null - index: CONST Int type=kotlin.Int value='0' + index: GET_VAR tmp4_index0 type=kotlin.Int operator=null value: CALL .inc type=kotlin.Int operator=POSTFIX_INCR - $this: GET_VAR tmp4 type=kotlin.Int operator=null - GET_VAR tmp4 type=kotlin.Int operator=null + $this: GET_VAR tmp5 type=kotlin.Int operator=null + GET_VAR tmp5 type=kotlin.Int operator=null diff --git a/compiler/testData/ir/irText/expressions/safeCalls.txt b/compiler/testData/ir/irText/expressions/safeCalls.txt index 31ecde092c4..d8c0d04f49f 100644 --- a/compiler/testData/ir/irText/expressions/safeCalls.txt +++ b/compiler/testData/ir/irText/expressions/safeCalls.txt @@ -16,52 +16,67 @@ FILE /safeCalls.kt FUN public fun test1(/*0*/ x: kotlin.String?): kotlin.Int? BLOCK_BODY RETURN type=kotlin.Nothing from=test1 - WHEN type=kotlin.Int? operator=SAFE_CALL - if: CALL .EQEQ type=kotlin.Boolean operator=EQEQ - arg0: GET_VAR x type=kotlin.String? operator=null - arg1: CONST Null type=kotlin.Nothing? value='null' - then: CONST Null type=kotlin.Nothing? value='null' - else: CALL . type=kotlin.Int operator=GET_PROPERTY - $this: GET_VAR x type=kotlin.String? operator=null + BLOCK type=kotlin.Int? operator=SAFE_CALL + VAR val tmp0_safe_receiver: kotlin.String? + GET_VAR x type=kotlin.String? operator=null + WHEN type=kotlin.Int? operator=SAFE_CALL + if: CALL .EQEQ type=kotlin.Boolean operator=EQEQ + arg0: GET_VAR tmp0_safe_receiver type=kotlin.String? operator=null + arg1: CONST Null type=kotlin.Nothing? value='null' + then: CONST Null type=kotlin.Nothing? value='null' + else: CALL . type=kotlin.Int operator=GET_PROPERTY + $this: GET_VAR tmp0_safe_receiver type=kotlin.String? operator=null FUN public fun test2(/*0*/ x: kotlin.String?): kotlin.Int? BLOCK_BODY RETURN type=kotlin.Nothing from=test2 - WHEN type=kotlin.Int? operator=SAFE_CALL - if: CALL .EQEQ type=kotlin.Boolean operator=EQEQ - arg0: GET_VAR x type=kotlin.String? operator=null - arg1: CONST Null type=kotlin.Nothing? value='null' - then: CONST Null type=kotlin.Nothing? value='null' - else: CALL .hashCode type=kotlin.Int operator=null - $this: GET_VAR x type=kotlin.String? operator=null + BLOCK type=kotlin.Int? operator=SAFE_CALL + VAR val tmp0_safe_receiver: kotlin.String? + GET_VAR x type=kotlin.String? operator=null + WHEN type=kotlin.Int? operator=SAFE_CALL + if: CALL .EQEQ type=kotlin.Boolean operator=EQEQ + arg0: GET_VAR tmp0_safe_receiver type=kotlin.String? operator=null + arg1: CONST Null type=kotlin.Nothing? value='null' + then: CONST Null type=kotlin.Nothing? value='null' + else: CALL .hashCode type=kotlin.Int operator=null + $this: GET_VAR tmp0_safe_receiver type=kotlin.String? operator=null FUN public fun test3(/*0*/ x: kotlin.String?, /*1*/ y: kotlin.Any?): kotlin.Boolean? BLOCK_BODY RETURN type=kotlin.Nothing from=test3 - WHEN type=kotlin.Boolean? operator=SAFE_CALL - if: CALL .EQEQ type=kotlin.Boolean operator=EQEQ - arg0: GET_VAR x type=kotlin.String? operator=null - arg1: CONST Null type=kotlin.Nothing? value='null' - then: CONST Null type=kotlin.Nothing? value='null' - else: CALL .equals type=kotlin.Boolean operator=null - $this: GET_VAR x type=kotlin.String? operator=null - other: GET_VAR y type=kotlin.Any? operator=null + BLOCK type=kotlin.Boolean? operator=SAFE_CALL + VAR val tmp0_safe_receiver: kotlin.String? + GET_VAR x type=kotlin.String? operator=null + WHEN type=kotlin.Boolean? operator=SAFE_CALL + if: CALL .EQEQ type=kotlin.Boolean operator=EQEQ + arg0: GET_VAR tmp0_safe_receiver type=kotlin.String? operator=null + arg1: CONST Null type=kotlin.Nothing? value='null' + then: CONST Null type=kotlin.Nothing? value='null' + else: CALL .equals type=kotlin.Boolean operator=null + $this: GET_VAR tmp0_safe_receiver type=kotlin.String? operator=null + other: GET_VAR y type=kotlin.Any? operator=null FUN public fun test4(/*0*/ x: Ref?): kotlin.Unit BLOCK_BODY - WHEN type=kotlin.Unit? operator=SAFE_CALL - if: CALL .EQEQ type=kotlin.Boolean operator=EQEQ - arg0: GET_VAR x type=Ref? operator=null - arg1: CONST Null type=kotlin.Nothing? value='null' - then: CONST Null type=kotlin.Nothing? value='null' - else: CALL . type=kotlin.Unit operator=EQ - $this: GET_VAR x type=Ref? operator=null - : CONST Int type=kotlin.Int value='0' + BLOCK type=kotlin.Unit? operator=SAFE_CALL + VAR val tmp0_safe_receiver: Ref? + GET_VAR x type=Ref? operator=null + WHEN type=kotlin.Unit? operator=SAFE_CALL + if: CALL .EQEQ type=kotlin.Boolean operator=EQEQ + arg0: GET_VAR tmp0_safe_receiver type=Ref? operator=null + arg1: CONST Null type=kotlin.Nothing? value='null' + then: CONST Null type=kotlin.Nothing? value='null' + else: CALL . type=kotlin.Unit operator=EQ + $this: GET_VAR tmp0_safe_receiver type=Ref? operator=null + : CONST Int type=kotlin.Int value='0' FUN public fun IHost.test5(/*0*/ s: kotlin.String?): kotlin.Int? BLOCK_BODY RETURN type=kotlin.Nothing from=test5 - WHEN type=kotlin.Int? operator=SAFE_CALL - if: CALL .EQEQ type=kotlin.Boolean operator=EQEQ - arg0: GET_VAR s type=kotlin.String? operator=null - arg1: CONST Null type=kotlin.Nothing? value='null' - then: CONST Null type=kotlin.Nothing? value='null' - else: CALL .extLength type=kotlin.Int operator=null - $this: $RECEIVER of: test5 type=IHost - $receiver: GET_VAR s type=kotlin.String? operator=null + BLOCK type=kotlin.Int? operator=SAFE_CALL + VAR val tmp0_safe_receiver: kotlin.String? + GET_VAR s type=kotlin.String? operator=null + WHEN type=kotlin.Int? operator=SAFE_CALL + if: CALL .EQEQ type=kotlin.Boolean operator=EQEQ + arg0: GET_VAR tmp0_safe_receiver type=kotlin.String? operator=null + arg1: CONST Null type=kotlin.Nothing? value='null' + then: CONST Null type=kotlin.Nothing? value='null' + else: CALL .extLength type=kotlin.Int operator=null + $this: $RECEIVER of: test5 type=IHost + $receiver: GET_VAR tmp0_safe_receiver type=kotlin.String? operator=null diff --git a/compiler/testData/ir/irText/expressions/smartCastsWithDestructuring.txt b/compiler/testData/ir/irText/expressions/smartCastsWithDestructuring.txt index f6b01ae6f3e..8754bd5869c 100644 --- a/compiler/testData/ir/irText/expressions/smartCastsWithDestructuring.txt +++ b/compiler/testData/ir/irText/expressions/smartCastsWithDestructuring.txt @@ -16,10 +16,12 @@ FILE /smartCastsWithDestructuring.kt GET_VAR x type=I1 operator=null then: RETURN type=kotlin.Nothing from=test BLOCK type=kotlin.Unit operator=DESTRUCTURING_DECLARATION + VAR val tmp0_container: I1 + GET_VAR x type=I1 operator=null VAR val c1: kotlin.Int CALL .component1 type=kotlin.Int operator=COMPONENT_N(index=1) - $receiver: GET_VAR x type=I1 operator=null + $receiver: GET_VAR tmp0_container type=I1 operator=null VAR val c2: kotlin.String CALL .component2 type=kotlin.String operator=COMPONENT_N(index=2) $receiver: TYPE_OP operator=IMPLICIT_CAST typeOperand=I2 - GET_VAR x type=I1 operator=null + GET_VAR tmp0_container type=I1 operator=null diff --git a/compiler/testData/ir/irText/expressions/stringPlus.txt b/compiler/testData/ir/irText/expressions/stringPlus.txt index 2670ff3bf2e..127a6a7d8e9 100644 --- a/compiler/testData/ir/irText/expressions/stringPlus.txt +++ b/compiler/testData/ir/irText/expressions/stringPlus.txt @@ -2,23 +2,26 @@ FILE /stringPlus.kt FUN public fun test1(/*0*/ a: kotlin.String, /*1*/ b: kotlin.Any): kotlin.String BLOCK_BODY RETURN type=kotlin.Nothing from=test1 - STRING_CONCATENATION type=kotlin.String - GET_VAR a type=kotlin.String operator=null - GET_VAR b type=kotlin.Any operator=null + CALL .plus type=kotlin.String operator=PLUS + $this: GET_VAR a type=kotlin.String operator=null + other: GET_VAR b type=kotlin.Any operator=null FUN public fun test2(/*0*/ a: kotlin.String, /*1*/ b: kotlin.Int): kotlin.String BLOCK_BODY RETURN type=kotlin.Nothing from=test2 - STRING_CONCATENATION type=kotlin.String - GET_VAR a type=kotlin.String operator=null - CONST String type=kotlin.String value='+' - GET_VAR b type=kotlin.Int operator=null + CALL .plus type=kotlin.String operator=PLUS + $this: CALL .plus type=kotlin.String operator=PLUS + $this: GET_VAR a type=kotlin.String operator=null + other: CONST String type=kotlin.String value='+' + other: GET_VAR b type=kotlin.Int operator=null FUN public fun test3(/*0*/ a: kotlin.String, /*1*/ b: kotlin.Int): kotlin.String BLOCK_BODY RETURN type=kotlin.Nothing from=test3 - STRING_CONCATENATION type=kotlin.String - GET_VAR a type=kotlin.String operator=null - CONST String type=kotlin.String value='+' - CALL .plus type=kotlin.Int operator=PLUS - $this: GET_VAR b type=kotlin.Int operator=null - other: CONST Int type=kotlin.Int value='1' - GET_VAR a type=kotlin.String operator=null + CALL .plus type=kotlin.String operator=PLUS + $this: CALL .plus type=kotlin.String operator=PLUS + $this: CALL .plus type=kotlin.String operator=PLUS + $this: GET_VAR a type=kotlin.String operator=null + other: CONST String type=kotlin.String value='+' + other: CALL .plus type=kotlin.Int operator=PLUS + $this: GET_VAR b type=kotlin.Int operator=null + other: CONST Int type=kotlin.Int value='1' + other: GET_VAR a type=kotlin.String operator=null diff --git a/compiler/testData/ir/irText/expressions/variableAsFunctionCall.txt b/compiler/testData/ir/irText/expressions/variableAsFunctionCall.txt index f68d25dd7e9..2a29933efd7 100644 --- a/compiler/testData/ir/irText/expressions/variableAsFunctionCall.txt +++ b/compiler/testData/ir/irText/expressions/variableAsFunctionCall.txt @@ -28,11 +28,22 @@ FILE /variableAsFunctionCall.kt FUN public fun test4(/*0*/ ns: kotlin.String?): kotlin.String? BLOCK_BODY RETURN type=kotlin.Nothing from=test4 - WHEN type=kotlin.String? operator=SAFE_CALL - if: CALL .EQEQ type=kotlin.Boolean operator=EQEQ - arg0: GET_VAR ns type=kotlin.String? operator=null - arg1: CONST Null type=kotlin.Nothing? value='null' - then: CONST Null type=kotlin.Nothing? value='null' - else: CALL .invoke type=kotlin.String operator=null - $this: CALL .k type=() -> kotlin.String operator=null - $this: GET_VAR ns type=kotlin.String? operator=null + BLOCK type=kotlin.String? operator=SAFE_CALL + VAR val tmp1_safe_receiver: (() -> kotlin.String)? + BLOCK type=(() -> kotlin.String)? operator=SAFE_CALL + VAR val tmp0_safe_receiver: kotlin.String? + GET_VAR ns type=kotlin.String? operator=null + WHEN type=(() -> kotlin.String)? operator=SAFE_CALL + if: CALL .EQEQ type=kotlin.Boolean operator=EQEQ + arg0: GET_VAR tmp0_safe_receiver type=kotlin.String? operator=null + arg1: CONST Null type=kotlin.Nothing? value='null' + then: CONST Null type=kotlin.Nothing? value='null' + else: CALL .k type=() -> kotlin.String operator=null + $this: GET_VAR tmp0_safe_receiver type=kotlin.String? operator=null + WHEN type=kotlin.String? operator=SAFE_CALL + if: CALL .EQEQ type=kotlin.Boolean operator=EQEQ + arg0: GET_VAR tmp1_safe_receiver type=(() -> kotlin.String)? operator=null + arg1: CONST Null type=kotlin.Nothing? value='null' + then: CONST Null type=kotlin.Nothing? value='null' + else: CALL .invoke type=kotlin.String operator=null + $this: GET_VAR tmp1_safe_receiver type=(() -> kotlin.String)? operator=null diff --git a/compiler/tests/org/jetbrains/kotlin/ir/IrTextTestCaseGenerated.java b/compiler/tests/org/jetbrains/kotlin/ir/IrTextTestCaseGenerated.java index a8f5d7088a5..98523b3c683 100644 --- a/compiler/tests/org/jetbrains/kotlin/ir/IrTextTestCaseGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/ir/IrTextTestCaseGenerated.java @@ -286,6 +286,12 @@ public class IrTextTestCaseGenerated extends AbstractIrTextTestCase { doTest(fileName); } + @TestMetadata("jvmStaticFieldReference.kt") + public void testJvmStaticFieldReference() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/ir/irText/expressions/jvmStaticFieldReference.kt"); + doTest(fileName); + } + @TestMetadata("literals.kt") public void testLiterals() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/ir/irText/expressions/literals.kt");