Refactor calls and related expressions
This commit is contained in:
committed by
Dmitry Petrov
parent
3e11f35918
commit
4ccf3c3590
@@ -106,6 +106,6 @@ abstract class IrDeclarationGeneratorBase(
|
||||
IrReturnExpressionImpl(startOffset, endOffset, irExpression.type)
|
||||
.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(
|
||||
ktElement.startOffset, ktElement.endOffset, smartCastType,
|
||||
IrTypeOperator.SMART_AS, smartCastType
|
||||
).apply { childExpression = this@smartCastIfNeeded }
|
||||
).apply { argument = this@smartCastIfNeeded }
|
||||
}
|
||||
}
|
||||
return this
|
||||
@@ -70,7 +70,7 @@ class IrExpressionGenerator(
|
||||
|
||||
override fun visitReturnExpression(expression: KtReturnExpression, data: Nothing?): IrExpression =
|
||||
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 {
|
||||
val compileTimeConstant = ConstantExpressionEvaluator.getConstant(expression, context.bindingContext)
|
||||
@@ -112,21 +112,22 @@ class IrExpressionGenerator(
|
||||
|
||||
return when (descriptor) {
|
||||
is ClassDescriptor ->
|
||||
IrSingletonReferenceImpl(expression.startOffset, expression.endOffset, expression.type(),
|
||||
descriptor.singletonDescriptor() ?: TODO("Unsupported class as value: ${descriptor.name}"))
|
||||
if (DescriptorUtils.isObject(descriptor))
|
||||
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 -> {
|
||||
generateCall(
|
||||
expression,
|
||||
resolvedCall ?: TODO("Property, no resolved call: ${descriptor.name}"),
|
||||
IrCallableOperator.PROPERTY_GET
|
||||
)
|
||||
generateCall(expression, resolvedCall ?: TODO("Property, no resolved call: ${descriptor.name}"), null)
|
||||
}
|
||||
is VariableDescriptor ->
|
||||
IrVariableReferenceImpl(expression.startOffset, expression.endOffset, expression.type(), descriptor)
|
||||
IrGetVariableExpressionImpl(expression.startOffset, expression.endOffset, expression.type(), descriptor)
|
||||
else ->
|
||||
IrDummyExpression(expression.startOffset, expression.endOffset, expression.type(),
|
||||
expression.getReferencedName() +
|
||||
": ${descriptor?.name} ${descriptor?.javaClass?.simpleName}")
|
||||
expression.getReferencedName() +
|
||||
": ${descriptor?.name} ${descriptor?.javaClass?.simpleName}")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -150,35 +151,47 @@ class IrExpressionGenerator(
|
||||
val referenceTarget = getOrFail(BindingContext.REFERENCE_TARGET, expression.instanceReference) { "No reference target for this" }
|
||||
return when (referenceTarget) {
|
||||
is ClassDescriptor ->
|
||||
IrThisExpressionImpl(expression.startOffset, expression.endOffset, expression.type(), referenceTarget)
|
||||
IrThisExpressionImpl(expression.startOffset, expression.endOffset, expression.type(), referenceTarget)
|
||||
is CallableDescriptor ->
|
||||
IrExtensionReceiverReferenceImpl(expression.startOffset, expression.endOffset, expression.type(), referenceTarget)
|
||||
IrGetExtensionReceiverExpressionImpl(expression.startOffset, expression.endOffset, expression.type(),
|
||||
referenceTarget.extensionReceiverParameter!!)
|
||||
else ->
|
||||
error("Expected this or receiver: $referenceTarget")
|
||||
error("Expected this or receiver: $referenceTarget")
|
||||
}
|
||||
}
|
||||
|
||||
private fun generateCall(
|
||||
ktExpression: KtExpression,
|
||||
resolvedCall: ResolvedCall<out CallableDescriptor>,
|
||||
operator: IrCallableOperator?,
|
||||
operator: IrOperator? = null,
|
||||
superQualifier: ClassDescriptor? = null
|
||||
): IrExpression =
|
||||
IrCallExpressionImpl(
|
||||
ktExpression.startOffset, ktExpression.endOffset, ktExpression.type(),
|
||||
resolvedCall.resultingDescriptor, resolvedCall.call.isSafeCall(), operator, superQualifier
|
||||
).apply {
|
||||
dispatchReceiver = generateReceiver(ktExpression, resolvedCall.dispatchReceiver)
|
||||
extensionReceiver = generateReceiver(ktExpression, resolvedCall.extensionReceiver)
|
||||
|
||||
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))
|
||||
): 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) {
|
||||
@@ -191,11 +204,11 @@ class IrExpressionGenerator(
|
||||
is ExpressionReceiver ->
|
||||
receiver.expression.generate()
|
||||
is ClassValueReceiver ->
|
||||
IrSingletonReferenceImpl(receiver.expression.startOffset, receiver.expression.endOffset, receiver.type,
|
||||
receiver.classQualifier.descriptor)
|
||||
IrGetObjectValueExpressionImpl(receiver.expression.startOffset, receiver.expression.endOffset, receiver.type,
|
||||
receiver.classQualifier.descriptor)
|
||||
is ExtensionReceiver ->
|
||||
IrExtensionReceiverReferenceImpl(ktExpression.startOffset, ktExpression.startOffset, receiver.type,
|
||||
receiver.declarationDescriptor.extensionReceiverParameter!!)
|
||||
IrGetExtensionReceiverExpressionImpl(ktExpression.startOffset, ktExpression.startOffset, receiver.type,
|
||||
receiver.declarationDescriptor.extensionReceiverParameter!!)
|
||||
null ->
|
||||
null
|
||||
else ->
|
||||
@@ -211,14 +224,4 @@ class IrExpressionGenerator(
|
||||
TODO("vararg")
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
fun ClassDescriptor.singletonDescriptor(): ClassDescriptor? =
|
||||
if (DescriptorUtils.isObject(this) || DescriptorUtils.isEnumEntry(this))
|
||||
this
|
||||
else
|
||||
companionObjectDescriptor
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
+3
-13
@@ -14,20 +14,10 @@
|
||||
* 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>() {
|
||||
override val size: Int get() = 2
|
||||
class IrBuiltIns(val builtIns: KotlinBuiltIns) {
|
||||
|
||||
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,
|
||||
override val parent: IrDeclaration
|
||||
) : IrDeclarationOwnerBase(startOffset, endOffset), IrExpressionBody {
|
||||
override var childExpression: IrExpression? = null
|
||||
override var argument: IrExpression? = null
|
||||
set(newExpression) {
|
||||
field?.detach()
|
||||
field = newExpression
|
||||
newExpression?.setTreeLocation(this, IrExpressionOwner1.EXPRESSION_INDEX)
|
||||
newExpression?.setTreeLocation(this, CHILD_EXPRESSION_INDEX)
|
||||
}
|
||||
|
||||
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) {
|
||||
validateChild(oldChild)
|
||||
childExpression = newChild
|
||||
argument = newChild
|
||||
}
|
||||
|
||||
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) {
|
||||
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.types.KotlinType
|
||||
|
||||
interface IrCallExpression : IrCompoundExpression {
|
||||
interface IrCallExpression : IrMemberAccessExpression, IrCompoundExpression {
|
||||
val superQualifier: ClassDescriptor?
|
||||
val operator: IrCallableOperator?
|
||||
val isSafe: Boolean
|
||||
val callee: CallableDescriptor
|
||||
var dispatchReceiver: IrExpression?
|
||||
var extensionReceiver: IrExpression?
|
||||
val operator: IrOperator?
|
||||
override val descriptor: CallableDescriptor
|
||||
|
||||
fun getValueArgument(valueParameterDescriptor: ValueParameterDescriptor): IrExpression?
|
||||
fun putValueArgument(valueParameterDescriptor: ValueParameterDescriptor, valueArgument: IrExpression?)
|
||||
@@ -38,33 +35,19 @@ interface IrCallExpression : IrCompoundExpression {
|
||||
}
|
||||
|
||||
fun IrCallExpression.getMappedValueArguments(): List<IrExpression?> =
|
||||
callee.valueParameters.mapNotNull { getValueArgument(it) }
|
||||
descriptor.valueParameters.mapNotNull { getValueArgument(it) }
|
||||
|
||||
abstract class IrCallExpressionBase(
|
||||
class IrCallExpressionImpl(
|
||||
startOffset: Int,
|
||||
endOffset: Int,
|
||||
type: KotlinType,
|
||||
override final val callee: CallableDescriptor,
|
||||
override val isSafe: Boolean,
|
||||
override val operator: IrCallableOperator?,
|
||||
override val descriptor: CallableDescriptor,
|
||||
isSafe: Boolean,
|
||||
override val operator: IrOperator?,
|
||||
override val superQualifier: ClassDescriptor?
|
||||
) : IrExpressionBase(startOffset, endOffset, type), IrCallExpression {
|
||||
) : IrMemberAccessExpressionBase(startOffset, endOffset, type, isSafe), IrCallExpression {
|
||||
private val argumentsByParameterIndex =
|
||||
kotlin.arrayOfNulls<IrExpression>(callee.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)
|
||||
}
|
||||
kotlin.arrayOfNulls<IrExpression>(descriptor.valueParameters.size)
|
||||
|
||||
override fun getValueArgument(valueParameterDescriptor: ValueParameterDescriptor): IrExpression? =
|
||||
argumentsByParameterIndex[valueParameterDescriptor.index]
|
||||
@@ -122,21 +105,6 @@ abstract class IrCallExpressionBase(
|
||||
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 =
|
||||
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")
|
||||
}
|
||||
|
||||
|
||||
+51
-5
@@ -24,6 +24,8 @@ interface IrCompoundExpression : IrExpression, IrExpressionOwner
|
||||
|
||||
interface IrCompoundExpression1 : IrCompoundExpression, IrExpressionOwner1
|
||||
|
||||
interface IrCompoundExpression2 : IrCompoundExpression, IrExpressionOwner2
|
||||
|
||||
interface IrCompoundExpressionN : IrCompoundExpression, IrExpressionOwnerN
|
||||
|
||||
abstract class IrCompoundExpressionNBase(
|
||||
@@ -72,19 +74,19 @@ abstract class IrCompoundExpression1Base(
|
||||
endOffset: Int,
|
||||
override val type: KotlinType
|
||||
) : IrExpressionBase(startOffset, endOffset, type), IrCompoundExpression1 {
|
||||
override var childExpression: IrExpression? = null
|
||||
override var argument: IrExpression? = null
|
||||
set(newExpression) {
|
||||
field?.detach()
|
||||
field = newExpression
|
||||
newExpression?.setTreeLocation(this, IrExpressionOwner1.EXPRESSION_INDEX)
|
||||
newExpression?.setTreeLocation(this, ARGUMENT0_INDEX)
|
||||
}
|
||||
|
||||
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) {
|
||||
validateChild(oldChild)
|
||||
childExpression = newChild
|
||||
argument = newChild
|
||||
}
|
||||
|
||||
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) {
|
||||
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)
|
||||
}
|
||||
}
|
||||
+13
-27
@@ -16,7 +16,8 @@
|
||||
|
||||
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.types.KotlinType
|
||||
|
||||
@@ -25,17 +26,13 @@ interface IrDeclarationReference : IrExpression {
|
||||
val descriptor: DeclarationDescriptor
|
||||
}
|
||||
|
||||
interface IrVariableReference : IrDeclarationReference {
|
||||
override val descriptor: VariableDescriptor
|
||||
}
|
||||
|
||||
interface IrSingletonReference : IrDeclarationReference {
|
||||
interface IrGetSingletonValueExpression : IrDeclarationReference {
|
||||
override val descriptor: ClassDescriptor
|
||||
}
|
||||
|
||||
interface IrExtensionReceiverReference : IrDeclarationReference {
|
||||
override val descriptor: CallableDescriptor
|
||||
}
|
||||
interface IrGetObjectValueExpression : IrGetSingletonValueExpression
|
||||
|
||||
interface IrGetEnumValueExpression : IrGetSingletonValueExpression
|
||||
|
||||
abstract class IrDeclarationReferenceBase<out D : DeclarationDescriptor>(
|
||||
startOffset: Int,
|
||||
@@ -44,34 +41,23 @@ abstract class IrDeclarationReferenceBase<out D : DeclarationDescriptor>(
|
||||
override val descriptor: D
|
||||
) : IrTerminalExpressionBase(startOffset, endOffset, type), IrDeclarationReference
|
||||
|
||||
class IrVariableReferenceImpl(
|
||||
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(
|
||||
class IrGetObjectValueExpressionImpl(
|
||||
startOffset: Int,
|
||||
endOffset: Int,
|
||||
type: KotlinType,
|
||||
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 =
|
||||
visitor.visitSingletonReference(this, data)
|
||||
visitor.visitGetObjectValue(this, data)
|
||||
}
|
||||
|
||||
|
||||
class IrExtensionReceiverReferenceImpl(
|
||||
class IrGetEnumValueExpressionImpl(
|
||||
startOffset: Int,
|
||||
endOffset: Int,
|
||||
type: KotlinType,
|
||||
override val descriptor: CallableDescriptor
|
||||
) : IrTerminalExpressionBase(startOffset, endOffset, type), IrExtensionReceiverReference {
|
||||
descriptor: ClassDescriptor
|
||||
) : IrDeclarationReferenceBase<ClassDescriptor>(startOffset, endOffset, type, descriptor), IrGetEnumValueExpression {
|
||||
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
|
||||
|
||||
fun setTreeLocation(parent: IrExpressionOwner?, index: Int)
|
||||
|
||||
companion object {
|
||||
const val DETACHED_INDEX = Int.MIN_VALUE
|
||||
}
|
||||
}
|
||||
|
||||
fun IrExpression.detach() {
|
||||
setTreeLocation(null, IrExpression.DETACHED_INDEX)
|
||||
setTreeLocation(null, DETACHED_INDEX)
|
||||
}
|
||||
|
||||
fun IrExpressionOwner.validateChild(child: IrExpression) {
|
||||
@@ -48,7 +44,7 @@ abstract class IrExpressionBase(
|
||||
override val type: KotlinType
|
||||
) : IrElementBase(startOffset, endOffset), IrExpression {
|
||||
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) {
|
||||
this.parent = parent
|
||||
|
||||
@@ -26,11 +26,12 @@ interface IrExpressionOwner : IrElement {
|
||||
}
|
||||
|
||||
interface IrExpressionOwner1 : IrExpressionOwner {
|
||||
var childExpression: IrExpression?
|
||||
var argument: IrExpression?
|
||||
}
|
||||
|
||||
companion object {
|
||||
const val EXPRESSION_INDEX = 0
|
||||
}
|
||||
interface IrExpressionOwner2 : IrExpressionOwner {
|
||||
var argument0: IrExpression?
|
||||
var argument1: IrExpression?
|
||||
}
|
||||
|
||||
interface IrExpressionOwnerN : IrExpressionOwner {
|
||||
|
||||
+50
@@ -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)
|
||||
}
|
||||
+46
@@ -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)
|
||||
}
|
||||
+111
@@ -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
|
||||
|
||||
var IrReturnExpression.returnedExpression: IrExpression?
|
||||
get() = childExpression
|
||||
get() = argument
|
||||
set(newReturnedExpression) {
|
||||
childExpression = newReturnedExpression
|
||||
argument = newReturnedExpression
|
||||
}
|
||||
|
||||
class IrReturnExpressionImpl(
|
||||
|
||||
+4
-3
@@ -20,10 +20,11 @@ import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
|
||||
enum class IrTypeOperator {
|
||||
SMART_AS,
|
||||
AS,
|
||||
AS_SAFE,
|
||||
IS;
|
||||
SMART_AS,
|
||||
SAFE_AS,
|
||||
IS,
|
||||
NOT_IS;
|
||||
}
|
||||
|
||||
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.SourceLocationManager
|
||||
import org.jetbrains.kotlin.ir.declarations.IrDeclaration
|
||||
import org.jetbrains.kotlin.ir.declarations.IrFile
|
||||
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.utils.Printer
|
||||
|
||||
@@ -48,12 +49,27 @@ class DumpIrTreeVisitor(out: Appendable): IrElementVisitor<Unit, String> {
|
||||
expression.dumpLabeledElementWith(data) {
|
||||
expression.dispatchReceiver?.accept(this, "\$this")
|
||||
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())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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) {
|
||||
printer.println(accept(elementRenderer, null).withLabel(label))
|
||||
indented(body)
|
||||
|
||||
@@ -63,20 +63,29 @@ class RenderIrElementVisitor : IrElementVisitor<String, Nothing?> {
|
||||
override fun visitReturnExpression(expression: IrReturnExpression, data: Nothing?): String =
|
||||
"RETURN type=${expression.renderType()}"
|
||||
|
||||
override fun visitVariableReference(expression: IrVariableReference, 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 =
|
||||
override fun visitGetExtensionReceiver(expression: IrGetExtensionReceiverExpression, data: Nothing?): String =
|
||||
"\$RECEIVER of: ${expression.descriptor.containingDeclaration.name}"
|
||||
|
||||
override fun visitThisExpression(expression: IrThisExpression, data: Nothing?): String =
|
||||
"THIS ${expression.classDescriptor.render()}"
|
||||
|
||||
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 =
|
||||
"DUMMY ${expression.description}"
|
||||
|
||||
@@ -44,17 +44,27 @@ interface IrElementVisitor<out R, in D> {
|
||||
fun visitBlockExpression(expression: IrBlockExpression, data: D): R = visitExpression(expression, data)
|
||||
fun visitStringTemplate(expression: IrStringConcatenationExpression, data: D) = visitExpression(expression, data)
|
||||
fun visitThisExpression(expression: IrThisExpression, data: D) = visitExpression(expression, data)
|
||||
|
||||
fun visitDeclarationReference(expression: IrDeclarationReference, data: D) = visitExpression(expression, data)
|
||||
fun visitVariableReference(expression: IrVariableReference, data: D) = visitDeclarationReference(expression, data)
|
||||
fun visitSingletonReference(expression: IrSingletonReference, data: D) = visitDeclarationReference(expression, data)
|
||||
fun visitExtensionReceiverReference(expression: IrExtensionReceiverReference, data: D) = visitDeclarationReference(expression, data)
|
||||
fun visitGetObjectValue(expression: IrGetObjectValueExpression, data: D) = visitDeclarationReference(expression, data)
|
||||
fun visitGetEnumValue(expression: IrGetEnumValueExpression, 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 visitCallExpression(expression: IrCallExpression, data: D) = visitExpression(expression, data)
|
||||
fun visitOperatorExpression(expression: IrOperatorExpression, 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)
|
||||
|
||||
// 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)
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
+8
-8
@@ -2,28 +2,28 @@ IrFile /calls.kt
|
||||
IrFunction public fun foo(/*0*/ x: kotlin.Int, /*1*/ y: kotlin.Int): kotlin.Int
|
||||
IrExpressionBody
|
||||
RETURN type=kotlin.Int
|
||||
VAR x
|
||||
GET_VAR x
|
||||
IrFunction public fun bar(/*0*/ x: kotlin.Int): kotlin.Int
|
||||
IrExpressionBody
|
||||
RETURN type=kotlin.Int
|
||||
CALL .foo
|
||||
x: VAR x
|
||||
x: GET_VAR x
|
||||
y: LITERAL Int type=kotlin.Int value='1'
|
||||
IrFunction public fun qux(/*0*/ x: kotlin.Int): kotlin.Int
|
||||
IrExpressionBody
|
||||
RETURN type=kotlin.Int
|
||||
CALL .foo
|
||||
x: CALL .foo
|
||||
x: VAR x
|
||||
y: VAR x
|
||||
y: VAR x
|
||||
x: GET_VAR x
|
||||
y: GET_VAR x
|
||||
y: GET_VAR x
|
||||
IrFunction public fun kotlin.Int.ext1(): kotlin.Int
|
||||
IrExpressionBody
|
||||
RETURN type=kotlin.Int
|
||||
$RECEIVER of: <root>
|
||||
$RECEIVER of: ext1
|
||||
IrFunction public fun kotlin.Int.ext2(/*0*/ x: kotlin.Int): kotlin.Int
|
||||
IrExpressionBody
|
||||
RETURN type=kotlin.Int
|
||||
CALL .foo
|
||||
x: $RECEIVER of: <root>
|
||||
y: VAR x
|
||||
x: $RECEIVER of: ext2
|
||||
y: GET_VAR x
|
||||
|
||||
+4
-4
@@ -2,10 +2,10 @@ IrFile /dotQualified.kt
|
||||
IrFunction public fun length(/*0*/ s: kotlin.String): kotlin.Int
|
||||
IrExpressionBody
|
||||
RETURN type=kotlin.Int
|
||||
CALL .length PROPERTY_GET
|
||||
$this: VAR s
|
||||
GET_PROPERTY .length
|
||||
$this: GET_VAR s
|
||||
IrFunction public fun lengthN(/*0*/ s: kotlin.String?): kotlin.Int?
|
||||
IrExpressionBody
|
||||
RETURN type=kotlin.Int?
|
||||
CALL ?.length PROPERTY_GET
|
||||
$this: VAR s
|
||||
GET_PROPERTY ?.length
|
||||
$this: GET_VAR s
|
||||
|
||||
@@ -7,5 +7,5 @@ IrFile /extensionPropertyGetterCall.kt
|
||||
IrFunction public fun kotlin.String.test5(): kotlin.String
|
||||
IrExpressionBody
|
||||
RETURN type=kotlin.String
|
||||
CALL .okext PROPERTY_GET
|
||||
GET_PROPERTY .okext
|
||||
$receiver: $RECEIVER of: test5
|
||||
|
||||
+6
-6
@@ -6,7 +6,7 @@ IrFile /references.kt
|
||||
IrProperty public val ok2: kotlin.String = "OK" getter=null setter=null
|
||||
IrExpressionBody
|
||||
RETURN type=kotlin.String
|
||||
CALL .ok PROPERTY_GET
|
||||
GET_PROPERTY .ok
|
||||
IrProperty public val ok3: kotlin.String getter=<get-ok3> setter=null
|
||||
IrPropertyGetter public fun <get-ok3>(): kotlin.String property=ok3
|
||||
IrExpressionBody
|
||||
@@ -15,21 +15,21 @@ IrFile /references.kt
|
||||
IrFunction public fun test1(): kotlin.String
|
||||
IrExpressionBody
|
||||
RETURN type=kotlin.String
|
||||
CALL .ok PROPERTY_GET
|
||||
GET_PROPERTY .ok
|
||||
IrFunction public fun test2(/*0*/ x: kotlin.String): kotlin.String
|
||||
IrExpressionBody
|
||||
RETURN type=kotlin.String
|
||||
VAR x
|
||||
GET_VAR x
|
||||
IrFunction public fun test3(): kotlin.String
|
||||
IrExpressionBody
|
||||
BLOCK type=kotlin.Nothing
|
||||
DUMMY KtProperty
|
||||
RETURN type=kotlin.Nothing
|
||||
VAR x
|
||||
GET_VAR x
|
||||
IrFunction public fun test4(): kotlin.String
|
||||
IrExpressionBody
|
||||
RETURN type=kotlin.String
|
||||
CALL .ok3 PROPERTY_GET
|
||||
GET_PROPERTY .ok3
|
||||
IrProperty public val kotlin.String.okext: kotlin.String getter=<get-okext> setter=null
|
||||
IrPropertyGetter public fun kotlin.String.<get-okext>(): kotlin.String property=okext
|
||||
IrExpressionBody
|
||||
@@ -38,5 +38,5 @@ IrFile /references.kt
|
||||
IrFunction public fun kotlin.String.test5(): kotlin.String
|
||||
IrExpressionBody
|
||||
RETURN type=kotlin.String
|
||||
CALL .okext PROPERTY_GET
|
||||
GET_PROPERTY .okext
|
||||
$receiver: $RECEIVER of: test5
|
||||
|
||||
Reference in New Issue
Block a user