mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
Java: Implemented enhanced deprecation inspection (JEP 277) for Java 9 (IDEA-159124)
This commit is contained in:
+11
-222
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2017 JetBrains s.r.o.
|
||||
* Copyright 2000-2016 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -15,30 +15,23 @@
|
||||
*/
|
||||
package com.intellij.codeInspection.deprecation;
|
||||
|
||||
import com.intellij.codeInsight.daemon.JavaErrorMessages;
|
||||
import com.intellij.codeInsight.daemon.impl.analysis.HighlightMessageUtil;
|
||||
import com.intellij.codeInsight.daemon.impl.analysis.JavaHighlightUtil;
|
||||
import com.intellij.codeInspection.BaseJavaBatchLocalInspectionTool;
|
||||
import com.intellij.codeInspection.DeprecationUtil;
|
||||
import com.intellij.codeInspection.ProblemHighlightType;
|
||||
import com.intellij.codeInspection.ProblemsHolder;
|
||||
import com.intellij.codeInspection.ui.MultipleCheckboxOptionsPanel;
|
||||
import com.intellij.openapi.util.TextRange;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.impl.PsiImplUtil;
|
||||
import com.intellij.psi.infos.MethodCandidateInfo;
|
||||
import com.intellij.psi.util.MethodSignatureBackedByPsiMethod;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiElementVisitor;
|
||||
import org.intellij.lang.annotations.Pattern;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author max
|
||||
*/
|
||||
public class DeprecationInspection extends BaseJavaBatchLocalInspectionTool {
|
||||
public class DeprecationInspection extends DeprecationInspectionBase {
|
||||
public static final String SHORT_NAME = DeprecationUtil.DEPRECATION_SHORT_NAME;
|
||||
public static final String ID = DeprecationUtil.DEPRECATION_ID;
|
||||
public static final String DISPLAY_NAME = DeprecationUtil.DEPRECATION_DISPLAY_NAME;
|
||||
@@ -51,9 +44,10 @@ public class DeprecationInspection extends BaseJavaBatchLocalInspectionTool {
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public PsiElementVisitor buildVisitor(@NotNull ProblemsHolder holder, boolean isOnTheFly) {
|
||||
public PsiElementVisitor buildVisitor(@NotNull final ProblemsHolder holder, boolean isOnTheFly) {
|
||||
return new DeprecationElementVisitor(holder, IGNORE_INSIDE_DEPRECATED, IGNORE_ABSTRACT_DEPRECATED_OVERRIDES,
|
||||
IGNORE_IMPORT_STATEMENTS, IGNORE_METHODS_OF_DEPRECATED);
|
||||
IGNORE_IMPORT_STATEMENTS, IGNORE_METHODS_OF_DEPRECATED,
|
||||
false);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -81,11 +75,6 @@ public class DeprecationInspection extends BaseJavaBatchLocalInspectionTool {
|
||||
return ID;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEnabledByDefault() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public JComponent createOptionsPanel() {
|
||||
final MultipleCheckboxOptionsPanel panel = new MultipleCheckboxOptionsPanel(this);
|
||||
@@ -96,210 +85,10 @@ public class DeprecationInspection extends BaseJavaBatchLocalInspectionTool {
|
||||
return panel;
|
||||
}
|
||||
|
||||
private static class DeprecationElementVisitor extends JavaElementVisitor {
|
||||
private final ProblemsHolder myHolder;
|
||||
private final boolean myIgnoreInsideDeprecated;
|
||||
private final boolean myIgnoreAbstractDeprecatedOverrides;
|
||||
private final boolean myIgnoreImportStatements;
|
||||
private final boolean myIgnoreMethodsOfDeprecated;
|
||||
|
||||
private DeprecationElementVisitor(ProblemsHolder holder,
|
||||
boolean ignoreInsideDeprecated,
|
||||
boolean ignoreAbstractDeprecatedOverrides,
|
||||
boolean ignoreImportStatements,
|
||||
boolean ignoreMethodsOfDeprecated) {
|
||||
myHolder = holder;
|
||||
myIgnoreInsideDeprecated = ignoreInsideDeprecated;
|
||||
myIgnoreAbstractDeprecatedOverrides = ignoreAbstractDeprecatedOverrides;
|
||||
myIgnoreImportStatements = ignoreImportStatements;
|
||||
myIgnoreMethodsOfDeprecated = ignoreMethodsOfDeprecated;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitReferenceElement(PsiJavaCodeReferenceElement reference) {
|
||||
PsiElement resolved = reference.advancedResolve(true).getElement();
|
||||
PsiElement refName = reference.getReferenceNameElement();
|
||||
checkDeprecated(resolved, refName, null, myIgnoreInsideDeprecated, myIgnoreImportStatements, myIgnoreMethodsOfDeprecated, myHolder);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitImportStaticStatement(PsiImportStaticStatement statement) {
|
||||
PsiJavaCodeReferenceElement importReference = statement.getImportReference();
|
||||
if (importReference != null) {
|
||||
PsiElement refName = importReference.getReferenceNameElement();
|
||||
checkDeprecated(importReference.resolve(), refName, null, myIgnoreInsideDeprecated, false, true, myHolder);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitReferenceExpression(PsiReferenceExpression expression) {
|
||||
visitReferenceElement(expression);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitNewExpression(PsiNewExpression expression) {
|
||||
PsiClass aClass = null;
|
||||
PsiType type = expression.getType();
|
||||
if (type instanceof PsiClassType) {
|
||||
aClass = ((PsiClassType)type).resolveGenerics().getElement();
|
||||
if (aClass instanceof PsiAnonymousClass) {
|
||||
type = ((PsiAnonymousClass)aClass).getBaseClassType();
|
||||
aClass = ((PsiClassType)type).resolveGenerics().getElement();
|
||||
}
|
||||
}
|
||||
if (aClass == null) return;
|
||||
PsiExpressionList list = expression.getArgumentList();
|
||||
PsiResolveHelper resolveHelper = JavaPsiFacade.getInstance(expression.getProject()).getResolveHelper();
|
||||
if (list != null && aClass.getConstructors().length > 0) {
|
||||
JavaResolveResult[] results = resolveHelper.multiResolveConstructor((PsiClassType)type, list, list);
|
||||
MethodCandidateInfo result = null;
|
||||
if (results.length == 1) result = (MethodCandidateInfo)results[0];
|
||||
|
||||
PsiMethod constructor = result == null ? null : result.getElement();
|
||||
PsiJavaCodeReferenceElement ref;
|
||||
if (constructor != null && (ref = expression.getClassOrAnonymousClassReference()) != null) {
|
||||
if (expression.getClassReference() == null && constructor.getParameterList().getParametersCount() == 0) return;
|
||||
checkDeprecated(constructor, ref, null, myIgnoreInsideDeprecated, myIgnoreImportStatements, true, myHolder);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitMethod(PsiMethod method) {
|
||||
MethodSignatureBackedByPsiMethod methodSignature = MethodSignatureBackedByPsiMethod.create(method, PsiSubstitutor.EMPTY);
|
||||
if (!method.isConstructor()) {
|
||||
List<MethodSignatureBackedByPsiMethod> superMethodSignatures = method.findSuperMethodSignaturesIncludingStatic(true);
|
||||
checkMethodOverridesDeprecated(methodSignature, superMethodSignatures, myIgnoreAbstractDeprecatedOverrides, myHolder);
|
||||
}
|
||||
else {
|
||||
checkImplicitCallToSuper(method);
|
||||
}
|
||||
}
|
||||
|
||||
private void checkImplicitCallToSuper(PsiMethod method) {
|
||||
final PsiClass containingClass = method.getContainingClass();
|
||||
assert containingClass != null;
|
||||
final PsiClass superClass = containingClass.getSuperClass();
|
||||
if (hasDefaultDeprecatedConstructor(superClass)) {
|
||||
if (superClass instanceof PsiAnonymousClass) {
|
||||
final PsiExpressionList argumentList = ((PsiAnonymousClass)superClass).getArgumentList();
|
||||
if (argumentList != null && argumentList.getExpressions().length > 0) return;
|
||||
}
|
||||
final PsiCodeBlock body = method.getBody();
|
||||
if (body != null) {
|
||||
final PsiStatement[] statements = body.getStatements();
|
||||
if (statements.length == 0 || !JavaHighlightUtil.isSuperOrThisCall(statements[0], true, true)) {
|
||||
registerDefaultConstructorProblem(superClass, method.getNameIdentifier(), false);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void registerDefaultConstructorProblem(PsiClass superClass, PsiElement nameIdentifier, boolean asDeprecated) {
|
||||
ProblemHighlightType type = asDeprecated ? ProblemHighlightType.LIKE_DEPRECATED : ProblemHighlightType.GENERIC_ERROR_OR_WARNING;
|
||||
myHolder.registerProblem(nameIdentifier, "Default constructor in " + superClass.getQualifiedName() + " is deprecated", type);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitClass(PsiClass aClass) {
|
||||
if (aClass instanceof PsiTypeParameter) return;
|
||||
final PsiMethod[] currentConstructors = aClass.getConstructors();
|
||||
if (currentConstructors.length == 0) {
|
||||
final PsiClass superClass = aClass.getSuperClass();
|
||||
if (hasDefaultDeprecatedConstructor(superClass)) {
|
||||
final boolean isAnonymous = aClass instanceof PsiAnonymousClass;
|
||||
if (isAnonymous) {
|
||||
final PsiExpressionList argumentList = ((PsiAnonymousClass)aClass).getArgumentList();
|
||||
if (argumentList != null && argumentList.getExpressions().length > 0) return;
|
||||
}
|
||||
PsiElement identifier = isAnonymous ? ((PsiAnonymousClass)aClass).getBaseClassReference() : aClass.getNameIdentifier();
|
||||
registerDefaultConstructorProblem(superClass, identifier, isAnonymous);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitRequiresStatement(PsiRequiresStatement statement) {
|
||||
PsiJavaModuleReferenceElement refElement = statement.getReferenceElement();
|
||||
if (refElement != null) {
|
||||
PsiPolyVariantReference ref = refElement.getReference();
|
||||
PsiElement target = ref != null ? ref.resolve() : null;
|
||||
if (target instanceof PsiJavaModule && PsiImplUtil.isDeprecatedByAnnotation((PsiJavaModule)target)) {
|
||||
String message = JavaErrorMessages.message("deprecated.symbol", HighlightMessageUtil.getSymbolName(target));
|
||||
myHolder.registerProblem(refElement, message, ProblemHighlightType.LIKE_DEPRECATED);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean hasDefaultDeprecatedConstructor(PsiClass superClass) {
|
||||
if (superClass != null) {
|
||||
final PsiMethod[] constructors = superClass.getConstructors();
|
||||
for (PsiMethod constructor : constructors) {
|
||||
if (constructor.getParameterList().getParametersCount() == 0 && constructor.isDeprecated()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private static void checkMethodOverridesDeprecated(MethodSignatureBackedByPsiMethod methodSignature,
|
||||
List<MethodSignatureBackedByPsiMethod> superMethodSignatures,
|
||||
boolean ignoreAbstractDeprecatedOverrides,
|
||||
ProblemsHolder holder) {
|
||||
PsiMethod method = methodSignature.getMethod();
|
||||
PsiElement methodName = method.getNameIdentifier();
|
||||
if (methodName == null) return;
|
||||
for (MethodSignatureBackedByPsiMethod superMethodSignature : superMethodSignatures) {
|
||||
PsiMethod superMethod = superMethodSignature.getMethod();
|
||||
PsiClass aClass = superMethod.getContainingClass();
|
||||
if (aClass == null) continue;
|
||||
// do not show deprecated warning for class implementing deprecated methods
|
||||
if (ignoreAbstractDeprecatedOverrides && !aClass.isDeprecated() && superMethod.hasModifierProperty(PsiModifier.ABSTRACT)) continue;
|
||||
if (superMethod.isDeprecated()) {
|
||||
String description = JavaErrorMessages.message("overrides.deprecated.method", HighlightMessageUtil.getSymbolName(aClass));
|
||||
holder.registerProblem(methodName, description, ProblemHighlightType.LIKE_DEPRECATED);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void checkDeprecated(PsiElement refElement,
|
||||
PsiElement elementToHighlight,
|
||||
@Nullable TextRange rangeInElement,
|
||||
ProblemsHolder holder) {
|
||||
checkDeprecated(refElement, elementToHighlight, rangeInElement, false, false, true, holder);
|
||||
checkDeprecated(refElement, elementToHighlight, rangeInElement, false, false, true, holder, false);
|
||||
}
|
||||
|
||||
private static void checkDeprecated(PsiElement refElement,
|
||||
PsiElement elementToHighlight,
|
||||
@Nullable TextRange rangeInElement,
|
||||
boolean ignoreInsideDeprecated,
|
||||
boolean ignoreImportStatements,
|
||||
boolean ignoreMethodsOfDeprecated,
|
||||
ProblemsHolder holder) {
|
||||
if (!(refElement instanceof PsiDocCommentOwner)) return;
|
||||
|
||||
if (!((PsiDocCommentOwner)refElement).isDeprecated()) {
|
||||
if (!ignoreMethodsOfDeprecated) {
|
||||
checkDeprecated(((PsiDocCommentOwner)refElement).getContainingClass(), elementToHighlight, rangeInElement,
|
||||
ignoreInsideDeprecated, ignoreImportStatements, false, holder);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (ignoreInsideDeprecated) {
|
||||
PsiElement parent = elementToHighlight;
|
||||
while ((parent = PsiTreeUtil.getParentOfType(parent, PsiDocCommentOwner.class, true)) != null) {
|
||||
if (((PsiDocCommentOwner)parent).isDeprecated()) return;
|
||||
}
|
||||
}
|
||||
|
||||
if (ignoreImportStatements && PsiTreeUtil.getParentOfType(elementToHighlight, PsiImportStatementBase.class) != null) {
|
||||
return;
|
||||
}
|
||||
|
||||
String description = JavaErrorMessages.message("deprecated.symbol", HighlightMessageUtil.getSymbolName(refElement));
|
||||
holder.registerProblem(elementToHighlight, description, ProblemHighlightType.LIKE_DEPRECATED, rangeInElement);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+286
@@ -0,0 +1,286 @@
|
||||
/*
|
||||
* Copyright 2000-2017 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.intellij.codeInspection.deprecation;
|
||||
|
||||
import com.intellij.codeInsight.AnnotationUtil;
|
||||
import com.intellij.codeInsight.daemon.JavaErrorMessages;
|
||||
import com.intellij.codeInsight.daemon.impl.analysis.HighlightMessageUtil;
|
||||
import com.intellij.codeInsight.daemon.impl.analysis.JavaHighlightUtil;
|
||||
import com.intellij.codeInspection.BaseJavaBatchLocalInspectionTool;
|
||||
import com.intellij.codeInspection.ProblemHighlightType;
|
||||
import com.intellij.codeInspection.ProblemsHolder;
|
||||
import com.intellij.openapi.util.TextRange;
|
||||
import com.intellij.pom.java.LanguageLevel;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.impl.JavaConstantExpressionEvaluator;
|
||||
import com.intellij.psi.impl.PsiImplUtil;
|
||||
import com.intellij.psi.infos.MethodCandidateInfo;
|
||||
import com.intellij.psi.util.MethodSignatureBackedByPsiMethod;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
abstract class DeprecationInspectionBase extends BaseJavaBatchLocalInspectionTool {
|
||||
|
||||
@Override
|
||||
public boolean isEnabledByDefault() {
|
||||
return true;
|
||||
}
|
||||
|
||||
protected static class DeprecationElementVisitor extends JavaElementVisitor {
|
||||
private final ProblemsHolder myHolder;
|
||||
private final boolean myIgnoreInsideDeprecated;
|
||||
private final boolean myIgnoreAbstractDeprecatedOverrides;
|
||||
private final boolean myIgnoreImportStatements;
|
||||
private final boolean myIgnoreMethodsOfDeprecated;
|
||||
private final boolean myForRemoval;
|
||||
|
||||
DeprecationElementVisitor(@NotNull ProblemsHolder holder,
|
||||
boolean ignoreInsideDeprecated,
|
||||
boolean ignoreAbstractDeprecatedOverrides,
|
||||
boolean ignoreImportStatements,
|
||||
boolean ignoreMethodsOfDeprecated,
|
||||
boolean forRemoval) {
|
||||
myHolder = holder;
|
||||
myIgnoreInsideDeprecated = ignoreInsideDeprecated;
|
||||
myIgnoreAbstractDeprecatedOverrides = ignoreAbstractDeprecatedOverrides;
|
||||
myIgnoreImportStatements = ignoreImportStatements;
|
||||
myIgnoreMethodsOfDeprecated = ignoreMethodsOfDeprecated;
|
||||
myForRemoval = forRemoval;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitReferenceElement(PsiJavaCodeReferenceElement reference) {
|
||||
JavaResolveResult result = reference.advancedResolve(true);
|
||||
PsiElement resolved = result.getElement();
|
||||
checkDeprecated(resolved, reference.getReferenceNameElement(), null, myIgnoreInsideDeprecated, myIgnoreImportStatements,
|
||||
myIgnoreMethodsOfDeprecated, myHolder, myForRemoval);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitImportStaticStatement(PsiImportStaticStatement statement) {
|
||||
PsiFile file = statement.getContainingFile();
|
||||
if (file instanceof PsiJavaFile && ((PsiJavaFile)file).getLanguageLevel().isAtLeast(LanguageLevel.JDK_1_9)) return;
|
||||
final PsiJavaCodeReferenceElement importReference = statement.getImportReference();
|
||||
if (importReference != null) {
|
||||
PsiElement resolved = importReference.resolve();
|
||||
checkDeprecated(resolved, importReference.getReferenceNameElement(), null, myIgnoreInsideDeprecated,
|
||||
false, true, myHolder, myForRemoval);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitReferenceExpression(PsiReferenceExpression expression) {
|
||||
visitReferenceElement(expression);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitNewExpression(PsiNewExpression expression) {
|
||||
PsiType type = expression.getType();
|
||||
PsiExpressionList list = expression.getArgumentList();
|
||||
if (!(type instanceof PsiClassType)) return;
|
||||
PsiClassType.ClassResolveResult typeResult = ((PsiClassType)type).resolveGenerics();
|
||||
PsiClass aClass = typeResult.getElement();
|
||||
if (aClass == null) return;
|
||||
if (aClass instanceof PsiAnonymousClass) {
|
||||
type = ((PsiAnonymousClass)aClass).getBaseClassType();
|
||||
typeResult = ((PsiClassType)type).resolveGenerics();
|
||||
aClass = typeResult.getElement();
|
||||
if (aClass == null) return;
|
||||
}
|
||||
final PsiResolveHelper resolveHelper = JavaPsiFacade.getInstance(expression.getProject()).getResolveHelper();
|
||||
final PsiMethod[] constructors = aClass.getConstructors();
|
||||
if (constructors.length > 0 && list != null) {
|
||||
JavaResolveResult[] results = resolveHelper.multiResolveConstructor((PsiClassType)type, list, list);
|
||||
MethodCandidateInfo result = null;
|
||||
if (results.length == 1) result = (MethodCandidateInfo)results[0];
|
||||
|
||||
PsiMethod constructor = result == null ? null : result.getElement();
|
||||
if (constructor != null && expression.getClassOrAnonymousClassReference() != null) {
|
||||
if (expression.getClassReference() == null && constructor.getParameterList().getParametersCount() == 0) return;
|
||||
checkDeprecated(constructor, expression.getClassOrAnonymousClassReference(), null, myIgnoreInsideDeprecated,
|
||||
myIgnoreImportStatements, true, myHolder, myForRemoval);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitMethod(PsiMethod method) {
|
||||
MethodSignatureBackedByPsiMethod methodSignature = MethodSignatureBackedByPsiMethod.create(method, PsiSubstitutor.EMPTY);
|
||||
if (!method.isConstructor()) {
|
||||
List<MethodSignatureBackedByPsiMethod> superMethodSignatures = method.findSuperMethodSignaturesIncludingStatic(true);
|
||||
checkMethodOverridesDeprecated(methodSignature, superMethodSignatures, myIgnoreAbstractDeprecatedOverrides, myHolder, myForRemoval);
|
||||
}
|
||||
else {
|
||||
checkImplicitCallToSuper(method);
|
||||
}
|
||||
}
|
||||
|
||||
private void checkImplicitCallToSuper(PsiMethod method) {
|
||||
final PsiClass containingClass = method.getContainingClass();
|
||||
assert containingClass != null;
|
||||
final PsiClass superClass = containingClass.getSuperClass();
|
||||
if (hasDefaultDeprecatedConstructor(superClass, myForRemoval)) {
|
||||
if (superClass instanceof PsiAnonymousClass) {
|
||||
final PsiExpressionList argumentList = ((PsiAnonymousClass)superClass).getArgumentList();
|
||||
if (argumentList != null && argumentList.getExpressions().length > 0) return;
|
||||
}
|
||||
final PsiCodeBlock body = method.getBody();
|
||||
if (body != null) {
|
||||
final PsiStatement[] statements = body.getStatements();
|
||||
if (statements.length == 0 || !JavaHighlightUtil.isSuperOrThisCall(statements[0], true, true)) {
|
||||
registerDefaultConstructorProblem(superClass, method.getNameIdentifier(), false);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void registerDefaultConstructorProblem(PsiClass superClass, PsiElement nameIdentifier, boolean asDeprecated) {
|
||||
String description =
|
||||
JavaErrorMessages.message(myForRemoval ? "marked.for.removal.default.constructor" : "deprecated.default.constructor",
|
||||
superClass.getQualifiedName());
|
||||
ProblemHighlightType type =
|
||||
asDeprecated && !myForRemoval ? ProblemHighlightType.LIKE_DEPRECATED : ProblemHighlightType.GENERIC_ERROR_OR_WARNING;
|
||||
myHolder.registerProblem(nameIdentifier, description, type);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitClass(PsiClass aClass) {
|
||||
if (aClass instanceof PsiTypeParameter) return;
|
||||
final PsiMethod[] currentConstructors = aClass.getConstructors();
|
||||
if (currentConstructors.length == 0) {
|
||||
final PsiClass superClass = aClass.getSuperClass();
|
||||
if (hasDefaultDeprecatedConstructor(superClass, myForRemoval)) {
|
||||
final boolean isAnonymous = aClass instanceof PsiAnonymousClass;
|
||||
if (isAnonymous) {
|
||||
final PsiExpressionList argumentList = ((PsiAnonymousClass)aClass).getArgumentList();
|
||||
if (argumentList != null && argumentList.getExpressions().length > 0) return;
|
||||
}
|
||||
registerDefaultConstructorProblem(superClass,
|
||||
isAnonymous ? ((PsiAnonymousClass)aClass).getBaseClassReference() : aClass.getNameIdentifier(),
|
||||
isAnonymous);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitRequiresStatement(PsiRequiresStatement statement) {
|
||||
PsiJavaModuleReferenceElement refElement = statement.getReferenceElement();
|
||||
if (refElement != null) {
|
||||
PsiPolyVariantReference ref = refElement.getReference();
|
||||
PsiElement target = ref != null ? ref.resolve() : null;
|
||||
if (target instanceof PsiJavaModule &&
|
||||
isMarkedForRemoval((PsiJavaModule)target, myForRemoval) &&
|
||||
PsiImplUtil.isDeprecatedByAnnotation((PsiJavaModule)target)) {
|
||||
String description = JavaErrorMessages.message(myForRemoval ? "marked.for.removal.symbol" : "deprecated.symbol",
|
||||
HighlightMessageUtil.getSymbolName(target));
|
||||
ProblemHighlightType type = myForRemoval ? ProblemHighlightType.GENERIC_ERROR_OR_WARNING : ProblemHighlightType.LIKE_DEPRECATED;
|
||||
myHolder.registerProblem(refElement, description, type);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean hasDefaultDeprecatedConstructor(PsiClass superClass, boolean forRemoval) {
|
||||
return superClass != null && Arrays.stream(superClass.getConstructors())
|
||||
.anyMatch(constructor -> constructor.getParameterList().getParametersCount() == 0 &&
|
||||
constructor.isDeprecated() &&
|
||||
isMarkedForRemoval(constructor, forRemoval));
|
||||
}
|
||||
|
||||
//@top
|
||||
static void checkMethodOverridesDeprecated(MethodSignatureBackedByPsiMethod methodSignature,
|
||||
List<MethodSignatureBackedByPsiMethod> superMethodSignatures,
|
||||
boolean ignoreAbstractDeprecatedOverrides, ProblemsHolder holder, boolean forRemoval) {
|
||||
PsiMethod method = methodSignature.getMethod();
|
||||
PsiElement methodName = method.getNameIdentifier();
|
||||
if (methodName == null) return;
|
||||
for (MethodSignatureBackedByPsiMethod superMethodSignature : superMethodSignatures) {
|
||||
PsiMethod superMethod = superMethodSignature.getMethod();
|
||||
PsiClass aClass = superMethod.getContainingClass();
|
||||
if (aClass == null) continue;
|
||||
// do not show deprecated warning for class implementing deprecated methods
|
||||
if (ignoreAbstractDeprecatedOverrides && !aClass.isDeprecated() && superMethod.hasModifierProperty(PsiModifier.ABSTRACT)) continue;
|
||||
if (superMethod.isDeprecated() && isMarkedForRemoval(superMethod, forRemoval)) {
|
||||
String description = JavaErrorMessages.message(forRemoval ? "overrides.marked.for.removal.method" : "overrides.deprecated.method",
|
||||
HighlightMessageUtil.getSymbolName(aClass, PsiSubstitutor.EMPTY));
|
||||
ProblemHighlightType type = forRemoval ? ProblemHighlightType.GENERIC_ERROR_OR_WARNING : ProblemHighlightType.LIKE_DEPRECATED;
|
||||
holder.registerProblem(methodName, description, type);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void checkDeprecated(PsiElement refElement,
|
||||
PsiElement elementToHighlight,
|
||||
@Nullable TextRange rangeInElement,
|
||||
boolean ignoreInsideDeprecated,
|
||||
boolean ignoreImportStatements,
|
||||
boolean ignoreMethodsOfDeprecated,
|
||||
ProblemsHolder holder,
|
||||
boolean forRemoval) {
|
||||
if (!(refElement instanceof PsiDocCommentOwner) || !isMarkedForRemoval((PsiDocCommentOwner)refElement, forRemoval)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!((PsiDocCommentOwner)refElement).isDeprecated()) {
|
||||
if (!ignoreMethodsOfDeprecated) {
|
||||
checkDeprecated(((PsiDocCommentOwner)refElement).getContainingClass(), elementToHighlight, rangeInElement,
|
||||
ignoreInsideDeprecated, ignoreImportStatements, false, holder, forRemoval);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (ignoreInsideDeprecated) {
|
||||
PsiElement parent = elementToHighlight;
|
||||
while ((parent = PsiTreeUtil.getParentOfType(parent, PsiDocCommentOwner.class, true)) != null) {
|
||||
if (((PsiDocCommentOwner)parent).isDeprecated()) return;
|
||||
}
|
||||
}
|
||||
|
||||
if (ignoreImportStatements && PsiTreeUtil.getParentOfType(elementToHighlight, PsiImportStatementBase.class) != null) {
|
||||
return;
|
||||
}
|
||||
|
||||
String description = JavaErrorMessages.message(forRemoval ? "marked.for.removal.symbol" : "deprecated.symbol",
|
||||
HighlightMessageUtil.getSymbolName(refElement, PsiSubstitutor.EMPTY));
|
||||
|
||||
ProblemHighlightType type = forRemoval ? ProblemHighlightType.GENERIC_ERROR_OR_WARNING : ProblemHighlightType.LIKE_DEPRECATED;
|
||||
holder.registerProblem(elementToHighlight, description, type, rangeInElement);
|
||||
}
|
||||
|
||||
private static boolean isMarkedForRemoval(PsiModifierListOwner superMethod, boolean forRemoval) {
|
||||
return isMarkedForRemoval(superMethod) == forRemoval;
|
||||
}
|
||||
|
||||
private static boolean isMarkedForRemoval(@Nullable PsiModifierListOwner element) {
|
||||
PsiAnnotation annotation = AnnotationUtil.findAnnotation(element, CommonClassNames.JAVA_LANG_DEPRECATED);
|
||||
if (annotation == null) {
|
||||
return false;
|
||||
}
|
||||
PsiAnnotationMemberValue value = annotation.findAttributeValue("forRemoval");
|
||||
Object result = null;
|
||||
if (value instanceof PsiLiteral) {
|
||||
result = ((PsiLiteral)value).getValue();
|
||||
}
|
||||
else if (value instanceof PsiExpression) {
|
||||
result = JavaConstantExpressionEvaluator.computeConstantExpression((PsiExpression)value, false);
|
||||
}
|
||||
return result instanceof Boolean && ((Boolean)result);
|
||||
}
|
||||
}
|
||||
+68
@@ -0,0 +1,68 @@
|
||||
/*
|
||||
* Copyright 2000-2017 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.intellij.codeInspection.deprecation;
|
||||
|
||||
import com.intellij.codeInspection.DeprecationUtil;
|
||||
import com.intellij.codeInspection.ProblemsHolder;
|
||||
import com.intellij.pom.java.LanguageLevel;
|
||||
import com.intellij.psi.PsiElementVisitor;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import com.intellij.psi.PsiJavaFile;
|
||||
import org.intellij.lang.annotations.Pattern;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class MarkedForRemovalInspection extends DeprecationInspectionBase {
|
||||
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public PsiElementVisitor buildVisitor(@NotNull final ProblemsHolder holder, boolean isOnTheFly) {
|
||||
PsiFile file = holder.getFile();
|
||||
if (file instanceof PsiJavaFile && ((PsiJavaFile)file).getLanguageLevel().isAtLeast(LanguageLevel.JDK_1_9)) {
|
||||
return new DeprecationElementVisitor(holder, false, false,
|
||||
false, false,
|
||||
true);
|
||||
}
|
||||
return PsiElementVisitor.EMPTY_VISITOR;
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public String getDisplayName() {
|
||||
return DeprecationUtil.FOR_REMOVAL_DISPLAY_NAME;
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public String getGroupDisplayName() {
|
||||
return "";
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public String getShortName() {
|
||||
return DeprecationUtil.FOR_REMOVAL_SHORT_NAME;
|
||||
}
|
||||
|
||||
@Pattern(VALID_ID_PATTERN)
|
||||
@Override
|
||||
@NotNull
|
||||
@NonNls
|
||||
public String getID() {
|
||||
return DeprecationUtil.FOR_REMOVAL_ID;
|
||||
}
|
||||
}
|
||||
@@ -167,6 +167,9 @@ constructor.call.must.be.first.statement=Call to ''{0}'' must be first statement
|
||||
direct.abstract.method.access=Abstract method ''{0}'' cannot be accessed directly
|
||||
unrelated.overriding.methods.return.types=methods have unrelated return types
|
||||
overrides.deprecated.method=Overrides deprecated method in ''{0}''
|
||||
overrides.marked.for.removal.method=Overrides method marked for removal in ''{0}''
|
||||
deprecated.default.constructor=Default constructor in ''{0}'' is deprecated
|
||||
marked.for.removal.default.constructor=Default constructor in ''{0}'' is deprecated and marked for removal
|
||||
recursive.constructor.invocation=Recursive constructor invocation
|
||||
wrong.constructor.arguments=''{0}'' cannot be applied to ''{1}''
|
||||
cannot.resolve.constructor=Cannot resolve constructor ''{0}''
|
||||
@@ -275,6 +278,7 @@ numeric.overflow.in.expression=Numeric overflow in expression
|
||||
static.member.accessed.via.instance.reference=Static member ''{0}.{1}'' accessed via instance reference
|
||||
unresolved.label=Undefined label: ''{0}''
|
||||
deprecated.symbol=''{0}'' is deprecated
|
||||
marked.for.removal.symbol=''{0}'' is deprecated and marked for removal
|
||||
qualifier.must.be.expression=Qualifier must be an expression
|
||||
cannot.resolve.symbol=Cannot resolve symbol ''{0}''
|
||||
class.is.already.defined.in.single.static.import=Class ''{0}'' is already defined in a single static import
|
||||
|
||||
@@ -0,0 +1,51 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<problems>
|
||||
|
||||
<problem>
|
||||
<file>Test.java</file>
|
||||
<line>9</line>
|
||||
<description>'Test' is deprecated and marked for removal</description>
|
||||
</problem>
|
||||
|
||||
<problem>
|
||||
<file>Test.java</file>
|
||||
<line>10</line>
|
||||
<description>'Test' is deprecated and marked for removal</description>
|
||||
</problem>
|
||||
|
||||
<problem>
|
||||
<file>Test.java</file>
|
||||
<line>15</line>
|
||||
<description>'Test' is deprecated and marked for removal</description>
|
||||
</problem>
|
||||
|
||||
<problem>
|
||||
<file>Test.java</file>
|
||||
<line>16</line>
|
||||
<description>'Test' is deprecated and marked for removal</description>
|
||||
</problem>
|
||||
|
||||
<problem>
|
||||
<file>Test.java</file>
|
||||
<line>21</line>
|
||||
<description>'Test' is deprecated and marked for removal</description>
|
||||
</problem>
|
||||
|
||||
<problem>
|
||||
<file>Test.java</file>
|
||||
<line>22</line>
|
||||
<description>'Test' is deprecated and marked for removal</description>
|
||||
</problem>
|
||||
|
||||
<problem>
|
||||
<file>Test.java</file>
|
||||
<line>27</line>
|
||||
<description>'Test' is deprecated and marked for removal</description>
|
||||
</problem>
|
||||
|
||||
<problem>
|
||||
<file>Test.java</file>
|
||||
<line>28</line>
|
||||
<description>'Test' is deprecated and marked for removal</description>
|
||||
</problem>
|
||||
</problems>
|
||||
@@ -0,0 +1,36 @@
|
||||
@Deprecated(forRemoval = true)
|
||||
class Test {
|
||||
public Test() {
|
||||
}
|
||||
}
|
||||
|
||||
class Usages {
|
||||
void normal() {
|
||||
Test t =
|
||||
new Test();
|
||||
}
|
||||
|
||||
@Deprecated()
|
||||
void normallyDeprecated() {
|
||||
Test t =
|
||||
new Test();
|
||||
}
|
||||
|
||||
@Deprecated(forRemoval = 1 + 1 == 2)
|
||||
void deprecatedForRemoval() {
|
||||
Test t =
|
||||
new Test();
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
void suppressDeprecation() {
|
||||
Test t =
|
||||
new Test();
|
||||
}
|
||||
|
||||
@SuppressWarnings("removal")
|
||||
void suppressRemoval() {
|
||||
Test t =
|
||||
new Test();
|
||||
}
|
||||
}
|
||||
+21
@@ -0,0 +1,21 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<problems>
|
||||
<problem>
|
||||
<file>Test.java</file>
|
||||
<line>5</line>
|
||||
<description>Default constructor in C is deprecated and marked for removal</description>
|
||||
</problem>
|
||||
|
||||
<problem>
|
||||
<file>Test.java</file>
|
||||
<line>10</line>
|
||||
<description>Default constructor in C is deprecated and marked for removal</description>
|
||||
</problem>
|
||||
|
||||
<problem>
|
||||
<file>Test.java</file>
|
||||
<line>15</line>
|
||||
<description>Default constructor in C is deprecated and marked for removal</description>
|
||||
</problem>
|
||||
</problems>
|
||||
|
||||
+22
@@ -0,0 +1,22 @@
|
||||
class C {
|
||||
@Deprecated(forRemoval=true) C() { }
|
||||
}
|
||||
|
||||
class D extends C {
|
||||
}
|
||||
|
||||
class P {
|
||||
void normal() {
|
||||
new C(){};
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
void suppressDeprecation() {
|
||||
new C(){};
|
||||
}
|
||||
|
||||
@SuppressWarnings("removal")
|
||||
void suppressRemoval() {
|
||||
new C(){};
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<problems>
|
||||
<problem>
|
||||
<file>Test.java</file>
|
||||
<line>6</line>
|
||||
<description>'foo' is deprecated and marked for removal</description>
|
||||
</problem>
|
||||
|
||||
<problem>
|
||||
<file>Test.java</file>
|
||||
<line>11</line>
|
||||
<description>'foo' is deprecated and marked for removal</description>
|
||||
</problem>
|
||||
|
||||
<problem>
|
||||
<file>Test.java</file>
|
||||
<line>16</line>
|
||||
<description>'foo' is deprecated and marked for removal</description>
|
||||
</problem>
|
||||
|
||||
<problem>
|
||||
<file>Test.java</file>
|
||||
<line>21</line>
|
||||
<description>'foo' is deprecated and marked for removal</description>
|
||||
</problem>
|
||||
</problems>
|
||||
@@ -0,0 +1,28 @@
|
||||
public class Test {
|
||||
@Deprecated(forRemoval = true)
|
||||
int foo;
|
||||
|
||||
int normal() {
|
||||
return foo;
|
||||
}
|
||||
|
||||
@Deprecated()
|
||||
int normallyDeprecated() {
|
||||
return foo;
|
||||
}
|
||||
|
||||
@Deprecated(forRemoval = 1 + 1 == 2)
|
||||
int deprecatedForRemoval() {
|
||||
return foo;
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
int suppressDeprecation() {
|
||||
return foo;
|
||||
}
|
||||
|
||||
@SuppressWarnings("removal")
|
||||
int suppressRemoval() {
|
||||
return foo;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<problems>
|
||||
<problem>
|
||||
<file>Test.java</file>
|
||||
<line>6</line>
|
||||
<description>'foo()' is deprecated and marked for removal</description>
|
||||
</problem>
|
||||
|
||||
<problem>
|
||||
<file>Test.java</file>
|
||||
<line>11</line>
|
||||
<description>'foo()' is deprecated and marked for removal</description>
|
||||
</problem>
|
||||
|
||||
<problem>
|
||||
<file>Test.java</file>
|
||||
<line>16</line>
|
||||
<description>'foo()' is deprecated and marked for removal</description>
|
||||
</problem>
|
||||
|
||||
<problem>
|
||||
<file>Test.java</file>
|
||||
<line>21</line>
|
||||
<description>'foo()' is deprecated and marked for removal</description>
|
||||
</problem>
|
||||
</problems>
|
||||
@@ -0,0 +1,28 @@
|
||||
public class Test {
|
||||
@Deprecated(forRemoval = true)
|
||||
void foo() {}
|
||||
|
||||
void normal() {
|
||||
foo();
|
||||
}
|
||||
|
||||
@Deprecated()
|
||||
void normallyDeprecated() {
|
||||
foo();
|
||||
}
|
||||
|
||||
@Deprecated(forRemoval = 1 + 1 == 2)
|
||||
void deprecatedForRemoval() {
|
||||
foo();
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
void suppressDeprecation() {
|
||||
foo();
|
||||
}
|
||||
|
||||
@SuppressWarnings("removal")
|
||||
void suppressRemoval() {
|
||||
foo();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<problems>
|
||||
<problem>
|
||||
<file>Test.java</file>
|
||||
<line>7</line>
|
||||
<description>Overrides method marked for removal in 'Test'</description>
|
||||
</problem>
|
||||
|
||||
<problem>
|
||||
<file>Test.java</file>
|
||||
<line>8</line>
|
||||
<description>'foo()' is deprecated and marked for removal</description>
|
||||
</problem>
|
||||
</problems>
|
||||
@@ -0,0 +1,17 @@
|
||||
public class Test {
|
||||
@Deprecated(forRemoval = true)
|
||||
void foo() {}
|
||||
}
|
||||
|
||||
class Overrides extends Test {
|
||||
void foo() {
|
||||
super.foo();
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("removal")
|
||||
class Suppressed extends Test {
|
||||
void foo() {
|
||||
super.foo();
|
||||
}
|
||||
}
|
||||
+8
-1
@@ -17,6 +17,7 @@ package com.intellij.java.codeInsight.daemon
|
||||
|
||||
import com.intellij.codeInsight.daemon.impl.JavaHighlightInfoTypes
|
||||
import com.intellij.codeInspection.deprecation.DeprecationInspection
|
||||
import com.intellij.codeInspection.deprecation.MarkedForRemovalInspection
|
||||
import com.intellij.java.testFramework.fixtures.LightJava9ModulesCodeInsightFixtureTestCase
|
||||
import com.intellij.java.testFramework.fixtures.MultiModuleJava9ProjectDescriptor.ModuleDescriptor.*
|
||||
import com.intellij.openapi.util.TextRange
|
||||
@@ -296,11 +297,17 @@ class ModuleHighlightingTest : LightJava9ModulesCodeInsightFixtureTestCase() {
|
||||
}
|
||||
|
||||
fun testDeprecations() {
|
||||
myFixture.enableInspections(DeprecationInspection())
|
||||
myFixture.enableInspections(DeprecationInspection(), MarkedForRemovalInspection())
|
||||
addFile("module-info.java", "@Deprecated module M2 { }", M2)
|
||||
highlight("""module M { requires <warning descr="'M2' is deprecated">M2</warning>; }""")
|
||||
}
|
||||
|
||||
fun testMarkedForRemoval() {
|
||||
myFixture.enableInspections(DeprecationInspection(), MarkedForRemovalInspection())
|
||||
addFile("module-info.java", "@Deprecated(forRemoval=true) module M2 { }", M2)
|
||||
highlight("""module M { requires <warning descr="'M2' is deprecated and marked for removal">M2</warning>; }""")
|
||||
}
|
||||
|
||||
fun testPackageConflicts() {
|
||||
addFile("pkg/collision2/C2.java", "package pkg.collision2;\npublic class C2 { }", M2)
|
||||
addFile("pkg/collision4/C4.java", "package pkg.collision4;\npublic class C4 { }", M4)
|
||||
|
||||
+72
@@ -0,0 +1,72 @@
|
||||
/*
|
||||
* Copyright 2000-2017 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.intellij.java.codeInspection;
|
||||
|
||||
import com.intellij.JavaTestUtil;
|
||||
import com.intellij.codeInspection.deprecation.MarkedForRemovalInspection;
|
||||
import com.intellij.openapi.projectRoots.Sdk;
|
||||
import com.intellij.openapi.roots.LanguageLevelProjectExtension;
|
||||
import com.intellij.openapi.roots.ModuleRootModificationUtil;
|
||||
import com.intellij.pom.java.LanguageLevel;
|
||||
import com.intellij.testFramework.IdeaTestUtil;
|
||||
import com.intellij.testFramework.InspectionTestCase;
|
||||
|
||||
/**
|
||||
* @author max
|
||||
*/
|
||||
public class MarkedForRemovalInspectionTest extends InspectionTestCase {
|
||||
@Override
|
||||
protected String getTestDataPath() {
|
||||
return JavaTestUtil.getJavaTestDataPath() + "/inspection";
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setUp() throws Exception {
|
||||
super.setUp();
|
||||
LanguageLevelProjectExtension.getInstance(myJavaFacade.getProject()).setLanguageLevel(LanguageLevel.JDK_1_9);
|
||||
ModuleRootModificationUtil.setModuleSdk(getModule(), getTestProjectSdk());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Sdk getTestProjectSdk() {
|
||||
return IdeaTestUtil.getMockJdk9();
|
||||
}
|
||||
|
||||
private void doTest() {
|
||||
doTest("forRemoval/" + getTestName(true), new MarkedForRemovalInspection());
|
||||
}
|
||||
|
||||
public void testForRemovalClass() {
|
||||
doTest();
|
||||
}
|
||||
|
||||
public void testForRemovalField() {
|
||||
doTest();
|
||||
}
|
||||
|
||||
public void testForRemovalMethod() {
|
||||
doTest();
|
||||
}
|
||||
|
||||
public void testForRemovalOverride() {
|
||||
doTest();
|
||||
}
|
||||
|
||||
public void testForRemovalDefaultConstructorInSuper() {
|
||||
doTest();
|
||||
}
|
||||
}
|
||||
@@ -21,4 +21,8 @@ public class DeprecationUtil {
|
||||
@NonNls public static final String DEPRECATION_SHORT_NAME = "Deprecation";
|
||||
@NonNls public static final String DEPRECATION_DISPLAY_NAME = InspectionsBundle.message("inspection.deprecated.display.name");
|
||||
@NonNls public static final String DEPRECATION_ID = "deprecation";
|
||||
|
||||
@NonNls public static final String FOR_REMOVAL_SHORT_NAME = "MarkedForRemoval";
|
||||
@NonNls public static final String FOR_REMOVAL_DISPLAY_NAME = InspectionsBundle.message("inspection.marked.for.removal.display.name");
|
||||
@NonNls public static final String FOR_REMOVAL_ID = "removal";
|
||||
}
|
||||
|
||||
@@ -100,6 +100,7 @@ dataflow.message.array.index.out.of.bounds=Array index is out of bounds
|
||||
|
||||
#deprecated
|
||||
inspection.deprecated.display.name=Deprecated API usage
|
||||
inspection.marked.for.removal.display.name=Usage of API marked for removal
|
||||
#empty method
|
||||
inspection.empty.method.display.name=Empty method
|
||||
inspection.empty.method.delete.quickfix=Delete unnecessary method(s)
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
<html>
|
||||
<body>
|
||||
This inspection reports usages of deprecated classes, fields, and methods which are marked for removal (Java 9+).
|
||||
</body>
|
||||
</html>
|
||||
@@ -704,9 +704,15 @@
|
||||
implementationClass="com.intellij.codeInspection.javaDoc.JavadocHtmlLintInspection"/>
|
||||
<externalAnnotator language="JAVA" implementationClass="com.intellij.codeInspection.javaDoc.JavadocHtmlLintAnnotator"/>
|
||||
|
||||
<localInspection groupPath="Java" language="JAVA" suppressId="deprecation" shortName="Deprecation" displayName="Deprecated API usage" groupKey="group.names.code.maturity.issues" groupBundle="messages.InspectionsBundle"
|
||||
<localInspection groupPath="Java" language="JAVA" suppressId="deprecation" shortName="Deprecation"
|
||||
key="inspection.deprecated.display.name" bundle="messages.InspectionsBundle"
|
||||
groupKey="group.names.code.maturity.issues" groupBundle="messages.InspectionsBundle"
|
||||
enabledByDefault="true" level="WARNING"
|
||||
implementationClass="com.intellij.codeInspection.deprecation.DeprecationInspection"/>
|
||||
<localInspection groupPath="Java" language="JAVA" suppressId="removal" shortName="MarkedForRemoval"
|
||||
key="inspection.marked.for.removal.display.name" bundle="messages.InspectionsBundle"
|
||||
groupKey="group.names.code.maturity.issues" groupBundle="messages.InspectionsBundle"
|
||||
enabledByDefault="true" level="WARNING" implementationClass="com.intellij.codeInspection.deprecation.MarkedForRemovalInspection"/>
|
||||
<localInspection groupPath="Java" language="JAVA" shortName="DeprecatedIsStillUsed" displayName="Deprecated member is still used"
|
||||
groupKey="group.names.code.maturity.issues" groupBundle="messages.InspectionsBundle" enabledByDefault="true" level="WARNING"
|
||||
implementationClass="com.intellij.codeInspection.DeprecatedIsStillUsedInspection" />
|
||||
|
||||
Reference in New Issue
Block a user