Refactor calls and related expressions

This commit is contained in:
Dmitry Petrov
2016-08-11 17:17:05 +03:00
committed by Dmitry Petrov
parent 3e11f35918
commit 4ccf3c3590
25 changed files with 561 additions and 257 deletions
@@ -106,6 +106,6 @@ abstract class IrDeclarationGeneratorBase(
IrReturnExpressionImpl(startOffset, endOffset, irExpression.type) IrReturnExpressionImpl(startOffset, endOffset, irExpression.type)
.apply { returnedExpression = irExpression } .apply { returnedExpression = irExpression }
return IrExpressionBodyImpl(startOffset, endOffset, containingDeclaration).apply { childExpression = bodyExpression } return IrExpressionBodyImpl(startOffset, endOffset, containingDeclaration).apply { argument = bodyExpression }
} }
} }
@@ -53,7 +53,7 @@ class IrExpressionGenerator(
return IrTypeOperatorExpressionImpl( return IrTypeOperatorExpressionImpl(
ktElement.startOffset, ktElement.endOffset, smartCastType, ktElement.startOffset, ktElement.endOffset, smartCastType,
IrTypeOperator.SMART_AS, smartCastType IrTypeOperator.SMART_AS, smartCastType
).apply { childExpression = this@smartCastIfNeeded } ).apply { argument = this@smartCastIfNeeded }
} }
} }
return this return this
@@ -70,7 +70,7 @@ class IrExpressionGenerator(
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, expression.type())
.apply { this.childExpression = 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)
@@ -112,21 +112,22 @@ class IrExpressionGenerator(
return when (descriptor) { return when (descriptor) {
is ClassDescriptor -> is ClassDescriptor ->
IrSingletonReferenceImpl(expression.startOffset, expression.endOffset, expression.type(), if (DescriptorUtils.isObject(descriptor))
descriptor.singletonDescriptor() ?: TODO("Unsupported class as value: ${descriptor.name}")) IrGetObjectValueExpressionImpl(expression.startOffset, expression.endOffset, expression.type(), descriptor)
else if (DescriptorUtils.isEnumEntry(descriptor))
IrGetEnumValueExpressionImpl(expression.startOffset, expression.endOffset, expression.type(), descriptor)
else
IrGetObjectValueExpressionImpl(expression.startOffset, expression.endOffset, expression.type(),
descriptor.companionObjectDescriptor ?: error("Class value without companion object: $descriptor"))
is PropertyDescriptor -> { is PropertyDescriptor -> {
generateCall( generateCall(expression, resolvedCall ?: TODO("Property, no resolved call: ${descriptor.name}"), null)
expression,
resolvedCall ?: TODO("Property, no resolved call: ${descriptor.name}"),
IrCallableOperator.PROPERTY_GET
)
} }
is VariableDescriptor -> is VariableDescriptor ->
IrVariableReferenceImpl(expression.startOffset, expression.endOffset, expression.type(), descriptor) IrGetVariableExpressionImpl(expression.startOffset, expression.endOffset, expression.type(), descriptor)
else -> else ->
IrDummyExpression(expression.startOffset, expression.endOffset, expression.type(), IrDummyExpression(expression.startOffset, expression.endOffset, expression.type(),
expression.getReferencedName() + expression.getReferencedName() +
": ${descriptor?.name} ${descriptor?.javaClass?.simpleName}") ": ${descriptor?.name} ${descriptor?.javaClass?.simpleName}")
} }
} }
@@ -150,35 +151,47 @@ 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, expression.type(), referenceTarget)
is CallableDescriptor -> is CallableDescriptor ->
IrExtensionReceiverReferenceImpl(expression.startOffset, expression.endOffset, expression.type(), referenceTarget) IrGetExtensionReceiverExpressionImpl(expression.startOffset, expression.endOffset, expression.type(),
referenceTarget.extensionReceiverParameter!!)
else -> else ->
error("Expected this or receiver: $referenceTarget") error("Expected this or receiver: $referenceTarget")
} }
} }
private fun generateCall( private fun generateCall(
ktExpression: KtExpression, ktExpression: KtExpression,
resolvedCall: ResolvedCall<out CallableDescriptor>, resolvedCall: ResolvedCall<out CallableDescriptor>,
operator: IrCallableOperator?, operator: IrOperator? = null,
superQualifier: ClassDescriptor? = null superQualifier: ClassDescriptor? = null
): IrExpression = ): IrExpression {
IrCallExpressionImpl( val descriptor = resolvedCall.resultingDescriptor
ktExpression.startOffset, ktExpression.endOffset, ktExpression.type(), return when (descriptor) {
resolvedCall.resultingDescriptor, resolvedCall.call.isSafeCall(), operator, superQualifier is PropertyDescriptor ->
).apply { IrGetPropertyExpressionImpl(
dispatchReceiver = generateReceiver(ktExpression, resolvedCall.dispatchReceiver) ktExpression.startOffset, ktExpression.endOffset, ktExpression.type(),
extensionReceiver = generateReceiver(ktExpression, resolvedCall.extensionReceiver) resolvedCall.call.isSafeCall(), descriptor
)
val valueParameters = resolvedCall.resultingDescriptor.valueParameters else ->
val valueArguments = resolvedCall.valueArgumentsByIndex ?: TODO("null for value arguments: ${ktExpression.text}") IrCallExpressionImpl(
for (index in valueArguments.indices) { ktExpression.startOffset, ktExpression.endOffset, ktExpression.type(),
val valueArgument = valueArguments[index] resolvedCall.resultingDescriptor, resolvedCall.call.isSafeCall(), operator, superQualifier
val valueParameter = valueParameters[index] ).apply {
putValueArgument(valueParameter, generateValueArgument(valueParameter, valueArgument)) 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? = private fun generateReceiver(ktExpression: KtExpression, receiver: ReceiverValue?): IrExpression? =
when (receiver) { when (receiver) {
@@ -191,11 +204,11 @@ class IrExpressionGenerator(
is ExpressionReceiver -> is ExpressionReceiver ->
receiver.expression.generate() receiver.expression.generate()
is ClassValueReceiver -> is ClassValueReceiver ->
IrSingletonReferenceImpl(receiver.expression.startOffset, receiver.expression.endOffset, receiver.type, IrGetObjectValueExpressionImpl(receiver.expression.startOffset, receiver.expression.endOffset, receiver.type,
receiver.classQualifier.descriptor) receiver.classQualifier.descriptor)
is ExtensionReceiver -> is ExtensionReceiver ->
IrExtensionReceiverReferenceImpl(ktExpression.startOffset, ktExpression.startOffset, receiver.type, IrGetExtensionReceiverExpressionImpl(ktExpression.startOffset, ktExpression.startOffset, receiver.type,
receiver.declarationDescriptor.extensionReceiverParameter!!) receiver.declarationDescriptor.extensionReceiverParameter!!)
null -> null ->
null null
else -> else ->
@@ -211,14 +224,4 @@ class IrExpressionGenerator(
TODO("vararg") TODO("vararg")
} }
} }
companion object {
fun ClassDescriptor.singletonDescriptor(): ClassDescriptor? =
if (DescriptorUtils.isObject(this) || DescriptorUtils.isEnumEntry(this))
this
else
companionObjectDescriptor
}
} }
@@ -14,20 +14,10 @@
* limitations under the License. * limitations under the License.
*/ */
package org.jetbrains.kotlin.ir.util package org.jetbrains.kotlin.ir
import java.util.* import org.jetbrains.kotlin.builtins.KotlinBuiltIns
class PairListImpl<T>(val first: T, val second: T) : AbstractList<T>() { class IrBuiltIns(val builtIns: KotlinBuiltIns) {
override val size: Int get() = 2
override fun get(index: Int): T =
when (index) {
0 -> first
1 -> second
else -> throw IndexOutOfBoundsException(index.toString())
}
} }
fun <T> pairList(first: T, second: T): List<T> =
PairListImpl(first, second)
@@ -0,0 +1,24 @@
/*
* 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
const val DETACHED_INDEX = Int.MIN_VALUE
const val CHILD_EXPRESSION_INDEX = 0
const val ARGUMENT0_INDEX = 0
const val ARGUMENT1_INDEX = 1
const val DISPATCH_RECEIVER_INDEX = -1
const val EXTENSION_RECEIVER_INDEX = -2
@@ -34,19 +34,19 @@ class IrExpressionBodyImpl(
endOffset: Int, endOffset: Int,
override val parent: IrDeclaration override val parent: IrDeclaration
) : IrDeclarationOwnerBase(startOffset, endOffset), IrExpressionBody { ) : IrDeclarationOwnerBase(startOffset, endOffset), IrExpressionBody {
override var childExpression: IrExpression? = null override var argument: IrExpression? = null
set(newExpression) { set(newExpression) {
field?.detach() field?.detach()
field = newExpression field = newExpression
newExpression?.setTreeLocation(this, IrExpressionOwner1.EXPRESSION_INDEX) newExpression?.setTreeLocation(this, CHILD_EXPRESSION_INDEX)
} }
override fun getChildExpression(index: Int): IrExpression? = override fun getChildExpression(index: Int): IrExpression? =
if (index == IrExpressionOwner1.EXPRESSION_INDEX) childExpression else null if (index == CHILD_EXPRESSION_INDEX) argument else null
override fun replaceChildExpression(oldChild: IrExpression, newChild: IrExpression) { override fun replaceChildExpression(oldChild: IrExpression, newChild: IrExpression) {
validateChild(oldChild) validateChild(oldChild)
childExpression = newChild argument = newChild
} }
override fun <R, D> accept(visitor: IrElementVisitor<R, D>, data: D): R = override fun <R, D> accept(visitor: IrElementVisitor<R, D>, data: D): R =
@@ -57,6 +57,6 @@ class IrExpressionBodyImpl(
} }
override fun <D> acceptChildExpressions(visitor: IrElementVisitor<Unit, D>, data: D) { override fun <D> acceptChildExpressions(visitor: IrElementVisitor<Unit, D>, data: D) {
childExpression?.accept(visitor, data) argument?.accept(visitor, data)
} }
} }
@@ -22,13 +22,10 @@ import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor
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
interface IrCallExpression : IrCompoundExpression { interface IrCallExpression : IrMemberAccessExpression, IrCompoundExpression {
val superQualifier: ClassDescriptor? val superQualifier: ClassDescriptor?
val operator: IrCallableOperator? val operator: IrOperator?
val isSafe: Boolean override val descriptor: CallableDescriptor
val callee: CallableDescriptor
var dispatchReceiver: IrExpression?
var extensionReceiver: IrExpression?
fun getValueArgument(valueParameterDescriptor: ValueParameterDescriptor): IrExpression? fun getValueArgument(valueParameterDescriptor: ValueParameterDescriptor): IrExpression?
fun putValueArgument(valueParameterDescriptor: ValueParameterDescriptor, valueArgument: IrExpression?) fun putValueArgument(valueParameterDescriptor: ValueParameterDescriptor, valueArgument: IrExpression?)
@@ -38,33 +35,19 @@ interface IrCallExpression : IrCompoundExpression {
} }
fun IrCallExpression.getMappedValueArguments(): List<IrExpression?> = fun IrCallExpression.getMappedValueArguments(): List<IrExpression?> =
callee.valueParameters.mapNotNull { getValueArgument(it) } descriptor.valueParameters.mapNotNull { getValueArgument(it) }
abstract class IrCallExpressionBase( class IrCallExpressionImpl(
startOffset: Int, startOffset: Int,
endOffset: Int, endOffset: Int,
type: KotlinType, type: KotlinType,
override final val callee: CallableDescriptor, override val descriptor: CallableDescriptor,
override val isSafe: Boolean, isSafe: Boolean,
override val operator: IrCallableOperator?, override val operator: IrOperator?,
override val superQualifier: ClassDescriptor? override val superQualifier: ClassDescriptor?
) : IrExpressionBase(startOffset, endOffset, type), IrCallExpression { ) : IrMemberAccessExpressionBase(startOffset, endOffset, type, isSafe), IrCallExpression {
private val argumentsByParameterIndex = private val argumentsByParameterIndex =
kotlin.arrayOfNulls<IrExpression>(callee.valueParameters.size) kotlin.arrayOfNulls<IrExpression>(descriptor.valueParameters.size)
override var dispatchReceiver: IrExpression? = null
set(newReceiver) {
field?.detach()
field = newReceiver
newReceiver?.setTreeLocation(this, DISPATCH_RECEIVER_INDEX)
}
override var extensionReceiver: IrExpression? = null
set(newReceiver) {
field?.detach()
field = newReceiver
newReceiver?.setTreeLocation(this, EXTENSION_RECEIVER_INDEX)
}
override fun getValueArgument(valueParameterDescriptor: ValueParameterDescriptor): IrExpression? = override fun getValueArgument(valueParameterDescriptor: ValueParameterDescriptor): IrExpression? =
argumentsByParameterIndex[valueParameterDescriptor.index] argumentsByParameterIndex[valueParameterDescriptor.index]
@@ -122,21 +105,6 @@ abstract class IrCallExpressionBase(
acceptChildExpressions(visitor, data) acceptChildExpressions(visitor, data)
} }
companion object {
const val DISPATCH_RECEIVER_INDEX = -1
const val EXTENSION_RECEIVER_INDEX = -2
}
}
class IrCallExpressionImpl(
startOffset: Int,
endOffset: Int,
type: KotlinType,
callee: CallableDescriptor,
isSafe: Boolean,
operator: IrCallableOperator? = null,
superQualifier: ClassDescriptor? = null
) : IrCallExpressionBase(startOffset, endOffset, type, callee, isSafe, operator, superQualifier), IrCallExpression {
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.visitCallExpression(this, data) visitor.visitCallExpression(this, data)
} }
@@ -1,69 +0,0 @@
/*
* Copyright 2010-2016 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.kotlin.ir.expressions
enum class IrCallableOperator {
PROPERTY_GET,
PROPERTY_SET,
INVOKE,
INVOKE_EXTENSION,
PLUSPLUS,
MINUSMINUS,
UMINUS,
EXCL,
LT,
GT,
LTEQ,
GTEQ,
EQEQ,
EQEQEQ,
EXCLEQ,
EXCLEQEQ,
IN,
NOT_IN,
ANDAND,
OROR,
RANGE,
PLUS,
MINUS,
MUL,
DIV,
MOD,
PLUSEQ,
MINUSEQ,
MULEQ,
DIVEQ,
MODEQ;
}
fun IrCallableOperator.isCompoundAssignment(): Boolean =
this >= IrCallableOperator.PLUSEQ && this <= IrCallableOperator.MODEQ
fun IrCallableOperator.hasCompoundAssignmentDual(): Boolean =
this >= IrCallableOperator.PLUS && this <= IrCallableOperator.MOD
fun IrCallableOperator.toDualOperator(): IrCallableOperator =
when {
isCompoundAssignment() ->
IrCallableOperator.values()[this.ordinal - IrCallableOperator.PLUSEQ.ordinal + IrCallableOperator.PLUS.ordinal]
hasCompoundAssignmentDual() ->
IrCallableOperator.values()[this.ordinal - IrCallableOperator.PLUS.ordinal + IrCallableOperator.PLUSEQ.ordinal]
else ->
throw UnsupportedOperationException("Operator $this is not a compound assignment")
}
@@ -24,6 +24,8 @@ interface IrCompoundExpression : IrExpression, IrExpressionOwner
interface IrCompoundExpression1 : IrCompoundExpression, IrExpressionOwner1 interface IrCompoundExpression1 : IrCompoundExpression, IrExpressionOwner1
interface IrCompoundExpression2 : IrCompoundExpression, IrExpressionOwner2
interface IrCompoundExpressionN : IrCompoundExpression, IrExpressionOwnerN interface IrCompoundExpressionN : IrCompoundExpression, IrExpressionOwnerN
abstract class IrCompoundExpressionNBase( abstract class IrCompoundExpressionNBase(
@@ -72,19 +74,19 @@ abstract class IrCompoundExpression1Base(
endOffset: Int, endOffset: Int,
override val type: KotlinType override val type: KotlinType
) : IrExpressionBase(startOffset, endOffset, type), IrCompoundExpression1 { ) : IrExpressionBase(startOffset, endOffset, type), IrCompoundExpression1 {
override var childExpression: IrExpression? = null override var argument: IrExpression? = null
set(newExpression) { set(newExpression) {
field?.detach() field?.detach()
field = newExpression field = newExpression
newExpression?.setTreeLocation(this, IrExpressionOwner1.EXPRESSION_INDEX) newExpression?.setTreeLocation(this, ARGUMENT0_INDEX)
} }
override fun getChildExpression(index: Int): IrExpression? = override fun getChildExpression(index: Int): IrExpression? =
if (index == IrExpressionOwner1.EXPRESSION_INDEX) childExpression else null if (index == ARGUMENT0_INDEX) argument else null
override fun replaceChildExpression(oldChild: IrExpression, newChild: IrExpression) { override fun replaceChildExpression(oldChild: IrExpression, newChild: IrExpression) {
validateChild(oldChild) validateChild(oldChild)
childExpression = newChild argument = newChild
} }
override fun <D> acceptChildren(visitor: IrElementVisitor<Unit, D>, data: D) { override fun <D> acceptChildren(visitor: IrElementVisitor<Unit, D>, data: D) {
@@ -92,6 +94,50 @@ abstract class IrCompoundExpression1Base(
} }
override fun <D> acceptChildExpressions(visitor: IrElementVisitor<Unit, D>, data: D) { override fun <D> acceptChildExpressions(visitor: IrElementVisitor<Unit, D>, data: D) {
childExpression?.accept(visitor, data) argument?.accept(visitor, data)
}
}
abstract class IrCompoundExpression2Base(
startOffset: Int,
endOffset: Int,
override val type: KotlinType
) : IrExpressionBase(startOffset, endOffset, type), IrCompoundExpression2 {
override var argument0: IrExpression? = null
set(newExpression) {
field?.detach()
field = newExpression
newExpression?.setTreeLocation(this, ARGUMENT0_INDEX)
}
override var argument1: IrExpression? = null
set(newExpression) {
field?.detach()
field = newExpression
newExpression?.setTreeLocation(this, ARGUMENT1_INDEX)
}
override fun getChildExpression(index: Int): IrExpression? =
when (index) {
ARGUMENT0_INDEX -> argument0
ARGUMENT1_INDEX -> argument1
else -> null
}
override fun replaceChildExpression(oldChild: IrExpression, newChild: IrExpression) {
validateChild(oldChild)
when (oldChild.index) {
ARGUMENT0_INDEX -> argument0 = newChild
ARGUMENT1_INDEX -> argument1 = newChild
}
}
override fun <D> acceptChildren(visitor: IrElementVisitor<Unit, D>, data: D) {
acceptChildExpressions(visitor, data)
}
override fun <D> acceptChildExpressions(visitor: IrElementVisitor<Unit, D>, data: D) {
argument0?.accept(visitor, data)
argument1?.accept(visitor, data)
} }
} }
@@ -16,7 +16,8 @@
package org.jetbrains.kotlin.ir.expressions package org.jetbrains.kotlin.ir.expressions
import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.descriptors.ClassDescriptor
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
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
@@ -25,17 +26,13 @@ interface IrDeclarationReference : IrExpression {
val descriptor: DeclarationDescriptor val descriptor: DeclarationDescriptor
} }
interface IrVariableReference : IrDeclarationReference { interface IrGetSingletonValueExpression : IrDeclarationReference {
override val descriptor: VariableDescriptor
}
interface IrSingletonReference : IrDeclarationReference {
override val descriptor: ClassDescriptor override val descriptor: ClassDescriptor
} }
interface IrExtensionReceiverReference : IrDeclarationReference { interface IrGetObjectValueExpression : IrGetSingletonValueExpression
override val descriptor: CallableDescriptor
} interface IrGetEnumValueExpression : IrGetSingletonValueExpression
abstract class IrDeclarationReferenceBase<out D : DeclarationDescriptor>( abstract class IrDeclarationReferenceBase<out D : DeclarationDescriptor>(
startOffset: Int, startOffset: Int,
@@ -44,34 +41,23 @@ abstract class IrDeclarationReferenceBase<out D : DeclarationDescriptor>(
override val descriptor: D override val descriptor: D
) : IrTerminalExpressionBase(startOffset, endOffset, type), IrDeclarationReference ) : IrTerminalExpressionBase(startOffset, endOffset, type), IrDeclarationReference
class IrVariableReferenceImpl( class IrGetObjectValueExpressionImpl(
startOffset: Int,
endOffset: Int,
type: KotlinType,
descriptor: VariableDescriptor
) : IrDeclarationReferenceBase<VariableDescriptor>(startOffset, endOffset, type, descriptor), IrVariableReference {
override fun <R, D> accept(visitor: IrElementVisitor<R, D>, data: D): R =
visitor.visitVariableReference(this, data)
}
class IrSingletonReferenceImpl(
startOffset: Int, startOffset: Int,
endOffset: Int, endOffset: Int,
type: KotlinType, type: KotlinType,
descriptor: ClassDescriptor descriptor: ClassDescriptor
) : IrDeclarationReferenceBase<ClassDescriptor>(startOffset, endOffset, type, descriptor), IrSingletonReference { ) : IrDeclarationReferenceBase<ClassDescriptor>(startOffset, endOffset, type, descriptor), IrGetObjectValueExpression {
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.visitSingletonReference(this, data) visitor.visitGetObjectValue(this, data)
} }
class IrGetEnumValueExpressionImpl(
class IrExtensionReceiverReferenceImpl(
startOffset: Int, startOffset: Int,
endOffset: Int, endOffset: Int,
type: KotlinType, type: KotlinType,
override val descriptor: CallableDescriptor descriptor: ClassDescriptor
) : IrTerminalExpressionBase(startOffset, endOffset, type), IrExtensionReceiverReference { ) : IrDeclarationReferenceBase<ClassDescriptor>(startOffset, endOffset, type, descriptor), IrGetEnumValueExpression {
override fun <R, D> accept(visitor: IrElementVisitor<R, D>, data: D): R { override fun <R, D> accept(visitor: IrElementVisitor<R, D>, data: D): R {
return visitor.visitExtensionReceiverReference(this, data) return visitor.visitGetEnumValue(this, data)
} }
} }
@@ -28,14 +28,10 @@ interface IrExpression : IrElement {
val type: KotlinType val type: KotlinType
fun setTreeLocation(parent: IrExpressionOwner?, index: Int) fun setTreeLocation(parent: IrExpressionOwner?, index: Int)
companion object {
const val DETACHED_INDEX = Int.MIN_VALUE
}
} }
fun IrExpression.detach() { fun IrExpression.detach() {
setTreeLocation(null, IrExpression.DETACHED_INDEX) setTreeLocation(null, DETACHED_INDEX)
} }
fun IrExpressionOwner.validateChild(child: IrExpression) { fun IrExpressionOwner.validateChild(child: IrExpression) {
@@ -48,7 +44,7 @@ abstract class IrExpressionBase(
override val type: KotlinType override val type: KotlinType
) : IrElementBase(startOffset, endOffset), IrExpression { ) : IrElementBase(startOffset, endOffset), IrExpression {
override var parent: IrExpressionOwner? = null override var parent: IrExpressionOwner? = null
override var index: Int = IrExpression.DETACHED_INDEX override var index: Int = DETACHED_INDEX
override fun setTreeLocation(parent: IrExpressionOwner?, index: Int) { override fun setTreeLocation(parent: IrExpressionOwner?, index: Int) {
this.parent = parent this.parent = parent
@@ -26,11 +26,12 @@ interface IrExpressionOwner : IrElement {
} }
interface IrExpressionOwner1 : IrExpressionOwner { interface IrExpressionOwner1 : IrExpressionOwner {
var childExpression: IrExpression? var argument: IrExpression?
}
companion object { interface IrExpressionOwner2 : IrExpressionOwner {
const val EXPRESSION_INDEX = 0 var argument0: IrExpression?
} var argument1: IrExpression?
} }
interface IrExpressionOwnerN : IrExpressionOwner { interface IrExpressionOwnerN : IrExpressionOwner {
@@ -0,0 +1,50 @@
/*
* 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.descriptors.CallableDescriptor
import org.jetbrains.kotlin.descriptors.VariableDescriptor
import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
import org.jetbrains.kotlin.types.KotlinType
interface IrGetVariableExpression : IrDeclarationReference {
override val descriptor: VariableDescriptor
}
interface IrGetExtensionReceiverExpression : IrDeclarationReference {
override val descriptor: CallableDescriptor
}
class IrGetVariableExpressionImpl(
startOffset: Int,
endOffset: Int,
type: KotlinType,
descriptor: VariableDescriptor
) : IrDeclarationReferenceBase<VariableDescriptor>(startOffset, endOffset, type, descriptor), IrGetVariableExpression {
override fun <R, D> accept(visitor: IrElementVisitor<R, D>, data: D): R =
visitor.visitGetVariable(this, data)
}
class IrGetExtensionReceiverExpressionImpl(
startOffset: Int,
endOffset: Int,
type: KotlinType,
override val descriptor: CallableDescriptor
) : IrTerminalExpressionBase(startOffset, endOffset, type), IrGetExtensionReceiverExpression {
override fun <R, D> accept(visitor: IrElementVisitor<R, D>, data: D): R =
visitor.visitGetExtensionReceiver(this, data)
}
@@ -0,0 +1,46 @@
/*
* 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.types.KotlinType
interface IrMemberAccessExpression : IrDeclarationReference, IrExpressionOwner {
var dispatchReceiver: IrExpression?
var extensionReceiver: IrExpression?
val isSafe: Boolean
}
abstract class IrMemberAccessExpressionBase(
startOffset: Int,
endOffset: Int,
type: KotlinType,
override val isSafe: Boolean
) : IrExpressionBase(startOffset, endOffset, type), IrMemberAccessExpression {
override var dispatchReceiver: IrExpression? = null
set(newReceiver) {
field?.detach()
field = newReceiver
newReceiver?.setTreeLocation(this, DISPATCH_RECEIVER_INDEX)
}
override var extensionReceiver: IrExpression? = null
set(newReceiver) {
field?.detach()
field = newReceiver
newReceiver?.setTreeLocation(this, EXTENSION_RECEIVER_INDEX)
}
}
@@ -0,0 +1,63 @@
/*
* 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
enum class IrOperator {
INVOKE, INVOKE_EXTENSION,
PREFIX_INCR, PREFIX_DECR, POSTFIX_INCR, POSTFIX_DECR,
UMINUS,
EXCL,
EXCLEXCL,
LT, GT, LTEQ, GTEQ,
EQEQ, EQEQEQ, EXCLEQ, EXCLEQEQ,
IN, NOT_IN,
ANDAND, OROR,
RANGE,
PLUS, MINUS, MUL, DIV, MOD,
EQ,
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
fun IrOperator.isIncrementOrDecrement(): Boolean =
this in INCR_DECR_START..INCR_DECR_END
fun IrOperator.isCompoundAssignment(): Boolean =
this in CAO_START .. CAO_END
fun IrOperator.isAssignmentOrCompoundAssignment(): Boolean =
this == IrOperator.EQ || isCompoundAssignment()
fun IrOperator.hasCompoundAssignmentDual(): Boolean =
this in DUAL_START .. DUAL_END
fun IrOperator.toDualOperator(): IrOperator =
when {
isCompoundAssignment() ->
IrOperator.values()[this.ordinal - CAO_START.ordinal + DUAL_START.ordinal]
hasCompoundAssignmentDual() ->
IrOperator.values()[this.ordinal - DUAL_START.ordinal + CAO_START.ordinal]
else ->
throw UnsupportedOperationException("Operator $this is not a compound assignment")
}
@@ -0,0 +1,53 @@
/*
* 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.descriptors.FunctionDescriptor
import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
import org.jetbrains.kotlin.types.KotlinType
interface IrOperatorExpression : IrExpression {
val operator: IrOperator
val relatedDescriptor: FunctionDescriptor?
}
interface IrUnaryOperatorExpression : IrOperatorExpression, IrCompoundExpression1
interface IrBinaryOperatorExpression : IrOperatorExpression, IrCompoundExpression2
class IrUnaryOperatorExpressionImpl(
startOffset: Int,
endOffset: Int,
type: KotlinType,
override val operator: IrOperator,
override val relatedDescriptor: FunctionDescriptor?
) : IrCompoundExpression1Base(startOffset, endOffset, type), IrUnaryOperatorExpression {
override fun <R, D> accept(visitor: IrElementVisitor<R, D>, data: D): R {
return visitor.visitUnaryOperator(this, data)
}
}
class IrBinaryOperatorExpressionImpl(
startOffset: Int,
endOffset: Int,
type: KotlinType,
override val operator: IrOperator,
override val relatedDescriptor: FunctionDescriptor?
) : IrCompoundExpression2Base(startOffset, endOffset, type), IrBinaryOperatorExpression {
override fun <R, D> accept(visitor: IrElementVisitor<R, D>, data: D): R =
visitor.visitBinaryOperator(this, data)
}
@@ -0,0 +1,111 @@
/*
* 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.descriptors.PropertyDescriptor
import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
import org.jetbrains.kotlin.types.KotlinType
interface IrPropertyAccessExpression : IrMemberAccessExpression {
override val descriptor: PropertyDescriptor
}
interface IrGetPropertyExpression : IrPropertyAccessExpression
interface IrSetPropertyExpression : IrPropertyAccessExpression, IrCompoundExpression1
class IrGetPropertyExpressionImpl(
startOffset: Int,
endOffset: Int,
type: KotlinType,
isSafe: Boolean,
override val descriptor: PropertyDescriptor
) : IrMemberAccessExpressionBase(startOffset, endOffset, type, isSafe), IrGetPropertyExpression {
override fun <R, D> accept(visitor: IrElementVisitor<R, D>, data: D): R {
return visitor.visitGetProperty(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) {
dispatchReceiver?.accept(visitor, data)
extensionReceiver?.accept(visitor, data)
}
override fun getChildExpression(index: Int): IrExpression? =
when (index) {
DISPATCH_RECEIVER_INDEX -> dispatchReceiver
EXTENSION_RECEIVER_INDEX -> extensionReceiver
else -> null
}
override fun replaceChildExpression(oldChild: IrExpression, newChild: IrExpression) {
validateChild(oldChild)
when (oldChild.index) {
DISPATCH_RECEIVER_INDEX -> dispatchReceiver = newChild
EXTENSION_RECEIVER_INDEX -> extensionReceiver = newChild
}
}
}
class IrSetPropertyExpressionImpl(
startOffset: Int,
endOffset: Int,
type: KotlinType,
isSafe: Boolean,
override val descriptor: PropertyDescriptor
) : IrMemberAccessExpressionBase(startOffset, endOffset, type, isSafe), IrSetPropertyExpression {
override var argument: IrExpression? = null
set(value) {
field?.detach()
field = value
value?.setTreeLocation(this, ARGUMENT0_INDEX)
}
override fun <R, D> accept(visitor: IrElementVisitor<R, D>, data: D): R {
return visitor.visitSetProperty(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) {
dispatchReceiver?.accept(visitor, data)
extensionReceiver?.accept(visitor, data)
argument?.accept(visitor, data)
}
override fun getChildExpression(index: Int): IrExpression? =
when (index) {
DISPATCH_RECEIVER_INDEX -> dispatchReceiver
EXTENSION_RECEIVER_INDEX -> extensionReceiver
ARGUMENT0_INDEX -> argument
else -> null
}
override fun replaceChildExpression(oldChild: IrExpression, newChild: IrExpression) {
validateChild(oldChild)
when (oldChild.index) {
DISPATCH_RECEIVER_INDEX -> dispatchReceiver = newChild
EXTENSION_RECEIVER_INDEX -> extensionReceiver = newChild
ARGUMENT0_INDEX -> argument = newChild
}
}
}
@@ -23,9 +23,9 @@ import org.jetbrains.kotlin.types.KotlinType
interface IrReturnExpression : IrCompoundExpression1 interface IrReturnExpression : IrCompoundExpression1
var IrReturnExpression.returnedExpression: IrExpression? var IrReturnExpression.returnedExpression: IrExpression?
get() = childExpression get() = argument
set(newReturnedExpression) { set(newReturnedExpression) {
childExpression = newReturnedExpression argument = newReturnedExpression
} }
class IrReturnExpressionImpl( class IrReturnExpressionImpl(
@@ -20,10 +20,11 @@ import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
import org.jetbrains.kotlin.types.KotlinType import org.jetbrains.kotlin.types.KotlinType
enum class IrTypeOperator { enum class IrTypeOperator {
SMART_AS,
AS, AS,
AS_SAFE, SMART_AS,
IS; SAFE_AS,
IS,
NOT_IS;
} }
interface IrTypeOperatorExpression : IrExpression, IrCompoundExpression1 { interface IrTypeOperatorExpression : IrExpression, IrCompoundExpression1 {
@@ -18,9 +18,10 @@ package org.jetbrains.kotlin.ir.util
import org.jetbrains.kotlin.ir.IrElement import org.jetbrains.kotlin.ir.IrElement
import org.jetbrains.kotlin.ir.SourceLocationManager import org.jetbrains.kotlin.ir.SourceLocationManager
import org.jetbrains.kotlin.ir.declarations.IrDeclaration
import org.jetbrains.kotlin.ir.declarations.IrFile import org.jetbrains.kotlin.ir.declarations.IrFile
import org.jetbrains.kotlin.ir.expressions.IrCallExpression import org.jetbrains.kotlin.ir.expressions.IrCallExpression
import org.jetbrains.kotlin.ir.expressions.IrGetPropertyExpression
import org.jetbrains.kotlin.ir.expressions.IrSetPropertyExpression
import org.jetbrains.kotlin.ir.visitors.IrElementVisitor import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
import org.jetbrains.kotlin.utils.Printer import org.jetbrains.kotlin.utils.Printer
@@ -48,12 +49,27 @@ class DumpIrTreeVisitor(out: Appendable): IrElementVisitor<Unit, String> {
expression.dumpLabeledElementWith(data) { expression.dumpLabeledElementWith(data) {
expression.dispatchReceiver?.accept(this, "\$this") expression.dispatchReceiver?.accept(this, "\$this")
expression.extensionReceiver?.accept(this, "\$receiver") expression.extensionReceiver?.accept(this, "\$receiver")
for (valueParameter in expression.callee.valueParameters) { for (valueParameter in expression.descriptor.valueParameters) {
expression.getValueArgument(valueParameter)?.accept(this, valueParameter.name.asString()) expression.getValueArgument(valueParameter)?.accept(this, valueParameter.name.asString())
} }
} }
} }
override fun visitGetProperty(expression: IrGetPropertyExpression, data: String) {
expression.dumpLabeledElementWith(data) {
expression.dispatchReceiver?.accept(this, "\$this")
expression.extensionReceiver?.accept(this, "\$receiver")
}
}
override fun visitSetProperty(expression: IrSetPropertyExpression, data: String) {
expression.dumpLabeledElementWith(data) {
expression.dispatchReceiver?.accept(this, "\$this")
expression.extensionReceiver?.accept(this, "\$receiver")
expression.argument?.accept(this, "\$value")
}
}
private inline fun IrElement.dumpLabeledElementWith(label: String, body: () -> Unit) { private inline fun IrElement.dumpLabeledElementWith(label: String, body: () -> Unit) {
printer.println(accept(elementRenderer, null).withLabel(label)) printer.println(accept(elementRenderer, null).withLabel(label))
indented(body) indented(body)
@@ -63,20 +63,29 @@ class RenderIrElementVisitor : IrElementVisitor<String, Nothing?> {
override fun visitReturnExpression(expression: IrReturnExpression, data: Nothing?): String = override fun visitReturnExpression(expression: IrReturnExpression, data: Nothing?): String =
"RETURN type=${expression.renderType()}" "RETURN type=${expression.renderType()}"
override fun visitVariableReference(expression: IrVariableReference, data: Nothing?): String = override fun visitGetExtensionReceiver(expression: IrGetExtensionReceiverExpression, data: Nothing?): String =
"VAR ${expression.descriptor.name}"
override fun visitSingletonReference(expression: IrSingletonReference, data: Nothing?): String =
"SINGLETON ${expression.descriptor.name}"
override fun visitExtensionReceiverReference(expression: IrExtensionReceiverReference, data: Nothing?): String =
"\$RECEIVER of: ${expression.descriptor.containingDeclaration.name}" "\$RECEIVER of: ${expression.descriptor.containingDeclaration.name}"
override fun visitThisExpression(expression: IrThisExpression, data: Nothing?): String = override fun visitThisExpression(expression: IrThisExpression, data: Nothing?): String =
"THIS ${expression.classDescriptor.render()}" "THIS ${expression.classDescriptor.render()}"
override fun visitCallExpression(expression: IrCallExpression, data: Nothing?): String = override fun visitCallExpression(expression: IrCallExpression, data: Nothing?): String =
"CALL ${if (expression.isSafe) "?." else "."}${expression.callee.name} ${expression.operator ?: ""}" "CALL ${if (expression.isSafe) "?." else "."}${expression.descriptor.name} ${expression.operator ?: ""}"
override fun visitGetProperty(expression: IrGetPropertyExpression, data: Nothing?): String =
"GET_PROPERTY ${if (expression.isSafe) "?." else "."}${expression.descriptor.name}"
override fun visitGetVariable(expression: IrGetVariableExpression, data: Nothing?): String =
"GET_VAR ${expression.descriptor.name}"
override fun visitGetObjectValue(expression: IrGetObjectValueExpression, data: Nothing?): String =
"GET_OBJECT ${expression.descriptor.name}"
override fun visitGetEnumValue(expression: IrGetEnumValueExpression, data: Nothing?): String =
"GET_ENUM_VALUE ${expression.descriptor.name}"
override fun visitSetProperty(expression: IrSetPropertyExpression, data: Nothing?): String =
"SET_PROPERTY ${if (expression.isSafe) "?." else "."}${expression.descriptor.name}"
override fun visitDummyExpression(expression: IrDummyExpression, data: Nothing?): String = override fun visitDummyExpression(expression: IrDummyExpression, data: Nothing?): String =
"DUMMY ${expression.description}" "DUMMY ${expression.description}"
@@ -44,17 +44,27 @@ interface IrElementVisitor<out R, in D> {
fun visitBlockExpression(expression: IrBlockExpression, data: D): R = visitExpression(expression, data) fun visitBlockExpression(expression: IrBlockExpression, data: D): R = visitExpression(expression, data)
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 visitDeclarationReference(expression: IrDeclarationReference, data: D) = visitExpression(expression, data) fun visitDeclarationReference(expression: IrDeclarationReference, data: D) = visitExpression(expression, data)
fun visitVariableReference(expression: IrVariableReference, data: D) = visitDeclarationReference(expression, data) fun visitGetObjectValue(expression: IrGetObjectValueExpression, data: D) = visitDeclarationReference(expression, data)
fun visitSingletonReference(expression: IrSingletonReference, data: D) = visitDeclarationReference(expression, data) fun visitGetEnumValue(expression: IrGetEnumValueExpression, data: D) = visitDeclarationReference(expression, data)
fun visitExtensionReceiverReference(expression: IrExtensionReceiverReference, data: D) = visitDeclarationReference(expression, data) fun visitGetVariable(expression: IrGetVariableExpression, data: D) = visitDeclarationReference(expression, data)
fun visitGetExtensionReceiver(expression: IrGetExtensionReceiverExpression, data: D) = visitDeclarationReference(expression, data)
fun visitMemberAccess(expression: IrMemberAccessExpression, data: D) = visitDeclarationReference(expression, data)
fun visitCallExpression(expression: IrCallExpression, data: D) = visitMemberAccess(expression, data)
fun visitPropertyAccess(expression: IrPropertyAccessExpression, data: D) = visitMemberAccess(expression, data)
fun visitGetProperty(expression: IrGetPropertyExpression, data: D) = visitPropertyAccess(expression, data)
fun visitSetProperty(expression: IrSetPropertyExpression, data: D) = visitPropertyAccess(expression, data)
fun visitOperatorExpression(expression: IrOperatorExpression, data: D) = visitExpression(expression, data)
fun visitCallExpression(expression: IrCallExpression, data: D) = visitExpression(expression, data) fun visitUnaryOperator(expression: IrUnaryOperatorExpression, data: D) = visitOperatorExpression(expression, data)
fun visitBinaryOperator(expression: IrBinaryOperatorExpression, data: D) = visitOperatorExpression(expression, data)
fun visitTypeOperatorExpression(expression: IrTypeOperatorExpression, data: D) = visitExpression(expression, data) fun visitTypeOperatorExpression(expression: IrTypeOperatorExpression, data: D) = visitExpression(expression, data)
// NB Use it only for testing purposes; will be removed as soon as all Kotlin expression types are covered // NB Use it only for testing purposes; will be removed as soon as all Kotlin expression types are covered
fun visitDummyExpression(expression: IrDummyExpression, data: D) = visitExpression(expression, data) fun visitDummyExpression(expression: IrDummyExpression, data: D) = visitExpression(expression, data)
} }
+8 -8
View File
@@ -2,28 +2,28 @@ 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 RETURN type=kotlin.Int
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 RETURN type=kotlin.Int
CALL .foo CALL .foo
x: 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 RETURN type=kotlin.Int
CALL .foo CALL .foo
x: CALL .foo x: CALL .foo
x: VAR x x: GET_VAR x
y: VAR x y: GET_VAR x
y: 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 RETURN type=kotlin.Int
$RECEIVER of: <root> $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 RETURN type=kotlin.Int
CALL .foo CALL .foo
x: $RECEIVER of: <root> x: $RECEIVER of: ext2
y: VAR x y: GET_VAR x
+4 -4
View File
@@ -2,10 +2,10 @@ 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 RETURN type=kotlin.Int
CALL .length PROPERTY_GET GET_PROPERTY .length
$this: 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? RETURN type=kotlin.Int?
CALL ?.length PROPERTY_GET GET_PROPERTY ?.length
$this: VAR s $this: GET_VAR s
@@ -7,5 +7,5 @@ IrFile /extensionPropertyGetterCall.kt
IrFunction public fun kotlin.String.test5(): kotlin.String IrFunction public fun kotlin.String.test5(): kotlin.String
IrExpressionBody IrExpressionBody
RETURN type=kotlin.String RETURN type=kotlin.String
CALL .okext PROPERTY_GET GET_PROPERTY .okext
$receiver: $RECEIVER of: test5 $receiver: $RECEIVER of: test5
+6 -6
View File
@@ -6,7 +6,7 @@ IrFile /references.kt
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 RETURN type=kotlin.String
CALL .ok PROPERTY_GET 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
@@ -15,21 +15,21 @@ IrFile /references.kt
IrFunction public fun test1(): kotlin.String IrFunction public fun test1(): kotlin.String
IrExpressionBody IrExpressionBody
RETURN type=kotlin.String RETURN type=kotlin.String
CALL .ok PROPERTY_GET 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 RETURN type=kotlin.String
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
DUMMY KtProperty DUMMY KtProperty
RETURN type=kotlin.Nothing RETURN type=kotlin.Nothing
VAR x GET_VAR x
IrFunction public fun test4(): kotlin.String IrFunction public fun test4(): kotlin.String
IrExpressionBody IrExpressionBody
RETURN type=kotlin.String RETURN type=kotlin.String
CALL .ok3 PROPERTY_GET 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
@@ -38,5 +38,5 @@ IrFile /references.kt
IrFunction public fun kotlin.String.test5(): kotlin.String IrFunction public fun kotlin.String.test5(): kotlin.String
IrExpressionBody IrExpressionBody
RETURN type=kotlin.String RETURN type=kotlin.String
CALL .okext PROPERTY_GET GET_PROPERTY .okext
$receiver: $RECEIVER of: test5 $receiver: $RECEIVER of: test5