dynamic receiver admits nullable values

This commit is contained in:
Andrey Breslav
2014-11-20 17:12:48 +03:00
parent ef34b5c9a9
commit 1f66c64ee0
5 changed files with 31 additions and 4 deletions
@@ -597,8 +597,7 @@ public class CandidateResolver {
BindingContext bindingContext = trace.getBindingContext();
if (!safeAccess && !receiverParameter.getType().isNullable() && receiverArgumentType.isNullable()) {
if (!SmartCastUtils.isNotNull(receiverArgument, bindingContext, context.dataFlowInfo)) {
if (!SmartCastUtils.canBeSmartCast(receiverParameter, receiverArgument, bindingContext, context.dataFlowInfo)) {
context.tracing.unsafeCall(trace, receiverArgumentType, implicitInvokeCheck);
return UNSAFE_CALL_ERROR;
}
@@ -22,6 +22,7 @@ import kotlin.Function1;
import kotlin.KotlinPackage;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.descriptors.ReceiverParameterDescriptor;
import org.jetbrains.jet.lang.psi.JetExpression;
import org.jetbrains.jet.lang.resolve.BindingContext;
import org.jetbrains.jet.lang.resolve.BindingTrace;
@@ -183,7 +184,8 @@ public class SmartCastUtils {
}
}
public static boolean isNotNull(
public static boolean canBeSmartCast(
@NotNull ReceiverParameterDescriptor receiverParameter,
@NotNull ReceiverValue receiver,
@NotNull BindingContext bindingContext,
@NotNull DataFlowInfo dataFlowInfo
@@ -192,7 +194,7 @@ public class SmartCastUtils {
List<JetType> smartCastVariants = getSmartCastVariants(receiver, bindingContext, dataFlowInfo);
for (JetType smartCastVariant : smartCastVariants) {
if (!smartCastVariant.isNullable()) return true;
if (JetTypeChecker.DEFAULT.isSubtypeOf(smartCastVariant, receiverParameter.getType())) return true;
}
return false;
}
@@ -0,0 +1,16 @@
// !MARK_DYNAMIC_CALLS
// MODULE[js]: m1
// FILE: k.kt
fun foo() {
dynamic {
<!DEBUG_INFO_DYNAMIC!>foo<!>()
<!DEBUG_INFO_DYNAMIC!>bar<!>.<!DEBUG_INFO_DYNAMIC!>baz<!>(0)
}
}
fun dynamic<T>(body: dynamic.() -> T): T {
val topLevel = null
return topLevel.body()
}
@@ -0,0 +1,4 @@
package
internal fun </*0*/ T> dynamic(/*0*/ body: dynamic.() -> T): T
internal fun foo(): kotlin.Unit
@@ -3722,6 +3722,12 @@ public class JetDiagnosticsTestGenerated extends AbstractJetDiagnosticsTest {
doTest(fileName);
}
@TestMetadata("block.kt")
public void testBlock() throws Exception {
String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/dynamicTypes/block.kt");
doTest(fileName);
}
@TestMetadata("dynamicCalls.kt")
public void testDynamicCalls() throws Exception {
String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/dynamicTypes/dynamicCalls.kt");