IrBody is no longer a declaration owner.
Local declarations in expression tree. Call generator supports argument reordering.
This commit is contained in:
committed by
Dmitry Petrov
parent
b1af1af8a4
commit
030111b130
@@ -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<out CallableDescriptor>,
|
||||
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<out CallableDescriptor>,
|
||||
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<out CallableDescriptor>,
|
||||
resultType: KotlinType
|
||||
): IrExpression {
|
||||
val valueArgumentsInEvaluationOrder = resolvedCall.valueArguments.values
|
||||
val hasResult = isUsedAsExpression(ktExpression)
|
||||
val irBlock = IrBlockExpressionImpl(ktExpression.startOffset, ktExpression.endOffset, resultType, hasResult)
|
||||
|
||||
val temporaryVariablesForValueArguments = HashMap<ResolvedValueArgument, Pair<VariableDescriptor, IrExpression>>()
|
||||
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}")
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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 : IrMemberDeclaration> 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)
|
||||
}
|
||||
}
|
||||
}
|
||||
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)
|
||||
}
|
||||
|
||||
@@ -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 : IrMemberDeclaration> D.register(): D =
|
||||
apply { container.addChildDeclaration(this) }
|
||||
|
||||
fun generateAnnotationEntries(annotationEntries: List<KtAnnotationEntry>) {
|
||||
// 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)
|
||||
}
|
||||
}
|
||||
@@ -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<IrExpression, Nothing?>(), 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<out CallableDescriptor>,
|
||||
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")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
@@ -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 <K, V : Any> IrGenerator.get(slice: ReadOnlySlice<K, V>, key: K): V? =
|
||||
context.bindingContext[slice, key]
|
||||
|
||||
inline fun <K, V : Any> IrGenerator.getOrFail(slice: ReadOnlySlice<K, V>, 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 <K, V : Any> IrGenerator.getOrElse(slice: ReadOnlySlice<K, V>, key: K, otherwise: (K) -> V): V =
|
||||
context.bindingContext[slice, key] ?: otherwise(key)
|
||||
|
||||
|
||||
@@ -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()
|
||||
}
|
||||
|
||||
+2
-1
@@ -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
|
||||
+18
-11
@@ -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 <D> acceptChildDeclarations(visitor: IrElementVisitor<Unit, D>, 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<IrMemberDeclaration> = 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 <D> acceptChildren(visitor: IrElementVisitor<Unit, D>, 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
|
||||
|
||||
@@ -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(
|
||||
|
||||
@@ -45,6 +45,10 @@ class IrFunctionImpl(
|
||||
override val descriptor: FunctionDescriptor,
|
||||
override val body: IrBody
|
||||
) : IrFunctionBase(startOffset, endOffset, originKind) {
|
||||
init {
|
||||
body.parent = this
|
||||
}
|
||||
|
||||
override fun <R, D> accept(visitor: IrElementVisitor<R, D>, data: D): R =
|
||||
visitor.visitFunction(this, data)
|
||||
}
|
||||
|
||||
@@ -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 <R, D> accept(visitor: IrElementVisitor<R, D>, data: D): R {
|
||||
return visitor.visitLocalVariable(this, data)
|
||||
}
|
||||
|
||||
override fun <D> acceptChildren(visitor: IrElementVisitor<Unit, D>, data: D) {
|
||||
acceptChildExpressions(visitor, data)
|
||||
}
|
||||
|
||||
override fun <D> acceptChildExpressions(visitor: IrElementVisitor<Unit, D>, data: D) {
|
||||
initializerExpression?.accept(visitor, data)
|
||||
}
|
||||
}
|
||||
@@ -71,6 +71,10 @@ class IrSimplePropertyImpl(
|
||||
descriptor: PropertyDescriptor,
|
||||
override val valueInitializer: IrBody?
|
||||
) : IrPropertyBase(startOffset, endOffset, originKind, descriptor), IrSimpleProperty {
|
||||
init {
|
||||
valueInitializer?.parent = this
|
||||
}
|
||||
|
||||
override fun <R, D> accept(visitor: IrElementVisitor<R, D>, data: D): R =
|
||||
visitor.visitSimpleProperty(this, data)
|
||||
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
|
||||
+48
@@ -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 <R, D> accept(visitor: DeclarationDescriptorVisitor<R, D>, data: D): R =
|
||||
visitor.visitVariableDescriptor(this, data)
|
||||
}
|
||||
@@ -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()
|
||||
|
||||
@@ -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 <D> acceptValueArguments(visitor: IrElementVisitor<Unit, D>, data: D)
|
||||
}
|
||||
|
||||
fun IrCallExpression.getMappedValueArguments(): List<IrExpression?> =
|
||||
descriptor.valueParameters.mapNotNull { getValueArgument(it) }
|
||||
|
||||
class IrCallExpressionImpl(
|
||||
startOffset: Int,
|
||||
endOffset: Int,
|
||||
@@ -49,22 +47,18 @@ class IrCallExpressionImpl(
|
||||
private val argumentsByParameterIndex =
|
||||
kotlin.arrayOfNulls<IrExpression>(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? =
|
||||
|
||||
@@ -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.*
|
||||
|
||||
@@ -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
|
||||
|
||||
+67
@@ -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<out D : IrMemberDeclaration> : IrExpression, IrDeclarationOwner1 {
|
||||
override val childDeclaration: D
|
||||
}
|
||||
|
||||
interface IrLocalVariableDeclarationExpression : IrLocalDeclarationExpression<IrLocalVariable> {
|
||||
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 <D> acceptChildren(visitor: IrElementVisitor<Unit, D>, data: D) {
|
||||
childDeclarationImpl?.accept(visitor, data)
|
||||
}
|
||||
}
|
||||
|
||||
class IrLocalVariableDeclarationExpressionImpl(
|
||||
startOffset: Int,
|
||||
endOffset: Int,
|
||||
type: KotlinType
|
||||
) : IrLocalDeclarationExpressionBase(startOffset, endOffset, type), IrLocalVariableDeclarationExpression {
|
||||
override fun <R, D> accept(visitor: IrElementVisitor<R, D>, data: D): R =
|
||||
visitor.visitLocalVariableDeclarationExpression(this, data)
|
||||
}
|
||||
+2
@@ -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 {
|
||||
|
||||
@@ -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
|
||||
+3
@@ -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
|
||||
|
||||
|
||||
@@ -50,7 +50,7 @@ class DumpIrTreeVisitor(out: Appendable): IrElementVisitor<Unit, String> {
|
||||
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())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -48,6 +48,9 @@ class RenderIrElementVisitor : IrElementVisitor<String, Nothing?> {
|
||||
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<String, Nothing?> {
|
||||
override fun <T> visitLiteral(expression: IrLiteralExpression<T>, 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()}"
|
||||
|
||||
|
||||
@@ -34,6 +34,7 @@ interface IrElementVisitor<out R, in D> {
|
||||
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<out R, in D> {
|
||||
fun visitStringTemplate(expression: IrStringConcatenationExpression, data: D) = visitExpression(expression, data)
|
||||
fun visitThisExpression(expression: IrThisExpression, data: D) = visitExpression(expression, data)
|
||||
|
||||
fun <T : IrMemberDeclaration> visitLocalDeclarationExpression(expression: IrLocalDeclarationExpression<T>, 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<out R, in D> {
|
||||
fun visitDummyExpression(expression: IrDummyExpression, data: D) = visitExpression(expression, data)
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
+1
-2
@@ -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'
|
||||
|
||||
@@ -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())
|
||||
}
|
||||
@@ -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
|
||||
+12
-17
@@ -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
|
||||
|
||||
+4
-6
@@ -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
|
||||
|
||||
@@ -2,10 +2,8 @@ IrFile /extensionPropertyGetterCall.kt
|
||||
IrProperty public val kotlin.String.okext: kotlin.String getter=<get-okext> setter=null
|
||||
IrPropertyGetter public fun kotlin.String.<get-okext>(): 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
|
||||
|
||||
+9
-17
@@ -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=<get-ok3> setter=null
|
||||
IrPropertyGetter public fun <get-ok3>(): 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=<get-okext> setter=null
|
||||
IrPropertyGetter public fun kotlin.String.<get-okext>(): 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
|
||||
|
||||
+1
-2
@@ -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'
|
||||
|
||||
+4
-8
@@ -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=<get-testValWithGetter> setter=null
|
||||
IrPropertyGetter public fun <get-testValWithGetter>(): 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=<get-testVarWithAccessors> setter=<set-testVarWithAccessors>
|
||||
IrPropertyGetter public fun <get-testVarWithAccessors>(): 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 <set-testVarWithAccessors>(/*0*/ v: kotlin.Int): kotlin.Unit property=testVarWithAccessors
|
||||
IrExpressionBody
|
||||
BLOCK type=kotlin.Unit
|
||||
|
||||
@@ -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");
|
||||
|
||||
Reference in New Issue
Block a user