Create from Usage: Respect smart-casts when suggesting parameter type candidates
#KT-6781 Fixed
This commit is contained in:
+5
-3
@@ -21,11 +21,9 @@ import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
|||||||
import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor
|
import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor
|
||||||
import org.jetbrains.kotlin.resolve.DescriptorUtils
|
import org.jetbrains.kotlin.resolve.DescriptorUtils
|
||||||
import org.jetbrains.kotlin.resolve.scopes.JetScope
|
import org.jetbrains.kotlin.resolve.scopes.JetScope
|
||||||
import java.util.LinkedHashSet
|
|
||||||
import org.jetbrains.kotlin.resolve.BindingContext
|
import org.jetbrains.kotlin.resolve.BindingContext
|
||||||
import com.intellij.refactoring.psi.SearchUtils
|
import com.intellij.refactoring.psi.SearchUtils
|
||||||
import org.jetbrains.kotlin.idea.references.JetSimpleNameReference
|
import org.jetbrains.kotlin.idea.references.JetSimpleNameReference
|
||||||
import java.util.HashSet
|
|
||||||
import org.jetbrains.kotlin.types.ErrorUtils
|
import org.jetbrains.kotlin.types.ErrorUtils
|
||||||
import org.jetbrains.kotlin.types.TypeUtils
|
import org.jetbrains.kotlin.types.TypeUtils
|
||||||
import org.jetbrains.kotlin.types.checker.JetTypeChecker
|
import org.jetbrains.kotlin.types.checker.JetTypeChecker
|
||||||
@@ -43,6 +41,8 @@ import org.jetbrains.kotlin.psi.psiUtil.getNonStrictParentOfType
|
|||||||
import org.jetbrains.kotlin.resolve.descriptorUtil.resolveTopLevelClass
|
import org.jetbrains.kotlin.resolve.descriptorUtil.resolveTopLevelClass
|
||||||
import org.jetbrains.kotlin.psi.*
|
import org.jetbrains.kotlin.psi.*
|
||||||
import org.jetbrains.kotlin.resolve.calls.callUtil.*
|
import org.jetbrains.kotlin.resolve.calls.callUtil.*
|
||||||
|
import org.jetbrains.kotlin.resolve.calls.smartcasts.*
|
||||||
|
import java.util.*
|
||||||
|
|
||||||
private fun JetType.contains(inner: JetType): Boolean {
|
private fun JetType.contains(inner: JetType): Boolean {
|
||||||
return JetTypeChecker.DEFAULT.equalTypes(this, inner) || getArguments().any { inner in it.getType() }
|
return JetTypeChecker.DEFAULT.equalTypes(this, inner) || getArguments().any { inner in it.getType() }
|
||||||
@@ -107,7 +107,9 @@ fun JetExpression.guessTypes(
|
|||||||
// if we know the actual type of the expression
|
// if we know the actual type of the expression
|
||||||
val theType1 = context[BindingContext.EXPRESSION_TYPE, this]
|
val theType1 = context[BindingContext.EXPRESSION_TYPE, this]
|
||||||
if (theType1 != null) {
|
if (theType1 != null) {
|
||||||
return array(theType1)
|
val dataFlowInfo = context[BindingContext.EXPRESSION_DATA_FLOW_INFO, this]
|
||||||
|
val possibleTypes = dataFlowInfo?.getPossibleTypes(DataFlowValueFactory.createDataFlowValue(this, theType1, context))
|
||||||
|
return if (possibleTypes != null && possibleTypes.isNotEmpty()) possibleTypes.copyToArray() else array(theType1)
|
||||||
}
|
}
|
||||||
|
|
||||||
// expression has an expected type
|
// expression has an expected type
|
||||||
|
|||||||
@@ -0,0 +1,9 @@
|
|||||||
|
// "Create function 'foo'" "true"
|
||||||
|
|
||||||
|
fun test(o: Any) {
|
||||||
|
if (o is String) foo(o)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun foo(o: String) {
|
||||||
|
throw UnsupportedOperationException("not implemented") //To change body of created functions use File | Settings | File Templates.
|
||||||
|
}
|
||||||
+10
@@ -0,0 +1,10 @@
|
|||||||
|
// "Create function 'foo'" "true"
|
||||||
|
|
||||||
|
fun test(s: String?) {
|
||||||
|
if (s == null) return
|
||||||
|
foo(s)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun foo(s: String) {
|
||||||
|
throw UnsupportedOperationException("not implemented") //To change body of created functions use File | Settings | File Templates.
|
||||||
|
}
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
// "Create function 'foo'" "true"
|
||||||
|
|
||||||
|
fun test(o: Any) {
|
||||||
|
if (o is String) <caret>foo(o)
|
||||||
|
}
|
||||||
+6
@@ -0,0 +1,6 @@
|
|||||||
|
// "Create function 'foo'" "true"
|
||||||
|
|
||||||
|
fun test(s: String?) {
|
||||||
|
if (s == null) return
|
||||||
|
<caret>foo(s)
|
||||||
|
}
|
||||||
@@ -1794,6 +1794,18 @@ public class QuickFixTestGenerated extends AbstractQuickFixTest {
|
|||||||
doTest(fileName);
|
doTest(fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("beforeSmartCastWithIs.kt")
|
||||||
|
public void testSmartCastWithIs() throws Exception {
|
||||||
|
String fileName = JetTestUtils.navigationMetadata("idea/testData/quickfix/createFromUsage/createFunction/call/beforeSmartCastWithIs.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("beforeSmartCastWithNullCheck.kt")
|
||||||
|
public void testSmartCastWithNullCheck() throws Exception {
|
||||||
|
String fileName = JetTestUtils.navigationMetadata("idea/testData/quickfix/createFromUsage/createFunction/call/beforeSmartCastWithNullCheck.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("beforeThisInClass.kt")
|
@TestMetadata("beforeThisInClass.kt")
|
||||||
public void testThisInClass() throws Exception {
|
public void testThisInClass() throws Exception {
|
||||||
String fileName = JetTestUtils.navigationMetadata("idea/testData/quickfix/createFromUsage/createFunction/call/beforeThisInClass.kt");
|
String fileName = JetTestUtils.navigationMetadata("idea/testData/quickfix/createFromUsage/createFunction/call/beforeThisInClass.kt");
|
||||||
|
|||||||
Reference in New Issue
Block a user