Smart completion after ?: works incorrectly
#KT-4926 Fixed
This commit is contained in:
@@ -50,7 +50,6 @@ import org.jetbrains.jet.lang.resolve.calls.util.DelegatingCall
|
|||||||
import org.jetbrains.jet.lang.resolve.calls.util.noErrorsInValueArguments
|
import org.jetbrains.jet.lang.resolve.calls.util.noErrorsInValueArguments
|
||||||
import org.jetbrains.jet.lang.resolve.calls.util.hasUnmappedParameters
|
import org.jetbrains.jet.lang.resolve.calls.util.hasUnmappedParameters
|
||||||
import org.jetbrains.jet.lang.descriptors.Visibilities
|
import org.jetbrains.jet.lang.descriptors.Visibilities
|
||||||
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptorWithVisibility
|
|
||||||
|
|
||||||
enum class Tail {
|
enum class Tail {
|
||||||
COMMA
|
COMMA
|
||||||
@@ -66,6 +65,7 @@ class ExpectedInfos(val bindingContext: BindingContext, val moduleDescriptor: Mo
|
|||||||
?: calculateForFunctionLiteralArgument(expressionWithType)
|
?: calculateForFunctionLiteralArgument(expressionWithType)
|
||||||
?: calculateForEq(expressionWithType)
|
?: calculateForEq(expressionWithType)
|
||||||
?: calculateForIf(expressionWithType)
|
?: calculateForIf(expressionWithType)
|
||||||
|
?: calculateForElvis(expressionWithType)
|
||||||
?: getFromBindingContext(expressionWithType)
|
?: getFromBindingContext(expressionWithType)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -186,6 +186,28 @@ class ExpectedInfos(val bindingContext: BindingContext, val moduleDescriptor: Mo
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun calculateForElvis(expressionWithType: JetExpression): Collection<ExpectedInfo>? {
|
||||||
|
val binaryExpression = expressionWithType.getParent() as? JetBinaryExpression
|
||||||
|
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 expectedInfos = calculate(binaryExpression)
|
||||||
|
if (expectedInfos != null) {
|
||||||
|
return if (otherOperandType != null)
|
||||||
|
expectedInfos.filter { it.`type`.isSubtypeOf(otherOperandType) }
|
||||||
|
else
|
||||||
|
expectedInfos
|
||||||
|
}
|
||||||
|
else if (otherOperandType != null) {
|
||||||
|
return listOf(ExpectedInfo(TypeUtils.makeNotNullable(otherOperandType), null))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
private fun getFromBindingContext(expressionWithType: JetExpression): Collection<ExpectedInfo>? {
|
private fun getFromBindingContext(expressionWithType: JetExpression): Collection<ExpectedInfo>? {
|
||||||
val expectedType = bindingContext[BindingContext.EXPECTED_EXPRESSION_TYPE, expressionWithType] ?: return null
|
val expectedType = bindingContext[BindingContext.EXPECTED_EXPRESSION_TYPE, expressionWithType] ?: return null
|
||||||
return listOf(ExpectedInfo(expectedType, null))
|
return listOf(ExpectedInfo(expectedType, null))
|
||||||
|
|||||||
@@ -0,0 +1,7 @@
|
|||||||
|
fun foo(s: String, c: Char){}
|
||||||
|
|
||||||
|
fun bar(p1: String?, p2: String) {
|
||||||
|
foo(p1 ?: <caret>
|
||||||
|
}
|
||||||
|
|
||||||
|
// ELEMENT: p2
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
fun foo(s: String, c: Char){}
|
||||||
|
|
||||||
|
fun bar(p1: String?, p2: String) {
|
||||||
|
foo(p1 ?: p2, <caret>
|
||||||
|
}
|
||||||
|
|
||||||
|
// ELEMENT: p2
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
fun foo(p: String?){}
|
||||||
|
fun foo(p: Char){}
|
||||||
|
|
||||||
|
fun bar(p1: String?, p2: String?, p3: Char) {
|
||||||
|
foo(p1 ?: <caret>
|
||||||
|
}
|
||||||
|
|
||||||
|
// EXIST: { itemText:"p2" }
|
||||||
|
// ABSENT: p3
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
fun foo1(): String? = null
|
||||||
|
fun foo2(): String? = null
|
||||||
|
fun foo3(): String = ""
|
||||||
|
|
||||||
|
fun bar() {
|
||||||
|
foo1() ?: <caret>
|
||||||
|
}
|
||||||
|
|
||||||
|
// EXIST: { itemText:"foo3()" }
|
||||||
|
// ABSENT: { itemText:"foo2()" }
|
||||||
|
// EXIST: { itemText:"!! foo2()" }
|
||||||
|
// EXIST: { itemText:"?: foo2()" }
|
||||||
@@ -216,6 +216,16 @@ public class JvmSmartCompletionTestGenerated extends AbstractJvmSmartCompletionT
|
|||||||
doTest("idea/testData/completion/smart/IfValue3.kt");
|
doTest("idea/testData/completion/smart/IfValue3.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("InElvisOperator1.kt")
|
||||||
|
public void testInElvisOperator1() throws Exception {
|
||||||
|
doTest("idea/testData/completion/smart/InElvisOperator1.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("InElvisOperator2.kt")
|
||||||
|
public void testInElvisOperator2() throws Exception {
|
||||||
|
doTest("idea/testData/completion/smart/InElvisOperator2.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("InaccessibleConstructor.kt")
|
@TestMetadata("InaccessibleConstructor.kt")
|
||||||
public void testInaccessibleConstructor() throws Exception {
|
public void testInaccessibleConstructor() throws Exception {
|
||||||
doTest("idea/testData/completion/smart/InaccessibleConstructor.kt");
|
doTest("idea/testData/completion/smart/InaccessibleConstructor.kt");
|
||||||
|
|||||||
+5
@@ -226,6 +226,11 @@ public class SmartCompletionHandlerTestGenerated extends AbstractSmartCompletion
|
|||||||
doTest("idea/testData/completion/handlers/smart/IfValue3.kt");
|
doTest("idea/testData/completion/handlers/smart/IfValue3.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("InElvisOperator.kt")
|
||||||
|
public void testInElvisOperator() throws Exception {
|
||||||
|
doTest("idea/testData/completion/handlers/smart/InElvisOperator.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("JavaEnumMemberInsertsImport.kt")
|
@TestMetadata("JavaEnumMemberInsertsImport.kt")
|
||||||
public void testJavaEnumMemberInsertsImport() throws Exception {
|
public void testJavaEnumMemberInsertsImport() throws Exception {
|
||||||
doTest("idea/testData/completion/handlers/smart/JavaEnumMemberInsertsImport.kt");
|
doTest("idea/testData/completion/handlers/smart/JavaEnumMemberInsertsImport.kt");
|
||||||
|
|||||||
Reference in New Issue
Block a user