Enum classes lowering.

This commit is contained in:
Dmitry Petrov
2016-09-28 15:11:37 +03:00
parent af76840826
commit fc754e533d
48 changed files with 1053 additions and 222 deletions
@@ -16,13 +16,13 @@
package org.jetbrains.kotlin.ir.declarations
import org.jetbrains.kotlin.descriptors.ConstructorDescriptor
import org.jetbrains.kotlin.descriptors.ClassConstructorDescriptor
interface IrConstructor : IrFunction {
override val declarationKind: IrDeclarationKind
get() = IrDeclarationKind.CONSTRUCTOR
override val descriptor: ConstructorDescriptor
override val descriptor: ClassConstructorDescriptor
}
@@ -16,6 +16,8 @@
package org.jetbrains.kotlin.ir.declarations
import org.jetbrains.kotlin.ir.util.transformFlat
interface IrDeclarationContainer {
val declarations: MutableList<IrDeclaration>
}
}
@@ -16,16 +16,18 @@
package org.jetbrains.kotlin.ir.declarations.impl
import org.jetbrains.kotlin.descriptors.ConstructorDescriptor
import org.jetbrains.kotlin.descriptors.ClassConstructorDescriptor
import org.jetbrains.kotlin.ir.declarations.IrConstructor
import org.jetbrains.kotlin.ir.declarations.IrDeclarationOrigin
import org.jetbrains.kotlin.ir.expressions.IrBody
import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
class IrConstructorImpl(startOffset: Int, endOffset: Int, origin: IrDeclarationOrigin, override val descriptor: ConstructorDescriptor) :
IrFunctionBase(startOffset, endOffset, origin), IrConstructor {
class IrConstructorImpl(
startOffset: Int, endOffset: Int, origin: IrDeclarationOrigin,
override val descriptor: ClassConstructorDescriptor
) : IrFunctionBase(startOffset, endOffset, origin), IrConstructor {
constructor(
startOffset: Int, endOffset: Int, origin: IrDeclarationOrigin, descriptor: ConstructorDescriptor,
startOffset: Int, endOffset: Int, origin: IrDeclarationOrigin, descriptor: ClassConstructorDescriptor,
body: IrBody
) : this(startOffset, endOffset, origin, descriptor) {
this.body = body
@@ -17,32 +17,27 @@
package org.jetbrains.kotlin.ir.descriptors
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
import org.jetbrains.kotlin.descriptors.ClassDescriptor
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.descriptors.annotations.Annotations
import org.jetbrains.kotlin.descriptors.impl.SimpleFunctionDescriptorImpl
import org.jetbrains.kotlin.descriptors.impl.TypeParameterDescriptorImpl
import org.jetbrains.kotlin.descriptors.impl.ValueParameterDescriptorImpl
import org.jetbrains.kotlin.incremental.components.NoLookupLocation
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.types.KotlinType
import org.jetbrains.kotlin.types.KotlinTypeFactory
import org.jetbrains.kotlin.types.TypeSubstitution
import org.jetbrains.kotlin.types.Variance
class IrBuiltIns(val builtIns: KotlinBuiltIns) {
val packageFragment = IrBuiltinsPackageFragmentDescriptorImpl(builtIns.builtInsModule)
class BuiltinsOperatorsBuilder(val packageFragment: PackageFragmentDescriptor, val builtIns: KotlinBuiltIns) {
val bool = builtIns.booleanType
val any = builtIns.anyType
val anyN = builtIns.nullableAnyType
val int = builtIns.intType
val nothing = builtIns.nothingType
val eqeqeq: FunctionDescriptor = defineOperator("EQEQEQ", bool, listOf(anyN, anyN))
val eqeq: FunctionDescriptor = defineOperator("EQEQ", bool, listOf(anyN, anyN))
val lt0: FunctionDescriptor = defineOperator("LT0", bool, listOf(int))
val lteq0: FunctionDescriptor = defineOperator("LTEQ0", bool, listOf(int))
val gt0: FunctionDescriptor = defineOperator("GT0", bool, listOf(int))
val gteq0: FunctionDescriptor = defineOperator("GTEQ0", bool, listOf(int))
val throwNpe: FunctionDescriptor = defineOperator("THROW_NPE", nothing, listOf())
val booleanNot: FunctionDescriptor = defineOperator("NOT", bool, listOf(bool))
private fun defineOperator(name: String, returnType: KotlinType, valueParameterTypes: List<KotlinType>): IrBuiltinOperatorDescriptor {
fun defineOperator(name: String, returnType: KotlinType, valueParameterTypes: List<KotlinType>): IrBuiltinOperatorDescriptor {
val operatorDescriptor = IrSimpleBuiltinOperatorDescriptorImpl(packageFragment, Name.identifier(name), returnType)
for ((i, valueParameterType) in valueParameterTypes.withIndex()) {
operatorDescriptor.addValueParameter(
@@ -50,7 +45,44 @@ class IrBuiltIns(val builtIns: KotlinBuiltIns) {
}
return operatorDescriptor
}
private fun ClassDescriptor.findSingleFunction(name: String): FunctionDescriptor =
getMemberScope(TypeSubstitution.EMPTY).getContributedFunctions(Name.identifier(name), NoLookupLocation.FROM_BUILTINS).single()
}
class IrBuiltIns(val builtIns: KotlinBuiltIns) {
private val packageFragment = IrBuiltinsPackageFragmentDescriptorImpl(builtIns.builtInsModule, KOTLIN_INTERNAL_IR_FQN)
private val builder = BuiltinsOperatorsBuilder(packageFragment, builtIns)
val eqeqeq: FunctionDescriptor = builder.run { defineOperator("EQEQEQ", bool, listOf(anyN, anyN)) }
val eqeq: FunctionDescriptor = builder.run { defineOperator("EQEQ", bool, listOf(anyN, anyN)) }
val lt0: FunctionDescriptor = builder.run { defineOperator("LT0", bool, listOf(int)) }
val lteq0: FunctionDescriptor = builder.run { defineOperator("LTEQ0", bool, listOf(int)) }
val gt0: FunctionDescriptor = builder.run { defineOperator("GT0", bool, listOf(int)) }
val gteq0: FunctionDescriptor = builder.run { defineOperator("GTEQ0", bool, listOf(int)) }
val throwNpe: FunctionDescriptor = builder.run { defineOperator("THROW_NPE", nothing, listOf()) }
val booleanNot: FunctionDescriptor = builder.run { defineOperator("NOT", bool, listOf(bool)) }
val enumValueOf: FunctionDescriptor =
SimpleFunctionDescriptorImpl.create(
packageFragment,
Annotations.EMPTY,
Name.identifier("enumValueOf"),
CallableMemberDescriptor.Kind.SYNTHESIZED,
org.jetbrains.kotlin.descriptors.SourceElement.NO_SOURCE
).apply {
val typeParameterT = TypeParameterDescriptorImpl.createWithDefaultBound(
this, Annotations.EMPTY, true, Variance.INVARIANT, Name.identifier("T"), 0
)
val valueParameterName = ValueParameterDescriptorImpl(
this, null, 0, Annotations.EMPTY, Name.identifier("name"), builtIns.stringType,
false, false, false, false, null, org.jetbrains.kotlin.descriptors.SourceElement.NO_SOURCE
)
val returnType = KotlinTypeFactory.simpleType(Annotations.EMPTY, typeParameterT.typeConstructor, listOf(), false)
initialize(null, null, listOf(typeParameterT), listOf(valueParameterName), returnType, Modality.FINAL, Visibilities.PUBLIC)
}
companion object {
val KOTLIN_INTERNAL_IR_FQN = FqName("kotlin.internal.ir")
}
}
@@ -25,9 +25,13 @@ import org.jetbrains.kotlin.types.TypeSubstitutor
interface IrBuiltinsPackageFragmentDescriptor : PackageFragmentDescriptor
class IrBuiltinsPackageFragmentDescriptorImpl(val containingModule: ModuleDescriptor) : IrBuiltinsPackageFragmentDescriptor {
override val fqName: FqName get() = FqName("kotlin.internal.ir")
override fun getName(): Name = Name.identifier("ir")
class IrBuiltinsPackageFragmentDescriptorImpl(
val containingModule: ModuleDescriptor,
override val fqName: FqName
) : IrBuiltinsPackageFragmentDescriptor {
private val shortName = fqName.shortName()
override fun getName(): Name = shortName
override fun getContainingDeclaration(): ModuleDescriptor = containingModule
@@ -17,7 +17,6 @@
package org.jetbrains.kotlin.ir.expressions
import org.jetbrains.kotlin.ir.IrElement
import org.jetbrains.kotlin.ir.IrStatement
import org.jetbrains.kotlin.ir.visitors.IrElementTransformer
interface IrBody : IrElement {
@@ -29,10 +28,6 @@ interface IrExpressionBody : IrBody {
var expression: IrExpression
}
interface IrStatementContainer {
val statements: MutableList<IrStatement>
}
interface IrBlockBody : IrBody, IrStatementContainer
interface IrSyntheticBody : IrBody {
@@ -16,9 +16,9 @@
package org.jetbrains.kotlin.ir.expressions
import org.jetbrains.kotlin.descriptors.ConstructorDescriptor
import org.jetbrains.kotlin.descriptors.ClassConstructorDescriptor
interface IrDelegatingConstructorCall : IrMemberAccessExpression {
override val descriptor: ConstructorDescriptor
override val descriptor: ClassConstructorDescriptor
}
@@ -16,15 +16,9 @@
package org.jetbrains.kotlin.ir.expressions
import org.jetbrains.kotlin.descriptors.ClassDescriptor
import org.jetbrains.kotlin.descriptors.ConstructorDescriptor
import org.jetbrains.kotlin.descriptors.ClassConstructorDescriptor
interface IrEnumConstructorCall : IrMemberAccessExpression {
override val descriptor: ConstructorDescriptor
val enumEntryDescriptor: ClassDescriptor?
override val descriptor: ClassConstructorDescriptor
}
val IrEnumConstructorCall.isSuper: Boolean
get() = enumEntryDescriptor == null
@@ -0,0 +1,23 @@
/*
* 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.IrStatement
interface IrStatementContainer {
val statements: MutableList<IrStatement>
}
@@ -21,6 +21,7 @@ import org.jetbrains.kotlin.descriptors.ClassDescriptor
import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor
import org.jetbrains.kotlin.ir.expressions.IrCall
import org.jetbrains.kotlin.ir.expressions.IrCallWithShallowCopy
import org.jetbrains.kotlin.ir.expressions.IrExpression
import org.jetbrains.kotlin.ir.expressions.IrStatementOrigin
import org.jetbrains.kotlin.ir.visitors.IrElementTransformer
import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
@@ -35,6 +36,13 @@ class IrCallImpl(
override val origin: IrStatementOrigin? = null,
override val superQualifier: ClassDescriptor? = null
) : IrCallWithIndexedArgumentsBase(startOffset, endOffset, type, descriptor.valueParameters.size, typeArguments), IrCallWithShallowCopy {
constructor(
startOffset: Int, endOffset: Int, descriptor: CallableDescriptor,
typeArguments: Map<TypeParameterDescriptor, KotlinType>? = null,
origin: IrStatementOrigin? = null,
superQualifier: ClassDescriptor? = null
) : this(startOffset, endOffset, descriptor.returnType!!, descriptor, typeArguments, origin, superQualifier)
override fun <R, D> accept(visitor: IrElementVisitor<R, D>, data: D): R =
visitor.visitCall(this, data)
@@ -16,7 +16,7 @@
package org.jetbrains.kotlin.ir.expressions.impl
import org.jetbrains.kotlin.descriptors.ConstructorDescriptor
import org.jetbrains.kotlin.descriptors.ClassConstructorDescriptor
import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor
import org.jetbrains.kotlin.ir.expressions.IrDelegatingConstructorCall
import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
@@ -26,8 +26,8 @@ import org.jetbrains.kotlin.types.KotlinType
class IrDelegatingConstructorCallImpl(
startOffset: Int,
endOffset: Int,
override val descriptor: ConstructorDescriptor,
typeArguments: Map<TypeParameterDescriptor, KotlinType>?
override val descriptor: ClassConstructorDescriptor,
typeArguments: Map<TypeParameterDescriptor, KotlinType>? = null
) : IrCallWithIndexedArgumentsBase(startOffset, endOffset, descriptor.builtIns.unitType, descriptor.valueParameters.size, typeArguments),
IrDelegatingConstructorCall {
override fun <R, D> accept(visitor: IrElementVisitor<R, D>, data: D): R {
@@ -16,8 +16,7 @@
package org.jetbrains.kotlin.ir.expressions.impl
import org.jetbrains.kotlin.descriptors.ClassDescriptor
import org.jetbrains.kotlin.descriptors.ConstructorDescriptor
import org.jetbrains.kotlin.descriptors.ClassConstructorDescriptor
import org.jetbrains.kotlin.ir.expressions.IrEnumConstructorCall
import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
import org.jetbrains.kotlin.resolve.descriptorUtil.builtIns
@@ -25,8 +24,7 @@ import org.jetbrains.kotlin.resolve.descriptorUtil.builtIns
class IrEnumConstructorCallImpl(
startOffset: Int,
endOffset: Int,
override val descriptor: ConstructorDescriptor,
override val enumEntryDescriptor: ClassDescriptor? = null
override val descriptor: ClassConstructorDescriptor
) : IrCallWithIndexedArgumentsBase(startOffset, endOffset, descriptor.builtIns.unitType, descriptor.valueParameters.size, null),
IrEnumConstructorCall {
override fun <R, D> accept(visitor: IrElementVisitor<R, D>, data: D): R {
@@ -21,6 +21,7 @@ import org.jetbrains.kotlin.ir.expressions.IrExpression
import org.jetbrains.kotlin.ir.expressions.IrReturn
import org.jetbrains.kotlin.ir.visitors.IrElementTransformer
import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
import org.jetbrains.kotlin.resolve.descriptorUtil.builtIns
import org.jetbrains.kotlin.types.KotlinType
class IrReturnImpl(
@@ -30,6 +31,9 @@ class IrReturnImpl(
override val returnTarget: CallableDescriptor,
override var value: IrExpression
) : IrExpressionBase(startOffset, endOffset, type), IrReturn {
constructor(startOffset: Int, endOffset: Int, returnTarget: CallableDescriptor, value: IrExpression) :
this(startOffset, endOffset, returnTarget.builtIns.nothingType, returnTarget, value)
override fun <R, D> accept(visitor: IrElementVisitor<R, D>, data: D): R =
visitor.visitReturn(this, data)
@@ -34,4 +34,7 @@ class IrSyntheticBodyImpl(startOffset: Int, endOffset: Int, override val kind: I
override fun <D> transformChildren(transformer: IrElementTransformer<D>, data: D) {
// no children
}
override fun toString(): String =
"IrSyntheticBodyImpl($kind)"
}
@@ -38,7 +38,7 @@ open class DeepCopyIrTree : IrElementTransformerVoid() {
protected open fun mapClassDeclaration(descriptor: ClassDescriptor) = descriptor
protected open fun mapTypeAliasDeclaration(descriptor: TypeAliasDescriptor) = descriptor
protected open fun mapFunctionDeclaration(descriptor: FunctionDescriptor) = descriptor
protected open fun mapConstructorDeclaration(descriptor: ConstructorDescriptor) = descriptor
protected open fun mapConstructorDeclaration(descriptor: ClassConstructorDescriptor) = descriptor
protected open fun mapPropertyDeclaration(descriptor: PropertyDescriptor) = descriptor
protected open fun mapLocalPropertyDeclaration(descriptor: VariableDescriptorWithAccessors) = descriptor
protected open fun mapEnumEntryDeclaration(descriptor: ClassDescriptor) = descriptor
@@ -52,9 +52,8 @@ open class DeepCopyIrTree : IrElementTransformerVoid() {
protected open fun mapPropertyReference(descriptor: PropertyDescriptor) = descriptor
protected open fun mapReceiverParameterReference(descriptor: ReceiverParameterDescriptor) = descriptor
protected open fun mapCallee(descriptor: CallableDescriptor) = descriptor
protected open fun mapDelegatedConstructorCallee(descriptor: ConstructorDescriptor) = descriptor
protected open fun mapEnumConstructorCallee(descriptor: ConstructorDescriptor) = descriptor
protected open fun mapEnumEntryInConstructor(descriptor: ClassDescriptor?) = descriptor
protected open fun mapDelegatedConstructorCallee(descriptor: ClassConstructorDescriptor) = descriptor
protected open fun mapEnumConstructorCallee(descriptor: ClassConstructorDescriptor) = descriptor
protected open fun mapCallableReference(descriptor: CallableDescriptor) = descriptor
protected open fun mapClassifierReference(descriptor: ClassifierDescriptor) = descriptor
protected open fun mapReturnTarget(descriptor: CallableDescriptor) = mapCallee(descriptor)
@@ -346,8 +345,7 @@ open class DeepCopyIrTree : IrElementTransformerVoid() {
override fun visitEnumConstructorCall(expression: IrEnumConstructorCall): IrEnumConstructorCall =
IrEnumConstructorCallImpl(
expression.startOffset, expression.endOffset,
mapEnumConstructorCallee(expression.descriptor),
mapEnumEntryInConstructor(expression.enumEntryDescriptor)
mapEnumConstructorCallee(expression.descriptor)
).transformValueArguments(expression)
override fun visitGetClass(expression: IrGetClass): IrGetClass =
@@ -119,11 +119,7 @@ class RenderIrElementVisitor : IrElementVisitor<String, Nothing?> {
"DELEGATING_CONSTRUCTOR_CALL '${expression.descriptor.ref()}'"
override fun visitEnumConstructorCall(expression: IrEnumConstructorCall, data: Nothing?): String =
"ENUM_CONSTRUCTOR_CALL '${expression.descriptor.ref()}' " +
expression.enumEntryDescriptor.let { enumEntryDescriptor ->
if (enumEntryDescriptor == null) "super"
else enumEntryDescriptor.ref()
}
"ENUM_CONSTRUCTOR_CALL '${expression.descriptor.ref()}'"
override fun visitInstanceInitializerCall(expression: IrInstanceInitializerCall, data: Nothing?): String =
"INSTANCE_INITIALIZER_CALL classDescriptor='${expression.classDescriptor.ref()}'"
@@ -0,0 +1,46 @@
/*
* 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.util
inline fun <T> MutableList<T>.transform(transformation: (T) -> T) {
forEachIndexed { i, item ->
set(i, transformation(item))
}
}
/**
* Transforms a mutable list in place.
* Each element `it` is replaced with a result of `transformation(it)`,
* `null` means "keep existing element" (to avoid creating excessive singleton lists).
*/
inline fun <T> MutableList<T>.transformFlat(transformation: (T) -> List<T>?) {
var i = 0
while (i < size) {
val item = get(i)
val transformed = transformation(item)
if (transformed == null) {
i++
continue
}
addAll(i, transformed)
i += transformed.size
removeAt(i)
}
}