[CJS BE] don't crash when intersection types passed for a reified parameter
#KT-37163 Fixed
This commit is contained in:
Generated
+15
@@ -20577,6 +20577,21 @@ public class IrJsCodegenBoxTestGenerated extends AbstractIrJsCodegenBoxTest {
|
||||
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")
|
||||
public void testSafecast() throws Exception {
|
||||
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");
|
||||
}
|
||||
|
||||
@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")
|
||||
public void testSafecast() throws Exception {
|
||||
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.
|
||||
*/
|
||||
|
||||
@@ -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.TopLevelFIF;
|
||||
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.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.checkers.PrimitiveNumericComparisonInfo;
|
||||
import org.jetbrains.kotlin.types.IntersectionTypeConstructor;
|
||||
import org.jetbrains.kotlin.types.KotlinType;
|
||||
import org.jetbrains.kotlin.types.TypeConstructor;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
|
||||
import static org.jetbrains.kotlin.builtins.FunctionTypesKt.isFunctionTypeOrSubtype;
|
||||
@@ -165,14 +174,12 @@ public final class PatternTranslator extends AbstractTranslator {
|
||||
return getIsTypeCheckCallableForReifiedType(typeParameterDescriptor);
|
||||
}
|
||||
|
||||
JsExpression result = null;
|
||||
for (KotlinType upperBound : typeParameterDescriptor.getUpperBounds()) {
|
||||
JsExpression next = doGetIsTypeCheckCallable(upperBound);
|
||||
if (next != null) {
|
||||
result = result != null ? namer().andPredicate(result, next) : next;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
return getIsTypeCheckForAll(typeParameterDescriptor.getUpperBounds());
|
||||
}
|
||||
|
||||
TypeConstructor typeConstructor = type.getConstructor();
|
||||
if (typeConstructor instanceof IntersectionTypeConstructor) {
|
||||
return getIsTypeCheckForAll(typeConstructor.getSupertypes());
|
||||
}
|
||||
|
||||
ClassDescriptor referencedClass = DescriptorUtils.getClassDescriptorForType(type);
|
||||
@@ -180,6 +187,18 @@ public final class PatternTranslator extends AbstractTranslator {
|
||||
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
|
||||
private JsExpression getIsTypeCheckCallableForBuiltin(@NotNull KotlinType 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.
|
||||
*/
|
||||
|
||||
@@ -50,7 +50,8 @@ class KTypeConstructor(val context: TranslationContext) {
|
||||
}
|
||||
|
||||
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) {
|
||||
val kClassName = context.getNameForIntrinsic(SpecialFunction.GET_REIFIED_TYPE_PARAMETER_KTYPE.suggestedName)
|
||||
@@ -64,7 +65,23 @@ class KTypeConstructor(val context: TranslationContext) {
|
||||
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 isMarkedNullable = JsBooleanLiteral(type.isMarkedNullable)
|
||||
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.
|
||||
*/
|
||||
|
||||
@@ -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.source.getPsi
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
import org.jetbrains.kotlin.types.SimpleType
|
||||
import org.jetbrains.kotlin.types.TypeUtils
|
||||
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 =
|
||||
getReferenceToJsClass(type.constructor.declarationDescriptor, context).also {
|
||||
getReferenceToJsClassOrArray(type, context).also {
|
||||
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 {
|
||||
return when (classifierDescriptor) {
|
||||
is ClassDescriptor -> {
|
||||
|
||||
Reference in New Issue
Block a user