diff --git a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/IrCallGenerator.kt b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/IrCallGenerator.kt new file mode 100644 index 00000000000..62ee7984b3f --- /dev/null +++ b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/IrCallGenerator.kt @@ -0,0 +1,174 @@ +/* + * 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 + +import org.jetbrains.kotlin.descriptors.* +import org.jetbrains.kotlin.ir.declarations.IrDeclarationOriginKind +import org.jetbrains.kotlin.ir.declarations.IrLocalVariableImpl +import org.jetbrains.kotlin.ir.descriptors.IrTemporaryVariableDescriptor +import org.jetbrains.kotlin.ir.descriptors.IrTemporaryVariableDescriptorImpl +import org.jetbrains.kotlin.ir.expressions.* +import org.jetbrains.kotlin.psi.KtExpression +import org.jetbrains.kotlin.psi.psiUtil.endOffset +import org.jetbrains.kotlin.psi.psiUtil.startOffset +import org.jetbrains.kotlin.resolve.BindingContext +import org.jetbrains.kotlin.resolve.calls.callUtil.isSafeCall +import org.jetbrains.kotlin.resolve.calls.model.* +import org.jetbrains.kotlin.resolve.scopes.receivers.* +import org.jetbrains.kotlin.types.KotlinType +import java.util.* + +class IrCallGenerator( + override val context: IrGeneratorContext, + val irExpressionGenerator: IrExpressionGenerator +) : IrGenerator { + fun generateCall( + ktExpression: KtExpression, + resolvedCall: ResolvedCall, + operator: IrOperator? = null, + superQualifier: ClassDescriptor? = null + ): IrExpression { + val descriptor = resolvedCall.resultingDescriptor + return when (descriptor) { + is PropertyDescriptor -> + IrGetPropertyExpressionImpl( + ktExpression.startOffset, ktExpression.endOffset, getTypeOrFail(ktExpression), + resolvedCall.call.isSafeCall(), descriptor + ).apply { + dispatchReceiver = generateReceiver(ktExpression, resolvedCall.dispatchReceiver) + extensionReceiver = generateReceiver(ktExpression, resolvedCall.extensionReceiver) + } + is FunctionDescriptor -> + generateFunctionCall(descriptor, ktExpression, operator, resolvedCall, superQualifier) + else -> + TODO("Unexpected callable descriptor: $descriptor ${descriptor.javaClass.simpleName}") + } + } + + private fun ResolvedCall<*>.requiresArgumentReordering(): Boolean { + var lastValueParameterIndex = -1 + for (valueArgument in call.valueArguments) { + val argumentMapping = getArgumentMapping(valueArgument) + if (argumentMapping !is ArgumentMatch || argumentMapping.isError()) { + error("Value argument in function call is mapped with error") + } + val argumentIndex = argumentMapping.valueParameter.index + if (argumentIndex < lastValueParameterIndex) return true + lastValueParameterIndex = argumentIndex + } + return false + } + + private fun generateFunctionCall( + descriptor: FunctionDescriptor, + ktExpression: KtExpression, + operator: IrOperator?, + resolvedCall: ResolvedCall, + superQualifier: ClassDescriptor? + ): IrExpression { + val resultType = getTypeOrFail(ktExpression) + val irCall = IrCallExpressionImpl( + ktExpression.startOffset, ktExpression.endOffset, resultType, + descriptor, resolvedCall.call.isSafeCall(), operator, superQualifier + ) + irCall.dispatchReceiver = generateReceiver(ktExpression, resolvedCall.dispatchReceiver) + irCall.extensionReceiver = generateReceiver(ktExpression, resolvedCall.extensionReceiver) + + return if (resolvedCall.requiresArgumentReordering()) { + generateCallWithArgumentReordering(irCall, ktExpression, resolvedCall, resultType) + } + else { + irCall.apply { + val valueArguments = resolvedCall.valueArgumentsByIndex + for (index in valueArguments!!.indices) { + val valueArgument = valueArguments[index] + val irArgument = generateValueArgument(valueArgument) ?: continue + irCall.putValueArgument(index, irArgument) + } + } + } + } + + private fun generateCallWithArgumentReordering( + irCall: IrCallExpression, + ktExpression: KtExpression, + resolvedCall: ResolvedCall, + resultType: KotlinType + ): IrExpression { + val valueArgumentsInEvaluationOrder = resolvedCall.valueArguments.values + val hasResult = isUsedAsExpression(ktExpression) + val irBlock = IrBlockExpressionImpl(ktExpression.startOffset, ktExpression.endOffset, resultType, hasResult) + + val temporaryVariablesForValueArguments = HashMap>() + for (valueArgument in valueArgumentsInEvaluationOrder) { + val irArgument = generateValueArgument(valueArgument) ?: continue + val irTemporary = irExpressionGenerator.declarationFactory.createTemporaryVariable(irArgument) + val irTemporaryDeclaration = IrLocalVariableDeclarationExpressionImpl(irArgument.startOffset, irArgument.endOffset, irArgument.type) + irTemporaryDeclaration.childDeclaration = irTemporary + + irBlock.addChildExpression(irTemporaryDeclaration) + + temporaryVariablesForValueArguments[valueArgument] = Pair(irTemporary.descriptor, irArgument) + } + + for ((index, valueArgument) in resolvedCall.valueArgumentsByIndex!!.withIndex()) { + val (temporaryDescriptor, irArgument) = temporaryVariablesForValueArguments[valueArgument]!! + val irGetTemporary = IrGetVariableExpressionImpl(irArgument.startOffset, irArgument.endOffset, + irArgument.type, temporaryDescriptor) + irCall.putValueArgument(index, irGetTemporary) + } + + irBlock.addChildExpression(irCall) + + return irBlock + } + + private fun generateReceiver(ktExpression: KtExpression, receiver: ReceiverValue?): IrExpression? = + when (receiver) { + is ImplicitClassReceiver -> + IrThisExpressionImpl(ktExpression.startOffset, ktExpression.startOffset, receiver.type, receiver.classDescriptor) + is ThisClassReceiver -> + (receiver as? ExpressionReceiver)?.expression?.let { receiverExpression -> + IrThisExpressionImpl(receiverExpression.startOffset, receiverExpression.endOffset, receiver.type, receiver.classDescriptor) + } ?: TODO("Non-implicit ThisClassReceiver should be an expression receiver") + is ExpressionReceiver -> + irExpressionGenerator.generateExpression(receiver.expression) + is ClassValueReceiver -> + IrGetObjectValueExpressionImpl(receiver.expression.startOffset, receiver.expression.endOffset, receiver.type, + receiver.classQualifier.descriptor) + is ExtensionReceiver -> + IrGetExtensionReceiverExpressionImpl(ktExpression.startOffset, ktExpression.startOffset, receiver.type, + receiver.declarationDescriptor.extensionReceiverParameter!!) + null -> + null + else -> + TODO("Receiver: ${receiver.javaClass.simpleName}") + } + + private fun generateValueArgument(valueArgument: ResolvedValueArgument): IrExpression? { + when (valueArgument) { + is DefaultValueArgument -> + return null + is ExpressionValueArgument -> + return irExpressionGenerator.generateExpression(valueArgument.valueArgument!!.getArgumentExpression()!!) + is VarargValueArgument -> + TODO("vararg") + else -> + TODO("Unexpected valueArgument: ${valueArgument.javaClass.simpleName}") + } + } +} diff --git a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/IrDeclarationFactory.kt b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/IrDeclarationFactory.kt index 6f5672d7db0..5ef0df4d2c9 100644 --- a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/IrDeclarationFactory.kt +++ b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/IrDeclarationFactory.kt @@ -18,31 +18,27 @@ package org.jetbrains.kotlin.psi2ir import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.ir.declarations.* +import org.jetbrains.kotlin.ir.descriptors.IrTemporaryVariableDescriptor +import org.jetbrains.kotlin.ir.descriptors.IrTemporaryVariableDescriptorImpl import org.jetbrains.kotlin.ir.expressions.IrBody -import org.jetbrains.kotlin.psi.* +import org.jetbrains.kotlin.ir.expressions.IrExpression +import org.jetbrains.kotlin.name.Name +import org.jetbrains.kotlin.psi.KtElement +import org.jetbrains.kotlin.psi.KtFunction +import org.jetbrains.kotlin.psi.KtProperty +import org.jetbrains.kotlin.psi.KtPropertyAccessor import org.jetbrains.kotlin.psi.psiUtil.endOffset import org.jetbrains.kotlin.psi.psiUtil.startOffset +import org.jetbrains.kotlin.types.KotlinType -class IrDeclarationFactory private constructor( - val fileEntry: PsiSourceManager.PsiFileEntry, - val irFileImpl: IrFileImpl, - val containingDeclaration: IrCompoundDeclaration -) { - fun createChild(containingDeclaration: IrCompoundDeclaration) = - IrDeclarationFactory(fileEntry, irFileImpl, containingDeclaration) - - private fun D.addToContainer(): D = - apply { containingDeclaration.addChildDeclaration(this) } - +abstract class IrDeclarationFactoryBase { fun createFunction(ktFunction: KtFunction, functionDescriptor: FunctionDescriptor, body: IrBody): IrFunction = IrFunctionImpl(ktFunction.startOffset, ktFunction.endOffset, IrDeclarationOriginKind.DEFINED, functionDescriptor, body) - .addToContainer() fun createSimpleProperty(ktProperty: KtProperty, propertyDescriptor: PropertyDescriptor, valueInitializer: IrBody?): IrSimpleProperty = IrSimplePropertyImpl(ktProperty.startOffset, ktProperty.endOffset, IrDeclarationOriginKind.DEFINED, propertyDescriptor, valueInitializer) - .addToContainer() fun createPropertyGetter( ktPropertyAccessor: KtPropertyAccessor, @@ -53,7 +49,6 @@ class IrDeclarationFactory private constructor( IrPropertyGetterImpl(ktPropertyAccessor.startOffset, ktPropertyAccessor.endOffset, IrDeclarationOriginKind.DEFINED, getterDescriptor, getterBody) .apply { irProperty.getter = this } - .addToContainer() fun createPropertySetter( ktPropertyAccessor: KtPropertyAccessor, @@ -64,16 +59,30 @@ class IrDeclarationFactory private constructor( IrPropertySetterImpl(ktPropertyAccessor.startOffset, ktPropertyAccessor.endOffset, IrDeclarationOriginKind.DEFINED, setterDescriptor, setterBody) .apply { irProperty.setter = this } - .addToContainer() +} - companion object { - fun create(irModule: IrModuleImpl, sourceManager: PsiSourceManager, ktFile: KtFile, descriptor: PackageFragmentDescriptor): IrDeclarationFactory { - val fileEntry = sourceManager.getOrCreateFileEntry(ktFile) - val fileName = fileEntry.getRecognizableName() - val irFile = IrFileImpl(fileEntry, fileName, descriptor) - sourceManager.putFileEntry(irFile, fileEntry) - irModule.addFile(irFile) - return IrDeclarationFactory(fileEntry, irFile, irFile) - } - } -} \ No newline at end of file +class IrDeclarationFactory() : IrDeclarationFactoryBase() + +class IrLocalDeclarationsFactory(val scopeOwner: DeclarationDescriptor) : IrDeclarationFactoryBase() { + private var lastTemporaryIndex = 0 + private fun nextTemporaryIndex() = lastTemporaryIndex++ + + fun createDescriptorForTemporaryVariable(type: KotlinType): IrTemporaryVariableDescriptor = + IrTemporaryVariableDescriptorImpl(scopeOwner, Name.identifier("tmp${nextTemporaryIndex()}"), type) + + fun createTemporaryVariable(ktElement: KtElement, type: KotlinType): IrLocalVariable = + IrLocalVariableImpl(ktElement.startOffset, ktElement.endOffset, + IrDeclarationOriginKind.IR_TEMPORARY_VARIABLE, + createDescriptorForTemporaryVariable(type)) + + fun createTemporaryVariable(irExpression: IrExpression): IrLocalVariable = + IrLocalVariableImpl(irExpression.startOffset, irExpression.endOffset, + IrDeclarationOriginKind.IR_TEMPORARY_VARIABLE, + createDescriptorForTemporaryVariable(irExpression.type) + ).apply { initializerExpression = irExpression } + + fun createLocalVariable(ktElement: KtElement, type: KotlinType, descriptor: VariableDescriptor): IrLocalVariable = + IrLocalVariableImpl(ktElement.startOffset, ktElement.endOffset, + IrDeclarationOriginKind.DEFINED, + descriptor) +} diff --git a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/IrDeclarationGenerator.kt b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/IrDeclarationGenerator.kt index d1f8c682005..2a75884c995 100644 --- a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/IrDeclarationGenerator.kt +++ b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/IrDeclarationGenerator.kt @@ -16,6 +16,7 @@ package org.jetbrains.kotlin.psi2ir +import org.jetbrains.kotlin.descriptors.DeclarationDescriptor import org.jetbrains.kotlin.descriptors.PropertyDescriptor import org.jetbrains.kotlin.descriptors.PropertyGetterDescriptor import org.jetbrains.kotlin.descriptors.PropertySetterDescriptor @@ -29,20 +30,15 @@ import org.jetbrains.kotlin.psi.psiUtil.endOffset import org.jetbrains.kotlin.psi.psiUtil.startOffset import org.jetbrains.kotlin.resolve.BindingContext -interface IrDeclarationGenerator : IrGenerator { - val irDeclaration: IrDeclaration - val parent: IrDeclarationGenerator? -} +interface IrDeclarationGenerator : IrGenerator abstract class IrDeclarationGeneratorBase( override val context: IrGeneratorContext, - override val irDeclaration: IrDeclaration, - override val parent: IrDeclarationGenerator, - val declarationFactory: IrDeclarationFactory + val container: IrDeclarationOwnerN, + val declarationFactory: IrDeclarationFactoryBase ) : IrDeclarationGenerator { - val irExpressionGenerator = IrExpressionGenerator(context, declarationFactory) - - val containingDeclaration: IrCompoundDeclaration get() = declarationFactory.containingDeclaration + private fun D.register(): D = + apply { container.addChildDeclaration(this) } fun generateAnnotationEntries(annotationEntries: List) { // TODO create IrAnnotation's for each KtAnnotationEntry @@ -64,26 +60,26 @@ abstract class IrDeclarationGeneratorBase( fun generateFunctionDeclaration(ktNamedFunction: KtNamedFunction) { val functionDescriptor = getOrFail(BindingContext.FUNCTION, ktNamedFunction) { "unresolved fun" } - val body = generateExpressionBody(ktNamedFunction.bodyExpression ?: TODO("function without body expression")) - declarationFactory.createFunction(ktNamedFunction, functionDescriptor, body) + val body = generateExpressionBody(functionDescriptor, ktNamedFunction.bodyExpression ?: TODO("function without body expression")) + declarationFactory.createFunction(ktNamedFunction, functionDescriptor, body).register() } fun generatePropertyDeclaration(ktProperty: KtProperty) { val propertyDescriptor = getPropertyDescriptor(ktProperty) if (ktProperty.hasDelegate()) TODO("handle delegated property") - val initializer = ktProperty.initializer?.let { generateExpressionBody(it) } - val irProperty = declarationFactory.createSimpleProperty(ktProperty, propertyDescriptor, initializer) + val initializer = ktProperty.initializer?.let { generateExpressionBody(propertyDescriptor, it) } + val irProperty = declarationFactory.createSimpleProperty(ktProperty, propertyDescriptor, initializer).register() ktProperty.getter?.let { ktGetter -> val accessorDescriptor = getOrFail(BindingContext.PROPERTY_ACCESSOR, ktGetter) { "unresolved getter" } val getterDescriptor = accessorDescriptor as? PropertyGetterDescriptor ?: TODO("not a getter?") - val getterBody = generateExpressionBody(ktGetter.bodyExpression ?: TODO("default getter")) - declarationFactory.createPropertyGetter(ktGetter, irProperty, getterDescriptor, getterBody) + val getterBody = generateExpressionBody(getterDescriptor, ktGetter.bodyExpression ?: TODO("default getter")) + declarationFactory.createPropertyGetter(ktGetter, irProperty, getterDescriptor, getterBody).register() } ktProperty.setter?.let { ktSetter -> val accessorDescriptor = getOrFail(BindingContext.PROPERTY_ACCESSOR, ktSetter) { "unresolved setter" } val setterDescriptor = accessorDescriptor as? PropertySetterDescriptor ?: TODO("not a setter?") - val setterBody = generateExpressionBody(ktSetter.bodyExpression ?: TODO("default setter")) - declarationFactory.createPropertySetter(ktSetter, irProperty, setterDescriptor, setterBody) + val setterBody = generateExpressionBody(setterDescriptor, ktSetter.bodyExpression ?: TODO("default setter")) + declarationFactory.createPropertySetter(ktSetter, irProperty, setterDescriptor, setterBody).register() } } @@ -93,19 +89,8 @@ abstract class IrDeclarationGeneratorBase( return propertyDescriptor } - fun generateExpressionBody(ktBody: KtExpression): IrBody { - val irExpression = irExpressionGenerator.generateExpression(ktBody) - - val startOffset = ktBody.startOffset - val endOffset = ktBody.endOffset - - val bodyExpression = - if (ktBody is KtBlockExpression) - irExpression - else - IrReturnExpressionImpl(startOffset, endOffset, irExpression.type) - .apply { returnedExpression = irExpression } - - return IrExpressionBodyImpl(startOffset, endOffset, containingDeclaration).apply { argument = bodyExpression } - } + fun generateExpressionBody(scopeOwner: DeclarationDescriptor, ktBody: KtExpression): IrBody = + IrExpressionBodyImpl(ktBody.startOffset, ktBody.endOffset).apply { + argument = IrExpressionGenerator(context, IrLocalDeclarationsFactory(scopeOwner)).generateExpression(ktBody) + } } \ No newline at end of file diff --git a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/IrExpressionGenerator.kt b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/IrExpressionGenerator.kt index 3239d8e7511..4accf94763c 100644 --- a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/IrExpressionGenerator.kt +++ b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/IrExpressionGenerator.kt @@ -16,66 +16,64 @@ package org.jetbrains.kotlin.psi2ir -import org.jetbrains.kotlin.descriptors.* +import org.jetbrains.kotlin.descriptors.CallableDescriptor +import org.jetbrains.kotlin.descriptors.ClassDescriptor +import org.jetbrains.kotlin.descriptors.PropertyDescriptor +import org.jetbrains.kotlin.descriptors.VariableDescriptor import org.jetbrains.kotlin.ir.expressions.* import org.jetbrains.kotlin.psi.* import org.jetbrains.kotlin.psi.psiUtil.endOffset import org.jetbrains.kotlin.psi.psiUtil.startOffset import org.jetbrains.kotlin.resolve.BindingContext import org.jetbrains.kotlin.resolve.DescriptorUtils -import org.jetbrains.kotlin.resolve.calls.callUtil.isSafeCall -import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall -import org.jetbrains.kotlin.resolve.calls.model.ResolvedValueArgument import org.jetbrains.kotlin.resolve.calls.model.VariableAsFunctionResolvedCall import org.jetbrains.kotlin.resolve.constants.IntValue import org.jetbrains.kotlin.resolve.constants.StringValue import org.jetbrains.kotlin.resolve.constants.evaluate.ConstantExpressionEvaluator -import org.jetbrains.kotlin.resolve.scopes.receivers.* class IrExpressionGenerator( override val context: IrGeneratorContext, - val declarationFactory: IrDeclarationFactory + val declarationFactory: IrLocalDeclarationsFactory ) : KtVisitor(), IrGenerator { + private val irCallGenerator = IrCallGenerator(context, this) + fun generateExpression(ktExpression: KtExpression) = ktExpression.generate() private fun KtElement.generate(): IrExpression = deparenthesize() - .accept(this@IrExpressionGenerator, null) - .smartCastIfNeeded(this) + .accept(this@IrExpressionGenerator, null) + .applySmartCastIfNeeded(this) - private fun KtExpression.type() = - getType(this) ?: TODO("no type for expression") - - private fun IrExpression.smartCastIfNeeded(ktElement: KtElement): IrExpression { + private fun IrExpression.applySmartCastIfNeeded(ktElement: KtElement): IrExpression { if (ktElement is KtExpression) { val smartCastType = get(BindingContext.SMARTCAST, ktElement) if (smartCastType != null) { return IrTypeOperatorExpressionImpl( ktElement.startOffset, ktElement.endOffset, smartCastType, IrTypeOperator.SMART_AS, smartCastType - ).apply { argument = this@smartCastIfNeeded } + ).apply { argument = this@applySmartCastIfNeeded } } } return this } override fun visitExpression(expression: KtExpression, data: Nothing?): IrExpression = - IrDummyExpression(expression.startOffset, expression.endOffset, expression.type(), expression.javaClass.simpleName) + IrDummyExpression(expression.startOffset, expression.endOffset, getTypeOrFail(expression), expression.javaClass.simpleName) override fun visitBlockExpression(expression: KtBlockExpression, data: Nothing?): IrExpression { - val irBlock = IrBlockExpressionImpl(expression.startOffset, expression.endOffset, expression.type(), false) + val irBlock = IrBlockExpressionImpl(expression.startOffset, expression.endOffset, getTypeOrFail(expression), false) expression.statements.forEach { irBlock.addChildExpression(it.generate()) } return irBlock } override fun visitReturnExpression(expression: KtReturnExpression, data: Nothing?): IrExpression = - IrReturnExpressionImpl(expression.startOffset, expression.endOffset, expression.type()) + IrReturnExpressionImpl(expression.startOffset, expression.endOffset, getTypeOrFail(expression)) .apply { this.argument = expression.returnedExpression?.generate() } override fun visitConstantExpression(expression: KtConstantExpression, data: Nothing?): IrExpression { val compileTimeConstant = ConstantExpressionEvaluator.getConstant(expression, context.bindingContext) ?: error("KtConstantExpression was not evaluated: ${expression.text}") - val constantValue = compileTimeConstant.toConstantValue(expression.type()) + val constantValue = compileTimeConstant.toConstantValue(getTypeOrFail(expression)) val constantType = constantValue.type return when (constantValue) { @@ -93,7 +91,7 @@ class IrExpressionGenerator( return expression.entries[0].generate() } - val irStringTemplate = IrStringConcatenationExpressionImpl(expression.startOffset, expression.endOffset, expression.type()) + val irStringTemplate = IrStringConcatenationExpressionImpl(expression.startOffset, expression.endOffset, getTypeOrFail(expression)) expression.entries.forEach { irStringTemplate.addChildExpression(it.generate()) } return irStringTemplate } @@ -108,24 +106,24 @@ class IrExpressionGenerator( TODO("Unexpected VariableAsFunctionResolvedCall") } - val descriptor = resolvedCall?.resultingDescriptor ?: get(BindingContext.REFERENCE_TARGET, expression) + val descriptor = resolvedCall?.resultingDescriptor return when (descriptor) { is ClassDescriptor -> if (DescriptorUtils.isObject(descriptor)) - IrGetObjectValueExpressionImpl(expression.startOffset, expression.endOffset, expression.type(), descriptor) + IrGetObjectValueExpressionImpl(expression.startOffset, expression.endOffset, getTypeOrFail(expression), descriptor) else if (DescriptorUtils.isEnumEntry(descriptor)) - IrGetEnumValueExpressionImpl(expression.startOffset, expression.endOffset, expression.type(), descriptor) + IrGetEnumValueExpressionImpl(expression.startOffset, expression.endOffset, getTypeOrFail(expression), descriptor) else - IrGetObjectValueExpressionImpl(expression.startOffset, expression.endOffset, expression.type(), + IrGetObjectValueExpressionImpl(expression.startOffset, expression.endOffset, getTypeOrFail(expression), descriptor.companionObjectDescriptor ?: error("Class value without companion object: $descriptor")) is PropertyDescriptor -> { - generateCall(expression, resolvedCall ?: TODO("Property, no resolved call: ${descriptor.name}"), null) + irCallGenerator.generateCall(expression, resolvedCall) } is VariableDescriptor -> - IrGetVariableExpressionImpl(expression.startOffset, expression.endOffset, expression.type(), descriptor) + IrGetVariableExpressionImpl(expression.startOffset, expression.endOffset, getTypeOrFail(expression), descriptor) else -> - IrDummyExpression(expression.startOffset, expression.endOffset, expression.type(), + IrDummyExpression(expression.startOffset, expression.endOffset, getTypeOrFail(expression), expression.getReferencedName() + ": ${descriptor?.name} ${descriptor?.javaClass?.simpleName}") } @@ -138,7 +136,7 @@ class IrExpressionGenerator( TODO("VariableAsFunctionResolvedCall = variable call + invoke call") } - return generateCall(expression, resolvedCall, null, null) + return irCallGenerator.generateCall(expression, resolvedCall) } override fun visitDotQualifiedExpression(expression: KtDotQualifiedExpression, data: Nothing?): IrExpression = @@ -151,77 +149,16 @@ class IrExpressionGenerator( val referenceTarget = getOrFail(BindingContext.REFERENCE_TARGET, expression.instanceReference) { "No reference target for this" } return when (referenceTarget) { is ClassDescriptor -> - IrThisExpressionImpl(expression.startOffset, expression.endOffset, expression.type(), referenceTarget) + IrThisExpressionImpl(expression.startOffset, expression.endOffset, getTypeOrFail(expression), referenceTarget) is CallableDescriptor -> - IrGetExtensionReceiverExpressionImpl(expression.startOffset, expression.endOffset, expression.type(), - referenceTarget.extensionReceiverParameter!!) + IrGetExtensionReceiverExpressionImpl( + expression.startOffset, expression.endOffset, getTypeOrFail(expression), + referenceTarget.extensionReceiverParameter!! + ) else -> error("Expected this or receiver: $referenceTarget") } } - private fun generateCall( - ktExpression: KtExpression, - resolvedCall: ResolvedCall, - operator: IrOperator? = null, - superQualifier: ClassDescriptor? = null - ): IrExpression { - val descriptor = resolvedCall.resultingDescriptor - return when (descriptor) { - is PropertyDescriptor -> - IrGetPropertyExpressionImpl( - ktExpression.startOffset, ktExpression.endOffset, ktExpression.type(), - resolvedCall.call.isSafeCall(), descriptor - ) - else -> - IrCallExpressionImpl( - ktExpression.startOffset, ktExpression.endOffset, ktExpression.type(), - resolvedCall.resultingDescriptor, resolvedCall.call.isSafeCall(), operator, superQualifier - ).apply { - val valueParameters = resolvedCall.resultingDescriptor.valueParameters - val valueArguments = resolvedCall.valueArgumentsByIndex ?: TODO("null for value arguments: ${ktExpression.text}") - for (index in valueArguments.indices) { - val valueArgument = valueArguments[index] - val valueParameter = valueParameters[index] - putValueArgument(valueParameter, generateValueArgument(valueParameter, valueArgument)) - } - } - }.apply { - dispatchReceiver = generateReceiver(ktExpression, resolvedCall.dispatchReceiver) - extensionReceiver = generateReceiver(ktExpression, resolvedCall.extensionReceiver) - } - } - - private fun generateReceiver(ktExpression: KtExpression, receiver: ReceiverValue?): IrExpression? = - when (receiver) { - is ImplicitClassReceiver -> - IrThisExpressionImpl(ktExpression.startOffset, ktExpression.startOffset, receiver.type, receiver.classDescriptor) - is ThisClassReceiver -> - (receiver as? ExpressionReceiver)?.expression?.let { receiverExpression -> - IrThisExpressionImpl(receiverExpression.startOffset, receiverExpression.endOffset, receiver.type, receiver.classDescriptor) - } ?: TODO("Non-implicit ThisClassReceiver should be an expression receiver") - is ExpressionReceiver -> - receiver.expression.generate() - is ClassValueReceiver -> - IrGetObjectValueExpressionImpl(receiver.expression.startOffset, receiver.expression.endOffset, receiver.type, - receiver.classQualifier.descriptor) - is ExtensionReceiver -> - IrGetExtensionReceiverExpressionImpl(ktExpression.startOffset, ktExpression.startOffset, receiver.type, - receiver.declarationDescriptor.extensionReceiverParameter!!) - null -> - null - else -> - TODO("Receiver: ${receiver.javaClass.simpleName}") - } - - private fun generateValueArgument(valueParameter: ValueParameterDescriptor, valueArgument: ResolvedValueArgument): IrExpression? { - if (valueParameter.varargElementType == null) { - assert(valueArgument.arguments.size == 1) { "Single value argument expected for a non-vararg parameter" } - return valueArgument.arguments.single().getArgumentExpression()!!.generate() - } - else { - TODO("vararg") - } - } } diff --git a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/IrFileGenerator.kt b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/IrFileGenerator.kt index 8cb025f1a21..c6b8d855ec0 100644 --- a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/IrFileGenerator.kt +++ b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/IrFileGenerator.kt @@ -16,16 +16,17 @@ package org.jetbrains.kotlin.psi2ir +import org.jetbrains.kotlin.ir.declarations.IrFile import org.jetbrains.kotlin.ir.declarations.IrFileImpl import org.jetbrains.kotlin.psi.KtFile class IrFileGenerator( private val ktFile: KtFile, context: IrGeneratorContext, - irDeclaration: IrFileImpl, + irFile: IrFile, parent: IrModuleGenerator, declarationFactory: IrDeclarationFactory -) : IrDeclarationGeneratorBase(context, irDeclaration, parent, declarationFactory) { +) : IrDeclarationGeneratorBase(context, irFile, declarationFactory) { fun generateFileContent() { generateAnnotationEntries(ktFile.annotationEntries) diff --git a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/IrGenerator.kt b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/IrGenerator.kt index 2373304449d..7eb65917fa7 100644 --- a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/IrGenerator.kt +++ b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/IrGenerator.kt @@ -18,6 +18,7 @@ package org.jetbrains.kotlin.psi2ir import org.jetbrains.kotlin.descriptors.CallableDescriptor import org.jetbrains.kotlin.psi.KtExpression +import org.jetbrains.kotlin.resolve.BindingContext import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall import org.jetbrains.kotlin.types.KotlinType @@ -30,12 +31,18 @@ interface IrGenerator { fun IrGenerator.getType(key: KtExpression): KotlinType? = context.bindingContext.getType(key) +fun IrGenerator.getTypeOrFail(key: KtExpression): KotlinType = + getType(key) ?: TODO("No type for expression: ${key.text}") + fun IrGenerator.get(slice: ReadOnlySlice, key: K): V? = context.bindingContext[slice, key] inline fun IrGenerator.getOrFail(slice: ReadOnlySlice, key: K, message: (K) -> String): V = context.bindingContext[slice, key] ?: throw RuntimeException(message(key)) +fun IrGenerator.isUsedAsExpression(ktExpression: KtExpression) = + get(BindingContext.USED_AS_EXPRESSION, ktExpression) ?: false + inline fun IrGenerator.getOrElse(slice: ReadOnlySlice, key: K, otherwise: (K) -> V): V = context.bindingContext[slice, key] ?: otherwise(key) diff --git a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/IrModuleGenerator.kt b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/IrModuleGenerator.kt index ebcf04c0e2a..d54830c8ee5 100644 --- a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/IrModuleGenerator.kt +++ b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/IrModuleGenerator.kt @@ -16,19 +16,19 @@ package org.jetbrains.kotlin.psi2ir -import org.jetbrains.kotlin.ir.declarations.IrModule +import org.jetbrains.kotlin.ir.declarations.IrFileImpl import org.jetbrains.kotlin.resolve.BindingContext class IrModuleGenerator(override val context: IrGeneratorContext) : IrDeclarationGenerator { - override val irDeclaration: IrModule get() = context.irModule - override val parent: IrDeclarationGenerator? get() = null - fun generateModuleContent() { for (ktFile in context.inputFiles) { val packageFragmentDescriptor = getOrFail(BindingContext.FILE_TO_PACKAGE_FRAGMENT, ktFile) { "no package fragment for file" } - val irFileElementFactory = IrDeclarationFactory.create(context.irModule, context.sourceManager, ktFile, packageFragmentDescriptor) - val irFile = irFileElementFactory.irFileImpl + val fileEntry = context.sourceManager.getOrCreateFileEntry(ktFile) + val fileName = fileEntry.getRecognizableName() + val irFile = IrFileImpl(fileEntry, fileName, packageFragmentDescriptor) + context.sourceManager.putFileEntry(irFile, fileEntry) context.irModule.addFile(irFile) + val irFileElementFactory = IrDeclarationFactory() val generator = IrFileGenerator(ktFile, context, irFile, this, irFileElementFactory) generator.generateFileContent() } diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/IrArgumentIndices.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/IrChildIndices.kt similarity index 92% rename from compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/IrArgumentIndices.kt rename to compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/IrChildIndices.kt index e9631ffb93e..e4f1cb8039e 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/IrArgumentIndices.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/IrChildIndices.kt @@ -14,8 +14,9 @@ * limitations under the License. */ -package org.jetbrains.kotlin.ir.expressions +package org.jetbrains.kotlin.ir +const val CHILD_DECLARATION_INDEX = 0 const val DETACHED_INDEX = Int.MIN_VALUE const val CHILD_EXPRESSION_INDEX = 0 const val ARGUMENT0_INDEX = 0 diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/declarations/IrCompoundDeclaration.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/declarations/IrCompoundDeclaration.kt index 82f0af6a718..c54a6f4516e 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/declarations/IrCompoundDeclaration.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/declarations/IrCompoundDeclaration.kt @@ -16,36 +16,43 @@ package org.jetbrains.kotlin.ir.declarations +import org.jetbrains.kotlin.ir.CHILD_DECLARATION_INDEX import org.jetbrains.kotlin.ir.IrElement import org.jetbrains.kotlin.ir.IrElementBase +import org.jetbrains.kotlin.ir.DETACHED_INDEX import org.jetbrains.kotlin.ir.visitors.IrElementVisitor import java.util.* interface IrDeclarationOwner : IrElement { - val childrenCount: Int fun getChildDeclaration(index: Int): IrMemberDeclaration? - fun addChildDeclaration(child: IrMemberDeclaration) fun replaceChildDeclaration(oldChild: IrMemberDeclaration, newChild: IrMemberDeclaration) - fun removeAllChildDeclarations() +} - // TODO This can be an expensive operation / prohibited for some children. +interface IrDeclarationOwner1 : IrDeclarationOwner { + val childDeclaration: IrMemberDeclaration +} + +interface IrDeclarationOwnerN : IrDeclarationOwner { + val childrenCount: Int + fun addChildDeclaration(child: IrMemberDeclaration) fun removeChildDeclaration(child: IrMemberDeclaration) + fun removeAllChildDeclarations() fun acceptChildDeclarations(visitor: IrElementVisitor, data: D) } -interface IrCompoundDeclaration : IrDeclaration, IrDeclarationOwner +interface IrCompoundDeclaration : IrDeclaration, IrDeclarationOwnerN interface IrMemberDeclaration : IrDeclaration { - override val parent: IrDeclarationOwner + override var parent: IrDeclarationOwner? fun setTreeLocation(parent: IrDeclarationOwner?, index: Int) } -abstract class IrDeclarationOwnerBase( +abstract class IrDeclarationOwnerNBase( startOffset: Int, endOffset: Int -) : IrElementBase(startOffset, endOffset), IrDeclarationOwner { +) : IrElementBase(startOffset, endOffset), IrDeclarationOwnerN { protected val childDeclarations: MutableList = ArrayList() override val childrenCount: Int @@ -90,7 +97,7 @@ abstract class IrCompoundDeclarationBase( startOffset: Int, endOffset: Int, override val originKind: IrDeclarationOriginKind -) : IrDeclarationOwnerBase(startOffset, endOffset), IrCompoundDeclaration { +) : IrDeclarationOwnerNBase(startOffset, endOffset), IrCompoundDeclaration { override var indexInParent: Int = IrDeclaration.DETACHED_INDEX override fun acceptChildren(visitor: IrElementVisitor, data: D) { @@ -105,7 +112,7 @@ abstract class IrCompoundMemberDeclarationBase( ) : IrCompoundDeclarationBase(startOffset, endOffset, originKind), IrMemberDeclaration { private var parentImpl: IrDeclarationOwner? = null - override var parent: IrDeclarationOwner + override var parent: IrDeclarationOwner? get() = parentImpl!! set(newParent) { parentImpl = newParent @@ -124,7 +131,7 @@ abstract class IrMemberDeclarationBase( ) : IrDeclarationBase(startOffset, endOffset, originKind), IrMemberDeclaration { private var parentImpl: IrDeclarationOwner? = null - override var parent: IrDeclarationOwner + override var parent: IrDeclarationOwner? get() = parentImpl!! set(newParent) { parentImpl = newParent diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/declarations/IrDeclaration.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/declarations/IrDeclaration.kt index 1f16e6d3088..a0eebb65a35 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/declarations/IrDeclaration.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/declarations/IrDeclaration.kt @@ -38,15 +38,16 @@ enum class IrDeclarationKind { MODULE, FILE, FUNCTION, - PROPERTY, PROPERTY_GETTER, PROPERTY_SETTER, + PROPERTY, + LOCAL_VARIABLE, CLASS } enum class IrDeclarationOriginKind { DEFINED, - DEFAULT_PROPERTY_ACCESSOR, + IR_TEMPORARY_VARIABLE, } abstract class IrDeclarationBase( diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/declarations/IrFunction.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/declarations/IrFunction.kt index 75b965025d6..29062c9ae5e 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/declarations/IrFunction.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/declarations/IrFunction.kt @@ -45,6 +45,10 @@ class IrFunctionImpl( override val descriptor: FunctionDescriptor, override val body: IrBody ) : IrFunctionBase(startOffset, endOffset, originKind) { + init { + body.parent = this + } + override fun accept(visitor: IrElementVisitor, data: D): R = visitor.visitFunction(this, data) } diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/declarations/IrLocalVariable.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/declarations/IrLocalVariable.kt new file mode 100644 index 00000000000..19979929b61 --- /dev/null +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/declarations/IrLocalVariable.kt @@ -0,0 +1,65 @@ +/* + * Copyright 2010-2016 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.jetbrains.kotlin.ir.declarations + +import org.jetbrains.kotlin.descriptors.VariableDescriptor +import org.jetbrains.kotlin.ir.CHILD_EXPRESSION_INDEX +import org.jetbrains.kotlin.ir.expressions.* +import org.jetbrains.kotlin.ir.visitors.IrElementVisitor + +interface IrLocalVariable : IrMemberDeclaration, IrExpressionOwner { + override val descriptor: VariableDescriptor + + override val declarationKind: IrDeclarationKind + get() = IrDeclarationKind.LOCAL_VARIABLE + + var initializerExpression: IrExpression? +} + +class IrLocalVariableImpl( + startOffset: Int, + endOffset: Int, + originKind: IrDeclarationOriginKind, + override val descriptor: VariableDescriptor +) : IrMemberDeclarationBase(startOffset, endOffset, originKind), IrLocalVariable { + override var initializerExpression: IrExpression? = null + set(value) { + field?.detach() + field = value + value?.setTreeLocation(this, CHILD_EXPRESSION_INDEX) + } + + override fun getChildExpression(index: Int): IrExpression? = + if (index == CHILD_EXPRESSION_INDEX) initializerExpression else null + + override fun replaceChildExpression(oldChild: IrExpression, newChild: IrExpression) { + validateChild(oldChild) + initializerExpression = newChild + } + + override fun accept(visitor: IrElementVisitor, data: D): R { + return visitor.visitLocalVariable(this, data) + } + + override fun acceptChildren(visitor: IrElementVisitor, data: D) { + acceptChildExpressions(visitor, data) + } + + override fun acceptChildExpressions(visitor: IrElementVisitor, data: D) { + initializerExpression?.accept(visitor, data) + } +} \ No newline at end of file diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/declarations/IrProperty.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/declarations/IrProperty.kt index cf9d7ba2ecb..cb80eb900cb 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/declarations/IrProperty.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/declarations/IrProperty.kt @@ -71,6 +71,10 @@ class IrSimplePropertyImpl( descriptor: PropertyDescriptor, override val valueInitializer: IrBody? ) : IrPropertyBase(startOffset, endOffset, originKind, descriptor), IrSimpleProperty { + init { + valueInitializer?.parent = this + } + override fun accept(visitor: IrElementVisitor, data: D): R = visitor.visitSimpleProperty(this, data) diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/declarations/IrPropertyAccessor.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/declarations/IrPropertyAccessor.kt index 1b13dbf5051..ac02c6dc771 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/declarations/IrPropertyAccessor.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/declarations/IrPropertyAccessor.kt @@ -47,6 +47,10 @@ abstract class IrPropertyAccessorBase( originKind: IrDeclarationOriginKind, override val body: IrBody ) : IrFunctionBase(startOffset, endOffset, originKind), IrPropertyAccessor { + init { + body.parent = this + } + override var property: IrProperty? = null } diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/descriptors/IrTemporaryVariableDescriptor.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/descriptors/IrTemporaryVariableDescriptor.kt new file mode 100644 index 00000000000..d18b82935d4 --- /dev/null +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/descriptors/IrTemporaryVariableDescriptor.kt @@ -0,0 +1,48 @@ +/* + * Copyright 2010-2016 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.jetbrains.kotlin.ir.descriptors + +import org.jetbrains.kotlin.descriptors.* +import org.jetbrains.kotlin.descriptors.annotations.Annotations +import org.jetbrains.kotlin.descriptors.impl.VariableDescriptorImpl +import org.jetbrains.kotlin.name.Name +import org.jetbrains.kotlin.resolve.constants.ConstantValue +import org.jetbrains.kotlin.types.KotlinType +import org.jetbrains.kotlin.types.TypeSubstitutor + +interface IrTemporaryVariableDescriptor : VariableDescriptor + +class IrTemporaryVariableDescriptorImpl( + containingDeclaration: DeclarationDescriptor, + name: Name, + outType: KotlinType +): VariableDescriptorImpl(containingDeclaration, Annotations.EMPTY, name, outType, SourceElement.NO_SOURCE), + IrTemporaryVariableDescriptor +{ + override fun getCompileTimeInitializer(): ConstantValue<*>? = null + + override fun getVisibility(): Visibility = Visibilities.LOCAL + + override fun substitute(substitutor: TypeSubstitutor): VariableDescriptor { + throw UnsupportedOperationException("Temporary variable descriptor shouldn't be substituted (so far): $this") + } + + override fun isVar(): Boolean = false + + override fun accept(visitor: DeclarationDescriptorVisitor, data: D): R = + visitor.visitVariableDescriptor(this, data) +} \ No newline at end of file diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/IrBody.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/IrBody.kt index c6ab45ffbe3..5ce52b41975 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/IrBody.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/IrBody.kt @@ -16,24 +16,27 @@ package org.jetbrains.kotlin.ir.expressions +import org.jetbrains.kotlin.ir.CHILD_EXPRESSION_INDEX import org.jetbrains.kotlin.ir.IrElement +import org.jetbrains.kotlin.ir.IrElementBase import org.jetbrains.kotlin.ir.declarations.IrDeclaration import org.jetbrains.kotlin.ir.declarations.IrDeclarationOwner -import org.jetbrains.kotlin.ir.declarations.IrDeclarationOwnerBase +import org.jetbrains.kotlin.ir.declarations.IrDeclarationOwnerNBase import org.jetbrains.kotlin.ir.visitors.IrElementVisitor interface IrBody : IrElement { - override val parent: IrDeclaration + override var parent: IrDeclaration } -interface IrExpressionBody : IrBody, IrExpressionOwner1, IrDeclarationOwner +interface IrExpressionBody : IrBody, IrExpressionOwner1 // TODO IrExpressionBodyImpl vs IrCompoundExpression1Impl: extract common base class? class IrExpressionBodyImpl( startOffset: Int, - endOffset: Int, - override val parent: IrDeclaration -) : IrDeclarationOwnerBase(startOffset, endOffset), IrExpressionBody { + endOffset: Int +) : IrElementBase(startOffset, endOffset), IrExpressionBody { + override lateinit var parent: IrDeclaration + override var argument: IrExpression? = null set(newExpression) { field?.detach() diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/IrCallExpression.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/IrCallExpression.kt index eb664deef3a..216518a5960 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/IrCallExpression.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/IrCallExpression.kt @@ -18,7 +18,8 @@ package org.jetbrains.kotlin.ir.expressions import org.jetbrains.kotlin.descriptors.CallableDescriptor import org.jetbrains.kotlin.descriptors.ClassDescriptor -import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor +import org.jetbrains.kotlin.ir.DISPATCH_RECEIVER_INDEX +import org.jetbrains.kotlin.ir.EXTENSION_RECEIVER_INDEX import org.jetbrains.kotlin.ir.visitors.IrElementVisitor import org.jetbrains.kotlin.types.KotlinType @@ -27,16 +28,13 @@ interface IrCallExpression : IrMemberAccessExpression, IrCompoundExpression { val operator: IrOperator? override val descriptor: CallableDescriptor - fun getValueArgument(valueParameterDescriptor: ValueParameterDescriptor): IrExpression? - fun putValueArgument(valueParameterDescriptor: ValueParameterDescriptor, valueArgument: IrExpression?) - fun removeValueArgument(valueParameterDescriptor: ValueParameterDescriptor) + fun getValueArgument(index: Int): IrExpression? + fun putValueArgument(index: Int, valueArgument: IrExpression?) + fun removeValueArgument(index: Int) fun acceptValueArguments(visitor: IrElementVisitor, data: D) } -fun IrCallExpression.getMappedValueArguments(): List = - descriptor.valueParameters.mapNotNull { getValueArgument(it) } - class IrCallExpressionImpl( startOffset: Int, endOffset: Int, @@ -49,22 +47,18 @@ class IrCallExpressionImpl( private val argumentsByParameterIndex = kotlin.arrayOfNulls(descriptor.valueParameters.size) - override fun getValueArgument(valueParameterDescriptor: ValueParameterDescriptor): IrExpression? = - argumentsByParameterIndex[valueParameterDescriptor.index] + override fun getValueArgument(index: Int): IrExpression? = + argumentsByParameterIndex[index] - override fun putValueArgument(valueParameterDescriptor: ValueParameterDescriptor, valueArgument: IrExpression?) { - putValueArgument(valueParameterDescriptor.index, valueArgument) - } - - private fun putValueArgument(index: Int, valueArgument: IrExpression?) { + override fun putValueArgument(index: Int, valueArgument: IrExpression?) { argumentsByParameterIndex[index]?.detach() argumentsByParameterIndex[index] = valueArgument valueArgument?.setTreeLocation(this, index) } - override fun removeValueArgument(valueParameterDescriptor: ValueParameterDescriptor) { - argumentsByParameterIndex[valueParameterDescriptor.index]?.detach() - argumentsByParameterIndex[valueParameterDescriptor.index] = null + override fun removeValueArgument(index: Int) { + argumentsByParameterIndex[index]?.detach() + argumentsByParameterIndex[index] = null } override fun getChildExpression(index: Int): IrExpression? = diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/IrCompoundExpression.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/IrCompoundExpression.kt index e2880e00324..eb087517fc0 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/IrCompoundExpression.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/IrCompoundExpression.kt @@ -16,6 +16,8 @@ package org.jetbrains.kotlin.ir.expressions +import org.jetbrains.kotlin.ir.ARGUMENT0_INDEX +import org.jetbrains.kotlin.ir.ARGUMENT1_INDEX import org.jetbrains.kotlin.ir.visitors.IrElementVisitor import org.jetbrains.kotlin.types.KotlinType import java.util.* diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/IrExpression.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/IrExpression.kt index 3bad8880e8a..ceb87086854 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/IrExpression.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/IrExpression.kt @@ -16,6 +16,7 @@ package org.jetbrains.kotlin.ir.expressions +import org.jetbrains.kotlin.ir.DETACHED_INDEX import org.jetbrains.kotlin.ir.IrElement import org.jetbrains.kotlin.ir.IrElementBase import org.jetbrains.kotlin.ir.visitors.IrElementVisitor diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/IrLocalDeclarationExpression.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/IrLocalDeclarationExpression.kt new file mode 100644 index 00000000000..53cea52dfa2 --- /dev/null +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/IrLocalDeclarationExpression.kt @@ -0,0 +1,67 @@ +/* + * Copyright 2010-2016 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.jetbrains.kotlin.ir.expressions + +import org.jetbrains.kotlin.ir.CHILD_DECLARATION_INDEX +import org.jetbrains.kotlin.ir.declarations.* +import org.jetbrains.kotlin.ir.visitors.IrElementVisitor +import org.jetbrains.kotlin.types.KotlinType + +interface IrLocalDeclarationExpression : IrExpression, IrDeclarationOwner1 { + override val childDeclaration: D +} + +interface IrLocalVariableDeclarationExpression : IrLocalDeclarationExpression { + override var childDeclaration: IrLocalVariable +} + +abstract class IrLocalDeclarationExpressionBase( + startOffset: Int, + endOffset: Int, + type: KotlinType +) : IrExpressionBase(startOffset, endOffset, type), IrLocalVariableDeclarationExpression { + private var childDeclarationImpl: IrLocalVariable? = null + override var childDeclaration: IrLocalVariable + get() = childDeclarationImpl!! + set(value) { + childDeclarationImpl?.detach() + childDeclarationImpl = value + value.setTreeLocation(this, CHILD_DECLARATION_INDEX) + } + + override fun getChildDeclaration(index: Int): IrMemberDeclaration? = + if (index == CHILD_DECLARATION_INDEX) childDeclaration else null + + override fun replaceChildDeclaration(oldChild: IrMemberDeclaration, newChild: IrMemberDeclaration) { + if (newChild !is IrLocalVariable) throw AssertionError("IrLocalVariable expected: $newChild") + validateChild(oldChild) + childDeclaration = newChild + } + + override fun acceptChildren(visitor: IrElementVisitor, data: D) { + childDeclarationImpl?.accept(visitor, data) + } +} + +class IrLocalVariableDeclarationExpressionImpl( + startOffset: Int, + endOffset: Int, + type: KotlinType +) : IrLocalDeclarationExpressionBase(startOffset, endOffset, type), IrLocalVariableDeclarationExpression { + override fun accept(visitor: IrElementVisitor, data: D): R = + visitor.visitLocalVariableDeclarationExpression(this, data) +} \ No newline at end of file diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/IrMemberAccessExpression.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/IrMemberAccessExpression.kt index dc6e9d34c77..a38ec54f77b 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/IrMemberAccessExpression.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/IrMemberAccessExpression.kt @@ -16,6 +16,8 @@ package org.jetbrains.kotlin.ir.expressions +import org.jetbrains.kotlin.ir.DISPATCH_RECEIVER_INDEX +import org.jetbrains.kotlin.ir.EXTENSION_RECEIVER_INDEX import org.jetbrains.kotlin.types.KotlinType interface IrMemberAccessExpression : IrDeclarationReference, IrExpressionOwner { diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/IrOperator.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/IrOperator.kt index fbb125e9940..21bc3f64eff 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/IrOperator.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/IrOperator.kt @@ -17,11 +17,12 @@ package org.jetbrains.kotlin.ir.expressions enum class IrOperator { - INVOKE, INVOKE_EXTENSION, + INVOKE, PREFIX_INCR, PREFIX_DECR, POSTFIX_INCR, POSTFIX_DECR, UMINUS, EXCL, EXCLEXCL, + ELVIS, LT, GT, LTEQ, GTEQ, EQEQ, EQEQEQ, EXCLEQ, EXCLEQEQ, IN, NOT_IN, @@ -32,32 +33,36 @@ enum class IrOperator { PLUSEQ, MINUSEQ, MULEQ, DIVEQ, MODEQ; } -private val CAO_START = IrOperator.PLUSEQ -private val CAO_END = IrOperator.MODEQ -private val DUAL_START = IrOperator.PLUS -private val DUAL_END = IrOperator.MOD -private val INCR_DECR_START = IrOperator.PREFIX_INCR -private val INCR_DECR_END = IrOperator.POSTFIX_DECR +private val CAO_START = IrOperator.PLUSEQ.ordinal +private val CAO_END = IrOperator.MODEQ.ordinal +private val DUAL_START = IrOperator.PLUS.ordinal +private val DUAL_END = IrOperator.MOD.ordinal +private val INCR_DECR_START = IrOperator.PREFIX_INCR.ordinal +private val INCR_DECR_END = IrOperator.POSTFIX_DECR.ordinal +private val RELATIONAL_START = IrOperator.LT.ordinal +private val RELATIONAL_END = IrOperator.GTEQ.ordinal fun IrOperator.isIncrementOrDecrement(): Boolean = - this in INCR_DECR_START..INCR_DECR_END + this.ordinal in INCR_DECR_START..INCR_DECR_END fun IrOperator.isCompoundAssignment(): Boolean = - this in CAO_START .. CAO_END + this.ordinal in CAO_START .. CAO_END fun IrOperator.isAssignmentOrCompoundAssignment(): Boolean = this == IrOperator.EQ || isCompoundAssignment() fun IrOperator.hasCompoundAssignmentDual(): Boolean = - this in DUAL_START .. DUAL_END + this.ordinal in DUAL_START .. DUAL_END fun IrOperator.toDualOperator(): IrOperator = when { isCompoundAssignment() -> - IrOperator.values()[this.ordinal - CAO_START.ordinal + DUAL_START.ordinal] + IrOperator.values()[this.ordinal - CAO_START + DUAL_START] hasCompoundAssignmentDual() -> - IrOperator.values()[this.ordinal - DUAL_START.ordinal + CAO_START.ordinal] + IrOperator.values()[this.ordinal - DUAL_START + CAO_START] else -> throw UnsupportedOperationException("Operator $this is not a compound assignment") } +fun IrOperator.isRelational(): Boolean = + this.ordinal in RELATIONAL_START .. RELATIONAL_END \ No newline at end of file diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/IrPropertyAccessExpression.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/IrPropertyAccessExpression.kt index ccb5db195d4..d42eac00832 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/IrPropertyAccessExpression.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/IrPropertyAccessExpression.kt @@ -17,6 +17,9 @@ package org.jetbrains.kotlin.ir.expressions import org.jetbrains.kotlin.descriptors.PropertyDescriptor +import org.jetbrains.kotlin.ir.ARGUMENT0_INDEX +import org.jetbrains.kotlin.ir.DISPATCH_RECEIVER_INDEX +import org.jetbrains.kotlin.ir.EXTENSION_RECEIVER_INDEX import org.jetbrains.kotlin.ir.visitors.IrElementVisitor import org.jetbrains.kotlin.types.KotlinType diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/DumpIrTree.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/DumpIrTree.kt index 4f90d33080e..6ec5ef5b7a3 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/DumpIrTree.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/DumpIrTree.kt @@ -50,7 +50,7 @@ class DumpIrTreeVisitor(out: Appendable): IrElementVisitor { expression.dispatchReceiver?.accept(this, "\$this") expression.extensionReceiver?.accept(this, "\$receiver") for (valueParameter in expression.descriptor.valueParameters) { - expression.getValueArgument(valueParameter)?.accept(this, valueParameter.name.asString()) + expression.getValueArgument(valueParameter.index)?.accept(this, valueParameter.name.asString()) } } } diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/RenderIrElement.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/RenderIrElement.kt index fbe0efcc8d9..026f97f79bc 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/RenderIrElement.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/RenderIrElement.kt @@ -48,6 +48,9 @@ class RenderIrElementVisitor : IrElementVisitor { override fun visitPropertySetter(declaration: IrPropertySetter, data: Nothing?): String = "IrPropertySetter ${declaration.descriptor.render()} property=${declaration.property?.name()}" + override fun visitLocalVariable(declaration: IrLocalVariable, data: Nothing?): String = + "IrLocalVariable ${declaration.descriptor.render()}" + override fun visitExpressionBody(body: IrExpressionBody, data: Nothing?): String = "IrExpressionBody" @@ -57,6 +60,9 @@ class RenderIrElementVisitor : IrElementVisitor { override fun visitLiteral(expression: IrLiteralExpression, data: Nothing?): String = "LITERAL ${expression.kind} type=${expression.renderType()} value='${expression.value}'" + override fun visitLocalVariableDeclarationExpression(expression: IrLocalVariableDeclarationExpression, data: Nothing?): String = + "LOCAL ${expression.childDeclaration.descriptor.name}" + override fun visitBlockExpression(expression: IrBlockExpression, data: Nothing?): String = "BLOCK type=${expression.renderType()}" diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/visitors/IrElementVisitor.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/visitors/IrElementVisitor.kt index 33b096b2692..c04df1d09c5 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/visitors/IrElementVisitor.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/visitors/IrElementVisitor.kt @@ -34,6 +34,7 @@ interface IrElementVisitor { fun visitProperty(declaration: IrProperty, data: D): R = visitDeclaration(declaration, data) fun visitSimpleProperty(declaration: IrSimpleProperty, data: D): R = visitProperty(declaration, data) fun visitDelegatedProperty(declaration: IrDelegatedProperty, data: D): R = visitProperty(declaration, data) + fun visitLocalVariable(declaration: IrLocalVariable, data: D) = visitDeclaration(declaration, data) fun visitBody(body: IrBody, data: D): R = visitElement(body, data) fun visitExpressionBody(body: IrExpressionBody, data: D): R = visitBody(body, data) @@ -45,6 +46,11 @@ interface IrElementVisitor { fun visitStringTemplate(expression: IrStringConcatenationExpression, data: D) = visitExpression(expression, data) fun visitThisExpression(expression: IrThisExpression, data: D) = visitExpression(expression, data) + fun visitLocalDeclarationExpression(expression: IrLocalDeclarationExpression, data: D) = + visitExpression(expression, data) + fun visitLocalVariableDeclarationExpression(expression: IrLocalVariableDeclarationExpression, data: D) = + visitLocalDeclarationExpression(expression, data) + fun visitDeclarationReference(expression: IrDeclarationReference, data: D) = visitExpression(expression, data) fun visitGetObjectValue(expression: IrGetObjectValueExpression, data: D) = visitDeclarationReference(expression, data) fun visitGetEnumValue(expression: IrGetEnumValueExpression, data: D) = visitDeclarationReference(expression, data) @@ -65,6 +71,4 @@ interface IrElementVisitor { fun visitDummyExpression(expression: IrDummyExpression, data: D) = visitExpression(expression, data) - - } diff --git a/compiler/testData/ir/irText/boxOk.txt b/compiler/testData/ir/irText/boxOk.txt index 5bf9798e49f..7bb9a5cc33b 100644 --- a/compiler/testData/ir/irText/boxOk.txt +++ b/compiler/testData/ir/irText/boxOk.txt @@ -1,5 +1,4 @@ IrFile /boxOk.kt IrFunction public fun box(): kotlin.String IrExpressionBody - RETURN type=kotlin.String - LITERAL String type=kotlin.String value='OK' + LITERAL String type=kotlin.String value='OK' diff --git a/compiler/testData/ir/irText/callWithReorderedArguments.kt b/compiler/testData/ir/irText/callWithReorderedArguments.kt new file mode 100644 index 00000000000..4eccf740b81 --- /dev/null +++ b/compiler/testData/ir/irText/callWithReorderedArguments.kt @@ -0,0 +1,13 @@ +// <<< callWithReorderedArguments.txt +fun foo(a: Int, b: Int) {} + +fun noReorder1() = 1 +fun noReorder2() = 2 + +fun reordered1() = 1 +fun reordered2() = 2 + +fun test() { + foo(a = noReorder1(), b = noReorder2()) + foo(b = reordered1(), a = reordered2()) +} \ No newline at end of file diff --git a/compiler/testData/ir/irText/callWithReorderedArguments.txt b/compiler/testData/ir/irText/callWithReorderedArguments.txt new file mode 100644 index 00000000000..be372e7faf0 --- /dev/null +++ b/compiler/testData/ir/irText/callWithReorderedArguments.txt @@ -0,0 +1,32 @@ +IrFile /callWithReorderedArguments.kt + IrFunction public fun foo(/*0*/ a: kotlin.Int, /*1*/ b: kotlin.Int): kotlin.Unit + IrExpressionBody + BLOCK type=kotlin.Unit + IrFunction public fun noReorder1(): kotlin.Int + IrExpressionBody + LITERAL Int type=kotlin.Int value='1' + IrFunction public fun noReorder2(): kotlin.Int + IrExpressionBody + LITERAL Int type=kotlin.Int value='2' + IrFunction public fun reordered1(): kotlin.Int + IrExpressionBody + LITERAL Int type=kotlin.Int value='1' + IrFunction public fun reordered2(): kotlin.Int + IrExpressionBody + LITERAL Int type=kotlin.Int value='2' + IrFunction public fun test(): kotlin.Unit + IrExpressionBody + BLOCK type=kotlin.Unit + CALL .foo + a: CALL .noReorder1 + b: CALL .noReorder2 + BLOCK type=kotlin.Unit + LOCAL tmp0 + IrLocalVariable val tmp0: kotlin.Int + CALL .reordered1 + LOCAL tmp1 + IrLocalVariable val tmp1: kotlin.Int + CALL .reordered2 + CALL .foo + a: GET_VAR tmp1 + b: GET_VAR tmp0 diff --git a/compiler/testData/ir/irText/calls.txt b/compiler/testData/ir/irText/calls.txt index 972d270351b..65943738941 100644 --- a/compiler/testData/ir/irText/calls.txt +++ b/compiler/testData/ir/irText/calls.txt @@ -1,29 +1,24 @@ IrFile /calls.kt IrFunction public fun foo(/*0*/ x: kotlin.Int, /*1*/ y: kotlin.Int): kotlin.Int IrExpressionBody - RETURN type=kotlin.Int - GET_VAR x + GET_VAR x IrFunction public fun bar(/*0*/ x: kotlin.Int): kotlin.Int IrExpressionBody - RETURN type=kotlin.Int - CALL .foo - x: GET_VAR x - y: LITERAL Int type=kotlin.Int value='1' + CALL .foo + x: GET_VAR x + y: LITERAL Int type=kotlin.Int value='1' IrFunction public fun qux(/*0*/ x: kotlin.Int): kotlin.Int IrExpressionBody - RETURN type=kotlin.Int - CALL .foo - x: CALL .foo - x: GET_VAR x - y: GET_VAR x + CALL .foo + x: CALL .foo + x: GET_VAR x y: GET_VAR x + y: GET_VAR x IrFunction public fun kotlin.Int.ext1(): kotlin.Int IrExpressionBody - RETURN type=kotlin.Int - $RECEIVER of: ext1 + $RECEIVER of: ext1 IrFunction public fun kotlin.Int.ext2(/*0*/ x: kotlin.Int): kotlin.Int IrExpressionBody - RETURN type=kotlin.Int - CALL .foo - x: $RECEIVER of: ext2 - y: GET_VAR x + CALL .foo + x: $RECEIVER of: ext2 + y: GET_VAR x diff --git a/compiler/testData/ir/irText/dotQualified.txt b/compiler/testData/ir/irText/dotQualified.txt index ae2978f6991..2ae9a96b467 100644 --- a/compiler/testData/ir/irText/dotQualified.txt +++ b/compiler/testData/ir/irText/dotQualified.txt @@ -1,11 +1,9 @@ IrFile /dotQualified.kt IrFunction public fun length(/*0*/ s: kotlin.String): kotlin.Int IrExpressionBody - RETURN type=kotlin.Int - GET_PROPERTY .length - $this: GET_VAR s + GET_PROPERTY .length + $this: GET_VAR s IrFunction public fun lengthN(/*0*/ s: kotlin.String?): kotlin.Int? IrExpressionBody - RETURN type=kotlin.Int? - GET_PROPERTY ?.length - $this: GET_VAR s + GET_PROPERTY ?.length + $this: GET_VAR s diff --git a/compiler/testData/ir/irText/extensionPropertyGetterCall.txt b/compiler/testData/ir/irText/extensionPropertyGetterCall.txt index 32b26ee83b6..ad4442ea3ff 100644 --- a/compiler/testData/ir/irText/extensionPropertyGetterCall.txt +++ b/compiler/testData/ir/irText/extensionPropertyGetterCall.txt @@ -2,10 +2,8 @@ IrFile /extensionPropertyGetterCall.kt IrProperty public val kotlin.String.okext: kotlin.String getter= setter=null IrPropertyGetter public fun kotlin.String.(): kotlin.String property=okext IrExpressionBody - RETURN type=kotlin.String - LITERAL String type=kotlin.String value='OK' + LITERAL String type=kotlin.String value='OK' IrFunction public fun kotlin.String.test5(): kotlin.String IrExpressionBody - RETURN type=kotlin.String - GET_PROPERTY .okext - $receiver: $RECEIVER of: test5 + GET_PROPERTY .okext + $receiver: $RECEIVER of: test5 diff --git a/compiler/testData/ir/irText/references.txt b/compiler/testData/ir/irText/references.txt index 6da12582631..d32caef7d2c 100644 --- a/compiler/testData/ir/irText/references.txt +++ b/compiler/testData/ir/irText/references.txt @@ -1,25 +1,20 @@ IrFile /references.kt IrProperty public val ok: kotlin.String = "OK" getter=null setter=null IrExpressionBody - RETURN type=kotlin.String - LITERAL String type=kotlin.String value='OK' + LITERAL String type=kotlin.String value='OK' IrProperty public val ok2: kotlin.String = "OK" getter=null setter=null IrExpressionBody - RETURN type=kotlin.String - GET_PROPERTY .ok + GET_PROPERTY .ok IrProperty public val ok3: kotlin.String getter= setter=null IrPropertyGetter public fun (): kotlin.String property=ok3 IrExpressionBody - RETURN type=kotlin.String - LITERAL String type=kotlin.String value='OK' + LITERAL String type=kotlin.String value='OK' IrFunction public fun test1(): kotlin.String IrExpressionBody - RETURN type=kotlin.String - GET_PROPERTY .ok + GET_PROPERTY .ok IrFunction public fun test2(/*0*/ x: kotlin.String): kotlin.String IrExpressionBody - RETURN type=kotlin.String - GET_VAR x + GET_VAR x IrFunction public fun test3(): kotlin.String IrExpressionBody BLOCK type=kotlin.Nothing @@ -28,15 +23,12 @@ IrFile /references.kt GET_VAR x IrFunction public fun test4(): kotlin.String IrExpressionBody - RETURN type=kotlin.String - GET_PROPERTY .ok3 + GET_PROPERTY .ok3 IrProperty public val kotlin.String.okext: kotlin.String getter= setter=null IrPropertyGetter public fun kotlin.String.(): kotlin.String property=okext IrExpressionBody - RETURN type=kotlin.String - LITERAL String type=kotlin.String value='OK' + LITERAL String type=kotlin.String value='OK' IrFunction public fun kotlin.String.test5(): kotlin.String IrExpressionBody - RETURN type=kotlin.String - GET_PROPERTY .okext - $receiver: $RECEIVER of: test5 + GET_PROPERTY .okext + $receiver: $RECEIVER of: test5 diff --git a/compiler/testData/ir/irText/smoke.testSimpleVal.txt b/compiler/testData/ir/irText/smoke.testSimpleVal.txt index b6e0f87da0a..f5db130b5f3 100644 --- a/compiler/testData/ir/irText/smoke.testSimpleVal.txt +++ b/compiler/testData/ir/irText/smoke.testSimpleVal.txt @@ -1,4 +1,3 @@ IrProperty public val testSimpleVal: kotlin.Int = 1 getter=null setter=null IrExpressionBody - RETURN type=kotlin.Int - LITERAL Int type=kotlin.Int value='1' + LITERAL Int type=kotlin.Int value='1' diff --git a/compiler/testData/ir/irText/smoke.txt b/compiler/testData/ir/irText/smoke.txt index fc0f0b021e1..ffe0925ca37 100644 --- a/compiler/testData/ir/irText/smoke.txt +++ b/compiler/testData/ir/irText/smoke.txt @@ -6,22 +6,18 @@ IrFile /smoke.kt LITERAL String type=kotlin.String value='OK' IrProperty public val testSimpleVal: kotlin.Int = 1 getter=null setter=null IrExpressionBody - RETURN type=kotlin.Int - LITERAL Int type=kotlin.Int value='1' + LITERAL Int type=kotlin.Int value='1' IrProperty public val testValWithGetter: kotlin.Int getter= setter=null IrPropertyGetter public fun (): kotlin.Int property=testValWithGetter IrExpressionBody - RETURN type=kotlin.Int - LITERAL Int type=kotlin.Int value='42' + LITERAL Int type=kotlin.Int value='42' IrProperty public var testSimpleVar: kotlin.Int getter=null setter=null IrExpressionBody - RETURN type=kotlin.Int - LITERAL Int type=kotlin.Int value='2' + LITERAL Int type=kotlin.Int value='2' IrProperty public var testVarWithAccessors: kotlin.Int getter= setter= IrPropertyGetter public fun (): kotlin.Int property=testVarWithAccessors IrExpressionBody - RETURN type=kotlin.Int - LITERAL Int type=kotlin.Int value='42' + LITERAL Int type=kotlin.Int value='42' IrPropertySetter public fun (/*0*/ v: kotlin.Int): kotlin.Unit property=testVarWithAccessors IrExpressionBody BLOCK type=kotlin.Unit diff --git a/compiler/tests/org/jetbrains/kotlin/ir/IrTextTestCaseGenerated.java b/compiler/tests/org/jetbrains/kotlin/ir/IrTextTestCaseGenerated.java index 70d029307d1..7edd4dbce8e 100644 --- a/compiler/tests/org/jetbrains/kotlin/ir/IrTextTestCaseGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/ir/IrTextTestCaseGenerated.java @@ -41,6 +41,12 @@ public class IrTextTestCaseGenerated extends AbstractIrTextTestCase { doTest(fileName); } + @TestMetadata("callWithReorderedArguments.kt") + public void testCallWithReorderedArguments() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/ir/irText/callWithReorderedArguments.kt"); + doTest(fileName); + } + @TestMetadata("calls.kt") public void testCalls() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/ir/irText/calls.kt");