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.descriptors.*
|
||||||
import org.jetbrains.kotlin.ir.declarations.*
|
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.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.endOffset
|
||||||
import org.jetbrains.kotlin.psi.psiUtil.startOffset
|
import org.jetbrains.kotlin.psi.psiUtil.startOffset
|
||||||
|
import org.jetbrains.kotlin.types.KotlinType
|
||||||
|
|
||||||
class IrDeclarationFactory private constructor(
|
abstract class IrDeclarationFactoryBase {
|
||||||
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) }
|
|
||||||
|
|
||||||
fun createFunction(ktFunction: KtFunction, functionDescriptor: FunctionDescriptor, body: IrBody): IrFunction =
|
fun createFunction(ktFunction: KtFunction, functionDescriptor: FunctionDescriptor, body: IrBody): IrFunction =
|
||||||
IrFunctionImpl(ktFunction.startOffset, ktFunction.endOffset,
|
IrFunctionImpl(ktFunction.startOffset, ktFunction.endOffset,
|
||||||
IrDeclarationOriginKind.DEFINED, functionDescriptor, body)
|
IrDeclarationOriginKind.DEFINED, functionDescriptor, body)
|
||||||
.addToContainer()
|
|
||||||
|
|
||||||
fun createSimpleProperty(ktProperty: KtProperty, propertyDescriptor: PropertyDescriptor, valueInitializer: IrBody?): IrSimpleProperty =
|
fun createSimpleProperty(ktProperty: KtProperty, propertyDescriptor: PropertyDescriptor, valueInitializer: IrBody?): IrSimpleProperty =
|
||||||
IrSimplePropertyImpl(ktProperty.startOffset, ktProperty.endOffset,
|
IrSimplePropertyImpl(ktProperty.startOffset, ktProperty.endOffset,
|
||||||
IrDeclarationOriginKind.DEFINED, propertyDescriptor, valueInitializer)
|
IrDeclarationOriginKind.DEFINED, propertyDescriptor, valueInitializer)
|
||||||
.addToContainer()
|
|
||||||
|
|
||||||
fun createPropertyGetter(
|
fun createPropertyGetter(
|
||||||
ktPropertyAccessor: KtPropertyAccessor,
|
ktPropertyAccessor: KtPropertyAccessor,
|
||||||
@@ -53,7 +49,6 @@ class IrDeclarationFactory private constructor(
|
|||||||
IrPropertyGetterImpl(ktPropertyAccessor.startOffset, ktPropertyAccessor.endOffset,
|
IrPropertyGetterImpl(ktPropertyAccessor.startOffset, ktPropertyAccessor.endOffset,
|
||||||
IrDeclarationOriginKind.DEFINED, getterDescriptor, getterBody)
|
IrDeclarationOriginKind.DEFINED, getterDescriptor, getterBody)
|
||||||
.apply { irProperty.getter = this }
|
.apply { irProperty.getter = this }
|
||||||
.addToContainer()
|
|
||||||
|
|
||||||
fun createPropertySetter(
|
fun createPropertySetter(
|
||||||
ktPropertyAccessor: KtPropertyAccessor,
|
ktPropertyAccessor: KtPropertyAccessor,
|
||||||
@@ -64,16 +59,30 @@ class IrDeclarationFactory private constructor(
|
|||||||
IrPropertySetterImpl(ktPropertyAccessor.startOffset, ktPropertyAccessor.endOffset,
|
IrPropertySetterImpl(ktPropertyAccessor.startOffset, ktPropertyAccessor.endOffset,
|
||||||
IrDeclarationOriginKind.DEFINED, setterDescriptor, setterBody)
|
IrDeclarationOriginKind.DEFINED, setterDescriptor, setterBody)
|
||||||
.apply { irProperty.setter = this }
|
.apply { irProperty.setter = this }
|
||||||
.addToContainer()
|
}
|
||||||
|
|
||||||
companion object {
|
class IrDeclarationFactory() : IrDeclarationFactoryBase()
|
||||||
fun create(irModule: IrModuleImpl, sourceManager: PsiSourceManager, ktFile: KtFile, descriptor: PackageFragmentDescriptor): IrDeclarationFactory {
|
|
||||||
val fileEntry = sourceManager.getOrCreateFileEntry(ktFile)
|
class IrLocalDeclarationsFactory(val scopeOwner: DeclarationDescriptor) : IrDeclarationFactoryBase() {
|
||||||
val fileName = fileEntry.getRecognizableName()
|
private var lastTemporaryIndex = 0
|
||||||
val irFile = IrFileImpl(fileEntry, fileName, descriptor)
|
private fun nextTemporaryIndex() = lastTemporaryIndex++
|
||||||
sourceManager.putFileEntry(irFile, fileEntry)
|
|
||||||
irModule.addFile(irFile)
|
fun createDescriptorForTemporaryVariable(type: KotlinType): IrTemporaryVariableDescriptor =
|
||||||
return IrDeclarationFactory(fileEntry, irFile, irFile)
|
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
|
package org.jetbrains.kotlin.psi2ir
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
||||||
import org.jetbrains.kotlin.descriptors.PropertyDescriptor
|
import org.jetbrains.kotlin.descriptors.PropertyDescriptor
|
||||||
import org.jetbrains.kotlin.descriptors.PropertyGetterDescriptor
|
import org.jetbrains.kotlin.descriptors.PropertyGetterDescriptor
|
||||||
import org.jetbrains.kotlin.descriptors.PropertySetterDescriptor
|
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.psi.psiUtil.startOffset
|
||||||
import org.jetbrains.kotlin.resolve.BindingContext
|
import org.jetbrains.kotlin.resolve.BindingContext
|
||||||
|
|
||||||
interface IrDeclarationGenerator : IrGenerator {
|
interface IrDeclarationGenerator : IrGenerator
|
||||||
val irDeclaration: IrDeclaration
|
|
||||||
val parent: IrDeclarationGenerator?
|
|
||||||
}
|
|
||||||
|
|
||||||
abstract class IrDeclarationGeneratorBase(
|
abstract class IrDeclarationGeneratorBase(
|
||||||
override val context: IrGeneratorContext,
|
override val context: IrGeneratorContext,
|
||||||
override val irDeclaration: IrDeclaration,
|
val container: IrDeclarationOwnerN,
|
||||||
override val parent: IrDeclarationGenerator,
|
val declarationFactory: IrDeclarationFactoryBase
|
||||||
val declarationFactory: IrDeclarationFactory
|
|
||||||
) : IrDeclarationGenerator {
|
) : IrDeclarationGenerator {
|
||||||
val irExpressionGenerator = IrExpressionGenerator(context, declarationFactory)
|
private fun <D : IrMemberDeclaration> D.register(): D =
|
||||||
|
apply { container.addChildDeclaration(this) }
|
||||||
val containingDeclaration: IrCompoundDeclaration get() = declarationFactory.containingDeclaration
|
|
||||||
|
|
||||||
fun generateAnnotationEntries(annotationEntries: List<KtAnnotationEntry>) {
|
fun generateAnnotationEntries(annotationEntries: List<KtAnnotationEntry>) {
|
||||||
// TODO create IrAnnotation's for each KtAnnotationEntry
|
// TODO create IrAnnotation's for each KtAnnotationEntry
|
||||||
@@ -64,26 +60,26 @@ abstract class IrDeclarationGeneratorBase(
|
|||||||
|
|
||||||
fun generateFunctionDeclaration(ktNamedFunction: KtNamedFunction) {
|
fun generateFunctionDeclaration(ktNamedFunction: KtNamedFunction) {
|
||||||
val functionDescriptor = getOrFail(BindingContext.FUNCTION, ktNamedFunction) { "unresolved fun" }
|
val functionDescriptor = getOrFail(BindingContext.FUNCTION, ktNamedFunction) { "unresolved fun" }
|
||||||
val body = generateExpressionBody(ktNamedFunction.bodyExpression ?: TODO("function without body expression"))
|
val body = generateExpressionBody(functionDescriptor, ktNamedFunction.bodyExpression ?: TODO("function without body expression"))
|
||||||
declarationFactory.createFunction(ktNamedFunction, functionDescriptor, body)
|
declarationFactory.createFunction(ktNamedFunction, functionDescriptor, body).register()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun generatePropertyDeclaration(ktProperty: KtProperty) {
|
fun generatePropertyDeclaration(ktProperty: KtProperty) {
|
||||||
val propertyDescriptor = getPropertyDescriptor(ktProperty)
|
val propertyDescriptor = getPropertyDescriptor(ktProperty)
|
||||||
if (ktProperty.hasDelegate()) TODO("handle delegated property")
|
if (ktProperty.hasDelegate()) TODO("handle delegated property")
|
||||||
val initializer = ktProperty.initializer?.let { generateExpressionBody(it) }
|
val initializer = ktProperty.initializer?.let { generateExpressionBody(propertyDescriptor, it) }
|
||||||
val irProperty = declarationFactory.createSimpleProperty(ktProperty, propertyDescriptor, initializer)
|
val irProperty = declarationFactory.createSimpleProperty(ktProperty, propertyDescriptor, initializer).register()
|
||||||
ktProperty.getter?.let { ktGetter ->
|
ktProperty.getter?.let { ktGetter ->
|
||||||
val accessorDescriptor = getOrFail(BindingContext.PROPERTY_ACCESSOR, ktGetter) { "unresolved getter" }
|
val accessorDescriptor = getOrFail(BindingContext.PROPERTY_ACCESSOR, ktGetter) { "unresolved getter" }
|
||||||
val getterDescriptor = accessorDescriptor as? PropertyGetterDescriptor ?: TODO("not a getter?")
|
val getterDescriptor = accessorDescriptor as? PropertyGetterDescriptor ?: TODO("not a getter?")
|
||||||
val getterBody = generateExpressionBody(ktGetter.bodyExpression ?: TODO("default getter"))
|
val getterBody = generateExpressionBody(getterDescriptor, ktGetter.bodyExpression ?: TODO("default getter"))
|
||||||
declarationFactory.createPropertyGetter(ktGetter, irProperty, getterDescriptor, getterBody)
|
declarationFactory.createPropertyGetter(ktGetter, irProperty, getterDescriptor, getterBody).register()
|
||||||
}
|
}
|
||||||
ktProperty.setter?.let { ktSetter ->
|
ktProperty.setter?.let { ktSetter ->
|
||||||
val accessorDescriptor = getOrFail(BindingContext.PROPERTY_ACCESSOR, ktSetter) { "unresolved setter" }
|
val accessorDescriptor = getOrFail(BindingContext.PROPERTY_ACCESSOR, ktSetter) { "unresolved setter" }
|
||||||
val setterDescriptor = accessorDescriptor as? PropertySetterDescriptor ?: TODO("not a setter?")
|
val setterDescriptor = accessorDescriptor as? PropertySetterDescriptor ?: TODO("not a setter?")
|
||||||
val setterBody = generateExpressionBody(ktSetter.bodyExpression ?: TODO("default setter"))
|
val setterBody = generateExpressionBody(setterDescriptor, ktSetter.bodyExpression ?: TODO("default setter"))
|
||||||
declarationFactory.createPropertySetter(ktSetter, irProperty, setterDescriptor, setterBody)
|
declarationFactory.createPropertySetter(ktSetter, irProperty, setterDescriptor, setterBody).register()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -93,19 +89,8 @@ abstract class IrDeclarationGeneratorBase(
|
|||||||
return propertyDescriptor
|
return propertyDescriptor
|
||||||
}
|
}
|
||||||
|
|
||||||
fun generateExpressionBody(ktBody: KtExpression): IrBody {
|
fun generateExpressionBody(scopeOwner: DeclarationDescriptor, ktBody: KtExpression): IrBody =
|
||||||
val irExpression = irExpressionGenerator.generateExpression(ktBody)
|
IrExpressionBodyImpl(ktBody.startOffset, ktBody.endOffset).apply {
|
||||||
|
argument = IrExpressionGenerator(context, IrLocalDeclarationsFactory(scopeOwner)).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 }
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
@@ -16,66 +16,64 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.psi2ir
|
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.ir.expressions.*
|
||||||
import org.jetbrains.kotlin.psi.*
|
import org.jetbrains.kotlin.psi.*
|
||||||
import org.jetbrains.kotlin.psi.psiUtil.endOffset
|
import org.jetbrains.kotlin.psi.psiUtil.endOffset
|
||||||
import org.jetbrains.kotlin.psi.psiUtil.startOffset
|
import org.jetbrains.kotlin.psi.psiUtil.startOffset
|
||||||
import org.jetbrains.kotlin.resolve.BindingContext
|
import org.jetbrains.kotlin.resolve.BindingContext
|
||||||
import org.jetbrains.kotlin.resolve.DescriptorUtils
|
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.calls.model.VariableAsFunctionResolvedCall
|
||||||
import org.jetbrains.kotlin.resolve.constants.IntValue
|
import org.jetbrains.kotlin.resolve.constants.IntValue
|
||||||
import org.jetbrains.kotlin.resolve.constants.StringValue
|
import org.jetbrains.kotlin.resolve.constants.StringValue
|
||||||
import org.jetbrains.kotlin.resolve.constants.evaluate.ConstantExpressionEvaluator
|
import org.jetbrains.kotlin.resolve.constants.evaluate.ConstantExpressionEvaluator
|
||||||
import org.jetbrains.kotlin.resolve.scopes.receivers.*
|
|
||||||
|
|
||||||
class IrExpressionGenerator(
|
class IrExpressionGenerator(
|
||||||
override val context: IrGeneratorContext,
|
override val context: IrGeneratorContext,
|
||||||
val declarationFactory: IrDeclarationFactory
|
val declarationFactory: IrLocalDeclarationsFactory
|
||||||
) : KtVisitor<IrExpression, Nothing?>(), IrGenerator {
|
) : KtVisitor<IrExpression, Nothing?>(), IrGenerator {
|
||||||
|
private val irCallGenerator = IrCallGenerator(context, this)
|
||||||
|
|
||||||
fun generateExpression(ktExpression: KtExpression) = ktExpression.generate()
|
fun generateExpression(ktExpression: KtExpression) = ktExpression.generate()
|
||||||
|
|
||||||
private fun KtElement.generate(): IrExpression =
|
private fun KtElement.generate(): IrExpression =
|
||||||
deparenthesize()
|
deparenthesize()
|
||||||
.accept(this@IrExpressionGenerator, null)
|
.accept(this@IrExpressionGenerator, null)
|
||||||
.smartCastIfNeeded(this)
|
.applySmartCastIfNeeded(this)
|
||||||
|
|
||||||
private fun KtExpression.type() =
|
private fun IrExpression.applySmartCastIfNeeded(ktElement: KtElement): IrExpression {
|
||||||
getType(this) ?: TODO("no type for expression")
|
|
||||||
|
|
||||||
private fun IrExpression.smartCastIfNeeded(ktElement: KtElement): IrExpression {
|
|
||||||
if (ktElement is KtExpression) {
|
if (ktElement is KtExpression) {
|
||||||
val smartCastType = get(BindingContext.SMARTCAST, ktElement)
|
val smartCastType = get(BindingContext.SMARTCAST, ktElement)
|
||||||
if (smartCastType != null) {
|
if (smartCastType != null) {
|
||||||
return IrTypeOperatorExpressionImpl(
|
return IrTypeOperatorExpressionImpl(
|
||||||
ktElement.startOffset, ktElement.endOffset, smartCastType,
|
ktElement.startOffset, ktElement.endOffset, smartCastType,
|
||||||
IrTypeOperator.SMART_AS, smartCastType
|
IrTypeOperator.SMART_AS, smartCastType
|
||||||
).apply { argument = this@smartCastIfNeeded }
|
).apply { argument = this@applySmartCastIfNeeded }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return this
|
return this
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun visitExpression(expression: KtExpression, data: Nothing?): IrExpression =
|
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 {
|
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()) }
|
expression.statements.forEach { irBlock.addChildExpression(it.generate()) }
|
||||||
return irBlock
|
return irBlock
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun visitReturnExpression(expression: KtReturnExpression, data: Nothing?): IrExpression =
|
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() }
|
.apply { this.argument = expression.returnedExpression?.generate() }
|
||||||
|
|
||||||
override fun visitConstantExpression(expression: KtConstantExpression, data: Nothing?): IrExpression {
|
override fun visitConstantExpression(expression: KtConstantExpression, data: Nothing?): IrExpression {
|
||||||
val compileTimeConstant = ConstantExpressionEvaluator.getConstant(expression, context.bindingContext)
|
val compileTimeConstant = ConstantExpressionEvaluator.getConstant(expression, context.bindingContext)
|
||||||
?: error("KtConstantExpression was not evaluated: ${expression.text}")
|
?: error("KtConstantExpression was not evaluated: ${expression.text}")
|
||||||
val constantValue = compileTimeConstant.toConstantValue(expression.type())
|
val constantValue = compileTimeConstant.toConstantValue(getTypeOrFail(expression))
|
||||||
val constantType = constantValue.type
|
val constantType = constantValue.type
|
||||||
|
|
||||||
return when (constantValue) {
|
return when (constantValue) {
|
||||||
@@ -93,7 +91,7 @@ class IrExpressionGenerator(
|
|||||||
return expression.entries[0].generate()
|
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()) }
|
expression.entries.forEach { irStringTemplate.addChildExpression(it.generate()) }
|
||||||
return irStringTemplate
|
return irStringTemplate
|
||||||
}
|
}
|
||||||
@@ -108,24 +106,24 @@ class IrExpressionGenerator(
|
|||||||
TODO("Unexpected VariableAsFunctionResolvedCall")
|
TODO("Unexpected VariableAsFunctionResolvedCall")
|
||||||
}
|
}
|
||||||
|
|
||||||
val descriptor = resolvedCall?.resultingDescriptor ?: get(BindingContext.REFERENCE_TARGET, expression)
|
val descriptor = resolvedCall?.resultingDescriptor
|
||||||
|
|
||||||
return when (descriptor) {
|
return when (descriptor) {
|
||||||
is ClassDescriptor ->
|
is ClassDescriptor ->
|
||||||
if (DescriptorUtils.isObject(descriptor))
|
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))
|
else if (DescriptorUtils.isEnumEntry(descriptor))
|
||||||
IrGetEnumValueExpressionImpl(expression.startOffset, expression.endOffset, expression.type(), descriptor)
|
IrGetEnumValueExpressionImpl(expression.startOffset, expression.endOffset, getTypeOrFail(expression), descriptor)
|
||||||
else
|
else
|
||||||
IrGetObjectValueExpressionImpl(expression.startOffset, expression.endOffset, expression.type(),
|
IrGetObjectValueExpressionImpl(expression.startOffset, expression.endOffset, getTypeOrFail(expression),
|
||||||
descriptor.companionObjectDescriptor ?: error("Class value without companion object: $descriptor"))
|
descriptor.companionObjectDescriptor ?: error("Class value without companion object: $descriptor"))
|
||||||
is PropertyDescriptor -> {
|
is PropertyDescriptor -> {
|
||||||
generateCall(expression, resolvedCall ?: TODO("Property, no resolved call: ${descriptor.name}"), null)
|
irCallGenerator.generateCall(expression, resolvedCall)
|
||||||
}
|
}
|
||||||
is VariableDescriptor ->
|
is VariableDescriptor ->
|
||||||
IrGetVariableExpressionImpl(expression.startOffset, expression.endOffset, expression.type(), descriptor)
|
IrGetVariableExpressionImpl(expression.startOffset, expression.endOffset, getTypeOrFail(expression), descriptor)
|
||||||
else ->
|
else ->
|
||||||
IrDummyExpression(expression.startOffset, expression.endOffset, expression.type(),
|
IrDummyExpression(expression.startOffset, expression.endOffset, getTypeOrFail(expression),
|
||||||
expression.getReferencedName() +
|
expression.getReferencedName() +
|
||||||
": ${descriptor?.name} ${descriptor?.javaClass?.simpleName}")
|
": ${descriptor?.name} ${descriptor?.javaClass?.simpleName}")
|
||||||
}
|
}
|
||||||
@@ -138,7 +136,7 @@ class IrExpressionGenerator(
|
|||||||
TODO("VariableAsFunctionResolvedCall = variable call + invoke call")
|
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 =
|
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" }
|
val referenceTarget = getOrFail(BindingContext.REFERENCE_TARGET, expression.instanceReference) { "No reference target for this" }
|
||||||
return when (referenceTarget) {
|
return when (referenceTarget) {
|
||||||
is ClassDescriptor ->
|
is ClassDescriptor ->
|
||||||
IrThisExpressionImpl(expression.startOffset, expression.endOffset, expression.type(), referenceTarget)
|
IrThisExpressionImpl(expression.startOffset, expression.endOffset, getTypeOrFail(expression), referenceTarget)
|
||||||
is CallableDescriptor ->
|
is CallableDescriptor ->
|
||||||
IrGetExtensionReceiverExpressionImpl(expression.startOffset, expression.endOffset, expression.type(),
|
IrGetExtensionReceiverExpressionImpl(
|
||||||
referenceTarget.extensionReceiverParameter!!)
|
expression.startOffset, expression.endOffset, getTypeOrFail(expression),
|
||||||
|
referenceTarget.extensionReceiverParameter!!
|
||||||
|
)
|
||||||
else ->
|
else ->
|
||||||
error("Expected this or receiver: $referenceTarget")
|
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
|
package org.jetbrains.kotlin.psi2ir
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.ir.declarations.IrFile
|
||||||
import org.jetbrains.kotlin.ir.declarations.IrFileImpl
|
import org.jetbrains.kotlin.ir.declarations.IrFileImpl
|
||||||
import org.jetbrains.kotlin.psi.KtFile
|
import org.jetbrains.kotlin.psi.KtFile
|
||||||
|
|
||||||
class IrFileGenerator(
|
class IrFileGenerator(
|
||||||
private val ktFile: KtFile,
|
private val ktFile: KtFile,
|
||||||
context: IrGeneratorContext,
|
context: IrGeneratorContext,
|
||||||
irDeclaration: IrFileImpl,
|
irFile: IrFile,
|
||||||
parent: IrModuleGenerator,
|
parent: IrModuleGenerator,
|
||||||
declarationFactory: IrDeclarationFactory
|
declarationFactory: IrDeclarationFactory
|
||||||
) : IrDeclarationGeneratorBase(context, irDeclaration, parent, declarationFactory) {
|
) : IrDeclarationGeneratorBase(context, irFile, declarationFactory) {
|
||||||
fun generateFileContent() {
|
fun generateFileContent() {
|
||||||
generateAnnotationEntries(ktFile.annotationEntries)
|
generateAnnotationEntries(ktFile.annotationEntries)
|
||||||
|
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ package org.jetbrains.kotlin.psi2ir
|
|||||||
|
|
||||||
import org.jetbrains.kotlin.descriptors.CallableDescriptor
|
import org.jetbrains.kotlin.descriptors.CallableDescriptor
|
||||||
import org.jetbrains.kotlin.psi.KtExpression
|
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.callUtil.getResolvedCall
|
||||||
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
|
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
|
||||||
import org.jetbrains.kotlin.types.KotlinType
|
import org.jetbrains.kotlin.types.KotlinType
|
||||||
@@ -30,12 +31,18 @@ interface IrGenerator {
|
|||||||
fun IrGenerator.getType(key: KtExpression): KotlinType? =
|
fun IrGenerator.getType(key: KtExpression): KotlinType? =
|
||||||
context.bindingContext.getType(key)
|
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? =
|
fun <K, V : Any> IrGenerator.get(slice: ReadOnlySlice<K, V>, key: K): V? =
|
||||||
context.bindingContext[slice, key]
|
context.bindingContext[slice, key]
|
||||||
|
|
||||||
inline fun <K, V : Any> IrGenerator.getOrFail(slice: ReadOnlySlice<K, V>, key: K, message: (K) -> String): V =
|
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))
|
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 =
|
inline fun <K, V : Any> IrGenerator.getOrElse(slice: ReadOnlySlice<K, V>, key: K, otherwise: (K) -> V): V =
|
||||||
context.bindingContext[slice, key] ?: otherwise(key)
|
context.bindingContext[slice, key] ?: otherwise(key)
|
||||||
|
|
||||||
|
|||||||
@@ -16,19 +16,19 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.psi2ir
|
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
|
import org.jetbrains.kotlin.resolve.BindingContext
|
||||||
|
|
||||||
class IrModuleGenerator(override val context: IrGeneratorContext) : IrDeclarationGenerator {
|
class IrModuleGenerator(override val context: IrGeneratorContext) : IrDeclarationGenerator {
|
||||||
override val irDeclaration: IrModule get() = context.irModule
|
|
||||||
override val parent: IrDeclarationGenerator? get() = null
|
|
||||||
|
|
||||||
fun generateModuleContent() {
|
fun generateModuleContent() {
|
||||||
for (ktFile in context.inputFiles) {
|
for (ktFile in context.inputFiles) {
|
||||||
val packageFragmentDescriptor = getOrFail(BindingContext.FILE_TO_PACKAGE_FRAGMENT, ktFile) { "no package fragment for file" }
|
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 fileEntry = context.sourceManager.getOrCreateFileEntry(ktFile)
|
||||||
val irFile = irFileElementFactory.irFileImpl
|
val fileName = fileEntry.getRecognizableName()
|
||||||
|
val irFile = IrFileImpl(fileEntry, fileName, packageFragmentDescriptor)
|
||||||
|
context.sourceManager.putFileEntry(irFile, fileEntry)
|
||||||
context.irModule.addFile(irFile)
|
context.irModule.addFile(irFile)
|
||||||
|
val irFileElementFactory = IrDeclarationFactory()
|
||||||
val generator = IrFileGenerator(ktFile, context, irFile, this, irFileElementFactory)
|
val generator = IrFileGenerator(ktFile, context, irFile, this, irFileElementFactory)
|
||||||
generator.generateFileContent()
|
generator.generateFileContent()
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-1
@@ -14,8 +14,9 @@
|
|||||||
* limitations under the License.
|
* 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 DETACHED_INDEX = Int.MIN_VALUE
|
||||||
const val CHILD_EXPRESSION_INDEX = 0
|
const val CHILD_EXPRESSION_INDEX = 0
|
||||||
const val ARGUMENT0_INDEX = 0
|
const val ARGUMENT0_INDEX = 0
|
||||||
+18
-11
@@ -16,36 +16,43 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.ir.declarations
|
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.IrElement
|
||||||
import org.jetbrains.kotlin.ir.IrElementBase
|
import org.jetbrains.kotlin.ir.IrElementBase
|
||||||
|
import org.jetbrains.kotlin.ir.DETACHED_INDEX
|
||||||
import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
|
import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
|
||||||
interface IrDeclarationOwner : IrElement {
|
interface IrDeclarationOwner : IrElement {
|
||||||
val childrenCount: Int
|
|
||||||
fun getChildDeclaration(index: Int): IrMemberDeclaration?
|
fun getChildDeclaration(index: Int): IrMemberDeclaration?
|
||||||
fun addChildDeclaration(child: IrMemberDeclaration)
|
|
||||||
fun replaceChildDeclaration(oldChild: IrMemberDeclaration, newChild: 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 removeChildDeclaration(child: IrMemberDeclaration)
|
||||||
|
fun removeAllChildDeclarations()
|
||||||
|
|
||||||
fun <D> acceptChildDeclarations(visitor: IrElementVisitor<Unit, D>, data: D)
|
fun <D> acceptChildDeclarations(visitor: IrElementVisitor<Unit, D>, data: D)
|
||||||
}
|
}
|
||||||
|
|
||||||
interface IrCompoundDeclaration : IrDeclaration, IrDeclarationOwner
|
interface IrCompoundDeclaration : IrDeclaration, IrDeclarationOwnerN
|
||||||
|
|
||||||
interface IrMemberDeclaration : IrDeclaration {
|
interface IrMemberDeclaration : IrDeclaration {
|
||||||
override val parent: IrDeclarationOwner
|
override var parent: IrDeclarationOwner?
|
||||||
|
|
||||||
fun setTreeLocation(parent: IrDeclarationOwner?, index: Int)
|
fun setTreeLocation(parent: IrDeclarationOwner?, index: Int)
|
||||||
}
|
}
|
||||||
|
|
||||||
abstract class IrDeclarationOwnerBase(
|
abstract class IrDeclarationOwnerNBase(
|
||||||
startOffset: Int,
|
startOffset: Int,
|
||||||
endOffset: Int
|
endOffset: Int
|
||||||
) : IrElementBase(startOffset, endOffset), IrDeclarationOwner {
|
) : IrElementBase(startOffset, endOffset), IrDeclarationOwnerN {
|
||||||
protected val childDeclarations: MutableList<IrMemberDeclaration> = ArrayList()
|
protected val childDeclarations: MutableList<IrMemberDeclaration> = ArrayList()
|
||||||
|
|
||||||
override val childrenCount: Int
|
override val childrenCount: Int
|
||||||
@@ -90,7 +97,7 @@ abstract class IrCompoundDeclarationBase(
|
|||||||
startOffset: Int,
|
startOffset: Int,
|
||||||
endOffset: Int,
|
endOffset: Int,
|
||||||
override val originKind: IrDeclarationOriginKind
|
override val originKind: IrDeclarationOriginKind
|
||||||
) : IrDeclarationOwnerBase(startOffset, endOffset), IrCompoundDeclaration {
|
) : IrDeclarationOwnerNBase(startOffset, endOffset), IrCompoundDeclaration {
|
||||||
override var indexInParent: Int = IrDeclaration.DETACHED_INDEX
|
override var indexInParent: Int = IrDeclaration.DETACHED_INDEX
|
||||||
|
|
||||||
override fun <D> acceptChildren(visitor: IrElementVisitor<Unit, D>, data: D) {
|
override fun <D> acceptChildren(visitor: IrElementVisitor<Unit, D>, data: D) {
|
||||||
@@ -105,7 +112,7 @@ abstract class IrCompoundMemberDeclarationBase(
|
|||||||
) : IrCompoundDeclarationBase(startOffset, endOffset, originKind), IrMemberDeclaration {
|
) : IrCompoundDeclarationBase(startOffset, endOffset, originKind), IrMemberDeclaration {
|
||||||
private var parentImpl: IrDeclarationOwner? = null
|
private var parentImpl: IrDeclarationOwner? = null
|
||||||
|
|
||||||
override var parent: IrDeclarationOwner
|
override var parent: IrDeclarationOwner?
|
||||||
get() = parentImpl!!
|
get() = parentImpl!!
|
||||||
set(newParent) {
|
set(newParent) {
|
||||||
parentImpl = newParent
|
parentImpl = newParent
|
||||||
@@ -124,7 +131,7 @@ abstract class IrMemberDeclarationBase(
|
|||||||
) : IrDeclarationBase(startOffset, endOffset, originKind), IrMemberDeclaration {
|
) : IrDeclarationBase(startOffset, endOffset, originKind), IrMemberDeclaration {
|
||||||
private var parentImpl: IrDeclarationOwner? = null
|
private var parentImpl: IrDeclarationOwner? = null
|
||||||
|
|
||||||
override var parent: IrDeclarationOwner
|
override var parent: IrDeclarationOwner?
|
||||||
get() = parentImpl!!
|
get() = parentImpl!!
|
||||||
set(newParent) {
|
set(newParent) {
|
||||||
parentImpl = newParent
|
parentImpl = newParent
|
||||||
|
|||||||
@@ -38,15 +38,16 @@ enum class IrDeclarationKind {
|
|||||||
MODULE,
|
MODULE,
|
||||||
FILE,
|
FILE,
|
||||||
FUNCTION,
|
FUNCTION,
|
||||||
PROPERTY,
|
|
||||||
PROPERTY_GETTER,
|
PROPERTY_GETTER,
|
||||||
PROPERTY_SETTER,
|
PROPERTY_SETTER,
|
||||||
|
PROPERTY,
|
||||||
|
LOCAL_VARIABLE,
|
||||||
CLASS
|
CLASS
|
||||||
}
|
}
|
||||||
|
|
||||||
enum class IrDeclarationOriginKind {
|
enum class IrDeclarationOriginKind {
|
||||||
DEFINED,
|
DEFINED,
|
||||||
DEFAULT_PROPERTY_ACCESSOR,
|
IR_TEMPORARY_VARIABLE,
|
||||||
}
|
}
|
||||||
|
|
||||||
abstract class IrDeclarationBase(
|
abstract class IrDeclarationBase(
|
||||||
|
|||||||
@@ -45,6 +45,10 @@ class IrFunctionImpl(
|
|||||||
override val descriptor: FunctionDescriptor,
|
override val descriptor: FunctionDescriptor,
|
||||||
override val body: IrBody
|
override val body: IrBody
|
||||||
) : IrFunctionBase(startOffset, endOffset, originKind) {
|
) : IrFunctionBase(startOffset, endOffset, originKind) {
|
||||||
|
init {
|
||||||
|
body.parent = this
|
||||||
|
}
|
||||||
|
|
||||||
override fun <R, D> accept(visitor: IrElementVisitor<R, D>, data: D): R =
|
override fun <R, D> accept(visitor: IrElementVisitor<R, D>, data: D): R =
|
||||||
visitor.visitFunction(this, data)
|
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,
|
descriptor: PropertyDescriptor,
|
||||||
override val valueInitializer: IrBody?
|
override val valueInitializer: IrBody?
|
||||||
) : IrPropertyBase(startOffset, endOffset, originKind, descriptor), IrSimpleProperty {
|
) : IrPropertyBase(startOffset, endOffset, originKind, descriptor), IrSimpleProperty {
|
||||||
|
init {
|
||||||
|
valueInitializer?.parent = this
|
||||||
|
}
|
||||||
|
|
||||||
override fun <R, D> accept(visitor: IrElementVisitor<R, D>, data: D): R =
|
override fun <R, D> accept(visitor: IrElementVisitor<R, D>, data: D): R =
|
||||||
visitor.visitSimpleProperty(this, data)
|
visitor.visitSimpleProperty(this, data)
|
||||||
|
|
||||||
|
|||||||
@@ -47,6 +47,10 @@ abstract class IrPropertyAccessorBase(
|
|||||||
originKind: IrDeclarationOriginKind,
|
originKind: IrDeclarationOriginKind,
|
||||||
override val body: IrBody
|
override val body: IrBody
|
||||||
) : IrFunctionBase(startOffset, endOffset, originKind), IrPropertyAccessor {
|
) : IrFunctionBase(startOffset, endOffset, originKind), IrPropertyAccessor {
|
||||||
|
init {
|
||||||
|
body.parent = this
|
||||||
|
}
|
||||||
|
|
||||||
override var property: IrProperty? = null
|
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
|
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.IrElement
|
||||||
|
import org.jetbrains.kotlin.ir.IrElementBase
|
||||||
import org.jetbrains.kotlin.ir.declarations.IrDeclaration
|
import org.jetbrains.kotlin.ir.declarations.IrDeclaration
|
||||||
import org.jetbrains.kotlin.ir.declarations.IrDeclarationOwner
|
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
|
import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
|
||||||
|
|
||||||
interface IrBody : IrElement {
|
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?
|
// TODO IrExpressionBodyImpl vs IrCompoundExpression1Impl: extract common base class?
|
||||||
class IrExpressionBodyImpl(
|
class IrExpressionBodyImpl(
|
||||||
startOffset: Int,
|
startOffset: Int,
|
||||||
endOffset: Int,
|
endOffset: Int
|
||||||
override val parent: IrDeclaration
|
) : IrElementBase(startOffset, endOffset), IrExpressionBody {
|
||||||
) : IrDeclarationOwnerBase(startOffset, endOffset), IrExpressionBody {
|
override lateinit var parent: IrDeclaration
|
||||||
|
|
||||||
override var argument: IrExpression? = null
|
override var argument: IrExpression? = null
|
||||||
set(newExpression) {
|
set(newExpression) {
|
||||||
field?.detach()
|
field?.detach()
|
||||||
|
|||||||
@@ -18,7 +18,8 @@ package org.jetbrains.kotlin.ir.expressions
|
|||||||
|
|
||||||
import org.jetbrains.kotlin.descriptors.CallableDescriptor
|
import org.jetbrains.kotlin.descriptors.CallableDescriptor
|
||||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
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.ir.visitors.IrElementVisitor
|
||||||
import org.jetbrains.kotlin.types.KotlinType
|
import org.jetbrains.kotlin.types.KotlinType
|
||||||
|
|
||||||
@@ -27,16 +28,13 @@ interface IrCallExpression : IrMemberAccessExpression, IrCompoundExpression {
|
|||||||
val operator: IrOperator?
|
val operator: IrOperator?
|
||||||
override val descriptor: CallableDescriptor
|
override val descriptor: CallableDescriptor
|
||||||
|
|
||||||
fun getValueArgument(valueParameterDescriptor: ValueParameterDescriptor): IrExpression?
|
fun getValueArgument(index: Int): IrExpression?
|
||||||
fun putValueArgument(valueParameterDescriptor: ValueParameterDescriptor, valueArgument: IrExpression?)
|
fun putValueArgument(index: Int, valueArgument: IrExpression?)
|
||||||
fun removeValueArgument(valueParameterDescriptor: ValueParameterDescriptor)
|
fun removeValueArgument(index: Int)
|
||||||
|
|
||||||
fun <D> acceptValueArguments(visitor: IrElementVisitor<Unit, D>, data: D)
|
fun <D> acceptValueArguments(visitor: IrElementVisitor<Unit, D>, data: D)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun IrCallExpression.getMappedValueArguments(): List<IrExpression?> =
|
|
||||||
descriptor.valueParameters.mapNotNull { getValueArgument(it) }
|
|
||||||
|
|
||||||
class IrCallExpressionImpl(
|
class IrCallExpressionImpl(
|
||||||
startOffset: Int,
|
startOffset: Int,
|
||||||
endOffset: Int,
|
endOffset: Int,
|
||||||
@@ -49,22 +47,18 @@ class IrCallExpressionImpl(
|
|||||||
private val argumentsByParameterIndex =
|
private val argumentsByParameterIndex =
|
||||||
kotlin.arrayOfNulls<IrExpression>(descriptor.valueParameters.size)
|
kotlin.arrayOfNulls<IrExpression>(descriptor.valueParameters.size)
|
||||||
|
|
||||||
override fun getValueArgument(valueParameterDescriptor: ValueParameterDescriptor): IrExpression? =
|
override fun getValueArgument(index: Int): IrExpression? =
|
||||||
argumentsByParameterIndex[valueParameterDescriptor.index]
|
argumentsByParameterIndex[index]
|
||||||
|
|
||||||
override fun putValueArgument(valueParameterDescriptor: ValueParameterDescriptor, valueArgument: IrExpression?) {
|
override fun putValueArgument(index: Int, valueArgument: IrExpression?) {
|
||||||
putValueArgument(valueParameterDescriptor.index, valueArgument)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun putValueArgument(index: Int, valueArgument: IrExpression?) {
|
|
||||||
argumentsByParameterIndex[index]?.detach()
|
argumentsByParameterIndex[index]?.detach()
|
||||||
argumentsByParameterIndex[index] = valueArgument
|
argumentsByParameterIndex[index] = valueArgument
|
||||||
valueArgument?.setTreeLocation(this, index)
|
valueArgument?.setTreeLocation(this, index)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun removeValueArgument(valueParameterDescriptor: ValueParameterDescriptor) {
|
override fun removeValueArgument(index: Int) {
|
||||||
argumentsByParameterIndex[valueParameterDescriptor.index]?.detach()
|
argumentsByParameterIndex[index]?.detach()
|
||||||
argumentsByParameterIndex[valueParameterDescriptor.index] = null
|
argumentsByParameterIndex[index] = null
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getChildExpression(index: Int): IrExpression? =
|
override fun getChildExpression(index: Int): IrExpression? =
|
||||||
|
|||||||
@@ -16,6 +16,8 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.ir.expressions
|
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.ir.visitors.IrElementVisitor
|
||||||
import org.jetbrains.kotlin.types.KotlinType
|
import org.jetbrains.kotlin.types.KotlinType
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
|||||||
@@ -16,6 +16,7 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.ir.expressions
|
package org.jetbrains.kotlin.ir.expressions
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.ir.DETACHED_INDEX
|
||||||
import org.jetbrains.kotlin.ir.IrElement
|
import org.jetbrains.kotlin.ir.IrElement
|
||||||
import org.jetbrains.kotlin.ir.IrElementBase
|
import org.jetbrains.kotlin.ir.IrElementBase
|
||||||
import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
|
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
|
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
|
import org.jetbrains.kotlin.types.KotlinType
|
||||||
|
|
||||||
interface IrMemberAccessExpression : IrDeclarationReference, IrExpressionOwner {
|
interface IrMemberAccessExpression : IrDeclarationReference, IrExpressionOwner {
|
||||||
|
|||||||
@@ -17,11 +17,12 @@
|
|||||||
package org.jetbrains.kotlin.ir.expressions
|
package org.jetbrains.kotlin.ir.expressions
|
||||||
|
|
||||||
enum class IrOperator {
|
enum class IrOperator {
|
||||||
INVOKE, INVOKE_EXTENSION,
|
INVOKE,
|
||||||
PREFIX_INCR, PREFIX_DECR, POSTFIX_INCR, POSTFIX_DECR,
|
PREFIX_INCR, PREFIX_DECR, POSTFIX_INCR, POSTFIX_DECR,
|
||||||
UMINUS,
|
UMINUS,
|
||||||
EXCL,
|
EXCL,
|
||||||
EXCLEXCL,
|
EXCLEXCL,
|
||||||
|
ELVIS,
|
||||||
LT, GT, LTEQ, GTEQ,
|
LT, GT, LTEQ, GTEQ,
|
||||||
EQEQ, EQEQEQ, EXCLEQ, EXCLEQEQ,
|
EQEQ, EQEQEQ, EXCLEQ, EXCLEQEQ,
|
||||||
IN, NOT_IN,
|
IN, NOT_IN,
|
||||||
@@ -32,32 +33,36 @@ enum class IrOperator {
|
|||||||
PLUSEQ, MINUSEQ, MULEQ, DIVEQ, MODEQ;
|
PLUSEQ, MINUSEQ, MULEQ, DIVEQ, MODEQ;
|
||||||
}
|
}
|
||||||
|
|
||||||
private val CAO_START = IrOperator.PLUSEQ
|
private val CAO_START = IrOperator.PLUSEQ.ordinal
|
||||||
private val CAO_END = IrOperator.MODEQ
|
private val CAO_END = IrOperator.MODEQ.ordinal
|
||||||
private val DUAL_START = IrOperator.PLUS
|
private val DUAL_START = IrOperator.PLUS.ordinal
|
||||||
private val DUAL_END = IrOperator.MOD
|
private val DUAL_END = IrOperator.MOD.ordinal
|
||||||
private val INCR_DECR_START = IrOperator.PREFIX_INCR
|
private val INCR_DECR_START = IrOperator.PREFIX_INCR.ordinal
|
||||||
private val INCR_DECR_END = IrOperator.POSTFIX_DECR
|
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 =
|
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 =
|
fun IrOperator.isCompoundAssignment(): Boolean =
|
||||||
this in CAO_START .. CAO_END
|
this.ordinal in CAO_START .. CAO_END
|
||||||
|
|
||||||
fun IrOperator.isAssignmentOrCompoundAssignment(): Boolean =
|
fun IrOperator.isAssignmentOrCompoundAssignment(): Boolean =
|
||||||
this == IrOperator.EQ || isCompoundAssignment()
|
this == IrOperator.EQ || isCompoundAssignment()
|
||||||
|
|
||||||
fun IrOperator.hasCompoundAssignmentDual(): Boolean =
|
fun IrOperator.hasCompoundAssignmentDual(): Boolean =
|
||||||
this in DUAL_START .. DUAL_END
|
this.ordinal in DUAL_START .. DUAL_END
|
||||||
|
|
||||||
fun IrOperator.toDualOperator(): IrOperator =
|
fun IrOperator.toDualOperator(): IrOperator =
|
||||||
when {
|
when {
|
||||||
isCompoundAssignment() ->
|
isCompoundAssignment() ->
|
||||||
IrOperator.values()[this.ordinal - CAO_START.ordinal + DUAL_START.ordinal]
|
IrOperator.values()[this.ordinal - CAO_START + DUAL_START]
|
||||||
hasCompoundAssignmentDual() ->
|
hasCompoundAssignmentDual() ->
|
||||||
IrOperator.values()[this.ordinal - DUAL_START.ordinal + CAO_START.ordinal]
|
IrOperator.values()[this.ordinal - DUAL_START + CAO_START]
|
||||||
else ->
|
else ->
|
||||||
throw UnsupportedOperationException("Operator $this is not a compound assignment")
|
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
|
package org.jetbrains.kotlin.ir.expressions
|
||||||
|
|
||||||
import org.jetbrains.kotlin.descriptors.PropertyDescriptor
|
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.ir.visitors.IrElementVisitor
|
||||||
import org.jetbrains.kotlin.types.KotlinType
|
import org.jetbrains.kotlin.types.KotlinType
|
||||||
|
|
||||||
|
|||||||
@@ -50,7 +50,7 @@ class DumpIrTreeVisitor(out: Appendable): IrElementVisitor<Unit, String> {
|
|||||||
expression.dispatchReceiver?.accept(this, "\$this")
|
expression.dispatchReceiver?.accept(this, "\$this")
|
||||||
expression.extensionReceiver?.accept(this, "\$receiver")
|
expression.extensionReceiver?.accept(this, "\$receiver")
|
||||||
for (valueParameter in expression.descriptor.valueParameters) {
|
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 =
|
override fun visitPropertySetter(declaration: IrPropertySetter, data: Nothing?): String =
|
||||||
"IrPropertySetter ${declaration.descriptor.render()} property=${declaration.property?.name()}"
|
"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 =
|
override fun visitExpressionBody(body: IrExpressionBody, data: Nothing?): String =
|
||||||
"IrExpressionBody"
|
"IrExpressionBody"
|
||||||
|
|
||||||
@@ -57,6 +60,9 @@ class RenderIrElementVisitor : IrElementVisitor<String, Nothing?> {
|
|||||||
override fun <T> visitLiteral(expression: IrLiteralExpression<T>, data: Nothing?): String =
|
override fun <T> visitLiteral(expression: IrLiteralExpression<T>, data: Nothing?): String =
|
||||||
"LITERAL ${expression.kind} type=${expression.renderType()} value='${expression.value}'"
|
"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 =
|
override fun visitBlockExpression(expression: IrBlockExpression, data: Nothing?): String =
|
||||||
"BLOCK type=${expression.renderType()}"
|
"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 visitProperty(declaration: IrProperty, data: D): R = visitDeclaration(declaration, data)
|
||||||
fun visitSimpleProperty(declaration: IrSimpleProperty, data: D): R = visitProperty(declaration, data)
|
fun visitSimpleProperty(declaration: IrSimpleProperty, data: D): R = visitProperty(declaration, data)
|
||||||
fun visitDelegatedProperty(declaration: IrDelegatedProperty, 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 visitBody(body: IrBody, data: D): R = visitElement(body, data)
|
||||||
fun visitExpressionBody(body: IrExpressionBody, data: D): R = visitBody(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 visitStringTemplate(expression: IrStringConcatenationExpression, data: D) = visitExpression(expression, data)
|
||||||
fun visitThisExpression(expression: IrThisExpression, 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 visitDeclarationReference(expression: IrDeclarationReference, data: D) = visitExpression(expression, data)
|
||||||
fun visitGetObjectValue(expression: IrGetObjectValueExpression, data: D) = visitDeclarationReference(expression, data)
|
fun visitGetObjectValue(expression: IrGetObjectValueExpression, data: D) = visitDeclarationReference(expression, data)
|
||||||
fun visitGetEnumValue(expression: IrGetEnumValueExpression, 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)
|
fun visitDummyExpression(expression: IrDummyExpression, data: D) = visitExpression(expression, data)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-2
@@ -1,5 +1,4 @@
|
|||||||
IrFile /boxOk.kt
|
IrFile /boxOk.kt
|
||||||
IrFunction public fun box(): kotlin.String
|
IrFunction public fun box(): kotlin.String
|
||||||
IrExpressionBody
|
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
|
IrFile /calls.kt
|
||||||
IrFunction public fun foo(/*0*/ x: kotlin.Int, /*1*/ y: kotlin.Int): kotlin.Int
|
IrFunction public fun foo(/*0*/ x: kotlin.Int, /*1*/ y: kotlin.Int): kotlin.Int
|
||||||
IrExpressionBody
|
IrExpressionBody
|
||||||
RETURN type=kotlin.Int
|
GET_VAR x
|
||||||
GET_VAR x
|
|
||||||
IrFunction public fun bar(/*0*/ x: kotlin.Int): kotlin.Int
|
IrFunction public fun bar(/*0*/ x: kotlin.Int): kotlin.Int
|
||||||
IrExpressionBody
|
IrExpressionBody
|
||||||
RETURN type=kotlin.Int
|
CALL .foo
|
||||||
CALL .foo
|
x: GET_VAR x
|
||||||
x: GET_VAR x
|
y: LITERAL Int type=kotlin.Int value='1'
|
||||||
y: LITERAL Int type=kotlin.Int value='1'
|
|
||||||
IrFunction public fun qux(/*0*/ x: kotlin.Int): kotlin.Int
|
IrFunction public fun qux(/*0*/ x: kotlin.Int): kotlin.Int
|
||||||
IrExpressionBody
|
IrExpressionBody
|
||||||
RETURN type=kotlin.Int
|
CALL .foo
|
||||||
CALL .foo
|
x: CALL .foo
|
||||||
x: CALL .foo
|
x: GET_VAR x
|
||||||
x: GET_VAR x
|
|
||||||
y: GET_VAR x
|
|
||||||
y: GET_VAR x
|
y: GET_VAR x
|
||||||
|
y: GET_VAR x
|
||||||
IrFunction public fun kotlin.Int.ext1(): kotlin.Int
|
IrFunction public fun kotlin.Int.ext1(): kotlin.Int
|
||||||
IrExpressionBody
|
IrExpressionBody
|
||||||
RETURN type=kotlin.Int
|
$RECEIVER of: ext1
|
||||||
$RECEIVER of: ext1
|
|
||||||
IrFunction public fun kotlin.Int.ext2(/*0*/ x: kotlin.Int): kotlin.Int
|
IrFunction public fun kotlin.Int.ext2(/*0*/ x: kotlin.Int): kotlin.Int
|
||||||
IrExpressionBody
|
IrExpressionBody
|
||||||
RETURN type=kotlin.Int
|
CALL .foo
|
||||||
CALL .foo
|
x: $RECEIVER of: ext2
|
||||||
x: $RECEIVER of: ext2
|
y: GET_VAR x
|
||||||
y: GET_VAR x
|
|
||||||
|
|||||||
+4
-6
@@ -1,11 +1,9 @@
|
|||||||
IrFile /dotQualified.kt
|
IrFile /dotQualified.kt
|
||||||
IrFunction public fun length(/*0*/ s: kotlin.String): kotlin.Int
|
IrFunction public fun length(/*0*/ s: kotlin.String): kotlin.Int
|
||||||
IrExpressionBody
|
IrExpressionBody
|
||||||
RETURN type=kotlin.Int
|
GET_PROPERTY .length
|
||||||
GET_PROPERTY .length
|
$this: GET_VAR s
|
||||||
$this: GET_VAR s
|
|
||||||
IrFunction public fun lengthN(/*0*/ s: kotlin.String?): kotlin.Int?
|
IrFunction public fun lengthN(/*0*/ s: kotlin.String?): kotlin.Int?
|
||||||
IrExpressionBody
|
IrExpressionBody
|
||||||
RETURN type=kotlin.Int?
|
GET_PROPERTY ?.length
|
||||||
GET_PROPERTY ?.length
|
$this: GET_VAR s
|
||||||
$this: GET_VAR s
|
|
||||||
|
|||||||
@@ -2,10 +2,8 @@ IrFile /extensionPropertyGetterCall.kt
|
|||||||
IrProperty public val kotlin.String.okext: kotlin.String getter=<get-okext> setter=null
|
IrProperty public val kotlin.String.okext: kotlin.String getter=<get-okext> setter=null
|
||||||
IrPropertyGetter public fun kotlin.String.<get-okext>(): kotlin.String property=okext
|
IrPropertyGetter public fun kotlin.String.<get-okext>(): kotlin.String property=okext
|
||||||
IrExpressionBody
|
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
|
IrFunction public fun kotlin.String.test5(): kotlin.String
|
||||||
IrExpressionBody
|
IrExpressionBody
|
||||||
RETURN type=kotlin.String
|
GET_PROPERTY .okext
|
||||||
GET_PROPERTY .okext
|
$receiver: $RECEIVER of: test5
|
||||||
$receiver: $RECEIVER of: test5
|
|
||||||
|
|||||||
+9
-17
@@ -1,25 +1,20 @@
|
|||||||
IrFile /references.kt
|
IrFile /references.kt
|
||||||
IrProperty public val ok: kotlin.String = "OK" getter=null setter=null
|
IrProperty public val ok: kotlin.String = "OK" getter=null setter=null
|
||||||
IrExpressionBody
|
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
|
IrProperty public val ok2: kotlin.String = "OK" getter=null setter=null
|
||||||
IrExpressionBody
|
IrExpressionBody
|
||||||
RETURN type=kotlin.String
|
GET_PROPERTY .ok
|
||||||
GET_PROPERTY .ok
|
|
||||||
IrProperty public val ok3: kotlin.String getter=<get-ok3> setter=null
|
IrProperty public val ok3: kotlin.String getter=<get-ok3> setter=null
|
||||||
IrPropertyGetter public fun <get-ok3>(): kotlin.String property=ok3
|
IrPropertyGetter public fun <get-ok3>(): kotlin.String property=ok3
|
||||||
IrExpressionBody
|
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
|
IrFunction public fun test1(): kotlin.String
|
||||||
IrExpressionBody
|
IrExpressionBody
|
||||||
RETURN type=kotlin.String
|
GET_PROPERTY .ok
|
||||||
GET_PROPERTY .ok
|
|
||||||
IrFunction public fun test2(/*0*/ x: kotlin.String): kotlin.String
|
IrFunction public fun test2(/*0*/ x: kotlin.String): kotlin.String
|
||||||
IrExpressionBody
|
IrExpressionBody
|
||||||
RETURN type=kotlin.String
|
GET_VAR x
|
||||||
GET_VAR x
|
|
||||||
IrFunction public fun test3(): kotlin.String
|
IrFunction public fun test3(): kotlin.String
|
||||||
IrExpressionBody
|
IrExpressionBody
|
||||||
BLOCK type=kotlin.Nothing
|
BLOCK type=kotlin.Nothing
|
||||||
@@ -28,15 +23,12 @@ IrFile /references.kt
|
|||||||
GET_VAR x
|
GET_VAR x
|
||||||
IrFunction public fun test4(): kotlin.String
|
IrFunction public fun test4(): kotlin.String
|
||||||
IrExpressionBody
|
IrExpressionBody
|
||||||
RETURN type=kotlin.String
|
GET_PROPERTY .ok3
|
||||||
GET_PROPERTY .ok3
|
|
||||||
IrProperty public val kotlin.String.okext: kotlin.String getter=<get-okext> setter=null
|
IrProperty public val kotlin.String.okext: kotlin.String getter=<get-okext> setter=null
|
||||||
IrPropertyGetter public fun kotlin.String.<get-okext>(): kotlin.String property=okext
|
IrPropertyGetter public fun kotlin.String.<get-okext>(): kotlin.String property=okext
|
||||||
IrExpressionBody
|
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
|
IrFunction public fun kotlin.String.test5(): kotlin.String
|
||||||
IrExpressionBody
|
IrExpressionBody
|
||||||
RETURN type=kotlin.String
|
GET_PROPERTY .okext
|
||||||
GET_PROPERTY .okext
|
$receiver: $RECEIVER of: test5
|
||||||
$receiver: $RECEIVER of: test5
|
|
||||||
|
|||||||
+1
-2
@@ -1,4 +1,3 @@
|
|||||||
IrProperty public val testSimpleVal: kotlin.Int = 1 getter=null setter=null
|
IrProperty public val testSimpleVal: kotlin.Int = 1 getter=null setter=null
|
||||||
IrExpressionBody
|
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'
|
LITERAL String type=kotlin.String value='OK'
|
||||||
IrProperty public val testSimpleVal: kotlin.Int = 1 getter=null setter=null
|
IrProperty public val testSimpleVal: kotlin.Int = 1 getter=null setter=null
|
||||||
IrExpressionBody
|
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
|
IrProperty public val testValWithGetter: kotlin.Int getter=<get-testValWithGetter> setter=null
|
||||||
IrPropertyGetter public fun <get-testValWithGetter>(): kotlin.Int property=testValWithGetter
|
IrPropertyGetter public fun <get-testValWithGetter>(): kotlin.Int property=testValWithGetter
|
||||||
IrExpressionBody
|
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
|
IrProperty public var testSimpleVar: kotlin.Int getter=null setter=null
|
||||||
IrExpressionBody
|
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>
|
IrProperty public var testVarWithAccessors: kotlin.Int getter=<get-testVarWithAccessors> setter=<set-testVarWithAccessors>
|
||||||
IrPropertyGetter public fun <get-testVarWithAccessors>(): kotlin.Int property=testVarWithAccessors
|
IrPropertyGetter public fun <get-testVarWithAccessors>(): kotlin.Int property=testVarWithAccessors
|
||||||
IrExpressionBody
|
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
|
IrPropertySetter public fun <set-testVarWithAccessors>(/*0*/ v: kotlin.Int): kotlin.Unit property=testVarWithAccessors
|
||||||
IrExpressionBody
|
IrExpressionBody
|
||||||
BLOCK type=kotlin.Unit
|
BLOCK type=kotlin.Unit
|
||||||
|
|||||||
@@ -41,6 +41,12 @@ public class IrTextTestCaseGenerated extends AbstractIrTextTestCase {
|
|||||||
doTest(fileName);
|
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")
|
@TestMetadata("calls.kt")
|
||||||
public void testCalls() throws Exception {
|
public void testCalls() throws Exception {
|
||||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/ir/irText/calls.kt");
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/ir/irText/calls.kt");
|
||||||
|
|||||||
Reference in New Issue
Block a user