From 5b315608086c7396605327fdad0bb50a5e78565e Mon Sep 17 00:00:00 2001 From: Mikhail Glukhikh Date: Tue, 4 Aug 2015 15:35:15 +0300 Subject: [PATCH] x?.y is now nullable even if y is Unit + three tests + codegen test fix + source code fix #KT-7936 Fixed #KT-8347 Fixed --- .../resolve/calls/CallExpressionResolver.java | 2 +- .../codegen/box/extensionFunctions/kt606.kt | 4 +++- .../diagnostics/tests/nullableTypes/elvisOnUnit.kt | 11 +++++++++++ .../diagnostics/tests/nullableTypes/elvisOnUnit.txt | 12 ++++++++++++ .../tests/nullableTypes/safeAccessOnUnit.kt | 7 +++++++ .../tests/nullableTypes/safeAccessOnUnit.txt | 13 +++++++++++++ .../diagnostics/testsWithStdLib/elvisOnUnitInLet.kt | 9 +++++++++ .../testsWithStdLib/elvisOnUnitInLet.txt | 5 +++++ .../checkers/JetDiagnosticsTestGenerated.java | 12 ++++++++++++ .../JetDiagnosticsTestWithStdLibGenerated.java | 6 ++++++ .../idea/quickfix/MigrateAnnotationMethodCallFix.kt | 2 +- 11 files changed, 80 insertions(+), 3 deletions(-) create mode 100644 compiler/testData/diagnostics/tests/nullableTypes/elvisOnUnit.kt create mode 100644 compiler/testData/diagnostics/tests/nullableTypes/elvisOnUnit.txt create mode 100644 compiler/testData/diagnostics/tests/nullableTypes/safeAccessOnUnit.kt create mode 100644 compiler/testData/diagnostics/tests/nullableTypes/safeAccessOnUnit.txt create mode 100644 compiler/testData/diagnostics/testsWithStdLib/elvisOnUnitInLet.kt create mode 100644 compiler/testData/diagnostics/testsWithStdLib/elvisOnUnitInLet.txt diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/CallExpressionResolver.java b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/CallExpressionResolver.java index 20c69567c1d..891b15f369e 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/CallExpressionResolver.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/CallExpressionResolver.java @@ -373,7 +373,7 @@ public class CallExpressionResolver { //TODO move further if (safeCall) { - if (selectorReturnType != null && !KotlinBuiltIns.isUnit(selectorReturnType)) { + if (selectorReturnType != null) { if (TypeUtils.isNullableType(receiverType)) { selectorReturnType = TypeUtils.makeNullable(selectorReturnType); selectorReturnTypeInfo = selectorReturnTypeInfo.replaceType(selectorReturnType); diff --git a/compiler/testData/codegen/box/extensionFunctions/kt606.kt b/compiler/testData/codegen/box/extensionFunctions/kt606.kt index 5e1de696f70..62f7c9035d5 100644 --- a/compiler/testData/codegen/box/extensionFunctions/kt606.kt +++ b/compiler/testData/codegen/box/extensionFunctions/kt606.kt @@ -15,7 +15,9 @@ interface ChannelPipeline { } class DefaultChannelPipeline : ChannelPipeline { - override fun print(any: Any) = System.out?.println(any) + override fun print(any: Any) { + System.out?.println(any) + } } diff --git a/compiler/testData/diagnostics/tests/nullableTypes/elvisOnUnit.kt b/compiler/testData/diagnostics/tests/nullableTypes/elvisOnUnit.kt new file mode 100644 index 00000000000..87606001595 --- /dev/null +++ b/compiler/testData/diagnostics/tests/nullableTypes/elvisOnUnit.kt @@ -0,0 +1,11 @@ +class My { + fun other() {} +} + +fun another() {} + +fun foo(x: My?) { + // Both elvis parts should be alive + // See also KT-7936, KT-8347 + x?.other() ?: another() +} \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/nullableTypes/elvisOnUnit.txt b/compiler/testData/diagnostics/tests/nullableTypes/elvisOnUnit.txt new file mode 100644 index 00000000000..c024e68eb7c --- /dev/null +++ b/compiler/testData/diagnostics/tests/nullableTypes/elvisOnUnit.txt @@ -0,0 +1,12 @@ +package + +internal fun another(): kotlin.Unit +internal fun foo(/*0*/ x: My?): kotlin.Unit + +internal final class My { + public constructor My() + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + internal final fun other(): kotlin.Unit + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} diff --git a/compiler/testData/diagnostics/tests/nullableTypes/safeAccessOnUnit.kt b/compiler/testData/diagnostics/tests/nullableTypes/safeAccessOnUnit.kt new file mode 100644 index 00000000000..e9904a7da75 --- /dev/null +++ b/compiler/testData/diagnostics/tests/nullableTypes/safeAccessOnUnit.kt @@ -0,0 +1,7 @@ +data class My(val x: Unit) + +fun foo(my: My?): Int? { + val x = my?.x + // ?. is required here + return x?.hashCode() +} \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/nullableTypes/safeAccessOnUnit.txt b/compiler/testData/diagnostics/tests/nullableTypes/safeAccessOnUnit.txt new file mode 100644 index 00000000000..f242831cec7 --- /dev/null +++ b/compiler/testData/diagnostics/tests/nullableTypes/safeAccessOnUnit.txt @@ -0,0 +1,13 @@ +package + +internal fun foo(/*0*/ my: My?): kotlin.Int? + +kotlin.data() internal final class My { + public constructor My(/*0*/ x: kotlin.Unit) + internal final val x: kotlin.Unit + internal final /*synthesized*/ fun component1(): kotlin.Unit + public final /*synthesized*/ fun copy(/*0*/ x: kotlin.Unit = ...): My + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} diff --git a/compiler/testData/diagnostics/testsWithStdLib/elvisOnUnitInLet.kt b/compiler/testData/diagnostics/testsWithStdLib/elvisOnUnitInLet.kt new file mode 100644 index 00000000000..a4e9d5b483f --- /dev/null +++ b/compiler/testData/diagnostics/testsWithStdLib/elvisOnUnitInLet.kt @@ -0,0 +1,9 @@ +fun foo(x: Int?) { + // Both parts of the Elvis should be alive, see KT-7936 + x?.let { + smth() + }?: orElse() +} + +fun smth() {} +fun orElse() {} \ No newline at end of file diff --git a/compiler/testData/diagnostics/testsWithStdLib/elvisOnUnitInLet.txt b/compiler/testData/diagnostics/testsWithStdLib/elvisOnUnitInLet.txt new file mode 100644 index 00000000000..d4518d65ea6 --- /dev/null +++ b/compiler/testData/diagnostics/testsWithStdLib/elvisOnUnitInLet.txt @@ -0,0 +1,5 @@ +package + +internal fun foo(/*0*/ x: kotlin.Int?): kotlin.Unit +internal fun orElse(): kotlin.Unit +internal fun smth(): kotlin.Unit diff --git a/compiler/tests/org/jetbrains/kotlin/checkers/JetDiagnosticsTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/checkers/JetDiagnosticsTestGenerated.java index ca63fe5a4f2..eda4793cbe1 100644 --- a/compiler/tests/org/jetbrains/kotlin/checkers/JetDiagnosticsTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/checkers/JetDiagnosticsTestGenerated.java @@ -9417,6 +9417,12 @@ public class JetDiagnosticsTestGenerated extends AbstractJetDiagnosticsTest { doTest(fileName); } + @TestMetadata("elvisOnUnit.kt") + public void testElvisOnUnit() throws Exception { + String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/nullableTypes/elvisOnUnit.kt"); + doTest(fileName); + } + @TestMetadata("nullAssertOnTypeWithNullableUpperBound.kt") public void testNullAssertOnTypeWithNullableUpperBound() throws Exception { String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/nullableTypes/nullAssertOnTypeWithNullableUpperBound.kt"); @@ -9441,6 +9447,12 @@ public class JetDiagnosticsTestGenerated extends AbstractJetDiagnosticsTest { doTest(fileName); } + @TestMetadata("safeAccessOnUnit.kt") + public void testSafeAccessOnUnit() throws Exception { + String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/nullableTypes/safeAccessOnUnit.kt"); + doTest(fileName); + } + @TestMetadata("safeCallOnTypeWithNullableUpperBound.kt") public void testSafeCallOnTypeWithNullableUpperBound() throws Exception { String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/nullableTypes/safeCallOnTypeWithNullableUpperBound.kt"); diff --git a/compiler/tests/org/jetbrains/kotlin/checkers/JetDiagnosticsTestWithStdLibGenerated.java b/compiler/tests/org/jetbrains/kotlin/checkers/JetDiagnosticsTestWithStdLibGenerated.java index 29e922cebd7..9f8aad13310 100644 --- a/compiler/tests/org/jetbrains/kotlin/checkers/JetDiagnosticsTestWithStdLibGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/checkers/JetDiagnosticsTestWithStdLibGenerated.java @@ -35,6 +35,12 @@ public class JetDiagnosticsTestWithStdLibGenerated extends AbstractJetDiagnostic JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/diagnostics/testsWithStdLib"), Pattern.compile("^(.+)\\.kt$"), true); } + @TestMetadata("elvisOnUnitInLet.kt") + public void testElvisOnUnitInLet() throws Exception { + String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/testsWithStdLib/elvisOnUnitInLet.kt"); + doTest(fileName); + } + @TestMetadata("instar.kt") public void testInstar() throws Exception { String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/testsWithStdLib/instar.kt"); diff --git a/idea/src/org/jetbrains/kotlin/idea/quickfix/MigrateAnnotationMethodCallFix.kt b/idea/src/org/jetbrains/kotlin/idea/quickfix/MigrateAnnotationMethodCallFix.kt index c0e4f5dfe0d..c9ad4572bea 100644 --- a/idea/src/org/jetbrains/kotlin/idea/quickfix/MigrateAnnotationMethodCallFix.kt +++ b/idea/src/org/jetbrains/kotlin/idea/quickfix/MigrateAnnotationMethodCallFix.kt @@ -59,7 +59,7 @@ class MigrateAnnotationMethodCallInWholeFile : IntentionAction { forEach { (it.getPsiElement() as? JetCallExpression)?.let { MigrateAnnotationMethodCallFix.replaceWithSimpleCall(it) } } - } + } ?: Unit companion object : JetSingleIntentionActionFactory() { override fun createAction(diagnostic: Diagnostic) = MigrateAnnotationMethodCallInWholeFile()