[JS IR BE] Support Enum::values

This commit is contained in:
Svyatoslav Kuzmich
2018-09-28 20:23:21 +03:00
parent 0210ec3114
commit bdc3daf972
22 changed files with 43 additions and 24 deletions
@@ -102,15 +102,16 @@ private fun JsIrBackendContext.performInlining(moduleFragment: IrModuleFragment)
}
private fun JsIrBackendContext.lower(moduleFragment: IrModuleFragment, dependencies: List<IrModuleFragment>) {
<<<<<<< HEAD
moduleFragment.files.forEach(UnitMaterializationLowering(this)::lower)
moduleFragment.files.forEach(EnumClassLowering(this)::runOnFilePostfix)
moduleFragment.files.forEach(EnumUsageLowering(this)::lower)
moduleFragment.files.forEach(VarargLowering(this)::lower)
moduleFragment.files.forEach(LateinitLowering(this, true)::lower)
moduleFragment.files.forEach(DefaultArgumentStubGenerator(this)::runOnFilePostfix)
moduleFragment.files.forEach(DefaultParameterInjector(this)::runOnFilePostfix)
moduleFragment.files.forEach(DefaultParameterCleaner(this)::runOnFilePostfix)
moduleFragment.files.forEach(SharedVariablesLowering(this)::runOnFilePostfix)
moduleFragment.files.forEach(EnumClassLowering(this)::runOnFilePostfix)
moduleFragment.files.forEach(EnumUsageLowering(this)::lower)
moduleFragment.files.forEach(ReturnableBlockLowering(this)::lower)
moduleFragment.files.forEach(LocalDelegatedPropertiesLowering()::lower)
moduleFragment.files.forEach(LocalDeclarationsLowering(this)::runOnFilePostfix)
@@ -12,12 +12,15 @@ import org.jetbrains.kotlin.backend.common.ir.copyParameterDeclarationsFrom
import org.jetbrains.kotlin.backend.common.lower.createIrBuilder
import org.jetbrains.kotlin.backend.common.lower.irBlockBody
import org.jetbrains.kotlin.backend.common.lower.irIfThen
import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET
import org.jetbrains.kotlin.ir.backend.js.JsIrBackendContext
import org.jetbrains.kotlin.ir.backend.js.ir.JsIrBuilder
import org.jetbrains.kotlin.ir.builders.*
import org.jetbrains.kotlin.ir.declarations.*
import org.jetbrains.kotlin.ir.declarations.impl.IrConstructorImpl
import org.jetbrains.kotlin.ir.expressions.*
import org.jetbrains.kotlin.ir.expressions.impl.IrCallImpl
import org.jetbrains.kotlin.ir.expressions.impl.IrVarargImpl
import org.jetbrains.kotlin.ir.symbols.IrConstructorSymbol
import org.jetbrains.kotlin.ir.symbols.IrValueParameterSymbol
import org.jetbrains.kotlin.ir.symbols.impl.IrConstructorSymbolImpl
@@ -144,6 +147,34 @@ class EnumClassTransformer(val context: JsIrBackendContext, private val irClass:
}
}
private fun List<IrExpression>.toArrayLiteral(arrayType: IrType, elementType: IrType): IrExpression {
val startOffset = firstOrNull()?.startOffset ?: UNDEFINED_OFFSET
val endOffset = lastOrNull()?.endOffset ?: UNDEFINED_OFFSET
val irVararg = IrVarargImpl(startOffset, endOffset, arrayType, elementType, this)
return IrCallImpl(startOffset, endOffset, arrayType, context.intrinsics.arrayLiteral).apply {
putValueArgument(0, irVararg)
}
}
private fun createEnumValuesBody(): IrBody {
val valuesFun = findFunctionDescriptorForMemberWithSyntheticBodyKind(IrSyntheticBodyKind.ENUM_VALUES)
val entryInstanceToFunction = context.enumEntryToGetInstanceFunction
return context.createIrBuilder(valuesFun.symbol).run {
irBlockBody {
+irReturn(
enumEntries.map {
val function = entryInstanceToFunction[it.symbol]!!
irCall(function)
}.toArrayLiteral(valuesFun.returnType, irClass.defaultType)
)
}
}
}
private fun lowerEnumConstructorsSignature() {
irClass.declarations.transform { declaration ->
if (declaration is IrConstructor) {
@@ -199,7 +230,7 @@ class EnumClassTransformer(val context: JsIrBackendContext, private val irClass:
irClass.transformChildrenVoid(object : IrElementTransformerVoid() {
override fun visitSyntheticBody(body: IrSyntheticBody): IrBody {
return when (body.kind) {
IrSyntheticBodyKind.ENUM_VALUES -> builder.irBlockBody { } // TODO: Implement
IrSyntheticBodyKind.ENUM_VALUES -> createEnumValuesBody()
IrSyntheticBodyKind.ENUM_VALUEOF -> createEnumValueOfBody()
}
}
@@ -176,6 +176,11 @@ class SimpleNameGenerator : NameGenerator {
}
is IrSimpleFunction -> {
if (declaration.dispatchReceiverParameter == null && declaration.parent is IrClass) {
nameBuilder.append(getNameForDeclaration(declaration.parent as IrDeclaration, context))
nameBuilder.append('.')
}
nameBuilder.append(declaration.name.asString())
declaration.extensionReceiverParameter?.let { nameBuilder.append("_\$${it.type.render()}") }
declaration.typeParameters.forEach { nameBuilder.append("_${it.name.asString()}") }
@@ -1,4 +1,3 @@
// IGNORE_BACKEND: JS_IR
// WITH_RUNTIME
enum class ResultType constructor(val reason: String) {
@@ -1,5 +1,4 @@
// IGNORE_BACKEND: JS_IR
// TODO: muted automatically, investigate should it be ran for JS or not
// IGNORE_BACKEND: JS, NATIVE
// WITH_RUNTIME
@@ -1,4 +1,3 @@
// IGNORE_BACKEND: JS_IR
enum class Game {
ROCK,
PAPER,
@@ -1,4 +1,3 @@
// IGNORE_BACKEND: JS_IR
enum class Test(vararg xs: Int) {
OK;
val values = xs
@@ -1,4 +1,3 @@
// IGNORE_BACKEND: JS_IR
enum class Test(val x: Int, val str: String) {
OK;
constructor(vararg xs: Int) : this(xs.size + 42, "OK")
@@ -1,4 +1,3 @@
// IGNORE_BACKEND: JS_IR
enum class Empty
fun box(): String {
-1
View File
@@ -1,6 +1,5 @@
// IGNORE_BACKEND: JVM_IR
// IGNORE_BACKEND: JS_IR
// TODO: muted automatically, investigate should it be ran for JS or not
// IGNORE_BACKEND: JS, NATIVE
// WITH_RUNTIME
@@ -1,5 +1,4 @@
// IGNORE_BACKEND: JS_IR
// TODO: muted automatically, investigate should it be ran for JS or not
// IGNORE_BACKEND: JS, NATIVE
// WITH_RUNTIME
-1
View File
@@ -1,4 +1,3 @@
// IGNORE_BACKEND: JS_IR
// WITH_RUNTIME
import Game.*
-1
View File
@@ -1,4 +1,3 @@
// IGNORE_BACKEND: JS_IR
enum class Color {
RED,
BLUE
@@ -1,6 +1,5 @@
// !LANGUAGE: +NestedClassesInAnnotations
// IGNORE_BACKEND: JVM_IR
// IGNORE_BACKEND: JS_IR
// WITH_RUNTIME
import kotlin.test.*
@@ -1,4 +1,3 @@
// IGNORE_BACKEND: JS_IR
// TODO: muted automatically, investigate should it be ran for JS or not
// IGNORE_BACKEND: JS, NATIVE
@@ -1,5 +1,4 @@
// IGNORE_BACKEND: JVM_IR
// IGNORE_BACKEND: JS_IR
// TODO: muted automatically, investigate should it be ran for JS or not
// IGNORE_BACKEND: JS, NATIVE
@@ -1,4 +1,3 @@
// IGNORE_BACKEND: JS_IR
enum class Variants {
O, K;
companion object {
@@ -1,4 +1,3 @@
// IGNORE_BACKEND: JS_IR
// EXPECTED_REACHABLE_NODES: 1291
package foo
@@ -1,4 +1,3 @@
// IGNORE_BACKEND: JS_IR
// EXPECTED_REACHABLE_NODES: 1295
package foo
-1
View File
@@ -1,4 +1,3 @@
// IGNORE_BACKEND: JS_IR
// EXPECTED_REACHABLE_NODES: 1555
package foo
+2 -2
View File
@@ -5,9 +5,9 @@
package kotlin
public class Enum<T : Enum<T>>(val name: String, val ordinal: Int) : Comparable<Enum<T>> {
public class Enum<E : Enum<E>>(val name: String, val ordinal: Int) : Comparable<E> {
override fun compareTo(other: Enum<T>) = ordinal.compareTo(other.ordinal)
override fun compareTo(other: E) = ordinal.compareTo(other.ordinal)
override fun equals(other: Any?) = this === other
+1 -2
View File
@@ -85,5 +85,4 @@ fun getNumberHashCode(obj: dynamic) = js("""
}
""").unsafeCast<Int>()
// TODO: Use getObjectHashCode instead
fun identityHashCode(obj: dynamic): Int = hashCode(obj)
fun identityHashCode(obj: dynamic): Int = getObjectHashCode(obj)