Represent class instance initialization "as from resolve".

This commit is contained in:
Dmitry Petrov
2016-09-01 18:32:07 +03:00
committed by Dmitry Petrov
parent c3c758c7cc
commit 1b5dd50359
43 changed files with 322 additions and 164 deletions
@@ -23,6 +23,7 @@ const val ARGUMENT1_SLOT = 1
const val DISPATCH_RECEIVER_SLOT = -1
const val EXTENSION_RECEIVER_SLOT = -2
const val FUNCTION_BODY_SLOT = -1
const val ANONYMOUS_INITIALIZER_BODY_SLOT = -1
const val MODULE_SLOT = 0
const val INITIALIZER_SLOT = 0
const val IF_CONDITION_SLOT = 0
@@ -0,0 +1,68 @@
/*
* Copyright 2010-2016 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.kotlin.ir.declarations
import org.jetbrains.kotlin.descriptors.ClassDescriptor
import org.jetbrains.kotlin.ir.*
import org.jetbrains.kotlin.ir.expressions.IrBlockBody
import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
interface IrAnonymousInitializer : IrDeclaration {
override val descriptor: ClassDescriptor // TODO special descriptor for anonymous initializer blocks
override val declarationKind: IrDeclarationKind
get() = IrDeclarationKind.ANONYMOUS_INITIALIZER
var body: IrBlockBody
}
class IrAnonymousInitializerImpl(
startOffset: Int,
endOffset: Int,
origin: IrDeclarationOrigin,
override val descriptor: ClassDescriptor
) : IrDeclarationBase(startOffset, endOffset, origin), IrAnonymousInitializer {
private var bodyImpl: IrBlockBody? = null
override var body: IrBlockBody
get() = bodyImpl!!
set(value) {
value.assertDetached()
bodyImpl?.detach()
bodyImpl = value
value.setTreeLocation(this, ANONYMOUS_INITIALIZER_BODY_SLOT)
}
override fun getChild(slot: Int): IrElement? =
when (slot) {
ANONYMOUS_INITIALIZER_BODY_SLOT -> body
else -> null
}
override fun replaceChild(slot: Int, newChild: IrElement) {
when (slot) {
ANONYMOUS_INITIALIZER_BODY_SLOT -> body = newChild.assertCast()
}
}
override fun <R, D> accept(visitor: IrElementVisitor<R, D>, data: D): R {
return visitor.visitAnonymousInitializer(this, data)
}
override fun <D> acceptChildren(visitor: IrElementVisitor<Unit, D>, data: D) {
body.accept(visitor, data)
}
}
@@ -29,10 +29,23 @@ interface IrClass : IrDeclaration {
override val descriptor: ClassDescriptor
val members: List<IrDeclaration>
var nestedInitializers: IrBody?
}
fun IrClass.getInstanceInitializerMembers() =
members.filter {
when (it) {
is IrDelegate ->
true
is IrAnonymousInitializer ->
true
is IrSimpleProperty ->
it.valueInitializer != null
is IrDelegatedProperty ->
true
else -> false
}
}
class IrClassImpl(
startOffset: Int,
endOffset: Int,
@@ -47,41 +60,21 @@ 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? =
when (slot) {
NESTED_INITIALIZERS_SLOT -> nestedInitializers
else -> members.getOrNull(slot)
}
members.getOrNull(slot)
override fun replaceChild(slot: Int, newChild: IrElement) {
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)
}
}
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) }
}
}
@@ -39,6 +39,7 @@ enum class IrDeclarationKind {
CLASS,
TYPEALIAS,
ENUM_ENTRY,
ANONYMOUS_INITIALIZER,
DUMMY;
}
@@ -20,16 +20,16 @@ import org.jetbrains.kotlin.descriptors.ClassDescriptor
import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
import org.jetbrains.kotlin.resolve.descriptorUtil.builtIns
interface IrNestedInitializersCall : IrExpression {
interface IrInstanceInitializerCall : IrExpression {
val classDescriptor: ClassDescriptor
}
class IrNestedInitializersCallImpl(
class IrInstanceInitializerCallImpl(
startOffset: Int,
endOffset: Int,
override val classDescriptor: ClassDescriptor
) : IrTerminalExpressionBase(startOffset, endOffset, classDescriptor.builtIns.unitType), IrNestedInitializersCall {
) : IrTerminalExpressionBase(startOffset, endOffset, classDescriptor.builtIns.unitType), IrInstanceInitializerCall {
override fun <R, D> accept(visitor: IrElementVisitor<R, D>, data: D): R {
return visitor.visitNestedInitializersCall(this, data)
return visitor.visitInstanceInitializerCall(this, data)
}
}
@@ -60,15 +60,6 @@ class DumpIrTreeVisitor(out: Appendable): IrElementVisitor<Unit, String> {
}
}
override fun visitClass(declaration: IrClass, data: String) {
declaration.dumpLabeledElementWith(data) {
declaration.nestedInitializers?.accept(this, "nestedInitializers")
declaration.members.forEach {
it.accept(this, "")
}
}
}
override fun visitEnumEntry(declaration: IrEnumEntry, data: String) {
declaration.dumpLabeledElementWith(data) {
declaration.initializerExpression.accept(this, "init")
@@ -69,6 +69,9 @@ class RenderIrElementVisitor : IrElementVisitor<String, Nothing?> {
override fun visitEnumEntry(declaration: IrEnumEntry, data: Nothing?): String =
"ENUM_ENTRY ${declaration.descriptor.render()}"
override fun visitAnonymousInitializer(declaration: IrAnonymousInitializer, data: Nothing?): String =
"ANONYMOUS_INITIALIZER ${declaration.descriptor.name}"
override fun visitExpressionBody(body: IrExpressionBody, data: Nothing?): String =
"EXPRESSION_BODY"
@@ -119,8 +122,8 @@ class RenderIrElementVisitor : IrElementVisitor<String, Nothing?> {
else enumEntryDescriptor.name
}
override fun visitNestedInitializersCall(expression: IrNestedInitializersCall, data: Nothing?): String =
"NESTED_INITIALIZERS_CALL classDescriptor=${expression.classDescriptor.name}"
override fun visitInstanceInitializerCall(expression: IrInstanceInitializerCall, data: Nothing?): String =
"INSTANCE_INITIALIZER_CALL classDescriptor=${expression.classDescriptor.name}"
override fun visitGetVariable(expression: IrGetVariable, data: Nothing?): String =
"GET_VAR ${expression.descriptor.name} type=${expression.type.render()} operator=${expression.operator}"
@@ -39,6 +39,7 @@ interface IrElementVisitor<out R, in D> {
fun visitVariable(declaration: IrVariable, data: D) = visitDeclaration(declaration, data)
fun visitDelegate(declaration: IrDelegate, data: D) = visitDeclaration(declaration, data)
fun visitEnumEntry(declaration: IrEnumEntry, data: D) = visitDeclaration(declaration, data)
fun visitAnonymousInitializer(declaration: IrAnonymousInitializer, data: D) = visitDeclaration(declaration, data)
fun visitBody(body: IrBody, data: D) = visitElement(body, data)
fun visitExpressionBody(body: IrExpressionBody, data: D) = visitBody(body, data)
@@ -71,7 +72,7 @@ interface IrElementVisitor<out R, in D> {
fun visitCallableReference(expression: IrCallableReference, data: D) = visitDeclarationReference(expression, data)
fun visitClassReference(expression: IrClassReference, data: D) = visitDeclarationReference(expression, data)
fun visitNestedInitializersCall(expression: IrNestedInitializersCall, data: D) = visitExpression(expression, data)
fun visitInstanceInitializerCall(expression: IrInstanceInitializerCall, data: D) = visitExpression(expression, data)
fun visitTypeOperator(expression: IrTypeOperatorCall, data: D) = visitExpression(expression, data)