Fix QuickFix-es with the same family name should be the same class instances (KT-25251)

#KT-25251 In Progress
This commit is contained in:
Nikolay Krasko
2018-07-17 17:43:23 +03:00
parent adfa469b21
commit 7358cc5bd6
@@ -55,7 +55,7 @@ class ObsoleteExperimentalCoroutinesInspection : AbstractKotlinInspection(), Cle
"Methods are absent in coroutines class since 1.3",
ProblemHighlightType.GENERIC_ERROR_OR_WARNING,
isOnTheFly,
ImportExtensionFunctionFix(fixFqName)
ObsoleteCoroutineUsageFix.createExtensionFix(fixFqName)
)
holder.registerProblem(problemDescriptor)
@@ -73,7 +73,7 @@ class ObsoleteExperimentalCoroutinesInspection : AbstractKotlinInspection(), Cle
"Experimental coroutines usages are obsolete since 1.3",
ProblemHighlightType.GENERIC_ERROR_OR_WARNING,
isOnTheFly,
ObsoleteCoroutineImportFix()
ObsoleteCoroutineUsageFix.createImportFix()
)
holder.registerProblem(problemDescriptor)
@@ -93,9 +93,6 @@ class ObsoleteExperimentalCoroutinesInspection : AbstractKotlinInspection(), Cle
private const val RESUME_WITH_EXCEPTION_FQNAME = "kotlin.coroutines.experimental.Continuation.resumeWithException"
private const val RESUME_WITH_EXCEPTION_FIX_FQNAME = "kotlin.coroutines.resumeWithException"
// All quick-fixes should have same name to be executable together
private const val QUICK_FIX_NAME = "Fix experimental coroutines usage"
private class Binding(
val bindTo: FqName,
val shouldRemove: Boolean,
@@ -129,43 +126,59 @@ class ObsoleteExperimentalCoroutinesInspection : AbstractKotlinInspection(), Cle
}
}
private class ObsoleteCoroutineImportFix : LocalQuickFix {
override fun getFamilyName() = QUICK_FIX_NAME
private class ObsoleteCoroutineUsageFix(val delegate: LocalQuickFix) : LocalQuickFix {
override fun getFamilyName(): String = QUICK_FIX_NAME
override fun applyFix(project: Project, descriptor: ProblemDescriptor) {
val element = descriptor.psiElement
val simpleNameExpression = when (element) {
is KtSimpleNameExpression -> element
is KtDotQualifiedExpression -> element.selectorExpression as? KtSimpleNameExpression
else -> null
} ?: return
delegate.applyFix(project, descriptor)
}
val binding = ObsoleteExperimentalCoroutinesInspection.findBinding(simpleNameExpression) ?: return
companion object {
private const val QUICK_FIX_NAME = "Fix experimental coroutines usage"
if (binding.shouldRemove) {
binding.importDirective.delete()
} else {
simpleNameExpression.mainReference.bindToFqName(
binding.bindTo, shorteningMode = KtSimpleNameReference.ShorteningMode.NO_SHORTENING
)
fun createImportFix() = ObsoleteCoroutineUsageFix(ObsoleteCoroutineImportFix())
fun createExtensionFix(fqName: String) = ObsoleteCoroutineUsageFix(ImportExtensionFunctionFix(fqName))
private class ObsoleteCoroutineImportFix : LocalQuickFix {
override fun getFamilyName() = QUICK_FIX_NAME
override fun applyFix(project: Project, descriptor: ProblemDescriptor) {
val element = descriptor.psiElement
val simpleNameExpression = when (element) {
is KtSimpleNameExpression -> element
is KtDotQualifiedExpression -> element.selectorExpression as? KtSimpleNameExpression
else -> null
} ?: return
val binding = ObsoleteExperimentalCoroutinesInspection.findBinding(simpleNameExpression) ?: return
if (binding.shouldRemove) {
binding.importDirective.delete()
} else {
simpleNameExpression.mainReference.bindToFqName(
binding.bindTo, shorteningMode = KtSimpleNameReference.ShorteningMode.NO_SHORTENING
)
}
}
}
private class ImportExtensionFunctionFix(val fqName: String) : LocalQuickFix {
override fun getFamilyName() = QUICK_FIX_NAME
override fun applyFix(project: Project, descriptor: ProblemDescriptor) {
val element = descriptor.psiElement
element as? KtSimpleNameExpression ?: return
val importFun =
KotlinTopLevelFunctionFqnNameIndex.getInstance()
.get(fqName, element.project, GlobalSearchScope.allScope(element.project))
.asSequence()
.map { it.resolveToDescriptorIfAny() }
.find { it != null && it.importableFqName?.asString() == fqName } ?: return
ImportInsertHelper.getInstance(element.project).importDescriptor(element.containingKtFile, importFun, false)
}
}
}
}
private class ImportExtensionFunctionFix(val fqName: String) : LocalQuickFix {
override fun getFamilyName() = QUICK_FIX_NAME
override fun applyFix(project: Project, descriptor: ProblemDescriptor) {
val element = descriptor.psiElement
element as? KtSimpleNameExpression ?: return
val importFun =
KotlinTopLevelFunctionFqnNameIndex.getInstance().get(fqName, element.project, GlobalSearchScope.allScope(element.project))
.asSequence()
.map { it.resolveToDescriptorIfAny() }
.find { it != null && it.importableFqName?.asString() == fqName } ?: return
ImportInsertHelper.getInstance(element.project).importDescriptor(element.containingKtFile, importFun, false)
}
}
}