mirror of
https://gitflic.ru/project/openide/openide.git
synced 2025-12-16 14:23:28 +07:00
ScheduledForRemovalInspection and UnstableApiUsageInspection: convert to Kotlin and support method overriding case.
GitOrigin-RevId: dd24dbf613673ae788e1f2ae0229c0ef27e66fe3
This commit is contained in:
committed by
intellij-monorepo-bot
parent
856a375563
commit
ed1acb9b0d
@@ -4,9 +4,13 @@ jvm.inspections.unstable.api.usage.display.name=Unstable API Usage
|
||||
jvm.inspections.unstable.api.usage.annotations.list=Unstable API annotations
|
||||
jvm.inspections.api.usage.ignore.inside.imports=Ignore inside imports
|
||||
jvm.inspections.unstable.api.usage.description=''{0}'' is marked unstable
|
||||
jvm.inspections.unstable.method.overridden.description=Overridden method ''{0}'' is marked unstable
|
||||
jvm.inspections.scheduled.for.removal.display.name=Usage of API scheduled for removal
|
||||
jvm.inspections.scheduled.for.removal.description.no.version=''{0}'' is scheduled for removal
|
||||
jvm.inspections.scheduled.for.removal.description.with.version=''{0}'' is scheduled for removal in {1}
|
||||
jvm.inspections.scheduled.for.removal.method.overridden.no.version.description=Overridden method ''{0}'' is scheduled for removal
|
||||
jvm.inspections.scheduled.for.removal.method.overridden.with.version.description=Overridden method ''{0}'' is scheduled for removal in {1}
|
||||
|
||||
jvm.inspections.missing.deprecated.annotation.on.scheduled.for.removal.api.display.name=Missing '@Deprecated' annotation on scheduled for removal API
|
||||
jvm.inspections.missing.deprecated.annotation.on.scheduled.for.removal.api.description=Scheduled for removal API must also be marked with '@Deprecated' annotation
|
||||
jvm.inspections.missing.deprecated.annotation.on.scheduled.for.removal.api.quick.fix=Add '@Deprecated' annotation
|
||||
|
||||
@@ -2,9 +2,11 @@
|
||||
package com.intellij.codeInspection;
|
||||
|
||||
import com.intellij.psi.PsiAnnotation;
|
||||
import com.intellij.psi.PsiMethod;
|
||||
import com.intellij.psi.PsiModifierListOwner;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.uast.UElement;
|
||||
import org.jetbrains.uast.UMethod;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@@ -17,4 +19,10 @@ public interface AnnotatedApiUsageProcessor {
|
||||
@NotNull PsiModifierListOwner annotatedTarget,
|
||||
@NotNull List<? extends PsiAnnotation> annotations
|
||||
);
|
||||
|
||||
void processAnnotatedMethodOverriding(
|
||||
@NotNull UMethod method,
|
||||
@NotNull PsiMethod overriddenMethod,
|
||||
@NotNull List<? extends PsiAnnotation> annotations
|
||||
);
|
||||
}
|
||||
|
||||
@@ -19,6 +19,7 @@ import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.uast.UClass;
|
||||
import org.jetbrains.uast.UElement;
|
||||
import org.jetbrains.uast.UExpression;
|
||||
import org.jetbrains.uast.UMethod;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.util.List;
|
||||
@@ -120,6 +121,14 @@ public abstract class AnnotatedElementInspectionBase extends LocalInspectionTool
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void processMethodOverriding(@NotNull UMethod method, @NotNull PsiMethod overriddenMethod) {
|
||||
List<PsiAnnotation> annotations = AnnotationUtil.findAllAnnotations(overriddenMethod, myAnnotations, false);
|
||||
if (!annotations.isEmpty()) {
|
||||
myAnnotatedApiProcessor.processAnnotatedMethodOverriding(method, overriddenMethod, annotations);
|
||||
}
|
||||
}
|
||||
|
||||
private void maybeProcessAnnotatedTarget(@NotNull UElement sourceNode, @NotNull PsiModifierListOwner target) {
|
||||
List<PsiAnnotation> annotations = AnnotationUtil.findAllAnnotations(target, myAnnotations, false);
|
||||
if (annotations.isEmpty()) {
|
||||
|
||||
@@ -1,59 +0,0 @@
|
||||
// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
package com.intellij.codeInspection;
|
||||
|
||||
import com.intellij.analysis.JvmAnalysisBundle;
|
||||
import com.intellij.codeInsight.AnnotationUtil;
|
||||
import com.intellij.psi.PsiAnnotation;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiModifierListOwner;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.uast.UElement;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
//TODO quickfix like in deprecation inspection?
|
||||
public class ScheduledForRemovalInspection extends AnnotatedElementInspectionBase {
|
||||
|
||||
private static final String ANNOTATION_NAME = ApiStatus.ScheduledForRemoval.class.getCanonicalName();
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
protected List<String> getAnnotations() {
|
||||
return Collections.singletonList(ANNOTATION_NAME);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
protected AnnotatedApiUsageProcessor buildAnnotatedApiUsageProcessor(@NotNull ProblemsHolder holder) {
|
||||
return new AnnotatedApiUsageProcessor() {
|
||||
@Override
|
||||
public void processAnnotatedTarget(@NotNull UElement sourceNode,
|
||||
@NotNull PsiModifierListOwner annotatedTarget,
|
||||
@NotNull List<? extends PsiAnnotation> annotations) {
|
||||
if (!AnnotatedElementInspectionBase.isLibraryElement(annotatedTarget)) {
|
||||
return;
|
||||
}
|
||||
//TODO determine highlight severity like in MarkedForRemovalInspection?
|
||||
PsiElement elementToHighlight = sourceNode.getSourcePsi();
|
||||
PsiAnnotation scheduledForRemoval = ContainerUtil.find(
|
||||
annotations, psiAnnotation -> psiAnnotation.hasQualifiedName(ANNOTATION_NAME)
|
||||
);
|
||||
if (elementToHighlight != null && scheduledForRemoval != null) {
|
||||
String inVersion = AnnotationUtil.getDeclaredStringAttributeValue(scheduledForRemoval, "inVersion");
|
||||
String targetText = getPresentableText(annotatedTarget);
|
||||
String message;
|
||||
if (inVersion == null || inVersion.isEmpty()) {
|
||||
message = JvmAnalysisBundle.message("jvm.inspections.scheduled.for.removal.description.no.version", targetText);
|
||||
}
|
||||
else {
|
||||
message = JvmAnalysisBundle.message("jvm.inspections.scheduled.for.removal.description.with.version", targetText, inVersion);
|
||||
}
|
||||
holder.registerProblem(elementToHighlight, message, ProblemHighlightType.LIKE_MARKED_FOR_REMOVAL);
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,76 @@
|
||||
// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
package com.intellij.codeInspection
|
||||
|
||||
import com.intellij.analysis.JvmAnalysisBundle
|
||||
import com.intellij.codeInsight.AnnotationUtil
|
||||
import com.intellij.psi.PsiAnnotation
|
||||
import com.intellij.psi.PsiMethod
|
||||
import com.intellij.psi.PsiModifierListOwner
|
||||
import org.jetbrains.annotations.ApiStatus
|
||||
import org.jetbrains.uast.UDeclaration
|
||||
import org.jetbrains.uast.UElement
|
||||
import org.jetbrains.uast.UMethod
|
||||
import org.jetbrains.uast.sourcePsiElement
|
||||
|
||||
//TODO quickfix like in deprecation inspection?
|
||||
class ScheduledForRemovalInspection : AnnotatedElementInspectionBase() {
|
||||
|
||||
private companion object {
|
||||
private val ANNOTATION_NAME = ApiStatus.ScheduledForRemoval::class.java.canonicalName
|
||||
}
|
||||
|
||||
override fun getAnnotations() = listOf(ANNOTATION_NAME)
|
||||
|
||||
override fun buildAnnotatedApiUsageProcessor(holder: ProblemsHolder): AnnotatedApiUsageProcessor =
|
||||
object : AnnotatedApiUsageProcessor {
|
||||
override fun processAnnotatedTarget(
|
||||
sourceNode: UElement,
|
||||
annotatedTarget: PsiModifierListOwner,
|
||||
annotations: List<PsiAnnotation>
|
||||
) {
|
||||
checkScheduledForRemovalApiUsage(annotatedTarget, sourceNode, annotations, false)
|
||||
}
|
||||
|
||||
override fun processAnnotatedMethodOverriding(
|
||||
method: UMethod,
|
||||
overriddenMethod: PsiMethod,
|
||||
annotations: List<PsiAnnotation>
|
||||
) {
|
||||
checkScheduledForRemovalApiUsage(overriddenMethod, method, annotations, true)
|
||||
}
|
||||
|
||||
private fun checkScheduledForRemovalApiUsage(
|
||||
annotatedTarget: PsiModifierListOwner,
|
||||
sourceNode: UElement,
|
||||
annotations: List<PsiAnnotation>,
|
||||
isMethodOverriding: Boolean
|
||||
) {
|
||||
if (!isLibraryElement(annotatedTarget)) {
|
||||
return
|
||||
}
|
||||
val elementToHighlight = (sourceNode as? UDeclaration)?.uastAnchor.sourcePsiElement ?: sourceNode.sourcePsi
|
||||
val scheduledForRemoval = annotations.find { psiAnnotation -> psiAnnotation.hasQualifiedName(ANNOTATION_NAME) }
|
||||
if (elementToHighlight != null && scheduledForRemoval != null) {
|
||||
val inVersion = AnnotationUtil.getDeclaredStringAttributeValue(scheduledForRemoval, "inVersion")
|
||||
val targetName = getPresentableText(annotatedTarget)
|
||||
val isEmptyVersion = inVersion == null || inVersion.isEmpty()
|
||||
val message: String = when {
|
||||
isEmptyVersion && isMethodOverriding -> JvmAnalysisBundle.message(
|
||||
"jvm.inspections.scheduled.for.removal.method.overridden.no.version.description", targetName
|
||||
)
|
||||
|
||||
!isEmptyVersion && isMethodOverriding -> JvmAnalysisBundle.message(
|
||||
"jvm.inspections.scheduled.for.removal.method.overridden.with.version.description", targetName, inVersion
|
||||
)
|
||||
|
||||
!isEmptyVersion && !isMethodOverriding -> JvmAnalysisBundle.message(
|
||||
"jvm.inspections.scheduled.for.removal.description.with.version", targetName, inVersion
|
||||
)
|
||||
|
||||
else -> JvmAnalysisBundle.message("jvm.inspections.scheduled.for.removal.description.no.version", targetName)
|
||||
}
|
||||
holder.registerProblem(elementToHighlight, message, ProblemHighlightType.LIKE_MARKED_FOR_REMOVAL)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,72 +0,0 @@
|
||||
// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
package com.intellij.codeInspection;
|
||||
|
||||
import com.intellij.analysis.JvmAnalysisBundle;
|
||||
import com.intellij.codeInspection.util.SpecialAnnotationsUtil;
|
||||
import com.intellij.psi.PsiAnnotation;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiModifierListOwner;
|
||||
import com.siyeh.ig.ui.ExternalizableStringSet;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.uast.UElement;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
import java.util.List;
|
||||
|
||||
import static com.intellij.codeInspection.deprecation.DeprecationInspectionBase.getPresentableName;
|
||||
|
||||
public class UnstableApiUsageInspection extends AnnotatedElementInspectionBase {
|
||||
public final List<String> unstableApiAnnotations = new ExternalizableStringSet(
|
||||
"org.jetbrains.annotations.ApiStatus.Experimental",
|
||||
"org.jetbrains.annotations.ApiStatus.Internal",
|
||||
"com.google.common.annotations.Beta",
|
||||
"io.reactivex.annotations.Beta",
|
||||
"io.reactivex.annotations.Experimental",
|
||||
"rx.annotations.Experimental",
|
||||
"rx.annotations.Beta",
|
||||
"org.apache.http.annotation.Beta",
|
||||
"org.gradle.api.Incubating"
|
||||
);
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
protected List<String> getAnnotations() {
|
||||
return unstableApiAnnotations;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
protected AnnotatedApiUsageProcessor buildAnnotatedApiUsageProcessor(@NotNull ProblemsHolder holder) {
|
||||
return new AnnotatedApiUsageProcessor() {
|
||||
@Override
|
||||
public void processAnnotatedTarget(@NotNull UElement sourceNode,
|
||||
@NotNull PsiModifierListOwner annotatedTarget,
|
||||
@NotNull List<? extends PsiAnnotation> annotations) {
|
||||
if (!AnnotatedElementInspectionBase.isLibraryElement(annotatedTarget)) {
|
||||
return;
|
||||
}
|
||||
String message = JvmAnalysisBundle.message("jvm.inspections.unstable.api.usage.description", getPresentableName(annotatedTarget));
|
||||
PsiElement elementToHighlight = sourceNode.getSourcePsi();
|
||||
if (elementToHighlight != null) {
|
||||
holder.registerProblem(elementToHighlight, message, ProblemHighlightType.GENERIC_ERROR_OR_WARNING);
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public JPanel createOptionsPanel() {
|
||||
JPanel checkboxPanel = super.createOptionsPanel();
|
||||
|
||||
//TODO in add annotation window "Include non-project items" should be enabled by default
|
||||
JPanel annotationsListControl = SpecialAnnotationsUtil.createSpecialAnnotationsListControl(
|
||||
unstableApiAnnotations, JvmAnalysisBundle.message("jvm.inspections.unstable.api.usage.annotations.list"));
|
||||
|
||||
JPanel panel = new JPanel(new BorderLayout(2, 2));
|
||||
panel.add(checkboxPanel, BorderLayout.NORTH);
|
||||
panel.add(annotationsListControl, BorderLayout.CENTER);
|
||||
return panel;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,81 @@
|
||||
// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
package com.intellij.codeInspection
|
||||
|
||||
import com.intellij.analysis.JvmAnalysisBundle
|
||||
import com.intellij.codeInspection.deprecation.DeprecationInspectionBase.getPresentableName
|
||||
import com.intellij.codeInspection.util.SpecialAnnotationsUtil
|
||||
import com.intellij.psi.PsiAnnotation
|
||||
import com.intellij.psi.PsiMethod
|
||||
import com.intellij.psi.PsiModifierListOwner
|
||||
import com.siyeh.ig.ui.ExternalizableStringSet
|
||||
import org.jetbrains.uast.UDeclaration
|
||||
import org.jetbrains.uast.UElement
|
||||
import org.jetbrains.uast.UMethod
|
||||
import org.jetbrains.uast.sourcePsiElement
|
||||
import java.awt.BorderLayout
|
||||
import javax.swing.JPanel
|
||||
|
||||
class UnstableApiUsageInspection : AnnotatedElementInspectionBase() {
|
||||
|
||||
val unstableApiAnnotations: List<String> = ExternalizableStringSet(
|
||||
"org.jetbrains.annotations.ApiStatus.Experimental",
|
||||
"org.jetbrains.annotations.ApiStatus.Internal",
|
||||
"com.google.common.annotations.Beta",
|
||||
"io.reactivex.annotations.Beta",
|
||||
"io.reactivex.annotations.Experimental",
|
||||
"rx.annotations.Experimental",
|
||||
"rx.annotations.Beta",
|
||||
"org.apache.http.annotation.Beta",
|
||||
"org.gradle.api.Incubating"
|
||||
)
|
||||
|
||||
override fun getAnnotations() = unstableApiAnnotations
|
||||
|
||||
override fun buildAnnotatedApiUsageProcessor(holder: ProblemsHolder) =
|
||||
object : AnnotatedApiUsageProcessor {
|
||||
override fun processAnnotatedTarget(
|
||||
sourceNode: UElement,
|
||||
annotatedTarget: PsiModifierListOwner,
|
||||
annotations: List<PsiAnnotation>
|
||||
) {
|
||||
checkUnstableApiUsage(annotatedTarget, sourceNode, false)
|
||||
}
|
||||
|
||||
override fun processAnnotatedMethodOverriding(
|
||||
method: UMethod,
|
||||
overriddenMethod: PsiMethod,
|
||||
annotations: List<PsiAnnotation>
|
||||
) {
|
||||
checkUnstableApiUsage(overriddenMethod, method, true)
|
||||
}
|
||||
|
||||
private fun checkUnstableApiUsage(annotatedTarget: PsiModifierListOwner, sourceNode: UElement, isMethodOverriding: Boolean) {
|
||||
if (!isLibraryElement(annotatedTarget)) {
|
||||
return
|
||||
}
|
||||
val targetName = getPresentableName(annotatedTarget)
|
||||
val message = if (isMethodOverriding) {
|
||||
JvmAnalysisBundle.message("jvm.inspections.unstable.method.overridden.description", targetName)
|
||||
} else {
|
||||
JvmAnalysisBundle.message("jvm.inspections.unstable.api.usage.description", targetName)
|
||||
}
|
||||
val elementToHighlight = (sourceNode as? UDeclaration)?.uastAnchor.sourcePsiElement ?: sourceNode.sourcePsi
|
||||
if (elementToHighlight != null) {
|
||||
holder.registerProblem(elementToHighlight, message, ProblemHighlightType.GENERIC_ERROR_OR_WARNING)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun createOptionsPanel(): JPanel {
|
||||
val checkboxPanel = super.createOptionsPanel()
|
||||
|
||||
//TODO in add annotation window "Include non-project items" should be enabled by default
|
||||
val annotationsListControl = SpecialAnnotationsUtil.createSpecialAnnotationsListControl(
|
||||
unstableApiAnnotations, JvmAnalysisBundle.message("jvm.inspections.unstable.api.usage.annotations.list"))
|
||||
|
||||
val panel = JPanel(BorderLayout(2, 2))
|
||||
panel.add(checkboxPanel, BorderLayout.NORTH)
|
||||
panel.add(annotationsListControl, BorderLayout.CENTER)
|
||||
return panel
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user