mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
ImplicitSubclassInspection cleanup and modernizing
This commit is contained in:
+27
-28
@@ -22,6 +22,7 @@ import com.intellij.codeInspection.*
|
||||
import com.intellij.lang.jvm.JvmClass
|
||||
import com.intellij.lang.jvm.JvmModifier
|
||||
import com.intellij.lang.jvm.JvmModifiersOwner
|
||||
import com.intellij.lang.jvm.JvmNamedElement
|
||||
import com.intellij.lang.jvm.actions.MemberRequest
|
||||
import com.intellij.lang.jvm.actions.createModifierActions
|
||||
import com.intellij.openapi.application.ApplicationManager
|
||||
@@ -29,6 +30,8 @@ import com.intellij.openapi.diagnostic.Logger
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.openapi.ui.Messages
|
||||
import com.intellij.psi.*
|
||||
import com.intellij.uast.UastSmartPointer
|
||||
import com.intellij.uast.createUastSmartPointer
|
||||
import com.intellij.util.IncorrectOperationException
|
||||
import com.intellij.util.SmartList
|
||||
import org.jetbrains.uast.UClass
|
||||
@@ -39,32 +42,31 @@ class ImplicitSubclassInspection : LocalInspectionTool() {
|
||||
|
||||
private fun checkClass(aClass: UClass, manager: InspectionManager, isOnTheFly: Boolean): Array<ProblemDescriptor>? {
|
||||
|
||||
val classIsFinal = aClass.isFinal || aClass.hasModifierProperty(PsiModifier.PRIVATE)
|
||||
val psiClass = aClass.javaPsi
|
||||
val classIsFinal = aClass.isFinal || psiClass.hasModifierProperty(PsiModifier.PRIVATE)
|
||||
|
||||
val problems = SmartList<ProblemDescriptor>()
|
||||
|
||||
val subclassProviders = ImplicitSubclassProvider.EP_NAME.extensions
|
||||
.asSequence().filter { it.isApplicableTo(aClass) }
|
||||
.asSequence().filter { it.isApplicableTo(psiClass) }
|
||||
|
||||
val subclassInfos = subclassProviders.mapNotNull { it.getSubclassingInfo(aClass) }
|
||||
val subclassInfos = subclassProviders.mapNotNull { it.getSubclassingInfo(psiClass) }
|
||||
|
||||
val methodsToOverride = aClass.methods.mapNotNull { method ->
|
||||
subclassInfos
|
||||
.mapNotNull { it.methodsInfo?.get(method)?.description }
|
||||
.mapNotNull { it.methodsInfo?.get(method.javaPsi)?.description }
|
||||
.firstOrNull()?.let { description ->
|
||||
method to description
|
||||
}
|
||||
}
|
||||
|
||||
val methodsToAttachToClassFix = if (classIsFinal)
|
||||
SmartList<SmartPsiElementPointer<UDeclaration>>()
|
||||
SmartList<UastSmartPointer<UDeclaration>>()
|
||||
else null
|
||||
|
||||
val smartPointerManager = SmartPointerManager.getInstance(aClass.project)
|
||||
|
||||
for ((method, description) in methodsToOverride) {
|
||||
if (method.isFinal || method.isStatic || method.hasModifierProperty(PsiModifier.PRIVATE)) {
|
||||
methodsToAttachToClassFix?.add(smartPointerManager.createSmartPsiElementPointer(method, method.containingFile))
|
||||
if (method.isFinal || method.isStatic || method.javaPsi.hasModifierProperty(PsiModifier.PRIVATE)) {
|
||||
methodsToAttachToClassFix?.add(method.createUastSmartPointer())
|
||||
|
||||
val methodFixes = createFixesIfApplicable(method, method.name)
|
||||
problemTargets(method, methodHighlightableModifiersSet).forEach {
|
||||
@@ -81,9 +83,9 @@ class ImplicitSubclassInspection : LocalInspectionTool() {
|
||||
if ((methodsToOverride.isNotEmpty() || classReasonToBeSubclassed != null)) {
|
||||
problemTargets(aClass, classHighlightableModifiersSet).forEach {
|
||||
problems.add(manager.createProblemDescriptor(
|
||||
it, classReasonToBeSubclassed ?: InspectionsBundle.message("inspection.implicit.subclass.display.forClass", aClass.name),
|
||||
it, classReasonToBeSubclassed ?: InspectionsBundle.message("inspection.implicit.subclass.display.forClass", psiClass.name),
|
||||
isOnTheFly,
|
||||
createFixesIfApplicable(aClass, aClass.name ?: "class", methodsToAttachToClassFix ?: emptyList()),
|
||||
createFixesIfApplicable(aClass, psiClass.name ?: "class", methodsToAttachToClassFix ?: emptyList()),
|
||||
ProblemHighlightType.GENERIC_ERROR_OR_WARNING)
|
||||
)
|
||||
}
|
||||
@@ -95,23 +97,22 @@ class ImplicitSubclassInspection : LocalInspectionTool() {
|
||||
|
||||
private fun createFixesIfApplicable(aClass: UDeclaration,
|
||||
hintTargetName: String,
|
||||
methodsToAttachToClassFix: List<SmartPsiElementPointer<UDeclaration>> = emptyList()): Array<LocalQuickFix> {
|
||||
methodsToAttachToClassFix: List<UastSmartPointer<UDeclaration>> = emptyList()): Array<LocalQuickFix> {
|
||||
val fix = MakeExtendableFix(aClass, hintTargetName, methodsToAttachToClassFix)
|
||||
if (!fix.hasActionsToPerform) return emptyArray()
|
||||
return arrayOf(fix)
|
||||
}
|
||||
|
||||
private fun problemTargets(declaration: UDeclaration, highlightableModifiersSet: Set<String>): List<PsiElement> {
|
||||
val modifiersElements = declaration.modifierList?.let {
|
||||
it.getChildren().filter {
|
||||
it is PsiKeyword && highlightableModifiersSet.contains(it.getText())
|
||||
}
|
||||
} ?: emptyList<PsiElement>()
|
||||
val modifiersElements = getRelatedJavaModifiers(declaration, highlightableModifiersSet)
|
||||
if (modifiersElements.isNotEmpty()) return modifiersElements
|
||||
return listOfNotNull(declaration.uastAnchor?.sourcePsi)
|
||||
}
|
||||
|
||||
if (modifiersElements.isEmpty())
|
||||
return (declaration as? PsiNameIdentifierOwner)?.nameIdentifier?.let { listOf(it) } ?: emptyList<PsiElement>()
|
||||
else
|
||||
return modifiersElements
|
||||
private fun getRelatedJavaModifiers(declaration: UDeclaration,
|
||||
highlightableModifiersSet: Set<String>): List<PsiElement> {
|
||||
val modifierList = (declaration.sourcePsi as? PsiModifierListOwner)?.modifierList ?: return emptyList()
|
||||
return modifierList.children.filter { it is PsiKeyword && highlightableModifiersSet.contains(it.getText()) }
|
||||
}
|
||||
|
||||
private val methodHighlightableModifiersSet = setOf(PsiModifier.FINAL, PsiModifier.PRIVATE, PsiModifier.STATIC)
|
||||
@@ -120,8 +121,8 @@ class ImplicitSubclassInspection : LocalInspectionTool() {
|
||||
|
||||
private class MakeExtendableFix(uDeclaration: UDeclaration,
|
||||
hintTargetName: String,
|
||||
val siblings: List<SmartPsiElementPointer<UDeclaration>> = emptyList())
|
||||
: LocalQuickFixOnPsiElement(uDeclaration) {
|
||||
val siblings: List<UastSmartPointer<UDeclaration>> = emptyList())
|
||||
: LocalQuickFixOnPsiElement(uDeclaration.sourcePsi!!) {
|
||||
|
||||
companion object {
|
||||
private val LOG = Logger.getInstance("#com.intellij.codeInspection.inheritance.MakeExtendableFix")
|
||||
@@ -162,14 +163,12 @@ class ImplicitSubclassInspection : LocalInspectionTool() {
|
||||
private fun collectMakeExtendable(declaration: UDeclaration,
|
||||
actionsList: SmartList<IntentionAction>,
|
||||
checkParent: Boolean = true) {
|
||||
val isClassMember = !(declaration is JvmClass)
|
||||
declaration.modifierList?.apply {
|
||||
addIfApplicable(declaration, JvmModifier.FINAL, false, actionsList)
|
||||
val isClassMember = declaration !is JvmClass
|
||||
addIfApplicable(declaration, JvmModifier.FINAL, false, actionsList)
|
||||
addIfApplicable(declaration, JvmModifier.PRIVATE, false, actionsList)
|
||||
if (isClassMember) {
|
||||
addIfApplicable(declaration, JvmModifier.STATIC, false, actionsList)
|
||||
}
|
||||
}
|
||||
if (checkParent && isClassMember) {
|
||||
(declaration.uastParent as? UClass)?.apply {
|
||||
addIfApplicable(this, JvmModifier.FINAL, false, actionsList)
|
||||
@@ -206,7 +205,7 @@ class ImplicitSubclassInspection : LocalInspectionTool() {
|
||||
|
||||
private fun siblingsDescription() =
|
||||
when (siblings.size) {
|
||||
1 -> "'${(siblings.firstOrNull()?.element as? PsiNamedElement)?.name}'"
|
||||
1 -> "'${(siblings.firstOrNull()?.element?.javaPsi as? JvmNamedElement)?.name}'"
|
||||
else -> ""
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user