JS backend: fixed wrong NPE when casting to generic type.

This commit is contained in:
Zalim Bashorov
2014-06-23 20:10:35 +04:00
parent 0d0751c3f9
commit 444932d4c1
3 changed files with 84 additions and 3 deletions
@@ -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"
}