JS/RTTI: fix cast to Any
This commit is contained in:
committed by
Alexey Andreev
parent
2b3ebc7e9f
commit
38b0effe15
+2
-1
@@ -62,5 +62,6 @@ var HasMetadata.sideEffects: Boolean by MetadataProperty(default = true)
|
||||
enum class TypeCheck {
|
||||
TYPEOF,
|
||||
INSTANCEOF,
|
||||
OR_NULL
|
||||
OR_NULL,
|
||||
IS_ANY
|
||||
}
|
||||
|
||||
@@ -35,6 +35,12 @@ public class CastTestGenerated extends AbstractCastTest {
|
||||
JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("js/js.translator/testData/expression/cast/cases"), Pattern.compile("^(.+)\\.kt$"), true);
|
||||
}
|
||||
|
||||
@TestMetadata("castToAny.kt")
|
||||
public void testCastToAny() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("js/js.translator/testData/expression/cast/cases/castToAny.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("castToGenericType.kt")
|
||||
public void testCastToGenericType() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("js/js.translator/testData/expression/cast/cases/castToGenericType.kt");
|
||||
|
||||
@@ -22,6 +22,8 @@ import com.google.dart.compiler.backend.js.ast.metadata.MetadataProperties;
|
||||
import com.google.dart.compiler.backend.js.ast.metadata.TypeCheck;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns;
|
||||
import org.jetbrains.kotlin.descriptors.CallableDescriptor;
|
||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor;
|
||||
import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor;
|
||||
@@ -399,13 +401,23 @@ public final class Namer {
|
||||
return invokeFunctionAndSetTypeCheckMetadata("orNull", callable, TypeCheck.OR_NULL);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public JsExpression isAny() {
|
||||
return invokeFunctionAndSetTypeCheckMetadata("isAny", null, TypeCheck.IS_ANY);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private JsExpression invokeFunctionAndSetTypeCheckMetadata(
|
||||
@NotNull String functionName,
|
||||
@NotNull JsExpression argument,
|
||||
@Nullable JsExpression argument,
|
||||
@NotNull TypeCheck metadata
|
||||
) {
|
||||
JsInvocation invocation = new JsInvocation(kotlin(functionName), argument);
|
||||
JsInvocation invocation = new JsInvocation(kotlin(functionName));
|
||||
|
||||
if (argument != null) {
|
||||
invocation.getArguments().add(argument);
|
||||
}
|
||||
|
||||
MetadataProperties.setTypeCheck(invocation, metadata);
|
||||
MetadataProperties.setSideEffects(invocation, false);
|
||||
return invocation;
|
||||
|
||||
+3
@@ -25,6 +25,7 @@ import com.google.dart.compiler.backend.js.ast.*;
|
||||
import com.google.dart.compiler.backend.js.ast.metadata.MetadataPackage;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns;
|
||||
import org.jetbrains.kotlin.descriptors.*;
|
||||
import org.jetbrains.kotlin.js.descriptorUtils.DescriptorUtilsKt;
|
||||
import org.jetbrains.kotlin.js.patterns.NamePredicate;
|
||||
@@ -116,6 +117,8 @@ public final class PatternTranslator extends AbstractTranslator {
|
||||
|
||||
@NotNull
|
||||
private JsExpression doGetIsTypeCheckCallable(@NotNull KotlinType type) {
|
||||
if (KotlinBuiltIns.isAnyOrNullableAny(type)) return namer().isAny();
|
||||
|
||||
JsExpression builtinCheck = getIsTypeCheckCallableForBuiltin(type);
|
||||
if (builtinCheck != null) return builtinCheck;
|
||||
|
||||
|
||||
@@ -68,7 +68,7 @@ private class TypeCheckRewritingVisitor(private val context: TranslationContext)
|
||||
val calleeArgument = callee?.arguments?.firstOrNull()
|
||||
val argument = x.arguments.firstOrNull()
|
||||
|
||||
if (callee != null && calleeArgument != null && argument != null) {
|
||||
if (callee != null && argument != null) {
|
||||
val replacement = getReplacement(callee, calleeArgument, argument)
|
||||
|
||||
if (replacement != null) {
|
||||
@@ -80,7 +80,16 @@ private class TypeCheckRewritingVisitor(private val context: TranslationContext)
|
||||
return true
|
||||
}
|
||||
|
||||
private fun getReplacement(callee: JsInvocation, calleeArgument: JsExpression, argument: JsExpression): JsExpression? {
|
||||
private fun getReplacement(callee: JsInvocation, calleeArgument: JsExpression?, argument: JsExpression): JsExpression? {
|
||||
if (calleeArgument == null) {
|
||||
// Kotlin.isAny()(argument) -> argument != null
|
||||
if (callee.typeCheck == TypeCheck.IS_ANY) {
|
||||
return TranslationUtils.isNotNullCheck(argument)
|
||||
}
|
||||
|
||||
return null
|
||||
}
|
||||
|
||||
// Kotlin.isTypeOf(calleeArgument)(argument) -> typeOf argument === calleeArgument
|
||||
if (callee.typeCheck == TypeCheck.TYPEOF) {
|
||||
return typeOfIs(argument, calleeArgument as JsStringLiteral)
|
||||
@@ -93,8 +102,10 @@ private class TypeCheckRewritingVisitor(private val context: TranslationContext)
|
||||
|
||||
// Kotlin.orNull(calleeArgument)(argument) -> (tmp = argument) == null || calleeArgument(tmp)
|
||||
if (callee.typeCheck == TypeCheck.OR_NULL) {
|
||||
if (calleeArgument is JsInvocation && calleeArgument.typeCheck == TypeCheck.OR_NULL) {
|
||||
return JsInvocation(calleeArgument, argument)
|
||||
if (calleeArgument is JsInvocation) {
|
||||
if (calleeArgument.typeCheck == TypeCheck.OR_NULL) return JsInvocation(calleeArgument, argument)
|
||||
|
||||
if (calleeArgument.typeCheck == TypeCheck.IS_ANY) return argument
|
||||
}
|
||||
|
||||
var nullCheckTarget = argument
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
package foo
|
||||
|
||||
fun box(): String {
|
||||
val x = 0
|
||||
val y = 1
|
||||
val z = 2
|
||||
val xs = arrayListOf(z, y, x)
|
||||
xs.remove(x as Any)
|
||||
assertEquals(listOf(z, y), xs)
|
||||
|
||||
return "OK"
|
||||
}
|
||||
@@ -555,6 +555,12 @@ var Kotlin = {};
|
||||
}
|
||||
};
|
||||
|
||||
Kotlin.isAny = function () {
|
||||
return function (object) {
|
||||
return object != null;
|
||||
}
|
||||
};
|
||||
|
||||
Kotlin.kotlinModuleMetadata = function (abiVersion, moduleName, data) {
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user