Generate get/set for local delegated properties as accessor calls.

This commit is contained in:
Dmitry Petrov
2016-09-02 14:42:40 +03:00
committed by Dmitry Petrov
parent f2e778d2d0
commit 8b95992af1
8 changed files with 104 additions and 6 deletions
@@ -114,7 +114,7 @@ class AssignmentGenerator(statementGenerator: StatementGenerator) : StatementGen
BackingFieldLValue(ktLeft.startOffset, ktLeft.endOffset, descriptor.propertyDescriptor, operator)
is LocalVariableDescriptor ->
if (descriptor.isDelegated)
TODO("Delegated local variable")
DelegatedLocalPropertyLValue(ktLeft.startOffset, ktLeft.endOffset, descriptor, operator)
else
VariableLValue(ktLeft.startOffset, ktLeft.endOffset, descriptor, operator)
is PropertyDescriptor ->
@@ -17,6 +17,7 @@
package org.jetbrains.kotlin.psi2ir.generators
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.descriptors.impl.LocalVariableDescriptor
import org.jetbrains.kotlin.ir.expressions.*
import org.jetbrains.kotlin.psi.KtElement
import org.jetbrains.kotlin.psi.psiUtil.endOffset
@@ -35,7 +36,7 @@ class CallGenerator(statementGenerator: StatementGenerator): StatementGeneratorE
generatePropertyGetterCall(descriptor, startOffset, endOffset, call)
is VariableDescriptor ->
call.callReceiver.call { dispatchReceiverValue, extensionReceiverValue ->
IrGetVariableImpl(startOffset, endOffset, descriptor, operator)
generateGetVariable(startOffset, endOffset, descriptor, operator)
}
is FunctionDescriptor ->
generateFunctionCall(descriptor, startOffset, endOffset, operator, call)
@@ -44,6 +45,12 @@ class CallGenerator(statementGenerator: StatementGenerator): StatementGeneratorE
}
}
fun generateGetVariable(startOffset: Int, endOffset: Int, descriptor: VariableDescriptor, operator: IrOperator? = null) =
if (descriptor is LocalVariableDescriptor && descriptor.isDelegated)
IrCallImpl(startOffset, endOffset, descriptor.type, descriptor.getter!!, operator ?: IrOperator.GET_LOCAL_PROPERTY)
else
IrGetVariableImpl(startOffset, endOffset, descriptor, operator)
fun generateDelegatingConstructorCall(startOffset: Int, endOffset: Int, call: CallBuilder) : IrExpression {
val descriptor = call.descriptor
if (descriptor !is ConstructorDescriptor) throw AssertionError("Constructor expected: $descriptor")
@@ -255,7 +255,7 @@ class StatementGenerator(
CallGenerator(this).generateCall(expression.startOffset, expression.endOffset, pregenerateCall(resolvedCall))
}
is VariableDescriptor ->
IrGetVariableImpl(expression.startOffset, expression.endOffset, descriptor)
CallGenerator(this).generateGetVariable(expression.startOffset, expression.endOffset, descriptor)
else ->
IrDummyExpression(
expression.startOffset, expression.endOffset, getInferredTypeWithImplicitCastsOrFail(expression),
@@ -0,0 +1,43 @@
/*
* 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.intermediate
import org.jetbrains.kotlin.descriptors.VariableDescriptorWithAccessors
import org.jetbrains.kotlin.ir.expressions.IrCallImpl
import org.jetbrains.kotlin.ir.expressions.IrExpression
import org.jetbrains.kotlin.ir.expressions.IrOperator
import org.jetbrains.kotlin.types.KotlinType
class DelegatedLocalPropertyLValue(
val startOffset: Int,
val endOffset: Int,
val descriptor: VariableDescriptorWithAccessors,
val irOperator: IrOperator? = null
) : LValue, AssignmentReceiver {
override val type: KotlinType get() = descriptor.type
override fun load(): IrExpression =
IrCallImpl(startOffset, endOffset, descriptor.type, descriptor.getter!!, irOperator)
override fun store(irExpression: IrExpression): IrExpression =
IrCallImpl(startOffset, endOffset, descriptor.type, descriptor.setter!!, irOperator).apply {
putArgument(0, irExpression)
}
override fun assign(withLValue: (LValue) -> IrExpression): IrExpression =
withLValue(this)
}
@@ -72,6 +72,7 @@ interface IrOperator {
object DESTRUCTURING_DECLARATION : IrOperatorImpl("DESTRUCTURING_DECLARATION")
object GET_PROPERTY : IrOperatorImpl("GET_PROPERTY")
object GET_LOCAL_PROPERTY : IrOperatorImpl("GET_LOCAL_PROPERTY")
object IF : IrOperatorImpl("IF")
object WHEN : IrOperatorImpl("WHEN")
@@ -69,6 +69,12 @@ class RenderIrElementVisitor : IrElementVisitor<String, Nothing?> {
override fun visitAnonymousInitializer(declaration: IrAnonymousInitializer, data: Nothing?): String =
"ANONYMOUS_INITIALIZER ${declaration.descriptor.name}"
override fun visitLocalDelegatedProperty(declaration: IrLocalDelegatedProperty, data: Nothing?): String =
"LOCAL_DELEGATED_PROPERTY ${declaration.descriptor.render()}"
override fun visitLocalPropertyAccessor(declaration: IrLocalPropertyAccessor, data: Nothing?): String =
"LOCAL_PROPERTY_ACCESSOR ${declaration.descriptor.name}" // can't render, see nullability for modality
override fun visitExpressionBody(body: IrExpressionBody, data: Nothing?): String =
"EXPRESSION_BODY"