Constructors represented "as in Java".
TODO: extract nested initializers somehow.
This commit is contained in:
committed by
Dmitry Petrov
parent
57c1b3e0e2
commit
8528c23194
+27
-9
@@ -16,12 +16,15 @@
|
||||
|
||||
package org.jetbrains.kotlin.psi2ir.generators
|
||||
|
||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor
|
||||
import org.jetbrains.kotlin.ir.expressions.*
|
||||
import org.jetbrains.kotlin.psi.KtElement
|
||||
import org.jetbrains.kotlin.psi.psiUtil.endOffset
|
||||
import org.jetbrains.kotlin.psi.psiUtil.startOffset
|
||||
import org.jetbrains.kotlin.psi2ir.intermediate.*
|
||||
import org.jetbrains.kotlin.resolve.BindingContext
|
||||
import org.jetbrains.kotlin.resolve.calls.callResolverUtil.getSuperCallExpression
|
||||
import org.jetbrains.kotlin.resolve.calls.callUtil.isSafeCall
|
||||
import org.jetbrains.kotlin.resolve.calls.model.*
|
||||
import org.jetbrains.kotlin.resolve.scopes.receivers.*
|
||||
@@ -39,10 +42,9 @@ fun StatementGenerator.generateReceiver(ktDefaultElement: KtElement, receiver: R
|
||||
is ImplicitClassReceiver ->
|
||||
IrThisReferenceImpl(ktDefaultElement.startOffset, ktDefaultElement.startOffset, receiver.type, receiver.classDescriptor)
|
||||
is ThisClassReceiver ->
|
||||
(receiver as? ExpressionReceiver)?.expression?.let { receiverExpression ->
|
||||
IrThisReferenceImpl(receiverExpression.startOffset, receiverExpression.endOffset, receiver.type,
|
||||
receiver.classDescriptor)
|
||||
} ?: TODO("Non-implicit ThisClassReceiver should be an expression receiver")
|
||||
generateThisOrSuperReceiver(receiver, receiver.classDescriptor)
|
||||
is SuperCallReceiverValue ->
|
||||
generateThisOrSuperReceiver(receiver, receiver.thisType.constructor.declarationDescriptor as ClassDescriptor)
|
||||
is ExpressionReceiver ->
|
||||
generateExpression(receiver.expression)
|
||||
is ClassValueReceiver ->
|
||||
@@ -61,6 +63,13 @@ fun StatementGenerator.generateReceiver(ktDefaultElement: KtElement, receiver: R
|
||||
OnceExpressionValue(receiverExpression)
|
||||
}
|
||||
|
||||
private fun generateThisOrSuperReceiver(receiver: ReceiverValue, classDescriptor: ClassDescriptor): IrExpression {
|
||||
val expressionReceiver = receiver as? ExpressionReceiver ?:
|
||||
throw AssertionError("'this' or 'super' receiver should be an expression receiver")
|
||||
val ktReceiver = expressionReceiver.expression
|
||||
return IrThisReferenceImpl(ktReceiver.startOffset, ktReceiver.endOffset, receiver.type, classDescriptor)
|
||||
}
|
||||
|
||||
fun StatementGenerator.generateCallReceiver(
|
||||
ktDefaultElement: KtElement,
|
||||
dispatchReceiver: ReceiverValue?,
|
||||
@@ -129,18 +138,25 @@ fun StatementGenerator.generateValueArgument(valueArgument: ResolvedValueArgumen
|
||||
TODO("Unexpected valueArgument: ${valueArgument.javaClass.simpleName}")
|
||||
}
|
||||
|
||||
fun StatementGenerator.pregenerateCall(resolvedCall: ResolvedCall<*>): CallBuilder {
|
||||
val call = pregenerateCallReceivers(resolvedCall)
|
||||
fun Generator.getSuperQualifier(resolvedCall: ResolvedCall<*>): ClassDescriptor? {
|
||||
val superCallExpression = getSuperCallExpression(resolvedCall.call) ?: return null
|
||||
return getOrFail(BindingContext.REFERENCE_TARGET, superCallExpression.instanceReference) as ClassDescriptor
|
||||
}
|
||||
|
||||
fun StatementGenerator.pregenerateCall(resolvedCall: ResolvedCall<*>): CallBuilder {
|
||||
val call = pregenerateCallWithReceivers(resolvedCall)
|
||||
pregenerateValueArguments(call, resolvedCall)
|
||||
return call
|
||||
}
|
||||
|
||||
private fun StatementGenerator.pregenerateValueArguments(call: CallBuilder, resolvedCall: ResolvedCall<*>) {
|
||||
resolvedCall.valueArgumentsByIndex!!.forEachIndexed { index, valueArgument ->
|
||||
val valueParameter = call.descriptor.valueParameters[index]
|
||||
call.irValueArgumentsByIndex[index] = generateValueArgument(valueArgument, valueParameter)
|
||||
}
|
||||
|
||||
return call
|
||||
}
|
||||
|
||||
fun StatementGenerator.pregenerateCallReceivers(resolvedCall: ResolvedCall<*>): CallBuilder {
|
||||
fun StatementGenerator.pregenerateCallWithReceivers(resolvedCall: ResolvedCall<*>): CallBuilder {
|
||||
val call = CallBuilder(resolvedCall)
|
||||
|
||||
call.callReceiver = generateCallReceiver(resolvedCall.call.callElement,
|
||||
@@ -148,5 +164,7 @@ fun StatementGenerator.pregenerateCallReceivers(resolvedCall: ResolvedCall<*>):
|
||||
resolvedCall.extensionReceiver,
|
||||
resolvedCall.call.isSafeCall())
|
||||
|
||||
call.superQualifier = getSuperQualifier(resolvedCall)
|
||||
|
||||
return call
|
||||
}
|
||||
+179
@@ -0,0 +1,179 @@
|
||||
/*
|
||||
* 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.psi2ir.generators
|
||||
|
||||
import org.jetbrains.kotlin.descriptors.ConstructorDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.PropertyDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.impl.LocalVariableDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.impl.SyntheticFieldDescriptor
|
||||
import org.jetbrains.kotlin.ir.expressions.IrBlockImpl
|
||||
import org.jetbrains.kotlin.ir.expressions.IrExpression
|
||||
import org.jetbrains.kotlin.ir.expressions.IrOperator
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
import org.jetbrains.kotlin.psi.psiUtil.endOffset
|
||||
import org.jetbrains.kotlin.psi.psiUtil.startOffset
|
||||
import org.jetbrains.kotlin.psi2ir.defaultLoad
|
||||
import org.jetbrains.kotlin.psi2ir.intermediate.*
|
||||
import org.jetbrains.kotlin.resolve.BindingContext
|
||||
import org.jetbrains.kotlin.resolve.calls.callUtil.isSafeCall
|
||||
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
|
||||
import org.jetbrains.kotlin.resolve.scopes.receivers.ThisClassReceiver
|
||||
|
||||
class AssignmentGenerator(statementGenerator: StatementGenerator) : StatementGeneratorExtension(statementGenerator) {
|
||||
fun generateAssignment(expression: KtBinaryExpression): IrExpression {
|
||||
val ktLeft = expression.left!!
|
||||
val irRhs = statementGenerator.generateExpression(expression.right!!)
|
||||
val irAssignmentReceiver = generateAssignmentReceiver(ktLeft, IrOperator.EQ)
|
||||
return irAssignmentReceiver.assign(irRhs)
|
||||
}
|
||||
|
||||
fun generateAugmentedAssignment(expression: KtBinaryExpression, irOperator: IrOperator): IrExpression {
|
||||
val opResolvedCall = getResolvedCall(expression)!!
|
||||
val isSimpleAssignment = get(BindingContext.VARIABLE_REASSIGNMENT, expression) ?: false
|
||||
val ktLeft = expression.left!!
|
||||
val ktRight = expression.right!!
|
||||
val irAssignmentReceiver = generateAssignmentReceiver(ktLeft, irOperator)
|
||||
|
||||
return irAssignmentReceiver.assign { irLValue ->
|
||||
val opCall = statementGenerator.pregenerateCall(opResolvedCall)
|
||||
opCall.setExplicitReceiverValue(irLValue)
|
||||
opCall.irValueArgumentsByIndex[0] = statementGenerator.generateExpression(ktRight)
|
||||
val irOpCall = CallGenerator(this).generateCall(expression, opCall, irOperator)
|
||||
|
||||
if (isSimpleAssignment) {
|
||||
// Set( Op( Get(), RHS ) )
|
||||
irLValue.store(irOpCall)
|
||||
}
|
||||
else {
|
||||
// Op( Get(), RHS )
|
||||
irOpCall
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun generatePrefixIncrementDecrement(expression: KtPrefixExpression, irOperator: IrOperator): IrExpression {
|
||||
val opResolvedCall = getResolvedCall(expression)!!
|
||||
val ktBaseExpression = expression.baseExpression!!
|
||||
val irAssignmentReceiver = generateAssignmentReceiver(ktBaseExpression, irOperator)
|
||||
|
||||
return irAssignmentReceiver.assign { irLValue ->
|
||||
val irBlock = IrBlockImpl(expression.startOffset, expression.endOffset, irLValue.type, irOperator)
|
||||
|
||||
// VAR tmp = [lhs].inc()
|
||||
val opCall = statementGenerator.pregenerateCall(opResolvedCall)
|
||||
opCall.setExplicitReceiverValue(irLValue)
|
||||
val irOpCall = CallGenerator(this).generateCall(expression, opCall, irOperator)
|
||||
val irTmp = statementGenerator.scope.createTemporaryVariable(irOpCall)
|
||||
irBlock.addStatement(irTmp)
|
||||
|
||||
// [lhs] = tmp
|
||||
irBlock.addStatement(irLValue.store(irTmp.defaultLoad()))
|
||||
|
||||
// ^ tmp
|
||||
irBlock.addStatement(irTmp.defaultLoad())
|
||||
|
||||
irBlock
|
||||
}
|
||||
}
|
||||
|
||||
fun generatePostfixIncrementDecrement(expression: KtPostfixExpression, irOperator: IrOperator): IrExpression {
|
||||
val opResolvedCall = getResolvedCall(expression)!!
|
||||
val ktBaseExpression = expression.baseExpression!!
|
||||
val irAssignmentReceiver = generateAssignmentReceiver(ktBaseExpression, irOperator)
|
||||
|
||||
return irAssignmentReceiver.assign { irLValue ->
|
||||
val irBlock = IrBlockImpl(expression.startOffset, expression.endOffset, irLValue.type, irOperator)
|
||||
|
||||
// VAR tmp = [lhs]
|
||||
val irTmp = scope.createTemporaryVariable(irLValue.load())
|
||||
irBlock.addStatement(irTmp)
|
||||
|
||||
// [lhs] = tmp.inc()
|
||||
val opCall = statementGenerator.pregenerateCall(opResolvedCall)
|
||||
opCall.setExplicitReceiverValue(VariableLValue(irTmp))
|
||||
val irOpCall = CallGenerator(this).generateCall(expression, opCall, irOperator)
|
||||
irBlock.addStatement(irLValue.store(irOpCall))
|
||||
|
||||
// ^ tmp
|
||||
irBlock.addStatement(irTmp.defaultLoad())
|
||||
|
||||
irBlock
|
||||
}
|
||||
}
|
||||
|
||||
fun generateAssignmentReceiver(ktLeft: KtExpression, operator: IrOperator): AssignmentReceiver {
|
||||
if (ktLeft is KtArrayAccessExpression) {
|
||||
return generateArrayAccessAssignmentReceiver(ktLeft, operator)
|
||||
}
|
||||
|
||||
val resolvedCall = getResolvedCall(ktLeft) ?: TODO("no resolved call for LHS")
|
||||
val descriptor = resolvedCall.candidateDescriptor
|
||||
|
||||
return when (descriptor) {
|
||||
is SyntheticFieldDescriptor ->
|
||||
BackingFieldLValue(ktLeft.startOffset, ktLeft.endOffset, descriptor.propertyDescriptor, operator)
|
||||
is LocalVariableDescriptor ->
|
||||
if (descriptor.isDelegated)
|
||||
TODO("Delegated local variable")
|
||||
else
|
||||
VariableLValue(ktLeft.startOffset, ktLeft.endOffset, descriptor, operator)
|
||||
is PropertyDescriptor ->
|
||||
generateAssignmentReceiverForProperty(descriptor, operator, ktLeft, resolvedCall)
|
||||
else ->
|
||||
TODO("Other cases of LHS")
|
||||
}
|
||||
}
|
||||
|
||||
private fun generateAssignmentReceiverForProperty(
|
||||
descriptor: PropertyDescriptor,
|
||||
irOperator: IrOperator,
|
||||
ktLeft: KtExpression,
|
||||
resolvedCall: ResolvedCall<*>
|
||||
): AssignmentReceiver {
|
||||
if (isValInitializationInConstructor(descriptor, resolvedCall)) {
|
||||
return BackingFieldLValue(ktLeft.startOffset, ktLeft.endOffset, descriptor, null)
|
||||
}
|
||||
|
||||
val propertyReceiver = statementGenerator.generateCallReceiver(
|
||||
ktLeft, resolvedCall.dispatchReceiver, resolvedCall.extensionReceiver, resolvedCall.call.isSafeCall())
|
||||
|
||||
val superQualifier = getSuperQualifier(resolvedCall)
|
||||
|
||||
return SimplePropertyLValue(scope, ktLeft.startOffset, ktLeft.endOffset, irOperator, descriptor, propertyReceiver, superQualifier)
|
||||
}
|
||||
|
||||
private fun isValInitializationInConstructor(descriptor: PropertyDescriptor, resolvedCall: ResolvedCall<*>): Boolean =
|
||||
!descriptor.isVar &&
|
||||
statementGenerator.scopeOwner is ConstructorDescriptor &&
|
||||
resolvedCall.dispatchReceiver is ThisClassReceiver
|
||||
|
||||
private fun generateArrayAccessAssignmentReceiver(ktLeft: KtArrayAccessExpression, irOperator: IrOperator): ArrayAccessAssignmentReceiver {
|
||||
val irArray = statementGenerator.generateExpression(ktLeft.arrayExpression!!)
|
||||
val irIndexExpressions = ktLeft.indexExpressions.map { statementGenerator.generateExpression(it) }
|
||||
|
||||
val indexedGetResolvedCall = get(BindingContext.INDEXED_LVALUE_GET, ktLeft)
|
||||
val indexedGetCall = indexedGetResolvedCall?.let { statementGenerator.pregenerateCallWithReceivers(it) }
|
||||
|
||||
val indexedSetResolvedCall = get(BindingContext.INDEXED_LVALUE_SET, ktLeft)
|
||||
val indexedSetCall = indexedSetResolvedCall?.let { statementGenerator.pregenerateCallWithReceivers(it) }
|
||||
|
||||
return ArrayAccessAssignmentReceiver(irArray, irIndexExpressions, indexedGetCall, indexedSetCall,
|
||||
CallGenerator(statementGenerator),
|
||||
ktLeft.startOffset, ktLeft.endOffset, irOperator)
|
||||
}
|
||||
|
||||
}
|
||||
@@ -18,11 +18,13 @@ package org.jetbrains.kotlin.psi2ir.generators
|
||||
|
||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
||||
import org.jetbrains.kotlin.descriptors.CallableDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.PropertyDescriptor
|
||||
import org.jetbrains.kotlin.ir.IrStatement
|
||||
import org.jetbrains.kotlin.ir.expressions.*
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
import org.jetbrains.kotlin.psi.psiUtil.endOffset
|
||||
import org.jetbrains.kotlin.psi.psiUtil.startOffset
|
||||
import org.jetbrains.kotlin.resolve.BindingContext
|
||||
import java.util.*
|
||||
|
||||
class BodyGenerator(val scopeOwner: CallableDescriptor, override val context: GeneratorContext): GeneratorWithScope {
|
||||
@@ -82,26 +84,24 @@ class BodyGenerator(val scopeOwner: CallableDescriptor, override val context: Ge
|
||||
|
||||
|
||||
fun generateSecondaryConstructorBody(ktConstructor: KtSecondaryConstructor): IrBody {
|
||||
val statementGenerator = createStatementGenerator()
|
||||
|
||||
val irBlockBody = IrBlockBodyImpl(ktConstructor.startOffset, ktConstructor.endOffset)
|
||||
|
||||
val ktDelegatingConstructorCall = ktConstructor.getDelegationCall()
|
||||
val delegatingConstructorCall = statementGenerator.pregenerateCall(getResolvedCall(ktDelegatingConstructorCall)!!)
|
||||
val irDelegatingConstructorCall = CallGenerator(statementGenerator).generateCall(
|
||||
ktDelegatingConstructorCall, delegatingConstructorCall, IrOperator.DELEGATING_CONSTRUCTOR_CALL)
|
||||
irBlockBody.addStatement(irDelegatingConstructorCall)
|
||||
generateDelegatingConstructorCall(irBlockBody, ktConstructor)
|
||||
|
||||
val ktBody = ktConstructor.bodyExpression
|
||||
if (ktBody != null) {
|
||||
statementGenerator.generateBlockBodyStatements(irBlockBody, ktBody)
|
||||
ktConstructor.bodyExpression?.let { ktBody ->
|
||||
createStatementGenerator().generateBlockBodyStatements(irBlockBody, ktBody)
|
||||
}
|
||||
|
||||
return irBlockBody
|
||||
}
|
||||
|
||||
fun generateAnonymousInitializer(ktInitializer: KtAnonymousInitializer): IrStatement {
|
||||
return createStatementGenerator().generateStatement(ktInitializer.body!!)
|
||||
private fun generateDelegatingConstructorCall(irBlockBody: IrBlockBodyImpl, ktConstructor: KtSecondaryConstructor) {
|
||||
val statementGenerator = createStatementGenerator()
|
||||
val ktDelegatingConstructorCall = ktConstructor.getDelegationCall()
|
||||
val delegatingConstructorCall = statementGenerator.pregenerateCall(getResolvedCall(ktDelegatingConstructorCall)!!)
|
||||
val irDelegatingConstructorCall = CallGenerator(statementGenerator).generateCall(
|
||||
ktDelegatingConstructorCall, delegatingConstructorCall, IrOperator.DELEGATING_CONSTRUCTOR_CALL)
|
||||
irBlockBody.addStatement(irDelegatingConstructorCall)
|
||||
}
|
||||
|
||||
private fun createStatementGenerator() =
|
||||
@@ -114,6 +114,90 @@ class BodyGenerator(val scopeOwner: CallableDescriptor, override val context: Ge
|
||||
fun getLoop(expression: KtExpression): IrLoop? =
|
||||
loopTable[expression]
|
||||
|
||||
fun generatePrimaryConstructorBody(ktClassOrObject: KtClassOrObject): IrBody {
|
||||
val irBlockBody = IrBlockBodyImpl(ktClassOrObject.startOffset, ktClassOrObject.endOffset)
|
||||
|
||||
generateSuperConstructorCall(irBlockBody, ktClassOrObject)
|
||||
generateInitializersForPropertiesDefinedInPrimaryConstructor(irBlockBody, ktClassOrObject)
|
||||
generateInitializersForClassBody(irBlockBody, ktClassOrObject)
|
||||
|
||||
return irBlockBody
|
||||
}
|
||||
|
||||
fun generateSecondaryConstructorBodyWithClassInitializers(ktConstructor: KtSecondaryConstructor, ktClassOrObject: KtClassOrObject): IrBody {
|
||||
val irBlockBody = IrBlockBodyImpl(ktClassOrObject.startOffset, ktClassOrObject.endOffset)
|
||||
|
||||
generateDelegatingConstructorCall(irBlockBody, ktConstructor)
|
||||
generateInitializersForClassBody(irBlockBody, ktClassOrObject)
|
||||
|
||||
ktConstructor.bodyExpression?.let { ktBody ->
|
||||
createStatementGenerator().generateBlockBodyStatements(irBlockBody, ktBody)
|
||||
}
|
||||
|
||||
return irBlockBody
|
||||
}
|
||||
|
||||
private fun generateSuperConstructorCall(irBlockBody: IrBlockBodyImpl, ktClassOrObject: KtClassOrObject) {
|
||||
val ktSuperTypeList = ktClassOrObject.getSuperTypeList() ?: return
|
||||
for (ktSuperTypeListEntry in ktSuperTypeList.entries) {
|
||||
if (ktSuperTypeListEntry is KtSuperTypeCallEntry) {
|
||||
val statementGenerator = createStatementGenerator()
|
||||
val superConstructorCall = statementGenerator.pregenerateCall(getResolvedCall(ktSuperTypeListEntry)!!)
|
||||
val irSuperConstructorCall = CallGenerator(statementGenerator).generateCall(
|
||||
ktSuperTypeListEntry, superConstructorCall, IrOperator.SUPER_CONSTRUCTOR_CALL)
|
||||
irBlockBody.addStatement(irSuperConstructorCall)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun generateInitializersForClassBody(irBlockBody: IrBlockBodyImpl, ktClassOrObject: KtClassOrObject) {
|
||||
ktClassOrObject.getBody()?.let { ktClassBody ->
|
||||
for (ktDeclaration in ktClassBody.declarations) {
|
||||
when (ktDeclaration) {
|
||||
is KtProperty -> generateInitializerForPropertyDefinedInClassBody(irBlockBody, ktDeclaration)
|
||||
is KtClassInitializer -> generateAnonymousInitializer(irBlockBody, ktDeclaration)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun generateAnonymousInitializer(irBlockBody: IrBlockBodyImpl, ktClassInitializer: KtClassInitializer) {
|
||||
if (ktClassInitializer.body == null) return
|
||||
val irInitializer = generateAnonymousInitializer(ktClassInitializer)
|
||||
irBlockBody.addStatement(irInitializer)
|
||||
}
|
||||
|
||||
fun generateAnonymousInitializer(ktInitializer: KtAnonymousInitializer): IrStatement {
|
||||
return createStatementGenerator().generateStatement(ktInitializer.body!!)
|
||||
}
|
||||
|
||||
private fun generateInitializerForPropertyDefinedInClassBody(irBlockBody: IrBlockBodyImpl, ktProperty: KtProperty) {
|
||||
val propertyDescriptor = getOrFail(BindingContext.VARIABLE, ktProperty) as PropertyDescriptor
|
||||
ktProperty.initializer?.let { ktInitializer ->
|
||||
irBlockBody.addStatement(createPropertyInitializationExpression(
|
||||
ktProperty, propertyDescriptor, createStatementGenerator().generateExpression(ktInitializer)))
|
||||
}
|
||||
}
|
||||
|
||||
private fun generateInitializersForPropertiesDefinedInPrimaryConstructor(irBlockBody: IrBlockBodyImpl, ktClassOrObject: KtClassOrObject) {
|
||||
ktClassOrObject.getPrimaryConstructor()?.let { ktPrimaryConstructor ->
|
||||
for (ktParameter in ktPrimaryConstructor.valueParameters) {
|
||||
if (ktParameter.hasValOrVar()) {
|
||||
val propertyDescriptor = getOrFail(BindingContext.PRIMARY_CONSTRUCTOR_PARAMETER, ktParameter)
|
||||
val valueParameterDescriptor = getOrFail(BindingContext.VALUE_PARAMETER, ktParameter)
|
||||
|
||||
irBlockBody.addStatement(
|
||||
createPropertyInitializationExpression(
|
||||
ktParameter, propertyDescriptor,
|
||||
IrGetVariableImpl(ktParameter.startOffset, ktParameter.endOffset,
|
||||
valueParameterDescriptor, IrOperator.INITIALIZE_PROPERTY_FROM_PARAMETER)
|
||||
))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun createPropertyInitializationExpression(ktElement: KtElement, propertyDescriptor: PropertyDescriptor, value: IrExpression) =
|
||||
IrSetBackingFieldImpl(ktElement.startOffset, ktElement.endOffset, propertyDescriptor, value)
|
||||
}
|
||||
|
||||
|
||||
+1
-4
@@ -26,10 +26,7 @@ import org.jetbrains.kotlin.psi2ir.deparenthesize
|
||||
import org.jetbrains.kotlin.resolve.BindingContext
|
||||
import org.jetbrains.kotlin.utils.SmartList
|
||||
|
||||
class BranchingExpressionGenerator(val statementGenerator: StatementGenerator) : GeneratorWithScope {
|
||||
override val scope: Scope get() = statementGenerator.scope
|
||||
override val context: GeneratorContext get() = statementGenerator.context
|
||||
|
||||
class BranchingExpressionGenerator(statementGenerator: StatementGenerator) : StatementGeneratorExtension(statementGenerator) {
|
||||
fun generateIfExpression(expression: KtIfExpression): IrExpression {
|
||||
val resultType = getInferredTypeWithImplicitCastsOrFail(expression)
|
||||
|
||||
|
||||
@@ -72,7 +72,8 @@ class CallGenerator(
|
||||
IrGetterCallImpl(startOffset, endOffset, descriptor.getter!!,
|
||||
dispatchReceiverValue?.load(),
|
||||
extensionReceiverValue?.load(),
|
||||
IrOperator.GET_PROPERTY)
|
||||
IrOperator.GET_PROPERTY,
|
||||
call.superQualifier)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+22
-54
@@ -16,11 +16,15 @@
|
||||
|
||||
package org.jetbrains.kotlin.psi2ir.generators
|
||||
|
||||
import org.jetbrains.kotlin.descriptors.ConstructorDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.PropertyDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
||||
import org.jetbrains.kotlin.ir.declarations.*
|
||||
import org.jetbrains.kotlin.ir.expressions.*
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
import org.jetbrains.kotlin.ir.expressions.IrExpressionBodyImpl
|
||||
import org.jetbrains.kotlin.ir.expressions.IrGetVariableImpl
|
||||
import org.jetbrains.kotlin.ir.expressions.IrOperator
|
||||
import org.jetbrains.kotlin.psi.KtAnonymousInitializer
|
||||
import org.jetbrains.kotlin.psi.KtClassOrObject
|
||||
import org.jetbrains.kotlin.psi.KtParameter
|
||||
import org.jetbrains.kotlin.psi.KtSecondaryConstructor
|
||||
import org.jetbrains.kotlin.psi.psiUtil.endOffset
|
||||
import org.jetbrains.kotlin.psi.psiUtil.startOffset
|
||||
import org.jetbrains.kotlin.resolve.BindingContext
|
||||
@@ -40,13 +44,12 @@ class ClassGenerator(val declarationGenerator: DeclarationGenerator) : Generator
|
||||
}
|
||||
|
||||
private fun generatePrimaryConstructor(irClass: IrClassImpl, ktClassOrObject: KtClassOrObject) {
|
||||
val ktPrimaryConstructor = ktClassOrObject.getPrimaryConstructor() ?: return
|
||||
val primaryConstructorDescriptor = irClass.descriptor.unsubstitutedPrimaryConstructor ?: return
|
||||
|
||||
val primaryConstructorDescriptor = getOrFail(BindingContext.CONSTRUCTOR, ktPrimaryConstructor)
|
||||
val irPrimaryConstructor = IrFunctionImpl(ktClassOrObject.startOffset, ktClassOrObject.endOffset, IrDeclarationOrigin.DEFINED,
|
||||
primaryConstructorDescriptor)
|
||||
|
||||
irPrimaryConstructor.body = generatePrimaryConstructorBodyFromClass(ktClassOrObject, primaryConstructorDescriptor)
|
||||
irPrimaryConstructor.body = BodyGenerator(primaryConstructorDescriptor, context).generatePrimaryConstructorBody(ktClassOrObject)
|
||||
|
||||
irClass.addMember(irPrimaryConstructor)
|
||||
}
|
||||
@@ -66,7 +69,12 @@ class ClassGenerator(val declarationGenerator: DeclarationGenerator) : Generator
|
||||
for (ktDeclaration in ktClassBody.declarations) {
|
||||
if (ktDeclaration is KtAnonymousInitializer) continue
|
||||
|
||||
val irMember = declarationGenerator.generateMemberDeclaration(ktDeclaration)
|
||||
val irMember =
|
||||
if (ktDeclaration is KtSecondaryConstructor && isConstructorDelegatingToSuper(ktDeclaration, irClass.descriptor))
|
||||
declarationGenerator.generateSecondaryConstructorWithClassInitializers(ktDeclaration, ktClassOrObject)
|
||||
else
|
||||
declarationGenerator.generateMemberDeclaration(ktDeclaration)
|
||||
|
||||
irClass.addMember(irMember)
|
||||
if (irMember is IrProperty) {
|
||||
irMember.getter?.let { irClass.addMember(it) }
|
||||
@@ -76,6 +84,12 @@ class ClassGenerator(val declarationGenerator: DeclarationGenerator) : Generator
|
||||
}
|
||||
}
|
||||
|
||||
private fun isConstructorDelegatingToSuper(ktConstructor: KtSecondaryConstructor, classOwner: ClassDescriptor): Boolean {
|
||||
val delegatingResolvedCall = getResolvedCall(ktConstructor.getDelegationCall())!!
|
||||
val calleeOwner = delegatingResolvedCall.resultingDescriptor.containingDeclaration as ClassDescriptor
|
||||
return calleeOwner != classOwner
|
||||
}
|
||||
|
||||
private fun generatePropertyForPrimaryConstructorParameter(ktParameter: KtParameter): IrDeclaration {
|
||||
val valueParameterDescriptor = getOrFail(BindingContext.VALUE_PARAMETER, ktParameter)
|
||||
val propertyDescriptor = getOrFail(BindingContext.PRIMARY_CONSTRUCTOR_PARAMETER, ktParameter)
|
||||
@@ -86,52 +100,6 @@ class ClassGenerator(val declarationGenerator: DeclarationGenerator) : Generator
|
||||
return irProperty
|
||||
}
|
||||
|
||||
private fun generatePrimaryConstructorBodyFromClass(ktClassOrObject: KtClassOrObject, primaryConstructorDescriptor: ConstructorDescriptor): IrBody {
|
||||
val irBlockBody = IrBlockBodyImpl(ktClassOrObject.startOffset, ktClassOrObject.endOffset)
|
||||
|
||||
generateInitializersForPropertiesDefinedInPrimaryConstructor(irBlockBody, ktClassOrObject)
|
||||
generateInitializersForClassBody(irBlockBody, ktClassOrObject, primaryConstructorDescriptor)
|
||||
|
||||
return irBlockBody
|
||||
}
|
||||
|
||||
private fun generateInitializersForClassBody(irBlockBody: IrBlockBodyImpl, ktClassOrObject: KtClassOrObject, primaryConstructorDescriptor: ConstructorDescriptor) {
|
||||
ktClassOrObject.getBody()?.let { ktClassBody ->
|
||||
for (ktDeclaration in ktClassBody.declarations) {
|
||||
when (ktDeclaration) {
|
||||
is KtProperty -> generateInitializerForPropertyDefinedInClassBody(irBlockBody, ktDeclaration)
|
||||
is KtClassInitializer -> generateAnonymousInitializer(irBlockBody, ktDeclaration, primaryConstructorDescriptor)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun generateAnonymousInitializer(irBlockBody: IrBlockBodyImpl, ktClassInitializer: KtClassInitializer, primaryConstructorDescriptor: ConstructorDescriptor) {
|
||||
if (ktClassInitializer.body == null) return
|
||||
val irInitializer = BodyGenerator(primaryConstructorDescriptor, context).generateAnonymousInitializer(ktClassInitializer)
|
||||
irBlockBody.addStatement(irInitializer)
|
||||
}
|
||||
|
||||
private fun generateInitializerForPropertyDefinedInClassBody(irBlockBody: IrBlockBodyImpl, ktProperty: KtProperty) {
|
||||
val propertyDescriptor = getOrFail(BindingContext.VARIABLE, ktProperty) as PropertyDescriptor
|
||||
if (ktProperty.initializer != null) {
|
||||
irBlockBody.addStatement(createInitializeProperty(ktProperty, propertyDescriptor))
|
||||
}
|
||||
}
|
||||
|
||||
private fun generateInitializersForPropertiesDefinedInPrimaryConstructor(irBlockBody: IrBlockBodyImpl, ktClassOrObject: KtClassOrObject) {
|
||||
ktClassOrObject.getPrimaryConstructor()?.let { ktPrimaryConstructor ->
|
||||
for (ktParameter in ktPrimaryConstructor.valueParameters) {
|
||||
if (ktParameter.hasValOrVar()) {
|
||||
val propertyDescriptor = getOrFail(BindingContext.PRIMARY_CONSTRUCTOR_PARAMETER, ktParameter)
|
||||
irBlockBody.addStatement(createInitializeProperty(ktParameter, propertyDescriptor))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun createInitializeProperty(ktElement: KtElement, propertyDescriptor: PropertyDescriptor) =
|
||||
IrInitializePropertyImpl(ktElement.startOffset, ktElement.endOffset, context.builtIns.unitType, propertyDescriptor)
|
||||
|
||||
|
||||
}
|
||||
|
||||
+15
-3
@@ -60,7 +60,15 @@ class DeclarationGenerator(override val context: GeneratorContext) : Generator {
|
||||
|
||||
fun generateSecondaryConstructor(ktConstructor: KtSecondaryConstructor) : IrFunction {
|
||||
val constructorDescriptor = getOrFail(BindingContext.CONSTRUCTOR, ktConstructor)
|
||||
val body = BodyGenerator(constructorDescriptor, context).generateSecondaryConstructorBody(ktConstructor)
|
||||
val body = createBodyGenerator(constructorDescriptor).generateSecondaryConstructorBody(ktConstructor)
|
||||
return IrFunctionImpl(ktConstructor.startOffset, ktConstructor.endOffset, IrDeclarationOrigin.DEFINED,
|
||||
constructorDescriptor, body)
|
||||
}
|
||||
|
||||
|
||||
fun generateSecondaryConstructorWithClassInitializers(ktConstructor: KtSecondaryConstructor, ktClassOrObject: KtClassOrObject): IrDeclaration {
|
||||
val constructorDescriptor = getOrFail(BindingContext.CONSTRUCTOR, ktConstructor)
|
||||
val body = createBodyGenerator(constructorDescriptor).generateSecondaryConstructorBodyWithClassInitializers(ktConstructor, ktClassOrObject)
|
||||
return IrFunctionImpl(ktConstructor.startOffset, ktConstructor.endOffset, IrDeclarationOrigin.DEFINED,
|
||||
constructorDescriptor, body)
|
||||
}
|
||||
@@ -101,8 +109,12 @@ class DeclarationGenerator(override val context: GeneratorContext) : Generator {
|
||||
}
|
||||
|
||||
private fun generateFunctionBody(scopeOwner: CallableDescriptor, ktBody: KtExpression): IrBody =
|
||||
BodyGenerator(scopeOwner, context).generateFunctionBody(ktBody)
|
||||
createBodyGenerator(scopeOwner).generateFunctionBody(ktBody)
|
||||
|
||||
private fun generateInitializerBody(scopeOwner: CallableDescriptor, ktBody: KtExpression): IrBody =
|
||||
BodyGenerator(scopeOwner, context).generatePropertyInitializerBody(ktBody)
|
||||
createBodyGenerator(scopeOwner).generatePropertyInitializerBody(ktBody)
|
||||
|
||||
private fun createBodyGenerator(descriptor: CallableDescriptor) =
|
||||
BodyGenerator(descriptor, context)
|
||||
|
||||
}
|
||||
@@ -17,17 +17,14 @@
|
||||
package org.jetbrains.kotlin.psi2ir.generators
|
||||
|
||||
import org.jetbrains.kotlin.descriptors.CallableDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
||||
import org.jetbrains.kotlin.ir.expressions.IrDummyExpression
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
import org.jetbrains.kotlin.psi.KtElement
|
||||
import org.jetbrains.kotlin.psi.KtExpression
|
||||
import org.jetbrains.kotlin.psi.psiUtil.endOffset
|
||||
import org.jetbrains.kotlin.psi.psiUtil.startOffset
|
||||
import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall
|
||||
import org.jetbrains.kotlin.resolve.calls.callUtil.isSafeCall
|
||||
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.classValueType
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
import org.jetbrains.kotlin.types.typeUtil.makeNullable
|
||||
import org.jetbrains.kotlin.util.slicedMap.ReadOnlySlice
|
||||
import java.lang.AssertionError
|
||||
import java.lang.RuntimeException
|
||||
|
||||
+1
-4
@@ -29,10 +29,7 @@ import org.jetbrains.kotlin.psi.psiUtil.endOffset
|
||||
import org.jetbrains.kotlin.psi.psiUtil.startOffset
|
||||
import org.jetbrains.kotlin.resolve.BindingContext
|
||||
|
||||
class LocalFunctionGenerator(val statementGenerator: StatementGenerator) : GeneratorWithScope {
|
||||
override val scope: Scope get() = statementGenerator.scope
|
||||
override val context: GeneratorContext get() = statementGenerator.context
|
||||
|
||||
class LocalFunctionGenerator(statementGenerator: StatementGenerator) : StatementGeneratorExtension(statementGenerator) {
|
||||
fun generateLambda(ktLambda: KtLambdaExpression): IrStatement {
|
||||
val ktFun = ktLambda.functionLiteral
|
||||
val lambdaExpressionType = getInferredTypeWithImplicitCastsOrFail(ktLambda)
|
||||
|
||||
+1
-4
@@ -27,10 +27,7 @@ import org.jetbrains.kotlin.psi2ir.intermediate.VariableLValue
|
||||
import org.jetbrains.kotlin.psi2ir.intermediate.setExplicitReceiverValue
|
||||
import org.jetbrains.kotlin.resolve.BindingContext
|
||||
|
||||
class LoopExpressionGenerator(val statementGenerator: StatementGenerator) : GeneratorWithScope {
|
||||
override val scope: Scope get() = statementGenerator.scope
|
||||
override val context: GeneratorContext get() = statementGenerator.context
|
||||
|
||||
class LoopExpressionGenerator(statementGenerator: StatementGenerator) : StatementGeneratorExtension(statementGenerator){
|
||||
fun generateWhileLoop(ktWhile: KtWhileExpression): IrExpression =
|
||||
generateConditionalLoop(ktWhile,
|
||||
IrWhileLoopImpl(ktWhile.startOffset, ktWhile.endOffset,
|
||||
|
||||
+6
-155
@@ -16,31 +16,20 @@
|
||||
|
||||
package org.jetbrains.kotlin.psi2ir.generators
|
||||
|
||||
import org.jetbrains.kotlin.descriptors.ConstructorDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.PropertyDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.impl.LocalVariableDescriptor
|
||||
import org.jetbrains.kotlin.ir.IrStatement
|
||||
import org.jetbrains.kotlin.ir.expressions.*
|
||||
import org.jetbrains.kotlin.lexer.KtTokens
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
import org.jetbrains.kotlin.psi.psiUtil.endOffset
|
||||
import org.jetbrains.kotlin.psi.psiUtil.startOffset
|
||||
import org.jetbrains.kotlin.psi2ir.defaultLoad
|
||||
import org.jetbrains.kotlin.psi2ir.intermediate.*
|
||||
import org.jetbrains.kotlin.psi2ir.intermediate.createRematerializableOrTemporary
|
||||
import org.jetbrains.kotlin.resolve.BindingContext
|
||||
import org.jetbrains.kotlin.resolve.calls.callUtil.isSafeCall
|
||||
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
|
||||
import org.jetbrains.kotlin.resolve.scopes.receivers.ThisClassReceiver
|
||||
import org.jetbrains.kotlin.types.typeUtil.makeNotNullable
|
||||
import org.jetbrains.kotlin.types.typeUtil.makeNullable
|
||||
import java.lang.AssertionError
|
||||
|
||||
|
||||
class OperatorExpressionGenerator(
|
||||
val statementGenerator: StatementGenerator
|
||||
) : GeneratorWithScope {
|
||||
override val scope: Scope get() = statementGenerator.scope
|
||||
override val context: GeneratorContext get() = statementGenerator.context
|
||||
class OperatorExpressionGenerator(statementGenerator: StatementGenerator) : StatementGeneratorExtension(statementGenerator) {
|
||||
|
||||
fun generatePrefixExpression(expression: KtPrefixExpression): IrExpression {
|
||||
val ktOperator = expression.operationReference.getReferencedNameElementType()
|
||||
@@ -48,7 +37,7 @@ class OperatorExpressionGenerator(
|
||||
|
||||
return when (irOperator) {
|
||||
null -> throw AssertionError("Unexpected prefix operator: $ktOperator")
|
||||
in INCREMENT_DECREMENT_OPERATORS -> generatePrefixIncrementDecrementOperator(expression, irOperator)
|
||||
in INCREMENT_DECREMENT_OPERATORS -> AssignmentGenerator(statementGenerator).generatePrefixIncrementDecrement(expression, irOperator)
|
||||
in OPERATORS_DESUGARED_TO_CALLS -> generatePrefixOperatorAsCall(expression, irOperator)
|
||||
else -> createDummyExpression(expression, ktOperator.toString())
|
||||
}
|
||||
@@ -60,7 +49,7 @@ class OperatorExpressionGenerator(
|
||||
|
||||
return when (irOperator) {
|
||||
null -> throw AssertionError("Unexpected postfix operator: $ktOperator")
|
||||
in INCREMENT_DECREMENT_OPERATORS -> generatePostfixIncrementDecrementOperator(expression, irOperator)
|
||||
in INCREMENT_DECREMENT_OPERATORS -> AssignmentGenerator(statementGenerator).generatePostfixIncrementDecrement(expression, irOperator)
|
||||
IrOperator.EXCLEXCL -> generateExclExclOperator(expression, irOperator)
|
||||
else -> createDummyExpression(expression, ktOperator.toString())
|
||||
}
|
||||
@@ -103,9 +92,9 @@ class OperatorExpressionGenerator(
|
||||
|
||||
return when (irOperator) {
|
||||
null -> throw AssertionError("Unexpected infix operator: $ktOperator")
|
||||
IrOperator.EQ -> generateAssignment(expression)
|
||||
IrOperator.EQ -> AssignmentGenerator(statementGenerator).generateAssignment(expression)
|
||||
in AUGMENTED_ASSIGNMENTS -> AssignmentGenerator(statementGenerator).generateAugmentedAssignment(expression, irOperator)
|
||||
IrOperator.ELVIS -> generateElvis(expression)
|
||||
in AUGMENTED_ASSIGNMENTS -> generateAugmentedAssignment(expression, irOperator)
|
||||
in OPERATORS_DESUGARED_TO_CALLS -> generateBinaryOperatorAsCall(expression, irOperator)
|
||||
in COMPARISON_OPERATORS -> generateComparisonOperator(expression, irOperator)
|
||||
in EQUALITY_OPERATORS -> generateEqualityOperator(expression, irOperator)
|
||||
@@ -224,55 +213,7 @@ class OperatorExpressionGenerator(
|
||||
return CallGenerator(this).generateCall(expression, statementGenerator.pregenerateCall(operatorCall), irOperator)
|
||||
}
|
||||
|
||||
private fun generatePrefixIncrementDecrementOperator(expression: KtPrefixExpression, irOperator: IrOperator): IrExpression {
|
||||
val opResolvedCall = getResolvedCall(expression)!!
|
||||
val ktBaseExpression = expression.baseExpression!!
|
||||
val irAssignmentReceiver = generateAssignmentReceiver(ktBaseExpression, irOperator)
|
||||
|
||||
return irAssignmentReceiver.assign { irLValue ->
|
||||
val irBlock = IrBlockImpl(expression.startOffset, expression.endOffset, irLValue.type, irOperator)
|
||||
|
||||
// VAR tmp = [lhs].inc()
|
||||
val opCall = statementGenerator.pregenerateCall(opResolvedCall)
|
||||
opCall.setExplicitReceiverValue(irLValue)
|
||||
val irOpCall = CallGenerator(this).generateCall(expression, opCall, irOperator)
|
||||
val irTmp = statementGenerator.scope.createTemporaryVariable(irOpCall)
|
||||
irBlock.addStatement(irTmp)
|
||||
|
||||
// [lhs] = tmp
|
||||
irBlock.addStatement(irLValue.store(irTmp.defaultLoad()))
|
||||
|
||||
// ^ tmp
|
||||
irBlock.addStatement(irTmp.defaultLoad())
|
||||
|
||||
irBlock
|
||||
}
|
||||
}
|
||||
|
||||
private fun generatePostfixIncrementDecrementOperator(expression: KtPostfixExpression, irOperator: IrOperator): IrExpression {
|
||||
val opResolvedCall = getResolvedCall(expression)!!
|
||||
val ktBaseExpression = expression.baseExpression!!
|
||||
val irAssignmentReceiver = generateAssignmentReceiver(ktBaseExpression, irOperator)
|
||||
|
||||
return irAssignmentReceiver.assign { irLValue ->
|
||||
val irBlock = IrBlockImpl(expression.startOffset, expression.endOffset, irLValue.type, irOperator)
|
||||
|
||||
// VAR tmp = [lhs]
|
||||
val irTmp = scope.createTemporaryVariable(irLValue.load())
|
||||
irBlock.addStatement(irTmp)
|
||||
|
||||
// [lhs] = tmp.inc()
|
||||
val opCall = statementGenerator.pregenerateCall(opResolvedCall)
|
||||
opCall.setExplicitReceiverValue(VariableLValue(irTmp))
|
||||
val irOpCall = CallGenerator(this).generateCall(expression, opCall, irOperator)
|
||||
irBlock.addStatement(irLValue.store(irOpCall))
|
||||
|
||||
// ^ tmp
|
||||
irBlock.addStatement(irTmp.defaultLoad())
|
||||
|
||||
irBlock
|
||||
}
|
||||
}
|
||||
|
||||
private fun generateExclExclOperator(expression: KtPostfixExpression, irOperator: IrOperator): IrExpression {
|
||||
val ktArgument = expression.baseExpression!!
|
||||
@@ -301,95 +242,5 @@ class OperatorExpressionGenerator(
|
||||
return CallGenerator(statementGenerator).generateCall(expression, statementGenerator.pregenerateCall(resolvedCall), irOperator)
|
||||
}
|
||||
|
||||
private fun generateAugmentedAssignment(expression: KtBinaryExpression, irOperator: IrOperator): IrExpression {
|
||||
val opResolvedCall = getResolvedCall(expression)!!
|
||||
val isSimpleAssignment = get(BindingContext.VARIABLE_REASSIGNMENT, expression) ?: false
|
||||
val ktLeft = expression.left!!
|
||||
val ktRight = expression.right!!
|
||||
val irAssignmentReceiver = generateAssignmentReceiver(ktLeft, irOperator)
|
||||
|
||||
return irAssignmentReceiver.assign { irLValue ->
|
||||
val opCall = statementGenerator.pregenerateCall(opResolvedCall)
|
||||
opCall.setExplicitReceiverValue(irLValue)
|
||||
opCall.irValueArgumentsByIndex[0] = statementGenerator.generateExpression(ktRight)
|
||||
val irOpCall = CallGenerator(this).generateCall(expression, opCall, irOperator)
|
||||
|
||||
if (isSimpleAssignment) {
|
||||
// Set( Op( Get(), RHS ) )
|
||||
irLValue.store(irOpCall)
|
||||
}
|
||||
else {
|
||||
// Op( Get(), RHS )
|
||||
irOpCall
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun generateAssignment(expression: KtBinaryExpression): IrExpression {
|
||||
val ktLeft = expression.left!!
|
||||
val irRhs = statementGenerator.generateExpression(expression.right!!)
|
||||
val irAssignmentReceiver = generateAssignmentReceiver(ktLeft, IrOperator.EQ)
|
||||
return irAssignmentReceiver.assign(irRhs)
|
||||
}
|
||||
|
||||
private fun generateAssignmentReceiver(ktLeft: KtExpression, irOperator: IrOperator): AssignmentReceiver {
|
||||
if (ktLeft is KtArrayAccessExpression) {
|
||||
return generateArrayAccessAssignmentReceiver(ktLeft, irOperator)
|
||||
}
|
||||
|
||||
val resolvedCall = getResolvedCall(ktLeft) ?: TODO("no resolved call for LHS")
|
||||
val descriptor = resolvedCall.candidateDescriptor
|
||||
|
||||
return when (descriptor) {
|
||||
is LocalVariableDescriptor ->
|
||||
if (descriptor.isDelegated)
|
||||
TODO("Delegated local variable")
|
||||
else
|
||||
VariableLValue(ktLeft.startOffset, ktLeft.endOffset, descriptor, irOperator)
|
||||
is PropertyDescriptor ->
|
||||
generateAssignmentReceiverForProperty(descriptor, irOperator, ktLeft, resolvedCall)
|
||||
else ->
|
||||
TODO("Other cases of LHS")
|
||||
}
|
||||
}
|
||||
|
||||
private fun generateAssignmentReceiverForProperty(
|
||||
descriptor: PropertyDescriptor,
|
||||
irOperator: IrOperator,
|
||||
ktLeft: KtExpression,
|
||||
resolvedCall: ResolvedCall<*>
|
||||
): AssignmentReceiver {
|
||||
if (isPropertyInitializationWithinPrimaryConstructor(descriptor, resolvedCall)) {
|
||||
return PropertyInitializerLValue(ktLeft.startOffset, ktLeft.endOffset, descriptor)
|
||||
}
|
||||
|
||||
val propertyReceiver = statementGenerator.generateCallReceiver(
|
||||
ktLeft, resolvedCall.dispatchReceiver, resolvedCall.extensionReceiver, resolvedCall.call.isSafeCall())
|
||||
|
||||
return SimplePropertyLValue(scope, ktLeft.startOffset, ktLeft.endOffset, irOperator, descriptor, propertyReceiver)
|
||||
}
|
||||
|
||||
private fun isPropertyInitializationWithinPrimaryConstructor(descriptor: PropertyDescriptor, resolvedCall: ResolvedCall<*>): Boolean {
|
||||
val scopeOwner = statementGenerator.scopeOwner
|
||||
|
||||
return scopeOwner is ConstructorDescriptor && scopeOwner.isPrimary &&
|
||||
descriptor.containingDeclaration == scopeOwner.containingDeclaration &&
|
||||
resolvedCall.extensionReceiver == null && resolvedCall.dispatchReceiver is ThisClassReceiver
|
||||
}
|
||||
|
||||
private fun generateArrayAccessAssignmentReceiver(ktLeft: KtArrayAccessExpression, irOperator: IrOperator): ArrayAccessAssignmentReceiver {
|
||||
val irArray = statementGenerator.generateExpression(ktLeft.arrayExpression!!)
|
||||
val irIndexExpressions = ktLeft.indexExpressions.map { statementGenerator.generateExpression(it) }
|
||||
|
||||
val indexedGetResolvedCall = get(BindingContext.INDEXED_LVALUE_GET, ktLeft)
|
||||
val indexedGetCall = indexedGetResolvedCall?.let { statementGenerator.pregenerateCallReceivers(it) }
|
||||
|
||||
val indexedSetResolvedCall = get(BindingContext.INDEXED_LVALUE_SET, ktLeft)
|
||||
val indexedSetCall = indexedSetResolvedCall?.let { statementGenerator.pregenerateCallReceivers(it) }
|
||||
|
||||
return ArrayAccessAssignmentReceiver(irArray, irIndexExpressions, indexedGetCall, indexedSetCall,
|
||||
CallGenerator(statementGenerator),
|
||||
ktLeft.startOffset, ktLeft.endOffset, irOperator)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -326,3 +326,7 @@ class StatementGenerator(
|
||||
LocalFunctionGenerator(this).generateFunction(function)
|
||||
}
|
||||
|
||||
abstract class StatementGeneratorExtension(val statementGenerator: StatementGenerator) : GeneratorWithScope {
|
||||
override val scope: Scope get() = statementGenerator.scope
|
||||
override val context: GeneratorContext get() = statementGenerator.context
|
||||
}
|
||||
-32
@@ -1,32 +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.psi2ir.generators
|
||||
|
||||
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
||||
import org.jetbrains.kotlin.ir.declarations.IrDeclarationOrigin
|
||||
import org.jetbrains.kotlin.ir.declarations.IrVariable
|
||||
import org.jetbrains.kotlin.ir.declarations.IrVariableImpl
|
||||
import org.jetbrains.kotlin.ir.descriptors.IrTemporaryVariableDescriptor
|
||||
import org.jetbrains.kotlin.ir.descriptors.IrTemporaryVariableDescriptorImpl
|
||||
import org.jetbrains.kotlin.ir.expressions.IrExpression
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
|
||||
class TemporaryVariableFactory(val scopeOwner: DeclarationDescriptor) {
|
||||
|
||||
|
||||
}
|
||||
+1
-4
@@ -23,10 +23,7 @@ import org.jetbrains.kotlin.psi.psiUtil.endOffset
|
||||
import org.jetbrains.kotlin.psi.psiUtil.startOffset
|
||||
import org.jetbrains.kotlin.resolve.BindingContext
|
||||
|
||||
class TryCatchExpressionGenerator(val statementGenerator: StatementGenerator) : GeneratorWithScope {
|
||||
override val scope: Scope get() = statementGenerator.scope
|
||||
override val context: GeneratorContext get() = statementGenerator.context
|
||||
|
||||
class TryCatchExpressionGenerator(statementGenerator: StatementGenerator) : StatementGeneratorExtension(statementGenerator) {
|
||||
fun generateTryCatch(ktTry: KtTryExpression): IrExpression {
|
||||
val resultType = getInferredTypeWithImplicitCastsOrFail(ktTry)
|
||||
val irTryCatch = IrTryCatchImpl(ktTry.startOffset, ktTry.endOffset, resultType)
|
||||
|
||||
+11
-17
@@ -17,29 +17,23 @@
|
||||
package org.jetbrains.kotlin.psi2ir.intermediate
|
||||
|
||||
import org.jetbrains.kotlin.descriptors.PropertyDescriptor
|
||||
import org.jetbrains.kotlin.ir.expressions.IrExpression
|
||||
import org.jetbrains.kotlin.ir.expressions.IrInitializePropertyImpl
|
||||
import org.jetbrains.kotlin.ir.expressions.*
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
import org.jetbrains.kotlin.types.typeUtil.builtIns
|
||||
|
||||
class PropertyInitializerLValue(
|
||||
class BackingFieldLValue(
|
||||
val startOffset: Int,
|
||||
val endOffset: Int,
|
||||
val propertyDescriptor: PropertyDescriptor
|
||||
val descriptor: PropertyDescriptor,
|
||||
val operator: IrOperator?
|
||||
) : LValue, AssignmentReceiver {
|
||||
override val type: KotlinType get() = propertyDescriptor.type
|
||||
override val type: KotlinType get() = descriptor.type
|
||||
|
||||
override fun store(irExpression: IrExpression): IrExpression {
|
||||
val irInitProperty = IrInitializePropertyImpl(startOffset, endOffset, type.builtIns.unitType, propertyDescriptor)
|
||||
irInitProperty.initBlockExpression = irExpression
|
||||
return irInitProperty
|
||||
}
|
||||
override fun store(irExpression: IrExpression): IrExpression =
|
||||
IrSetBackingFieldImpl(startOffset, endOffset, descriptor, irExpression, operator)
|
||||
|
||||
override fun load(): IrExpression {
|
||||
throw AssertionError("Property initializer LValue for $propertyDescriptor should not be used in compound assignment.")
|
||||
}
|
||||
override fun load(): IrExpression =
|
||||
IrGetBackingFieldImpl(startOffset, endOffset, descriptor, operator)
|
||||
|
||||
override fun assign(withLValue: (LValue) -> IrExpression): IrExpression {
|
||||
return withLValue(this)
|
||||
}
|
||||
override fun assign(withLValue: (LValue) -> IrExpression): IrExpression =
|
||||
withLValue(this)
|
||||
}
|
||||
+10
-4
@@ -16,6 +16,7 @@
|
||||
|
||||
package org.jetbrains.kotlin.psi2ir.intermediate
|
||||
|
||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.PropertyDescriptor
|
||||
import org.jetbrains.kotlin.ir.declarations.IrVariable
|
||||
import org.jetbrains.kotlin.ir.expressions.*
|
||||
@@ -29,7 +30,8 @@ class SimplePropertyLValue(
|
||||
val endOffset: Int,
|
||||
val irOperator: IrOperator?,
|
||||
val descriptor: PropertyDescriptor,
|
||||
val callReceiver: CallReceiver
|
||||
val callReceiver: CallReceiver,
|
||||
val superQualifier: ClassDescriptor?
|
||||
) : LValue, AssignmentReceiver {
|
||||
override val type: KotlinType get() = descriptor.type
|
||||
|
||||
@@ -39,7 +41,8 @@ class SimplePropertyLValue(
|
||||
IrGetterCallImpl(startOffset, endOffset, getter,
|
||||
dispatchReceiverValue?.load(),
|
||||
extensionReceiverValue?.load(),
|
||||
irOperator)
|
||||
irOperator,
|
||||
superQualifier)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -49,7 +52,9 @@ class SimplePropertyLValue(
|
||||
IrSetterCallImpl(startOffset, endOffset, setter,
|
||||
dispatchReceiverValue?.load(),
|
||||
extensionReceiverValue?.load(),
|
||||
irExpression, irOperator)
|
||||
irExpression,
|
||||
irOperator,
|
||||
superQualifier)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -71,7 +76,8 @@ class SimplePropertyLValue(
|
||||
|
||||
val irResultExpression = withLValue(
|
||||
SimplePropertyLValue(scope, startOffset, endOffset, irOperator, descriptor,
|
||||
SimpleCallReceiver(tmpDispatchReceiverValue, tmpExtensionReceiverValue))
|
||||
SimpleCallReceiver(tmpDispatchReceiverValue, tmpExtensionReceiverValue),
|
||||
superQualifier)
|
||||
)
|
||||
|
||||
if (variablesForReceivers.isEmpty()) {
|
||||
|
||||
+111
@@ -0,0 +1,111 @@
|
||||
/*
|
||||
* Copyright 2010-2016 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.ir.expressions
|
||||
|
||||
import org.jetbrains.kotlin.descriptors.PropertyDescriptor
|
||||
import org.jetbrains.kotlin.ir.*
|
||||
import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
import org.jetbrains.kotlin.types.typeUtil.builtIns
|
||||
|
||||
interface IrBackingFieldExpression : IrDeclarationReference {
|
||||
override val descriptor: PropertyDescriptor
|
||||
val operator: IrOperator?
|
||||
}
|
||||
|
||||
interface IrGetBackingField : IrBackingFieldExpression
|
||||
|
||||
interface IrSetBackingField : IrBackingFieldExpression {
|
||||
var value: IrExpression
|
||||
}
|
||||
|
||||
abstract class IrBackingFieldExpressionBase(
|
||||
startOffset: Int,
|
||||
endOffset: Int,
|
||||
descriptor: PropertyDescriptor,
|
||||
type: KotlinType,
|
||||
override val operator: IrOperator? = null
|
||||
) : IrDeclarationReferenceBase<PropertyDescriptor>(startOffset, endOffset, type, descriptor), IrBackingFieldExpression
|
||||
|
||||
class IrGetBackingFieldImpl(
|
||||
startOffset: Int,
|
||||
endOffset: Int,
|
||||
descriptor: PropertyDescriptor,
|
||||
operator: IrOperator? = null
|
||||
) : IrBackingFieldExpressionBase(startOffset, endOffset, descriptor, descriptor.type, operator), IrGetBackingField {
|
||||
override fun getChild(slot: Int): IrElement? =
|
||||
null
|
||||
|
||||
override fun replaceChild(slot: Int, newChild: IrElement) {
|
||||
throwNoSuchSlot(slot)
|
||||
}
|
||||
|
||||
override fun <R, D> accept(visitor: IrElementVisitor<R, D>, data: D): R {
|
||||
return visitor.visitGetBackingField(this, data)
|
||||
}
|
||||
|
||||
override fun <D> acceptChildren(visitor: IrElementVisitor<Unit, D>, data: D) {
|
||||
// no children
|
||||
}
|
||||
}
|
||||
|
||||
class IrSetBackingFieldImpl(
|
||||
startOffset: Int,
|
||||
endOffset: Int,
|
||||
descriptor: PropertyDescriptor,
|
||||
operator: IrOperator? = null
|
||||
) : IrBackingFieldExpressionBase(startOffset, endOffset, descriptor, descriptor.type.builtIns.unitType, operator), IrSetBackingField {
|
||||
constructor(
|
||||
startOffset: Int,
|
||||
endOffset: Int,
|
||||
descriptor: PropertyDescriptor,
|
||||
value: IrExpression,
|
||||
operator: IrOperator? = null
|
||||
) : this(startOffset, endOffset, descriptor, operator) {
|
||||
this.value = value
|
||||
}
|
||||
|
||||
private var valueImpl: IrExpression? = null
|
||||
override var value: IrExpression
|
||||
get() = valueImpl!!
|
||||
set(value) {
|
||||
value.assertDetached()
|
||||
valueImpl?.detach()
|
||||
valueImpl = value
|
||||
value.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()
|
||||
}
|
||||
}
|
||||
|
||||
override fun <R, D> accept(visitor: IrElementVisitor<R, D>, data: D): R {
|
||||
return visitor.visitSetBackingField(this, data)
|
||||
}
|
||||
|
||||
override fun <D> acceptChildren(visitor: IrElementVisitor<Unit, D>, data: D) {
|
||||
value.accept(visitor, data)
|
||||
}
|
||||
}
|
||||
@@ -18,10 +18,11 @@ package org.jetbrains.kotlin.ir.expressions
|
||||
|
||||
import org.jetbrains.kotlin.descriptors.CallableDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.PropertyAccessorDescriptor
|
||||
import org.jetbrains.kotlin.ir.*
|
||||
import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
import java.lang.AssertionError
|
||||
import java.lang.UnsupportedOperationException
|
||||
|
||||
interface IrCall : IrMemberAccessExpression {
|
||||
val superQualifier: ClassDescriptor?
|
||||
@@ -83,88 +84,3 @@ class IrCallImpl(
|
||||
argumentsByParameterIndex.forEach { it?.accept(visitor, data) }
|
||||
}
|
||||
}
|
||||
|
||||
abstract class IrPropertyAccessorCallBase(
|
||||
startOffset: Int,
|
||||
endOffset: Int,
|
||||
override val descriptor: CallableDescriptor,
|
||||
override val operator: IrOperator? = null,
|
||||
override val superQualifier: ClassDescriptor? = null
|
||||
) : IrMemberAccessExpressionBase(startOffset, endOffset, descriptor.returnType!!), IrCall {
|
||||
override fun <R, D> accept(visitor: IrElementVisitor<R, D>, data: D): R {
|
||||
return visitor.visitCall(this, data)
|
||||
}
|
||||
}
|
||||
|
||||
class IrGetterCallImpl(
|
||||
startOffset: Int,
|
||||
endOffset: Int,
|
||||
descriptor: CallableDescriptor,
|
||||
operator: IrOperator? = null,
|
||||
superQualifier: ClassDescriptor? = null
|
||||
) : IrPropertyAccessorCallBase(startOffset, endOffset, descriptor, operator, superQualifier), IrCall {
|
||||
constructor(
|
||||
startOffset: Int,
|
||||
endOffset: Int,
|
||||
descriptor: CallableDescriptor,
|
||||
dispatchReceiver: IrExpression?,
|
||||
extensionReceiver: IrExpression?,
|
||||
operator: IrOperator? = null,
|
||||
superQualifier: ClassDescriptor? = null
|
||||
) : this(startOffset, endOffset, descriptor, operator, superQualifier) {
|
||||
this.dispatchReceiver = dispatchReceiver
|
||||
this.extensionReceiver = extensionReceiver
|
||||
}
|
||||
|
||||
override fun getArgument(index: Int): IrExpression? = null
|
||||
|
||||
override fun putArgument(index: Int, valueArgument: IrExpression?) {
|
||||
throw UnsupportedOperationException("Property setter call has no arguments")
|
||||
}
|
||||
|
||||
override fun removeArgument(index: Int) {
|
||||
throw UnsupportedOperationException("Property getter call has no arguments")
|
||||
}
|
||||
}
|
||||
|
||||
class IrSetterCallImpl(
|
||||
startOffset: Int,
|
||||
endOffset: Int,
|
||||
descriptor: CallableDescriptor,
|
||||
operator: IrOperator? = null,
|
||||
superQualifier: ClassDescriptor? = null
|
||||
) : IrPropertyAccessorCallBase(startOffset, endOffset, descriptor, operator, superQualifier), IrCall {
|
||||
constructor(
|
||||
startOffset: Int,
|
||||
endOffset: Int,
|
||||
descriptor: CallableDescriptor,
|
||||
dispatchReceiver: IrExpression?,
|
||||
extensionReceiver: IrExpression?,
|
||||
argument: IrExpression,
|
||||
operator: IrOperator? = null,
|
||||
superQualifier: ClassDescriptor? = null
|
||||
) : this(startOffset, endOffset, descriptor, operator, superQualifier) {
|
||||
this.dispatchReceiver = dispatchReceiver
|
||||
this.extensionReceiver = extensionReceiver
|
||||
putArgument(SETTER_ARGUMENT_INDEX, argument)
|
||||
}
|
||||
|
||||
private var argumentImpl: IrExpression? = null
|
||||
|
||||
override fun getArgument(index: Int): IrExpression? =
|
||||
if (index == SETTER_ARGUMENT_INDEX) argumentImpl!! else null
|
||||
|
||||
override fun putArgument(index: Int, valueArgument: IrExpression?) {
|
||||
if (index != SETTER_ARGUMENT_INDEX) return
|
||||
argumentImpl?.detach()
|
||||
valueArgument?.assertDetached()
|
||||
argumentImpl = valueArgument
|
||||
valueArgument?.setTreeLocation(this, SETTER_ARGUMENT_INDEX)
|
||||
}
|
||||
|
||||
override fun removeArgument(index: Int) {
|
||||
if (index != SETTER_ARGUMENT_INDEX) return
|
||||
argumentImpl?.detach()
|
||||
argumentImpl = null
|
||||
}
|
||||
}
|
||||
@@ -87,6 +87,7 @@ interface IrOperator {
|
||||
object LAMBDA : IrOperatorImpl("LAMBDA")
|
||||
object ANONYMOUS_FUNCTION : IrOperatorImpl("ANONYMOUS_FUNCTION")
|
||||
|
||||
object SUPER_CONSTRUCTOR_CALL : IrOperatorImpl("SUPER_CONSTRUCTOR_CALL")
|
||||
object DELEGATING_CONSTRUCTOR_CALL : IrOperatorImpl("DELEGATING_CONSTRUCTOR_CALL")
|
||||
object INITIALIZE_PROPERTY_FROM_PARAMETER : IrOperatorImpl("INITIALIZE_PROPERTY_FROM_PARAMETER")
|
||||
object ANONYMOUS_INITIALIZER : IrOperatorImpl("ANONYMOUS_INITIALIZER")
|
||||
|
||||
+109
@@ -0,0 +1,109 @@
|
||||
/*
|
||||
* Copyright 2010-2016 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.ir.expressions
|
||||
|
||||
import org.jetbrains.kotlin.descriptors.CallableDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
||||
import org.jetbrains.kotlin.ir.SETTER_ARGUMENT_INDEX
|
||||
import org.jetbrains.kotlin.ir.assertDetached
|
||||
import org.jetbrains.kotlin.ir.detach
|
||||
import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
|
||||
|
||||
abstract class IrPropertyAccessorCallBase(
|
||||
startOffset: Int,
|
||||
endOffset: Int,
|
||||
override val descriptor: CallableDescriptor,
|
||||
override val operator: IrOperator? = null,
|
||||
override val superQualifier: ClassDescriptor? = null
|
||||
) : IrMemberAccessExpressionBase(startOffset, endOffset, descriptor.returnType!!), IrCall {
|
||||
override fun <R, D> accept(visitor: IrElementVisitor<R, D>, data: D): R {
|
||||
return visitor.visitCall(this, data)
|
||||
}
|
||||
}
|
||||
|
||||
class IrGetterCallImpl(
|
||||
startOffset: Int,
|
||||
endOffset: Int,
|
||||
descriptor: CallableDescriptor,
|
||||
operator: IrOperator? = null,
|
||||
superQualifier: ClassDescriptor? = null
|
||||
) : IrPropertyAccessorCallBase(startOffset, endOffset, descriptor, operator, superQualifier), IrCall {
|
||||
constructor(
|
||||
startOffset: Int,
|
||||
endOffset: Int,
|
||||
descriptor: CallableDescriptor,
|
||||
dispatchReceiver: IrExpression?,
|
||||
extensionReceiver: IrExpression?,
|
||||
operator: IrOperator? = null,
|
||||
superQualifier: ClassDescriptor? = null
|
||||
) : this(startOffset, endOffset, descriptor, operator, superQualifier) {
|
||||
this.dispatchReceiver = dispatchReceiver
|
||||
this.extensionReceiver = extensionReceiver
|
||||
}
|
||||
|
||||
override fun getArgument(index: Int): IrExpression? = null
|
||||
|
||||
override fun putArgument(index: Int, valueArgument: IrExpression?) {
|
||||
throw UnsupportedOperationException("Property setter call has no arguments")
|
||||
}
|
||||
|
||||
override fun removeArgument(index: Int) {
|
||||
throw UnsupportedOperationException("Property getter call has no arguments")
|
||||
}
|
||||
}
|
||||
|
||||
class IrSetterCallImpl(
|
||||
startOffset: Int,
|
||||
endOffset: Int,
|
||||
descriptor: CallableDescriptor,
|
||||
operator: IrOperator? = null,
|
||||
superQualifier: ClassDescriptor? = null
|
||||
) : IrPropertyAccessorCallBase(startOffset, endOffset, descriptor, operator, superQualifier), IrCall {
|
||||
constructor(
|
||||
startOffset: Int,
|
||||
endOffset: Int,
|
||||
descriptor: CallableDescriptor,
|
||||
dispatchReceiver: IrExpression?,
|
||||
extensionReceiver: IrExpression?,
|
||||
argument: IrExpression,
|
||||
operator: IrOperator? = null,
|
||||
superQualifier: ClassDescriptor? = null
|
||||
) : this(startOffset, endOffset, descriptor, operator, superQualifier) {
|
||||
this.dispatchReceiver = dispatchReceiver
|
||||
this.extensionReceiver = extensionReceiver
|
||||
putArgument(SETTER_ARGUMENT_INDEX, argument)
|
||||
}
|
||||
|
||||
private var argumentImpl: IrExpression? = null
|
||||
|
||||
override fun getArgument(index: Int): IrExpression? =
|
||||
if (index == SETTER_ARGUMENT_INDEX) argumentImpl!! else null
|
||||
|
||||
override fun putArgument(index: Int, valueArgument: IrExpression?) {
|
||||
if (index != SETTER_ARGUMENT_INDEX) return
|
||||
argumentImpl?.detach()
|
||||
valueArgument?.assertDetached()
|
||||
argumentImpl = valueArgument
|
||||
valueArgument?.setTreeLocation(this, SETTER_ARGUMENT_INDEX)
|
||||
}
|
||||
|
||||
override fun removeArgument(index: Int) {
|
||||
if (index != SETTER_ARGUMENT_INDEX) return
|
||||
argumentImpl?.detach()
|
||||
argumentImpl = null
|
||||
}
|
||||
}
|
||||
@@ -91,15 +91,24 @@ class RenderIrElementVisitor : IrElementVisitor<String, Nothing?> {
|
||||
"THIS ${expression.classDescriptor.render()} type=${expression.type.render()}"
|
||||
|
||||
override fun visitCall(expression: IrCall, data: Nothing?): String =
|
||||
"CALL .${expression.descriptor.name} " +
|
||||
"CALL .${expression.descriptor.name} ${expression.renderSuperQualifier()}" +
|
||||
"type=${expression.type.render()} operator=${expression.operator}"
|
||||
|
||||
private fun IrCall.renderSuperQualifier(): String =
|
||||
superQualifier?.let { "superQualifier=${it.name} " } ?: ""
|
||||
|
||||
override fun visitGetVariable(expression: IrGetVariable, data: Nothing?): String =
|
||||
"GET_VAR ${expression.descriptor.name} type=${expression.type.render()} operator=${expression.operator}"
|
||||
|
||||
override fun visitSetVariable(expression: IrSetVariable, data: Nothing?): String =
|
||||
"SET_VAR ${expression.descriptor.name} type=${expression.type.render()} operator=${expression.operator}"
|
||||
|
||||
override fun visitGetBackingField(expression: IrGetBackingField, data: Nothing?): String =
|
||||
"GET_BACKING_FIELD ${expression.descriptor.name} type=${expression.type.render()} operator=${expression.operator}"
|
||||
|
||||
override fun visitSetBackingField(expression: IrSetBackingField, data: Nothing?): String =
|
||||
"SET_BACKING_FIELD ${expression.descriptor.name} type=${expression.type.render()} operator=${expression.operator}"
|
||||
|
||||
override fun visitGetObjectValue(expression: IrGetObjectValue, data: Nothing?): String =
|
||||
"GET_OBJECT ${expression.descriptor.name} type=${expression.type.render()}"
|
||||
|
||||
|
||||
@@ -56,6 +56,8 @@ interface IrElementVisitor<out R, in D> {
|
||||
fun visitGetEnumValue(expression: IrGetEnumValue, data: D) = visitSingletonReference(expression, data)
|
||||
fun visitGetVariable(expression: IrGetVariable, data: D) = visitDeclarationReference(expression, data)
|
||||
fun visitSetVariable(expression: IrSetVariable, data: D) = visitDeclarationReference(expression, data)
|
||||
fun visitGetBackingField(expression: IrGetBackingField, data: D) = visitDeclarationReference(expression, data)
|
||||
fun visitSetBackingField(expression: IrSetBackingField, data: D) = visitDeclarationReference(expression, data)
|
||||
fun visitGetExtensionReceiver(expression: IrGetExtensionReceiver, data: D) = visitDeclarationReference(expression, data)
|
||||
fun visitInitializeProperty(expression: IrInitializeProperty, data: D): R = visitDeclarationReference(expression, data)
|
||||
fun visitCall(expression: IrCall, data: D) = visitDeclarationReference(expression, data)
|
||||
@@ -80,4 +82,5 @@ interface IrElementVisitor<out R, in D> {
|
||||
fun visitDummyDeclaration(declaration: IrDummyDeclaration, data: D) = visitDeclaration(declaration, data)
|
||||
fun visitDummyExpression(expression: IrDummyExpression, data: D) = visitExpression(expression, data)
|
||||
|
||||
|
||||
}
|
||||
|
||||
+10
-3
@@ -2,9 +2,12 @@ FILE /classMembers.kt
|
||||
CLASS CLASS C
|
||||
FUN public constructor C(/*0*/ x: kotlin.Int, /*1*/ y: kotlin.Int, /*2*/ z: kotlin.Int = ...)
|
||||
BLOCK_BODY
|
||||
INITIALIZE_PROPERTY y
|
||||
INITIALIZE_PROPERTY z
|
||||
INITIALIZE_PROPERTY property
|
||||
SET_BACKING_FIELD y type=kotlin.Unit operator=null
|
||||
GET_VAR y type=kotlin.Int operator=INITIALIZE_PROPERTY_FROM_PARAMETER
|
||||
SET_BACKING_FIELD z type=kotlin.Unit operator=null
|
||||
GET_VAR z type=kotlin.Int operator=INITIALIZE_PROPERTY_FROM_PARAMETER
|
||||
SET_BACKING_FIELD property type=kotlin.Unit operator=null
|
||||
CONST Int type=kotlin.Int value='0'
|
||||
PROPERTY public final val y: kotlin.Int getter=null setter=null
|
||||
EXPRESSION_BODY
|
||||
GET_VAR y type=kotlin.Int operator=INITIALIZE_PROPERTY_FROM_PARAMETER
|
||||
@@ -45,6 +48,8 @@ FILE /classMembers.kt
|
||||
CALL .println type=kotlin.Unit operator=null
|
||||
message: CONST String type=kotlin.String value='2'
|
||||
CLASS CLASS NestedClass
|
||||
FUN public constructor NestedClass()
|
||||
BLOCK_BODY
|
||||
FUN public final fun function(): kotlin.Unit
|
||||
BLOCK_BODY
|
||||
CALL .println type=kotlin.Unit operator=null
|
||||
@@ -61,3 +66,5 @@ FILE /classMembers.kt
|
||||
CALL .foo type=kotlin.Unit operator=null
|
||||
$this: THIS public interface NestedInterface type=C.NestedInterface
|
||||
CLASS OBJECT Companion
|
||||
FUN private constructor Companion()
|
||||
BLOCK_BODY
|
||||
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
open class Base
|
||||
|
||||
class Test : Base {
|
||||
constructor()
|
||||
constructor(xx: Int): super()
|
||||
constructor(xx: Short): this()
|
||||
}
|
||||
+14
@@ -0,0 +1,14 @@
|
||||
FILE /delegatingConstructorCallsInSecondaryConstructors.kt
|
||||
CLASS CLASS Base
|
||||
FUN public constructor Base()
|
||||
BLOCK_BODY
|
||||
CLASS CLASS Test
|
||||
FUN public constructor Test()
|
||||
BLOCK_BODY
|
||||
CALL .<init> type=Base operator=DELEGATING_CONSTRUCTOR_CALL
|
||||
FUN public constructor Test(/*0*/ xx: kotlin.Int)
|
||||
BLOCK_BODY
|
||||
CALL .<init> type=Base operator=DELEGATING_CONSTRUCTOR_CALL
|
||||
FUN public constructor Test(/*0*/ xx: kotlin.Short)
|
||||
BLOCK_BODY
|
||||
CALL .<init> type=Test operator=DELEGATING_CONSTRUCTOR_CALL
|
||||
+13
@@ -0,0 +1,13 @@
|
||||
class TestInitValFromParameter(val x: Int)
|
||||
|
||||
class TestInitValInClass {
|
||||
val x = 0
|
||||
}
|
||||
|
||||
class TestInitValInInitBlock {
|
||||
val x: Int
|
||||
init {
|
||||
x = 0
|
||||
}
|
||||
}
|
||||
|
||||
+24
@@ -0,0 +1,24 @@
|
||||
FILE /initVal.kt
|
||||
CLASS CLASS TestInitValFromParameter
|
||||
FUN public constructor TestInitValFromParameter(/*0*/ x: kotlin.Int)
|
||||
BLOCK_BODY
|
||||
SET_BACKING_FIELD x type=kotlin.Unit operator=null
|
||||
GET_VAR x type=kotlin.Int operator=INITIALIZE_PROPERTY_FROM_PARAMETER
|
||||
PROPERTY public final val x: kotlin.Int getter=null setter=null
|
||||
EXPRESSION_BODY
|
||||
GET_VAR x type=kotlin.Int operator=INITIALIZE_PROPERTY_FROM_PARAMETER
|
||||
CLASS CLASS TestInitValInClass
|
||||
FUN public constructor TestInitValInClass()
|
||||
BLOCK_BODY
|
||||
SET_BACKING_FIELD x type=kotlin.Unit operator=null
|
||||
CONST Int type=kotlin.Int value='0'
|
||||
PROPERTY public final val x: kotlin.Int = 0 getter=null setter=null
|
||||
EXPRESSION_BODY
|
||||
CONST Int type=kotlin.Int value='0'
|
||||
CLASS CLASS TestInitValInInitBlock
|
||||
FUN public constructor TestInitValInInitBlock()
|
||||
BLOCK_BODY
|
||||
BLOCK type=kotlin.Unit operator=null
|
||||
SET_BACKING_FIELD x type=kotlin.Unit operator=null
|
||||
CONST Int type=kotlin.Int value='0'
|
||||
PROPERTY public final val x: kotlin.Int getter=null setter=null
|
||||
+38
@@ -0,0 +1,38 @@
|
||||
class TestInitVarFromParameter(var x: Int)
|
||||
|
||||
class TestInitVarInClass {
|
||||
var x = 0
|
||||
}
|
||||
|
||||
class TestInitVarInInitBlock {
|
||||
var x: Int
|
||||
init {
|
||||
x = 0
|
||||
}
|
||||
}
|
||||
|
||||
class TestInitVarWithCustomSetter {
|
||||
var x = 0
|
||||
set(value) { field = value }
|
||||
}
|
||||
|
||||
class TestInitVarWithCustomSetterWithExplicitCtor {
|
||||
var x: Int
|
||||
set(value) { field = value }
|
||||
|
||||
init {
|
||||
x = 0
|
||||
}
|
||||
|
||||
constructor()
|
||||
}
|
||||
|
||||
class TestInitVarWithCustomSetterInCtor {
|
||||
var x: Int set(value) {
|
||||
field = value
|
||||
}
|
||||
|
||||
constructor() {
|
||||
x = 42
|
||||
}
|
||||
}
|
||||
+62
@@ -0,0 +1,62 @@
|
||||
FILE /initVar.kt
|
||||
CLASS CLASS TestInitVarFromParameter
|
||||
FUN public constructor TestInitVarFromParameter(/*0*/ x: kotlin.Int)
|
||||
BLOCK_BODY
|
||||
SET_BACKING_FIELD x type=kotlin.Unit operator=null
|
||||
GET_VAR x type=kotlin.Int operator=INITIALIZE_PROPERTY_FROM_PARAMETER
|
||||
PROPERTY public final var x: kotlin.Int getter=null setter=null
|
||||
EXPRESSION_BODY
|
||||
GET_VAR x type=kotlin.Int operator=INITIALIZE_PROPERTY_FROM_PARAMETER
|
||||
CLASS CLASS TestInitVarInClass
|
||||
FUN public constructor TestInitVarInClass()
|
||||
BLOCK_BODY
|
||||
SET_BACKING_FIELD x type=kotlin.Unit operator=null
|
||||
CONST Int type=kotlin.Int value='0'
|
||||
PROPERTY public final var x: kotlin.Int getter=null setter=null
|
||||
EXPRESSION_BODY
|
||||
CONST Int type=kotlin.Int value='0'
|
||||
CLASS CLASS TestInitVarInInitBlock
|
||||
FUN public constructor TestInitVarInInitBlock()
|
||||
BLOCK_BODY
|
||||
BLOCK type=kotlin.Unit operator=null
|
||||
CALL .<set-x> type=kotlin.Unit operator=EQ
|
||||
$this: THIS public final class TestInitVarInInitBlock type=TestInitVarInInitBlock
|
||||
<set-?>: CONST Int type=kotlin.Int value='0'
|
||||
PROPERTY public final var x: kotlin.Int getter=null setter=null
|
||||
CLASS CLASS TestInitVarWithCustomSetter
|
||||
FUN public constructor TestInitVarWithCustomSetter()
|
||||
BLOCK_BODY
|
||||
SET_BACKING_FIELD x type=kotlin.Unit operator=null
|
||||
CONST Int type=kotlin.Int value='0'
|
||||
PROPERTY public final var x: kotlin.Int getter=null setter=<set-x>
|
||||
EXPRESSION_BODY
|
||||
CONST Int type=kotlin.Int value='0'
|
||||
PROPERTY_SETTER public final fun <set-x>(/*0*/ value: kotlin.Int): kotlin.Unit property=x
|
||||
BLOCK_BODY
|
||||
SET_BACKING_FIELD x type=kotlin.Unit operator=EQ
|
||||
GET_VAR value type=kotlin.Int operator=null
|
||||
CLASS CLASS TestInitVarWithCustomSetterWithExplicitCtor
|
||||
PROPERTY public final var x: kotlin.Int getter=null setter=<set-x>
|
||||
PROPERTY_SETTER public final fun <set-x>(/*0*/ value: kotlin.Int): kotlin.Unit property=x
|
||||
BLOCK_BODY
|
||||
SET_BACKING_FIELD x type=kotlin.Unit operator=EQ
|
||||
GET_VAR value type=kotlin.Int operator=null
|
||||
FUN public constructor TestInitVarWithCustomSetterWithExplicitCtor()
|
||||
BLOCK_BODY
|
||||
CALL .<init> type=kotlin.Any operator=DELEGATING_CONSTRUCTOR_CALL
|
||||
BLOCK type=kotlin.Unit operator=null
|
||||
CALL .<set-x> type=kotlin.Unit operator=EQ
|
||||
$this: THIS public final class TestInitVarWithCustomSetterWithExplicitCtor type=TestInitVarWithCustomSetterWithExplicitCtor
|
||||
value: CONST Int type=kotlin.Int value='0'
|
||||
CLASS CLASS TestInitVarWithCustomSetterInCtor
|
||||
PROPERTY public final var x: kotlin.Int getter=null setter=<set-x>
|
||||
PROPERTY_SETTER public final fun <set-x>(/*0*/ value: kotlin.Int): kotlin.Unit property=x
|
||||
BLOCK_BODY
|
||||
SET_BACKING_FIELD x type=kotlin.Unit operator=EQ
|
||||
GET_VAR value type=kotlin.Int operator=null
|
||||
FUN public constructor TestInitVarWithCustomSetterInCtor()
|
||||
BLOCK_BODY
|
||||
CALL .<init> type=kotlin.Any operator=DELEGATING_CONSTRUCTOR_CALL
|
||||
CALL .<set-x> type=kotlin.Unit operator=EQ
|
||||
$this: THIS public final class TestInitVarWithCustomSetterInCtor type=TestInitVarWithCustomSetterInCtor
|
||||
value: CONST Int type=kotlin.Int value='42'
|
||||
+11
-6
@@ -2,8 +2,10 @@ FILE /primaryConstructor.kt
|
||||
CLASS CLASS Test1
|
||||
FUN public constructor Test1(/*0*/ x: kotlin.Int, /*1*/ y: kotlin.Int)
|
||||
BLOCK_BODY
|
||||
INITIALIZE_PROPERTY x
|
||||
INITIALIZE_PROPERTY y
|
||||
SET_BACKING_FIELD x type=kotlin.Unit operator=null
|
||||
GET_VAR x type=kotlin.Int operator=INITIALIZE_PROPERTY_FROM_PARAMETER
|
||||
SET_BACKING_FIELD y type=kotlin.Unit operator=null
|
||||
GET_VAR y type=kotlin.Int operator=INITIALIZE_PROPERTY_FROM_PARAMETER
|
||||
PROPERTY public final val x: kotlin.Int getter=null setter=null
|
||||
EXPRESSION_BODY
|
||||
GET_VAR x type=kotlin.Int operator=INITIALIZE_PROPERTY_FROM_PARAMETER
|
||||
@@ -13,8 +15,10 @@ FILE /primaryConstructor.kt
|
||||
CLASS CLASS Test2
|
||||
FUN public constructor Test2(/*0*/ x: kotlin.Int, /*1*/ y: kotlin.Int)
|
||||
BLOCK_BODY
|
||||
INITIALIZE_PROPERTY y
|
||||
INITIALIZE_PROPERTY x
|
||||
SET_BACKING_FIELD y type=kotlin.Unit operator=null
|
||||
GET_VAR y type=kotlin.Int operator=INITIALIZE_PROPERTY_FROM_PARAMETER
|
||||
SET_BACKING_FIELD x type=kotlin.Unit operator=null
|
||||
GET_VAR x type=kotlin.Int operator=null
|
||||
PROPERTY public final val y: kotlin.Int getter=null setter=null
|
||||
EXPRESSION_BODY
|
||||
GET_VAR y type=kotlin.Int operator=INITIALIZE_PROPERTY_FROM_PARAMETER
|
||||
@@ -24,9 +28,10 @@ FILE /primaryConstructor.kt
|
||||
CLASS CLASS Test3
|
||||
FUN public constructor Test3(/*0*/ x: kotlin.Int, /*1*/ y: kotlin.Int)
|
||||
BLOCK_BODY
|
||||
INITIALIZE_PROPERTY y
|
||||
SET_BACKING_FIELD y type=kotlin.Unit operator=null
|
||||
GET_VAR y type=kotlin.Int operator=INITIALIZE_PROPERTY_FROM_PARAMETER
|
||||
BLOCK type=kotlin.Unit operator=null
|
||||
INITIALIZE_PROPERTY x
|
||||
SET_BACKING_FIELD x type=kotlin.Unit operator=null
|
||||
GET_VAR x type=kotlin.Int operator=null
|
||||
PROPERTY public final val y: kotlin.Int getter=null setter=null
|
||||
EXPRESSION_BODY
|
||||
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
open class Base
|
||||
|
||||
class TestImplicitPrimaryConstructor : Base()
|
||||
|
||||
class TestExplicitPrimaryConstructor() : Base()
|
||||
|
||||
class TestWithDelegatingConstructor(val x: Int, val y: Int) : Base() {
|
||||
constructor(x: Int) : this(x, 0)
|
||||
}
|
||||
|
||||
+31
@@ -0,0 +1,31 @@
|
||||
FILE /primaryConstructorWithSuperConstructorCall.kt
|
||||
CLASS CLASS Base
|
||||
FUN public constructor Base()
|
||||
BLOCK_BODY
|
||||
CLASS CLASS TestImplicitPrimaryConstructor
|
||||
FUN public constructor TestImplicitPrimaryConstructor()
|
||||
BLOCK_BODY
|
||||
CALL .<init> type=Base operator=SUPER_CONSTRUCTOR_CALL
|
||||
CLASS CLASS TestExplicitPrimaryConstructor
|
||||
FUN public constructor TestExplicitPrimaryConstructor()
|
||||
BLOCK_BODY
|
||||
CALL .<init> type=Base operator=SUPER_CONSTRUCTOR_CALL
|
||||
CLASS CLASS TestWithDelegatingConstructor
|
||||
FUN public constructor TestWithDelegatingConstructor(/*0*/ x: kotlin.Int, /*1*/ y: kotlin.Int)
|
||||
BLOCK_BODY
|
||||
CALL .<init> type=Base operator=SUPER_CONSTRUCTOR_CALL
|
||||
SET_BACKING_FIELD x type=kotlin.Unit operator=null
|
||||
GET_VAR x type=kotlin.Int operator=INITIALIZE_PROPERTY_FROM_PARAMETER
|
||||
SET_BACKING_FIELD y type=kotlin.Unit operator=null
|
||||
GET_VAR y type=kotlin.Int operator=INITIALIZE_PROPERTY_FROM_PARAMETER
|
||||
PROPERTY public final val x: kotlin.Int getter=null setter=null
|
||||
EXPRESSION_BODY
|
||||
GET_VAR x type=kotlin.Int operator=INITIALIZE_PROPERTY_FROM_PARAMETER
|
||||
PROPERTY public final val y: kotlin.Int getter=null setter=null
|
||||
EXPRESSION_BODY
|
||||
GET_VAR y type=kotlin.Int operator=INITIALIZE_PROPERTY_FROM_PARAMETER
|
||||
FUN public constructor TestWithDelegatingConstructor(/*0*/ x: kotlin.Int)
|
||||
BLOCK_BODY
|
||||
CALL .<init> type=TestWithDelegatingConstructor operator=DELEGATING_CONSTRUCTOR_CALL
|
||||
x: GET_VAR x type=kotlin.Int operator=null
|
||||
y: CONST Int type=kotlin.Int value='0'
|
||||
@@ -0,0 +1,19 @@
|
||||
interface ILeft {
|
||||
fun foo() {}
|
||||
val bar: Int get() = 1
|
||||
}
|
||||
|
||||
interface IRight {
|
||||
fun foo() {}
|
||||
val bar: Int get() = 2
|
||||
}
|
||||
|
||||
class CBoth : ILeft, IRight {
|
||||
override fun foo() {
|
||||
super<ILeft>.foo()
|
||||
super<IRight>.foo()
|
||||
}
|
||||
|
||||
override val bar: Int
|
||||
get() = super<ILeft>.bar + super<IRight>.bar
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
FILE /qualifiedSuperCalls.kt
|
||||
CLASS INTERFACE ILeft
|
||||
FUN public open fun foo(): kotlin.Unit
|
||||
BLOCK_BODY
|
||||
PROPERTY public open val bar: kotlin.Int getter=<get-bar> setter=null
|
||||
PROPERTY_GETTER public open fun <get-bar>(): kotlin.Int property=bar
|
||||
BLOCK_BODY
|
||||
RETURN type=kotlin.Nothing from=<get-bar>
|
||||
CONST Int type=kotlin.Int value='1'
|
||||
CLASS INTERFACE IRight
|
||||
FUN public open fun foo(): kotlin.Unit
|
||||
BLOCK_BODY
|
||||
PROPERTY public open val bar: kotlin.Int getter=<get-bar> setter=null
|
||||
PROPERTY_GETTER public open fun <get-bar>(): kotlin.Int property=bar
|
||||
BLOCK_BODY
|
||||
RETURN type=kotlin.Nothing from=<get-bar>
|
||||
CONST Int type=kotlin.Int value='2'
|
||||
CLASS CLASS CBoth
|
||||
FUN public constructor CBoth()
|
||||
BLOCK_BODY
|
||||
FUN public open override /*2*/ fun foo(): kotlin.Unit
|
||||
BLOCK_BODY
|
||||
CALL .foo superQualifier=ILeft type=kotlin.Unit operator=null
|
||||
$this: THIS public final class CBoth : ILeft, IRight type=ILeft
|
||||
CALL .foo superQualifier=IRight type=kotlin.Unit operator=null
|
||||
$this: THIS public final class CBoth : ILeft, IRight type=IRight
|
||||
PROPERTY public open override /*2*/ val bar: kotlin.Int getter=<get-bar> setter=null
|
||||
PROPERTY_GETTER public open override /*2*/ fun <get-bar>(): kotlin.Int property=bar
|
||||
BLOCK_BODY
|
||||
RETURN type=kotlin.Nothing from=<get-bar>
|
||||
CALL .plus type=kotlin.Int operator=PLUS
|
||||
$this: CALL .<get-bar> superQualifier=ILeft type=kotlin.Int operator=GET_PROPERTY
|
||||
$this: THIS public final class CBoth : ILeft, IRight type=ILeft
|
||||
other: CALL .<get-bar> superQualifier=IRight type=kotlin.Int operator=GET_PROPERTY
|
||||
$this: THIS public final class CBoth : ILeft, IRight type=IRight
|
||||
+14
@@ -0,0 +1,14 @@
|
||||
open class Base
|
||||
|
||||
class TestProperty : Base {
|
||||
val x = 0
|
||||
constructor()
|
||||
}
|
||||
|
||||
class TestInitBlock : Base {
|
||||
val x: Int
|
||||
init {
|
||||
x = 0
|
||||
}
|
||||
constructor()
|
||||
}
|
||||
+21
@@ -0,0 +1,21 @@
|
||||
FILE /secondaryConstructorWithInitializersFromClassBody.kt
|
||||
CLASS CLASS Base
|
||||
FUN public constructor Base()
|
||||
BLOCK_BODY
|
||||
CLASS CLASS TestProperty
|
||||
PROPERTY public final val x: kotlin.Int = 0 getter=null setter=null
|
||||
EXPRESSION_BODY
|
||||
CONST Int type=kotlin.Int value='0'
|
||||
FUN public constructor TestProperty()
|
||||
BLOCK_BODY
|
||||
CALL .<init> type=Base operator=DELEGATING_CONSTRUCTOR_CALL
|
||||
SET_BACKING_FIELD x type=kotlin.Unit operator=null
|
||||
CONST Int type=kotlin.Int value='0'
|
||||
CLASS CLASS TestInitBlock
|
||||
PROPERTY public final val x: kotlin.Int getter=null setter=null
|
||||
FUN public constructor TestInitBlock()
|
||||
BLOCK_BODY
|
||||
CALL .<init> type=Base operator=DELEGATING_CONSTRUCTOR_CALL
|
||||
BLOCK type=kotlin.Unit operator=null
|
||||
SET_BACKING_FIELD x type=kotlin.Unit operator=null
|
||||
CONST Int type=kotlin.Int value='0'
|
||||
@@ -0,0 +1,14 @@
|
||||
open class Base {
|
||||
open fun foo() {}
|
||||
|
||||
open val bar: String = ""
|
||||
}
|
||||
|
||||
class Derived : Base() {
|
||||
override fun foo() {
|
||||
super.foo()
|
||||
}
|
||||
|
||||
override val bar: String
|
||||
get() = super.bar
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
FILE /superCalls.kt
|
||||
CLASS CLASS Base
|
||||
FUN public constructor Base()
|
||||
BLOCK_BODY
|
||||
SET_BACKING_FIELD bar type=kotlin.Unit operator=null
|
||||
CONST String type=kotlin.String value=''
|
||||
FUN public open fun foo(): kotlin.Unit
|
||||
BLOCK_BODY
|
||||
PROPERTY public open val bar: kotlin.String = "" getter=null setter=null
|
||||
EXPRESSION_BODY
|
||||
CONST String type=kotlin.String value=''
|
||||
CLASS CLASS Derived
|
||||
FUN public constructor Derived()
|
||||
BLOCK_BODY
|
||||
CALL .<init> type=Base operator=SUPER_CONSTRUCTOR_CALL
|
||||
FUN public open override /*1*/ fun foo(): kotlin.Unit
|
||||
BLOCK_BODY
|
||||
CALL .foo superQualifier=Base type=kotlin.Unit operator=null
|
||||
$this: THIS public final class Derived : Base type=Base
|
||||
PROPERTY public open override /*1*/ val bar: kotlin.String getter=<get-bar> setter=null
|
||||
PROPERTY_GETTER public open override /*1*/ fun <get-bar>(): kotlin.String property=bar
|
||||
BLOCK_BODY
|
||||
RETURN type=kotlin.Nothing from=<get-bar>
|
||||
CALL .<get-bar> superQualifier=Base type=kotlin.String operator=GET_PROPERTY
|
||||
$this: THIS public final class Derived : Base type=Base
|
||||
@@ -14,7 +14,8 @@ FILE /arrayAugmentedAssignment1.kt
|
||||
CLASS CLASS C
|
||||
FUN public constructor C(/*0*/ x: kotlin.IntArray)
|
||||
BLOCK_BODY
|
||||
INITIALIZE_PROPERTY x
|
||||
SET_BACKING_FIELD x type=kotlin.Unit operator=null
|
||||
GET_VAR x type=kotlin.IntArray operator=INITIALIZE_PROPERTY_FROM_PARAMETER
|
||||
PROPERTY public final val x: kotlin.IntArray getter=null setter=null
|
||||
EXPRESSION_BODY
|
||||
GET_VAR x type=kotlin.IntArray operator=INITIALIZE_PROPERTY_FROM_PARAMETER
|
||||
|
||||
+2
-1
@@ -2,7 +2,8 @@ FILE /assignments.kt
|
||||
CLASS CLASS Ref
|
||||
FUN public constructor Ref(/*0*/ x: kotlin.Int)
|
||||
BLOCK_BODY
|
||||
INITIALIZE_PROPERTY x
|
||||
SET_BACKING_FIELD x type=kotlin.Unit operator=null
|
||||
GET_VAR x type=kotlin.Int operator=INITIALIZE_PROPERTY_FROM_PARAMETER
|
||||
PROPERTY public final var x: kotlin.Int getter=null setter=null
|
||||
EXPRESSION_BODY
|
||||
GET_VAR x type=kotlin.Int operator=INITIALIZE_PROPERTY_FROM_PARAMETER
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
FILE /augmentedAssignment2.kt
|
||||
CLASS CLASS A
|
||||
FUN public constructor A()
|
||||
BLOCK_BODY
|
||||
FUN public operator fun A.plusAssign(/*0*/ s: kotlin.String): kotlin.Unit
|
||||
BLOCK_BODY
|
||||
FUN public operator fun A.minusAssign(/*0*/ s: kotlin.String): kotlin.Unit
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
FILE /chainOfSafeCalls.kt
|
||||
CLASS CLASS C
|
||||
FUN public constructor C()
|
||||
BLOCK_BODY
|
||||
FUN public final fun foo(): C
|
||||
BLOCK_BODY
|
||||
RETURN type=kotlin.Nothing from=foo
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
var testSimple: Int = 0
|
||||
set(value) {
|
||||
field = value
|
||||
}
|
||||
|
||||
var testAugmented: Int = 0
|
||||
set(value) {
|
||||
field += value
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
FILE /field.kt
|
||||
PROPERTY public var testSimple: kotlin.Int getter=null setter=<set-testSimple>
|
||||
EXPRESSION_BODY
|
||||
CONST Int type=kotlin.Int value='0'
|
||||
PROPERTY_SETTER public fun <set-testSimple>(/*0*/ value: kotlin.Int): kotlin.Unit property=testSimple
|
||||
BLOCK_BODY
|
||||
SET_BACKING_FIELD testSimple type=kotlin.Unit operator=EQ
|
||||
GET_VAR value type=kotlin.Int operator=null
|
||||
PROPERTY public var testAugmented: kotlin.Int getter=null setter=<set-testAugmented>
|
||||
EXPRESSION_BODY
|
||||
CONST Int type=kotlin.Int value='0'
|
||||
PROPERTY_SETTER public fun <set-testAugmented>(/*0*/ value: kotlin.Int): kotlin.Unit property=testAugmented
|
||||
BLOCK_BODY
|
||||
SET_BACKING_FIELD testAugmented type=kotlin.Unit operator=PLUSEQ
|
||||
CALL .plus type=kotlin.Int operator=PLUSEQ
|
||||
$this: GET_BACKING_FIELD testAugmented type=kotlin.Int operator=PLUSEQ
|
||||
other: GET_VAR value type=kotlin.Int operator=null
|
||||
@@ -1,9 +1,12 @@
|
||||
FILE /forWithImplicitReceivers.kt
|
||||
CLASS OBJECT FiveTimes
|
||||
FUN private constructor FiveTimes()
|
||||
BLOCK_BODY
|
||||
CLASS CLASS IntCell
|
||||
FUN public constructor IntCell(/*0*/ value: kotlin.Int)
|
||||
BLOCK_BODY
|
||||
INITIALIZE_PROPERTY value
|
||||
SET_BACKING_FIELD value type=kotlin.Unit operator=null
|
||||
GET_VAR value type=kotlin.Int operator=INITIALIZE_PROPERTY_FROM_PARAMETER
|
||||
PROPERTY public final var value: kotlin.Int getter=null setter=null
|
||||
EXPRESSION_BODY
|
||||
GET_VAR value type=kotlin.Int operator=INITIALIZE_PROPERTY_FROM_PARAMETER
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
FILE /safeCallWithIncrementDecrement.kt
|
||||
CLASS CLASS C
|
||||
FUN public constructor C()
|
||||
BLOCK_BODY
|
||||
PROPERTY public var test.C?.p: kotlin.Int getter=<get-p> setter=<set-p>
|
||||
PROPERTY_GETTER public fun test.C?.<get-p>(): kotlin.Int property=p
|
||||
BLOCK_BODY
|
||||
|
||||
+2
-1
@@ -2,7 +2,8 @@ FILE /safeCalls.kt
|
||||
CLASS CLASS Ref
|
||||
FUN public constructor Ref(/*0*/ value: kotlin.Int)
|
||||
BLOCK_BODY
|
||||
INITIALIZE_PROPERTY value
|
||||
SET_BACKING_FIELD value type=kotlin.Unit operator=null
|
||||
GET_VAR value type=kotlin.Int operator=INITIALIZE_PROPERTY_FROM_PARAMETER
|
||||
PROPERTY public final var value: kotlin.Int getter=null setter=null
|
||||
EXPRESSION_BODY
|
||||
GET_VAR value type=kotlin.Int operator=INITIALIZE_PROPERTY_FROM_PARAMETER
|
||||
|
||||
@@ -1,12 +1,22 @@
|
||||
FILE /values.kt
|
||||
CLASS ENUM_CLASS Enum
|
||||
FUN private constructor Enum()
|
||||
BLOCK_BODY
|
||||
CLASS ENUM_ENTRY A
|
||||
FUN private constructor A()
|
||||
BLOCK_BODY
|
||||
CLASS OBJECT A
|
||||
FUN private constructor A()
|
||||
BLOCK_BODY
|
||||
PROPERTY public val a: kotlin.Int = 0 getter=null setter=null
|
||||
EXPRESSION_BODY
|
||||
CONST Int type=kotlin.Int value='0'
|
||||
CLASS CLASS Z
|
||||
FUN public constructor Z()
|
||||
BLOCK_BODY
|
||||
CLASS OBJECT Companion
|
||||
FUN private constructor Companion()
|
||||
BLOCK_BODY
|
||||
FUN public fun test1(): Enum
|
||||
BLOCK_BODY
|
||||
RETURN type=kotlin.Nothing from=test1
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
FILE /when.kt
|
||||
CLASS OBJECT A
|
||||
FUN private constructor A()
|
||||
BLOCK_BODY
|
||||
FUN public fun testWithSubject(/*0*/ x: kotlin.Any?): kotlin.String
|
||||
BLOCK_BODY
|
||||
RETURN type=kotlin.Nothing from=testWithSubject
|
||||
|
||||
@@ -1,6 +1,10 @@
|
||||
FILE /multipleImplicitReceivers.kt
|
||||
CLASS OBJECT A
|
||||
FUN private constructor A()
|
||||
BLOCK_BODY
|
||||
CLASS OBJECT B
|
||||
FUN private constructor B()
|
||||
BLOCK_BODY
|
||||
CLASS INTERFACE IFoo
|
||||
PROPERTY public open val A.foo: B getter=<get-foo> setter=null
|
||||
PROPERTY_GETTER public open fun A.<get-foo>(): B property=foo
|
||||
|
||||
@@ -49,17 +49,59 @@ public class IrTextTestCaseGenerated extends AbstractIrTextTestCase {
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("delegatingConstructorCallsInSecondaryConstructors.kt")
|
||||
public void testDelegatingConstructorCallsInSecondaryConstructors() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/ir/irText/classes/delegatingConstructorCallsInSecondaryConstructors.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("initVal.kt")
|
||||
public void testInitVal() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/ir/irText/classes/initVal.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("initVar.kt")
|
||||
public void testInitVar() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/ir/irText/classes/initVar.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("primaryConstructor.kt")
|
||||
public void testPrimaryConstructor() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/ir/irText/classes/primaryConstructor.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("primaryConstructorWithSuperConstructorCall.kt")
|
||||
public void testPrimaryConstructorWithSuperConstructorCall() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/ir/irText/classes/primaryConstructorWithSuperConstructorCall.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("qualifiedSuperCalls.kt")
|
||||
public void testQualifiedSuperCalls() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/ir/irText/classes/qualifiedSuperCalls.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("secondaryConstructorWithInitializersFromClassBody.kt")
|
||||
public void testSecondaryConstructorWithInitializersFromClassBody() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/ir/irText/classes/secondaryConstructorWithInitializersFromClassBody.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("secondaryConstructors.kt")
|
||||
public void testSecondaryConstructors() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/ir/irText/classes/secondaryConstructors.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("superCalls.kt")
|
||||
public void testSuperCalls() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/ir/irText/classes/superCalls.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/testData/ir/irText/expressions")
|
||||
@@ -190,6 +232,12 @@ public class IrTextTestCaseGenerated extends AbstractIrTextTestCase {
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("field.kt")
|
||||
public void testField() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/ir/irText/expressions/field.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("for.kt")
|
||||
public void testFor() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/ir/irText/expressions/for.kt");
|
||||
|
||||
Reference in New Issue
Block a user