JS backend: fixed wrong NPE when casting to generic type.
This commit is contained in:
@@ -32,6 +32,10 @@ public final class CastTest extends AbstractExpressionTest {
|
||||
checkFooBoxIsOk();
|
||||
}
|
||||
|
||||
public void testCastToGenericType() throws Exception {
|
||||
checkFooBoxIsOk();
|
||||
}
|
||||
|
||||
public void testSmartCastInExtensionFunction() throws Exception {
|
||||
checkFooBoxIsOk();
|
||||
}
|
||||
|
||||
@@ -17,7 +17,6 @@
|
||||
package org.jetbrains.k2js.translate.expression;
|
||||
|
||||
import com.google.dart.compiler.backend.js.ast.*;
|
||||
import com.intellij.psi.tree.IElementType;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor;
|
||||
@@ -29,6 +28,7 @@ import org.jetbrains.jet.lang.resolve.BindingContextUtils;
|
||||
import org.jetbrains.jet.lang.resolve.constants.CompileTimeConstant;
|
||||
import org.jetbrains.jet.lang.resolve.constants.NullValue;
|
||||
import org.jetbrains.jet.lang.types.JetType;
|
||||
import org.jetbrains.jet.lang.types.TypeUtils;
|
||||
import org.jetbrains.jet.lexer.JetTokens;
|
||||
import org.jetbrains.k2js.translate.context.TemporaryVariable;
|
||||
import org.jetbrains.k2js.translate.context.TranslationContext;
|
||||
@@ -347,9 +347,12 @@ public final class ExpressionVisitor extends TranslatorVisitor<JsNode> {
|
||||
if (expression.getOperationReference().getReferencedNameElementType() != JetTokens.AS_KEYWORD)
|
||||
return jsExpression.source(expression);
|
||||
|
||||
JetType rightType = BindingContextUtils.getNotNull(context.bindingContext(), BindingContext.TYPE, expression.getRight());
|
||||
JetTypeReference right = expression.getRight();
|
||||
assert right != null;
|
||||
|
||||
JetType rightType = BindingContextUtils.getNotNull(context.bindingContext(), BindingContext.TYPE, right);
|
||||
JetType leftType = BindingContextUtils.getNotNull(context.bindingContext(), BindingContext.EXPRESSION_TYPE, expression.getLeft());
|
||||
if (rightType.isNullable() || !leftType.isNullable()) {
|
||||
if (TypeUtils.isNullableType(rightType) || !TypeUtils.isNullableType(leftType)) {
|
||||
return jsExpression.source(expression);
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,74 @@
|
||||
package foo
|
||||
|
||||
class A(val s: String)
|
||||
|
||||
fun castsNotNullToNullableT<T>(a: Any) {
|
||||
a as T
|
||||
a as T?
|
||||
a as? T
|
||||
a as? T?
|
||||
}
|
||||
|
||||
fun castsNullableToNullableT<T>(a: Any?) {
|
||||
a as T
|
||||
a as T?
|
||||
a as? T
|
||||
a as? T?
|
||||
}
|
||||
|
||||
|
||||
fun castsNotNullToNotNullT<T : Any>(a: Any) {
|
||||
a as T
|
||||
a as T?
|
||||
a as? T
|
||||
a as? T?
|
||||
}
|
||||
|
||||
fun castNullableToNotNullT<T : Any>(a: Any?) {
|
||||
a as T
|
||||
}
|
||||
|
||||
fun castsNullableToNotNullT<T : Any>(a: Any?) {
|
||||
a as T?
|
||||
a as? T
|
||||
a as? T?
|
||||
}
|
||||
|
||||
fun test(f: () -> Unit) {
|
||||
try {
|
||||
f()
|
||||
}
|
||||
catch(e: Exception) {
|
||||
throw Exception("Failed in $f with unexpected exception $e")
|
||||
}
|
||||
}
|
||||
|
||||
fun fails(f: () -> Unit) {
|
||||
try {
|
||||
f()
|
||||
}
|
||||
catch(e: Exception) {
|
||||
return
|
||||
}
|
||||
|
||||
throw Exception("Expected an exception to be thrown from $f")
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
val a = A("OK")
|
||||
|
||||
test { castsNotNullToNullableT<A>(a) }
|
||||
|
||||
test { castsNullableToNullableT<A>(a) }
|
||||
test { castsNullableToNullableT<A>(null) }
|
||||
|
||||
test { castsNotNullToNotNullT<A>(a) }
|
||||
|
||||
test { castsNullableToNotNullT<A>(a) }
|
||||
test { castsNullableToNotNullT<A>(null) }
|
||||
|
||||
test { castNullableToNotNullT<A>(a) }
|
||||
fails { castNullableToNotNullT<A>(null) }
|
||||
|
||||
return "OK"
|
||||
}
|
||||
Reference in New Issue
Block a user