Generate IrTypeParameter and IrValueParameter declarations

This commit is contained in:
Dmitry Petrov
2017-03-15 17:47:46 +03:00
parent 03b664febd
commit 8cea27b5bb
149 changed files with 2251 additions and 331 deletions
@@ -19,15 +19,17 @@ package org.jetbrains.kotlin.ir.builders
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor
import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET
import org.jetbrains.kotlin.ir.declarations.IrClass
import org.jetbrains.kotlin.ir.declarations.impl.IrClassImpl
import org.jetbrains.kotlin.ir.declarations.IrDeclarationOrigin
import org.jetbrains.kotlin.ir.declarations.IrFunction
import org.jetbrains.kotlin.ir.declarations.impl.IrFunctionImpl
import org.jetbrains.kotlin.ir.declarations.putDefault
import org.jetbrains.kotlin.ir.expressions.IrExpression
class IrMemberFunctionBuilder(
context: IrGeneratorContext,
val irClass: IrClassImpl,
val irClass: IrClass,
val function: FunctionDescriptor,
val origin: IrDeclarationOrigin,
startOffset: Int = UNDEFINED_OFFSET,
@@ -35,11 +37,12 @@ class IrMemberFunctionBuilder(
) : IrBlockBodyBuilder(context, Scope(function), startOffset, endOffset) {
lateinit var irFunction: IrFunction
inline fun addToClass(body: IrMemberFunctionBuilder.(IrFunction) -> Unit) {
inline fun addToClass(body: IrMemberFunctionBuilder.(IrFunction) -> Unit): IrFunction {
irFunction = IrFunctionImpl(startOffset, endOffset, origin, function)
body(irFunction)
irFunction.body = doBuild()
irClass.addMember(irFunction)
irClass.declarations.add(irFunction)
return irFunction
}
fun putDefault(parameter: ValueParameterDescriptor, value: IrExpression) {
@@ -18,13 +18,19 @@ package org.jetbrains.kotlin.ir.declarations
import org.jetbrains.kotlin.descriptors.ClassDescriptor
interface IrClass : IrDeclaration, IrDeclarationContainer {
interface IrClass : IrDeclaration, IrDeclarationContainer, IrTypeParametersContainer {
override val declarationKind: IrDeclarationKind
get() = IrDeclarationKind.CLASS
override val descriptor: ClassDescriptor
}
val typeParameters: MutableList<IrTypeParameter>
fun IrClass.addMember(member: IrDeclaration) {
declarations.add(member)
}
fun IrClass.addAll(members: List<IrDeclaration>) {
declarations.addAll(members)
}
fun IrClass.getInstanceInitializerMembers() =
@@ -16,8 +16,6 @@
package org.jetbrains.kotlin.ir.declarations
import org.jetbrains.kotlin.ir.util.transformFlat
interface IrDeclarationContainer {
val declarations: MutableList<IrDeclaration>
}
@@ -21,19 +21,32 @@ import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor
import org.jetbrains.kotlin.ir.expressions.IrBody
import org.jetbrains.kotlin.ir.expressions.IrExpressionBody
interface IrFunction : IrDeclaration {
interface IrFunction : IrDeclaration, IrTypeParametersContainer {
override val descriptor: FunctionDescriptor
val typeParameters: MutableList<IrTypeParameter>
var dispatchReceiverParameter: IrValueParameter?
var extensionReceiverParameter: IrValueParameter?
val valueParameters: MutableList<IrValueParameter>
var body: IrBody?
override val declarationKind: IrDeclarationKind
get() = IrDeclarationKind.FUNCTION
fun putDefault(parameter: ValueParameterDescriptor, expressionBody: IrExpressionBody)
fun getDefault(parameter: ValueParameterDescriptor): IrExpressionBody?
}
fun IrFunction.getIrValueParameter(parameter: ValueParameterDescriptor): IrValueParameter =
valueParameters.getOrElse(parameter.index) {
throw AssertionError("No IrValueParameter for $parameter")
}.also { found ->
assert(found.descriptor == parameter) {
"Parameter indices mismatch at $descriptor: $parameter != ${found.descriptor}"
}
}
fun IrFunction.getDefault(parameter: ValueParameterDescriptor): IrExpressionBody? =
getIrValueParameter(parameter).defaultValue
fun IrFunction.putDefault(parameter: ValueParameterDescriptor, expressionBody: IrExpressionBody) {
getIrValueParameter(parameter).defaultValue = expressionBody
}
@@ -0,0 +1,21 @@
/*
* Copyright 2010-2017 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
interface IrTypeParametersContainer {
val typeParameters: MutableList<IrTypeParameter>
}
@@ -41,14 +41,6 @@ class IrClassImpl(
override val typeParameters: MutableList<IrTypeParameter> = SmartList()
fun addMember(member: IrDeclaration) {
declarations.add(member)
}
fun addAll(members: List<IrDeclaration>) {
declarations.addAll(members)
}
override fun <R, D> accept(visitor: IrElementVisitor<R, D>, data: D): R =
visitor.visitClass(this, data)
@@ -35,30 +35,27 @@ abstract class IrFunctionBase(
) : IrDeclarationBase(startOffset, endOffset, origin), IrFunction {
override val typeParameters: MutableList<IrTypeParameter> = SmartList()
override var dispatchReceiverParameter: IrValueParameter? = null
override var extensionReceiverParameter: IrValueParameter? = null
override val valueParameters: MutableList<IrValueParameter> = ArrayList()
final override var body: IrBody? = null
private fun getIrValueParameter(parameter: ValueParameterDescriptor): IrValueParameter =
valueParameters.getOrElse(parameter.index) {
throw AssertionError("No IrValueParameter for $parameter")
}
override fun getDefault(parameter: ValueParameterDescriptor): IrExpressionBody? =
getIrValueParameter(parameter).defaultValue
override fun putDefault(parameter: ValueParameterDescriptor, expressionBody: IrExpressionBody) {
getIrValueParameter(parameter).defaultValue = expressionBody
}
override fun <D> acceptChildren(visitor: IrElementVisitor<Unit, D>, data: D) {
typeParameters.forEach { it.accept(visitor, data) }
dispatchReceiverParameter?.accept(visitor, data)
extensionReceiverParameter?.accept(visitor, data)
valueParameters.forEach { it.accept(visitor, data) }
body?.accept(visitor, data)
}
override fun <D> transformChildren(transformer: IrElementTransformer<D>, data: D) {
typeParameters.transform { it.transform(transformer, data) }
dispatchReceiverParameter = dispatchReceiverParameter?.transform(transformer, data)
extensionReceiverParameter = extensionReceiverParameter?.transform(transformer, data)
valueParameters.transform { it.transform(transformer, data) }
body = body?.transform(transformer, data)
@@ -36,7 +36,7 @@ class IrValueParameterImpl(
endOffset: Int,
origin: IrDeclarationOrigin,
descriptor: ParameterDescriptor,
defaultValue: IrExpressionBody
defaultValue: IrExpressionBody?
) : this(startOffset, endOffset, origin, descriptor) {
this.defaultValue = defaultValue
}
@@ -85,7 +85,9 @@ open class DeepCopyIrTree : IrElementTransformerVoid() {
mapDeclarationOrigin(declaration.origin),
mapClassDeclaration(declaration.descriptor),
declaration.declarations.map { it.transform(this, null) as IrDeclaration }
)
).apply {
transformTypeParameters(declaration, descriptor.declaredTypeParameters)
}
override fun visitTypeAlias(declaration: IrTypeAlias): IrTypeAlias =
IrTypeAliasImpl(
@@ -100,7 +102,7 @@ open class DeepCopyIrTree : IrElementTransformerVoid() {
mapDeclarationOrigin(declaration.origin),
mapFunctionDeclaration(declaration.descriptor),
declaration.body?.transform(this, null)
).transformDefaults(declaration)
).transformParameters(declaration)
override fun visitConstructor(declaration: IrConstructor): IrConstructor =
IrConstructorImpl(
@@ -108,17 +110,59 @@ open class DeepCopyIrTree : IrElementTransformerVoid() {
mapDeclarationOrigin(declaration.origin),
mapConstructorDeclaration(declaration.descriptor),
declaration.body!!.transform(this, null)
).transformDefaults(declaration)
).transformParameters(declaration)
private fun <T : IrFunction> T.transformDefaults(original: T): T {
for (originalValueParameter in original.descriptor.valueParameters) {
val valueParameter = descriptor.valueParameters[originalValueParameter.index]
original.getDefault(originalValueParameter)?.let { irDefaultParameterValue ->
putDefault(valueParameter, irDefaultParameterValue.transform(this@DeepCopyIrTree, null))
private fun <T : IrTypeParametersContainer> T.transformTypeParameters(original: T, myTypeParameters: List<TypeParameterDescriptor>): T =
apply {
original.typeParameters.mapTo(typeParameters) { originalTypeParameter ->
copyTypeParameter(originalTypeParameter, myTypeParameters[originalTypeParameter.descriptor.index])
}
}
}
return this
}
private fun <T : IrFunction> T.transformParameters(original: T): T =
apply {
transformTypeParameters(original, descriptor.typeParameters)
transformValueParameters(original)
}
private fun <T : IrFunction> T.transformValueParameters(original: T) =
apply {
dispatchReceiverParameter = original.dispatchReceiverParameter?.let {
copyValueParameter(it, descriptor.dispatchReceiverParameter ?: throw AssertionError("No dispatch receiver in $descriptor"))
}
extensionReceiverParameter = original.extensionReceiverParameter?.let {
copyValueParameter(it, descriptor.extensionReceiverParameter ?: throw AssertionError("No extension receiver in $descriptor"))
}
original.valueParameters.mapIndexedTo(valueParameters) { i, originalValueParameter ->
copyValueParameter(originalValueParameter, descriptor.valueParameters[i])
}
}
private fun copyTypeParameter(
originalTypeParameter: IrTypeParameter,
newTypeParameterDescriptor: TypeParameterDescriptor
): IrTypeParameterImpl =
IrTypeParameterImpl(
originalTypeParameter.startOffset, originalTypeParameter.endOffset,
mapDeclarationOrigin(originalTypeParameter.origin),
newTypeParameterDescriptor
)
private fun copyValueParameter(
originalValueParameter: IrValueParameter,
newParameterDescriptor: ParameterDescriptor
): IrValueParameterImpl =
IrValueParameterImpl(
originalValueParameter.startOffset, originalValueParameter.endOffset,
mapDeclarationOrigin(originalValueParameter.origin),
newParameterDescriptor,
originalValueParameter.defaultValue?.transform(this@DeepCopyIrTree, null)
)
// TODO visitTypeParameter
// TODO visitValueParameter
override fun visitProperty(declaration: IrProperty): IrProperty =
IrPropertyImpl(
@@ -71,6 +71,8 @@ class DumpIrTreeVisitor(out: Appendable): IrElementVisitor<Unit, String> {
override fun visitFunction(declaration: IrFunction, data: String) {
declaration.dumpLabeledElementWith(data) {
declaration.typeParameters.dumpElements()
declaration.dispatchReceiverParameter?.accept(this, "\$this")
declaration.extensionReceiverParameter?.accept(this, "\$receiver")
declaration.valueParameters.dumpElements()
declaration.body?.accept(this, "")
}
@@ -16,11 +16,13 @@
package org.jetbrains.kotlin.ir.util
import org.jetbrains.kotlin.descriptors.ClassDescriptor
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
import org.jetbrains.kotlin.descriptors.ReceiverParameterDescriptor
import org.jetbrains.kotlin.ir.IrElement
import org.jetbrains.kotlin.ir.declarations.*
import org.jetbrains.kotlin.ir.expressions.*
import org.jetbrains.kotlin.ir.util.RenderIrElementVisitor.Companion.ref
import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
import org.jetbrains.kotlin.renderer.ClassifierNamePolicy
import org.jetbrains.kotlin.renderer.DescriptorRenderer
@@ -209,14 +211,17 @@ class RenderIrElementVisitor : IrElementVisitor<String, Nothing?> {
internal fun IrDeclaration.name(): String =
descriptor.name.toString()
internal fun IrDeclaration.renderDeclared(): String =
DECLARATION_RENDERER.render(this.descriptor)
internal fun DeclarationDescriptor.ref(): String =
if (this is ReceiverParameterDescriptor)
"<receiver: ${containingDeclaration.ref()}>"
internal fun DescriptorRenderer.renderDescriptor(descriptor: DeclarationDescriptor): String =
if (descriptor is ReceiverParameterDescriptor)
"<receiver: ${descriptor.containingDeclaration.ref()}>"
else
REFERENCE_RENDERER.render(this)
render(descriptor)
internal fun IrDeclaration.renderDeclared(): String =
DECLARATION_RENDERER.renderDescriptor(this.descriptor)
internal fun DeclarationDescriptor.ref(): String =
REFERENCE_RENDERER.renderDescriptor(this)
internal fun KotlinType.render(): String =
DECLARATION_RENDERER.renderType(this)