KT-11481 "Add import" intention is not available for 'is' branches in when
#KT-11481 Fixed
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
}
|
||||
@@ -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");
|
||||
|
||||
Reference in New Issue
Block a user