From ee06678484c1dac861fa0dcd30b95918da6fe140 Mon Sep 17 00:00:00 2001 From: Zalim Bashorov Date: Tue, 24 Dec 2019 01:51:34 +0300 Subject: [PATCH] [JS BE] Fix `is` check with Function #KT-33149 fixed --- .../kotlin/js/translate/expression/PatternTranslator.java | 7 +++++-- .../testData/box/rtti/isJsPrimitiveNullableType.kt | 8 +++++++- js/js.translator/testData/box/rtti/isJsPrimitiveType.kt | 7 ++++++- 3 files changed, 18 insertions(+), 4 deletions(-) diff --git a/js/js.translator/src/org/jetbrains/kotlin/js/translate/expression/PatternTranslator.java b/js/js.translator/src/org/jetbrains/kotlin/js/translate/expression/PatternTranslator.java index a1b3746a324..773bf28fcf8 100644 --- a/js/js.translator/src/org/jetbrains/kotlin/js/translate/expression/PatternTranslator.java +++ b/js/js.translator/src/org/jetbrains/kotlin/js/translate/expression/PatternTranslator.java @@ -1,5 +1,5 @@ /* - * Copyright 2010-2018 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors. * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. */ @@ -34,6 +34,7 @@ import java.util.Collections; import static org.jetbrains.kotlin.builtins.FunctionTypesKt.isFunctionTypeOrSubtype; import static org.jetbrains.kotlin.builtins.KotlinBuiltIns.isArray; +import static org.jetbrains.kotlin.builtins.KotlinBuiltIns.isNotNullOrNullableFunctionSupertype; import static org.jetbrains.kotlin.js.descriptorUtils.DescriptorUtilsKt.getNameIfStandardType; import static org.jetbrains.kotlin.js.translate.utils.BindingUtils.getTypeByReference; import static org.jetbrains.kotlin.js.translate.utils.JsAstUtils.equality; @@ -181,7 +182,9 @@ public final class PatternTranslator extends AbstractTranslator { @Nullable private JsExpression getIsTypeCheckCallableForBuiltin(@NotNull KotlinType type) { - if (isFunctionTypeOrSubtype(type) && !ReflectionTypes.isNumberedKPropertyOrKMutablePropertyType(type)) { + if ((isNotNullOrNullableFunctionSupertype(type) || isFunctionTypeOrSubtype(type)) && + !ReflectionTypes.isNumberedKPropertyOrKMutablePropertyType(type) + ) { return namer().isTypeOf(new JsStringLiteral("function")); } diff --git a/js/js.translator/testData/box/rtti/isJsPrimitiveNullableType.kt b/js/js.translator/testData/box/rtti/isJsPrimitiveNullableType.kt index 7e6fcb22de1..7b0143a87cc 100644 --- a/js/js.translator/testData/box/rtti/isJsPrimitiveNullableType.kt +++ b/js/js.translator/testData/box/rtti/isJsPrimitiveNullableType.kt @@ -6,6 +6,7 @@ val STRING = 2 val BOOLEAN = 3 val OBJECT = 4 val FUNCTION = 5 +val FUNCTION0 = FUNCTION // right now we can't distinguish functions with different arity fun testNullable(a: Any?, actualType: Int) { assertEquals(a == null || actualType == NUMBER, a is Int?, "$a is Int?") @@ -13,7 +14,8 @@ fun testNullable(a: Any?, actualType: Int) { assertEquals(a == null || actualType == NUMBER, a is Double?, "$a is Double?") assertEquals(a == null || actualType == BOOLEAN, a is Boolean?, "$a is Boolean?") assertEquals(a == null || actualType == STRING, a is String?, "$a is String?") - assertEquals(a == null || actualType == FUNCTION, a is Function0<*>?, "$a is Function?") + assertEquals(a == null || actualType == FUNCTION0, a is Function0<*>?, "$a is Function0?") + assertEquals(a == null || actualType == FUNCTION || actualType == FUNCTION0, a is Function<*>?, "$a is Function?") } fun box(): String { @@ -28,12 +30,16 @@ fun box(): String { testNullable(false, BOOLEAN) testNullable(object {}, OBJECT) + testNullable({}, FUNCTION0) + testNullable({}, FUNCTION) + testNullable({a: Any -> }, FUNCTION) testNullable(null, NUMBER) testNullable(null, STRING) testNullable(null, BOOLEAN) testNullable(null, OBJECT) + testNullable(null, FUNCTION0) testNullable(null, FUNCTION) return "OK" diff --git a/js/js.translator/testData/box/rtti/isJsPrimitiveType.kt b/js/js.translator/testData/box/rtti/isJsPrimitiveType.kt index 0562dbc53c4..14b8dd253cd 100644 --- a/js/js.translator/testData/box/rtti/isJsPrimitiveType.kt +++ b/js/js.translator/testData/box/rtti/isJsPrimitiveType.kt @@ -6,6 +6,7 @@ val STRING = 2 val BOOLEAN = 3 val OBJECT = 4 val FUNCTION = 5 +val FUNCTION0 = FUNCTION // right now we can't distinguish functions with different arity fun test(a: Any, actualType: Int) { assertEquals(actualType == NUMBER, a is Int, "$a is Int") @@ -13,7 +14,8 @@ fun test(a: Any, actualType: Int) { assertEquals(actualType == NUMBER, a is Double, "$a is Double") assertEquals(actualType == BOOLEAN, a is Boolean, "$a is Boolean") assertEquals(actualType == STRING, a is String, "$a is String") - assertEquals(actualType == FUNCTION, a is Function0<*>, "$a is Function") + assertEquals(actualType == FUNCTION0, a is Function0<*>, "$a is Function0") + assertEquals(actualType == FUNCTION || actualType == FUNCTION0, a is Function<*>, "$a is Function") } fun box(): String { @@ -29,7 +31,10 @@ fun box(): String { test(object {}, OBJECT) + test({}, FUNCTION0) + test({}, FUNCTION) + test({a: Any -> }, FUNCTION) return "OK" } \ No newline at end of file