- IR expressions for calls & references
- first calls "parsed"
This commit is contained in:
committed by
Dmitry Petrov
parent
c09ba962c4
commit
c93666f6f1
@@ -16,37 +16,61 @@
|
||||
|
||||
package org.jetbrains.kotlin.psi2ir
|
||||
|
||||
import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.ir.expressions.*
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
import org.jetbrains.kotlin.psi.psiUtil.endOffset
|
||||
import org.jetbrains.kotlin.psi.psiUtil.startOffset
|
||||
import org.jetbrains.kotlin.resolve.BindingContext
|
||||
import org.jetbrains.kotlin.resolve.DescriptorUtils
|
||||
import org.jetbrains.kotlin.resolve.calls.callUtil.isSafeCall
|
||||
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
|
||||
import org.jetbrains.kotlin.resolve.calls.model.ResolvedValueArgument
|
||||
import org.jetbrains.kotlin.resolve.calls.model.VariableAsFunctionResolvedCall
|
||||
import org.jetbrains.kotlin.resolve.constants.IntValue
|
||||
import org.jetbrains.kotlin.resolve.constants.StringValue
|
||||
import org.jetbrains.kotlin.resolve.constants.evaluate.ConstantExpressionEvaluator
|
||||
import org.jetbrains.kotlin.resolve.scopes.receivers.*
|
||||
|
||||
class IrExpressionGenerator(
|
||||
override val context: IrGeneratorContext,
|
||||
val declarationFactory: IrDeclarationFactory
|
||||
) : KtVisitor<IrExpressionBase, Nothing?>(), IrGenerator {
|
||||
) : KtVisitor<IrExpression, Nothing?>(), IrGenerator {
|
||||
fun generateExpression(ktExpression: KtExpression) = ktExpression.generate()
|
||||
|
||||
private fun KtElement.generate(): IrExpressionBase = accept(this@IrExpressionGenerator, null)
|
||||
private fun KtExpression.type() = getType(this) ?: TODO("no type for expression")
|
||||
private fun KtElement.generate(): IrExpression =
|
||||
accept(this@IrExpressionGenerator, null).applySmartCast(this)
|
||||
|
||||
override fun visitExpression(expression: KtExpression, data: Nothing?): IrExpressionBase =
|
||||
IrDummyExpression(expression.startOffset, expression.endOffset, expression.type())
|
||||
private fun KtExpression.type() =
|
||||
getType(this) ?: TODO("no type for expression")
|
||||
|
||||
override fun visitBlockExpression(expression: KtBlockExpression, data: Nothing?): IrExpressionBase {
|
||||
val irBlock = IrBlockExpressionImpl(expression.startOffset, expression.endOffset, expression.type())
|
||||
expression.statements.forEach { irBlock.childExpressions.add(it.generate()) }
|
||||
private fun IrExpression.applySmartCast(ktElement: KtElement): IrExpression {
|
||||
if (ktElement is KtExpression) {
|
||||
val smartCastType = get(BindingContext.SMARTCAST, ktElement)
|
||||
if (smartCastType != null) {
|
||||
return IrTypeOperatorExpressionImpl(
|
||||
ktElement.startOffset, ktElement.endOffset, smartCastType,
|
||||
IrTypeOperator.SMART_AS, smartCastType
|
||||
).apply { childExpression = this@applySmartCast }
|
||||
}
|
||||
}
|
||||
return this
|
||||
}
|
||||
|
||||
override fun visitExpression(expression: KtExpression, data: Nothing?): IrExpression =
|
||||
IrDummyExpression(expression.startOffset, expression.endOffset, expression.type(), expression.javaClass.simpleName)
|
||||
|
||||
override fun visitBlockExpression(expression: KtBlockExpression, data: Nothing?): IrExpression {
|
||||
val irBlock = IrBlockExpressionImpl(expression.startOffset, expression.endOffset, expression.type(), false)
|
||||
expression.statements.forEach { irBlock.addChildExpression(it.generate()) }
|
||||
return irBlock
|
||||
}
|
||||
|
||||
override fun visitReturnExpression(expression: KtReturnExpression, data: Nothing?): IrExpressionBase =
|
||||
override fun visitReturnExpression(expression: KtReturnExpression, data: Nothing?): IrExpression =
|
||||
IrReturnExpressionImpl(expression.startOffset, expression.endOffset, expression.type())
|
||||
.apply { this.childExpression = expression.returnedExpression?.generate() }
|
||||
|
||||
override fun visitConstantExpression(expression: KtConstantExpression, data: Nothing?): IrExpressionBase {
|
||||
override fun visitConstantExpression(expression: KtConstantExpression, data: Nothing?): IrExpression {
|
||||
val compileTimeConstant = ConstantExpressionEvaluator.getConstant(expression, context.bindingContext)
|
||||
?: error("KtConstantExpression was not evaluated: ${expression.text}")
|
||||
val constantValue = compileTimeConstant.toConstantValue(expression.type())
|
||||
@@ -62,7 +86,7 @@ class IrExpressionGenerator(
|
||||
}
|
||||
}
|
||||
|
||||
override fun visitStringTemplateExpression(expression: KtStringTemplateExpression, data: Nothing?): IrExpressionBase {
|
||||
override fun visitStringTemplateExpression(expression: KtStringTemplateExpression, data: Nothing?): IrExpression {
|
||||
if (expression.entries.size == 1 && expression.entries[0] is KtLiteralStringTemplateEntry) {
|
||||
return expression.entries[0].generate()
|
||||
}
|
||||
@@ -72,6 +96,110 @@ class IrExpressionGenerator(
|
||||
return irStringTemplate
|
||||
}
|
||||
|
||||
override fun visitLiteralStringTemplateEntry(entry: KtLiteralStringTemplateEntry, data: Nothing?): IrExpressionBase =
|
||||
override fun visitLiteralStringTemplateEntry(entry: KtLiteralStringTemplateEntry, data: Nothing?): IrExpression =
|
||||
IrLiteralExpressionImpl.string(entry.startOffset, entry.endOffset, context.builtIns.stringType, entry.text)
|
||||
|
||||
override fun visitSimpleNameExpression(expression: KtSimpleNameExpression, data: Nothing?): IrExpression {
|
||||
val resolvedCall = getResolvedCall(expression)
|
||||
|
||||
if (resolvedCall is VariableAsFunctionResolvedCall) {
|
||||
TODO("Unexpected VariableAsFunctionResolvedCall")
|
||||
}
|
||||
|
||||
val descriptor = resolvedCall?.resultingDescriptor ?: get(BindingContext.REFERENCE_TARGET, expression)
|
||||
|
||||
return when (descriptor) {
|
||||
is ClassDescriptor ->
|
||||
IrSingletonReferenceImpl(expression.startOffset, expression.endOffset, expression.type(),
|
||||
descriptor.singletonDescriptor() ?: TODO("Unsupported class as value: ${descriptor.name}"))
|
||||
is PropertyDescriptor -> {
|
||||
generateCall(
|
||||
expression,
|
||||
resolvedCall ?: TODO("Property, no resolved call: ${descriptor.name}"),
|
||||
IrCallableOperator.PROPERTY_GET
|
||||
)
|
||||
}
|
||||
is VariableDescriptor ->
|
||||
IrVariableReferenceImpl(expression.startOffset, expression.endOffset, expression.type(), descriptor)
|
||||
else ->
|
||||
IrDummyExpression(expression.startOffset, expression.endOffset, expression.type(),
|
||||
expression.getReferencedName() +
|
||||
": ${descriptor?.name} ${descriptor?.javaClass?.simpleName}")
|
||||
}
|
||||
}
|
||||
|
||||
override fun visitCallExpression(expression: KtCallExpression, data: Nothing?): IrExpression {
|
||||
val resolvedCall = getResolvedCall(expression) ?: TODO("No resolved call for call expression")
|
||||
|
||||
if (resolvedCall is VariableAsFunctionResolvedCall) {
|
||||
TODO("VariableAsFunctionResolvedCall = variable call + invoke call")
|
||||
}
|
||||
|
||||
return generateCall(expression, resolvedCall, null, null)
|
||||
}
|
||||
|
||||
private fun generateCall(
|
||||
ktExpression: KtExpression,
|
||||
resolvedCall: ResolvedCall<out CallableDescriptor>,
|
||||
operator: IrCallableOperator?,
|
||||
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))
|
||||
}
|
||||
}
|
||||
|
||||
private fun generateReceiver(ktExpression: KtExpression, receiver: ReceiverValue?): IrExpression? =
|
||||
when (receiver) {
|
||||
is ImplicitClassReceiver ->
|
||||
IrThisExpressionImpl(ktExpression.startOffset, ktExpression.startOffset, receiver.type, receiver.classDescriptor)
|
||||
is ThisClassReceiver ->
|
||||
(receiver as? ExpressionReceiver)?.expression?.let { receiverExpression ->
|
||||
IrThisExpressionImpl(receiverExpression.startOffset, receiverExpression.endOffset, receiver.type, receiver.classDescriptor)
|
||||
} ?: TODO("Non-implicit ThisClassReceiver should be an expression receiver")
|
||||
is ExpressionReceiver ->
|
||||
receiver.expression.generate()
|
||||
is ClassValueReceiver ->
|
||||
IrSingletonReferenceImpl(receiver.expression.startOffset, receiver.expression.endOffset, receiver.type,
|
||||
receiver.classQualifier.descriptor)
|
||||
is ExtensionReceiver ->
|
||||
IrExtensionReceiverReferenceImpl(ktExpression.startOffset, ktExpression.startOffset, receiver.type,
|
||||
receiver.declarationDescriptor.extensionReceiverParameter!!)
|
||||
null ->
|
||||
null
|
||||
else ->
|
||||
IrDummyExpression(ktExpression.startOffset, ktExpression.endOffset, receiver.type,
|
||||
"Receiver: ${receiver.javaClass.simpleName}")
|
||||
}
|
||||
|
||||
private fun generateValueArgument(valueParameter: ValueParameterDescriptor, valueArgument: ResolvedValueArgument): IrExpression? {
|
||||
if (valueParameter.varargElementType == null) {
|
||||
assert(valueArgument.arguments.size == 1) { "Single value argument expected for a non-vararg parameter" }
|
||||
return valueArgument.arguments.single().getArgumentExpression()!!.generate()
|
||||
}
|
||||
else {
|
||||
TODO("vararg")
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
fun ClassDescriptor.singletonDescriptor(): ClassDescriptor? =
|
||||
if (DescriptorUtils.isObject(this) || DescriptorUtils.isEnumEntry(this))
|
||||
this
|
||||
else
|
||||
companionObjectDescriptor
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,7 +16,10 @@
|
||||
|
||||
package org.jetbrains.kotlin.psi2ir
|
||||
|
||||
import org.jetbrains.kotlin.descriptors.CallableDescriptor
|
||||
import org.jetbrains.kotlin.psi.KtExpression
|
||||
import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall
|
||||
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
import org.jetbrains.kotlin.util.slicedMap.ReadOnlySlice
|
||||
|
||||
@@ -34,4 +37,7 @@ inline fun <K, V : Any> IrGenerator.getOrFail(slice: ReadOnlySlice<K, V>, key: K
|
||||
context.bindingContext[slice, key] ?: throw RuntimeException(message(key))
|
||||
|
||||
inline fun <K, V : Any> IrGenerator.getOrElse(slice: ReadOnlySlice<K, V>, key: K, otherwise: (K) -> V): V =
|
||||
context.bindingContext[slice, key] ?: otherwise(key)
|
||||
context.bindingContext[slice, key] ?: otherwise(key)
|
||||
|
||||
fun IrGenerator.getResolvedCall(key: KtExpression): ResolvedCall<out CallableDescriptor>? =
|
||||
key.getResolvedCall(context.bindingContext)
|
||||
@@ -20,12 +20,18 @@ import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
|
||||
|
||||
interface IrBlockExpression : IrCompoundExpressionN
|
||||
interface IrBlockExpression : IrCompoundExpressionN {
|
||||
val hasResult: Boolean
|
||||
}
|
||||
|
||||
fun IrBlockExpression.getResultExpression() =
|
||||
if (hasResult) childExpressions.lastOrNull() else null
|
||||
|
||||
class IrBlockExpressionImpl(
|
||||
startOffset: Int,
|
||||
endOffset: Int,
|
||||
type: KotlinType
|
||||
type: KotlinType,
|
||||
override val hasResult: Boolean
|
||||
) : IrCompoundExpressionNBase(startOffset, endOffset, type), IrBlockExpression {
|
||||
override fun <R, D> accept(visitor: IrElementVisitor<R, D>, data: D): R =
|
||||
visitor.visitBlockExpression(this, data)
|
||||
|
||||
@@ -0,0 +1,142 @@
|
||||
/*
|
||||
* 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.ClassDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor
|
||||
import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
|
||||
interface IrCallExpression : IrCompoundExpression {
|
||||
val superQualifier: ClassDescriptor?
|
||||
val operator: IrCallableOperator?
|
||||
val isSafe: Boolean
|
||||
val callee: CallableDescriptor
|
||||
var dispatchReceiver: IrExpression?
|
||||
var extensionReceiver: IrExpression?
|
||||
|
||||
fun getValueArgument(valueParameterDescriptor: ValueParameterDescriptor): IrExpression?
|
||||
fun putValueArgument(valueParameterDescriptor: ValueParameterDescriptor, valueArgument: IrExpression?)
|
||||
fun removeValueArgument(valueParameterDescriptor: ValueParameterDescriptor)
|
||||
|
||||
fun <D> acceptValueArguments(visitor: IrElementVisitor<Unit, D>, data: D)
|
||||
}
|
||||
|
||||
fun IrCallExpression.getMappedValueArguments(): List<IrExpression?> =
|
||||
callee.valueParameters.mapNotNull { getValueArgument(it) }
|
||||
|
||||
abstract class IrCallExpressionBase(
|
||||
startOffset: Int,
|
||||
endOffset: Int,
|
||||
type: KotlinType,
|
||||
override final val callee: CallableDescriptor,
|
||||
override val isSafe: Boolean,
|
||||
override val operator: IrCallableOperator?,
|
||||
override val superQualifier: ClassDescriptor?
|
||||
) : IrExpressionBase(startOffset, endOffset, type), 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)
|
||||
}
|
||||
|
||||
override fun getValueArgument(valueParameterDescriptor: ValueParameterDescriptor): IrExpression? =
|
||||
argumentsByParameterIndex[valueParameterDescriptor.index]
|
||||
|
||||
override fun putValueArgument(valueParameterDescriptor: ValueParameterDescriptor, valueArgument: IrExpression?) {
|
||||
putValueArgument(valueParameterDescriptor.index, valueArgument)
|
||||
}
|
||||
|
||||
private fun putValueArgument(index: Int, valueArgument: IrExpression?) {
|
||||
argumentsByParameterIndex[index]?.detach()
|
||||
argumentsByParameterIndex[index] = valueArgument
|
||||
valueArgument?.setTreeLocation(this, index)
|
||||
}
|
||||
|
||||
override fun removeValueArgument(valueParameterDescriptor: ValueParameterDescriptor) {
|
||||
argumentsByParameterIndex[valueParameterDescriptor.index]?.detach()
|
||||
argumentsByParameterIndex[valueParameterDescriptor.index] = null
|
||||
}
|
||||
|
||||
override fun getChildExpression(index: Int): IrExpression? =
|
||||
when (index) {
|
||||
DISPATCH_RECEIVER_INDEX ->
|
||||
dispatchReceiver
|
||||
EXTENSION_RECEIVER_INDEX ->
|
||||
extensionReceiver
|
||||
else ->
|
||||
argumentsByParameterIndex.getOrNull(index)
|
||||
}
|
||||
|
||||
override fun replaceChildExpression(oldChild: IrExpression, newChild: IrExpression) {
|
||||
validateChild(oldChild)
|
||||
when (oldChild.index) {
|
||||
DISPATCH_RECEIVER_INDEX ->
|
||||
dispatchReceiver = newChild
|
||||
EXTENSION_RECEIVER_INDEX ->
|
||||
extensionReceiver = newChild
|
||||
else ->
|
||||
putValueArgument(oldChild.index, newChild)
|
||||
}
|
||||
}
|
||||
|
||||
override fun <D> acceptValueArguments(visitor: IrElementVisitor<Unit, D>, data: D) {
|
||||
for (valueArgument in argumentsByParameterIndex) {
|
||||
valueArgument?.let { it.accept(visitor, data) }
|
||||
}
|
||||
}
|
||||
|
||||
override fun <D> acceptChildExpressions(visitor: IrElementVisitor<Unit, D>, data: D) {
|
||||
dispatchReceiver?.accept(visitor, data)
|
||||
extensionReceiver?.accept(visitor, data)
|
||||
acceptValueArguments(visitor, data)
|
||||
}
|
||||
|
||||
override fun <D> acceptChildren(visitor: IrElementVisitor<Unit, D>, data: D) {
|
||||
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)
|
||||
}
|
||||
@@ -0,0 +1,69 @@
|
||||
/*
|
||||
* 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")
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,77 @@
|
||||
/*
|
||||
* 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.*
|
||||
import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
|
||||
|
||||
interface IrDeclarationReference : IrExpression {
|
||||
val descriptor: DeclarationDescriptor
|
||||
}
|
||||
|
||||
interface IrVariableReference : IrDeclarationReference {
|
||||
override val descriptor: VariableDescriptor
|
||||
}
|
||||
|
||||
interface IrSingletonReference : IrDeclarationReference {
|
||||
override val descriptor: ClassDescriptor
|
||||
}
|
||||
|
||||
interface IrExtensionReceiverReference : IrDeclarationReference {
|
||||
override val descriptor: CallableDescriptor
|
||||
}
|
||||
|
||||
abstract class IrDeclarationReferenceBase<out D : DeclarationDescriptor>(
|
||||
startOffset: Int,
|
||||
endOffset: Int,
|
||||
type: KotlinType,
|
||||
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(
|
||||
startOffset: Int,
|
||||
endOffset: Int,
|
||||
type: KotlinType,
|
||||
descriptor: ClassDescriptor
|
||||
) : IrDeclarationReferenceBase<ClassDescriptor>(startOffset, endOffset, type, descriptor), IrSingletonReference {
|
||||
override fun <R, D> accept(visitor: IrElementVisitor<R, D>, data: D): R =
|
||||
visitor.visitSingletonReference(this, data)
|
||||
}
|
||||
|
||||
|
||||
class IrExtensionReceiverReferenceImpl(
|
||||
startOffset: Int,
|
||||
endOffset: Int,
|
||||
type: KotlinType,
|
||||
override val descriptor: CallableDescriptor
|
||||
) : IrTerminalExpressionBase(startOffset, endOffset, type), IrExtensionReceiverReference {
|
||||
override fun <R, D> accept(visitor: IrElementVisitor<R, D>, data: D): R {
|
||||
return visitor.visitExtensionReceiverReference(this, data)
|
||||
}
|
||||
}
|
||||
@@ -22,10 +22,11 @@ import org.jetbrains.kotlin.types.KotlinType
|
||||
class IrDummyExpression(
|
||||
startOffset: Int,
|
||||
endOffset: Int,
|
||||
type: KotlinType
|
||||
type: KotlinType,
|
||||
val description: String
|
||||
) : IrExpressionBase(startOffset, endOffset, type) {
|
||||
override fun <R, D> accept(visitor: IrElementVisitor<R, D>, data: D): R =
|
||||
visitor.visitElement(this, data)
|
||||
visitor.visitDummyExpression(this, data)
|
||||
|
||||
override fun <D> acceptChildren(visitor: IrElementVisitor<Unit, D>, data: D) {
|
||||
// No children
|
||||
|
||||
@@ -18,6 +18,7 @@ package org.jetbrains.kotlin.ir.expressions
|
||||
|
||||
import org.jetbrains.kotlin.ir.IrElement
|
||||
import org.jetbrains.kotlin.ir.IrElementBase
|
||||
import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
|
||||
|
||||
@@ -53,4 +54,14 @@ abstract class IrExpressionBase(
|
||||
this.parent = parent
|
||||
this.index = index
|
||||
}
|
||||
}
|
||||
|
||||
abstract class IrTerminalExpressionBase(
|
||||
startOffset: Int,
|
||||
endOffset: Int,
|
||||
type: KotlinType
|
||||
) : IrExpressionBase(startOffset, endOffset, type) {
|
||||
override fun <D> acceptChildren(visitor: IrElementVisitor<Unit, D>, data: D) {
|
||||
// No children
|
||||
}
|
||||
}
|
||||
@@ -33,16 +33,6 @@ interface IrExpressionOwner1 : IrExpressionOwner {
|
||||
}
|
||||
}
|
||||
|
||||
interface IrExpressionOwner2 : IrExpressionOwner {
|
||||
var childExpression1: IrExpression?
|
||||
var childExpression2: IrExpression?
|
||||
|
||||
companion object {
|
||||
const val EXPRESSION1_INDEX = 1
|
||||
const val EXPRESSION2_INDEX = 2
|
||||
}
|
||||
}
|
||||
|
||||
interface IrExpressionOwnerN : IrExpressionOwner {
|
||||
val childExpressions: List<IrExpression>
|
||||
fun addChildExpression(child: IrExpression)
|
||||
|
||||
@@ -48,14 +48,10 @@ class IrLiteralExpressionImpl<out T> (
|
||||
type: KotlinType,
|
||||
override val kind: IrLiteralKind<T>,
|
||||
override val value: T
|
||||
) : IrExpressionBase(startOffset, endOffset, type), IrLiteralExpression<T> {
|
||||
) : IrTerminalExpressionBase(startOffset, endOffset, type), IrLiteralExpression<T> {
|
||||
override fun <R, D> accept(visitor: IrElementVisitor<R, D>, data: D): R =
|
||||
visitor.visitLiteral(this, data)
|
||||
|
||||
override fun <D> acceptChildren(visitor: IrElementVisitor<Unit, D>, data: D) {
|
||||
// No children
|
||||
}
|
||||
|
||||
companion object {
|
||||
fun string(startOffset: Int, endOffset: Int, type: KotlinType, value: String): IrLiteralExpressionImpl<String> =
|
||||
IrLiteralExpressionImpl(startOffset, endOffset, type, IrLiteralKind.String, value)
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
/*
|
||||
* 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.ClassDescriptor
|
||||
import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
|
||||
interface IrThisExpression : IrExpression {
|
||||
val classDescriptor: ClassDescriptor
|
||||
}
|
||||
|
||||
class IrThisExpressionImpl(
|
||||
startOffset: Int,
|
||||
endOffset: Int,
|
||||
type: KotlinType,
|
||||
override val classDescriptor: ClassDescriptor
|
||||
) : IrTerminalExpressionBase(startOffset, endOffset, type), IrThisExpression {
|
||||
override fun <R, D> accept(visitor: IrElementVisitor<R, D>, data: D): R {
|
||||
return visitor.visitThisExpression(this, data)
|
||||
}
|
||||
}
|
||||
+44
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
* Copyright 2010-2016 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.ir.expressions
|
||||
|
||||
import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
|
||||
enum class IrTypeOperator {
|
||||
SMART_AS,
|
||||
AS,
|
||||
AS_SAFE,
|
||||
IS;
|
||||
}
|
||||
|
||||
interface IrTypeOperatorExpression : IrExpression, IrCompoundExpression1 {
|
||||
val operator: IrTypeOperator
|
||||
val typeOperand: KotlinType
|
||||
}
|
||||
|
||||
class IrTypeOperatorExpressionImpl(
|
||||
startOffset: Int,
|
||||
endOffset: Int,
|
||||
type: KotlinType,
|
||||
override val operator: IrTypeOperator,
|
||||
override val typeOperand: KotlinType
|
||||
) : IrCompoundExpression1Base(startOffset, endOffset, type), IrTypeOperatorExpression {
|
||||
override fun <R, D> accept(visitor: IrElementVisitor<R, D>, data: D): R {
|
||||
return visitor.visitTypeOperatorExpression(this, data)
|
||||
}
|
||||
}
|
||||
@@ -18,23 +18,52 @@ package org.jetbrains.kotlin.ir.util
|
||||
|
||||
import org.jetbrains.kotlin.ir.IrElement
|
||||
import org.jetbrains.kotlin.ir.declarations.IrDeclaration
|
||||
import org.jetbrains.kotlin.ir.expressions.IrCallExpression
|
||||
import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
|
||||
import org.jetbrains.kotlin.utils.Printer
|
||||
|
||||
fun IrDeclaration.dump(): String {
|
||||
val sb = StringBuilder()
|
||||
accept(DumpIrTreeVisitor(sb), null)
|
||||
accept(DumpIrTreeVisitor(sb), "")
|
||||
return sb.toString()
|
||||
}
|
||||
|
||||
class DumpIrTreeVisitor(out: Appendable): IrElementVisitor<Unit, Nothing?> {
|
||||
class DumpIrTreeVisitor(out: Appendable): IrElementVisitor<Unit, String> {
|
||||
val printer = Printer(out, " ")
|
||||
val elementRenderer = RenderIrElementVisitor()
|
||||
|
||||
override fun visitElement(element: IrElement, data: Nothing?) {
|
||||
printer.println(element.accept(elementRenderer, null))
|
||||
override fun visitElement(element: IrElement, data: String) {
|
||||
element.dumpLabeledSubTree(data)
|
||||
}
|
||||
|
||||
override fun visitCallExpression(expression: IrCallExpression, data: String) {
|
||||
expression.dumpLabeledElementWith(data) {
|
||||
expression.dispatchReceiver?.accept(this, "\$this")
|
||||
expression.extensionReceiver?.accept(this, "\$receiver")
|
||||
for (valueParameter in expression.callee.valueParameters) {
|
||||
expression.getValueArgument(valueParameter)?.accept(this, valueParameter.name.asString())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private inline fun IrElement.dumpLabeledElementWith(label: String, body: () -> Unit) {
|
||||
printer.println(accept(elementRenderer, null).withLabel(label))
|
||||
indented(body)
|
||||
}
|
||||
|
||||
private fun IrElement.dumpLabeledSubTree(label: String) {
|
||||
printer.println(accept(elementRenderer, null).withLabel(label))
|
||||
indented {
|
||||
acceptChildren(this@DumpIrTreeVisitor, "")
|
||||
}
|
||||
}
|
||||
|
||||
private inline fun indented(body: () -> Unit) {
|
||||
printer.pushIndent()
|
||||
element.acceptChildren(this, null)
|
||||
body()
|
||||
printer.popIndent()
|
||||
}
|
||||
|
||||
private fun String.withLabel(label: String) =
|
||||
if (label.isEmpty()) this else "$label: $this"
|
||||
}
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
package org.jetbrains.kotlin.ir.util
|
||||
|
||||
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
||||
import org.jetbrains.kotlin.ir.IrElement
|
||||
import org.jetbrains.kotlin.ir.declarations.*
|
||||
import org.jetbrains.kotlin.ir.expressions.*
|
||||
@@ -27,40 +28,58 @@ import org.jetbrains.kotlin.renderer.OverrideRenderingPolicy
|
||||
|
||||
class RenderIrElementVisitor : IrElementVisitor<String, Nothing?> {
|
||||
override fun visitElement(element: IrElement, data: Nothing?): String =
|
||||
"??? ${element.javaClass.simpleName}"
|
||||
"? ${element.javaClass.simpleName}"
|
||||
|
||||
override fun visitDeclaration(declaration: IrDeclaration, data: Nothing?): String =
|
||||
"??? ${declaration.javaClass.simpleName} ${declaration.descriptor?.name}"
|
||||
"? ${declaration.javaClass.simpleName} ${declaration.descriptor?.name}"
|
||||
|
||||
override fun visitFile(declaration: IrFile, data: Nothing?): String =
|
||||
"IrFile ${declaration.name}"
|
||||
|
||||
override fun visitFunction(declaration: IrFunction, data: Nothing?): String =
|
||||
"IrFunction ${declaration.renderDescriptor()}"
|
||||
"IrFunction ${declaration.descriptor.render()}"
|
||||
|
||||
override fun visitProperty(declaration: IrProperty, data: Nothing?): String =
|
||||
"IrProperty ${declaration.renderDescriptor()} getter=${declaration.getter?.name()} setter=${declaration.setter?.name()}"
|
||||
"IrProperty ${declaration.descriptor.render()} getter=${declaration.getter?.name()} setter=${declaration.setter?.name()}"
|
||||
|
||||
override fun visitPropertyGetter(declaration: IrPropertyGetter, data: Nothing?): String =
|
||||
"IrPropertyGetter ${declaration.renderDescriptor()} property=${declaration.property?.name()}"
|
||||
"IrPropertyGetter ${declaration.descriptor.render()} property=${declaration.property?.name()}"
|
||||
|
||||
override fun visitPropertySetter(declaration: IrPropertySetter, data: Nothing?): String =
|
||||
"IrPropertySetter ${declaration.renderDescriptor()} property=${declaration.property?.name()}"
|
||||
"IrPropertySetter ${declaration.descriptor.render()} property=${declaration.property?.name()}"
|
||||
|
||||
override fun visitExpressionBody(body: IrExpressionBody, data: Nothing?): String =
|
||||
"IrExpressionBody"
|
||||
|
||||
override fun visitExpression(expression: IrExpression, data: Nothing?): String =
|
||||
"??? ${expression.javaClass.simpleName} type=${expression.renderType()}"
|
||||
"? ${expression.javaClass.simpleName} type=${expression.renderType()}"
|
||||
|
||||
override fun <T> visitLiteral(expression: IrLiteralExpression<T>, data: Nothing?): String =
|
||||
"IrLiteral ${expression.kind} type=${expression.renderType()} value='${expression.value}'"
|
||||
"LITERAL ${expression.kind} type=${expression.renderType()} value='${expression.value}'"
|
||||
|
||||
override fun visitBlockExpression(expression: IrBlockExpression, data: Nothing?): String =
|
||||
"IrBlockExpression type=${expression.renderType()}"
|
||||
"BLOCK type=${expression.renderType()}"
|
||||
|
||||
override fun visitReturnExpression(expression: IrReturnExpression, data: Nothing?): String =
|
||||
"IrReturnExpression type=${expression.renderType()}"
|
||||
"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 =
|
||||
"\$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 ${expression.callee.name} ${expression.operator ?: ""}"
|
||||
|
||||
override fun visitDummyExpression(expression: IrDummyExpression, data: Nothing?): String =
|
||||
"DUMMY ${expression.description}"
|
||||
|
||||
companion object {
|
||||
private val DESCRIPTOR_RENDERER = DescriptorRenderer.withOptions {
|
||||
@@ -72,8 +91,13 @@ class RenderIrElementVisitor : IrElementVisitor<String, Nothing?> {
|
||||
modifiers = DescriptorRendererModifier.ALL
|
||||
}
|
||||
|
||||
private fun IrDeclaration.name(): String = descriptor?.let { it.name.toString() } ?: "<none>"
|
||||
private fun IrDeclaration.renderDescriptor(): String = descriptor?.let { DESCRIPTOR_RENDERER.render(it) } ?: "<none>"
|
||||
private fun IrExpression.renderType(): String = DESCRIPTOR_RENDERER.renderType(type)
|
||||
internal fun IrDeclaration.name(): String =
|
||||
descriptor?.let { it.name.toString() } ?: "<none>"
|
||||
|
||||
internal fun DeclarationDescriptor.render(): String =
|
||||
DESCRIPTOR_RENDERER.render(this)
|
||||
|
||||
internal fun IrExpression.renderType(): String =
|
||||
DESCRIPTOR_RENDERER.renderType(type)
|
||||
}
|
||||
}
|
||||
@@ -43,4 +43,18 @@ interface IrElementVisitor<out R, in D> {
|
||||
fun visitReturnExpression(expression: IrReturnExpression, 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 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 visitCallExpression(expression: IrCallExpression, 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
|
||||
fun visitDummyExpression(expression: IrDummyExpression, data: D) = visitExpression(expression, data)
|
||||
|
||||
|
||||
}
|
||||
|
||||
+2
-2
@@ -1,5 +1,5 @@
|
||||
IrFile /boxOk.kt
|
||||
IrFunction public fun box(): kotlin.String
|
||||
IrExpressionBody
|
||||
IrReturnExpression type=kotlin.String
|
||||
IrLiteral String type=kotlin.String value='OK'
|
||||
RETURN type=kotlin.String
|
||||
LITERAL String type=kotlin.String value='OK'
|
||||
|
||||
Vendored
+8
@@ -0,0 +1,8 @@
|
||||
fun foo(x: Int, y: Int) = x
|
||||
fun bar(x: Int) = foo(x, 1)
|
||||
fun qux(x: Int) = foo(foo(x, x), x)
|
||||
|
||||
fun Int.ext1() = this
|
||||
fun Int.ext2(x: Int) = foo(this, x)
|
||||
|
||||
// IR_FILE_TXT calls.txt
|
||||
+29
@@ -0,0 +1,29 @@
|
||||
IrFile /calls.kt
|
||||
IrFunction public fun foo(/*0*/ x: kotlin.Int, /*1*/ y: kotlin.Int): kotlin.Int
|
||||
IrExpressionBody
|
||||
RETURN type=kotlin.Int
|
||||
VAR x
|
||||
IrFunction public fun bar(/*0*/ x: kotlin.Int): kotlin.Int
|
||||
IrExpressionBody
|
||||
RETURN type=kotlin.Int
|
||||
CALL foo
|
||||
x: 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
|
||||
IrFunction public fun kotlin.Int.ext1(): kotlin.Int
|
||||
IrExpressionBody
|
||||
RETURN type=kotlin.Int
|
||||
DUMMY KtThisExpression
|
||||
IrFunction public fun kotlin.Int.ext2(/*0*/ x: kotlin.Int): kotlin.Int
|
||||
IrExpressionBody
|
||||
RETURN type=kotlin.Int
|
||||
CALL foo
|
||||
x: DUMMY KtThisExpression
|
||||
y: VAR x
|
||||
@@ -0,0 +1,4 @@
|
||||
val String.okext: String get() = "OK"
|
||||
fun String.test5() = okext
|
||||
|
||||
// IR_FILE_TXT extensionPropertyGetterCall.txt
|
||||
@@ -0,0 +1,11 @@
|
||||
IrFile /extensionPropertyGetterCall.kt
|
||||
IrProperty public val kotlin.String.okext: kotlin.String getter=<get-okext> setter=null
|
||||
IrPropertyGetter public fun kotlin.String.<get-okext>(): kotlin.String property=okext
|
||||
IrExpressionBody
|
||||
RETURN type=kotlin.String
|
||||
LITERAL String type=kotlin.String value='OK'
|
||||
IrFunction public fun kotlin.String.test5(): kotlin.String
|
||||
IrExpressionBody
|
||||
RETURN type=kotlin.String
|
||||
CALL okext PROPERTY_GET
|
||||
$receiver: $RECEIVER of: test5
|
||||
+19
@@ -0,0 +1,19 @@
|
||||
val ok = "OK"
|
||||
val ok2 = ok
|
||||
val ok3: String get() = "OK"
|
||||
|
||||
fun test1() = ok
|
||||
|
||||
fun test2(x: String) = x
|
||||
|
||||
fun test3(): String {
|
||||
val x = "OK"
|
||||
return x
|
||||
}
|
||||
|
||||
fun test4() = ok3
|
||||
|
||||
val String.okext: String get() = "OK"
|
||||
fun String.test5() = okext
|
||||
|
||||
// IR_FILE_TXT references.txt
|
||||
+42
@@ -0,0 +1,42 @@
|
||||
IrFile /references.kt
|
||||
IrProperty public val ok: kotlin.String = "OK" getter=null setter=null
|
||||
IrExpressionBody
|
||||
RETURN type=kotlin.String
|
||||
LITERAL String type=kotlin.String value='OK'
|
||||
IrProperty public val ok2: kotlin.String = "OK" getter=null setter=null
|
||||
IrExpressionBody
|
||||
RETURN type=kotlin.String
|
||||
CALL ok PROPERTY_GET
|
||||
IrProperty public val ok3: kotlin.String getter=<get-ok3> setter=null
|
||||
IrPropertyGetter public fun <get-ok3>(): kotlin.String property=ok3
|
||||
IrExpressionBody
|
||||
RETURN type=kotlin.String
|
||||
LITERAL String type=kotlin.String value='OK'
|
||||
IrFunction public fun test1(): kotlin.String
|
||||
IrExpressionBody
|
||||
RETURN type=kotlin.String
|
||||
CALL ok PROPERTY_GET
|
||||
IrFunction public fun test2(/*0*/ x: kotlin.String): kotlin.String
|
||||
IrExpressionBody
|
||||
RETURN type=kotlin.String
|
||||
VAR x
|
||||
IrFunction public fun test3(): kotlin.String
|
||||
IrExpressionBody
|
||||
BLOCK type=kotlin.Nothing
|
||||
DUMMY KtProperty
|
||||
RETURN type=kotlin.Nothing
|
||||
VAR x
|
||||
IrFunction public fun test4(): kotlin.String
|
||||
IrExpressionBody
|
||||
RETURN type=kotlin.String
|
||||
CALL ok3 PROPERTY_GET
|
||||
IrProperty public val kotlin.String.okext: kotlin.String getter=<get-okext> setter=null
|
||||
IrPropertyGetter public fun kotlin.String.<get-okext>(): kotlin.String property=okext
|
||||
IrExpressionBody
|
||||
RETURN type=kotlin.String
|
||||
LITERAL String type=kotlin.String value='OK'
|
||||
IrFunction public fun kotlin.String.test5(): kotlin.String
|
||||
IrExpressionBody
|
||||
RETURN type=kotlin.String
|
||||
CALL okext PROPERTY_GET
|
||||
$receiver: $RECEIVER of: test5
|
||||
+12
-12
@@ -1,27 +1,27 @@
|
||||
IrFile /smoke.kt
|
||||
IrFunction public fun testFun(): kotlin.String
|
||||
IrExpressionBody
|
||||
IrBlockExpression type=kotlin.Nothing
|
||||
IrReturnExpression type=kotlin.Nothing
|
||||
IrLiteral String type=kotlin.String value='OK'
|
||||
BLOCK type=kotlin.Nothing
|
||||
RETURN type=kotlin.Nothing
|
||||
LITERAL String type=kotlin.String value='OK'
|
||||
IrProperty public val testSimpleVal: kotlin.Int = 1 getter=null setter=null
|
||||
IrExpressionBody
|
||||
IrReturnExpression type=kotlin.Int
|
||||
IrLiteral Int type=kotlin.Int value='1'
|
||||
RETURN type=kotlin.Int
|
||||
LITERAL Int type=kotlin.Int value='1'
|
||||
IrProperty public val testValWithGetter: kotlin.Int getter=<get-testValWithGetter> setter=null
|
||||
IrPropertyGetter public fun <get-testValWithGetter>(): kotlin.Int property=testValWithGetter
|
||||
IrExpressionBody
|
||||
IrReturnExpression type=kotlin.Int
|
||||
IrLiteral Int type=kotlin.Int value='42'
|
||||
RETURN type=kotlin.Int
|
||||
LITERAL Int type=kotlin.Int value='42'
|
||||
IrProperty public var testSimpleVar: kotlin.Int getter=null setter=null
|
||||
IrExpressionBody
|
||||
IrReturnExpression type=kotlin.Int
|
||||
IrLiteral Int type=kotlin.Int value='2'
|
||||
RETURN type=kotlin.Int
|
||||
LITERAL Int type=kotlin.Int value='2'
|
||||
IrProperty public var testVarWithAccessors: kotlin.Int getter=<get-testVarWithAccessors> setter=<set-testVarWithAccessors>
|
||||
IrPropertyGetter public fun <get-testVarWithAccessors>(): kotlin.Int property=testVarWithAccessors
|
||||
IrExpressionBody
|
||||
IrReturnExpression type=kotlin.Int
|
||||
IrLiteral Int type=kotlin.Int value='42'
|
||||
RETURN type=kotlin.Int
|
||||
LITERAL Int type=kotlin.Int value='42'
|
||||
IrPropertySetter public fun <set-testVarWithAccessors>(/*0*/ v: kotlin.Int): kotlin.Unit property=testVarWithAccessors
|
||||
IrExpressionBody
|
||||
IrBlockExpression type=kotlin.Unit
|
||||
BLOCK type=kotlin.Unit
|
||||
|
||||
@@ -41,6 +41,24 @@ public class IrTextTestCaseGenerated extends AbstractIrTextTestCase {
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("calls.kt")
|
||||
public void testCalls() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/ir/irText/calls.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("extensionPropertyGetterCall.kt")
|
||||
public void testExtensionPropertyGetterCall() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/ir/irText/extensionPropertyGetterCall.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("references.kt")
|
||||
public void testReferences() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/ir/irText/references.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("smoke.kt")
|
||||
public void testSmoke() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/ir/irText/smoke.kt");
|
||||
|
||||
Reference in New Issue
Block a user