[CJS BE] don't crash when intersection types passed for a reified parameter
#KT-37163 Fixed
This commit is contained in:
Generated
+15
@@ -25186,6 +25186,21 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT
|
|||||||
runTest("compiler/testData/codegen/box/reified/reifiedIntersectionType.kt");
|
runTest("compiler/testData/codegen/box/reified/reifiedIntersectionType.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("reifiedIntersectionTypeArgument.kt")
|
||||||
|
public void testReifiedIntersectionTypeArgument() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/reified/reifiedIntersectionTypeArgument.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("reifiedIntersectionTypeArgumentCrossModule.kt")
|
||||||
|
public void testReifiedIntersectionTypeArgumentCrossModule() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/reified/reifiedIntersectionTypeArgumentCrossModule.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("reifiedTypeArgumentWithIntersectionTypeAsTypeArgument.kt")
|
||||||
|
public void testReifiedTypeArgumentWithIntersectionTypeAsTypeArgument() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/reified/reifiedTypeArgumentWithIntersectionTypeAsTypeArgument.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("safecast.kt")
|
@TestMetadata("safecast.kt")
|
||||||
public void testSafecast() throws Exception {
|
public void testSafecast() throws Exception {
|
||||||
runTest("compiler/testData/codegen/box/reified/safecast.kt");
|
runTest("compiler/testData/codegen/box/reified/safecast.kt");
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
// IGNORE_BACKEND: JS
|
|
||||||
// KJS_WITH_FULL_RUNTIME
|
// KJS_WITH_FULL_RUNTIME
|
||||||
|
|
||||||
|
// KT-37163
|
||||||
// Case that was found in kotlinx.coroutines
|
// Case that was found in kotlinx.coroutines
|
||||||
|
|
||||||
fun test1() {
|
fun test1() {
|
||||||
@@ -20,18 +20,6 @@ public inline fun <reified T, R> combine(
|
|||||||
fun <T> flowOf(value: T): Flow<T> = TODO()
|
fun <T> flowOf(value: T): Flow<T> = TODO()
|
||||||
interface Flow<out T>
|
interface Flow<out T>
|
||||||
|
|
||||||
// Simplified case
|
|
||||||
|
|
||||||
class In<in T>
|
|
||||||
|
|
||||||
inline fun <reified K> select(x: K, y: K): K = x
|
|
||||||
interface A
|
|
||||||
interface B
|
|
||||||
|
|
||||||
fun test2(a: In<A>, b: In<B>) {
|
|
||||||
select(a, b)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun box(): String {
|
fun box(): String {
|
||||||
return "OK"
|
return "OK"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,62 @@
|
|||||||
|
// IGNORE_BACKEND_FIR: JVM_IR
|
||||||
|
// WITH_RUNTIME
|
||||||
|
// KJS_WITH_FULL_RUNTIME
|
||||||
|
|
||||||
|
// See KT-37163
|
||||||
|
|
||||||
|
import kotlin.reflect.typeOf
|
||||||
|
|
||||||
|
class In<in T>
|
||||||
|
|
||||||
|
interface A
|
||||||
|
interface B
|
||||||
|
class C() : A, B
|
||||||
|
|
||||||
|
// TODO check real effects to fix the behavior when we reach consensus
|
||||||
|
// and to be sure that something is not dropped by optimizations.
|
||||||
|
|
||||||
|
var l = ""
|
||||||
|
fun log(s: String) {
|
||||||
|
l += s + ";"
|
||||||
|
}
|
||||||
|
|
||||||
|
fun consume(a: Any?) {}
|
||||||
|
|
||||||
|
@OptIn(kotlin.ExperimentalStdlibApi::class)
|
||||||
|
inline fun <reified K> select(x: K, y: Any): K where K : A, K : B {
|
||||||
|
log((x is K).toString())
|
||||||
|
log((y is K).toString())
|
||||||
|
consume(K::class)
|
||||||
|
log("KClass was created")
|
||||||
|
consume(typeOf<K>())
|
||||||
|
log("KType was created")
|
||||||
|
consume(Array<K>(1) { x })
|
||||||
|
log("array was created")
|
||||||
|
return x as K
|
||||||
|
}
|
||||||
|
|
||||||
|
fun test(a: Any, b: Any) {
|
||||||
|
if (a is A && a is B) {
|
||||||
|
select(a, b)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun box(): String {
|
||||||
|
test(C(), object : A, B {})
|
||||||
|
test(C(), object : A {})
|
||||||
|
test(C(), object : B {})
|
||||||
|
test(C(), object {})
|
||||||
|
test(C(), Any())
|
||||||
|
|
||||||
|
// if (
|
||||||
|
// l != "true;true;KClass was created;KType was created;array was created;" +
|
||||||
|
// "true;false;KClass was created;KType was created;array was created;" +
|
||||||
|
// "true;false;KClass was created;KType was created;array was created;" +
|
||||||
|
// "true;false;KClass was created;KType was created;array was created;" +
|
||||||
|
// "true;false;KClass was created;KType was created;array was created;"
|
||||||
|
// ) {
|
||||||
|
// return "fail: $l"
|
||||||
|
// }
|
||||||
|
|
||||||
|
return "OK"
|
||||||
|
}
|
||||||
+66
@@ -0,0 +1,66 @@
|
|||||||
|
// IGNORE_BACKEND_FIR: JVM_IR
|
||||||
|
// WITH_RUNTIME
|
||||||
|
// KJS_WITH_FULL_RUNTIME
|
||||||
|
|
||||||
|
// See KT-37163
|
||||||
|
|
||||||
|
// MODULE: m1
|
||||||
|
// FILE: a.kt
|
||||||
|
import kotlin.reflect.typeOf
|
||||||
|
|
||||||
|
class In<in T>
|
||||||
|
|
||||||
|
interface A
|
||||||
|
interface B
|
||||||
|
class C() : A, B
|
||||||
|
|
||||||
|
// TODO check real effects to fix the behavior when we reach consensus
|
||||||
|
// and to be sure that something is not dropped by optimizations.
|
||||||
|
|
||||||
|
var l = ""
|
||||||
|
fun log(s: String) {
|
||||||
|
l += s + ";"
|
||||||
|
}
|
||||||
|
|
||||||
|
fun consume(a: Any?) {}
|
||||||
|
|
||||||
|
@OptIn(kotlin.ExperimentalStdlibApi::class)
|
||||||
|
inline fun <reified K> select(x: K, y: Any): K where K : A, K : B {
|
||||||
|
log((x is K).toString())
|
||||||
|
log((y is K).toString())
|
||||||
|
consume(K::class)
|
||||||
|
log("KClass was created")
|
||||||
|
consume(typeOf<K>())
|
||||||
|
log("KType was created")
|
||||||
|
consume(Array<K>(1) { x })
|
||||||
|
log("array was created")
|
||||||
|
return x as K
|
||||||
|
}
|
||||||
|
|
||||||
|
// MODULE: main(m1)
|
||||||
|
// FILE: b.kt
|
||||||
|
fun test(a: Any, b: Any) {
|
||||||
|
if (a is A && a is B) {
|
||||||
|
select(a, b)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun box(): String {
|
||||||
|
test(C(), object : A, B {})
|
||||||
|
test(C(), object : A {})
|
||||||
|
test(C(), object : B {})
|
||||||
|
test(C(), object {})
|
||||||
|
test(C(), Any())
|
||||||
|
|
||||||
|
// if (
|
||||||
|
// l != "true;true;KClass was created;KType was created;array was created;" +
|
||||||
|
// "true;false;KClass was created;KType was created;array was created;" +
|
||||||
|
// "true;false;KClass was created;KType was created;array was created;" +
|
||||||
|
// "true;false;KClass was created;KType was created;array was created;" +
|
||||||
|
// "true;false;KClass was created;KType was created;array was created;"
|
||||||
|
// ) {
|
||||||
|
// return "fail: $l"
|
||||||
|
// }
|
||||||
|
|
||||||
|
return "OK"
|
||||||
|
}
|
||||||
Vendored
+32
@@ -0,0 +1,32 @@
|
|||||||
|
// IGNORE_BACKEND_FIR: JVM_IR
|
||||||
|
// WITH_RUNTIME
|
||||||
|
// KJS_WITH_FULL_RUNTIME
|
||||||
|
|
||||||
|
// See KT-37163
|
||||||
|
|
||||||
|
import kotlin.reflect.typeOf
|
||||||
|
|
||||||
|
class In<in T>
|
||||||
|
|
||||||
|
interface A
|
||||||
|
interface B
|
||||||
|
|
||||||
|
// TODO check real effects to fix the behavior when we reach consensus
|
||||||
|
// and to be sure that something is not dropped by optimizations.
|
||||||
|
|
||||||
|
@OptIn(kotlin.ExperimentalStdlibApi::class)
|
||||||
|
inline fun <reified K> select(x: K, y: K) {
|
||||||
|
x is K
|
||||||
|
x as K
|
||||||
|
K::class
|
||||||
|
typeOf<K>()
|
||||||
|
Array<K>(1) { x }
|
||||||
|
}
|
||||||
|
fun test() {
|
||||||
|
select(In<A>(), In<B>())
|
||||||
|
}
|
||||||
|
|
||||||
|
fun box(): String {
|
||||||
|
test()
|
||||||
|
return "OK"
|
||||||
|
}
|
||||||
+15
@@ -26702,6 +26702,21 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
|
|||||||
runTest("compiler/testData/codegen/box/reified/reifiedIntersectionType.kt");
|
runTest("compiler/testData/codegen/box/reified/reifiedIntersectionType.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("reifiedIntersectionTypeArgument.kt")
|
||||||
|
public void testReifiedIntersectionTypeArgument() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/reified/reifiedIntersectionTypeArgument.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("reifiedIntersectionTypeArgumentCrossModule.kt")
|
||||||
|
public void testReifiedIntersectionTypeArgumentCrossModule() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/reified/reifiedIntersectionTypeArgumentCrossModule.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("reifiedTypeArgumentWithIntersectionTypeAsTypeArgument.kt")
|
||||||
|
public void testReifiedTypeArgumentWithIntersectionTypeAsTypeArgument() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/reified/reifiedTypeArgumentWithIntersectionTypeAsTypeArgument.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("safecast.kt")
|
@TestMetadata("safecast.kt")
|
||||||
public void testSafecast() throws Exception {
|
public void testSafecast() throws Exception {
|
||||||
runTest("compiler/testData/codegen/box/reified/safecast.kt");
|
runTest("compiler/testData/codegen/box/reified/safecast.kt");
|
||||||
|
|||||||
+15
@@ -25519,6 +25519,21 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes
|
|||||||
runTest("compiler/testData/codegen/box/reified/reifiedIntersectionType.kt");
|
runTest("compiler/testData/codegen/box/reified/reifiedIntersectionType.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("reifiedIntersectionTypeArgument.kt")
|
||||||
|
public void testReifiedIntersectionTypeArgument() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/reified/reifiedIntersectionTypeArgument.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("reifiedIntersectionTypeArgumentCrossModule.kt")
|
||||||
|
public void testReifiedIntersectionTypeArgumentCrossModule() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/reified/reifiedIntersectionTypeArgumentCrossModule.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("reifiedTypeArgumentWithIntersectionTypeAsTypeArgument.kt")
|
||||||
|
public void testReifiedTypeArgumentWithIntersectionTypeAsTypeArgument() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/reified/reifiedTypeArgumentWithIntersectionTypeAsTypeArgument.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("safecast.kt")
|
@TestMetadata("safecast.kt")
|
||||||
public void testSafecast() throws Exception {
|
public void testSafecast() throws Exception {
|
||||||
runTest("compiler/testData/codegen/box/reified/safecast.kt");
|
runTest("compiler/testData/codegen/box/reified/safecast.kt");
|
||||||
|
|||||||
+15
@@ -25186,6 +25186,21 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes
|
|||||||
runTest("compiler/testData/codegen/box/reified/reifiedIntersectionType.kt");
|
runTest("compiler/testData/codegen/box/reified/reifiedIntersectionType.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("reifiedIntersectionTypeArgument.kt")
|
||||||
|
public void testReifiedIntersectionTypeArgument() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/reified/reifiedIntersectionTypeArgument.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("reifiedIntersectionTypeArgumentCrossModule.kt")
|
||||||
|
public void testReifiedIntersectionTypeArgumentCrossModule() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/reified/reifiedIntersectionTypeArgumentCrossModule.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("reifiedTypeArgumentWithIntersectionTypeAsTypeArgument.kt")
|
||||||
|
public void testReifiedTypeArgumentWithIntersectionTypeAsTypeArgument() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/reified/reifiedTypeArgumentWithIntersectionTypeAsTypeArgument.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("safecast.kt")
|
@TestMetadata("safecast.kt")
|
||||||
public void testSafecast() throws Exception {
|
public void testSafecast() throws Exception {
|
||||||
runTest("compiler/testData/codegen/box/reified/safecast.kt");
|
runTest("compiler/testData/codegen/box/reified/safecast.kt");
|
||||||
|
|||||||
Generated
+15
@@ -20577,6 +20577,21 @@ public class IrJsCodegenBoxTestGenerated extends AbstractIrJsCodegenBoxTest {
|
|||||||
runTest("compiler/testData/codegen/box/reified/reifiedIntersectionType.kt");
|
runTest("compiler/testData/codegen/box/reified/reifiedIntersectionType.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("reifiedIntersectionTypeArgument.kt")
|
||||||
|
public void testReifiedIntersectionTypeArgument() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/reified/reifiedIntersectionTypeArgument.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("reifiedIntersectionTypeArgumentCrossModule.kt")
|
||||||
|
public void testReifiedIntersectionTypeArgumentCrossModule() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/reified/reifiedIntersectionTypeArgumentCrossModule.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("reifiedTypeArgumentWithIntersectionTypeAsTypeArgument.kt")
|
||||||
|
public void testReifiedTypeArgumentWithIntersectionTypeAsTypeArgument() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/reified/reifiedTypeArgumentWithIntersectionTypeAsTypeArgument.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("safecast.kt")
|
@TestMetadata("safecast.kt")
|
||||||
public void testSafecast() throws Exception {
|
public void testSafecast() throws Exception {
|
||||||
runTest("compiler/testData/codegen/box/reified/safecast.kt");
|
runTest("compiler/testData/codegen/box/reified/safecast.kt");
|
||||||
|
|||||||
+15
@@ -20637,6 +20637,21 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest {
|
|||||||
runTest("compiler/testData/codegen/box/reified/reifiedIntersectionType.kt");
|
runTest("compiler/testData/codegen/box/reified/reifiedIntersectionType.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("reifiedIntersectionTypeArgument.kt")
|
||||||
|
public void testReifiedIntersectionTypeArgument() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/reified/reifiedIntersectionTypeArgument.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("reifiedIntersectionTypeArgumentCrossModule.kt")
|
||||||
|
public void testReifiedIntersectionTypeArgumentCrossModule() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/reified/reifiedIntersectionTypeArgumentCrossModule.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("reifiedTypeArgumentWithIntersectionTypeAsTypeArgument.kt")
|
||||||
|
public void testReifiedTypeArgumentWithIntersectionTypeAsTypeArgument() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/reified/reifiedTypeArgumentWithIntersectionTypeAsTypeArgument.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("safecast.kt")
|
@TestMetadata("safecast.kt")
|
||||||
public void testSafecast() throws Exception {
|
public void testSafecast() throws Exception {
|
||||||
runTest("compiler/testData/codegen/box/reified/safecast.kt");
|
runTest("compiler/testData/codegen/box/reified/safecast.kt");
|
||||||
|
|||||||
+30
-11
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
* Copyright 2010-2020 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.
|
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@@ -23,13 +23,22 @@ import org.jetbrains.kotlin.js.translate.general.Translation;
|
|||||||
import org.jetbrains.kotlin.js.translate.intrinsic.functions.factories.ArrayFIF;
|
import org.jetbrains.kotlin.js.translate.intrinsic.functions.factories.ArrayFIF;
|
||||||
import org.jetbrains.kotlin.js.translate.intrinsic.functions.factories.TopLevelFIF;
|
import org.jetbrains.kotlin.js.translate.intrinsic.functions.factories.TopLevelFIF;
|
||||||
import org.jetbrains.kotlin.js.translate.reference.ReferenceTranslator;
|
import org.jetbrains.kotlin.js.translate.reference.ReferenceTranslator;
|
||||||
import org.jetbrains.kotlin.js.translate.utils.*;
|
import org.jetbrains.kotlin.js.translate.utils.AnnotationsUtils;
|
||||||
|
import org.jetbrains.kotlin.js.translate.utils.JsAstUtils;
|
||||||
|
import org.jetbrains.kotlin.js.translate.utils.TranslationUtils;
|
||||||
|
import org.jetbrains.kotlin.js.translate.utils.UtilsKt;
|
||||||
import org.jetbrains.kotlin.name.Name;
|
import org.jetbrains.kotlin.name.Name;
|
||||||
import org.jetbrains.kotlin.psi.*;
|
import org.jetbrains.kotlin.psi.KtBinaryExpressionWithTypeRHS;
|
||||||
|
import org.jetbrains.kotlin.psi.KtExpression;
|
||||||
|
import org.jetbrains.kotlin.psi.KtIsExpression;
|
||||||
|
import org.jetbrains.kotlin.psi.KtTypeReference;
|
||||||
import org.jetbrains.kotlin.resolve.DescriptorUtils;
|
import org.jetbrains.kotlin.resolve.DescriptorUtils;
|
||||||
import org.jetbrains.kotlin.resolve.checkers.PrimitiveNumericComparisonInfo;
|
import org.jetbrains.kotlin.resolve.checkers.PrimitiveNumericComparisonInfo;
|
||||||
|
import org.jetbrains.kotlin.types.IntersectionTypeConstructor;
|
||||||
import org.jetbrains.kotlin.types.KotlinType;
|
import org.jetbrains.kotlin.types.KotlinType;
|
||||||
|
import org.jetbrains.kotlin.types.TypeConstructor;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
|
|
||||||
import static org.jetbrains.kotlin.builtins.FunctionTypesKt.isFunctionTypeOrSubtype;
|
import static org.jetbrains.kotlin.builtins.FunctionTypesKt.isFunctionTypeOrSubtype;
|
||||||
@@ -165,14 +174,12 @@ public final class PatternTranslator extends AbstractTranslator {
|
|||||||
return getIsTypeCheckCallableForReifiedType(typeParameterDescriptor);
|
return getIsTypeCheckCallableForReifiedType(typeParameterDescriptor);
|
||||||
}
|
}
|
||||||
|
|
||||||
JsExpression result = null;
|
return getIsTypeCheckForAll(typeParameterDescriptor.getUpperBounds());
|
||||||
for (KotlinType upperBound : typeParameterDescriptor.getUpperBounds()) {
|
}
|
||||||
JsExpression next = doGetIsTypeCheckCallable(upperBound);
|
|
||||||
if (next != null) {
|
TypeConstructor typeConstructor = type.getConstructor();
|
||||||
result = result != null ? namer().andPredicate(result, next) : next;
|
if (typeConstructor instanceof IntersectionTypeConstructor) {
|
||||||
}
|
return getIsTypeCheckForAll(typeConstructor.getSupertypes());
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ClassDescriptor referencedClass = DescriptorUtils.getClassDescriptorForType(type);
|
ClassDescriptor referencedClass = DescriptorUtils.getClassDescriptorForType(type);
|
||||||
@@ -180,6 +187,18 @@ public final class PatternTranslator extends AbstractTranslator {
|
|||||||
return namer().isInstanceOf(typeName);
|
return namer().isInstanceOf(typeName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
private JsExpression getIsTypeCheckForAll(Collection<KotlinType> typesToCheck) {
|
||||||
|
JsExpression result = null;
|
||||||
|
for (KotlinType type : typesToCheck) {
|
||||||
|
JsExpression next = doGetIsTypeCheckCallable(type);
|
||||||
|
if (next != null) {
|
||||||
|
result = result != null ? namer().andPredicate(result, next) : next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
private JsExpression getIsTypeCheckCallableForBuiltin(@NotNull KotlinType type) {
|
private JsExpression getIsTypeCheckCallableForBuiltin(@NotNull KotlinType type) {
|
||||||
if ((isNotNullOrNullableFunctionSupertype(type) || isFunctionTypeOrSubtype(type)) &&
|
if ((isNotNullOrNullableFunctionSupertype(type) || isFunctionTypeOrSubtype(type)) &&
|
||||||
|
|||||||
+20
-3
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
* Copyright 2010-2020 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.
|
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@@ -50,7 +50,8 @@ class KTypeConstructor(val context: TranslationContext) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun createSimpleKType(type: SimpleType): JsExpression {
|
private fun createSimpleKType(type: SimpleType): JsExpression {
|
||||||
val classifier: ClassifierDescriptor = type.constructor.declarationDescriptor!!
|
val typeConstructor = type.constructor
|
||||||
|
val classifier = typeConstructor.declarationDescriptor
|
||||||
|
|
||||||
if (classifier is TypeParameterDescriptor && classifier.isReified) {
|
if (classifier is TypeParameterDescriptor && classifier.isReified) {
|
||||||
val kClassName = context.getNameForIntrinsic(SpecialFunction.GET_REIFIED_TYPE_PARAMETER_KTYPE.suggestedName)
|
val kClassName = context.getNameForIntrinsic(SpecialFunction.GET_REIFIED_TYPE_PARAMETER_KTYPE.suggestedName)
|
||||||
@@ -64,7 +65,23 @@ class KTypeConstructor(val context: TranslationContext) {
|
|||||||
return reifiedTypeParameterType
|
return reifiedTypeParameterType
|
||||||
}
|
}
|
||||||
|
|
||||||
val kClassifier = createKClassifier(classifier)
|
val kClassifier =
|
||||||
|
when {
|
||||||
|
classifier != null -> {
|
||||||
|
createKClassifier(classifier)
|
||||||
|
}
|
||||||
|
typeConstructor is IntersectionTypeConstructor -> {
|
||||||
|
val getKClassM = context.getNameForIntrinsic("getKClassM")
|
||||||
|
val args = JsArrayLiteral(
|
||||||
|
typeConstructor.supertypes.map { getReferenceToJsClass(it.constructor.declarationDescriptor, context) }
|
||||||
|
)
|
||||||
|
|
||||||
|
JsInvocation(getKClassM.makeRef(), args)
|
||||||
|
}
|
||||||
|
else -> {
|
||||||
|
error("Can't get KClass for $type")
|
||||||
|
}
|
||||||
|
}
|
||||||
val arguments = JsArrayLiteral(type.arguments.map { createKTypeProjection(it) })
|
val arguments = JsArrayLiteral(type.arguments.map { createKTypeProjection(it) })
|
||||||
val isMarkedNullable = JsBooleanLiteral(type.isMarkedNullable)
|
val isMarkedNullable = JsBooleanLiteral(type.isMarkedNullable)
|
||||||
return callHelperFunction(
|
return callHelperFunction(
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2010-2018 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
* Copyright 2010-2020 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.
|
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@@ -40,7 +40,6 @@ import org.jetbrains.kotlin.resolve.scopes.receivers.Receiver
|
|||||||
import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue
|
import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue
|
||||||
import org.jetbrains.kotlin.resolve.source.getPsi
|
import org.jetbrains.kotlin.resolve.source.getPsi
|
||||||
import org.jetbrains.kotlin.types.KotlinType
|
import org.jetbrains.kotlin.types.KotlinType
|
||||||
import org.jetbrains.kotlin.types.SimpleType
|
|
||||||
import org.jetbrains.kotlin.types.TypeUtils
|
import org.jetbrains.kotlin.types.TypeUtils
|
||||||
import org.jetbrains.kotlin.utils.DFS
|
import org.jetbrains.kotlin.utils.DFS
|
||||||
|
|
||||||
@@ -128,10 +127,17 @@ fun <T, S> List<T>.splitToRanges(classifier: (T) -> S): List<Pair<List<T>, S>> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun getReferenceToJsClass(type: KotlinType, context: TranslationContext): JsExpression =
|
fun getReferenceToJsClass(type: KotlinType, context: TranslationContext): JsExpression =
|
||||||
getReferenceToJsClass(type.constructor.declarationDescriptor, context).also {
|
getReferenceToJsClassOrArray(type, context).also {
|
||||||
it.kType = KTypeConstructor(context).createKType(type)
|
it.kType = KTypeConstructor(context).createKType(type)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun getReferenceToJsClassOrArray(type: KotlinType, context: TranslationContext): JsExpression {
|
||||||
|
val classifierDescriptor = type.constructor.declarationDescriptor
|
||||||
|
?: return JsArrayLiteral(type.constructor.supertypes.map { getReferenceToJsClass(it.constructor.declarationDescriptor, context) })
|
||||||
|
|
||||||
|
return getReferenceToJsClass(classifierDescriptor, context)
|
||||||
|
}
|
||||||
|
|
||||||
fun getReferenceToJsClass(classifierDescriptor: ClassifierDescriptor?, context: TranslationContext): JsExpression {
|
fun getReferenceToJsClass(classifierDescriptor: ClassifierDescriptor?, context: TranslationContext): JsExpression {
|
||||||
return when (classifierDescriptor) {
|
return when (classifierDescriptor) {
|
||||||
is ClassDescriptor -> {
|
is ClassDescriptor -> {
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2010-2018 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
* Copyright 2010-2020 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.
|
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@@ -62,5 +62,16 @@ internal object NothingKClassImpl : KClassImpl<Nothing>(js("Object")) {
|
|||||||
|
|
||||||
override fun equals(other: Any?): Boolean = other === this
|
override fun equals(other: Any?): Boolean = other === this
|
||||||
|
|
||||||
|
override fun hashCode(): Int = 0
|
||||||
|
}
|
||||||
|
|
||||||
|
internal class ErrorKClass : KClass<Nothing> {
|
||||||
|
override val simpleName: String? get() = error("Unknown simpleName for ErrorKClass")
|
||||||
|
override val qualifiedName: String? get() = error("Unknown qualifiedName for ErrorKClass")
|
||||||
|
|
||||||
|
override fun isInstance(value: Any?): Boolean = error("Can's check isInstance on ErrorKClass")
|
||||||
|
|
||||||
|
override fun equals(other: Any?): Boolean = other === this
|
||||||
|
|
||||||
override fun hashCode(): Int = 0
|
override fun hashCode(): Int = 0
|
||||||
}
|
}
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2010-2018 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
* Copyright 2010-2020 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.
|
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@@ -9,7 +9,20 @@ import kotlin.reflect.*
|
|||||||
import kotlin.reflect.js.internal.*
|
import kotlin.reflect.js.internal.*
|
||||||
|
|
||||||
@JsName("getKClass")
|
@JsName("getKClass")
|
||||||
internal fun <T : Any> getKClass(jClass: JsClass<T>): KClass<T> = getOrCreateKClass(jClass)
|
internal fun <T : Any> getKClass(jClass: Any /* JsClass<T> | Array<JsClass<T>> */): KClass<T> {
|
||||||
|
return if (js("Array").isArray(jClass)) {
|
||||||
|
getKClassM(jClass.unsafeCast<Array<JsClass<T>>>())
|
||||||
|
} else {
|
||||||
|
getKClass1(jClass.unsafeCast<JsClass<T>>())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@JsName("getKClassM")
|
||||||
|
internal fun <T : Any> getKClassM(jClasses: Array<JsClass<T>>): KClass<T> = when (jClasses.size) {
|
||||||
|
1 -> getKClass1(jClasses[0])
|
||||||
|
0 -> NothingKClassImpl.unsafeCast<KClass<T>>()
|
||||||
|
else -> ErrorKClass().unsafeCast<KClass<T>>()
|
||||||
|
}
|
||||||
|
|
||||||
@JsName("getKClassFromExpression")
|
@JsName("getKClassFromExpression")
|
||||||
internal fun <T : Any> getKClassFromExpression(e: T): KClass<T> =
|
internal fun <T : Any> getKClassFromExpression(e: T): KClass<T> =
|
||||||
@@ -37,7 +50,7 @@ internal fun <T : Any> getKClassFromExpression(e: T): KClass<T> =
|
|||||||
constructor === js("Error") -> PrimitiveClasses.throwableClass
|
constructor === js("Error") -> PrimitiveClasses.throwableClass
|
||||||
else -> {
|
else -> {
|
||||||
val jsClass: JsClass<T> = constructor
|
val jsClass: JsClass<T> = constructor
|
||||||
getOrCreateKClass(jsClass)
|
getKClass1(jsClass)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -45,7 +58,8 @@ internal fun <T : Any> getKClassFromExpression(e: T): KClass<T> =
|
|||||||
}
|
}
|
||||||
}.unsafeCast<KClass<T>>()
|
}.unsafeCast<KClass<T>>()
|
||||||
|
|
||||||
private fun <T : Any> getOrCreateKClass(jClass: JsClass<T>): KClass<T> {
|
@JsName("getKClass1")
|
||||||
|
internal fun <T : Any> getKClass1(jClass: JsClass<T>): KClass<T> {
|
||||||
if (jClass === js("String")) return PrimitiveClasses.stringClass.unsafeCast<KClass<T>>()
|
if (jClass === js("String")) return PrimitiveClasses.stringClass.unsafeCast<KClass<T>>()
|
||||||
|
|
||||||
val metadata = jClass.asDynamic().`$metadata$`
|
val metadata = jClass.asDynamic().`$metadata$`
|
||||||
|
|||||||
Reference in New Issue
Block a user