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