Representation for nested initializers in a class & nested initializers call.
This commit is contained in:
committed by
Dmitry Petrov
parent
8528c23194
commit
8d86c0a2dd
@@ -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) }
|
||||
|
||||
+35
@@ -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)
|
||||
}
|
||||
}
|
||||
+32
@@ -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)
|
||||
|
||||
+4
-4
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user