Fix priority for "add import" action wrt DeprecatedSinceKotlin
This commit is contained in:
+1
-1
@@ -67,7 +67,7 @@ abstract class DeclarationLookupObjectImpl(
|
|||||||
}
|
}
|
||||||
|
|
||||||
// This function is kind of a hack to avoid using DeprecationResolver as it's hard to preserve same resolutionFacade for descriptor
|
// This function is kind of a hack to avoid using DeprecationResolver as it's hard to preserve same resolutionFacade for descriptor
|
||||||
private fun isDeprecatedAtCallSite(descriptor: DeclarationDescriptor, languageVersionSettings: LanguageVersionSettings?): Boolean {
|
fun isDeprecatedAtCallSite(descriptor: DeclarationDescriptor, languageVersionSettings: LanguageVersionSettings?): Boolean {
|
||||||
val isDeprecatedAtDeclarationSite = KotlinBuiltIns.isDeprecated(descriptor)
|
val isDeprecatedAtDeclarationSite = KotlinBuiltIns.isDeprecated(descriptor)
|
||||||
if (languageVersionSettings == null) return isDeprecatedAtDeclarationSite
|
if (languageVersionSettings == null) return isDeprecatedAtDeclarationSite
|
||||||
|
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ import com.intellij.psi.statistics.StatisticsManager
|
|||||||
import com.intellij.psi.util.proximity.PsiProximityComparator
|
import com.intellij.psi.util.proximity.PsiProximityComparator
|
||||||
import com.intellij.ui.popup.list.ListPopupImpl
|
import com.intellij.ui.popup.list.ListPopupImpl
|
||||||
import com.intellij.ui.popup.list.PopupListElementRenderer
|
import com.intellij.ui.popup.list.PopupListElementRenderer
|
||||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
import org.jetbrains.kotlin.config.LanguageVersionSettings
|
||||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
||||||
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
||||||
import org.jetbrains.kotlin.descriptors.PackageViewDescriptor
|
import org.jetbrains.kotlin.descriptors.PackageViewDescriptor
|
||||||
@@ -42,8 +42,10 @@ import org.jetbrains.kotlin.idea.KotlinDescriptorIconProvider
|
|||||||
import org.jetbrains.kotlin.idea.caches.resolve.resolveImportReference
|
import org.jetbrains.kotlin.idea.caches.resolve.resolveImportReference
|
||||||
import org.jetbrains.kotlin.idea.codeInsight.DescriptorToSourceUtilsIde
|
import org.jetbrains.kotlin.idea.codeInsight.DescriptorToSourceUtilsIde
|
||||||
import org.jetbrains.kotlin.idea.completion.KotlinStatisticsInfo
|
import org.jetbrains.kotlin.idea.completion.KotlinStatisticsInfo
|
||||||
|
import org.jetbrains.kotlin.idea.completion.isDeprecatedAtCallSite
|
||||||
import org.jetbrains.kotlin.idea.core.ImportableFqNameClassifier
|
import org.jetbrains.kotlin.idea.core.ImportableFqNameClassifier
|
||||||
import org.jetbrains.kotlin.idea.imports.importableFqName
|
import org.jetbrains.kotlin.idea.imports.importableFqName
|
||||||
|
import org.jetbrains.kotlin.idea.project.languageVersionSettings
|
||||||
import org.jetbrains.kotlin.idea.references.KtSimpleNameReference
|
import org.jetbrains.kotlin.idea.references.KtSimpleNameReference
|
||||||
import org.jetbrains.kotlin.idea.references.mainReference
|
import org.jetbrains.kotlin.idea.references.mainReference
|
||||||
import org.jetbrains.kotlin.idea.references.resolveMainReferenceToDescriptors
|
import org.jetbrains.kotlin.idea.references.resolveMainReferenceToDescriptors
|
||||||
@@ -69,7 +71,7 @@ internal fun createSingleImportAction(
|
|||||||
val prioritizer = Prioritizer(element.containingKtFile)
|
val prioritizer = Prioritizer(element.containingKtFile)
|
||||||
val variants = fqNames.mapNotNull { fqName ->
|
val variants = fqNames.mapNotNull { fqName ->
|
||||||
val sameFqNameDescriptors = file.resolveImportReference(fqName)
|
val sameFqNameDescriptors = file.resolveImportReference(fqName)
|
||||||
val priority = sameFqNameDescriptors.map { prioritizer.priority(it) }.min() ?: return@mapNotNull null
|
val priority = sameFqNameDescriptors.map { prioritizer.priority(it, file.languageVersionSettings) }.min() ?: return@mapNotNull null
|
||||||
Prioritizer.VariantWithPriority(SingleImportVariant(fqName, sameFqNameDescriptors), priority)
|
Prioritizer.VariantWithPriority(SingleImportVariant(fqName, sameFqNameDescriptors), priority)
|
||||||
}.sortedBy { it.priority }.map { it.variant }
|
}.sortedBy { it.priority }.map { it.variant }
|
||||||
|
|
||||||
@@ -89,7 +91,8 @@ internal fun createSingleImportActionForConstructor(
|
|||||||
.filterIsInstance<ClassDescriptor>()
|
.filterIsInstance<ClassDescriptor>()
|
||||||
.flatMap { it.constructors }
|
.flatMap { it.constructors }
|
||||||
|
|
||||||
val priority = sameFqNameDescriptors.asSequence().map { prioritizer.priority(it) }.min() ?: return@mapNotNull null
|
val priority =
|
||||||
|
sameFqNameDescriptors.asSequence().map { prioritizer.priority(it, file.languageVersionSettings) }.min() ?: return@mapNotNull null
|
||||||
Prioritizer.VariantWithPriority(SingleImportVariant(fqName, sameFqNameDescriptors), priority)
|
Prioritizer.VariantWithPriority(SingleImportVariant(fqName, sameFqNameDescriptors), priority)
|
||||||
}.sortedBy { it.priority }.map { it.variant }
|
}.sortedBy { it.priority }.map { it.variant }
|
||||||
return KotlinAddImportAction(project, editor, element, variants)
|
return KotlinAddImportAction(project, editor, element, variants)
|
||||||
@@ -116,7 +119,7 @@ internal fun createGroupedImportsAction(
|
|||||||
SingleImportVariant(samePackageFqNames.first(), descriptors)
|
SingleImportVariant(samePackageFqNames.first(), descriptors)
|
||||||
}
|
}
|
||||||
|
|
||||||
val priority = prioritizer.priority(descriptors)
|
val priority = prioritizer.priority(descriptors, file.languageVersionSettings)
|
||||||
DescriptorGroupPrioritizer.VariantWithPriority(variant, priority)
|
DescriptorGroupPrioritizer.VariantWithPriority(variant, priority)
|
||||||
}
|
}
|
||||||
.sortedBy {
|
.sortedBy {
|
||||||
@@ -272,8 +275,8 @@ private class Prioritizer(private val file: KtFile, private val compareNames: Bo
|
|||||||
private val classifier = ImportableFqNameClassifier(file)
|
private val classifier = ImportableFqNameClassifier(file)
|
||||||
private val proximityComparator = PsiProximityComparator(file)
|
private val proximityComparator = PsiProximityComparator(file)
|
||||||
|
|
||||||
inner class Priority(descriptor: DeclarationDescriptor) : Comparable<Priority> {
|
inner class Priority(descriptor: DeclarationDescriptor, languageVersionSettings: LanguageVersionSettings) : Comparable<Priority> {
|
||||||
private val isDeprecated = KotlinBuiltIns.isDeprecated(descriptor)
|
private val isDeprecated = isDeprecatedAtCallSite(descriptor, languageVersionSettings)
|
||||||
private val fqName = descriptor.importableFqName!!
|
private val fqName = descriptor.importableFqName!!
|
||||||
private val classification = classifier.classify(fqName, false)
|
private val classification = classifier.classify(fqName, false)
|
||||||
private val declaration = DescriptorToSourceUtilsIde.getAnyDeclaration(file.project, descriptor)
|
private val declaration = DescriptorToSourceUtilsIde.getAnyDeclaration(file.project, descriptor)
|
||||||
@@ -297,7 +300,8 @@ private class Prioritizer(private val file: KtFile, private val compareNames: Bo
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun priority(descriptor: DeclarationDescriptor) = Priority(descriptor)
|
fun priority(descriptor: DeclarationDescriptor, languageVersionSettings: LanguageVersionSettings) =
|
||||||
|
Priority(descriptor, languageVersionSettings)
|
||||||
|
|
||||||
data class VariantWithPriority(val variant: AutoImportVariant, val priority: Priority)
|
data class VariantWithPriority(val variant: AutoImportVariant, val priority: Priority)
|
||||||
}
|
}
|
||||||
@@ -305,8 +309,11 @@ private class Prioritizer(private val file: KtFile, private val compareNames: Bo
|
|||||||
private class DescriptorGroupPrioritizer(file: KtFile) {
|
private class DescriptorGroupPrioritizer(file: KtFile) {
|
||||||
private val prioritizer = Prioritizer(file, false)
|
private val prioritizer = Prioritizer(file, false)
|
||||||
|
|
||||||
inner class Priority(val descriptors: List<DeclarationDescriptor>) : Comparable<Priority> {
|
inner class Priority(
|
||||||
val ownDescriptorsPriority = descriptors.asSequence().map { prioritizer.priority(it) }.max()!!
|
val descriptors: List<DeclarationDescriptor>,
|
||||||
|
languageVersionSettings: LanguageVersionSettings
|
||||||
|
) : Comparable<Priority> {
|
||||||
|
val ownDescriptorsPriority = descriptors.asSequence().map { prioritizer.priority(it, languageVersionSettings) }.max()!!
|
||||||
|
|
||||||
override fun compareTo(other: Priority): Int {
|
override fun compareTo(other: Priority): Int {
|
||||||
val c1 = ownDescriptorsPriority.compareTo(other.ownDescriptorsPriority)
|
val c1 = ownDescriptorsPriority.compareTo(other.ownDescriptorsPriority)
|
||||||
@@ -316,7 +323,8 @@ private class DescriptorGroupPrioritizer(file: KtFile) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun priority(descriptors: List<DeclarationDescriptor>) = Priority(descriptors)
|
fun priority(descriptors: List<DeclarationDescriptor>, languageVersionSettings: LanguageVersionSettings) =
|
||||||
|
Priority(descriptors, languageVersionSettings)
|
||||||
|
|
||||||
data class VariantWithPriority(val variant: AutoImportVariant, val priority: Priority)
|
data class VariantWithPriority(val variant: AutoImportVariant, val priority: Priority)
|
||||||
}
|
}
|
||||||
|
|||||||
+50
@@ -0,0 +1,50 @@
|
|||||||
|
// FILE: first.before.kt
|
||||||
|
// "Import" "true"
|
||||||
|
// ERROR: Destructuring declaration initializer of type Some must have a 'component1()' function
|
||||||
|
|
||||||
|
package testing
|
||||||
|
|
||||||
|
import aaa.Some
|
||||||
|
|
||||||
|
fun testing() {
|
||||||
|
val (a) = <caret>Some()
|
||||||
|
}
|
||||||
|
//-----------------------
|
||||||
|
|
||||||
|
|
||||||
|
// FILE: second.kt
|
||||||
|
|
||||||
|
package aaa
|
||||||
|
|
||||||
|
public class Some
|
||||||
|
|
||||||
|
@Deprecated("Bad, use from package other")
|
||||||
|
@DeprecatedSinceKotlin(warningSince = "1.0")
|
||||||
|
operator fun Some.component1() = 1
|
||||||
|
//-----------------------
|
||||||
|
|
||||||
|
// FILE: other_second.kt
|
||||||
|
|
||||||
|
package other
|
||||||
|
|
||||||
|
import aaa.Some
|
||||||
|
|
||||||
|
operator fun Some.component1() = 1
|
||||||
|
//-----------------------
|
||||||
|
|
||||||
|
|
||||||
|
// FILE: first.after.kt
|
||||||
|
// "Import" "true"
|
||||||
|
// ERROR: Destructuring declaration initializer of type Some must have a 'component1()' function
|
||||||
|
|
||||||
|
package testing
|
||||||
|
|
||||||
|
import aaa.Some
|
||||||
|
import other.component1
|
||||||
|
|
||||||
|
fun testing() {
|
||||||
|
val (a) = <caret>Some()
|
||||||
|
}
|
||||||
|
//-----------------------
|
||||||
|
|
||||||
|
|
||||||
+50
@@ -0,0 +1,50 @@
|
|||||||
|
// FILE: first.before.kt
|
||||||
|
// "Import" "true"
|
||||||
|
// ERROR: Destructuring declaration initializer of type Some must have a 'component1()' function
|
||||||
|
|
||||||
|
package testing
|
||||||
|
|
||||||
|
import aaa.Some
|
||||||
|
|
||||||
|
fun testing() {
|
||||||
|
val (a) = <caret>Some()
|
||||||
|
}
|
||||||
|
//-----------------------
|
||||||
|
|
||||||
|
|
||||||
|
// FILE: second.kt
|
||||||
|
|
||||||
|
package aaa
|
||||||
|
|
||||||
|
public class Some
|
||||||
|
|
||||||
|
@Deprecated("Good")
|
||||||
|
@DeprecatedSinceKotlin(warningSince = "999.999")
|
||||||
|
operator fun Some.component1() = 1
|
||||||
|
//-----------------------
|
||||||
|
|
||||||
|
// FILE: other_second.kt
|
||||||
|
|
||||||
|
package other
|
||||||
|
|
||||||
|
import aaa.Some
|
||||||
|
|
||||||
|
operator fun Some.component1() = 1
|
||||||
|
//-----------------------
|
||||||
|
|
||||||
|
|
||||||
|
// FILE: first.after.kt
|
||||||
|
// "Import" "true"
|
||||||
|
// ERROR: Destructuring declaration initializer of type Some must have a 'component1()' function
|
||||||
|
|
||||||
|
package testing
|
||||||
|
|
||||||
|
import aaa.Some
|
||||||
|
import aaa.component1
|
||||||
|
|
||||||
|
fun testing() {
|
||||||
|
val (a) = <caret>Some()
|
||||||
|
}
|
||||||
|
//-----------------------
|
||||||
|
|
||||||
|
|
||||||
+10
@@ -641,6 +641,16 @@ public class QuickFixMultiFileTestGenerated extends AbstractQuickFixMultiFileTes
|
|||||||
runTest("idea/testData/quickfix/autoImports/extensionFunctionImportImplicitReceiver.before.Main.kt");
|
runTest("idea/testData/quickfix/autoImports/extensionFunctionImportImplicitReceiver.before.Main.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("extensionPreferDeprecatedSinceApplicable.test")
|
||||||
|
public void testExtensionPreferDeprecatedSinceApplicable() throws Exception {
|
||||||
|
runTest("idea/testData/quickfix/autoImports/extensionPreferDeprecatedSinceApplicable.test");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("extensionPreferDeprecatedSinceNotApplicable.test")
|
||||||
|
public void testExtensionPreferDeprecatedSinceNotApplicable() throws Exception {
|
||||||
|
runTest("idea/testData/quickfix/autoImports/extensionPreferDeprecatedSinceNotApplicable.test");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("extensionPropertyImport.before.Main.kt")
|
@TestMetadata("extensionPropertyImport.before.Main.kt")
|
||||||
public void testExtensionPropertyImport() throws Exception {
|
public void testExtensionPropertyImport() throws Exception {
|
||||||
runTest("idea/testData/quickfix/autoImports/extensionPropertyImport.before.Main.kt");
|
runTest("idea/testData/quickfix/autoImports/extensionPropertyImport.before.Main.kt");
|
||||||
|
|||||||
Reference in New Issue
Block a user