mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
ImplicitSubclassProvider API updates and ImplicitSubclassInspection descriptions improvements
This commit is contained in:
committed by
nickl
parent
0026a6cd63
commit
3ce45245ee
+1
-1
@@ -23,7 +23,7 @@ public class ImplementedAtRuntimeConditionImpl extends ImplementedAtRuntimeCondi
|
||||
@Override
|
||||
public boolean isImplementedAtRuntime(@NotNull PsiClass psiClass) {
|
||||
for (ImplicitSubclassProvider provider : ImplicitSubclassProvider.Companion.getEP_NAME().getExtensions()) {
|
||||
SubclassingInfo info = provider.getSubclassingInfo(psiClass);
|
||||
ImplicitSubclassProvider.SubclassingInfo info = provider.getSubclassingInfo(psiClass);
|
||||
if (info != null && !info.isAbstract()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
+8
-8
@@ -39,7 +39,7 @@ class ImplicitSubclassInspection : AbstractBaseUastLocalInspectionTool() {
|
||||
val methodsToOverride = aClass.methods.mapNotNull {
|
||||
method ->
|
||||
subclassInfos
|
||||
.mapNotNull { it.getOverridingInfo(method)?.description }
|
||||
.mapNotNull { it.methodsInfo?.get(method)?.description }
|
||||
.firstOrNull()?.let { description ->
|
||||
method to description
|
||||
}
|
||||
@@ -55,8 +55,8 @@ class ImplicitSubclassInspection : AbstractBaseUastLocalInspectionTool() {
|
||||
if (method.isFinal || method.isStatic || method.hasModifierProperty(PsiModifier.PRIVATE)) {
|
||||
methodsToAttachToClassFix?.add(smartPointerManager.createSmartPsiElementPointer(method, method.containingFile))
|
||||
|
||||
val methodFixes = if (method.modifierList.isWritable)
|
||||
arrayOf<LocalQuickFix>(FixSubclassing(method, method.name))
|
||||
val methodFixes = if (canApplyFix(method))
|
||||
arrayOf<LocalQuickFix>(MakeExtendableFix(method, method.name))
|
||||
else
|
||||
emptyArray()
|
||||
|
||||
@@ -76,7 +76,7 @@ class ImplicitSubclassInspection : AbstractBaseUastLocalInspectionTool() {
|
||||
problems.add(manager.createProblemDescriptor(
|
||||
it, classReasonToBeSubclassed ?: InspectionsBundle.message("inspection.implicit.subclass.display.forClass", aClass.name),
|
||||
isOnTheFly,
|
||||
arrayOf<LocalQuickFix>(FixSubclassing(aClass, aClass.name ?: "class", methodsToAttachToClassFix ?: emptyList())),
|
||||
arrayOf<LocalQuickFix>(MakeExtendableFix(aClass, aClass.name ?: "class", methodsToAttachToClassFix ?: emptyList())),
|
||||
ProblemHighlightType.GENERIC_ERROR_OR_WARNING)
|
||||
)
|
||||
}
|
||||
@@ -86,7 +86,7 @@ class ImplicitSubclassInspection : AbstractBaseUastLocalInspectionTool() {
|
||||
return problems.toTypedArray()
|
||||
}
|
||||
|
||||
private fun canApplyFix(aClass: UClass) = aClass.modifierList?.isWritable ?: false
|
||||
private fun canApplyFix(aClass: UDeclaration) = aClass.modifierList?.isWritable ?: false
|
||||
|
||||
private fun problemTargets(declaration: UDeclaration, highlightableModifiersSet: Set<String>): List<PsiElement> {
|
||||
val modifiersElements = declaration.modifierList?.let {
|
||||
@@ -105,9 +105,9 @@ class ImplicitSubclassInspection : AbstractBaseUastLocalInspectionTool() {
|
||||
|
||||
private val classHighlightableModifiersSet = setOf(PsiModifier.FINAL, PsiModifier.PRIVATE)
|
||||
|
||||
private class FixSubclassing(uDeclaration: UDeclaration,
|
||||
hintTargetName: String,
|
||||
val siblings: List<SmartPsiElementPointer<UDeclaration>> = emptyList())
|
||||
private class MakeExtendableFix(uDeclaration: UDeclaration,
|
||||
hintTargetName: String,
|
||||
val siblings: List<SmartPsiElementPointer<UDeclaration>> = emptyList())
|
||||
: LocalQuickFixOnPsiElement(uDeclaration) {
|
||||
|
||||
override fun getFamilyName(): String = QuickFixBundle.message("fix.modifiers.family")
|
||||
|
||||
+21
-25
@@ -55,34 +55,30 @@ abstract class ImplicitSubclassProvider {
|
||||
*/
|
||||
abstract fun getSubclassingInfo(psiClass: PsiClass): SubclassingInfo?
|
||||
|
||||
/**
|
||||
* Information about implicitly overridden methods.
|
||||
* @property description an explanation why this method was overridden.
|
||||
* @property isAbstract is overridden method abstract.
|
||||
*/
|
||||
class OverridingInfo @JvmOverloads constructor(@Nls(capitalization = Sentence)
|
||||
val description: String,
|
||||
val isAbstract: Boolean = false)
|
||||
|
||||
/**
|
||||
* Information about implicitly created subclass.
|
||||
* @property description an explanation why this class was subclassed.
|
||||
* @property isAbstract is created subclass abstract.
|
||||
* @property methodsInfo map of methods overridden in class and corresponding [OverridingInfo]s,
|
||||
* or `null` if no method-level info is provided
|
||||
*/
|
||||
class SubclassingInfo @JvmOverloads constructor(@Nls(capitalization = Sentence)
|
||||
val description: String,
|
||||
val methodsInfo: Map<PsiMethod, OverridingInfo>? = null,
|
||||
val isAbstract: Boolean = false)
|
||||
|
||||
|
||||
companion object {
|
||||
val EP_NAME = ExtensionPointName.create<ImplicitSubclassProvider>("com.intellij.codeInsight.implicitSubclassProvider")
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Information about implicitly overridden methods.
|
||||
* @property description an explanation why this method was overridden.
|
||||
* @property isAbstract is overridden method abstract.
|
||||
*/
|
||||
class OverridingInfo @JvmOverloads constructor(@Nls(capitalization = Sentence)
|
||||
val description: String,
|
||||
val isAbstract: Boolean = false)
|
||||
|
||||
/**
|
||||
* Information about implicitly created subclass.
|
||||
* @property description an explanation why this class was subclassed.
|
||||
* @property isAbstract is created subclass abstract.
|
||||
*/
|
||||
open class SubclassingInfo @JvmOverloads constructor(@Nls(capitalization = Sentence)
|
||||
val description: String,
|
||||
val isAbstract: Boolean = false) {
|
||||
/**
|
||||
* @param method a method of class for which the info was created.
|
||||
* @return an info about reason for method overriding, or `null` if this method will not be overridden.
|
||||
*/
|
||||
open fun getOverridingInfo(method: PsiMethod): OverridingInfo? = null
|
||||
|
||||
}
|
||||
|
||||
@@ -825,11 +825,11 @@ inspection.reflection.invocation.argument.not.assignable=Argument is not assigna
|
||||
inspection.reflection.invocation.item.not.assignable=Array item is not assignable to ''{0}''
|
||||
inspection.reflection.invocation.array.not.assignable=Array {0,choice,1#item has|1<items have} incompatible {0,choice,1#type|1<types}
|
||||
|
||||
inspection.implicit.subclass.display.forClass=Class ''{0}'' is eligible for implicit subclassing and must not be final
|
||||
inspection.implicit.subclass.display.forClass=Class ''{0}'' could be implicitly subclassed and must not be final
|
||||
inspection.implicit.subclass.display.forMethod=Method ''{0}'' should be overridable
|
||||
inspection.implicit.subclass.make.class.extendable=Make class ''{0}'' {1,choice,0#|1#and method {2} |1<and {1} required methods }extendable
|
||||
inspection.implicit.subclass.extendable=Make ''{0}'' overridable
|
||||
inspection.implicit.subclass.display.name=Final class is eligible for implicit subclassing
|
||||
inspection.implicit.subclass.display.name=Final declaration can't be overridden at runtime
|
||||
|
||||
inspection.reflection.visibility.name=Reflective access across modules issues
|
||||
|
||||
|
||||
+1
-2
@@ -16,7 +16,6 @@
|
||||
package com.siyeh.ig.psiutils;
|
||||
|
||||
import com.intellij.codeInspection.inheritance.ImplicitSubclassProvider;
|
||||
import com.intellij.codeInspection.inheritance.SubclassingInfo;
|
||||
import com.intellij.openapi.progress.ProgressManager;
|
||||
import com.intellij.psi.CommonClassNames;
|
||||
import com.intellij.psi.PsiClass;
|
||||
@@ -86,7 +85,7 @@ public class InheritanceUtil {
|
||||
if (!provider.isApplicableTo(aClass)) {
|
||||
continue;
|
||||
}
|
||||
SubclassingInfo info = provider.getSubclassingInfo(aClass);
|
||||
ImplicitSubclassProvider.SubclassingInfo info = provider.getSubclassingInfo(aClass);
|
||||
if (info != null && !info.isAbstract()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -16,10 +16,8 @@
|
||||
package org.jetbrains.idea.devkit.inspections;
|
||||
|
||||
import com.intellij.codeInspection.inheritance.ImplicitSubclassProvider;
|
||||
import com.intellij.codeInspection.inheritance.SubclassingInfo;
|
||||
import com.intellij.psi.PsiClass;
|
||||
import com.intellij.psi.util.InheritanceUtil;
|
||||
import org.jetbrains.annotations.Nls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.idea.devkit.DevKitBundle;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<html>
|
||||
<body>
|
||||
Reports if class is eligible for being subclassed at runtime by some framework (like Spring or Hibernate),
|
||||
Reports if class is could be subclassed at runtime by some framework (like Spring or Hibernate),
|
||||
but something in code prevents this class from being subclassed or method from being overridden.
|
||||
</body>
|
||||
</html>
|
||||
Reference in New Issue
Block a user