[JS IR BE] Reflection support
This commit is contained in:
+2
@@ -26,6 +26,8 @@ fun IrType.isInterface() = toKotlinType().isInterface()
|
|||||||
|
|
||||||
fun IrType.isPrimitiveArray() = KotlinBuiltIns.isPrimitiveArray(toKotlinType())
|
fun IrType.isPrimitiveArray() = KotlinBuiltIns.isPrimitiveArray(toKotlinType())
|
||||||
|
|
||||||
|
fun IrType.getPrimitiveArrayElementType() = KotlinBuiltIns.getPrimitiveArrayElementType(toKotlinType())
|
||||||
|
|
||||||
fun IrType.isTypeParameter() = toKotlinType().isTypeParameter()
|
fun IrType.isTypeParameter() = toKotlinType().isTypeParameter()
|
||||||
|
|
||||||
fun IrType.isFunctionOrKFunction() = toKotlinType().isFunctionOrKFunctionType
|
fun IrType.isFunctionOrKFunction() = toKotlinType().isFunctionOrKFunctionType
|
||||||
|
|||||||
@@ -6,6 +6,7 @@
|
|||||||
package org.jetbrains.kotlin.ir.backend.js
|
package org.jetbrains.kotlin.ir.backend.js
|
||||||
|
|
||||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
||||||
|
import org.jetbrains.kotlin.builtins.PrimitiveType
|
||||||
import org.jetbrains.kotlin.descriptors.*
|
import org.jetbrains.kotlin.descriptors.*
|
||||||
import org.jetbrains.kotlin.descriptors.annotations.Annotations
|
import org.jetbrains.kotlin.descriptors.annotations.Annotations
|
||||||
import org.jetbrains.kotlin.descriptors.impl.SimpleFunctionDescriptorImpl
|
import org.jetbrains.kotlin.descriptors.impl.SimpleFunctionDescriptorImpl
|
||||||
@@ -118,11 +119,21 @@ class JsIntrinsics(
|
|||||||
// val isCharSymbol = getInternalFunction("isChar")
|
// val isCharSymbol = getInternalFunction("isChar")
|
||||||
val isObjectSymbol = getInternalFunction("isObject")
|
val isObjectSymbol = getInternalFunction("isObject")
|
||||||
|
|
||||||
|
val isPrimitiveArray = mapOf(
|
||||||
|
PrimitiveType.BOOLEAN to getInternalFunction("isBooleanArray"),
|
||||||
|
PrimitiveType.BYTE to getInternalFunction("isByteArray"),
|
||||||
|
PrimitiveType.SHORT to getInternalFunction("isShortArray"),
|
||||||
|
PrimitiveType.CHAR to getInternalFunction("isCharArray"),
|
||||||
|
PrimitiveType.INT to getInternalFunction("isIntArray"),
|
||||||
|
PrimitiveType.FLOAT to getInternalFunction("isFloatArray"),
|
||||||
|
PrimitiveType.LONG to getInternalFunction("isLongArray"),
|
||||||
|
PrimitiveType.DOUBLE to getInternalFunction("isLongArray")
|
||||||
|
)
|
||||||
|
|
||||||
// Other:
|
// Other:
|
||||||
|
|
||||||
val jsObjectCreate = defineObjectCreateIntrinsic() // Object.create
|
val jsObjectCreate = defineObjectCreateIntrinsic() // Object.create
|
||||||
val jsSetJSField = defineSetJSPropertyIntrinsic() // till we don't have dynamic type we use intrinsic which sets a field with any name
|
val jsSetJSField = defineSetJSPropertyIntrinsic() // till we don't have dynamic type we use intrinsic which sets a field with any name
|
||||||
val jsToJsType = defineToJsType() // creates name reference to KotlinType
|
|
||||||
val jsCode = getInternalFunction("js") // js("<code>")
|
val jsCode = getInternalFunction("js") // js("<code>")
|
||||||
val jsHashCode = getInternalFunction("hashCode")
|
val jsHashCode = getInternalFunction("hashCode")
|
||||||
val jsGetObjectHashCode = getInternalFunction("getObjectHashCode")
|
val jsGetObjectHashCode = getInternalFunction("getObjectHashCode")
|
||||||
@@ -139,6 +150,10 @@ class JsIntrinsics(
|
|||||||
val f = getInternalFunctions("getContinuation")
|
val f = getInternalFunctions("getContinuation")
|
||||||
symbolTable.referenceSimpleFunction(f.single())
|
symbolTable.referenceSimpleFunction(f.single())
|
||||||
}
|
}
|
||||||
|
val jsGetKClass = getInternalWithoutPackage("getKClass")
|
||||||
|
val jsGetKClassFromExpression = getInternalWithoutPackage("getKClassFromExpression")
|
||||||
|
val jsClass = getInternalFunction("jsClass")
|
||||||
|
|
||||||
val jsNumberRangeToNumber = getInternalFunction("numberRangeToNumber")
|
val jsNumberRangeToNumber = getInternalFunction("numberRangeToNumber")
|
||||||
val jsNumberRangeToLong = getInternalFunction("numberRangeToLong")
|
val jsNumberRangeToLong = getInternalFunction("numberRangeToLong")
|
||||||
|
|
||||||
@@ -162,28 +177,9 @@ class JsIntrinsics(
|
|||||||
private fun getInternalFunction(name: String) =
|
private fun getInternalFunction(name: String) =
|
||||||
context.symbolTable.referenceSimpleFunction(context.getInternalFunctions(name).single())
|
context.symbolTable.referenceSimpleFunction(context.getInternalFunctions(name).single())
|
||||||
|
|
||||||
private fun defineToJsType(): IrSimpleFunction {
|
private fun getInternalWithoutPackage(name: String) =
|
||||||
val desc = SimpleFunctionDescriptorImpl.create(
|
context.symbolTable.referenceSimpleFunction(context.getFunctions(FqName(name)).single())
|
||||||
module,
|
|
||||||
Annotations.EMPTY,
|
|
||||||
Name.identifier("\$toJSType\$"),
|
|
||||||
CallableMemberDescriptor.Kind.SYNTHESIZED,
|
|
||||||
SourceElement.NO_SOURCE
|
|
||||||
).apply {
|
|
||||||
|
|
||||||
val typeParameter = TypeParameterDescriptorImpl.createWithDefaultBound(
|
|
||||||
this,
|
|
||||||
Annotations.EMPTY,
|
|
||||||
false,
|
|
||||||
Variance.INVARIANT,
|
|
||||||
Name.identifier("T"),
|
|
||||||
0
|
|
||||||
)
|
|
||||||
initialize(null, null, listOf(typeParameter), emptyList(), builtIns.anyType, Modality.FINAL, Visibilities.PUBLIC)
|
|
||||||
}
|
|
||||||
|
|
||||||
return stubBuilder.generateFunctionStub(desc)
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: unify how we create intrinsic symbols
|
// TODO: unify how we create intrinsic symbols
|
||||||
private fun defineObjectCreateIntrinsic(): IrSimpleFunction {
|
private fun defineObjectCreateIntrinsic(): IrSimpleFunction {
|
||||||
|
|||||||
@@ -114,6 +114,7 @@ private fun JsIrBackendContext.lower(moduleFragment: IrModuleFragment) {
|
|||||||
moduleFragment.files.forEach(clble.getReferenceCollector())
|
moduleFragment.files.forEach(clble.getReferenceCollector())
|
||||||
moduleFragment.files.forEach(clble.getClosureBuilder())
|
moduleFragment.files.forEach(clble.getClosureBuilder())
|
||||||
moduleFragment.files.forEach(clble.getReferenceReplacer())
|
moduleFragment.files.forEach(clble.getReferenceReplacer())
|
||||||
|
moduleFragment.files.forEach(ClassReferenceLowering(this)::lower)
|
||||||
moduleFragment.files.forEach(IntrinsicifyCallsLowering(this)::lower)
|
moduleFragment.files.forEach(IntrinsicifyCallsLowering(this)::lower)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+53
@@ -0,0 +1,53 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
|
||||||
|
* that can be found in the license/LICENSE.txt file.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jetbrains.kotlin.ir.backend.js.lower
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.backend.common.FileLoweringPass
|
||||||
|
import org.jetbrains.kotlin.ir.backend.js.JsIrBackendContext
|
||||||
|
import org.jetbrains.kotlin.ir.backend.js.ir.JsIrBuilder
|
||||||
|
import org.jetbrains.kotlin.ir.declarations.IrFile
|
||||||
|
import org.jetbrains.kotlin.ir.expressions.IrClassReference
|
||||||
|
import org.jetbrains.kotlin.ir.expressions.IrExpression
|
||||||
|
import org.jetbrains.kotlin.ir.expressions.IrGetClass
|
||||||
|
import org.jetbrains.kotlin.ir.types.IrType
|
||||||
|
import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid
|
||||||
|
import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid
|
||||||
|
|
||||||
|
class ClassReferenceLowering(val context: JsIrBackendContext) : FileLoweringPass {
|
||||||
|
private val intrinsics = context.intrinsics
|
||||||
|
|
||||||
|
private fun callGetKClassFromExpression(returnType: IrType, typeArgument: IrType, argument: IrExpression) =
|
||||||
|
JsIrBuilder.buildCall(intrinsics.jsGetKClassFromExpression, returnType, listOf(typeArgument)).apply {
|
||||||
|
putValueArgument(0, argument)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun callGetKClass(returnType: IrType, typeArgument: IrType, argument: IrExpression) =
|
||||||
|
JsIrBuilder.buildCall(intrinsics.jsGetKClass, returnType, listOf(typeArgument)).apply {
|
||||||
|
putValueArgument(0, argument)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun callJsClass(type: IrType) =
|
||||||
|
JsIrBuilder.buildCall(intrinsics.jsClass, typeArguments = listOf(type))
|
||||||
|
|
||||||
|
override fun lower(irFile: IrFile) {
|
||||||
|
irFile.transformChildrenVoid(object : IrElementTransformerVoid() {
|
||||||
|
override fun visitGetClass(expression: IrGetClass) =
|
||||||
|
callGetKClassFromExpression(
|
||||||
|
returnType = expression.type,
|
||||||
|
typeArgument = expression.argument.type,
|
||||||
|
argument = expression.argument.transform(this, null)
|
||||||
|
)
|
||||||
|
|
||||||
|
override fun visitClassReference(expression: IrClassReference) =
|
||||||
|
callGetKClass(
|
||||||
|
returnType = expression.type,
|
||||||
|
typeArgument = expression.classType,
|
||||||
|
argument = callJsClass(expression.classType)
|
||||||
|
)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
+4
-3
@@ -325,9 +325,10 @@ class IntrinsicifyCallsLowering(private val context: JsIrBackendContext) : FileL
|
|||||||
|
|
||||||
// assignment to a property
|
// assignment to a property
|
||||||
IrStatementOrigin.EQ -> {
|
IrStatementOrigin.EQ -> {
|
||||||
val fieldSymbol = IrFieldSymbolImpl((symbol.descriptor as PropertyAccessorDescriptor).correspondingProperty)
|
if (symbol.descriptor is PropertyAccessorDescriptor) {
|
||||||
return JsIrBuilder.buildSetField(fieldSymbol, call.dispatchReceiver, call.getValueArgument(0)!!, call.type)
|
val fieldSymbol = IrFieldSymbolImpl((symbol.descriptor as PropertyAccessorDescriptor).correspondingProperty)
|
||||||
|
return JsIrBuilder.buildSetField(fieldSymbol, call.dispatchReceiver, call.getValueArgument(0)!!, call.type)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+4
-3
@@ -50,7 +50,7 @@ class TypeOperatorLowering(val context: JsIrBackendContext) : FileLoweringPass {
|
|||||||
|
|
||||||
private val instanceOfIntrinsicSymbol = context.intrinsics.jsInstanceOf.symbol
|
private val instanceOfIntrinsicSymbol = context.intrinsics.jsInstanceOf.symbol
|
||||||
private val typeOfIntrinsicSymbol = context.intrinsics.jsTypeOf.symbol
|
private val typeOfIntrinsicSymbol = context.intrinsics.jsTypeOf.symbol
|
||||||
private val toJSTypeIntrinsicSymbol = context.intrinsics.jsToJsType.symbol
|
private val jsClassIntrinsicSymbol = context.intrinsics.jsClass
|
||||||
|
|
||||||
private val stringMarker = JsIrBuilder.buildString(context.irBuiltIns.stringType, "string")
|
private val stringMarker = JsIrBuilder.buildString(context.irBuiltIns.stringType, "string")
|
||||||
private val booleanMarker = JsIrBuilder.buildString(context.irBuiltIns.stringType, "boolean")
|
private val booleanMarker = JsIrBuilder.buildString(context.irBuiltIns.stringType, "boolean")
|
||||||
@@ -241,13 +241,14 @@ class TypeOperatorLowering(val context: JsIrBackendContext) : FileLoweringPass {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun wrapTypeReference(toType: IrType) =
|
private fun wrapTypeReference(toType: IrType) =
|
||||||
JsIrBuilder.buildCall(toJSTypeIntrinsicSymbol).apply { putTypeArgument(0, toType) }
|
JsIrBuilder.buildCall(jsClassIntrinsicSymbol).apply { putTypeArgument(0, toType) }
|
||||||
|
|
||||||
private fun generateGenericArrayCheck(argument: IrExpression) =
|
private fun generateGenericArrayCheck(argument: IrExpression) =
|
||||||
JsIrBuilder.buildCall(isArraySymbol).apply { putValueArgument(0, argument) }
|
JsIrBuilder.buildCall(isArraySymbol).apply { putValueArgument(0, argument) }
|
||||||
|
|
||||||
private fun generatePrimitiveArrayTypeCheck(argument: IrExpression, toType: IrType): IrExpression {
|
private fun generatePrimitiveArrayTypeCheck(argument: IrExpression, toType: IrType): IrExpression {
|
||||||
TODO("Implement Typed Array check")
|
val f = context.intrinsics.isPrimitiveArray[toType.getPrimitiveArrayElementType()]!!
|
||||||
|
return JsIrBuilder.buildCall(f).apply { putValueArgument(0, argument) }
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun generateInterfaceCheck(argument: IrExpression, toType: IrType): IrExpression {
|
private fun generateInterfaceCheck(argument: IrExpression, toType: IrType): IrExpression {
|
||||||
|
|||||||
+10
@@ -23,6 +23,7 @@ import org.jetbrains.kotlin.ir.types.classifierOrFail
|
|||||||
import org.jetbrains.kotlin.ir.types.isAny
|
import org.jetbrains.kotlin.ir.types.isAny
|
||||||
import org.jetbrains.kotlin.ir.util.defaultType
|
import org.jetbrains.kotlin.ir.util.defaultType
|
||||||
import org.jetbrains.kotlin.ir.util.isInterface
|
import org.jetbrains.kotlin.ir.util.isInterface
|
||||||
|
import org.jetbrains.kotlin.ir.util.isObject
|
||||||
import org.jetbrains.kotlin.ir.util.isReal
|
import org.jetbrains.kotlin.ir.util.isReal
|
||||||
import org.jetbrains.kotlin.ir.util.resolveFakeOverride
|
import org.jetbrains.kotlin.ir.util.resolveFakeOverride
|
||||||
import org.jetbrains.kotlin.js.backend.ast.*
|
import org.jetbrains.kotlin.js.backend.ast.*
|
||||||
@@ -158,6 +159,15 @@ class JsClassGenerator(private val irClass: IrClass, val context: JsGenerationCo
|
|||||||
metadataLiteral.propertyInitializers += simpleNameProp
|
metadataLiteral.propertyInitializers += simpleNameProp
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val classKind = JsStringLiteral(
|
||||||
|
when {
|
||||||
|
irClass.isInterface -> "interface"
|
||||||
|
irClass.isObject -> "object"
|
||||||
|
else -> "class"
|
||||||
|
}
|
||||||
|
)
|
||||||
|
metadataLiteral.propertyInitializers += JsPropertyInitializer(JsNameRef(Namer.METADATA_CLASS_KIND), classKind)
|
||||||
|
|
||||||
metadataLiteral.propertyInitializers += generateSuperClasses()
|
metadataLiteral.propertyInitializers += generateSuperClasses()
|
||||||
return jsAssignment(JsNameRef(Namer.METADATA, classNameRef), metadataLiteral).makeStmt()
|
return jsAssignment(JsNameRef(Namer.METADATA, classNameRef), metadataLiteral).makeStmt()
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -90,7 +90,7 @@ class JsIntrinsicTransformers(backendContext: JsIrBackendContext) {
|
|||||||
jsAssignment(JsNameRef(fieldNameLiteral, receiver), fieldValue)
|
jsAssignment(JsNameRef(fieldNameLiteral, receiver), fieldValue)
|
||||||
}
|
}
|
||||||
|
|
||||||
add(intrinsics.jsToJsType) { call, context ->
|
add(intrinsics.jsClass) { call, context ->
|
||||||
val typeName = context.getNameForSymbol(call.getTypeArgument(0)!!.classifierOrFail)
|
val typeName = context.getNameForSymbol(call.getTypeArgument(0)!!.classifierOrFail)
|
||||||
typeName.makeRef()
|
typeName.makeRef()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
// IGNORE_BACKEND: JS_IR
|
|
||||||
operator fun Int.compareTo(c: Char) = 0
|
operator fun Int.compareTo(c: Char) = 0
|
||||||
|
|
||||||
fun foo(x: Int, y: Char): String {
|
fun foo(x: Int, y: Char): String {
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
// !LANGUAGE: +ProperIeee754Comparisons
|
// !LANGUAGE: +ProperIeee754Comparisons
|
||||||
// IGNORE_BACKEND: JS_IR
|
|
||||||
operator fun Int.compareTo(c: Char) = 0
|
operator fun Int.compareTo(c: Char) = 0
|
||||||
|
|
||||||
fun foo(x: Int, y: Char): String {
|
fun foo(x: Int, y: Char): String {
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
// !LANGUAGE: +ProperIeee754Comparisons
|
// !LANGUAGE: +ProperIeee754Comparisons
|
||||||
// IGNORE_BACKEND: JS_IR
|
|
||||||
class C {
|
class C {
|
||||||
operator fun Int.compareTo(c: Char) = 0
|
operator fun Int.compareTo(c: Char) = 0
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
// IGNORE_BACKEND: JS_IR
|
|
||||||
// WITH_RUNTIME
|
// WITH_RUNTIME
|
||||||
|
|
||||||
import kotlin.test.assertEquals
|
import kotlin.test.assertEquals
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
// IGNORE_BACKEND: JVM_IR
|
// IGNORE_BACKEND: JVM_IR
|
||||||
// IGNORE_BACKEND: JS_IR
|
|
||||||
// IGNORE_BACKEND: NATIVE
|
// IGNORE_BACKEND: NATIVE
|
||||||
|
|
||||||
class Generic<P : Any>(val p: P)
|
class Generic<P : Any>(val p: P)
|
||||||
|
|||||||
-1
@@ -1,4 +1,3 @@
|
|||||||
// IGNORE_BACKEND: JS_IR
|
|
||||||
class B
|
class B
|
||||||
|
|
||||||
fun B.magic() {
|
fun B.magic() {
|
||||||
|
|||||||
-1
@@ -1,5 +1,4 @@
|
|||||||
// IGNORE_BACKEND: JVM_IR
|
// IGNORE_BACKEND: JVM_IR
|
||||||
// IGNORE_BACKEND: JS_IR
|
|
||||||
// See KT-12337 Reference to property with invisible setter should not be a KMutableProperty
|
// See KT-12337 Reference to property with invisible setter should not be a KMutableProperty
|
||||||
|
|
||||||
import kotlin.reflect.KProperty1
|
import kotlin.reflect.KProperty1
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
// IGNORE_BACKEND: JS_IR
|
|
||||||
// IGNORE_BACKEND: NATIVE
|
// IGNORE_BACKEND: NATIVE
|
||||||
// KT-16291 Smart cast doesn't work when getting class of instance
|
// KT-16291 Smart cast doesn't work when getting class of instance
|
||||||
|
|
||||||
|
|||||||
Vendored
-1
@@ -1,4 +1,3 @@
|
|||||||
// IGNORE_BACKEND: JS_IR
|
|
||||||
// WITH_RUNTIME
|
// WITH_RUNTIME
|
||||||
|
|
||||||
fun box(): String {
|
fun box(): String {
|
||||||
|
|||||||
-1
@@ -1,4 +1,3 @@
|
|||||||
// IGNORE_BACKEND: JS_IR
|
|
||||||
// WITH_RUNTIME
|
// WITH_RUNTIME
|
||||||
|
|
||||||
fun box(): String {
|
fun box(): String {
|
||||||
|
|||||||
Vendored
-1
@@ -1,4 +1,3 @@
|
|||||||
// IGNORE_BACKEND: JS_IR
|
|
||||||
// WITH_RUNTIME
|
// WITH_RUNTIME
|
||||||
|
|
||||||
fun box(): String {
|
fun box(): String {
|
||||||
|
|||||||
Vendored
-1
@@ -1,4 +1,3 @@
|
|||||||
// IGNORE_BACKEND: JS_IR
|
|
||||||
// WITH_RUNTIME
|
// WITH_RUNTIME
|
||||||
|
|
||||||
class Host(var value: String) {
|
class Host(var value: String) {
|
||||||
|
|||||||
-1
@@ -1,4 +1,3 @@
|
|||||||
// IGNORE_BACKEND: JS_IR
|
|
||||||
// WITH_RUNTIME
|
// WITH_RUNTIME
|
||||||
|
|
||||||
fun box(): String {
|
fun box(): String {
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
// IGNORE_BACKEND: JVM_IR
|
// IGNORE_BACKEND: JVM_IR
|
||||||
// IGNORE_BACKEND: JS_IR
|
|
||||||
//WITH_RUNTIME
|
//WITH_RUNTIME
|
||||||
class Test {
|
class Test {
|
||||||
|
|
||||||
|
|||||||
Vendored
-1
@@ -1,5 +1,4 @@
|
|||||||
// IGNORE_BACKEND: JVM_IR
|
// IGNORE_BACKEND: JVM_IR
|
||||||
// IGNORE_BACKEND: JS_IR
|
|
||||||
// WITH_RUNTIME
|
// WITH_RUNTIME
|
||||||
|
|
||||||
fun box(): String {
|
fun box(): String {
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
// IGNORE_BACKEND: JVM_IR
|
// IGNORE_BACKEND: JVM_IR
|
||||||
// IGNORE_BACKEND: JS_IR
|
|
||||||
// WITH_RUNTIME
|
// WITH_RUNTIME
|
||||||
|
|
||||||
fun box(): String {
|
fun box(): String {
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
// IGNORE_BACKEND: JVM_IR
|
// IGNORE_BACKEND: JVM_IR
|
||||||
// IGNORE_BACKEND: JS_IR
|
|
||||||
enum class Test(val x: String, val closure1: () -> String) {
|
enum class Test(val x: String, val closure1: () -> String) {
|
||||||
FOO("O", run { { FOO.x } }) {
|
FOO("O", run { { FOO.x } }) {
|
||||||
override val y: String = "K"
|
override val y: String = "K"
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
// IGNORE_BACKEND: JVM_IR
|
// IGNORE_BACKEND: JVM_IR
|
||||||
// IGNORE_BACKEND: JS_IR
|
|
||||||
enum class X {
|
enum class X {
|
||||||
B {
|
B {
|
||||||
val value2 = "K"
|
val value2 = "K"
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
// IGNORE_BACKEND: JS_IR
|
|
||||||
fun test1(f: (Int) -> Int) = f(1)
|
fun test1(f: (Int) -> Int) = f(1)
|
||||||
|
|
||||||
fun test2(f: Int.() -> Int) = 2.f()
|
fun test2(f: Int.() -> Int) = 2.f()
|
||||||
|
|||||||
-1
@@ -1,4 +1,3 @@
|
|||||||
// IGNORE_BACKEND: JS_IR
|
|
||||||
fun box(): String {
|
fun box(): String {
|
||||||
var s = ""
|
var s = ""
|
||||||
var foo = "O"
|
var foo = "O"
|
||||||
|
|||||||
-1
@@ -1,4 +1,3 @@
|
|||||||
// IGNORE_BACKEND: JS_IR
|
|
||||||
fun box(): String {
|
fun box(): String {
|
||||||
fun foo(x: String) = x
|
fun foo(x: String) = x
|
||||||
fun foo() = foo("K")
|
fun foo() = foo("K")
|
||||||
|
|||||||
-1
@@ -1,4 +1,3 @@
|
|||||||
// IGNORE_BACKEND: JS_IR
|
|
||||||
fun box(): String {
|
fun box(): String {
|
||||||
var s = ""
|
var s = ""
|
||||||
|
|
||||||
|
|||||||
-1
@@ -1,4 +1,3 @@
|
|||||||
// IGNORE_BACKEND: JS_IR
|
|
||||||
fun box(): String {
|
fun box(): String {
|
||||||
var s = ""
|
var s = ""
|
||||||
var foo = "K"
|
var foo = "K"
|
||||||
|
|||||||
-1
@@ -1,4 +1,3 @@
|
|||||||
// IGNORE_BACKEND: JS_IR
|
|
||||||
fun box(): String {
|
fun box(): String {
|
||||||
var s = ""
|
var s = ""
|
||||||
var foo = "O"
|
var foo = "O"
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
// !LANGUAGE: +InlineClasses
|
// !LANGUAGE: +InlineClasses
|
||||||
// IGNORE_BACKEND: JVM_IR
|
// IGNORE_BACKEND: JVM_IR
|
||||||
// IGNORE_BACKEND: JS_IR
|
|
||||||
|
|
||||||
inline class Foo<T>(val x: Any) {
|
inline class Foo<T>(val x: Any) {
|
||||||
fun bar() {}
|
fun bar() {}
|
||||||
|
|||||||
+1
-1
@@ -1,5 +1,5 @@
|
|||||||
// !LANGUAGE: +InlineClasses
|
// !LANGUAGE: +InlineClasses
|
||||||
// IGNORE_BACKEND: JVM_IR, JS_IR
|
// IGNORE_BACKEND: JVM_IR
|
||||||
|
|
||||||
inline class SuccessOrFailure<out T>(val value: Any?) {
|
inline class SuccessOrFailure<out T>(val value: Any?) {
|
||||||
val isFailure: Boolean get() = value is Failure
|
val isFailure: Boolean get() = value is Failure
|
||||||
|
|||||||
-1
@@ -1,4 +1,3 @@
|
|||||||
// IGNORE_BACKEND: JS_IR
|
|
||||||
abstract class Base(val fn: () -> String)
|
abstract class Base(val fn: () -> String)
|
||||||
|
|
||||||
class Host {
|
class Host {
|
||||||
|
|||||||
-1
@@ -1,4 +1,3 @@
|
|||||||
// IGNORE_BACKEND: JS_IR
|
|
||||||
abstract class Base(val fn: () -> String)
|
abstract class Base(val fn: () -> String)
|
||||||
|
|
||||||
interface Host {
|
interface Host {
|
||||||
|
|||||||
Vendored
-1
@@ -1,4 +1,3 @@
|
|||||||
// IGNORE_BACKEND: JS_IR
|
|
||||||
abstract class Base(val fn: () -> String)
|
abstract class Base(val fn: () -> String)
|
||||||
|
|
||||||
object Test : Base(run { { Test.ok() } }) {
|
object Test : Base(run { { Test.ok() } }) {
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
// IGNORE_BACKEND: JS_IR
|
|
||||||
// LANGUAGE_VERSION: 1.2
|
// LANGUAGE_VERSION: 1.2
|
||||||
|
|
||||||
fun box(): String {
|
fun box(): String {
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
// IGNORE_BACKEND: JS_IR
|
|
||||||
// WITH_RUNTIME
|
// WITH_RUNTIME
|
||||||
|
|
||||||
import kotlin.test.assertEquals
|
import kotlin.test.assertEquals
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
// IGNORE_BACKEND: JS_IR
|
|
||||||
// WITH_RUNTIME
|
// WITH_RUNTIME
|
||||||
|
|
||||||
import kotlin.test.assertEquals
|
import kotlin.test.assertEquals
|
||||||
|
|||||||
-1
@@ -1,4 +1,3 @@
|
|||||||
// IGNORE_BACKEND: JS_IR
|
|
||||||
// WITH_RUNTIME
|
// WITH_RUNTIME
|
||||||
|
|
||||||
const val M = 0.toChar()
|
const val M = 0.toChar()
|
||||||
|
|||||||
-1
@@ -1,4 +1,3 @@
|
|||||||
// IGNORE_BACKEND: JS_IR
|
|
||||||
// TODO: muted automatically, investigate should it be ran for JS or not
|
// TODO: muted automatically, investigate should it be ran for JS or not
|
||||||
// IGNORE_BACKEND: JS, NATIVE
|
// IGNORE_BACKEND: JS, NATIVE
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
// IGNORE_BACKEND: JS_IR
|
|
||||||
// IGNORE_BACKEND: NATIVE
|
// IGNORE_BACKEND: NATIVE
|
||||||
// WITH_REFLECT
|
// WITH_REFLECT
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
// IGNORE_BACKEND: JS_IR
|
|
||||||
// IGNORE_BACKEND: NATIVE
|
// IGNORE_BACKEND: NATIVE
|
||||||
// WITH_REFLECT
|
// WITH_REFLECT
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
// IGNORE_BACKEND: JVM_IR
|
// IGNORE_BACKEND: JVM_IR
|
||||||
// IGNORE_BACKEND: JS_IR
|
|
||||||
// IGNORE_BACKEND: NATIVE
|
// IGNORE_BACKEND: NATIVE
|
||||||
// WITH_REFLECT
|
// WITH_REFLECT
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
// IGNORE_BACKEND: JS_IR
|
|
||||||
// WITH_RUNTIME
|
// WITH_RUNTIME
|
||||||
|
|
||||||
// FILE: test.kt
|
// FILE: test.kt
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
// IGNORE_BACKEND: JS_IR
|
|
||||||
// WITH_RUNTIME
|
// WITH_RUNTIME
|
||||||
|
|
||||||
fun box(): String {
|
fun box(): String {
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
// IGNORE_BACKEND: JS_IR
|
|
||||||
val foo: ((String) -> String) = run {
|
val foo: ((String) -> String) = run {
|
||||||
{ it }
|
{ it }
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
// IGNORE_BACKEND: JS_IR
|
|
||||||
fun test() = foo({ line: String -> line })
|
fun test() = foo({ line: String -> line })
|
||||||
|
|
||||||
fun <T> foo(x: T): T = TODO()
|
fun <T> foo(x: T): T = TODO()
|
||||||
|
|||||||
@@ -1,12 +1,12 @@
|
|||||||
// IGNORE_BACKEND: JVM_IR
|
// IGNORE_BACKEND: JVM_IR
|
||||||
inline fun run(block: () -> Unit) = block()
|
inline fun run2(block: () -> Unit) = block()
|
||||||
|
|
||||||
class A {
|
class A {
|
||||||
val prop: Int
|
val prop: Int
|
||||||
constructor(arg: Boolean) {
|
constructor(arg: Boolean) {
|
||||||
if (arg) {
|
if (arg) {
|
||||||
prop = 1
|
prop = 1
|
||||||
run { return }
|
run2 { return }
|
||||||
throw RuntimeException("fail 0")
|
throw RuntimeException("fail 0")
|
||||||
}
|
}
|
||||||
prop = 2
|
prop = 2
|
||||||
|
|||||||
@@ -5,10 +5,7 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.js.test
|
package org.jetbrains.kotlin.js.test
|
||||||
|
|
||||||
import org.jetbrains.kotlin.config.ApiVersion
|
import org.jetbrains.kotlin.config.*
|
||||||
import org.jetbrains.kotlin.config.LanguageVersion
|
|
||||||
import org.jetbrains.kotlin.config.LanguageVersionSettingsImpl
|
|
||||||
import org.jetbrains.kotlin.config.languageVersionSettings
|
|
||||||
import org.jetbrains.kotlin.ir.backend.js.Result
|
import org.jetbrains.kotlin.ir.backend.js.Result
|
||||||
import org.jetbrains.kotlin.ir.backend.js.compile
|
import org.jetbrains.kotlin.ir.backend.js.compile
|
||||||
import org.jetbrains.kotlin.js.config.JsConfig
|
import org.jetbrains.kotlin.js.config.JsConfig
|
||||||
@@ -24,9 +21,11 @@ private val runtimeSources = listOfKtFilesFrom(
|
|||||||
"libraries/stdlib/js/src/kotlin/jsTypeOf.kt",
|
"libraries/stdlib/js/src/kotlin/jsTypeOf.kt",
|
||||||
"libraries/stdlib/js/src/kotlin/dynamic.kt",
|
"libraries/stdlib/js/src/kotlin/dynamic.kt",
|
||||||
"libraries/stdlib/js/src/kotlin/annotations.kt",
|
"libraries/stdlib/js/src/kotlin/annotations.kt",
|
||||||
|
"libraries/stdlib/js/src/kotlin/reflect",
|
||||||
|
"libraries/stdlib/js/src/kotlin/annotationsJVM.kt",
|
||||||
|
|
||||||
"libraries/stdlib/src/kotlin/internal/Annotations.kt",
|
"libraries/stdlib/src/kotlin/internal",
|
||||||
|
"libraries/stdlib/src/kotlin/util/Standard.kt",
|
||||||
"core/builtins/native/kotlin/Annotation.kt",
|
"core/builtins/native/kotlin/Annotation.kt",
|
||||||
"core/builtins/native/kotlin/Number.kt",
|
"core/builtins/native/kotlin/Number.kt",
|
||||||
"core/builtins/native/kotlin/Comparable.kt",
|
"core/builtins/native/kotlin/Comparable.kt",
|
||||||
@@ -39,9 +38,14 @@ private val runtimeSources = listOfKtFilesFrom(
|
|||||||
"core/builtins/src/kotlin/Range.kt",
|
"core/builtins/src/kotlin/Range.kt",
|
||||||
"core/builtins/src/kotlin/Ranges.kt",
|
"core/builtins/src/kotlin/Ranges.kt",
|
||||||
"core/builtins/src/kotlin/Unit.kt",
|
"core/builtins/src/kotlin/Unit.kt",
|
||||||
|
"core/builtins/src/kotlin/reflect",
|
||||||
|
"core/builtins/src/kotlin/Function.kt",
|
||||||
|
|
||||||
"core/builtins/native/kotlin/Collections.kt",
|
"core/builtins/native/kotlin/Collections.kt",
|
||||||
"core/builtins/native/kotlin/Iterator.kt",
|
"core/builtins/native/kotlin/Iterator.kt",
|
||||||
|
|
||||||
|
"libraries/stdlib/common/src/kotlin/JvmAnnotationsH.kt",
|
||||||
|
|
||||||
"libraries/stdlib/js/irRuntime",
|
"libraries/stdlib/js/irRuntime",
|
||||||
BasicBoxTest.COMMON_FILES_DIR_PATH
|
BasicBoxTest.COMMON_FILES_DIR_PATH
|
||||||
)
|
)
|
||||||
@@ -85,13 +89,20 @@ abstract class BasicIrBoxTest(
|
|||||||
// TODO: split input files to some parts (global common, local common, test)
|
// TODO: split input files to some parts (global common, local common, test)
|
||||||
.filterNot { it.virtualFilePath.contains(BasicBoxTest.COMMON_FILES_DIR_PATH) }
|
.filterNot { it.virtualFilePath.contains(BasicBoxTest.COMMON_FILES_DIR_PATH) }
|
||||||
|
|
||||||
|
val runtimeConfiguration = config.configuration.copy()
|
||||||
|
|
||||||
|
// TODO: is it right in general? Maybe sometimes we need to compile with newer versions or with additional language features.
|
||||||
|
runtimeConfiguration.languageVersionSettings = LanguageVersionSettingsImpl(
|
||||||
|
LanguageVersion.LATEST_STABLE, ApiVersion.LATEST_STABLE,
|
||||||
|
specificFeatures = mapOf(
|
||||||
|
LanguageFeature.AllowContractsForCustomFunctions to LanguageFeature.State.ENABLED,
|
||||||
|
LanguageFeature.MultiPlatformProjects to LanguageFeature.State.ENABLED
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
if (runtimeResult == null) {
|
if (runtimeResult == null) {
|
||||||
val myConfiguration = config.configuration.copy()
|
runtimeResult = compile(config.project, runtimeSources.map(::createPsiFile), runtimeConfiguration)
|
||||||
|
|
||||||
// TODO: is it right in general? Maybe sometimes we need to compile with newer versions or with additional language features.
|
|
||||||
myConfiguration.languageVersionSettings = LanguageVersionSettingsImpl(LanguageVersion.LATEST_STABLE, ApiVersion.LATEST_STABLE)
|
|
||||||
|
|
||||||
runtimeResult = compile(config.project, runtimeSources.map(::createPsiFile), myConfiguration)
|
|
||||||
runtimeFile.write(runtimeResult!!.generatedCode)
|
runtimeFile.write(runtimeResult!!.generatedCode)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -101,7 +112,7 @@ abstract class BasicIrBoxTest(
|
|||||||
compile(
|
compile(
|
||||||
config.project,
|
config.project,
|
||||||
allFiles,
|
allFiles,
|
||||||
config.configuration,
|
runtimeConfiguration,
|
||||||
FqName((testPackage?.let { "$it." } ?: "") + testFunction))
|
FqName((testPackage?.let { "$it." } ?: "") + testFunction))
|
||||||
} else {
|
} else {
|
||||||
compile(
|
compile(
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
// IGNORE_BACKEND: JS_IR
|
|
||||||
// EXPECTED_REACHABLE_NODES: 1114
|
// EXPECTED_REACHABLE_NODES: 1114
|
||||||
package foo
|
package foo
|
||||||
import kotlin.test.assertEquals
|
import kotlin.test.assertEquals
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
// IGNORE_BACKEND: JS_IR
|
|
||||||
// EXPECTED_REACHABLE_NODES: 1094
|
// EXPECTED_REACHABLE_NODES: 1094
|
||||||
package foo
|
package foo
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
// IGNORE_BACKEND: JS_IR
|
|
||||||
// EXPECTED_REACHABLE_NODES: 1122
|
// EXPECTED_REACHABLE_NODES: 1122
|
||||||
/*
|
/*
|
||||||
* Copy of JVM-backend test
|
* Copy of JVM-backend test
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
// IGNORE_BACKEND: JS_IR
|
|
||||||
// EXPECTED_REACHABLE_NODES: 1131
|
// EXPECTED_REACHABLE_NODES: 1131
|
||||||
/*
|
/*
|
||||||
* Copy of JVM-backend test
|
* Copy of JVM-backend test
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
// IGNORE_BACKEND: JS_IR
|
|
||||||
// EXPECTED_REACHABLE_NODES: 1127
|
// EXPECTED_REACHABLE_NODES: 1127
|
||||||
package foo
|
package foo
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
// IGNORE_BACKEND: JS_IR
|
|
||||||
// EXPECTED_REACHABLE_NODES: 1115
|
// EXPECTED_REACHABLE_NODES: 1115
|
||||||
package foo
|
package foo
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
// IGNORE_BACKEND: JS_IR
|
|
||||||
// EXPECTED_REACHABLE_NODES: 1116
|
// EXPECTED_REACHABLE_NODES: 1116
|
||||||
package foo
|
package foo
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
// IGNORE_BACKEND: JS_IR
|
|
||||||
// EXPECTED_REACHABLE_NODES: 1122
|
// EXPECTED_REACHABLE_NODES: 1122
|
||||||
// CHECK_LABELS_COUNT: function=test0 count=0
|
// CHECK_LABELS_COUNT: function=test0 count=0
|
||||||
// CHECK_LABELS_COUNT: function=test1 count=0
|
// CHECK_LABELS_COUNT: function=test1 count=0
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
// IGNORE_BACKEND: JS_IR
|
|
||||||
// EXPECTED_REACHABLE_NODES: 1135
|
// EXPECTED_REACHABLE_NODES: 1135
|
||||||
open class C {
|
open class C {
|
||||||
private fun constructor() = "C.constructor"
|
private fun constructor() = "C.constructor"
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
// IGNORE_BACKEND: JS_IR
|
|
||||||
// EXPECTED_REACHABLE_NODES: 1111
|
// EXPECTED_REACHABLE_NODES: 1111
|
||||||
//FILE: nativeClassAsReifiedTypeArgument.kt
|
//FILE: nativeClassAsReifiedTypeArgument.kt
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
// IGNORE_BACKEND: JS_IR
|
|
||||||
// EXPECTED_REACHABLE_NODES: 1099
|
// EXPECTED_REACHABLE_NODES: 1099
|
||||||
external class A
|
external class A
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
// IGNORE_BACKEND: JS_IR
|
|
||||||
// EXPECTED_REACHABLE_NODES: 1169
|
// EXPECTED_REACHABLE_NODES: 1169
|
||||||
package foo
|
package foo
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
// IGNORE_BACKEND: JS_IR
|
|
||||||
// EXPECTED_REACHABLE_NODES: 1165
|
// EXPECTED_REACHABLE_NODES: 1165
|
||||||
package foo
|
package foo
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
// IGNORE_BACKEND: JS_IR
|
|
||||||
// EXPECTED_REACHABLE_NODES: 1177
|
// EXPECTED_REACHABLE_NODES: 1177
|
||||||
package foo
|
package foo
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
// IGNORE_BACKEND: JS_IR
|
|
||||||
// EXPECTED_REACHABLE_NODES: 1168
|
// EXPECTED_REACHABLE_NODES: 1168
|
||||||
package foo
|
package foo
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
// IGNORE_BACKEND: JS_IR
|
|
||||||
// EXPECTED_REACHABLE_NODES: 1177
|
// EXPECTED_REACHABLE_NODES: 1177
|
||||||
package foo
|
package foo
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
// IGNORE_BACKEND: JS_IR
|
|
||||||
// EXPECTED_REACHABLE_NODES: 1165
|
// EXPECTED_REACHABLE_NODES: 1165
|
||||||
package foo
|
package foo
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
// IGNORE_BACKEND: JS_IR
|
|
||||||
// EXPECTED_REACHABLE_NODES: 1177
|
// EXPECTED_REACHABLE_NODES: 1177
|
||||||
package foo
|
package foo
|
||||||
|
|
||||||
|
|||||||
@@ -4,6 +4,12 @@
|
|||||||
*/
|
*/
|
||||||
package kotlin
|
package kotlin
|
||||||
|
|
||||||
|
open class Error(override val message: String?, override val cause: Throwable?) : Throwable() {
|
||||||
|
constructor() : this(null, null)
|
||||||
|
constructor(_message: String?) : this(_message, null)
|
||||||
|
constructor(_cause: Throwable?) : this(null, _cause)
|
||||||
|
}
|
||||||
|
|
||||||
open class Exception(override val message: String?, override val cause: Throwable?) : Throwable() {
|
open class Exception(override val message: String?, override val cause: Throwable?) : Throwable() {
|
||||||
constructor() : this(null, null)
|
constructor() : this(null, null)
|
||||||
constructor(_message: String?) : this(_message, null)
|
constructor(_message: String?) : this(_message, null)
|
||||||
|
|||||||
@@ -0,0 +1,27 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
|
||||||
|
* that can be found in the license/LICENSE.txt file.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package kotlin
|
||||||
|
|
||||||
|
// TODO: Ignore FunctionN interfaces
|
||||||
|
|
||||||
|
public interface Function0<out R> : Function<R> {
|
||||||
|
public operator fun invoke(): R
|
||||||
|
}
|
||||||
|
|
||||||
|
public interface Function1<in P1, out R> : Function<R> {
|
||||||
|
public operator fun invoke(p1: P1): R
|
||||||
|
}
|
||||||
|
|
||||||
|
public interface Function2<in P1, in P2, out R> : Function<R> {
|
||||||
|
public operator fun invoke(p1: P1, p2: P2): R
|
||||||
|
}
|
||||||
|
|
||||||
|
public interface Function3<in P1, in P2, in P3, out R> : Function<R> {
|
||||||
|
public operator fun invoke(p1: P1, p2: P2, p3: P3): R
|
||||||
|
}
|
||||||
|
|
||||||
|
public inline fun <reified T> arrayOfNulls(size: Int): Array<T?> = js("[]") // FIXME: Implement
|
||||||
|
|
||||||
@@ -0,0 +1,355 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
|
||||||
|
* that can be found in the license/LICENSE.txt file.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package kotlin.ranges
|
||||||
|
|
||||||
|
// FIXME: Use stdlib _Ranges.kt instead
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a progression from this value down to the specified [to] value with the step -1.
|
||||||
|
*
|
||||||
|
* The [to] value should be less than or equal to `this` value.
|
||||||
|
* If the [to] value is greater than `this` value the returned progression is empty.
|
||||||
|
*/
|
||||||
|
public infix fun Int.downTo(to: Byte): IntProgression {
|
||||||
|
return IntProgression.fromClosedRange(this, to.toInt(), -1)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a progression from this value down to the specified [to] value with the step -1.
|
||||||
|
*
|
||||||
|
* The [to] value should be less than or equal to `this` value.
|
||||||
|
* If the [to] value is greater than `this` value the returned progression is empty.
|
||||||
|
*/
|
||||||
|
public infix fun Long.downTo(to: Byte): LongProgression {
|
||||||
|
return LongProgression.fromClosedRange(this, to.toLong(), -1L)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a progression from this value down to the specified [to] value with the step -1.
|
||||||
|
*
|
||||||
|
* The [to] value should be less than or equal to `this` value.
|
||||||
|
* If the [to] value is greater than `this` value the returned progression is empty.
|
||||||
|
*/
|
||||||
|
public infix fun Byte.downTo(to: Byte): IntProgression {
|
||||||
|
return IntProgression.fromClosedRange(this.toInt(), to.toInt(), -1)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a progression from this value down to the specified [to] value with the step -1.
|
||||||
|
*
|
||||||
|
* The [to] value should be less than or equal to `this` value.
|
||||||
|
* If the [to] value is greater than `this` value the returned progression is empty.
|
||||||
|
*/
|
||||||
|
public infix fun Short.downTo(to: Byte): IntProgression {
|
||||||
|
return IntProgression.fromClosedRange(this.toInt(), to.toInt(), -1)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a progression from this value down to the specified [to] value with the step -1.
|
||||||
|
*
|
||||||
|
* The [to] value should be less than or equal to `this` value.
|
||||||
|
* If the [to] value is greater than `this` value the returned progression is empty.
|
||||||
|
*/
|
||||||
|
public infix fun Char.downTo(to: Char): CharProgression {
|
||||||
|
return CharProgression.fromClosedRange(this, to, -1)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a progression from this value down to the specified [to] value with the step -1.
|
||||||
|
*
|
||||||
|
* The [to] value should be less than or equal to `this` value.
|
||||||
|
* If the [to] value is greater than `this` value the returned progression is empty.
|
||||||
|
*/
|
||||||
|
public infix fun Int.downTo(to: Int): IntProgression {
|
||||||
|
return IntProgression.fromClosedRange(this, to, -1)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a progression from this value down to the specified [to] value with the step -1.
|
||||||
|
*
|
||||||
|
* The [to] value should be less than or equal to `this` value.
|
||||||
|
* If the [to] value is greater than `this` value the returned progression is empty.
|
||||||
|
*/
|
||||||
|
public infix fun Long.downTo(to: Int): LongProgression {
|
||||||
|
return LongProgression.fromClosedRange(this, to.toLong(), -1L)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a progression from this value down to the specified [to] value with the step -1.
|
||||||
|
*
|
||||||
|
* The [to] value should be less than or equal to `this` value.
|
||||||
|
* If the [to] value is greater than `this` value the returned progression is empty.
|
||||||
|
*/
|
||||||
|
public infix fun Byte.downTo(to: Int): IntProgression {
|
||||||
|
return IntProgression.fromClosedRange(this.toInt(), to, -1)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a progression from this value down to the specified [to] value with the step -1.
|
||||||
|
*
|
||||||
|
* The [to] value should be less than or equal to `this` value.
|
||||||
|
* If the [to] value is greater than `this` value the returned progression is empty.
|
||||||
|
*/
|
||||||
|
public infix fun Short.downTo(to: Int): IntProgression {
|
||||||
|
return IntProgression.fromClosedRange(this.toInt(), to, -1)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a progression from this value down to the specified [to] value with the step -1.
|
||||||
|
*
|
||||||
|
* The [to] value should be less than or equal to `this` value.
|
||||||
|
* If the [to] value is greater than `this` value the returned progression is empty.
|
||||||
|
*/
|
||||||
|
public infix fun Int.downTo(to: Long): LongProgression {
|
||||||
|
return LongProgression.fromClosedRange(this.toLong(), to, -1L)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a progression from this value down to the specified [to] value with the step -1.
|
||||||
|
*
|
||||||
|
* The [to] value should be less than or equal to `this` value.
|
||||||
|
* If the [to] value is greater than `this` value the returned progression is empty.
|
||||||
|
*/
|
||||||
|
public infix fun Long.downTo(to: Long): LongProgression {
|
||||||
|
return LongProgression.fromClosedRange(this, to, -1L)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a progression from this value down to the specified [to] value with the step -1.
|
||||||
|
*
|
||||||
|
* The [to] value should be less than or equal to `this` value.
|
||||||
|
* If the [to] value is greater than `this` value the returned progression is empty.
|
||||||
|
*/
|
||||||
|
public infix fun Byte.downTo(to: Long): LongProgression {
|
||||||
|
return LongProgression.fromClosedRange(this.toLong(), to, -1L)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a progression from this value down to the specified [to] value with the step -1.
|
||||||
|
*
|
||||||
|
* The [to] value should be less than or equal to `this` value.
|
||||||
|
* If the [to] value is greater than `this` value the returned progression is empty.
|
||||||
|
*/
|
||||||
|
public infix fun Short.downTo(to: Long): LongProgression {
|
||||||
|
return LongProgression.fromClosedRange(this.toLong(), to, -1L)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a progression from this value down to the specified [to] value with the step -1.
|
||||||
|
*
|
||||||
|
* The [to] value should be less than or equal to `this` value.
|
||||||
|
* If the [to] value is greater than `this` value the returned progression is empty.
|
||||||
|
*/
|
||||||
|
public infix fun Int.downTo(to: Short): IntProgression {
|
||||||
|
return IntProgression.fromClosedRange(this, to.toInt(), -1)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a progression from this value down to the specified [to] value with the step -1.
|
||||||
|
*
|
||||||
|
* The [to] value should be less than or equal to `this` value.
|
||||||
|
* If the [to] value is greater than `this` value the returned progression is empty.
|
||||||
|
*/
|
||||||
|
public infix fun Long.downTo(to: Short): LongProgression {
|
||||||
|
return LongProgression.fromClosedRange(this, to.toLong(), -1L)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a progression from this value down to the specified [to] value with the step -1.
|
||||||
|
*
|
||||||
|
* The [to] value should be less than or equal to `this` value.
|
||||||
|
* If the [to] value is greater than `this` value the returned progression is empty.
|
||||||
|
*/
|
||||||
|
public infix fun Byte.downTo(to: Short): IntProgression {
|
||||||
|
return IntProgression.fromClosedRange(this.toInt(), to.toInt(), -1)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a progression from this value down to the specified [to] value with the step -1.
|
||||||
|
*
|
||||||
|
* The [to] value should be less than or equal to `this` value.
|
||||||
|
* If the [to] value is greater than `this` value the returned progression is empty.
|
||||||
|
*/
|
||||||
|
public infix fun Short.downTo(to: Short): IntProgression {
|
||||||
|
return IntProgression.fromClosedRange(this.toInt(), to.toInt(), -1)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a range from this value up to but excluding the specified [to] value.
|
||||||
|
*
|
||||||
|
* If the [to] value is less than or equal to `this` value the returned range is empty.
|
||||||
|
*/
|
||||||
|
public infix fun Int.until(to: Byte): IntRange {
|
||||||
|
return this .. (to.toInt() - 1).toInt()
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a range from this value up to but excluding the specified [to] value.
|
||||||
|
*
|
||||||
|
* If the [to] value is less than or equal to `this` value the returned range is empty.
|
||||||
|
*/
|
||||||
|
public infix fun Long.until(to: Byte): LongRange {
|
||||||
|
return this .. (to.toLong() - 1).toLong()
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a range from this value up to but excluding the specified [to] value.
|
||||||
|
*
|
||||||
|
* If the [to] value is less than or equal to `this` value the returned range is empty.
|
||||||
|
*/
|
||||||
|
public infix fun Byte.until(to: Byte): IntRange {
|
||||||
|
return this.toInt() .. (to.toInt() - 1).toInt()
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a range from this value up to but excluding the specified [to] value.
|
||||||
|
*
|
||||||
|
* If the [to] value is less than or equal to `this` value the returned range is empty.
|
||||||
|
*/
|
||||||
|
public infix fun Short.until(to: Byte): IntRange {
|
||||||
|
return this.toInt() .. (to.toInt() - 1).toInt()
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a range from this value up to but excluding the specified [to] value.
|
||||||
|
*
|
||||||
|
* If the [to] value is less than or equal to `this` value the returned range is empty.
|
||||||
|
*
|
||||||
|
* If the [to] value is less than or equal to `'\u0000'` the returned range is empty.
|
||||||
|
*/
|
||||||
|
public infix fun Char.until(to: Char): CharRange {
|
||||||
|
if (to <= '\u0000') return CharRange.EMPTY
|
||||||
|
return this .. (to - 1).toChar()
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a range from this value up to but excluding the specified [to] value.
|
||||||
|
*
|
||||||
|
* If the [to] value is less than or equal to `this` value the returned range is empty.
|
||||||
|
*
|
||||||
|
* If the [to] value is less than or equal to [Int.MIN_VALUE] the returned range is empty.
|
||||||
|
*/
|
||||||
|
public infix fun Int.until(to: Int): IntRange {
|
||||||
|
if (to <= Int.MIN_VALUE) return IntRange.EMPTY
|
||||||
|
return this .. (to - 1).toInt()
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a range from this value up to but excluding the specified [to] value.
|
||||||
|
*
|
||||||
|
* If the [to] value is less than or equal to `this` value the returned range is empty.
|
||||||
|
*/
|
||||||
|
public infix fun Long.until(to: Int): LongRange {
|
||||||
|
return this .. (to.toLong() - 1).toLong()
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a range from this value up to but excluding the specified [to] value.
|
||||||
|
*
|
||||||
|
* If the [to] value is less than or equal to `this` value the returned range is empty.
|
||||||
|
*
|
||||||
|
* If the [to] value is less than or equal to [Int.MIN_VALUE] the returned range is empty.
|
||||||
|
*/
|
||||||
|
public infix fun Byte.until(to: Int): IntRange {
|
||||||
|
if (to <= Int.MIN_VALUE) return IntRange.EMPTY
|
||||||
|
return this.toInt() .. (to - 1).toInt()
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a range from this value up to but excluding the specified [to] value.
|
||||||
|
*
|
||||||
|
* If the [to] value is less than or equal to `this` value the returned range is empty.
|
||||||
|
*
|
||||||
|
* If the [to] value is less than or equal to [Int.MIN_VALUE] the returned range is empty.
|
||||||
|
*/
|
||||||
|
public infix fun Short.until(to: Int): IntRange {
|
||||||
|
if (to <= Int.MIN_VALUE) return IntRange.EMPTY
|
||||||
|
return this.toInt() .. (to - 1).toInt()
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a range from this value up to but excluding the specified [to] value.
|
||||||
|
*
|
||||||
|
* If the [to] value is less than or equal to `this` value the returned range is empty.
|
||||||
|
*
|
||||||
|
* If the [to] value is less than or equal to [Long.MIN_VALUE] the returned range is empty.
|
||||||
|
*/
|
||||||
|
public infix fun Int.until(to: Long): LongRange {
|
||||||
|
if (to <= Long.MIN_VALUE) return LongRange.EMPTY
|
||||||
|
return this.toLong() .. (to - 1).toLong()
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a range from this value up to but excluding the specified [to] value.
|
||||||
|
*
|
||||||
|
* If the [to] value is less than or equal to `this` value the returned range is empty.
|
||||||
|
*
|
||||||
|
* If the [to] value is less than or equal to [Long.MIN_VALUE] the returned range is empty.
|
||||||
|
*/
|
||||||
|
public infix fun Long.until(to: Long): LongRange {
|
||||||
|
if (to <= Long.MIN_VALUE) return LongRange.EMPTY
|
||||||
|
return this .. (to - 1).toLong()
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a range from this value up to but excluding the specified [to] value.
|
||||||
|
*
|
||||||
|
* If the [to] value is less than or equal to `this` value the returned range is empty.
|
||||||
|
*
|
||||||
|
* If the [to] value is less than or equal to [Long.MIN_VALUE] the returned range is empty.
|
||||||
|
*/
|
||||||
|
public infix fun Byte.until(to: Long): LongRange {
|
||||||
|
if (to <= Long.MIN_VALUE) return LongRange.EMPTY
|
||||||
|
return this.toLong() .. (to - 1).toLong()
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a range from this value up to but excluding the specified [to] value.
|
||||||
|
*
|
||||||
|
* If the [to] value is less than or equal to `this` value the returned range is empty.
|
||||||
|
*
|
||||||
|
* If the [to] value is less than or equal to [Long.MIN_VALUE] the returned range is empty.
|
||||||
|
*/
|
||||||
|
public infix fun Short.until(to: Long): LongRange {
|
||||||
|
if (to <= Long.MIN_VALUE) return LongRange.EMPTY
|
||||||
|
return this.toLong() .. (to - 1).toLong()
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a range from this value up to but excluding the specified [to] value.
|
||||||
|
*
|
||||||
|
* If the [to] value is less than or equal to `this` value the returned range is empty.
|
||||||
|
*/
|
||||||
|
public infix fun Int.until(to: Short): IntRange {
|
||||||
|
return this .. (to.toInt() - 1).toInt()
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a range from this value up to but excluding the specified [to] value.
|
||||||
|
*
|
||||||
|
* If the [to] value is less than or equal to `this` value the returned range is empty.
|
||||||
|
*/
|
||||||
|
public infix fun Long.until(to: Short): LongRange {
|
||||||
|
return this .. (to.toLong() - 1).toLong()
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a range from this value up to but excluding the specified [to] value.
|
||||||
|
*
|
||||||
|
* If the [to] value is less than or equal to `this` value the returned range is empty.
|
||||||
|
*/
|
||||||
|
public infix fun Byte.until(to: Short): IntRange {
|
||||||
|
return this.toInt() .. (to.toInt() - 1).toInt()
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a range from this value up to but excluding the specified [to] value.
|
||||||
|
*
|
||||||
|
* If the [to] value is less than or equal to `this` value the returned range is empty.
|
||||||
|
*/
|
||||||
|
public infix fun Short.until(to: Short): IntRange {
|
||||||
|
return this.toInt() .. (to.toInt() - 1).toInt()
|
||||||
|
}
|
||||||
@@ -74,6 +74,8 @@ public fun isInterface(ctor: dynamic, IType: dynamic): Boolean {
|
|||||||
|
|
||||||
fun typeOf(obj: dynamic) = js("typeof obj").unsafeCast<String>()
|
fun typeOf(obj: dynamic) = js("typeof obj").unsafeCast<String>()
|
||||||
|
|
||||||
|
fun instanceOf(obj: dynamic, jsClass: dynamic) = js("obj instanceof jsClass").unsafeCast<Boolean>()
|
||||||
|
|
||||||
fun isObject(obj: dynamic): Boolean {
|
fun isObject(obj: dynamic): Boolean {
|
||||||
val objTypeOf = typeOf(obj)
|
val objTypeOf = typeOf(obj)
|
||||||
|
|
||||||
@@ -96,4 +98,54 @@ public fun isArrayish(o: dynamic) =
|
|||||||
|
|
||||||
public fun isChar(c: Any): Boolean {
|
public fun isChar(c: Any): Boolean {
|
||||||
return js("throw Error(\"isChar is not implemented\")").unsafeCast<Boolean>()
|
return js("throw Error(\"isChar is not implemented\")").unsafeCast<Boolean>()
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: Distinguish Boolean/Byte and Short/Char
|
||||||
|
public fun isBooleanArray(a: dynamic) = js("a instanceof Int8Array")
|
||||||
|
public fun isByteArray(a: dynamic) = js("a instanceof Int8Array")
|
||||||
|
public fun isShortArray(a: dynamic) = js("a instanceof Int16Array")
|
||||||
|
public fun isCharArray(a: dynamic) = js("a instanceof Uint16Array")
|
||||||
|
public fun isIntArray(a: dynamic) = js("a instanceof Int32Array")
|
||||||
|
public fun isFloatArray(a: dynamic) = js("a instanceof Float32Array")
|
||||||
|
public fun isDoubleArray(a: dynamic) = js("a instanceof Float64Array")
|
||||||
|
public fun isLongArray(a: dynamic) = isArray(a) // TODO: Implement
|
||||||
|
|
||||||
|
|
||||||
|
internal fun jsIn(x: String, y: dynamic): Boolean = js("x in y")
|
||||||
|
internal fun jsGetPrototypeOf(jsClass: dynamic) = js("Object.getPrototypeOf(jsClass)")
|
||||||
|
|
||||||
|
public fun jsIsType(obj: dynamic, jsClass: dynamic): Boolean {
|
||||||
|
if (jsClass === js("Object")) {
|
||||||
|
return isObject(obj)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (obj == null || jsClass == null || (typeOf(obj) != "object" && typeOf(obj) != "function")) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
if (typeOf(jsClass) == "function" && instanceOf(obj, jsClass)) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
var proto = jsGetPrototypeOf(jsClass)
|
||||||
|
var constructor = proto?.constructor
|
||||||
|
if (constructor != null && jsIn("${'$'}metadata${'$'}", constructor)) {
|
||||||
|
var metadata = constructor.`$metadata$`
|
||||||
|
if (metadata.kind === "object") {
|
||||||
|
return obj === jsClass
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var klassMetadata = jsClass.`$metadata$`
|
||||||
|
|
||||||
|
// In WebKit (JavaScriptCore) for some interfaces from DOM typeof returns "object", nevertheless they can be used in RHS of instanceof
|
||||||
|
if (klassMetadata == null) {
|
||||||
|
return instanceOf(obj, jsClass)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (klassMetadata.kind === "interface" && obj.constructor != null) {
|
||||||
|
return isInterfaceImpl(obj.constructor, jsClass)
|
||||||
|
}
|
||||||
|
|
||||||
|
return false
|
||||||
}
|
}
|
||||||
@@ -98,3 +98,5 @@ internal inline fun copyArrayType(from: dynamic, to: dynamic) {
|
|||||||
to.`$type$` = from.`$type$`
|
to.`$type$` = from.`$type$`
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal inline fun jsIsType(obj: dynamic, jsClass: dynamic) = js("Kotlin").isType(obj, jsClass)
|
||||||
@@ -60,7 +60,7 @@ internal class SimpleKClassImpl<T : Any>(jClass: JsClass<T>) : KClassImpl<T>(jCl
|
|||||||
override val simpleName: String? = jClass.asDynamic().`$metadata$`?.simpleName.unsafeCast<String?>()
|
override val simpleName: String? = jClass.asDynamic().`$metadata$`?.simpleName.unsafeCast<String?>()
|
||||||
|
|
||||||
override fun isInstance(value: Any?): Boolean {
|
override fun isInstance(value: Any?): Boolean {
|
||||||
return js("Kotlin").isType(value, jClass)
|
return jsIsType(value, jClass)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user