Represent class instance initialization "as from resolve".
This commit is contained in:
committed by
Dmitry Petrov
parent
c3c758c7cc
commit
1b5dd50359
@@ -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
|
||||
|
||||
+68
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
+4
-4
@@ -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)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user