Simplify IrElement hierarchy.
IrDeclaration can be now hosted under IrExpression (as IrStatement).
This commit is contained in:
committed by
Dmitry Petrov
parent
55eb79febf
commit
37cce98d19
@@ -17,6 +17,7 @@
|
||||
package org.jetbrains.kotlin.psi2ir
|
||||
|
||||
import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.ir.assertCast
|
||||
import org.jetbrains.kotlin.ir.expressions.*
|
||||
import org.jetbrains.kotlin.psi.KtExpression
|
||||
import org.jetbrains.kotlin.psi.psiUtil.endOffset
|
||||
@@ -29,7 +30,7 @@ import java.util.*
|
||||
|
||||
class IrCallGenerator(
|
||||
override val context: IrGeneratorContext,
|
||||
val irExpressionGenerator: IrExpressionGenerator
|
||||
val irStatementGenerator: IrStatementGenerator
|
||||
) : IrGenerator {
|
||||
fun generateCall(
|
||||
ktExpression: KtExpression,
|
||||
@@ -92,7 +93,7 @@ class IrCallGenerator(
|
||||
for (index in valueArguments!!.indices) {
|
||||
val valueArgument = valueArguments[index]
|
||||
val irArgument = generateValueArgument(valueArgument) ?: continue
|
||||
irCall.putValueArgument(index, irArgument)
|
||||
irCall.putArgument(index, irArgument)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -105,17 +106,16 @@ class IrCallGenerator(
|
||||
resultType: KotlinType
|
||||
): IrExpression {
|
||||
val valueArgumentsInEvaluationOrder = resolvedCall.valueArguments.values
|
||||
val hasResult = isUsedAsExpression(ktExpression)
|
||||
val irBlock = IrBlockExpressionImpl(ktExpression.startOffset, ktExpression.endOffset, resultType, hasResult)
|
||||
|
||||
val irBlock = IrBlockExpressionImpl(ktExpression.startOffset, ktExpression.endOffset, resultType,
|
||||
hasResult = isUsedAsExpression(ktExpression),
|
||||
isDesugared = true)
|
||||
|
||||
val temporaryVariablesForValueArguments = HashMap<ResolvedValueArgument, Pair<VariableDescriptor, IrExpression>>()
|
||||
for (valueArgument in valueArgumentsInEvaluationOrder) {
|
||||
val irArgument = generateValueArgument(valueArgument) ?: continue
|
||||
val irTemporary = irExpressionGenerator.declarationFactory.createTemporaryVariable(irArgument)
|
||||
val irTemporaryDeclaration = IrLocalVariableDeclarationExpressionImpl(irArgument.startOffset, irArgument.endOffset)
|
||||
irTemporaryDeclaration.childDeclaration = irTemporary
|
||||
|
||||
irBlock.addChildExpression(irTemporaryDeclaration)
|
||||
val irTemporary = irStatementGenerator.declarationFactory.createTemporaryVariable(irArgument)
|
||||
irBlock.addStatement(irTemporary)
|
||||
|
||||
temporaryVariablesForValueArguments[valueArgument] = Pair(irTemporary.descriptor, irArgument)
|
||||
}
|
||||
@@ -124,16 +124,16 @@ class IrCallGenerator(
|
||||
val (temporaryDescriptor, irArgument) = temporaryVariablesForValueArguments[valueArgument]!!
|
||||
val irGetTemporary = IrGetVariableExpressionImpl(irArgument.startOffset, irArgument.endOffset,
|
||||
irArgument.type, temporaryDescriptor)
|
||||
irCall.putValueArgument(index, irGetTemporary)
|
||||
irCall.putArgument(index, irGetTemporary)
|
||||
}
|
||||
|
||||
irBlock.addChildExpression(irCall)
|
||||
irBlock.addStatement(irCall)
|
||||
|
||||
return irBlock
|
||||
}
|
||||
|
||||
// TODO smart casts on implicit receivers
|
||||
private fun generateReceiver(ktExpression: KtExpression, receiver: ReceiverValue?): IrExpression? =
|
||||
fun generateReceiver(ktExpression: KtExpression, receiver: ReceiverValue?): IrExpression? =
|
||||
when (receiver) {
|
||||
is ImplicitClassReceiver ->
|
||||
IrThisExpressionImpl(ktExpression.startOffset, ktExpression.startOffset, receiver.type, receiver.classDescriptor)
|
||||
@@ -142,7 +142,7 @@ class IrCallGenerator(
|
||||
IrThisExpressionImpl(receiverExpression.startOffset, receiverExpression.endOffset, receiver.type, receiver.classDescriptor)
|
||||
} ?: TODO("Non-implicit ThisClassReceiver should be an expression receiver")
|
||||
is ExpressionReceiver ->
|
||||
irExpressionGenerator.generateExpression(receiver.expression)
|
||||
irStatementGenerator.generateStatement(receiver.expression).assertCast()
|
||||
is ClassValueReceiver ->
|
||||
IrGetObjectValueExpressionImpl(receiver.expression.startOffset, receiver.expression.endOffset, receiver.type,
|
||||
receiver.classQualifier.descriptor)
|
||||
@@ -155,12 +155,12 @@ class IrCallGenerator(
|
||||
TODO("Receiver: ${receiver.javaClass.simpleName}")
|
||||
}
|
||||
|
||||
private fun generateValueArgument(valueArgument: ResolvedValueArgument): IrExpression? {
|
||||
fun generateValueArgument(valueArgument: ResolvedValueArgument): IrExpression? {
|
||||
when (valueArgument) {
|
||||
is DefaultValueArgument ->
|
||||
return null
|
||||
is ExpressionValueArgument ->
|
||||
return irExpressionGenerator.generateExpression(valueArgument.valueArgument!!.getArgumentExpression()!!)
|
||||
return irStatementGenerator.generateStatement(valueArgument.valueArgument!!.getArgumentExpression()!!).assertCast()
|
||||
is VarargValueArgument ->
|
||||
TODO("vararg")
|
||||
else ->
|
||||
|
||||
@@ -70,20 +70,22 @@ class IrLocalDeclarationsFactory(val scopeOwner: DeclarationDescriptor) : IrDecl
|
||||
fun createDescriptorForTemporaryVariable(type: KotlinType): IrTemporaryVariableDescriptor =
|
||||
IrTemporaryVariableDescriptorImpl(scopeOwner, Name.identifier("tmp${nextTemporaryIndex()}"), type)
|
||||
|
||||
fun createTemporaryVariable(ktElement: KtElement, type: KotlinType): IrLocalVariable =
|
||||
IrLocalVariableImpl(ktElement.startOffset, ktElement.endOffset,
|
||||
IrDeclarationOriginKind.IR_TEMPORARY_VARIABLE,
|
||||
createDescriptorForTemporaryVariable(type))
|
||||
fun createTemporaryVariable(ktElement: KtElement, type: KotlinType): IrVariable =
|
||||
IrVariableImpl(ktElement.startOffset, ktElement.endOffset,
|
||||
IrDeclarationOriginKind.IR_TEMPORARY_VARIABLE,
|
||||
createDescriptorForTemporaryVariable(type))
|
||||
|
||||
fun createTemporaryVariable(irExpression: IrExpression): IrLocalVariable =
|
||||
IrLocalVariableImpl(irExpression.startOffset, irExpression.endOffset,
|
||||
IrDeclarationOriginKind.IR_TEMPORARY_VARIABLE,
|
||||
createDescriptorForTemporaryVariable(irExpression.type
|
||||
?: throw AssertionError("No type for $irExpression"))
|
||||
).apply { initializerExpression = irExpression }
|
||||
fun createTemporaryVariable(irExpression: IrExpression): IrVariable =
|
||||
IrVariableImpl(irExpression.startOffset, irExpression.endOffset,
|
||||
IrDeclarationOriginKind.IR_TEMPORARY_VARIABLE,
|
||||
createDescriptorForTemporaryVariable(
|
||||
irExpression.type
|
||||
?: throw AssertionError("No type for $irExpression")
|
||||
)
|
||||
).apply { initializer = irExpression }
|
||||
|
||||
fun createLocalVariable(ktElement: KtElement, descriptor: VariableDescriptor): IrLocalVariable =
|
||||
IrLocalVariableImpl(ktElement.startOffset, ktElement.endOffset,
|
||||
IrDeclarationOriginKind.DEFINED,
|
||||
descriptor)
|
||||
fun createLocalVariable(ktElement: KtElement, descriptor: VariableDescriptor): IrVariable =
|
||||
IrVariableImpl(ktElement.startOffset, ktElement.endOffset,
|
||||
IrDeclarationOriginKind.DEFINED,
|
||||
descriptor)
|
||||
}
|
||||
|
||||
@@ -20,6 +20,7 @@ import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.PropertyDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.PropertyGetterDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.PropertySetterDescriptor
|
||||
import org.jetbrains.kotlin.ir.assertCast
|
||||
import org.jetbrains.kotlin.ir.declarations.*
|
||||
import org.jetbrains.kotlin.ir.expressions.IrBody
|
||||
import org.jetbrains.kotlin.ir.expressions.IrExpressionBodyImpl
|
||||
@@ -33,11 +34,9 @@ interface IrDeclarationGenerator : IrGenerator
|
||||
|
||||
abstract class IrDeclarationGeneratorBase(
|
||||
override val context: IrGeneratorContext,
|
||||
val container: IrDeclarationOwnerN,
|
||||
val declarationFactory: IrDeclarationFactoryBase
|
||||
) : IrDeclarationGenerator {
|
||||
private fun <D : IrMemberDeclaration> D.register(): D =
|
||||
apply { container.addChildDeclaration(this) }
|
||||
protected abstract fun <D : IrDeclaration> D.register(): D
|
||||
|
||||
fun generateAnnotationEntries(annotationEntries: List<KtAnnotationEntry>) {
|
||||
// TODO create IrAnnotation's for each KtAnnotationEntry
|
||||
@@ -50,10 +49,10 @@ abstract class IrDeclarationGeneratorBase(
|
||||
generateFunctionDeclaration(ktDeclaration)
|
||||
is KtProperty ->
|
||||
generatePropertyDeclaration(ktDeclaration)
|
||||
is KtClassOrObject ->
|
||||
TODO("classOrObject")
|
||||
is KtTypeAlias ->
|
||||
TODO("typealias")
|
||||
is KtClassOrObject -> {}
|
||||
// TODO("classOrObject")
|
||||
is KtTypeAlias -> {}
|
||||
// TODO("typealias")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -90,6 +89,6 @@ abstract class IrDeclarationGeneratorBase(
|
||||
|
||||
fun generateExpressionBody(scopeOwner: DeclarationDescriptor, ktBody: KtExpression): IrBody =
|
||||
IrExpressionBodyImpl(ktBody.startOffset, ktBody.endOffset).apply {
|
||||
argument = IrExpressionGenerator(context, IrLocalDeclarationsFactory(scopeOwner)).generateExpression(ktBody)
|
||||
expression = IrStatementGenerator(context, IrLocalDeclarationsFactory(scopeOwner)).generateStatement(ktBody).assertCast()
|
||||
}
|
||||
}
|
||||
@@ -16,17 +16,20 @@
|
||||
|
||||
package org.jetbrains.kotlin.psi2ir
|
||||
|
||||
import org.jetbrains.kotlin.ir.declarations.IrDeclaration
|
||||
import org.jetbrains.kotlin.ir.declarations.IrFile
|
||||
import org.jetbrains.kotlin.ir.declarations.IrFileImpl
|
||||
import org.jetbrains.kotlin.psi.KtFile
|
||||
|
||||
class IrFileGenerator(
|
||||
private val ktFile: KtFile,
|
||||
private val irFile: IrFile,
|
||||
context: IrGeneratorContext,
|
||||
irFile: IrFile,
|
||||
parent: IrModuleGenerator,
|
||||
declarationFactory: IrDeclarationFactory
|
||||
) : IrDeclarationGeneratorBase(context, irFile, declarationFactory) {
|
||||
) : IrDeclarationGeneratorBase(context, declarationFactory) {
|
||||
override fun <D : IrDeclaration> D.register(): D =
|
||||
apply { irFile.addDeclaration(this) }
|
||||
|
||||
fun generateFileContent() {
|
||||
generateAnnotationEntries(ktFile.annotationEntries)
|
||||
|
||||
|
||||
@@ -37,6 +37,9 @@ fun IrGenerator.getTypeOrFail(key: KtExpression): KotlinType =
|
||||
fun <K, V : Any> IrGenerator.get(slice: ReadOnlySlice<K, V>, key: K): V? =
|
||||
context.bindingContext[slice, key]
|
||||
|
||||
fun <K, V : Any> IrGenerator.getOrFail(slice: ReadOnlySlice<K, V>, key: K): V =
|
||||
context.bindingContext[slice, key] ?: throw RuntimeException("No $slice for $key")
|
||||
|
||||
inline fun <K, V : Any> IrGenerator.getOrFail(slice: ReadOnlySlice<K, V>, key: K, message: (K) -> String): V =
|
||||
context.bindingContext[slice, key] ?: throw RuntimeException(message(key))
|
||||
|
||||
|
||||
@@ -22,14 +22,14 @@ import org.jetbrains.kotlin.resolve.BindingContext
|
||||
class IrModuleGenerator(override val context: IrGeneratorContext) : IrDeclarationGenerator {
|
||||
fun generateModuleContent() {
|
||||
for (ktFile in context.inputFiles) {
|
||||
val packageFragmentDescriptor = getOrFail(BindingContext.FILE_TO_PACKAGE_FRAGMENT, ktFile) { "no package fragment for file" }
|
||||
val packageFragmentDescriptor = getOrFail(BindingContext.FILE_TO_PACKAGE_FRAGMENT, ktFile)
|
||||
val fileEntry = context.sourceManager.getOrCreateFileEntry(ktFile)
|
||||
val fileName = fileEntry.getRecognizableName()
|
||||
val irFile = IrFileImpl(fileEntry, fileName, packageFragmentDescriptor)
|
||||
context.sourceManager.putFileEntry(irFile, fileEntry)
|
||||
context.irModule.addFile(irFile)
|
||||
val irFileElementFactory = IrDeclarationFactory()
|
||||
val generator = IrFileGenerator(ktFile, context, irFile, this, irFileElementFactory)
|
||||
val generator = IrFileGenerator(ktFile, irFile, context, irFileElementFactory)
|
||||
generator.generateFileContent()
|
||||
}
|
||||
}
|
||||
|
||||
+41
-35
@@ -20,6 +20,8 @@ import org.jetbrains.kotlin.descriptors.CallableDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.PropertyDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.VariableDescriptor
|
||||
import org.jetbrains.kotlin.ir.IrStatement
|
||||
import org.jetbrains.kotlin.ir.assertCast
|
||||
import org.jetbrains.kotlin.ir.expressions.*
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
import org.jetbrains.kotlin.psi.psiUtil.endOffset
|
||||
@@ -31,55 +33,59 @@ import org.jetbrains.kotlin.resolve.constants.IntValue
|
||||
import org.jetbrains.kotlin.resolve.constants.StringValue
|
||||
import org.jetbrains.kotlin.resolve.constants.evaluate.ConstantExpressionEvaluator
|
||||
|
||||
class IrExpressionGenerator(
|
||||
class IrStatementGenerator(
|
||||
override val context: IrGeneratorContext,
|
||||
val declarationFactory: IrLocalDeclarationsFactory
|
||||
) : KtVisitor<IrExpression, Nothing?>(), IrGenerator {
|
||||
) : KtVisitor<IrStatement, Nothing?>(), IrGenerator {
|
||||
private val irCallGenerator = IrCallGenerator(context, this)
|
||||
|
||||
fun generateExpression(ktExpression: KtExpression) = ktExpression.generate()
|
||||
fun generateStatement(ktExpression: KtExpression) = ktExpression.generate()
|
||||
|
||||
private fun KtElement.generate(): IrExpression =
|
||||
private fun KtElement.generate(): IrStatement =
|
||||
deparenthesize()
|
||||
.accept(this@IrExpressionGenerator, null)
|
||||
.accept(this@IrStatementGenerator, null)
|
||||
.applySmartCastIfNeeded(this)
|
||||
|
||||
private fun IrExpression.applySmartCastIfNeeded(ktElement: KtElement): IrExpression {
|
||||
if (ktElement is KtExpression) {
|
||||
private fun KtElement.generateExpression(): IrExpression =
|
||||
generate().assertCast()
|
||||
|
||||
private fun IrStatement.applySmartCastIfNeeded(ktElement: KtElement): IrStatement {
|
||||
if (this is IrExpression && ktElement is KtExpression) {
|
||||
val smartCastType = get(BindingContext.SMARTCAST, ktElement)
|
||||
if (smartCastType != null) {
|
||||
return IrTypeOperatorExpressionImpl(
|
||||
ktElement.startOffset, ktElement.endOffset, smartCastType,
|
||||
IrTypeOperator.SMART_AS, smartCastType
|
||||
).apply { argument = this@applySmartCastIfNeeded }
|
||||
IrTypeOperator.SMART_AS, this@applySmartCastIfNeeded, smartCastType
|
||||
)
|
||||
}
|
||||
}
|
||||
return this
|
||||
}
|
||||
|
||||
override fun visitExpression(expression: KtExpression, data: Nothing?): IrExpression =
|
||||
IrDummyExpression(expression.startOffset, expression.endOffset, getTypeOrFail(expression), expression.javaClass.simpleName)
|
||||
override fun visitExpression(expression: KtExpression, data: Nothing?): IrStatement =
|
||||
IrDummyExpression(expression.startOffset, expression.endOffset, getType(expression), expression.javaClass.simpleName)
|
||||
|
||||
override fun visitProperty(property: KtProperty, data: Nothing?): IrExpression {
|
||||
override fun visitProperty(property: KtProperty, data: Nothing?): IrStatement {
|
||||
if (property.delegateExpression != null) TODO("Local delegated property")
|
||||
|
||||
val variableDescriptor = getOrFail(BindingContext.VARIABLE, property) { "No descriptor for local variable ${property.name}" }
|
||||
val variableDescriptor = getOrFail(BindingContext.VARIABLE, property)
|
||||
|
||||
val irLocalVariable = declarationFactory.createLocalVariable(property, variableDescriptor)
|
||||
irLocalVariable.initializerExpression = property.initializer?.generate()
|
||||
irLocalVariable.initializer = property.initializer?.generateExpression()
|
||||
|
||||
return IrLocalVariableDeclarationExpressionImpl(property.startOffset, property.endOffset, irLocalVariable)
|
||||
return irLocalVariable
|
||||
}
|
||||
|
||||
override fun visitBlockExpression(expression: KtBlockExpression, data: Nothing?): IrExpression {
|
||||
val irBlock = IrBlockExpressionImpl(expression.startOffset, expression.endOffset, getTypeOrFail(expression), false)
|
||||
expression.statements.forEach { irBlock.addChildExpression(it.generate()) }
|
||||
override fun visitBlockExpression(expression: KtBlockExpression, data: Nothing?): IrStatement {
|
||||
val irBlock = IrBlockExpressionImpl(expression.startOffset, expression.endOffset, getType(expression),
|
||||
hasResult = isUsedAsExpression(expression), isDesugared = false)
|
||||
expression.statements.forEach { irBlock.addStatement(it.generate()) }
|
||||
return irBlock
|
||||
}
|
||||
|
||||
override fun visitReturnExpression(expression: KtReturnExpression, data: Nothing?): IrExpression =
|
||||
IrReturnExpressionImpl(expression.startOffset, expression.endOffset, getTypeOrFail(expression))
|
||||
.apply { this.argument = expression.returnedExpression?.generate() }
|
||||
override fun visitReturnExpression(expression: KtReturnExpression, data: Nothing?): IrStatement =
|
||||
IrReturnExpressionImpl(expression.startOffset, expression.endOffset, getType(expression),
|
||||
expression.returnedExpression?.generateExpression())
|
||||
|
||||
override fun visitConstantExpression(expression: KtConstantExpression, data: Nothing?): IrExpression {
|
||||
val compileTimeConstant = ConstantExpressionEvaluator.getConstant(expression, context.bindingContext)
|
||||
@@ -97,17 +103,17 @@ class IrExpressionGenerator(
|
||||
}
|
||||
}
|
||||
|
||||
override fun visitStringTemplateExpression(expression: KtStringTemplateExpression, data: Nothing?): IrExpression {
|
||||
override fun visitStringTemplateExpression(expression: KtStringTemplateExpression, data: Nothing?): IrStatement {
|
||||
if (expression.entries.size == 1 && expression.entries[0] is KtLiteralStringTemplateEntry) {
|
||||
return expression.entries[0].generate()
|
||||
}
|
||||
|
||||
val irStringTemplate = IrStringConcatenationExpressionImpl(expression.startOffset, expression.endOffset, getTypeOrFail(expression))
|
||||
expression.entries.forEach { irStringTemplate.addChildExpression(it.generate()) }
|
||||
val irStringTemplate = IrStringConcatenationExpressionImpl(expression.startOffset, expression.endOffset, getType(expression))
|
||||
expression.entries.forEach { irStringTemplate.addArgument(it.generateExpression()) }
|
||||
return irStringTemplate
|
||||
}
|
||||
|
||||
override fun visitLiteralStringTemplateEntry(entry: KtLiteralStringTemplateEntry, data: Nothing?): IrExpression =
|
||||
override fun visitLiteralStringTemplateEntry(entry: KtLiteralStringTemplateEntry, data: Nothing?): IrStatement =
|
||||
IrLiteralExpressionImpl.string(entry.startOffset, entry.endOffset, context.builtIns.stringType, entry.text)
|
||||
|
||||
override fun visitSimpleNameExpression(expression: KtSimpleNameExpression, data: Nothing?): IrExpression {
|
||||
@@ -122,25 +128,25 @@ class IrExpressionGenerator(
|
||||
return when (descriptor) {
|
||||
is ClassDescriptor ->
|
||||
if (DescriptorUtils.isObject(descriptor))
|
||||
IrGetObjectValueExpressionImpl(expression.startOffset, expression.endOffset, getTypeOrFail(expression), descriptor)
|
||||
IrGetObjectValueExpressionImpl(expression.startOffset, expression.endOffset, getType(expression), descriptor)
|
||||
else if (DescriptorUtils.isEnumEntry(descriptor))
|
||||
IrGetEnumValueExpressionImpl(expression.startOffset, expression.endOffset, getTypeOrFail(expression), descriptor)
|
||||
IrGetEnumValueExpressionImpl(expression.startOffset, expression.endOffset, getType(expression), descriptor)
|
||||
else
|
||||
IrGetObjectValueExpressionImpl(expression.startOffset, expression.endOffset, getTypeOrFail(expression),
|
||||
IrGetObjectValueExpressionImpl(expression.startOffset, expression.endOffset, getType(expression),
|
||||
descriptor.companionObjectDescriptor ?: error("Class value without companion object: $descriptor"))
|
||||
is PropertyDescriptor -> {
|
||||
irCallGenerator.generateCall(expression, resolvedCall)
|
||||
}
|
||||
is VariableDescriptor ->
|
||||
IrGetVariableExpressionImpl(expression.startOffset, expression.endOffset, getTypeOrFail(expression), descriptor)
|
||||
IrGetVariableExpressionImpl(expression.startOffset, expression.endOffset, getType(expression), descriptor)
|
||||
else ->
|
||||
IrDummyExpression(expression.startOffset, expression.endOffset, getTypeOrFail(expression),
|
||||
IrDummyExpression(expression.startOffset, expression.endOffset, getType(expression),
|
||||
expression.getReferencedName() +
|
||||
": ${descriptor?.name} ${descriptor?.javaClass?.simpleName}")
|
||||
}
|
||||
}
|
||||
|
||||
override fun visitCallExpression(expression: KtCallExpression, data: Nothing?): IrExpression {
|
||||
override fun visitCallExpression(expression: KtCallExpression, data: Nothing?): IrStatement {
|
||||
val resolvedCall = getResolvedCall(expression) ?: TODO("No resolved call for call expression")
|
||||
|
||||
if (resolvedCall is VariableAsFunctionResolvedCall) {
|
||||
@@ -150,20 +156,20 @@ class IrExpressionGenerator(
|
||||
return irCallGenerator.generateCall(expression, resolvedCall)
|
||||
}
|
||||
|
||||
override fun visitDotQualifiedExpression(expression: KtDotQualifiedExpression, data: Nothing?): IrExpression =
|
||||
override fun visitDotQualifiedExpression(expression: KtDotQualifiedExpression, data: Nothing?): IrStatement =
|
||||
expression.selectorExpression!!.accept(this, data)
|
||||
|
||||
override fun visitSafeQualifiedExpression(expression: KtSafeQualifiedExpression, data: Nothing?): IrExpression =
|
||||
override fun visitSafeQualifiedExpression(expression: KtSafeQualifiedExpression, data: Nothing?): IrStatement =
|
||||
expression.selectorExpression!!.accept(this, data)
|
||||
|
||||
override fun visitThisExpression(expression: KtThisExpression, data: Nothing?): IrExpression {
|
||||
val referenceTarget = getOrFail(BindingContext.REFERENCE_TARGET, expression.instanceReference) { "No reference target for this" }
|
||||
return when (referenceTarget) {
|
||||
is ClassDescriptor ->
|
||||
IrThisExpressionImpl(expression.startOffset, expression.endOffset, getTypeOrFail(expression), referenceTarget)
|
||||
IrThisExpressionImpl(expression.startOffset, expression.endOffset, getType(expression), referenceTarget)
|
||||
is CallableDescriptor ->
|
||||
IrGetExtensionReceiverExpressionImpl(
|
||||
expression.startOffset, expression.endOffset, getTypeOrFail(expression),
|
||||
expression.startOffset, expression.endOffset, getType(expression),
|
||||
referenceTarget.extensionReceiverParameter!!
|
||||
)
|
||||
else ->
|
||||
@@ -21,10 +21,47 @@ import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
|
||||
interface IrElement {
|
||||
val startOffset: Int
|
||||
val endOffset: Int
|
||||
|
||||
val parent: IrElement?
|
||||
val slot: Int
|
||||
fun setTreeLocation(newParent: IrElement?, newSlot: Int)
|
||||
fun getChild(slot: Int): IrElement?
|
||||
fun replaceChild(slot: Int, newChild: IrElement)
|
||||
|
||||
fun <R, D> accept(visitor: IrElementVisitor<R, D>, data: D): R
|
||||
fun <D> acceptChildren(visitor: IrElementVisitor<Unit, D>, data: D): Unit
|
||||
}
|
||||
|
||||
abstract class IrElementBase(override val startOffset: Int, override val endOffset: Int) : IrElement
|
||||
interface IrStatement : IrElement
|
||||
|
||||
abstract class IrElementBase(override val startOffset: Int, override val endOffset: Int) : IrElement {
|
||||
override var parent: IrElement? = null
|
||||
override var slot: Int = DETACHED_SLOT
|
||||
|
||||
override fun setTreeLocation(newParent: IrElement?, newSlot: Int) {
|
||||
parent = newParent
|
||||
slot = newSlot
|
||||
}
|
||||
}
|
||||
|
||||
fun IrElement?.detach() {
|
||||
this?.setTreeLocation(null, DETACHED_SLOT)
|
||||
}
|
||||
|
||||
fun IrElement.replaceWith(otherElement: IrElement) {
|
||||
parent?.replaceChild(slot, otherElement)
|
||||
}
|
||||
|
||||
fun IrElement.assertChild(child: IrElement) {
|
||||
assert(getChild(child.slot) == child) { "$this: Invalid child: $child" }
|
||||
}
|
||||
|
||||
fun IrElement.assertDetached() {
|
||||
assert(parent == null && slot == DETACHED_SLOT) { "$this: should be detached" }
|
||||
}
|
||||
|
||||
fun IrElement.throwNoSuchSlot(slot: Int): Nothing =
|
||||
throw AssertionError("$this: no such slot $slot")
|
||||
|
||||
inline fun <reified T : IrElement> IrElement.assertCast(): T =
|
||||
if (this is T) this else throw AssertionError("Expected ${T::class.simpleName}: $this")
|
||||
+10
-7
@@ -16,10 +16,13 @@
|
||||
|
||||
package org.jetbrains.kotlin.ir
|
||||
|
||||
const val CHILD_DECLARATION_INDEX = 0
|
||||
const val DETACHED_INDEX = Int.MIN_VALUE
|
||||
const val CHILD_EXPRESSION_INDEX = 0
|
||||
const val ARGUMENT0_INDEX = 0
|
||||
const val ARGUMENT1_INDEX = 1
|
||||
const val DISPATCH_RECEIVER_INDEX = -1
|
||||
const val EXTENSION_RECEIVER_INDEX = -2
|
||||
const val CHILD_DECLARATION_SLOT = 0
|
||||
const val DETACHED_SLOT = Int.MIN_VALUE
|
||||
const val CHILD_EXPRESSION_SLOT = 0
|
||||
const val ARGUMENT0_SLOT = 0
|
||||
const val ARGUMENT1_SLOT = 1
|
||||
const val DISPATCH_RECEIVER_SLOT = -1
|
||||
const val EXTENSION_RECEIVER_SLOT = -2
|
||||
const val FUNCTION_BODY_SLOT = 0
|
||||
const val MODULE_SLOT = 0
|
||||
const val INITIALIZER_SLOT = 0
|
||||
@@ -17,13 +17,21 @@
|
||||
package org.jetbrains.kotlin.ir.declarations
|
||||
|
||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
||||
import org.jetbrains.kotlin.ir.*
|
||||
import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
|
||||
import java.util.*
|
||||
|
||||
interface IrClassElement : IrElement
|
||||
|
||||
interface IrClass : IrDeclaration {
|
||||
override val declarationKind: IrDeclarationKind
|
||||
get() = IrDeclarationKind.CLASS
|
||||
|
||||
interface IrClass : IrCompoundDeclaration, IrMemberDeclaration {
|
||||
override val descriptor: ClassDescriptor
|
||||
|
||||
override val declarationKind: IrDeclarationKind
|
||||
get() = IrDeclarationKind.MODULE
|
||||
val children: List<IrClassElement>
|
||||
|
||||
fun addChild(child: IrClassElement)
|
||||
}
|
||||
|
||||
class IrClassImpl(
|
||||
@@ -31,7 +39,30 @@ class IrClassImpl(
|
||||
endOffset: Int,
|
||||
originKind: IrDeclarationOriginKind,
|
||||
override val descriptor: ClassDescriptor
|
||||
) : IrCompoundMemberDeclarationBase(startOffset, endOffset, originKind), IrClass {
|
||||
) : IrDeclarationBase(startOffset, endOffset, originKind), IrClass {
|
||||
override val children: MutableList<IrClassElement> = ArrayList()
|
||||
|
||||
override fun addChild(child: IrClassElement) {
|
||||
child.assertDetached()
|
||||
child.setTreeLocation(this, children.size)
|
||||
children.add(child)
|
||||
}
|
||||
|
||||
override fun getChild(slot: Int): IrElement? =
|
||||
children.getOrNull(slot)
|
||||
|
||||
override fun replaceChild(slot: Int, newChild: IrElement) {
|
||||
newChild.assertDetached()
|
||||
children.getOrNull(slot)?.detach() ?: throwNoSuchSlot(slot)
|
||||
children[slot] = newChild.assertCast()
|
||||
newChild.setTreeLocation(this, slot)
|
||||
}
|
||||
|
||||
override fun <R, D> accept(visitor: IrElementVisitor<R, D>, data: D): R =
|
||||
visitor.visitClass(this, data)
|
||||
|
||||
override fun <D> acceptChildren(visitor: IrElementVisitor<Unit, D>, data: D) {
|
||||
children.forEach { it.accept(visitor, data) }
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
-152
@@ -1,152 +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.declarations
|
||||
|
||||
import org.jetbrains.kotlin.ir.CHILD_DECLARATION_INDEX
|
||||
import org.jetbrains.kotlin.ir.IrElement
|
||||
import org.jetbrains.kotlin.ir.IrElementBase
|
||||
import org.jetbrains.kotlin.ir.DETACHED_INDEX
|
||||
import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
|
||||
import java.util.*
|
||||
|
||||
interface IrDeclarationOwner : IrElement {
|
||||
fun getChildDeclaration(index: Int): IrMemberDeclaration?
|
||||
fun replaceChildDeclaration(oldChild: IrMemberDeclaration, newChild: IrMemberDeclaration)
|
||||
}
|
||||
|
||||
interface IrDeclarationOwner1 : IrDeclarationOwner {
|
||||
val childDeclaration: IrMemberDeclaration
|
||||
}
|
||||
|
||||
interface IrDeclarationOwnerN : IrDeclarationOwner {
|
||||
val childrenCount: Int
|
||||
fun addChildDeclaration(child: IrMemberDeclaration)
|
||||
fun removeChildDeclaration(child: IrMemberDeclaration)
|
||||
fun removeAllChildDeclarations()
|
||||
|
||||
fun <D> acceptChildDeclarations(visitor: IrElementVisitor<Unit, D>, data: D)
|
||||
}
|
||||
|
||||
interface IrCompoundDeclaration : IrDeclaration, IrDeclarationOwnerN
|
||||
|
||||
interface IrMemberDeclaration : IrDeclaration {
|
||||
override var parent: IrDeclarationOwner?
|
||||
|
||||
fun setTreeLocation(parent: IrDeclarationOwner?, index: Int)
|
||||
}
|
||||
|
||||
abstract class IrDeclarationOwnerNBase(
|
||||
startOffset: Int,
|
||||
endOffset: Int
|
||||
) : IrElementBase(startOffset, endOffset), IrDeclarationOwnerN {
|
||||
protected val childDeclarations: MutableList<IrMemberDeclaration> = ArrayList()
|
||||
|
||||
override val childrenCount: Int
|
||||
get() = childDeclarations.size
|
||||
|
||||
override fun getChildDeclaration(index: Int): IrMemberDeclaration? =
|
||||
childDeclarations.getOrNull(index)
|
||||
|
||||
override fun addChildDeclaration(child: IrMemberDeclaration) {
|
||||
child.setTreeLocation(this, childDeclarations.size)
|
||||
childDeclarations.add(child)
|
||||
}
|
||||
|
||||
override fun removeChildDeclaration(child: IrMemberDeclaration) {
|
||||
validateChild(child)
|
||||
childDeclarations.removeAt(child.indexInParent)
|
||||
for (i in child.indexInParent..childDeclarations.size - 1) {
|
||||
childDeclarations[i].setTreeLocation(this, i)
|
||||
}
|
||||
child.detach()
|
||||
}
|
||||
|
||||
override fun removeAllChildDeclarations() {
|
||||
childDeclarations.forEach { it.detach() }
|
||||
childDeclarations.clear()
|
||||
}
|
||||
|
||||
override fun replaceChildDeclaration(oldChild: IrMemberDeclaration, newChild: IrMemberDeclaration) {
|
||||
validateChild(oldChild)
|
||||
childDeclarations[oldChild.indexInParent] = newChild
|
||||
newChild.setTreeLocation(this, oldChild.indexInParent)
|
||||
oldChild.detach()
|
||||
}
|
||||
|
||||
override fun <D> acceptChildDeclarations(visitor: IrElementVisitor<Unit, D>, data: D) {
|
||||
childDeclarations.forEach { it.accept(visitor, data) }
|
||||
}
|
||||
}
|
||||
|
||||
// TODO synchronization?
|
||||
abstract class IrCompoundDeclarationBase(
|
||||
startOffset: Int,
|
||||
endOffset: Int,
|
||||
override val originKind: IrDeclarationOriginKind
|
||||
) : IrDeclarationOwnerNBase(startOffset, endOffset), IrCompoundDeclaration {
|
||||
override var indexInParent: Int = IrDeclaration.DETACHED_INDEX
|
||||
|
||||
override fun <D> acceptChildren(visitor: IrElementVisitor<Unit, D>, data: D) {
|
||||
acceptChildDeclarations(visitor, data)
|
||||
}
|
||||
}
|
||||
|
||||
abstract class IrCompoundMemberDeclarationBase(
|
||||
startOffset: Int,
|
||||
endOffset: Int,
|
||||
originKind: IrDeclarationOriginKind
|
||||
) : IrCompoundDeclarationBase(startOffset, endOffset, originKind), IrMemberDeclaration {
|
||||
private var parentImpl: IrDeclarationOwner? = null
|
||||
|
||||
override var parent: IrDeclarationOwner?
|
||||
get() = parentImpl!!
|
||||
set(newParent) {
|
||||
parentImpl = newParent
|
||||
}
|
||||
|
||||
override fun setTreeLocation(parent: IrDeclarationOwner?, index: Int) {
|
||||
this.parentImpl = parent
|
||||
this.indexInParent = index
|
||||
}
|
||||
}
|
||||
|
||||
abstract class IrMemberDeclarationBase(
|
||||
startOffset: Int,
|
||||
endOffset: Int,
|
||||
originKind: IrDeclarationOriginKind
|
||||
) : IrDeclarationBase(startOffset, endOffset, originKind), IrMemberDeclaration {
|
||||
private var parentImpl: IrDeclarationOwner? = null
|
||||
|
||||
override var parent: IrDeclarationOwner?
|
||||
get() = parentImpl!!
|
||||
set(newParent) {
|
||||
parentImpl = newParent
|
||||
}
|
||||
|
||||
override fun setTreeLocation(parent: IrDeclarationOwner?, index: Int) {
|
||||
this.parentImpl = parent
|
||||
this.indexInParent = index
|
||||
}
|
||||
}
|
||||
|
||||
fun IrMemberDeclaration.detach() {
|
||||
setTreeLocation(null, IrDeclaration.DETACHED_INDEX)
|
||||
}
|
||||
|
||||
fun IrDeclarationOwner.validateChild(child: IrMemberDeclaration) {
|
||||
assert(child.parent == this && getChildDeclaration(child.indexInParent) == child) { "Invalid child: $child" }
|
||||
}
|
||||
@@ -17,21 +17,13 @@
|
||||
package org.jetbrains.kotlin.ir.declarations
|
||||
|
||||
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
||||
import org.jetbrains.kotlin.ir.IrElement
|
||||
import org.jetbrains.kotlin.ir.IrElementBase
|
||||
import org.jetbrains.kotlin.ir.IrStatement
|
||||
|
||||
interface IrDeclaration : IrElement {
|
||||
override val parent: IrDeclarationOwner?
|
||||
val indexInParent: Int
|
||||
|
||||
interface IrDeclaration : IrStatement, IrClassElement {
|
||||
val descriptor: DeclarationDescriptor?
|
||||
|
||||
val declarationKind: IrDeclarationKind
|
||||
val originKind: IrDeclarationOriginKind
|
||||
|
||||
companion object {
|
||||
const val DETACHED_INDEX = Int.MIN_VALUE
|
||||
}
|
||||
}
|
||||
|
||||
enum class IrDeclarationKind {
|
||||
@@ -41,7 +33,7 @@ enum class IrDeclarationKind {
|
||||
PROPERTY_GETTER,
|
||||
PROPERTY_SETTER,
|
||||
PROPERTY,
|
||||
LOCAL_VARIABLE,
|
||||
VARIABLE,
|
||||
CLASS
|
||||
}
|
||||
|
||||
@@ -54,6 +46,4 @@ abstract class IrDeclarationBase(
|
||||
startOffset: Int,
|
||||
endOffset: Int,
|
||||
override val originKind: IrDeclarationOriginKind
|
||||
) : IrElementBase(startOffset, endOffset), IrDeclaration {
|
||||
override var indexInParent: Int = IrDeclaration.DETACHED_INDEX
|
||||
}
|
||||
) : IrElementBase(startOffset, endOffset), IrDeclaration
|
||||
|
||||
@@ -17,28 +17,48 @@
|
||||
package org.jetbrains.kotlin.ir.declarations
|
||||
|
||||
import org.jetbrains.kotlin.descriptors.PackageFragmentDescriptor
|
||||
import org.jetbrains.kotlin.ir.SourceLocationManager
|
||||
import org.jetbrains.kotlin.ir.*
|
||||
import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
|
||||
import java.util.*
|
||||
|
||||
interface IrFile : IrCompoundDeclaration {
|
||||
interface IrFile : IrElement {
|
||||
val name: String
|
||||
val fileEntry: SourceLocationManager.FileEntry
|
||||
val module: IrModule
|
||||
override val descriptor: PackageFragmentDescriptor
|
||||
val packageFragmentDescriptor: PackageFragmentDescriptor
|
||||
val declarations: List<IrDeclaration>
|
||||
|
||||
override val parent: Nothing? get() = null
|
||||
|
||||
override val declarationKind: IrDeclarationKind
|
||||
get() = IrDeclarationKind.FILE
|
||||
fun addDeclaration(declaration: IrDeclaration)
|
||||
}
|
||||
|
||||
class IrFileImpl(
|
||||
override val fileEntry: SourceLocationManager.FileEntry,
|
||||
override val name: String,
|
||||
override val descriptor: PackageFragmentDescriptor
|
||||
) : IrCompoundDeclarationBase(0, fileEntry.maxOffset, IrDeclarationOriginKind.DEFINED), IrFile {
|
||||
override lateinit var module: IrModule
|
||||
override val packageFragmentDescriptor: PackageFragmentDescriptor
|
||||
) : IrElementBase(0, fileEntry.maxOffset), IrFile {
|
||||
override val declarations: MutableList<IrDeclaration> = ArrayList()
|
||||
|
||||
override fun addDeclaration(declaration: IrDeclaration) {
|
||||
declaration.assertDetached()
|
||||
declaration.setTreeLocation(this, declarations.size)
|
||||
declarations.add(declaration)
|
||||
}
|
||||
|
||||
override fun getChild(slot: Int): IrElement? =
|
||||
declarations.getOrNull(slot)
|
||||
|
||||
override fun replaceChild(slot: Int, newChild: IrElement) {
|
||||
newChild.assertDetached()
|
||||
declarations.getOrNull(slot)?.detach() ?: throwNoSuchSlot(slot)
|
||||
declarations[slot] = newChild.assertCast()
|
||||
newChild.setTreeLocation(this, slot)
|
||||
}
|
||||
|
||||
override fun <R, D> accept(visitor: IrElementVisitor<R, D>, data: D): R =
|
||||
visitor.visitFile(this, data)
|
||||
|
||||
override fun <D> acceptChildren(visitor: IrElementVisitor<Unit, D>, data: D) {
|
||||
declarations.forEach { it.accept(visitor, data) }
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -17,10 +17,11 @@
|
||||
package org.jetbrains.kotlin.ir.declarations
|
||||
|
||||
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
||||
import org.jetbrains.kotlin.ir.*
|
||||
import org.jetbrains.kotlin.ir.expressions.IrBody
|
||||
import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
|
||||
|
||||
interface IrFunction : IrMemberDeclaration {
|
||||
interface IrFunction : IrDeclaration {
|
||||
override val descriptor: FunctionDescriptor
|
||||
val body: IrBody
|
||||
|
||||
@@ -31,8 +32,36 @@ interface IrFunction : IrMemberDeclaration {
|
||||
abstract class IrFunctionBase(
|
||||
startOffset: Int,
|
||||
endOffset: Int,
|
||||
originKind: IrDeclarationOriginKind
|
||||
) : IrMemberDeclarationBase(startOffset, endOffset, originKind), IrFunction {
|
||||
originKind: IrDeclarationOriginKind,
|
||||
body: IrBody? = null
|
||||
) : IrDeclarationBase(startOffset, endOffset, originKind), IrFunction {
|
||||
init {
|
||||
body?.setTreeLocation(this, FUNCTION_BODY_SLOT)
|
||||
}
|
||||
|
||||
private var bodyImpl: IrBody? = body
|
||||
override var body: IrBody
|
||||
get() = bodyImpl!!
|
||||
set(newValue) {
|
||||
newValue.assertDetached()
|
||||
bodyImpl?.detach()
|
||||
bodyImpl = newValue
|
||||
newValue.setTreeLocation(this, FUNCTION_BODY_SLOT)
|
||||
}
|
||||
|
||||
override fun getChild(slot: Int): IrElement? =
|
||||
when (slot) {
|
||||
FUNCTION_BODY_SLOT -> body
|
||||
else -> null
|
||||
}
|
||||
|
||||
override fun replaceChild(slot: Int, newChild: IrElement) {
|
||||
when (slot) {
|
||||
FUNCTION_BODY_SLOT -> body = newChild.assertCast()
|
||||
else -> throwNoSuchSlot(slot)
|
||||
}
|
||||
}
|
||||
|
||||
override fun <D> acceptChildren(visitor: IrElementVisitor<Unit, D>, data: D) {
|
||||
body.accept(visitor, data)
|
||||
}
|
||||
@@ -43,12 +72,8 @@ class IrFunctionImpl(
|
||||
endOffset: Int,
|
||||
originKind: IrDeclarationOriginKind,
|
||||
override val descriptor: FunctionDescriptor,
|
||||
override val body: IrBody
|
||||
) : IrFunctionBase(startOffset, endOffset, originKind) {
|
||||
init {
|
||||
body.parent = this
|
||||
}
|
||||
|
||||
body: IrBody
|
||||
) : IrFunctionBase(startOffset, endOffset, originKind, body) {
|
||||
override fun <R, D> accept(visitor: IrElementVisitor<R, D>, data: D): R =
|
||||
visitor.visitFunction(this, data)
|
||||
}
|
||||
|
||||
@@ -17,41 +17,44 @@
|
||||
package org.jetbrains.kotlin.ir.declarations
|
||||
|
||||
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
|
||||
import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET
|
||||
import org.jetbrains.kotlin.ir.*
|
||||
import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
|
||||
import java.util.*
|
||||
|
||||
interface IrModule : IrDeclaration {
|
||||
override val descriptor: ModuleDescriptor
|
||||
|
||||
interface IrModule : IrElement {
|
||||
override val startOffset: Int get() = UNDEFINED_OFFSET
|
||||
override val endOffset: Int get() = UNDEFINED_OFFSET
|
||||
|
||||
override val parent: Nothing? get() = null
|
||||
override val indexInParent: Int get() = MODULE_INDEX
|
||||
override val parent: IrElement? get() = null
|
||||
override val slot: Int get() = MODULE_SLOT
|
||||
override fun setTreeLocation(newParent: IrElement?, newSlot: Int) {
|
||||
throw AssertionError("IrModule can't have a parent element")
|
||||
}
|
||||
|
||||
override val declarationKind: IrDeclarationKind
|
||||
get() = IrDeclarationKind.MODULE
|
||||
val descriptor: ModuleDescriptor
|
||||
|
||||
val files: List<IrFile>
|
||||
|
||||
companion object {
|
||||
const val MODULE_INDEX = -1
|
||||
}
|
||||
fun addFile(file: IrFile)
|
||||
}
|
||||
|
||||
class IrModuleImpl(
|
||||
override val descriptor: ModuleDescriptor
|
||||
) : IrModule {
|
||||
|
||||
override val originKind: IrDeclarationOriginKind
|
||||
get() = IrDeclarationOriginKind.DEFINED
|
||||
|
||||
override val files: MutableList<IrFile> = ArrayList()
|
||||
|
||||
fun addFile(file: IrFileImpl) {
|
||||
override fun addFile(file: IrFile) {
|
||||
file.assertDetached()
|
||||
file.setTreeLocation(this, files.size)
|
||||
files.add(file)
|
||||
file.module = this
|
||||
}
|
||||
|
||||
override fun getChild(slot: Int): IrElement? =
|
||||
files.getOrNull(slot)
|
||||
|
||||
override fun replaceChild(slot: Int, newChild: IrElement) {
|
||||
newChild.assertDetached()
|
||||
files.getOrNull(slot)?.detach() ?: throwNoSuchSlot(slot)
|
||||
}
|
||||
|
||||
override fun <R, D> accept(visitor: IrElementVisitor<R, D>, data: D): R =
|
||||
|
||||
@@ -17,10 +17,11 @@
|
||||
package org.jetbrains.kotlin.ir.declarations
|
||||
|
||||
import org.jetbrains.kotlin.descriptors.PropertyDescriptor
|
||||
import org.jetbrains.kotlin.ir.*
|
||||
import org.jetbrains.kotlin.ir.expressions.IrBody
|
||||
import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
|
||||
|
||||
interface IrProperty : IrMemberDeclaration {
|
||||
interface IrProperty : IrDeclaration {
|
||||
override val descriptor: PropertyDescriptor
|
||||
var getter: IrPropertyGetter?
|
||||
var setter: IrPropertySetter?
|
||||
@@ -32,11 +33,11 @@ interface IrProperty : IrMemberDeclaration {
|
||||
}
|
||||
|
||||
interface IrSimpleProperty : IrProperty {
|
||||
val valueInitializer: IrBody?
|
||||
var valueInitializer: IrBody?
|
||||
}
|
||||
|
||||
interface IrDelegatedProperty : IrProperty {
|
||||
val delegateInitializer: IrBody
|
||||
var delegateInitializer: IrBody
|
||||
}
|
||||
|
||||
// TODO synchronization?
|
||||
@@ -45,15 +46,17 @@ abstract class IrPropertyBase(
|
||||
endOffset: Int,
|
||||
originKind: IrDeclarationOriginKind,
|
||||
override val descriptor: PropertyDescriptor
|
||||
) : IrMemberDeclarationBase(startOffset, endOffset, originKind), IrProperty {
|
||||
) : IrDeclarationBase(startOffset, endOffset, originKind), IrProperty {
|
||||
override var getter: IrPropertyGetter? = null
|
||||
set(newGetter) {
|
||||
newGetter?.run { assert(property == null) { "$newGetter: should not have a property" } }
|
||||
newGetter?.property = this
|
||||
field = newGetter
|
||||
}
|
||||
|
||||
override var setter: IrPropertySetter? = null
|
||||
set(newSetter) {
|
||||
newSetter?.run { assert(property == null) { "$newSetter: should not have a property" } }
|
||||
newSetter?.property = this
|
||||
field = newSetter
|
||||
}
|
||||
@@ -69,10 +72,27 @@ class IrSimplePropertyImpl(
|
||||
endOffset: Int,
|
||||
originKind: IrDeclarationOriginKind,
|
||||
descriptor: PropertyDescriptor,
|
||||
override val valueInitializer: IrBody?
|
||||
valueInitializer: IrBody? = null
|
||||
) : IrPropertyBase(startOffset, endOffset, originKind, descriptor), IrSimpleProperty {
|
||||
init {
|
||||
valueInitializer?.parent = this
|
||||
override var valueInitializer: IrBody? = valueInitializer
|
||||
set(value) {
|
||||
value?.assertDetached()
|
||||
field?.detach()
|
||||
field = value
|
||||
value?.setTreeLocation(this, INITIALIZER_SLOT)
|
||||
}
|
||||
|
||||
override fun getChild(slot: Int): IrElement? =
|
||||
when (slot) {
|
||||
INITIALIZER_SLOT -> valueInitializer
|
||||
else -> null
|
||||
}
|
||||
|
||||
override fun replaceChild(slot: Int, newChild: IrElement) {
|
||||
when (slot) {
|
||||
INITIALIZER_SLOT -> valueInitializer = newChild.assertCast()
|
||||
else -> throwNoSuchSlot(slot)
|
||||
}
|
||||
}
|
||||
|
||||
override fun <R, D> accept(visitor: IrElementVisitor<R, D>, data: D): R =
|
||||
@@ -88,8 +108,29 @@ class IrDelegatedPropertyImpl(
|
||||
endOffset: Int,
|
||||
originKind: IrDeclarationOriginKind,
|
||||
descriptor: PropertyDescriptor,
|
||||
override val delegateInitializer: IrBody
|
||||
delegateInitializer: IrBody
|
||||
) : IrPropertyBase(startOffset, endOffset, originKind, descriptor), IrDelegatedProperty {
|
||||
override var delegateInitializer: IrBody = delegateInitializer
|
||||
set(value) {
|
||||
value.assertDetached()
|
||||
field.detach()
|
||||
field = value
|
||||
value.setTreeLocation(this, INITIALIZER_SLOT)
|
||||
}
|
||||
|
||||
override fun getChild(slot: Int): IrElement? =
|
||||
when (slot) {
|
||||
INITIALIZER_SLOT -> delegateInitializer
|
||||
else -> null
|
||||
}
|
||||
|
||||
override fun replaceChild(slot: Int, newChild: IrElement) {
|
||||
when (slot) {
|
||||
INITIALIZER_SLOT -> delegateInitializer = newChild.assertCast()
|
||||
else -> throwNoSuchSlot(slot)
|
||||
}
|
||||
}
|
||||
|
||||
override fun <R, D> accept(visitor: IrElementVisitor<R, D>, data: D): R =
|
||||
visitor.visitDelegatedProperty(this, data)
|
||||
|
||||
|
||||
@@ -45,12 +45,8 @@ abstract class IrPropertyAccessorBase(
|
||||
startOffset: Int,
|
||||
endOffset: Int,
|
||||
originKind: IrDeclarationOriginKind,
|
||||
override val body: IrBody
|
||||
) : IrFunctionBase(startOffset, endOffset, originKind), IrPropertyAccessor {
|
||||
init {
|
||||
body.parent = this
|
||||
}
|
||||
|
||||
body: IrBody
|
||||
) : IrFunctionBase(startOffset, endOffset, originKind, body), IrPropertyAccessor {
|
||||
override var property: IrProperty? = null
|
||||
}
|
||||
|
||||
|
||||
+20
-18
@@ -17,38 +17,44 @@
|
||||
package org.jetbrains.kotlin.ir.declarations
|
||||
|
||||
import org.jetbrains.kotlin.descriptors.VariableDescriptor
|
||||
import org.jetbrains.kotlin.ir.CHILD_EXPRESSION_INDEX
|
||||
import org.jetbrains.kotlin.ir.*
|
||||
import org.jetbrains.kotlin.ir.expressions.*
|
||||
import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
|
||||
|
||||
interface IrLocalVariable : IrMemberDeclaration, IrExpressionOwner {
|
||||
interface IrVariable : IrDeclaration {
|
||||
override val descriptor: VariableDescriptor
|
||||
|
||||
override val declarationKind: IrDeclarationKind
|
||||
get() = IrDeclarationKind.LOCAL_VARIABLE
|
||||
get() = IrDeclarationKind.VARIABLE
|
||||
|
||||
var initializerExpression: IrExpression?
|
||||
var initializer: IrExpression?
|
||||
}
|
||||
|
||||
class IrLocalVariableImpl(
|
||||
class IrVariableImpl(
|
||||
startOffset: Int,
|
||||
endOffset: Int,
|
||||
originKind: IrDeclarationOriginKind,
|
||||
override val descriptor: VariableDescriptor
|
||||
) : IrMemberDeclarationBase(startOffset, endOffset, originKind), IrLocalVariable {
|
||||
override var initializerExpression: IrExpression? = null
|
||||
) : IrDeclarationBase(startOffset, endOffset, originKind), IrVariable {
|
||||
override var initializer: IrExpression? = null
|
||||
set(value) {
|
||||
value?.assertDetached()
|
||||
field?.detach()
|
||||
field = value
|
||||
value?.setTreeLocation(this, CHILD_EXPRESSION_INDEX)
|
||||
value?.setTreeLocation(this, INITIALIZER_SLOT)
|
||||
}
|
||||
|
||||
override fun getChildExpression(index: Int): IrExpression? =
|
||||
if (index == CHILD_EXPRESSION_INDEX) initializerExpression else null
|
||||
override fun getChild(slot: Int): IrElement? =
|
||||
when (slot) {
|
||||
INITIALIZER_SLOT -> initializer
|
||||
else -> null
|
||||
}
|
||||
|
||||
override fun replaceChildExpression(oldChild: IrExpression, newChild: IrExpression) {
|
||||
validateChild(oldChild)
|
||||
initializerExpression = newChild
|
||||
override fun replaceChild(slot: Int, newChild: IrElement) {
|
||||
when (slot) {
|
||||
INITIALIZER_SLOT -> initializer = newChild.assertCast<IrExpression>()
|
||||
else -> throwNoSuchSlot(slot)
|
||||
}
|
||||
}
|
||||
|
||||
override fun <R, D> accept(visitor: IrElementVisitor<R, D>, data: D): R {
|
||||
@@ -56,10 +62,6 @@ class IrLocalVariableImpl(
|
||||
}
|
||||
|
||||
override fun <D> acceptChildren(visitor: IrElementVisitor<Unit, D>, data: D) {
|
||||
acceptChildExpressions(visitor, data)
|
||||
}
|
||||
|
||||
override fun <D> acceptChildExpressions(visitor: IrElementVisitor<Unit, D>, data: D) {
|
||||
initializerExpression?.accept(visitor, data)
|
||||
initializer?.accept(visitor, data)
|
||||
}
|
||||
}
|
||||
@@ -16,27 +16,51 @@
|
||||
|
||||
package org.jetbrains.kotlin.ir.expressions
|
||||
|
||||
import org.jetbrains.kotlin.ir.IrElement
|
||||
import org.jetbrains.kotlin.ir.IrStatement
|
||||
import org.jetbrains.kotlin.ir.assertCast
|
||||
import org.jetbrains.kotlin.ir.assertDetached
|
||||
import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
import java.util.*
|
||||
|
||||
|
||||
interface IrBlockExpression : IrCompoundExpressionN {
|
||||
interface IrBlockExpression : IrExpression {
|
||||
val hasResult: Boolean
|
||||
}
|
||||
val isDesugared: Boolean
|
||||
|
||||
fun IrBlockExpression.getResultExpression() =
|
||||
if (hasResult) childExpressions.lastOrNull() else null
|
||||
val statements: List<IrStatement>
|
||||
fun addStatement(statement: IrStatement)
|
||||
}
|
||||
|
||||
class IrBlockExpressionImpl(
|
||||
startOffset: Int,
|
||||
endOffset: Int,
|
||||
type: KotlinType?,
|
||||
override val hasResult: Boolean
|
||||
) : IrCompoundExpressionNBase(startOffset, endOffset, type), IrBlockExpression {
|
||||
override val hasResult: Boolean,
|
||||
override val isDesugared: Boolean
|
||||
) : IrExpressionBase(startOffset, endOffset, type), IrBlockExpression {
|
||||
override val statements: MutableList<IrStatement> = ArrayList()
|
||||
|
||||
override fun addStatement(statement: IrStatement) {
|
||||
statement.assertDetached()
|
||||
statement.setTreeLocation(this, statements.size)
|
||||
statements.add(statement)
|
||||
}
|
||||
|
||||
override fun getChild(slot: Int): IrElement? =
|
||||
statements.getOrNull(slot)
|
||||
|
||||
override fun replaceChild(slot: Int, newChild: IrElement) {
|
||||
if (0 <= slot && slot < statements.size) {
|
||||
statements[slot] = newChild.assertCast()
|
||||
}
|
||||
}
|
||||
|
||||
override fun <R, D> accept(visitor: IrElementVisitor<R, D>, data: D): R =
|
||||
visitor.visitBlockExpression(this, data)
|
||||
|
||||
override fun <D> acceptChildren(visitor: IrElementVisitor<Unit, D>, data: D) {
|
||||
childExpressions.forEach { it.accept(visitor, data) }
|
||||
statements.forEach { it.accept(visitor, data) }
|
||||
}
|
||||
}
|
||||
@@ -16,50 +16,53 @@
|
||||
|
||||
package org.jetbrains.kotlin.ir.expressions
|
||||
|
||||
import org.jetbrains.kotlin.ir.CHILD_EXPRESSION_INDEX
|
||||
import org.jetbrains.kotlin.ir.IrElement
|
||||
import org.jetbrains.kotlin.ir.IrElementBase
|
||||
import org.jetbrains.kotlin.ir.declarations.IrDeclaration
|
||||
import org.jetbrains.kotlin.ir.declarations.IrDeclarationOwner
|
||||
import org.jetbrains.kotlin.ir.declarations.IrDeclarationOwnerNBase
|
||||
import org.jetbrains.kotlin.ir.*
|
||||
import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
|
||||
|
||||
interface IrBody : IrElement {
|
||||
override var parent: IrDeclaration
|
||||
interface IrBody : IrElement
|
||||
|
||||
interface IrExpressionBody : IrBody {
|
||||
var expression: IrExpression
|
||||
}
|
||||
|
||||
interface IrExpressionBody : IrBody, IrExpressionOwner1
|
||||
|
||||
// TODO IrExpressionBodyImpl vs IrCompoundExpression1Impl: extract common base class?
|
||||
class IrExpressionBodyImpl(
|
||||
startOffset: Int,
|
||||
endOffset: Int
|
||||
) : IrElementBase(startOffset, endOffset), IrExpressionBody {
|
||||
override lateinit var parent: IrDeclaration
|
||||
constructor(
|
||||
startOffset: Int,
|
||||
endOffset: Int,
|
||||
expression: IrExpression
|
||||
) : this(startOffset, endOffset) {
|
||||
this.expression = expression
|
||||
}
|
||||
|
||||
override var argument: IrExpression? = null
|
||||
set(newExpression) {
|
||||
field?.detach()
|
||||
field = newExpression
|
||||
newExpression?.setTreeLocation(this, CHILD_EXPRESSION_INDEX)
|
||||
private var expressionImpl: IrExpression? = null
|
||||
override var expression: IrExpression
|
||||
get() = expressionImpl!!
|
||||
set(newValue) {
|
||||
newValue.assertDetached()
|
||||
expressionImpl?.detach()
|
||||
expressionImpl = newValue
|
||||
newValue.setTreeLocation(this, CHILD_EXPRESSION_SLOT)
|
||||
}
|
||||
|
||||
override fun getChildExpression(index: Int): IrExpression? =
|
||||
if (index == CHILD_EXPRESSION_INDEX) argument else null
|
||||
override fun getChild(slot: Int): IrElement? =
|
||||
when (slot) {
|
||||
CHILD_EXPRESSION_SLOT -> expression
|
||||
else -> null
|
||||
}
|
||||
|
||||
override fun replaceChildExpression(oldChild: IrExpression, newChild: IrExpression) {
|
||||
validateChild(oldChild)
|
||||
argument = newChild
|
||||
override fun replaceChild(slot: Int, newChild: IrElement) {
|
||||
when (slot) {
|
||||
CHILD_EXPRESSION_SLOT -> expression = newChild.assertCast()
|
||||
}
|
||||
}
|
||||
|
||||
override fun <R, D> accept(visitor: IrElementVisitor<R, D>, data: D): R =
|
||||
visitor.visitExpressionBody(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) {
|
||||
argument?.accept(visitor, data)
|
||||
expression.accept(visitor, data)
|
||||
}
|
||||
}
|
||||
@@ -18,21 +18,18 @@ package org.jetbrains.kotlin.ir.expressions
|
||||
|
||||
import org.jetbrains.kotlin.descriptors.CallableDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
||||
import org.jetbrains.kotlin.ir.DISPATCH_RECEIVER_INDEX
|
||||
import org.jetbrains.kotlin.ir.EXTENSION_RECEIVER_INDEX
|
||||
import org.jetbrains.kotlin.ir.*
|
||||
import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
|
||||
interface IrCallExpression : IrMemberAccessExpression, IrCompoundExpression {
|
||||
interface IrCallExpression : IrMemberAccessExpression {
|
||||
val superQualifier: ClassDescriptor?
|
||||
val operator: IrOperator?
|
||||
override val descriptor: CallableDescriptor
|
||||
|
||||
fun getValueArgument(index: Int): IrExpression?
|
||||
fun putValueArgument(index: Int, valueArgument: IrExpression?)
|
||||
fun removeValueArgument(index: Int)
|
||||
|
||||
fun <D> acceptValueArguments(visitor: IrElementVisitor<Unit, D>, data: D)
|
||||
fun getArgument(index: Int): IrExpression?
|
||||
fun putArgument(index: Int, valueArgument: IrExpression?)
|
||||
fun removeArgument(index: Int)
|
||||
}
|
||||
|
||||
class IrCallExpressionImpl(
|
||||
@@ -42,63 +39,45 @@ class IrCallExpressionImpl(
|
||||
override val descriptor: CallableDescriptor,
|
||||
isSafe: Boolean,
|
||||
override val operator: IrOperator?,
|
||||
override val superQualifier: ClassDescriptor?
|
||||
override val superQualifier: ClassDescriptor? = null
|
||||
) : IrMemberAccessExpressionBase(startOffset, endOffset, type, isSafe), IrCallExpression {
|
||||
private val argumentsByParameterIndex =
|
||||
kotlin.arrayOfNulls<IrExpression>(descriptor.valueParameters.size)
|
||||
arrayOfNulls<IrExpression>(descriptor.valueParameters.size)
|
||||
|
||||
override fun getValueArgument(index: Int): IrExpression? =
|
||||
override fun getArgument(index: Int): IrExpression? =
|
||||
argumentsByParameterIndex[index]
|
||||
|
||||
override fun putValueArgument(index: Int, valueArgument: IrExpression?) {
|
||||
override fun putArgument(index: Int, valueArgument: IrExpression?) {
|
||||
if (index >= argumentsByParameterIndex.size) throw AssertionError("$this: No such argument slot: $index")
|
||||
valueArgument?.assertDetached()
|
||||
argumentsByParameterIndex[index]?.detach()
|
||||
argumentsByParameterIndex[index] = valueArgument
|
||||
valueArgument?.setTreeLocation(this, index)
|
||||
}
|
||||
|
||||
override fun removeValueArgument(index: Int) {
|
||||
override fun removeArgument(index: Int) {
|
||||
argumentsByParameterIndex[index]?.detach()
|
||||
argumentsByParameterIndex[index] = null
|
||||
}
|
||||
|
||||
override fun getChildExpression(index: Int): IrExpression? =
|
||||
when (index) {
|
||||
DISPATCH_RECEIVER_INDEX ->
|
||||
dispatchReceiver
|
||||
EXTENSION_RECEIVER_INDEX ->
|
||||
extensionReceiver
|
||||
else ->
|
||||
argumentsByParameterIndex.getOrNull(index)
|
||||
}
|
||||
override fun getChild(slot: Int): IrElement? =
|
||||
if (0 <= slot)
|
||||
argumentsByParameterIndex.getOrNull(slot)
|
||||
else
|
||||
super.getChild(slot)
|
||||
|
||||
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)
|
||||
override fun replaceChild(slot: Int, newChild: IrElement) {
|
||||
if (0 <= slot)
|
||||
putArgument(slot, newChild.assertCast())
|
||||
else
|
||||
super.replaceChild(slot, newChild)
|
||||
}
|
||||
|
||||
override fun <R, D> accept(visitor: IrElementVisitor<R, D>, data: D): R =
|
||||
visitor.visitCallExpression(this, data)
|
||||
|
||||
override fun <D> acceptChildren(visitor: IrElementVisitor<Unit, D>, data: D) {
|
||||
super.acceptChildren(visitor, data)
|
||||
argumentsByParameterIndex.forEach { it?.accept(visitor, data) }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,145 +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
|
||||
|
||||
import org.jetbrains.kotlin.ir.ARGUMENT0_INDEX
|
||||
import org.jetbrains.kotlin.ir.ARGUMENT1_INDEX
|
||||
import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
import java.util.*
|
||||
|
||||
interface IrCompoundExpression : IrExpression, IrExpressionOwner
|
||||
|
||||
interface IrCompoundExpression1 : IrCompoundExpression, IrExpressionOwner1
|
||||
|
||||
interface IrCompoundExpression2 : IrCompoundExpression, IrExpressionOwner2
|
||||
|
||||
interface IrCompoundExpressionN : IrCompoundExpression, IrExpressionOwnerN
|
||||
|
||||
abstract class IrCompoundExpressionNBase(
|
||||
startOffset: Int,
|
||||
endOffset: Int,
|
||||
override val type: KotlinType?
|
||||
) : IrExpressionBase(startOffset, endOffset, type), IrCompoundExpressionN {
|
||||
override val childExpressions: MutableList<IrExpression> = ArrayList()
|
||||
|
||||
override fun <D> acceptChildren(visitor: IrElementVisitor<Unit, D>, data: D) {
|
||||
childExpressions.forEach { it.accept(visitor, data) }
|
||||
}
|
||||
|
||||
override fun addChildExpression(child: IrExpression) {
|
||||
child.setTreeLocation(this, childExpressions.size)
|
||||
childExpressions.add(child)
|
||||
}
|
||||
|
||||
override fun getChildExpression(index: Int): IrExpression? =
|
||||
childExpressions.getOrNull(index)
|
||||
|
||||
override fun removeChildExpression(child: IrExpression) {
|
||||
validateChild(child)
|
||||
childExpressions.removeAt(child.index)
|
||||
for (i in child.index ..childExpressions.size - 1) {
|
||||
childExpressions[i].setTreeLocation(parent, i)
|
||||
}
|
||||
child.detach()
|
||||
}
|
||||
|
||||
override fun replaceChildExpression(oldChild: IrExpression, newChild: IrExpression) {
|
||||
validateChild(oldChild)
|
||||
childExpressions[oldChild.index] = newChild
|
||||
newChild.setTreeLocation(this, oldChild.index)
|
||||
oldChild.detach()
|
||||
}
|
||||
|
||||
override fun <D> acceptChildExpressions(visitor: IrElementVisitor<Unit, D>, data: D) {
|
||||
childExpressions.forEach { it.accept(visitor, data) }
|
||||
}
|
||||
}
|
||||
|
||||
// TODO IrExpressionBodyImpl vs IrCompoundExpression1Impl: extract common base class?
|
||||
abstract class IrCompoundExpression1Base(
|
||||
startOffset: Int,
|
||||
endOffset: Int,
|
||||
override val type: KotlinType?
|
||||
) : IrExpressionBase(startOffset, endOffset, type), IrCompoundExpression1 {
|
||||
override var argument: IrExpression? = null
|
||||
set(newExpression) {
|
||||
field?.detach()
|
||||
field = newExpression
|
||||
newExpression?.setTreeLocation(this, ARGUMENT0_INDEX)
|
||||
}
|
||||
|
||||
override fun getChildExpression(index: Int): IrExpression? =
|
||||
if (index == ARGUMENT0_INDEX) argument else null
|
||||
|
||||
override fun replaceChildExpression(oldChild: IrExpression, newChild: IrExpression) {
|
||||
validateChild(oldChild)
|
||||
argument = newChild
|
||||
}
|
||||
|
||||
override fun <D> acceptChildren(visitor: IrElementVisitor<Unit, D>, data: D) {
|
||||
acceptChildExpressions(visitor, data)
|
||||
}
|
||||
|
||||
override fun <D> acceptChildExpressions(visitor: IrElementVisitor<Unit, D>, data: D) {
|
||||
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)
|
||||
}
|
||||
}
|
||||
+22
-3
@@ -18,6 +18,8 @@ package org.jetbrains.kotlin.ir.expressions
|
||||
|
||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
||||
import org.jetbrains.kotlin.ir.IrElement
|
||||
import org.jetbrains.kotlin.ir.throwNoSuchSlot
|
||||
import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
|
||||
@@ -39,14 +41,31 @@ abstract class IrDeclarationReferenceBase<out D : DeclarationDescriptor>(
|
||||
endOffset: Int,
|
||||
type: KotlinType?,
|
||||
override val descriptor: D
|
||||
) : IrTerminalExpressionBase(startOffset, endOffset, type), IrDeclarationReference
|
||||
) : IrExpressionBase(startOffset, endOffset, type), IrDeclarationReference
|
||||
|
||||
abstract class IrTerminalDeclarationReferenceBase<out D : DeclarationDescriptor>(
|
||||
startOffset: Int,
|
||||
endOffset: Int,
|
||||
type: KotlinType?,
|
||||
descriptor: D
|
||||
) : IrDeclarationReferenceBase<D>(startOffset, endOffset, type, descriptor) {
|
||||
override fun getChild(slot: Int): IrElement? = null
|
||||
|
||||
override fun replaceChild(slot: Int, newChild: IrElement) {
|
||||
throwNoSuchSlot(slot)
|
||||
}
|
||||
|
||||
override fun <D> acceptChildren(visitor: IrElementVisitor<Unit, D>, data: D) {
|
||||
// No children
|
||||
}
|
||||
}
|
||||
|
||||
class IrGetObjectValueExpressionImpl(
|
||||
startOffset: Int,
|
||||
endOffset: Int,
|
||||
type: KotlinType?,
|
||||
descriptor: ClassDescriptor
|
||||
) : IrDeclarationReferenceBase<ClassDescriptor>(startOffset, endOffset, type, descriptor), IrGetObjectValueExpression {
|
||||
) : IrTerminalDeclarationReferenceBase<ClassDescriptor>(startOffset, endOffset, type, descriptor), IrGetObjectValueExpression {
|
||||
override fun <R, D> accept(visitor: IrElementVisitor<R, D>, data: D): R =
|
||||
visitor.visitGetObjectValue(this, data)
|
||||
}
|
||||
@@ -56,7 +75,7 @@ class IrGetEnumValueExpressionImpl(
|
||||
endOffset: Int,
|
||||
type: KotlinType?,
|
||||
descriptor: ClassDescriptor
|
||||
) : IrDeclarationReferenceBase<ClassDescriptor>(startOffset, endOffset, type, descriptor), IrGetEnumValueExpression {
|
||||
) : IrTerminalDeclarationReferenceBase<ClassDescriptor>(startOffset, endOffset, type, descriptor), IrGetEnumValueExpression {
|
||||
override fun <R, D> accept(visitor: IrElementVisitor<R, D>, data: D): R {
|
||||
return visitor.visitGetEnumValue(this, data)
|
||||
}
|
||||
|
||||
@@ -24,7 +24,7 @@ class IrDummyExpression(
|
||||
endOffset: Int,
|
||||
type: KotlinType?,
|
||||
val description: String
|
||||
) : IrExpressionBase(startOffset, endOffset, type) {
|
||||
) : IrTerminalExpressionBase(startOffset, endOffset, type) {
|
||||
override fun <R, D> accept(visitor: IrElementVisitor<R, D>, data: D): R =
|
||||
visitor.visitDummyExpression(this, data)
|
||||
|
||||
|
||||
@@ -16,48 +16,34 @@
|
||||
|
||||
package org.jetbrains.kotlin.ir.expressions
|
||||
|
||||
import org.jetbrains.kotlin.ir.DETACHED_INDEX
|
||||
import org.jetbrains.kotlin.ir.IrElement
|
||||
import org.jetbrains.kotlin.ir.IrElementBase
|
||||
import org.jetbrains.kotlin.ir.IrStatement
|
||||
import org.jetbrains.kotlin.ir.throwNoSuchSlot
|
||||
import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
|
||||
|
||||
interface IrExpression : IrElement {
|
||||
override val parent: IrExpressionOwner?
|
||||
val index: Int
|
||||
interface IrExpression : IrStatement {
|
||||
val type: KotlinType?
|
||||
|
||||
fun setTreeLocation(parent: IrExpressionOwner?, index: Int)
|
||||
}
|
||||
|
||||
fun IrExpression.detach() {
|
||||
setTreeLocation(null, DETACHED_INDEX)
|
||||
}
|
||||
|
||||
fun IrExpressionOwner.validateChild(child: IrExpression) {
|
||||
assert(child.parent == this && getChildExpression(child.index) == child) { "Inconsistent child: $child" }
|
||||
}
|
||||
|
||||
abstract class IrExpressionBase(
|
||||
startOffset: Int,
|
||||
endOffset: Int,
|
||||
override val type: KotlinType?
|
||||
) : IrElementBase(startOffset, endOffset), IrExpression {
|
||||
override var parent: IrExpressionOwner? = null
|
||||
override var index: Int = DETACHED_INDEX
|
||||
|
||||
override fun setTreeLocation(parent: IrExpressionOwner?, index: Int) {
|
||||
this.parent = parent
|
||||
this.index = index
|
||||
}
|
||||
}
|
||||
) : IrElementBase(startOffset, endOffset), IrExpression
|
||||
|
||||
abstract class IrTerminalExpressionBase(
|
||||
startOffset: Int,
|
||||
endOffset: Int,
|
||||
type: KotlinType?
|
||||
) : IrExpressionBase(startOffset, endOffset, type) {
|
||||
override fun getChild(slot: Int): IrElement? = null
|
||||
|
||||
override fun replaceChild(slot: Int, newChild: IrElement) {
|
||||
throwNoSuchSlot(slot)
|
||||
}
|
||||
|
||||
override fun <D> acceptChildren(visitor: IrElementVisitor<Unit, D>, data: D) {
|
||||
// No children
|
||||
}
|
||||
|
||||
@@ -1,41 +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
|
||||
|
||||
import org.jetbrains.kotlin.ir.IrElement
|
||||
import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
|
||||
|
||||
interface IrExpressionOwner : IrElement {
|
||||
fun getChildExpression(index: Int): IrExpression?
|
||||
fun replaceChildExpression(oldChild: IrExpression, newChild: IrExpression)
|
||||
fun <D> acceptChildExpressions(visitor: IrElementVisitor<Unit, D>, data: D)
|
||||
}
|
||||
|
||||
interface IrExpressionOwner1 : IrExpressionOwner {
|
||||
var argument: IrExpression?
|
||||
}
|
||||
|
||||
interface IrExpressionOwner2 : IrExpressionOwner {
|
||||
var argument0: IrExpression?
|
||||
var argument1: IrExpression?
|
||||
}
|
||||
|
||||
interface IrExpressionOwnerN : IrExpressionOwner {
|
||||
val childExpressions: List<IrExpression>
|
||||
fun addChildExpression(child: IrExpression)
|
||||
fun removeChildExpression(child: IrExpression)
|
||||
}
|
||||
+3
-3
@@ -34,7 +34,7 @@ class IrGetVariableExpressionImpl(
|
||||
endOffset: Int,
|
||||
type: KotlinType?,
|
||||
descriptor: VariableDescriptor
|
||||
) : IrDeclarationReferenceBase<VariableDescriptor>(startOffset, endOffset, type, descriptor), IrGetVariableExpression {
|
||||
) : IrTerminalDeclarationReferenceBase<VariableDescriptor>(startOffset, endOffset, type, descriptor), IrGetVariableExpression {
|
||||
override fun <R, D> accept(visitor: IrElementVisitor<R, D>, data: D): R =
|
||||
visitor.visitGetVariable(this, data)
|
||||
}
|
||||
@@ -43,8 +43,8 @@ class IrGetExtensionReceiverExpressionImpl(
|
||||
startOffset: Int,
|
||||
endOffset: Int,
|
||||
type: KotlinType?,
|
||||
override val descriptor: CallableDescriptor
|
||||
) : IrTerminalExpressionBase(startOffset, endOffset, type), IrGetExtensionReceiverExpression {
|
||||
descriptor: CallableDescriptor
|
||||
) : IrTerminalDeclarationReferenceBase<CallableDescriptor>(startOffset, endOffset, type, descriptor), IrGetExtensionReceiverExpression {
|
||||
override fun <R, D> accept(visitor: IrElementVisitor<R, D>, data: D): R =
|
||||
visitor.visitGetExtensionReceiver(this, data)
|
||||
}
|
||||
-70
@@ -1,70 +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
|
||||
|
||||
import org.jetbrains.kotlin.ir.CHILD_DECLARATION_INDEX
|
||||
import org.jetbrains.kotlin.ir.declarations.*
|
||||
import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
|
||||
interface IrLocalDeclarationExpression<out D : IrMemberDeclaration> : IrExpression, IrDeclarationOwner1 {
|
||||
override val childDeclaration: D
|
||||
}
|
||||
|
||||
interface IrLocalVariableDeclarationExpression : IrLocalDeclarationExpression<IrLocalVariable> {
|
||||
override var childDeclaration: IrLocalVariable
|
||||
}
|
||||
|
||||
abstract class IrLocalDeclarationExpressionBase(
|
||||
startOffset: Int,
|
||||
endOffset: Int,
|
||||
type: KotlinType?
|
||||
) : IrExpressionBase(startOffset, endOffset, type), IrLocalVariableDeclarationExpression {
|
||||
private var childDeclarationImpl: IrLocalVariable? = null
|
||||
override var childDeclaration: IrLocalVariable
|
||||
get() = childDeclarationImpl!!
|
||||
set(value) {
|
||||
childDeclarationImpl?.detach()
|
||||
childDeclarationImpl = value
|
||||
value.setTreeLocation(this, CHILD_DECLARATION_INDEX)
|
||||
}
|
||||
|
||||
override fun getChildDeclaration(index: Int): IrMemberDeclaration? =
|
||||
if (index == CHILD_DECLARATION_INDEX) childDeclaration else null
|
||||
|
||||
override fun replaceChildDeclaration(oldChild: IrMemberDeclaration, newChild: IrMemberDeclaration) {
|
||||
if (newChild !is IrLocalVariable) throw AssertionError("IrLocalVariable expected: $newChild")
|
||||
validateChild(oldChild)
|
||||
childDeclaration = newChild
|
||||
}
|
||||
|
||||
override fun <D> acceptChildren(visitor: IrElementVisitor<Unit, D>, data: D) {
|
||||
childDeclarationImpl?.accept(visitor, data)
|
||||
}
|
||||
}
|
||||
|
||||
class IrLocalVariableDeclarationExpressionImpl(
|
||||
startOffset: Int,
|
||||
endOffset: Int
|
||||
) : IrLocalDeclarationExpressionBase(startOffset, endOffset, null), IrLocalVariableDeclarationExpression {
|
||||
constructor(startOffset: Int, endOffset: Int, childDeclaration: IrLocalVariable) : this(startOffset, endOffset) {
|
||||
this.childDeclaration = childDeclaration
|
||||
}
|
||||
|
||||
override fun <R, D> accept(visitor: IrElementVisitor<R, D>, data: D): R =
|
||||
visitor.visitLocalVariableDeclarationExpression(this, data)
|
||||
}
|
||||
+27
-5
@@ -16,11 +16,11 @@
|
||||
|
||||
package org.jetbrains.kotlin.ir.expressions
|
||||
|
||||
import org.jetbrains.kotlin.ir.DISPATCH_RECEIVER_INDEX
|
||||
import org.jetbrains.kotlin.ir.EXTENSION_RECEIVER_INDEX
|
||||
import org.jetbrains.kotlin.ir.*
|
||||
import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
|
||||
interface IrMemberAccessExpression : IrDeclarationReference, IrExpressionOwner {
|
||||
interface IrMemberAccessExpression : IrDeclarationReference {
|
||||
var dispatchReceiver: IrExpression?
|
||||
var extensionReceiver: IrExpression?
|
||||
val isSafe: Boolean
|
||||
@@ -34,15 +34,37 @@ abstract class IrMemberAccessExpressionBase(
|
||||
) : IrExpressionBase(startOffset, endOffset, type), IrMemberAccessExpression {
|
||||
override var dispatchReceiver: IrExpression? = null
|
||||
set(newReceiver) {
|
||||
newReceiver?.assertDetached()
|
||||
field?.detach()
|
||||
field = newReceiver
|
||||
newReceiver?.setTreeLocation(this, DISPATCH_RECEIVER_INDEX)
|
||||
newReceiver?.setTreeLocation(this, DISPATCH_RECEIVER_SLOT)
|
||||
}
|
||||
|
||||
override var extensionReceiver: IrExpression? = null
|
||||
set(newReceiver) {
|
||||
newReceiver?.assertDetached()
|
||||
field?.detach()
|
||||
field = newReceiver
|
||||
newReceiver?.setTreeLocation(this, EXTENSION_RECEIVER_INDEX)
|
||||
newReceiver?.setTreeLocation(this, EXTENSION_RECEIVER_SLOT)
|
||||
}
|
||||
|
||||
override fun getChild(slot: Int): IrElement? =
|
||||
when (slot) {
|
||||
DISPATCH_RECEIVER_SLOT -> dispatchReceiver
|
||||
EXTENSION_RECEIVER_SLOT -> extensionReceiver
|
||||
else -> null
|
||||
}
|
||||
|
||||
override fun replaceChild(slot: Int, newChild: IrElement) {
|
||||
when (slot) {
|
||||
DISPATCH_RECEIVER_SLOT -> dispatchReceiver = newChild.assertCast()
|
||||
EXTENSION_RECEIVER_SLOT -> extensionReceiver = newChild.assertCast()
|
||||
else -> throwNoSuchSlot(slot)
|
||||
}
|
||||
}
|
||||
|
||||
override fun <D> acceptChildren(visitor: IrElementVisitor<Unit, D>, data: D) {
|
||||
dispatchReceiver?.accept(visitor, data)
|
||||
extensionReceiver?.accept(visitor, data)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -30,7 +30,8 @@ enum class IrOperator {
|
||||
RANGE,
|
||||
PLUS, MINUS, MUL, DIV, MOD,
|
||||
EQ,
|
||||
PLUSEQ, MINUSEQ, MULEQ, DIVEQ, MODEQ;
|
||||
PLUSEQ, MINUSEQ, MULEQ, DIVEQ, MODEQ,
|
||||
DESTRUCTURING;
|
||||
}
|
||||
|
||||
private val CAO_START = IrOperator.PLUSEQ.ordinal
|
||||
|
||||
+101
-4
@@ -17,6 +17,7 @@
|
||||
package org.jetbrains.kotlin.ir.expressions
|
||||
|
||||
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
||||
import org.jetbrains.kotlin.ir.*
|
||||
import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
|
||||
@@ -25,9 +26,14 @@ interface IrOperatorExpression : IrExpression {
|
||||
val relatedDescriptor: FunctionDescriptor?
|
||||
}
|
||||
|
||||
interface IrUnaryOperatorExpression : IrOperatorExpression, IrCompoundExpression1
|
||||
interface IrUnaryOperatorExpression : IrOperatorExpression {
|
||||
var argument: IrExpression
|
||||
}
|
||||
|
||||
interface IrBinaryOperatorExpression : IrOperatorExpression, IrCompoundExpression2
|
||||
interface IrBinaryOperatorExpression : IrOperatorExpression {
|
||||
var argument0: IrExpression
|
||||
var argument1: IrExpression
|
||||
}
|
||||
|
||||
class IrUnaryOperatorExpressionImpl(
|
||||
startOffset: Int,
|
||||
@@ -35,10 +41,48 @@ class IrUnaryOperatorExpressionImpl(
|
||||
type: KotlinType?,
|
||||
override val operator: IrOperator,
|
||||
override val relatedDescriptor: FunctionDescriptor?
|
||||
) : IrCompoundExpression1Base(startOffset, endOffset, type), IrUnaryOperatorExpression {
|
||||
) : IrExpressionBase(startOffset, endOffset, type), IrUnaryOperatorExpression {
|
||||
constructor(
|
||||
startOffset: Int,
|
||||
endOffset: Int,
|
||||
type: KotlinType?,
|
||||
operator: IrOperator,
|
||||
relatedDescriptor: FunctionDescriptor?,
|
||||
argument: IrExpression
|
||||
) : this(startOffset, endOffset, type, operator, relatedDescriptor) {
|
||||
this.argument = argument
|
||||
}
|
||||
|
||||
private var argumentImpl: IrExpression? = null
|
||||
override var argument: IrExpression
|
||||
get() = argumentImpl!!
|
||||
set(value) {
|
||||
value.assertDetached()
|
||||
argumentImpl?.detach()
|
||||
argumentImpl = value
|
||||
value.setTreeLocation(this, ARGUMENT0_SLOT)
|
||||
}
|
||||
|
||||
override fun getChild(slot: Int): IrElement? =
|
||||
when (slot) {
|
||||
ARGUMENT0_SLOT -> argument
|
||||
else -> null
|
||||
}
|
||||
|
||||
override fun replaceChild(slot: Int, newChild: IrElement) {
|
||||
when (slot) {
|
||||
ARGUMENT0_SLOT -> argument = newChild.assertCast()
|
||||
else -> throwNoSuchSlot(slot)
|
||||
}
|
||||
}
|
||||
|
||||
override fun <R, D> accept(visitor: IrElementVisitor<R, D>, data: D): R {
|
||||
return visitor.visitUnaryOperator(this, data)
|
||||
}
|
||||
|
||||
override fun <D> acceptChildren(visitor: IrElementVisitor<Unit, D>, data: D) {
|
||||
argument.accept(visitor, data)
|
||||
}
|
||||
}
|
||||
|
||||
class IrBinaryOperatorExpressionImpl(
|
||||
@@ -47,7 +91,60 @@ class IrBinaryOperatorExpressionImpl(
|
||||
type: KotlinType?,
|
||||
override val operator: IrOperator,
|
||||
override val relatedDescriptor: FunctionDescriptor?
|
||||
) : IrCompoundExpression2Base(startOffset, endOffset, type), IrBinaryOperatorExpression {
|
||||
) : IrExpressionBase(startOffset, endOffset, type), IrBinaryOperatorExpression {
|
||||
constructor(
|
||||
startOffset: Int,
|
||||
endOffset: Int,
|
||||
type: KotlinType?,
|
||||
operator: IrOperator,
|
||||
relatedDescriptor: FunctionDescriptor?,
|
||||
argument0: IrExpression,
|
||||
argument1: IrExpression
|
||||
) : this(startOffset, endOffset, type, operator, relatedDescriptor) {
|
||||
this.argument0 = argument0
|
||||
this.argument1 = argument1
|
||||
}
|
||||
|
||||
private var argument0Impl: IrExpression? = null
|
||||
override var argument0: IrExpression
|
||||
get() = argument0Impl!!
|
||||
set(value) {
|
||||
value.assertDetached()
|
||||
argument0Impl?.detach()
|
||||
argument0Impl = value
|
||||
value.setTreeLocation(this, ARGUMENT0_SLOT)
|
||||
}
|
||||
|
||||
private var argument1Impl: IrExpression? = null
|
||||
override var argument1: IrExpression
|
||||
get() = argument1Impl!!
|
||||
set(value) {
|
||||
value.assertDetached()
|
||||
argument1Impl?.detach()
|
||||
argument1Impl = value
|
||||
value.setTreeLocation(this, ARGUMENT1_SLOT)
|
||||
}
|
||||
|
||||
override fun getChild(slot: Int): IrElement? =
|
||||
when (slot) {
|
||||
ARGUMENT0_SLOT -> argument0
|
||||
ARGUMENT1_SLOT -> argument1
|
||||
else -> null
|
||||
}
|
||||
|
||||
override fun replaceChild(slot: Int, newChild: IrElement) {
|
||||
when (slot) {
|
||||
ARGUMENT0_SLOT -> argument0 = newChild.assertCast()
|
||||
ARGUMENT1_SLOT -> argument1 = newChild.assertCast()
|
||||
else -> throwNoSuchSlot(slot)
|
||||
}
|
||||
}
|
||||
|
||||
override fun <R, D> accept(visitor: IrElementVisitor<R, D>, data: D): R =
|
||||
visitor.visitBinaryOperator(this, data)
|
||||
|
||||
override fun <D> acceptChildren(visitor: IrElementVisitor<Unit, D>, data: D) {
|
||||
argument0.acceptChildren(visitor, data)
|
||||
argument1.acceptChildren(visitor, data)
|
||||
}
|
||||
}
|
||||
|
||||
+34
-54
@@ -17,9 +17,7 @@
|
||||
package org.jetbrains.kotlin.ir.expressions
|
||||
|
||||
import org.jetbrains.kotlin.descriptors.PropertyDescriptor
|
||||
import org.jetbrains.kotlin.ir.ARGUMENT0_INDEX
|
||||
import org.jetbrains.kotlin.ir.DISPATCH_RECEIVER_INDEX
|
||||
import org.jetbrains.kotlin.ir.EXTENSION_RECEIVER_INDEX
|
||||
import org.jetbrains.kotlin.ir.*
|
||||
import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
|
||||
@@ -29,7 +27,9 @@ interface IrPropertyAccessExpression : IrMemberAccessExpression {
|
||||
|
||||
interface IrGetPropertyExpression : IrPropertyAccessExpression
|
||||
|
||||
interface IrSetPropertyExpression : IrPropertyAccessExpression, IrCompoundExpression1
|
||||
interface IrSetPropertyExpression : IrPropertyAccessExpression {
|
||||
var value: IrExpression
|
||||
}
|
||||
|
||||
class IrGetPropertyExpressionImpl(
|
||||
startOffset: Int,
|
||||
@@ -38,33 +38,8 @@ class IrGetPropertyExpressionImpl(
|
||||
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
|
||||
}
|
||||
}
|
||||
override fun <R, D> accept(visitor: IrElementVisitor<R, D>, data: D): R =
|
||||
visitor.visitGetProperty(this, data)
|
||||
}
|
||||
|
||||
class IrSetPropertyExpressionImpl(
|
||||
@@ -74,11 +49,25 @@ class IrSetPropertyExpressionImpl(
|
||||
isSafe: Boolean,
|
||||
override val descriptor: PropertyDescriptor
|
||||
) : IrMemberAccessExpressionBase(startOffset, endOffset, type, isSafe), IrSetPropertyExpression {
|
||||
override var argument: IrExpression? = null
|
||||
constructor(
|
||||
startOffset: Int,
|
||||
endOffset: Int,
|
||||
type: KotlinType?,
|
||||
isSafe: Boolean,
|
||||
descriptor: PropertyDescriptor,
|
||||
value: IrExpression
|
||||
) : this(startOffset, endOffset, type, isSafe, descriptor) {
|
||||
this.value = value
|
||||
}
|
||||
|
||||
private var valueImpl: IrExpression? = null
|
||||
override var value: IrExpression
|
||||
get() = valueImpl!!
|
||||
set(value) {
|
||||
field?.detach()
|
||||
field = value
|
||||
value?.setTreeLocation(this, ARGUMENT0_INDEX)
|
||||
value.assertDetached()
|
||||
valueImpl?.detach()
|
||||
valueImpl = value
|
||||
value.setTreeLocation(this, ARGUMENT0_SLOT)
|
||||
}
|
||||
|
||||
override fun <R, D> accept(visitor: IrElementVisitor<R, D>, data: D): R {
|
||||
@@ -86,29 +75,20 @@ class IrSetPropertyExpressionImpl(
|
||||
}
|
||||
|
||||
override fun <D> acceptChildren(visitor: IrElementVisitor<Unit, D>, data: D) {
|
||||
acceptChildExpressions(visitor, data)
|
||||
super.acceptChildren(visitor, data)
|
||||
value.accept(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 getChild(slot: Int): IrElement? =
|
||||
when (slot) {
|
||||
ARGUMENT0_SLOT -> value
|
||||
else -> super.getChild(slot)
|
||||
}
|
||||
|
||||
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
|
||||
override fun replaceChild(slot: Int, newChild: IrElement) {
|
||||
when (slot) {
|
||||
ARGUMENT0_SLOT -> value = newChild.assertCast()
|
||||
else -> super.replaceChild(slot, newChild)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,17 +16,56 @@
|
||||
|
||||
package org.jetbrains.kotlin.ir.expressions
|
||||
|
||||
import org.jetbrains.kotlin.ir.*
|
||||
import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
|
||||
|
||||
interface IrReturnExpression : IrCompoundExpression1
|
||||
interface IrReturnExpression : IrExpression {
|
||||
var value: IrExpression?
|
||||
}
|
||||
|
||||
class IrReturnExpressionImpl(
|
||||
startOffset: Int,
|
||||
endOffset: Int,
|
||||
type: KotlinType?
|
||||
) : IrCompoundExpression1Base(startOffset, endOffset, type), IrReturnExpression {
|
||||
) : IrExpressionBase(startOffset, endOffset, type), IrReturnExpression {
|
||||
constructor(
|
||||
startOffset: Int,
|
||||
endOffset: Int,
|
||||
type: KotlinType?,
|
||||
value: IrExpression?
|
||||
) : this(startOffset, endOffset, type) {
|
||||
this.value = value
|
||||
}
|
||||
|
||||
override var value: IrExpression? = null
|
||||
set(newValue) {
|
||||
newValue?.assertDetached()
|
||||
field?.detach()
|
||||
field = newValue
|
||||
newValue?.setTreeLocation(this, CHILD_EXPRESSION_SLOT)
|
||||
}
|
||||
|
||||
override fun getChild(slot: Int): IrElement? =
|
||||
when (slot) {
|
||||
CHILD_EXPRESSION_SLOT -> value
|
||||
else -> null
|
||||
}
|
||||
|
||||
override fun replaceChild(slot: Int, newChild: IrElement) {
|
||||
when (slot) {
|
||||
CHILD_EXPRESSION_SLOT -> value = newChild.assertCast()
|
||||
else -> throwNoSuchSlot(slot)
|
||||
}
|
||||
}
|
||||
|
||||
override fun <R, D> accept(visitor: IrElementVisitor<R, D>, data: D): R =
|
||||
visitor.visitReturnExpression(this, data)
|
||||
|
||||
override fun <D> acceptChildren(visitor: IrElementVisitor<Unit, D>, data: D) {
|
||||
value?.accept(visitor, data)
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
+34
-2
@@ -16,16 +16,48 @@
|
||||
|
||||
package org.jetbrains.kotlin.ir.expressions
|
||||
|
||||
import org.jetbrains.kotlin.ir.*
|
||||
import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
import java.util.*
|
||||
|
||||
interface IrStringConcatenationExpression : IrCompoundExpressionN
|
||||
interface IrStringConcatenationExpression : IrExpression {
|
||||
val arguments: List<IrExpression>
|
||||
fun addArgument(argument: IrExpression)
|
||||
}
|
||||
|
||||
class IrStringConcatenationExpressionImpl(
|
||||
startOffset: Int,
|
||||
endOffset: Int,
|
||||
type: KotlinType?
|
||||
) : IrCompoundExpressionNBase(startOffset, endOffset, type), IrStringConcatenationExpression {
|
||||
) : IrExpressionBase(startOffset, endOffset, type), IrStringConcatenationExpression {
|
||||
override val arguments: MutableList<IrExpression> = ArrayList()
|
||||
|
||||
override fun addArgument(argument: IrExpression) {
|
||||
argument.assertDetached()
|
||||
argument.setTreeLocation(this, arguments.size)
|
||||
arguments.add(argument)
|
||||
}
|
||||
|
||||
override fun getChild(slot: Int): IrElement? =
|
||||
arguments.getOrNull(slot)
|
||||
|
||||
override fun replaceChild(slot: Int, newChild: IrElement) {
|
||||
newChild.assertDetached()
|
||||
if (0 <= slot && slot < arguments.size) {
|
||||
arguments[slot].detach()
|
||||
arguments[slot] = newChild.assertCast()
|
||||
newChild.setTreeLocation(this, slot)
|
||||
}
|
||||
else {
|
||||
throwNoSuchSlot(slot)
|
||||
}
|
||||
}
|
||||
|
||||
override fun <R, D> accept(visitor: IrElementVisitor<R, D>, data: D): R =
|
||||
visitor.visitStringTemplate(this, data)
|
||||
|
||||
override fun <D> acceptChildren(visitor: IrElementVisitor<Unit, D>, data: D) {
|
||||
arguments.forEach { it.accept(visitor, data) }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -30,7 +30,6 @@ class IrThisExpressionImpl(
|
||||
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)
|
||||
}
|
||||
override fun <R, D> accept(visitor: IrElementVisitor<R, D>, data: D): R =
|
||||
visitor.visitThisExpression(this, data)
|
||||
}
|
||||
+45
-4
@@ -16,6 +16,7 @@
|
||||
|
||||
package org.jetbrains.kotlin.ir.expressions
|
||||
|
||||
import org.jetbrains.kotlin.ir.*
|
||||
import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
|
||||
@@ -27,8 +28,9 @@ enum class IrTypeOperator {
|
||||
NOT_IS;
|
||||
}
|
||||
|
||||
interface IrTypeOperatorExpression : IrExpression, IrCompoundExpression1 {
|
||||
interface IrTypeOperatorExpression : IrExpression {
|
||||
val operator: IrTypeOperator
|
||||
var argument: IrExpression
|
||||
val typeOperand: KotlinType
|
||||
}
|
||||
|
||||
@@ -38,8 +40,47 @@ class IrTypeOperatorExpressionImpl(
|
||||
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)
|
||||
) : IrExpressionBase(startOffset, endOffset, type), IrTypeOperatorExpression {
|
||||
constructor(
|
||||
startOffset: Int,
|
||||
endOffset: Int,
|
||||
type: KotlinType?,
|
||||
operator: IrTypeOperator,
|
||||
argument: IrExpression,
|
||||
typeOperand: KotlinType
|
||||
) : this(startOffset, endOffset, type, operator, typeOperand) {
|
||||
this.argument = argument
|
||||
}
|
||||
|
||||
private var argumentImpl: IrExpression? = null
|
||||
override var argument: IrExpression
|
||||
get() = argumentImpl!!
|
||||
set(value) {
|
||||
value.assertDetached()
|
||||
argumentImpl?.detach()
|
||||
argumentImpl = value
|
||||
value.setTreeLocation(this, ARGUMENT0_SLOT)
|
||||
}
|
||||
|
||||
override fun getChild(slot: Int): IrElement? =
|
||||
when (slot) {
|
||||
ARGUMENT0_SLOT -> argument
|
||||
else -> null
|
||||
}
|
||||
|
||||
override fun replaceChild(slot: Int, newChild: IrElement) {
|
||||
when (slot) {
|
||||
ARGUMENT0_SLOT -> argument = newChild.assertCast()
|
||||
else -> throwNoSuchSlot(slot)
|
||||
}
|
||||
}
|
||||
|
||||
override fun <R, D> accept(visitor: IrElementVisitor<R, D>, data: D): R =
|
||||
visitor.visitTypeOperatorExpression(this, data)
|
||||
|
||||
override fun <D> acceptChildren(visitor: IrElementVisitor<Unit, D>, data: D) {
|
||||
argument.accept(visitor, data)
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -50,7 +50,7 @@ class DumpIrTreeVisitor(out: Appendable): IrElementVisitor<Unit, String> {
|
||||
expression.dispatchReceiver?.accept(this, "\$this")
|
||||
expression.extensionReceiver?.accept(this, "\$receiver")
|
||||
for (valueParameter in expression.descriptor.valueParameters) {
|
||||
expression.getValueArgument(valueParameter.index)?.accept(this, valueParameter.name.asString())
|
||||
expression.getArgument(valueParameter.index)?.accept(this, valueParameter.name.asString())
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -66,7 +66,7 @@ class DumpIrTreeVisitor(out: Appendable): IrElementVisitor<Unit, String> {
|
||||
expression.dumpLabeledElementWith(data) {
|
||||
expression.dispatchReceiver?.accept(this, "\$this")
|
||||
expression.extensionReceiver?.accept(this, "\$receiver")
|
||||
expression.argument?.accept(this, "\$value")
|
||||
expression.value.accept(this, "\$value")
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -48,8 +48,8 @@ class RenderIrElementVisitor : IrElementVisitor<String, Nothing?> {
|
||||
override fun visitPropertySetter(declaration: IrPropertySetter, data: Nothing?): String =
|
||||
"IrPropertySetter ${declaration.descriptor.render()} property=${declaration.property?.name()}"
|
||||
|
||||
override fun visitLocalVariable(declaration: IrLocalVariable, data: Nothing?): String =
|
||||
"IrLocalVariable ${declaration.descriptor.render()}"
|
||||
override fun visitLocalVariable(declaration: IrVariable, data: Nothing?): String =
|
||||
"VAR ${declaration.descriptor.render()}"
|
||||
|
||||
override fun visitExpressionBody(body: IrExpressionBody, data: Nothing?): String =
|
||||
"IrExpressionBody"
|
||||
@@ -60,11 +60,8 @@ class RenderIrElementVisitor : IrElementVisitor<String, Nothing?> {
|
||||
override fun <T> visitLiteral(expression: IrLiteralExpression<T>, data: Nothing?): String =
|
||||
"LITERAL ${expression.kind} type=${expression.renderType()} value='${expression.value}'"
|
||||
|
||||
override fun visitLocalVariableDeclarationExpression(expression: IrLocalVariableDeclarationExpression, data: Nothing?): String =
|
||||
"LOCAL ${expression.childDeclaration.descriptor.name}"
|
||||
|
||||
override fun visitBlockExpression(expression: IrBlockExpression, data: Nothing?): String =
|
||||
"BLOCK type=${expression.renderType()}"
|
||||
"BLOCK type=${expression.renderType()} hasResult=${expression.hasResult} isDesugared=${expression.isDesugared}"
|
||||
|
||||
override fun visitReturnExpression(expression: IrReturnExpression, data: Nothing?): String =
|
||||
"RETURN type=${expression.renderType()}"
|
||||
|
||||
@@ -22,19 +22,18 @@ import org.jetbrains.kotlin.ir.expressions.*
|
||||
|
||||
interface IrElementVisitor<out R, in D> {
|
||||
fun visitElement(element: IrElement, data: D): R
|
||||
fun visitModule(declaration: IrModule, data: D): R = visitElement(declaration, data)
|
||||
fun visitFile(declaration: IrFile, data: D): R = visitElement(declaration, data)
|
||||
|
||||
fun visitDeclaration(declaration: IrDeclaration, data: D): R = visitElement(declaration, data)
|
||||
fun visitModule(declaration: IrModule, data: D): R = visitDeclaration(declaration, data)
|
||||
fun visitCompoundDeclaration(declaration: IrCompoundDeclaration, data: D): R = visitDeclaration(declaration, data)
|
||||
fun visitFile(declaration: IrFile, data: D): R = visitCompoundDeclaration(declaration, data)
|
||||
fun visitClass(declaration: IrClass, data: D): R = visitCompoundDeclaration(declaration, data)
|
||||
fun visitClass(declaration: IrClass, data: D): R = visitDeclaration(declaration, data)
|
||||
fun visitFunction(declaration: IrFunction, data: D): R = visitDeclaration(declaration, data)
|
||||
fun visitPropertyGetter(declaration: IrPropertyGetter, data: D): R = visitFunction(declaration, data)
|
||||
fun visitPropertySetter(declaration: IrPropertySetter, data: D): R = visitFunction(declaration, data)
|
||||
fun visitProperty(declaration: IrProperty, data: D): R = visitDeclaration(declaration, data)
|
||||
fun visitSimpleProperty(declaration: IrSimpleProperty, data: D): R = visitProperty(declaration, data)
|
||||
fun visitDelegatedProperty(declaration: IrDelegatedProperty, data: D): R = visitProperty(declaration, data)
|
||||
fun visitLocalVariable(declaration: IrLocalVariable, data: D) = visitDeclaration(declaration, data)
|
||||
fun visitLocalVariable(declaration: IrVariable, data: D) = visitDeclaration(declaration, data)
|
||||
|
||||
fun visitBody(body: IrBody, data: D): R = visitElement(body, data)
|
||||
fun visitExpressionBody(body: IrExpressionBody, data: D): R = visitBody(body, data)
|
||||
@@ -46,11 +45,6 @@ interface IrElementVisitor<out R, in D> {
|
||||
fun visitStringTemplate(expression: IrStringConcatenationExpression, data: D) = visitExpression(expression, data)
|
||||
fun visitThisExpression(expression: IrThisExpression, data: D) = visitExpression(expression, data)
|
||||
|
||||
fun <T : IrMemberDeclaration> visitLocalDeclarationExpression(expression: IrLocalDeclarationExpression<T>, data: D) =
|
||||
visitExpression(expression, data)
|
||||
fun visitLocalVariableDeclarationExpression(expression: IrLocalVariableDeclarationExpression, data: D) =
|
||||
visitLocalDeclarationExpression(expression, data)
|
||||
|
||||
fun visitDeclarationReference(expression: IrDeclarationReference, data: D) = visitExpression(expression, data)
|
||||
fun visitGetObjectValue(expression: IrGetObjectValueExpression, data: D) = visitDeclarationReference(expression, data)
|
||||
fun visitGetEnumValue(expression: IrGetEnumValueExpression, data: D) = visitDeclarationReference(expression, data)
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
IrFile /callWithReorderedArguments.kt
|
||||
IrFunction public fun foo(/*0*/ a: kotlin.Int, /*1*/ b: kotlin.Int): kotlin.Unit
|
||||
IrExpressionBody
|
||||
BLOCK type=kotlin.Unit
|
||||
BLOCK type=kotlin.Unit hasResult=false isDesugared=false
|
||||
IrFunction public fun noReorder1(): kotlin.Int
|
||||
IrExpressionBody
|
||||
LITERAL Int type=kotlin.Int value='1'
|
||||
@@ -16,17 +16,15 @@ IrFile /callWithReorderedArguments.kt
|
||||
LITERAL Int type=kotlin.Int value='2'
|
||||
IrFunction public fun test(): kotlin.Unit
|
||||
IrExpressionBody
|
||||
BLOCK type=kotlin.Unit
|
||||
BLOCK type=kotlin.Unit hasResult=false isDesugared=false
|
||||
CALL .foo type=kotlin.Unit operator=
|
||||
a: CALL .noReorder1 type=kotlin.Int operator=
|
||||
b: CALL .noReorder2 type=kotlin.Int operator=
|
||||
BLOCK type=kotlin.Unit
|
||||
LOCAL tmp0
|
||||
IrLocalVariable val tmp0: kotlin.Int
|
||||
CALL .reordered1 type=kotlin.Int operator=
|
||||
LOCAL tmp1
|
||||
IrLocalVariable val tmp1: kotlin.Int
|
||||
CALL .reordered2 type=kotlin.Int operator=
|
||||
BLOCK type=kotlin.Unit hasResult=false isDesugared=true
|
||||
VAR val tmp0: kotlin.Int
|
||||
CALL .reordered1 type=kotlin.Int operator=
|
||||
VAR val tmp1: kotlin.Int
|
||||
CALL .reordered2 type=kotlin.Int operator=
|
||||
CALL .foo type=kotlin.Unit operator=
|
||||
a: GET_VAR tmp1 type=kotlin.Int
|
||||
b: GET_VAR tmp0 type=kotlin.Int
|
||||
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
object A
|
||||
|
||||
object B {
|
||||
operator fun A.component1() = 1
|
||||
operator fun A.component2() = 2
|
||||
}
|
||||
|
||||
fun B.test() { // <<< destructuring1.txt
|
||||
val (x, y) = A
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
IrFunction public fun B.test(): kotlin.Unit
|
||||
IrExpressionBody
|
||||
BLOCK type=kotlin.Unit hasResult=false isDesugared=false
|
||||
DUMMY KtDestructuringDeclaration type=kotlin.Unit
|
||||
+3
-4
@@ -17,10 +17,9 @@ IrFile /references.kt
|
||||
GET_VAR x type=kotlin.String
|
||||
IrFunction public fun test3(): kotlin.String
|
||||
IrExpressionBody
|
||||
BLOCK type=kotlin.Nothing
|
||||
LOCAL x
|
||||
IrLocalVariable val x: kotlin.String = "OK"
|
||||
LITERAL String type=kotlin.String value='OK'
|
||||
BLOCK type=kotlin.Nothing hasResult=false isDesugared=false
|
||||
VAR val x: kotlin.String = "OK"
|
||||
LITERAL String type=kotlin.String value='OK'
|
||||
RETURN type=kotlin.Nothing
|
||||
GET_VAR x type=kotlin.String
|
||||
IrFunction public fun test4(): kotlin.String
|
||||
|
||||
Vendored
+2
-2
@@ -1,6 +1,6 @@
|
||||
// <<< smoke.txt
|
||||
fun testFun(): String { return "OK" }
|
||||
val testSimpleVal = 1 // <<< smoke.testSimpleVal.txt
|
||||
val testSimpleVal = 1
|
||||
val testValWithGetter: Int get() = 42
|
||||
var testSimpleVar = 2
|
||||
var testVarWithAccessors: Int
|
||||
@@ -13,4 +13,4 @@ var testVarWithAccessors: Int
|
||||
// 2 IrPropertyGetter
|
||||
// 1 IrPropertySetter
|
||||
// 1 IrProperty public var testSimpleVar
|
||||
// 1 IrProperty public var testVarWithAccessors
|
||||
// 1 IrProperty public var testVarWithAccessors
|
||||
@@ -1,3 +0,0 @@
|
||||
IrProperty public val testSimpleVal: kotlin.Int = 1 getter=null setter=null
|
||||
IrExpressionBody
|
||||
LITERAL Int type=kotlin.Int value='1'
|
||||
+2
-2
@@ -1,7 +1,7 @@
|
||||
IrFile /smoke.kt
|
||||
IrFunction public fun testFun(): kotlin.String
|
||||
IrExpressionBody
|
||||
BLOCK type=kotlin.Nothing
|
||||
BLOCK type=kotlin.Nothing hasResult=false isDesugared=false
|
||||
RETURN type=kotlin.Nothing
|
||||
LITERAL String type=kotlin.String value='OK'
|
||||
IrProperty public val testSimpleVal: kotlin.Int = 1 getter=null setter=null
|
||||
@@ -20,4 +20,4 @@ IrFile /smoke.kt
|
||||
LITERAL Int type=kotlin.Int value='42'
|
||||
IrPropertySetter public fun <set-testVarWithAccessors>(/*0*/ v: kotlin.Int): kotlin.Unit property=testVarWithAccessors
|
||||
IrExpressionBody
|
||||
BLOCK type=kotlin.Unit
|
||||
BLOCK type=kotlin.Unit hasResult=false isDesugared=false
|
||||
|
||||
@@ -53,6 +53,12 @@ public class IrTextTestCaseGenerated extends AbstractIrTextTestCase {
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("destructuring1.kt")
|
||||
public void testDestructuring1() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/ir/irText/destructuring1.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("dotQualified.kt")
|
||||
public void testDotQualified() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/ir/irText/dotQualified.kt");
|
||||
|
||||
Reference in New Issue
Block a user