diff --git a/idea/src/org/jetbrains/jet/plugin/completion/smart/TypesWithAutoCasts.kt b/idea/src/org/jetbrains/jet/plugin/completion/smart/TypesWithAutoCasts.kt index c6e4a513a0c..fc357ce9e2c 100644 --- a/idea/src/org/jetbrains/jet/plugin/completion/smart/TypesWithAutoCasts.kt +++ b/idea/src/org/jetbrains/jet/plugin/completion/smart/TypesWithAutoCasts.kt @@ -34,6 +34,7 @@ import com.google.common.collect.SetMultimap import org.jetbrains.jet.lang.resolve.calls.autocasts.Nullability import java.util.HashSet import org.jetbrains.jet.lang.resolve.BindingContext +import org.jetbrains.jet.lang.resolve.scopes.receivers.ThisReceiver class TypesWithAutoCasts(val bindingContext: BindingContext) { public fun calculate(expression: JetExpression, receiver: JetExpression?): (DeclarationDescriptor) -> Iterable { @@ -77,43 +78,43 @@ class TypesWithAutoCasts(val bindingContext: BindingContext) { ) private fun processDataFlowInfo(dataFlowInfo: DataFlowInfo?, receiver: JetExpression?): ProcessDataFlowInfoResult { - if (dataFlowInfo != null) { - val dataFlowValueToVariable: (DataFlowValue) -> VariableDescriptor? - if (receiver != null) { - val receiverType = bindingContext[BindingContext.EXPRESSION_TYPE, receiver] - if (receiverType != null) { - val receiverId = DataFlowValueFactory.createDataFlowValue(receiver, receiverType, bindingContext).getId() - dataFlowValueToVariable = {(value) -> - val id = value.getId() - if (id is com.intellij.openapi.util.Pair<*, *> && id.first == receiverId) id.second as? VariableDescriptor else null - } - } - else { - return ProcessDataFlowInfoResult() + if (dataFlowInfo == null) return ProcessDataFlowInfoResult() + + val dataFlowValueToVariable: (DataFlowValue) -> VariableDescriptor? + if (receiver != null) { + val receiverType = bindingContext[BindingContext.EXPRESSION_TYPE, receiver] ?: return ProcessDataFlowInfoResult() + val receiverId = DataFlowValueFactory.createDataFlowValue(receiver, receiverType, bindingContext).getId() + dataFlowValueToVariable = {(value) -> + val id = value.getId() + if (id is com.intellij.openapi.util.Pair<*, *> && id.first == receiverId) id.second as? VariableDescriptor else null + } + } + else { + dataFlowValueToVariable = {(value) -> + val id = value.getId() + when { + id is VariableDescriptor -> id + id is com.intellij.openapi.util.Pair<*, *> && id.first is ThisReceiver -> id.second as? VariableDescriptor + else -> null } } - else { - dataFlowValueToVariable = {(value) -> value.getId() as? VariableDescriptor } - } - - val variableToType = HashMap>() - val typeInfo: SetMultimap = dataFlowInfo.getCompleteTypeInfo() - for ((dataFlowValue, types) in typeInfo.asMap().entrySet()) { - val variable = dataFlowValueToVariable.invoke(dataFlowValue) - if (variable != null) { - variableToType[variable] = types - } - } - - val nullabilityInfo: Map = dataFlowInfo.getCompleteNullabilityInfo() - val notNullVariables = nullabilityInfo - .filter { it.getValue() == Nullability.NOT_NULL } - .map { dataFlowValueToVariable(it.getKey()) } - .filterNotNullTo(HashSet()) - - return ProcessDataFlowInfoResult(variableToType, notNullVariables) } - return ProcessDataFlowInfoResult() + val variableToType = HashMap>() + val typeInfo: SetMultimap = dataFlowInfo.getCompleteTypeInfo() + for ((dataFlowValue, types) in typeInfo.asMap().entrySet()) { + val variable = dataFlowValueToVariable.invoke(dataFlowValue) + if (variable != null) { + variableToType[variable] = types + } + } + + val nullabilityInfo: Map = dataFlowInfo.getCompleteNullabilityInfo() + val notNullVariables = nullabilityInfo + .filter { it.getValue() == Nullability.NOT_NULL } + .map { dataFlowValueToVariable(it.getKey()) } + .filterNotNullTo(HashSet()) + + return ProcessDataFlowInfoResult(variableToType, notNullVariables) } } \ No newline at end of file diff --git a/idea/testData/completion/smart/AutoCastedThisType.kt.todo b/idea/testData/completion/smart/AutoCastedThisType.kt.todo index 1bb33e51e24..7e3476b746b 100644 --- a/idea/testData/completion/smart/AutoCastedThisType.kt.todo +++ b/idea/testData/completion/smart/AutoCastedThisType.kt.todo @@ -9,4 +9,4 @@ open class Foo{ class Bar : Foo -// EXIST: this +// EXIST: { itemText:"this" } diff --git a/idea/testData/completion/smart/AutoCastedType.kt b/idea/testData/completion/smart/AutoCastedType.kt index c40ffef2065..e9a00e99b5c 100644 --- a/idea/testData/completion/smart/AutoCastedType.kt +++ b/idea/testData/completion/smart/AutoCastedType.kt @@ -4,4 +4,4 @@ fun f(p: Any) { } } -// EXIST: p +// EXIST: { itemText:"p" } diff --git a/idea/testData/completion/smart/AutoCastedTypeWithQualifier.kt b/idea/testData/completion/smart/AutoCastedTypeWithQualifier.kt index fa674a8dfaf..7a55a376edb 100644 --- a/idea/testData/completion/smart/AutoCastedTypeWithQualifier.kt +++ b/idea/testData/completion/smart/AutoCastedTypeWithQualifier.kt @@ -6,5 +6,5 @@ class Foo(val prop1 : Any, val prop2 : Any){ } } -// EXIST: prop1 -// ABSENT: prop2 +// EXIST: { itemText:"prop1" } +// ABSENT: { itemText:"prop2" } diff --git a/idea/testData/completion/smart/AutoNotNullThisType.kt.todo b/idea/testData/completion/smart/AutoNotNullThisType.kt.todo index 792b1c22833..d72720d9cd2 100644 --- a/idea/testData/completion/smart/AutoNotNullThisType.kt.todo +++ b/idea/testData/completion/smart/AutoNotNullThisType.kt.todo @@ -5,4 +5,4 @@ fun String?.foo(){ } -// EXIST: this +// EXIST: { itemText:"this" } diff --git a/idea/testData/completion/smart/AutoNotNullType.kt b/idea/testData/completion/smart/AutoNotNullType.kt index bd76e0933c3..80d586a83ad 100644 --- a/idea/testData/completion/smart/AutoNotNullType.kt +++ b/idea/testData/completion/smart/AutoNotNullType.kt @@ -4,4 +4,4 @@ fun f(p: String?) { } } -// EXIST: p +// EXIST: { itemText:"p" } diff --git a/idea/testData/completion/smart/AutoNotNullType2.kt b/idea/testData/completion/smart/AutoNotNullType2.kt new file mode 100644 index 00000000000..724029f58eb --- /dev/null +++ b/idea/testData/completion/smart/AutoNotNullType2.kt @@ -0,0 +1,9 @@ +class Foo(val prop : String?){ + fun f(foo: Foo) { + if (foo.prop != null){ + var a: String = + } + } +} + +// ABSENT: { itemText:"prop" } diff --git a/idea/testData/completion/smart/AutoNotNullTypeForConstructorParameter.kt b/idea/testData/completion/smart/AutoNotNullTypeForConstructorParameter.kt new file mode 100644 index 00000000000..7aafd1b0972 --- /dev/null +++ b/idea/testData/completion/smart/AutoNotNullTypeForConstructorParameter.kt @@ -0,0 +1,11 @@ +class Foo(val s: String?) { + fun bar(){ + if (s != null) { + foo() + } + } +} + +fun foo(s: String){} + +// EXIST: { itemText:"s" } diff --git a/idea/testData/completion/smart/AutoNotNullTypeWithQualifier.kt b/idea/testData/completion/smart/AutoNotNullTypeWithQualifier.kt index 674679b98f7..b72df48506d 100644 --- a/idea/testData/completion/smart/AutoNotNullTypeWithQualifier.kt +++ b/idea/testData/completion/smart/AutoNotNullTypeWithQualifier.kt @@ -6,7 +6,7 @@ class Foo(val prop1 : String?, val prop2 : String?){ } } -// EXIST: prop1 -// ABSENT: { lookupString:"prop2", itemText:"prop2" } -// EXIST: { lookupString:"prop2", itemText:"!! prop2" } -// EXIST: { lookupString:"prop2", itemText:"?: prop2" } +// EXIST: { itemText:"prop1" } +// ABSENT: { itemText:"prop2" } +// EXIST: { itemText:"!! prop2" } +// EXIST: { itemText:"?: prop2" } diff --git a/idea/tests/org/jetbrains/jet/completion/JvmSmartCompletionTestGenerated.java b/idea/tests/org/jetbrains/jet/completion/JvmSmartCompletionTestGenerated.java index cc26b81bbf0..c7b4ada1788 100644 --- a/idea/tests/org/jetbrains/jet/completion/JvmSmartCompletionTestGenerated.java +++ b/idea/tests/org/jetbrains/jet/completion/JvmSmartCompletionTestGenerated.java @@ -71,6 +71,16 @@ public class JvmSmartCompletionTestGenerated extends AbstractJvmSmartCompletionT doTest("idea/testData/completion/smart/AutoNotNullType.kt"); } + @TestMetadata("AutoNotNullType2.kt") + public void testAutoNotNullType2() throws Exception { + doTest("idea/testData/completion/smart/AutoNotNullType2.kt"); + } + + @TestMetadata("AutoNotNullTypeForConstructorParameter.kt") + public void testAutoNotNullTypeForConstructorParameter() throws Exception { + doTest("idea/testData/completion/smart/AutoNotNullTypeForConstructorParameter.kt"); + } + @TestMetadata("AutoNotNullTypeWithQualifier.kt") public void testAutoNotNullTypeWithQualifier() throws Exception { doTest("idea/testData/completion/smart/AutoNotNullTypeWithQualifier.kt");