From 195274370f8f900e337b4beafc16f1970923512f Mon Sep 17 00:00:00 2001 From: Andrey Breslav Date: Mon, 30 Jun 2014 15:36:46 +0400 Subject: [PATCH] Fix the case of safe call and elvis operators: flexible types may be nullable --- .../resolve/calls/CallExpressionResolver.java | 5 ++-- .../safeCallOnTypeWithNullableUpperBound.kt | 4 +-- .../diagnostics/tests/platformTypes/elvis.kt | 14 ++++++++++ .../tests/platformTypes/safeCall.kt | 15 +++++++++++ .../checkers/JetDiagnosticsTestGenerated.java | 27 +++++++++++++++---- .../jetbrains/jet/lang/types/TypeUtils.java | 3 +++ 6 files changed, 59 insertions(+), 9 deletions(-) create mode 100644 compiler/testData/diagnostics/tests/platformTypes/elvis.kt create mode 100644 compiler/testData/diagnostics/tests/platformTypes/safeCall.kt diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/CallExpressionResolver.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/CallExpressionResolver.java index 623cc376f12..ba19ea0255c 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/CallExpressionResolver.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/CallExpressionResolver.java @@ -56,7 +56,8 @@ import java.util.Collections; import static org.jetbrains.jet.lang.diagnostics.Errors.*; import static org.jetbrains.jet.lang.resolve.calls.context.ContextDependency.INDEPENDENT; -import static org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiversPackage.*; +import static org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiversPackage.createQualifier; +import static org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiversPackage.resolveAsStandaloneExpression; import static org.jetbrains.jet.lang.types.TypeUtils.NO_EXPECTED_TYPE; public class CallExpressionResolver { @@ -300,7 +301,7 @@ public class CallExpressionResolver { //TODO move further if (expression.getOperationSign() == JetTokens.SAFE_ACCESS) { if (selectorReturnType != null && !KotlinBuiltIns.getInstance().isUnit(selectorReturnType)) { - if (receiverType.isNullable()) { + if (TypeUtils.isNullableType(receiverType)) { selectorReturnType = TypeUtils.makeNullable(selectorReturnType); } } diff --git a/compiler/testData/diagnostics/tests/nullableTypes/safeCallOnTypeWithNullableUpperBound.kt b/compiler/testData/diagnostics/tests/nullableTypes/safeCallOnTypeWithNullableUpperBound.kt index 1ab014ea1a8..cd310a55280 100644 --- a/compiler/testData/diagnostics/tests/nullableTypes/safeCallOnTypeWithNullableUpperBound.kt +++ b/compiler/testData/diagnostics/tests/nullableTypes/safeCallOnTypeWithNullableUpperBound.kt @@ -1,11 +1,11 @@ -fun test(t: T): String { +fun test(t: T): String? { if (t != null) { return t?.toString() } return t?.toString() } -fun T.testThis(): String { +fun T.testThis(): String? { if (this != null) { return this?.toString() } diff --git a/compiler/testData/diagnostics/tests/platformTypes/elvis.kt b/compiler/testData/diagnostics/tests/platformTypes/elvis.kt new file mode 100644 index 00000000000..aa64609c86f --- /dev/null +++ b/compiler/testData/diagnostics/tests/platformTypes/elvis.kt @@ -0,0 +1,14 @@ +// FILE: p/J.java + +package p; + +public class J { + public String s() { return null; } +} + +// FILE: k.kt +import p.* + +fun test(j: J) { + j.s()?.length ?: "" +} \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/platformTypes/safeCall.kt b/compiler/testData/diagnostics/tests/platformTypes/safeCall.kt new file mode 100644 index 00000000000..2c67f98cc28 --- /dev/null +++ b/compiler/testData/diagnostics/tests/platformTypes/safeCall.kt @@ -0,0 +1,15 @@ +// !CHECK_TYPE +// FILE: p/J.java + +package p; + +public class J { + public String s() { return null; } +} + +// FILE: k.kt +import p.* + +fun test(j: J) { + j.s()?.length.checkType { it : _ } +} \ No newline at end of file diff --git a/compiler/tests/org/jetbrains/jet/checkers/JetDiagnosticsTestGenerated.java b/compiler/tests/org/jetbrains/jet/checkers/JetDiagnosticsTestGenerated.java index c2cb657d95f..96c2cd25387 100644 --- a/compiler/tests/org/jetbrains/jet/checkers/JetDiagnosticsTestGenerated.java +++ b/compiler/tests/org/jetbrains/jet/checkers/JetDiagnosticsTestGenerated.java @@ -7697,7 +7697,20 @@ public class JetDiagnosticsTestGenerated extends AbstractJetDiagnosticsTest { @TestMetadata("dereference.kt") public void testDereference() throws Exception { - doTest("compiler/testData/diagnostics/tests/platformTypes/dereference.kt"); + String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/platformTypes/dereference.kt"); + doTest(fileName); + } + + @TestMetadata("elvis.kt") + public void testElvis() throws Exception { + String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/platformTypes/elvis.kt"); + doTest(fileName); + } + + @TestMetadata("safeCall.kt") + public void testSafeCall() throws Exception { + String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/platformTypes/safeCall.kt"); + doTest(fileName); } @TestMetadata("compiler/testData/diagnostics/tests/platformTypes/methodCall") @@ -7722,22 +7735,26 @@ public class JetDiagnosticsTestGenerated extends AbstractJetDiagnosticsTest { @TestMetadata("javaCollectionToKotlin.kt") public void testJavaCollectionToKotlin() throws Exception { - doTest("compiler/testData/diagnostics/tests/platformTypes/methodCall/javaCollectionToKotlin.kt"); + String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/platformTypes/methodCall/javaCollectionToKotlin.kt"); + doTest(fileName); } @TestMetadata("javaToJava.kt") public void testJavaToJava() throws Exception { - doTest("compiler/testData/diagnostics/tests/platformTypes/methodCall/javaToJava.kt"); + String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/platformTypes/methodCall/javaToJava.kt"); + doTest(fileName); } @TestMetadata("javaToKotlin.kt") public void testJavaToKotlin() throws Exception { - doTest("compiler/testData/diagnostics/tests/platformTypes/methodCall/javaToKotlin.kt"); + String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/platformTypes/methodCall/javaToKotlin.kt"); + doTest(fileName); } @TestMetadata("kotlinCollectionToJava.kt") public void testKotlinCollectionToJava() throws Exception { - doTest("compiler/testData/diagnostics/tests/platformTypes/methodCall/kotlinCollectionToJava.kt"); + String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/platformTypes/methodCall/kotlinCollectionToJava.kt"); + doTest(fileName); } @TestMetadata("list.kt") diff --git a/core/descriptors/src/org/jetbrains/jet/lang/types/TypeUtils.java b/core/descriptors/src/org/jetbrains/jet/lang/types/TypeUtils.java index 28bb00a17f2..57eb82b504c 100644 --- a/core/descriptors/src/org/jetbrains/jet/lang/types/TypeUtils.java +++ b/core/descriptors/src/org/jetbrains/jet/lang/types/TypeUtils.java @@ -423,6 +423,9 @@ public class TypeUtils { if (type.getConstructor().getDeclarationDescriptor() instanceof TypeParameterDescriptor) { return hasNullableSuperType(type); } + if (TypesPackage.isFlexible(type) && isNullableType(((FlexibleType) type).getUpperBound())) { + return true; + } return false; }