From 7bb84c139ddc4993a83f0a2bf4ed5d8356bd6f69 Mon Sep 17 00:00:00 2001 From: Valentin Kipyatkov Date: Wed, 7 May 2014 17:52:51 +0400 Subject: [PATCH] Smart completion: fixed logic in elvis operator --- .../jet/plugin/completion/ExpectedInfos.kt | 17 +++++++++------- .../completion/smart/InElvisOperator3.kt | 20 +++++++++++++++++++ .../completion/smart/InElvisOperator4.kt | 20 +++++++++++++++++++ .../completion/smart/InElvisOperator5.kt | 20 +++++++++++++++++++ .../completion/smart/InElvisOperator6.kt | 20 +++++++++++++++++++ .../JvmSmartCompletionTestGenerated.java | 20 +++++++++++++++++++ 6 files changed, 110 insertions(+), 7 deletions(-) create mode 100644 idea/testData/completion/smart/InElvisOperator3.kt create mode 100644 idea/testData/completion/smart/InElvisOperator4.kt create mode 100644 idea/testData/completion/smart/InElvisOperator5.kt create mode 100644 idea/testData/completion/smart/InElvisOperator6.kt diff --git a/idea/src/org/jetbrains/jet/plugin/completion/ExpectedInfos.kt b/idea/src/org/jetbrains/jet/plugin/completion/ExpectedInfos.kt index 09dc57e2726..d7a5ae2617f 100644 --- a/idea/src/org/jetbrains/jet/plugin/completion/ExpectedInfos.kt +++ b/idea/src/org/jetbrains/jet/plugin/completion/ExpectedInfos.kt @@ -51,6 +51,8 @@ import org.jetbrains.jet.lang.resolve.calls.util.noErrorsInValueArguments import org.jetbrains.jet.lang.resolve.calls.util.hasUnmappedParameters import org.jetbrains.jet.lang.descriptors.Visibilities import org.jetbrains.jet.lang.psi.JetBlockExpression +import org.jetbrains.jet.plugin.util.makeNullable +import org.jetbrains.jet.plugin.util.makeNotNullable enum class Tail { COMMA @@ -161,7 +163,7 @@ class ExpectedInfos(val bindingContext: BindingContext, val moduleDescriptor: Mo val otherOperand = if (expressionWithType == binaryExpression.getRight()) binaryExpression.getLeft() else binaryExpression.getRight() if (otherOperand != null) { val expressionType = bindingContext[BindingContext.EXPRESSION_TYPE, otherOperand] ?: return null - return listOf(ExpectedInfo(TypeUtils.makeNullable(expressionType), null)) + return listOf(ExpectedInfo(expressionType.makeNullable(), null)) } } } @@ -193,17 +195,18 @@ class ExpectedInfos(val bindingContext: BindingContext, val moduleDescriptor: Mo if (binaryExpression != null) { val operationToken = binaryExpression.getOperationToken() if (operationToken == JetTokens.ELVIS && expressionWithType == binaryExpression.getRight()) { - val otherOperand = binaryExpression.getLeft() ?: return null - val otherOperandType = bindingContext[BindingContext.EXPRESSION_TYPE, otherOperand] + val leftExpression = binaryExpression.getLeft() ?: return null + val leftType = bindingContext[BindingContext.EXPRESSION_TYPE, leftExpression] + val leftTypeNotNullable = leftType?.makeNotNullable() val expectedInfos = calculate(binaryExpression) if (expectedInfos != null) { - return if (otherOperandType != null) - expectedInfos.filter { it.`type`.isSubtypeOf(otherOperandType) } + return if (leftTypeNotNullable != null) + expectedInfos.filter { leftTypeNotNullable.isSubtypeOf(it.`type`) } else expectedInfos } - else if (otherOperandType != null) { - return listOf(ExpectedInfo(TypeUtils.makeNotNullable(otherOperandType), null)) + else if (leftTypeNotNullable != null) { + return listOf(ExpectedInfo(leftTypeNotNullable, null)) } } } diff --git a/idea/testData/completion/smart/InElvisOperator3.kt b/idea/testData/completion/smart/InElvisOperator3.kt new file mode 100644 index 00000000000..796bccd7dfb --- /dev/null +++ b/idea/testData/completion/smart/InElvisOperator3.kt @@ -0,0 +1,20 @@ +trait A +trait B : A +trait C + +fun foo(a: A){} +fun foo(c: C){} + +fun A.bar(a: A, b: B, c: C, a1: A?, b1: B?, c1: C?) { + foo(this ?: +} + +// EXIST: { itemText:"a" } +// EXIST: { itemText:"b" } +// ABSENT: { itemText:"c" } +// ABSENT: { itemText:"a1" } +// ABSENT: { itemText:"b1" } +// ABSENT: { itemText:"c1" } +// EXIST: { itemText:"!! a1" } +// EXIST: { itemText:"!! b1" } +// ABSENT: { itemText:"!! c1" } diff --git a/idea/testData/completion/smart/InElvisOperator4.kt b/idea/testData/completion/smart/InElvisOperator4.kt new file mode 100644 index 00000000000..913829bb034 --- /dev/null +++ b/idea/testData/completion/smart/InElvisOperator4.kt @@ -0,0 +1,20 @@ +trait A +trait B : A +trait C + +fun foo(a: A?){} +fun foo(c: C?){} + +fun A.bar(a: A, b: B, c: C, a1: A?, b1: B?, c1: C?) { + foo(this ?: +} + +// EXIST: { itemText:"a" } +// EXIST: { itemText:"b" } +// ABSENT: { itemText:"c" } +// EXIST: { itemText:"a1" } +// EXIST: { itemText:"b1" } +// ABSENT: { itemText:"c1" } +// ABSENT: { itemText:"!! a1" } +// ABSENT: { itemText:"!! b1" } +// ABSENT: { itemText:"!! c1" } diff --git a/idea/testData/completion/smart/InElvisOperator5.kt b/idea/testData/completion/smart/InElvisOperator5.kt new file mode 100644 index 00000000000..3d1fd267eb3 --- /dev/null +++ b/idea/testData/completion/smart/InElvisOperator5.kt @@ -0,0 +1,20 @@ +trait A +trait B : A +trait C + +fun foo(a: A){} +fun foo(c: C){} + +fun B.bar(a: A, b: B, c: C, a1: A?, b1: B?, c1: C?) { + foo(this ?: +} + +// EXIST: { itemText:"a" } +// EXIST: { itemText:"b" } +// ABSENT: { itemText:"c" } +// ABSENT: { itemText:"a1" } +// ABSENT: { itemText:"b1" } +// ABSENT: { itemText:"c1" } +// EXIST: { itemText:"!! a1" } +// EXIST: { itemText:"!! b1" } +// ABSENT: { itemText:"!! c1" } diff --git a/idea/testData/completion/smart/InElvisOperator6.kt b/idea/testData/completion/smart/InElvisOperator6.kt new file mode 100644 index 00000000000..24ba849ad57 --- /dev/null +++ b/idea/testData/completion/smart/InElvisOperator6.kt @@ -0,0 +1,20 @@ +trait A +trait B : A +trait C + +fun foo(a: A){} +fun foo(c: C){} + +fun B?.bar(a: A, b: B, c: C, a1: A?, b1: B?, c1: C?) { + foo(this ?: +} + +// EXIST: { itemText:"a" } +// EXIST: { itemText:"b" } +// ABSENT: { itemText:"c" } +// ABSENT: { itemText:"a1" } +// ABSENT: { itemText:"b1" } +// ABSENT: { itemText:"c1" } +// EXIST: { itemText:"!! a1" } +// EXIST: { itemText:"!! b1" } +// ABSENT: { itemText:"!! c1" } diff --git a/idea/tests/org/jetbrains/jet/completion/JvmSmartCompletionTestGenerated.java b/idea/tests/org/jetbrains/jet/completion/JvmSmartCompletionTestGenerated.java index 3b6198b418c..0e1a8fa524b 100644 --- a/idea/tests/org/jetbrains/jet/completion/JvmSmartCompletionTestGenerated.java +++ b/idea/tests/org/jetbrains/jet/completion/JvmSmartCompletionTestGenerated.java @@ -236,6 +236,26 @@ public class JvmSmartCompletionTestGenerated extends AbstractJvmSmartCompletionT doTest("idea/testData/completion/smart/InElvisOperator2.kt"); } + @TestMetadata("InElvisOperator3.kt") + public void testInElvisOperator3() throws Exception { + doTest("idea/testData/completion/smart/InElvisOperator3.kt"); + } + + @TestMetadata("InElvisOperator4.kt") + public void testInElvisOperator4() throws Exception { + doTest("idea/testData/completion/smart/InElvisOperator4.kt"); + } + + @TestMetadata("InElvisOperator5.kt") + public void testInElvisOperator5() throws Exception { + doTest("idea/testData/completion/smart/InElvisOperator5.kt"); + } + + @TestMetadata("InElvisOperator6.kt") + public void testInElvisOperator6() throws Exception { + doTest("idea/testData/completion/smart/InElvisOperator6.kt"); + } + @TestMetadata("InaccessibleConstructor.kt") public void testInaccessibleConstructor() throws Exception { doTest("idea/testData/completion/smart/InaccessibleConstructor.kt");