Ban import member intentions from import directives (KT-13710)
#KT-13710 Fixed
This commit is contained in:
@@ -347,6 +347,10 @@ fun KtSimpleNameExpression.isPackageDirectiveExpression(): Boolean {
|
||||
return parent is KtPackageDirective || parent?.parent is KtPackageDirective
|
||||
}
|
||||
|
||||
fun KtExpression.isInImportDirective(): Boolean {
|
||||
return parents.takeWhile { it !is KtDeclaration && it !is KtBlockExpression }.any { it is KtImportDirective }
|
||||
}
|
||||
|
||||
fun KtExpression.isLambdaOutsideParentheses(): Boolean {
|
||||
val parent = parent
|
||||
return when (parent) {
|
||||
|
||||
@@ -30,6 +30,7 @@ import org.jetbrains.kotlin.psi.KtNameReferenceExpression
|
||||
import org.jetbrains.kotlin.psi.KtPsiFactory
|
||||
import org.jetbrains.kotlin.psi.psiUtil.collectDescendantsOfType
|
||||
import org.jetbrains.kotlin.psi.psiUtil.getQualifiedElementSelector
|
||||
import org.jetbrains.kotlin.psi.psiUtil.isInImportDirective
|
||||
import org.jetbrains.kotlin.resolve.BindingContext
|
||||
import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
|
||||
import org.jetbrains.kotlin.resolve.scopes.receivers.ClassQualifier
|
||||
@@ -44,7 +45,9 @@ class ImportAllMembersIntention : SelfTargetingIntention<KtDotQualifiedExpressio
|
||||
val target = target(element) ?: return false
|
||||
val targetFqName = target.importableFqName ?: return false
|
||||
|
||||
val file = element.getContainingKtFile()
|
||||
if (element.isInImportDirective()) return false
|
||||
|
||||
val file = element.containingKtFile
|
||||
val project = file.project
|
||||
val dummyFileText = (file.packageDirective?.text ?: "") + "\n" + (file.importList?.text ?: "")
|
||||
val dummyFile = KtPsiFactory(project).createAnalyzableFile("Dummy.kt", dummyFileText, file)
|
||||
@@ -59,9 +62,9 @@ class ImportAllMembersIntention : SelfTargetingIntention<KtDotQualifiedExpressio
|
||||
val target = target(element)!!
|
||||
val classFqName = target.importableFqName!!.parent()
|
||||
|
||||
ImportInsertHelper.getInstance(element.project).importDescriptor(element.getContainingKtFile(), target, forceAllUnderImport = true)
|
||||
ImportInsertHelper.getInstance(element.project).importDescriptor(element.containingKtFile, target, forceAllUnderImport = true)
|
||||
|
||||
val qualifiedExpressions = element.getContainingKtFile().collectDescendantsOfType<KtDotQualifiedExpression> { qualifiedExpression ->
|
||||
val qualifiedExpressions = element.containingKtFile.collectDescendantsOfType<KtDotQualifiedExpression> { qualifiedExpression ->
|
||||
val qualifierName = qualifiedExpression.receiverExpression.getQualifiedElementSelector() as? KtNameReferenceExpression
|
||||
qualifierName?.getReferencedNameAsName() == classFqName.shortName() && target(qualifiedExpression)?.importableFqName?.parent() == classFqName
|
||||
}
|
||||
|
||||
@@ -18,21 +18,18 @@ package org.jetbrains.kotlin.idea.intentions
|
||||
|
||||
import com.intellij.openapi.editor.Editor
|
||||
import org.jetbrains.kotlin.idea.caches.resolve.analyze
|
||||
import org.jetbrains.kotlin.idea.core.ShortenReferences
|
||||
import org.jetbrains.kotlin.idea.imports.canBeReferencedViaImport
|
||||
import org.jetbrains.kotlin.idea.imports.importableFqName
|
||||
import org.jetbrains.kotlin.idea.references.mainReference
|
||||
import org.jetbrains.kotlin.idea.util.ImportDescriptorResult
|
||||
import org.jetbrains.kotlin.idea.util.ImportInsertHelper
|
||||
import org.jetbrains.kotlin.idea.core.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.psi.psiUtil.*
|
||||
import org.jetbrains.kotlin.resolve.BindingContext
|
||||
import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
|
||||
|
||||
@@ -44,6 +41,8 @@ class ImportMemberIntention : SelfTargetingOffsetIndependentIntention<KtNameRefe
|
||||
val qualifiedElement = element.getQualifiedElement()
|
||||
if (qualifiedElement == element) return false
|
||||
|
||||
if (element.isInImportDirective()) return false
|
||||
|
||||
val fqName = targetFqName(qualifiedElement) ?: return false
|
||||
|
||||
text = "Add import for '${fqName.asString()}'"
|
||||
@@ -55,7 +54,7 @@ class ImportMemberIntention : SelfTargetingOffsetIndependentIntention<KtNameRefe
|
||||
val targets = element.mainReference.resolveToDescriptors(bindingContext)
|
||||
val fqName = targets.map { it.importableFqName!! }.single()
|
||||
|
||||
val file = element.getContainingKtFile()
|
||||
val file = element.containingKtFile
|
||||
val helper = ImportInsertHelper.getInstance(element.project)
|
||||
if (helper.importDescriptor(file, targets.first()) == ImportDescriptorResult.FAIL) return
|
||||
|
||||
|
||||
+2
-7
@@ -22,10 +22,7 @@ import org.jetbrains.kotlin.diagnostics.Diagnostic
|
||||
import org.jetbrains.kotlin.idea.caches.resolve.analyzeFullyAndGetResult
|
||||
import org.jetbrains.kotlin.idea.quickfix.createFromUsage.callableBuilder.TypeInfo
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
import org.jetbrains.kotlin.psi.psiUtil.getAssignmentByLHS
|
||||
import org.jetbrains.kotlin.psi.psiUtil.getNonStrictParentOfType
|
||||
import org.jetbrains.kotlin.psi.psiUtil.getQualifiedElementSelector
|
||||
import org.jetbrains.kotlin.psi.psiUtil.isDotReceiver
|
||||
import org.jetbrains.kotlin.psi.psiUtil.*
|
||||
import org.jetbrains.kotlin.resolve.BindingContext
|
||||
import org.jetbrains.kotlin.resolve.calls.callUtil.getCall
|
||||
import java.util.Arrays
|
||||
@@ -50,8 +47,6 @@ object CreateClassFromReferenceExpressionActionFactory : CreateClassFromUsageFac
|
||||
|
||||
private fun isQualifierExpected(element: KtSimpleNameExpression) = element.isDotReceiver() || ((element.parent as? KtDotQualifiedExpression)?.isDotReceiver() ?: false)
|
||||
|
||||
private fun isInsideOfImport(element: KtSimpleNameExpression) = element.getNonStrictParentOfType<KtImportDirective>() != null
|
||||
|
||||
override fun getPossibleClassKinds(element: KtSimpleNameExpression, diagnostic: Diagnostic): List<ClassKind> {
|
||||
fun isEnum(element: PsiElement): Boolean {
|
||||
return when (element) {
|
||||
@@ -120,7 +115,7 @@ object CreateClassFromReferenceExpressionActionFactory : CreateClassFromUsageFac
|
||||
|
||||
val fullCallExpr = getFullCallExpression(element) ?: return null
|
||||
|
||||
if (isInsideOfImport(element) || isQualifierExpected(element)) {
|
||||
if (element.isInImportDirective() || isQualifierExpected(element)) {
|
||||
val receiverSelector = (fullCallExpr as? KtQualifiedExpression)?.receiverExpression?.getQualifiedElementSelector() as? KtReferenceExpression
|
||||
val qualifierDescriptor = receiverSelector?.let { context[BindingContext.REFERENCE_TARGET, it] }
|
||||
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
// IS_APPLICABLE: false
|
||||
// WITH_RUNTIME
|
||||
|
||||
import javax.swing.<caret>SwingConstants.CENTER
|
||||
@@ -0,0 +1,4 @@
|
||||
// IS_APPLICABLE: false
|
||||
// WITH_RUNTIME
|
||||
|
||||
import javax.swing.SwingConstants.<caret>CENTER
|
||||
@@ -0,0 +1,4 @@
|
||||
// IS_APPLICABLE: false
|
||||
// WITH_RUNTIME
|
||||
|
||||
import javax.swing.<caret>SwingConstants.CENTER
|
||||
@@ -7739,6 +7739,12 @@ public class IntentionTestGenerated extends AbstractIntentionTest {
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("ImportAllMembersInImport.kt")
|
||||
public void testImportAllMembersInImport() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/importAllMembers/ImportAllMembersInImport.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("NotFromCompanionObject.kt")
|
||||
public void testNotFromCompanionObject() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/importAllMembers/NotFromCompanionObject.kt");
|
||||
@@ -7802,6 +7808,18 @@ public class IntentionTestGenerated extends AbstractIntentionTest {
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("ImportMemberInImport.kt")
|
||||
public void testImportMemberInImport() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/importMember/ImportMemberInImport.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("ImportMemberInMiddleOfImport.kt")
|
||||
public void testImportMemberInMiddleOfImport() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/importMember/ImportMemberInMiddleOfImport.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("NestedClass1.kt")
|
||||
public void testNestedClass1() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/importMember/NestedClass1.kt");
|
||||
|
||||
Reference in New Issue
Block a user