Representation for nested initializers in a class & nested initializers call.

This commit is contained in:
Dmitry Petrov
2016-08-29 17:35:38 +03:00
committed by Dmitry Petrov
parent 8528c23194
commit 8d86c0a2dd
12 changed files with 162 additions and 99 deletions
@@ -87,7 +87,7 @@ class CallGenerator(
val returnType = descriptor.returnType!!
return call.callReceiver.call { dispatchReceiverValue, extensionReceiverValue ->
val irCall = IrCallImpl(startOffset, endOffset, returnType, descriptor, operator, call.superQualifier)
val irCall = IrFunCallImpl(startOffset, endOffset, returnType, descriptor, operator, call.superQualifier)
irCall.dispatchReceiver = dispatchReceiverValue?.load()
irCall.extensionReceiver = extensionReceiverValue?.load()
@@ -32,4 +32,5 @@ const val LOOP_BODY_SLOT = -1
const val LOOP_CONDITION_SLOT = -2
const val SETTER_ARGUMENT_INDEX = 0
const val TRY_RESULT_SLOT = -1
const val FINALLY_EXPRESSION_SLOT = -2
const val FINALLY_EXPRESSION_SLOT = -2
const val NESTED_INITIALIZERS_SLOT = -1
@@ -18,6 +18,7 @@ package org.jetbrains.kotlin.ir.declarations
import org.jetbrains.kotlin.descriptors.ClassDescriptor
import org.jetbrains.kotlin.ir.*
import org.jetbrains.kotlin.ir.expressions.IrBody
import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
import java.util.*
@@ -28,6 +29,8 @@ interface IrClass : IrDeclaration {
override val descriptor: ClassDescriptor
val members: List<IrDeclaration>
var nestedInitializers: IrBody?
}
class IrClassImpl(
@@ -44,20 +47,40 @@ class IrClassImpl(
members.add(member)
}
override var nestedInitializers: IrBody? = null
set(value) {
value?.assertDetached()
field?.detach()
field = value
value?.setTreeLocation(this, NESTED_INITIALIZERS_SLOT)
}
override fun getChild(slot: Int): IrElement? =
members.getOrNull(slot)
when (slot) {
NESTED_INITIALIZERS_SLOT -> nestedInitializers
else -> members.getOrNull(slot)
}
override fun replaceChild(slot: Int, newChild: IrElement) {
newChild.assertDetached()
members.getOrNull(slot)?.detach() ?: throwNoSuchSlot(slot)
members[slot] = newChild.assertCast()
newChild.setTreeLocation(this, slot)
when (slot) {
NESTED_INITIALIZERS_SLOT ->
nestedInitializers = newChild.assertCast()
else -> {
newChild.assertDetached()
members.getOrNull(slot)?.detach() ?: throwNoSuchSlot(slot)
members[slot] = newChild.assertCast()
newChild.setTreeLocation(this, slot)
}
}
}
override fun <R, D> accept(visitor: IrElementVisitor<R, D>, data: D): R =
visitor.visitClass(this, data)
override fun <D> acceptChildren(visitor: IrElementVisitor<Unit, D>, data: D) {
nestedInitializers?.accept(visitor, data)
members.forEach { it.accept(visitor, data) }
}
@@ -17,15 +17,15 @@
package org.jetbrains.kotlin.ir.expressions
import org.jetbrains.kotlin.descriptors.CallableDescriptor
import org.jetbrains.kotlin.descriptors.ClassDescriptor
import org.jetbrains.kotlin.ir.*
import org.jetbrains.kotlin.ir.IrElement
import org.jetbrains.kotlin.ir.assertCast
import org.jetbrains.kotlin.ir.assertDetached
import org.jetbrains.kotlin.ir.detach
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?
val operator: IrOperator?
override val descriptor: CallableDescriptor
@@ -34,16 +34,15 @@ interface IrCall : IrMemberAccessExpression {
fun removeArgument(index: Int)
}
class IrCallImpl(
abstract class IrCallBase(
startOffset: Int,
endOffset: Int,
type: KotlinType,
override val descriptor: CallableDescriptor,
override val operator: IrOperator? = null,
override val superQualifier: ClassDescriptor? = null
numArguments: Int,
override val operator: IrOperator? = null
) : IrMemberAccessExpressionBase(startOffset, endOffset, type), IrCall {
private val argumentsByParameterIndex =
arrayOfNulls<IrExpression>(descriptor.valueParameters.size)
protected val argumentsByParameterIndex =
arrayOfNulls<IrExpression>(numArguments)
override fun getArgument(index: Int): IrExpression? =
argumentsByParameterIndex[index]
@@ -76,9 +75,6 @@ class IrCallImpl(
super.replaceChild(slot, newChild)
}
override fun <R, D> accept(visitor: IrElementVisitor<R, D>, data: D): R =
visitor.visitCall(this, data)
override fun <D> acceptChildren(visitor: IrElementVisitor<Unit, D>, data: D) {
super.acceptChildren(visitor, data)
argumentsByParameterIndex.forEach { it?.accept(visitor, data) }
@@ -0,0 +1,35 @@
/*
* 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.ConstructorDescriptor
import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
import org.jetbrains.kotlin.resolve.descriptorUtil.builtIns
interface IrDelegatingConstructorCall : IrCall {
override val descriptor: ConstructorDescriptor
}
class IrDelegatingConstructorCallImpl(
startOffset: Int,
endOffset: Int,
override val descriptor: ConstructorDescriptor
) : IrCallBase(startOffset, endOffset, descriptor.builtIns.unitType, descriptor.valueParameters.size), IrDelegatingConstructorCall {
override fun <R, D> accept(visitor: IrElementVisitor<R, D>, data: D): R {
return visitor.visitDelegatingConstructorCall(this, data)
}
}
@@ -0,0 +1,38 @@
/*
* 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.visitors.IrElementVisitor
import org.jetbrains.kotlin.types.KotlinType
interface IrFunCall : IrCall {
val superQualifier: ClassDescriptor?
}
class IrFunCallImpl(
startOffset: Int,
endOffset: Int,
type: KotlinType,
override val descriptor: CallableDescriptor,
override val operator: IrOperator? = null,
override val superQualifier: ClassDescriptor? = null
) : IrCallBase(startOffset, endOffset, type, descriptor.valueParameters.size), IrFunCall {
override fun <R, D> accept(visitor: IrElementVisitor<R, D>, data: D): R =
visitor.visitFunCall(this, data)
}
@@ -1,63 +0,0 @@
/*
* Copyright 2010-2016 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.kotlin.ir.expressions
import org.jetbrains.kotlin.descriptors.PropertyDescriptor
import org.jetbrains.kotlin.ir.*
import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
import org.jetbrains.kotlin.types.KotlinType
interface IrInitializeProperty : IrDeclarationReference {
override val descriptor: PropertyDescriptor
var initBlockExpression: IrExpression?
}
class IrInitializePropertyImpl(
startOffset: Int,
endOffset: Int,
type: KotlinType,
descriptor: PropertyDescriptor
) : IrDeclarationReferenceBase<PropertyDescriptor>(startOffset, endOffset, type, descriptor), IrInitializeProperty {
override var initBlockExpression: IrExpression? = null
set(value) {
value?.assertDetached()
field?.detach()
field = value
value?.setTreeLocation(this, CHILD_EXPRESSION_SLOT)
}
override fun getChild(slot: Int): IrElement? =
when (slot) {
CHILD_EXPRESSION_SLOT -> initBlockExpression
else -> null
}
override fun replaceChild(slot: Int, newChild: IrElement) {
when (slot) {
CHILD_EXPRESSION_SLOT -> initBlockExpression = newChild.assertCast()
}
}
override fun <R, D> accept(visitor: IrElementVisitor<R, D>, data: D): R {
return visitor.visitInitializeProperty(this, data)
}
override fun <D> acceptChildren(visitor: IrElementVisitor<Unit, D>, data: D) {
initBlockExpression?.accept(visitor, data)
}
}
@@ -0,0 +1,32 @@
/*
* Copyright 2010-2016 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.kotlin.ir.expressions
import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
import org.jetbrains.kotlin.types.KotlinType
interface IrNestedInitializersCall : IrExpression
class IrNestedInitializersCallImpl(
startOffset: Int,
endOffset: Int,
type: KotlinType
) : IrTerminalExpressionBase(startOffset, endOffset, type), IrNestedInitializersCall {
override fun <R, D> accept(visitor: IrElementVisitor<R, D>, data: D): R {
return visitor.visitNestedInitializersCall(this, data)
}
}
@@ -20,14 +20,15 @@ import org.jetbrains.kotlin.descriptors.CallableDescriptor
import org.jetbrains.kotlin.descriptors.ClassDescriptor
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
abstract class IrPrimitiveCallBase(
startOffset: Int,
endOffset: Int,
override val operator: IrOperator,
override val descriptor: CallableDescriptor
) : IrExpressionBase(startOffset, endOffset, descriptor.returnType!!), IrCall {
) : IrExpressionBase(startOffset, endOffset, descriptor.returnType!!), IrFunCall {
override val superQualifier: ClassDescriptor? get() = null
override var dispatchReceiver: IrExpression?
get() = null
@@ -48,7 +49,7 @@ abstract class IrPrimitiveCallBase(
}
override fun <R, D> accept(visitor: IrElementVisitor<R, D>, data: D): R {
return visitor.visitCall(this, data)
return visitor.visitFunCall(this, data)
}
}
@@ -166,9 +167,6 @@ class IrBinaryPrimitiveImpl(
}
}
override fun <R, D> accept(visitor: IrElementVisitor<R, D>, data: D): R =
visitor.visitCall(this, data)
override fun <D> acceptChildren(visitor: IrElementVisitor<Unit, D>, data: D) {
argument0.accept(visitor, data)
argument1.accept(visitor, data)
@@ -29,9 +29,9 @@ abstract class IrPropertyAccessorCallBase(
override val descriptor: CallableDescriptor,
override val operator: IrOperator? = null,
override val superQualifier: ClassDescriptor? = null
) : IrMemberAccessExpressionBase(startOffset, endOffset, descriptor.returnType!!), IrCall {
) : IrMemberAccessExpressionBase(startOffset, endOffset, descriptor.returnType!!), IrFunCall {
override fun <R, D> accept(visitor: IrElementVisitor<R, D>, data: D): R {
return visitor.visitCall(this, data)
return visitor.visitFunCall(this, data)
}
}
@@ -41,7 +41,7 @@ class IrGetterCallImpl(
descriptor: CallableDescriptor,
operator: IrOperator? = null,
superQualifier: ClassDescriptor? = null
) : IrPropertyAccessorCallBase(startOffset, endOffset, descriptor, operator, superQualifier), IrCall {
) : IrPropertyAccessorCallBase(startOffset, endOffset, descriptor, operator, superQualifier), IrFunCall {
constructor(
startOffset: Int,
endOffset: Int,
@@ -72,7 +72,7 @@ class IrSetterCallImpl(
descriptor: CallableDescriptor,
operator: IrOperator? = null,
superQualifier: ClassDescriptor? = null
) : IrPropertyAccessorCallBase(startOffset, endOffset, descriptor, operator, superQualifier), IrCall {
) : IrPropertyAccessorCallBase(startOffset, endOffset, descriptor, operator, superQualifier), IrFunCall {
constructor(
startOffset: Int,
endOffset: Int,
@@ -90,13 +90,16 @@ class RenderIrElementVisitor : IrElementVisitor<String, Nothing?> {
override fun visitThisReference(expression: IrThisReference, data: Nothing?): String =
"THIS ${expression.classDescriptor.render()} type=${expression.type.render()}"
override fun visitCall(expression: IrCall, data: Nothing?): String =
override fun visitFunCall(expression: IrFunCall, data: Nothing?): String =
"CALL .${expression.descriptor.name} ${expression.renderSuperQualifier()}" +
"type=${expression.type.render()} operator=${expression.operator}"
private fun IrCall.renderSuperQualifier(): String =
private fun IrFunCall.renderSuperQualifier(): String =
superQualifier?.let { "superQualifier=${it.name} " } ?: ""
override fun visitNestedInitializersCall(expression: IrNestedInitializersCall, data: Nothing?): String =
"NESTED_INITIALIZERS_CALL"
override fun visitGetVariable(expression: IrGetVariable, data: Nothing?): String =
"GET_VAR ${expression.descriptor.name} type=${expression.type.render()} operator=${expression.operator}"
@@ -115,9 +118,6 @@ class RenderIrElementVisitor : IrElementVisitor<String, Nothing?> {
override fun visitGetEnumValue(expression: IrGetEnumValue, data: Nothing?): String =
"GET_ENUM_VALUE ${expression.descriptor.name} type=${expression.type.render()}"
override fun visitInitializeProperty(expression: IrInitializeProperty, data: Nothing?): String =
"INITIALIZE_PROPERTY ${expression.descriptor.name}"
override fun visitStringConcatenation(expression: IrStringConcatenation, data: Nothing?): String =
"STRING_CONCATENATION type=${expression.type.render()}"
@@ -59,10 +59,13 @@ interface IrElementVisitor<out R, in D> {
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)
fun visitFunCall(expression: IrFunCall, data: D) = visitCall(expression, data)
fun visitDelegatingConstructorCall(expression: IrDelegatingConstructorCall, data: D) = visitCall(expression, data)
fun visitCallableReference(expression: IrCallableReference, data: D) = visitDeclarationReference(expression, data)
fun visitNestedInitializersCall(expression: IrNestedInitializersCall, data: D) = visitExpression(expression, data)
fun visitTypeOperator(expression: IrTypeOperatorCall, data: D) = visitExpression(expression, data)
fun visitWhen(expression: IrWhen, data: D) = visitExpression(expression, data)