KT-11481 "Add import" intention is not available for 'is' branches in when

#KT-11481 Fixed
This commit is contained in:
Valentin Kipyatkov
2016-03-23 14:28:28 +03:00
parent f93bf9fbb4
commit 02d309c9cf
6 changed files with 92 additions and 11 deletions
@@ -26,10 +26,13 @@ import org.jetbrains.kotlin.idea.util.ImportInsertHelper
import org.jetbrains.kotlin.idea.util.ShortenReferences
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.psi.KtDotQualifiedExpression
import org.jetbrains.kotlin.psi.KtElement
import org.jetbrains.kotlin.psi.KtNameReferenceExpression
import org.jetbrains.kotlin.psi.KtUserType
import org.jetbrains.kotlin.psi.psiUtil.collectDescendantsOfType
import org.jetbrains.kotlin.psi.psiUtil.getQualifiedElement
import org.jetbrains.kotlin.psi.psiUtil.getQualifiedElementSelector
import org.jetbrains.kotlin.psi.psiUtil.getReceiverExpression
import org.jetbrains.kotlin.resolve.BindingContext
import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
@@ -38,9 +41,10 @@ class ImportMemberIntention : SelfTargetingOffsetIndependentIntention<KtNameRefe
"Add import for member"
){
override fun isApplicableTo(element: KtNameReferenceExpression): Boolean {
val qualifiedExpression = qualifiedExpression(element) ?: return false
val qualifiedElement = element.getQualifiedElement()
if (qualifiedElement == element) return false
val fqName = targetFqName(qualifiedExpression) ?: return false
val fqName = targetFqName(qualifiedElement) ?: return false
text = "Add import for '${fqName.asString()}'"
return true
@@ -59,19 +63,20 @@ class ImportMemberIntention : SelfTargetingOffsetIndependentIntention<KtNameRefe
val selector = qualifiedExpression.getQualifiedElementSelector() as? KtNameReferenceExpression
selector?.getReferencedNameAsName() == fqName.shortName() && targetFqName(qualifiedExpression) == fqName
}
val userTypes = file.collectDescendantsOfType<KtUserType> { userType ->
val selector = userType.getQualifiedElementSelector() as? KtNameReferenceExpression
selector?.getReferencedNameAsName() == fqName.shortName() && targetFqName(userType) == fqName
}
//TODO: not deep
ShortenReferences.DEFAULT.process(qualifiedExpressions)
ShortenReferences.DEFAULT.process(qualifiedExpressions + userTypes)
}
private fun qualifiedExpression(element: KtNameReferenceExpression): KtDotQualifiedExpression? {
return element.getQualifiedElement() as? KtDotQualifiedExpression
}
private fun targetFqName(qualifiedExpression: KtDotQualifiedExpression): FqName? {
val nameExpression = qualifiedExpression.getQualifiedElementSelector() as? KtNameReferenceExpression ?: return null
val bindingContext = qualifiedExpression.analyze(BodyResolveMode.PARTIAL)
if (bindingContext[BindingContext.QUALIFIER, qualifiedExpression.receiverExpression] == null) return null
private fun targetFqName(qualifiedElement: KtElement): FqName? {
val nameExpression = qualifiedElement.getQualifiedElementSelector() as? KtNameReferenceExpression ?: return null
val receiver = nameExpression.getReceiverExpression() ?: return null
val bindingContext = qualifiedElement.analyze(BodyResolveMode.PARTIAL)
if (bindingContext[BindingContext.QUALIFIER, receiver] == null) return null
val targets = nameExpression.mainReference.resolveToDescriptors(bindingContext)
if (targets.isEmpty()) return null
+15
View File
@@ -0,0 +1,15 @@
// INTENTION_TEXT: "Add import for 'ppp.Foo.Bar'"
// WITH_RUNTIME
package ppp
sealed class Foo {
class Bar(val x: Int) : Foo()
}
fun test() {
val foo = Foo.<caret>Bar(5)
when (foo) {
is Foo.Bar -> println(foo.x)
}
}
@@ -0,0 +1,17 @@
// INTENTION_TEXT: "Add import for 'ppp.Foo.Bar'"
// WITH_RUNTIME
package ppp
import ppp.Foo.Bar
sealed class Foo {
class Bar(val x: Int) : Foo()
}
fun test() {
val foo = <caret>Bar(5)
when (foo) {
is Bar -> println(foo.x)
}
}
+15
View File
@@ -0,0 +1,15 @@
// INTENTION_TEXT: "Add import for 'ppp.Foo.Bar'"
// WITH_RUNTIME
package ppp
sealed class Foo {
class Bar(val x: Int) : Foo()
}
fun test() {
val foo = Foo.Bar(5)
when (foo) {
is Foo.<caret>Bar -> println(foo.x)
}
}
@@ -0,0 +1,17 @@
// INTENTION_TEXT: "Add import for 'ppp.Foo.Bar'"
// WITH_RUNTIME
package ppp
import ppp.Foo.Bar
sealed class Foo {
class Bar(val x: Int) : Foo()
}
fun test() {
val foo = Bar(5)
when (foo) {
is <caret>Bar -> println(foo.x)
}
}
@@ -5706,6 +5706,18 @@ public class IntentionTestGenerated extends AbstractIntentionTest {
doTest(fileName);
}
@TestMetadata("NestedClass1.kt")
public void testNestedClass1() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/importMember/NestedClass1.kt");
doTest(fileName);
}
@TestMetadata("NestedClass2.kt")
public void testNestedClass2() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/importMember/NestedClass2.kt");
doTest(fileName);
}
@TestMetadata("NoTarget.kt")
public void testNoTarget() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/importMember/NoTarget.kt");