Refactoring: SelfTargetingIntention / IntentionBasedInspection
Remove complex logic which disables intention when bound inspection on Add much simpler logic in SelfTargetingIntention.equals
This commit is contained in:
+2
-2
@@ -147,8 +147,8 @@ abstract class IntentionBasedInspection<TElement : PsiElement>(
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* we implement IntentionAction to provide isAvailable which will be used to hide outdated items and make sure we never call 'invoke' for such item */
|
/* we implement IntentionAction to provide isAvailable which will be used to hide outdated items and make sure we never call 'invoke' for such item */
|
||||||
private open inner class IntentionBasedQuickFix(
|
internal open inner class IntentionBasedQuickFix(
|
||||||
private val intention: SelfTargetingRangeIntention<TElement>,
|
val intention: SelfTargetingRangeIntention<TElement>,
|
||||||
private val additionalChecker: (TElement, IntentionBasedInspection<TElement>) -> Boolean,
|
private val additionalChecker: (TElement, IntentionBasedInspection<TElement>) -> Boolean,
|
||||||
targetElement: TElement
|
targetElement: TElement
|
||||||
) : LocalQuickFixOnPsiElement(targetElement), IntentionAction {
|
) : LocalQuickFixOnPsiElement(targetElement), IntentionAction {
|
||||||
|
|||||||
+2
-43
@@ -17,15 +17,11 @@
|
|||||||
package org.jetbrains.kotlin.idea.intentions
|
package org.jetbrains.kotlin.idea.intentions
|
||||||
|
|
||||||
import com.intellij.codeInsight.FileModificationService
|
import com.intellij.codeInsight.FileModificationService
|
||||||
import com.intellij.codeInsight.daemon.HighlightDisplayKey
|
|
||||||
import com.intellij.codeInsight.intention.IntentionAction
|
import com.intellij.codeInsight.intention.IntentionAction
|
||||||
import com.intellij.codeInspection.IntentionWrapper
|
import com.intellij.codeInspection.IntentionWrapper
|
||||||
import com.intellij.codeInspection.LocalInspectionEP
|
|
||||||
import com.intellij.openapi.editor.Editor
|
import com.intellij.openapi.editor.Editor
|
||||||
import com.intellij.openapi.extensions.Extensions
|
|
||||||
import com.intellij.openapi.project.Project
|
import com.intellij.openapi.project.Project
|
||||||
import com.intellij.openapi.util.TextRange
|
import com.intellij.openapi.util.TextRange
|
||||||
import com.intellij.profile.codeInspection.InspectionProjectProfileManager
|
|
||||||
import com.intellij.psi.PsiDocumentManager
|
import com.intellij.psi.PsiDocumentManager
|
||||||
import com.intellij.psi.PsiElement
|
import com.intellij.psi.PsiElement
|
||||||
import com.intellij.psi.PsiFile
|
import com.intellij.psi.PsiFile
|
||||||
@@ -35,8 +31,6 @@ import org.jetbrains.kotlin.psi.KtBlockExpression
|
|||||||
import org.jetbrains.kotlin.psi.KtElement
|
import org.jetbrains.kotlin.psi.KtElement
|
||||||
import org.jetbrains.kotlin.psi.psiUtil.containsInside
|
import org.jetbrains.kotlin.psi.psiUtil.containsInside
|
||||||
import org.jetbrains.kotlin.psi.psiUtil.parentsWithSelf
|
import org.jetbrains.kotlin.psi.psiUtil.parentsWithSelf
|
||||||
import java.util.*
|
|
||||||
import kotlin.reflect.KClass
|
|
||||||
|
|
||||||
@Suppress("EqualsOrHashCode")
|
@Suppress("EqualsOrHashCode")
|
||||||
abstract class SelfTargetingIntention<TElement : PsiElement>(
|
abstract class SelfTargetingIntention<TElement : PsiElement>(
|
||||||
@@ -88,25 +82,11 @@ abstract class SelfTargetingIntention<TElement : PsiElement>(
|
|||||||
protected open fun allowCaretInsideElement(element: PsiElement): Boolean =
|
protected open fun allowCaretInsideElement(element: PsiElement): Boolean =
|
||||||
element !is KtBlockExpression
|
element !is KtBlockExpression
|
||||||
|
|
||||||
final override fun isAvailable(project: Project, editor: Editor, file: PsiFile): Boolean {
|
final override fun isAvailable(project: Project, editor: Editor, file: PsiFile) = getTarget(editor, file) != null
|
||||||
val target = getTarget(editor, file) ?: return false
|
|
||||||
return !isIntentionBaseInspectionEnabled(project, target)
|
|
||||||
}
|
|
||||||
|
|
||||||
var inspection: IntentionBasedInspection<TElement>? = null
|
var inspection: IntentionBasedInspection<TElement>? = null
|
||||||
internal set
|
internal set
|
||||||
|
|
||||||
protected fun isIntentionBaseInspectionEnabled(project: Project, target: TElement): Boolean {
|
|
||||||
val inspection = inspection ?: findInspection(this::class.java.kotlin) ?: return false
|
|
||||||
|
|
||||||
val key = HighlightDisplayKey.find(inspection.shortName)
|
|
||||||
if (!InspectionProjectProfileManager.getInstance(project).inspectionProfile.isToolEnabled(key, target)) {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
return inspection.intentionInfos.single { it.intention == this::class.java.kotlin }.additionalChecker(target, inspection)
|
|
||||||
}
|
|
||||||
|
|
||||||
final override fun invoke(project: Project, editor: Editor, file: PsiFile): Unit {
|
final override fun invoke(project: Project, editor: Editor, file: PsiFile): Unit {
|
||||||
PsiDocumentManager.getInstance(project).commitAllDocuments()
|
PsiDocumentManager.getInstance(project).commitAllDocuments()
|
||||||
val target = getTarget(editor, file) ?: return
|
val target = getTarget(editor, file) ?: return
|
||||||
@@ -121,32 +101,11 @@ abstract class SelfTargetingIntention<TElement : PsiElement>(
|
|||||||
override fun equals(other: Any?): Boolean {
|
override fun equals(other: Any?): Boolean {
|
||||||
// Nasty code because IntentionWrapper itself does not override equals
|
// Nasty code because IntentionWrapper itself does not override equals
|
||||||
if (other is IntentionWrapper) return this == other.action
|
if (other is IntentionWrapper) return this == other.action
|
||||||
|
if (other is IntentionBasedInspection<*>.IntentionBasedQuickFix) return this == other.intention
|
||||||
return other is SelfTargetingIntention<*> && javaClass == other.javaClass && text == other.text
|
return other is SelfTargetingIntention<*> && javaClass == other.javaClass && text == other.text
|
||||||
}
|
}
|
||||||
|
|
||||||
// Intentionally missed hashCode (IntentionWrapper does not override it)
|
// Intentionally missed hashCode (IntentionWrapper does not override it)
|
||||||
|
|
||||||
companion object {
|
|
||||||
private val intentionBasedInspections = HashMap<KClass<out SelfTargetingIntention<*>>, IntentionBasedInspection<*>?>()
|
|
||||||
|
|
||||||
fun <TElement : PsiElement> findInspection(intentionClass: KClass<out SelfTargetingIntention<TElement>>): IntentionBasedInspection<TElement>? {
|
|
||||||
if (intentionBasedInspections.containsKey(intentionClass)) {
|
|
||||||
@Suppress("UNCHECKED_CAST")
|
|
||||||
return intentionBasedInspections[intentionClass] as IntentionBasedInspection<TElement>?
|
|
||||||
}
|
|
||||||
|
|
||||||
for (extension in Extensions.getExtensions(LocalInspectionEP.LOCAL_INSPECTION)) {
|
|
||||||
val inspection = extension.instance as? IntentionBasedInspection<*> ?: continue
|
|
||||||
if (inspection.intentionInfos.any { it.intention == intentionClass }) {
|
|
||||||
intentionBasedInspections[intentionClass] = inspection
|
|
||||||
@Suppress("UNCHECKED_CAST")
|
|
||||||
return inspection as IntentionBasedInspection<TElement>
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return null
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
abstract class SelfTargetingRangeIntention<TElement : PsiElement>(
|
abstract class SelfTargetingRangeIntention<TElement : PsiElement>(
|
||||||
|
|||||||
+5
-8
@@ -32,15 +32,12 @@ class ChangePackageToMatchDirectoryIntention : SelfTargetingOffsetIndependentInt
|
|||||||
if (file.isInjectedFragment || file.packageMatchesDirectory()) return false
|
if (file.isInjectedFragment || file.packageMatchesDirectory()) return false
|
||||||
|
|
||||||
val fqNameByDirectory = file.getFqNameByDirectory()
|
val fqNameByDirectory = file.getFqNameByDirectory()
|
||||||
if (!fqNameByDirectory.hasIdentifiersOnly()) {
|
text = if (!fqNameByDirectory.hasIdentifiersOnly()) {
|
||||||
if (isIntentionBaseInspectionEnabled(file.project, element)) {
|
"File package doesn't match directory (cannot fix)"
|
||||||
text = "File package doesn't match directory"
|
}
|
||||||
return true
|
else {
|
||||||
}
|
"Change file's package to '${fqNameByDirectory.asString()}'"
|
||||||
return false
|
|
||||||
}
|
}
|
||||||
|
|
||||||
text = "Change file's package to '${fqNameByDirectory.asString()}'"
|
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user