redundant suppression in the editor: treat suppress ALL

This commit is contained in:
Anna Kozlova
2018-10-01 18:50:39 +02:00
parent daff04fec4
commit fe3955570d
5 changed files with 134 additions and 50 deletions
@@ -0,0 +1,14 @@
// "Remove 'ALL' suppression" "true"
import java.util.*;
class Test {
@SafeVarargs
static <T> List<T> foo(T... t){
return null;
}
void foo() {
List<ArrayList<String>> list = foo(new ArrayList<String>());
}
}
@@ -0,0 +1,15 @@
// "Remove 'ALL' suppression" "true"
import java.util.*;
@SuppressWarnings({"AL<caret>L"})
class Test {
@SafeVarargs
static <T> List<T> foo(T... t){
return null;
}
void foo() {
List<ArrayList<String>> list = foo(new ArrayList<String>());
}
}
@@ -0,0 +1,16 @@
// "Remove 'unchecked' suppression" "false"
import java.util.*;
@SuppressWarnings({"RedundantSuppression"})
class Test {
@SafeVarargs
static <T> List<T> foo(T... t){
return null;
}
@SuppressWarnings({"un<caret>checked"})
void foo() {
List<ArrayList<String>> list = foo(new ArrayList<String>());
}
}
@@ -252,7 +252,8 @@ public class LocalInspectionsPass extends ProgressableTextEditorHighlightingPass
PsiElement element = descriptor.getPsiElement();
if (element != null) {
Document thisDocument = documentManager.getDocument(getFile());
createHighlightsForDescriptor(myInfos, emptyActionRegistered, ilManager, getFile(), thisDocument, new LocalInspectionToolWrapper(localTool), severity, descriptor, element);
createHighlightsForDescriptor(myInfos, emptyActionRegistered, ilManager, getFile(), thisDocument,
new LocalInspectionToolWrapper(localTool), severity, descriptor, element, false);
}
}
}
@@ -432,7 +433,8 @@ public class LocalInspectionsPass extends ProgressableTextEditorHighlightingPass
HighlightSeverity severity = myProfileWrapper.getErrorLevel(HighlightDisplayKey.find(tool.getShortName()), file).getSeverity();
infos.clear();
createHighlightsForDescriptor(infos, emptyActionRegistered, ilManager, file, thisDocument, tool, severity, descriptor, psiElement);
createHighlightsForDescriptor(infos, emptyActionRegistered, ilManager, file, thisDocument, tool, severity, descriptor, psiElement,
myIgnoreSuppressed);
for (HighlightInfo info : infos) {
final EditorColorsScheme colorsScheme = getColorsScheme();
UpdateHighlightersUtil.addHighlighterToEditorIncrementally(myProject, myDocument, getFile(),
@@ -490,7 +492,8 @@ public class LocalInspectionsPass extends ProgressableTextEditorHighlightingPass
ProgressManager.checkCanceled();
PsiElement element = descriptor.getPsiElement();
if (element != null) {
createHighlightsForDescriptor(outInfos, emptyActionRegistered, ilManager, file, documentRange, tool, severity, descriptor, element);
createHighlightsForDescriptor(outInfos, emptyActionRegistered, ilManager, file, documentRange, tool, severity, descriptor, element,
myIgnoreSuppressed);
}
}
}
@@ -506,9 +509,9 @@ public class LocalInspectionsPass extends ProgressableTextEditorHighlightingPass
@NotNull LocalInspectionToolWrapper toolWrapper,
@NotNull HighlightSeverity severity,
@NotNull ProblemDescriptor descriptor,
@NotNull PsiElement element) {
@NotNull PsiElement element, boolean ignoreSuppressed) {
LocalInspectionTool tool = toolWrapper.getTool();
if (myIgnoreSuppressed && SuppressionUtil.inspectionResultSuppressed(element, tool)) {
if (ignoreSuppressed && SuppressionUtil.inspectionResultSuppressed(element, tool)) {
mySuppressedElements.computeIfAbsent(toolWrapper.getID(), shortName -> new HashSet<>()).add(element);
return;
}
@@ -226,15 +226,18 @@ public class RedundantSuppressInspection extends GlobalInspectionTool {
return result.toArray(ProblemDescriptor.EMPTY_ARRAY);
}
private static void collectSuppressions(@NotNull PsiElement element,
Map<PsiElement, Collection<String>> suppressedScopes,
boolean ignoreAll,
RedundantSuppressionDetector suppressor) {
private static boolean collectSuppressions(@NotNull PsiElement element,
Map<PsiElement, Collection<String>> suppressedScopes,
boolean ignoreAll,
RedundantSuppressionDetector suppressor) {
String idsString = suppressor.getSuppressionIds(element);
if (idsString != null && !idsString.isEmpty()) {
List<String> ids = new ArrayList<>();
StringUtil.tokenize(idsString, "[, ]").forEach(ids::add);
if (ignoreAll && (ids.contains(SuppressionUtil.ALL) || ids.contains(SuppressionUtil.ALL.toLowerCase()))) return;
boolean isSuppressAll = ids.contains(SuppressionUtil.ALL) || ids.contains(SuppressionUtil.ALL.toLowerCase());
if (ignoreAll && isSuppressAll) {
return false;
}
Collection<String> suppressed = suppressedScopes.get(element);
if (suppressed == null) {
suppressed = ids;
@@ -247,52 +250,15 @@ public class RedundantSuppressInspection extends GlobalInspectionTool {
}
}
suppressedScopes.put(element, suppressed);
return isSuppressAll;
}
return false;
}
public LocalInspectionTool createLocalTool(RedundantSuppressionDetector suppressor,
Map<String, Set<PsiElement>> toolToSuppressScopes,
Set<String> activeTools) {
return new LocalInspectionTool() {
@NotNull
@Override
public String getShortName() {
return SHORT_NAME;
}
@Nls
@NotNull
@Override
public String getDisplayName() {
return RedundantSuppressInspection.this.getDisplayName();
}
@NotNull
@Override
public PsiElementVisitor buildVisitor(@NotNull ProblemsHolder holder, boolean isOnTheFly) {
return new PsiElementVisitor() {
@Override
public void visitElement(PsiElement element) {
super.visitElement(element);
HashMap<PsiElement, Collection<String>> scopes = new HashMap<>();
collectSuppressions(element, scopes, false, suppressor);
Collection<String> suppressIds = scopes.get(element);
if (suppressIds != null) {
for (String suppressId : suppressIds) {
if (!activeTools.contains(suppressId)) continue;
Set<PsiElement> suppressedPlaces = toolToSuppressScopes.get(suppressId);
if (suppressedPlaces == null || suppressedPlaces.stream().noneMatch(place -> suppressor.isSuppressionFor(element, place, suppressId))) {
holder.registerProblem(element, suppressor.getHighlightingRange(element, suppressId),
InspectionsBundle.message("inspection.redundant.suppression.description"),
suppressor.createRemoveRedundantSuppressionFix(suppressId));
}
}
}
}
};
}
};
return new LocalRedundantSuppressionInspection(suppressor, activeTools, toolToSuppressScopes);
}
private static QuickFix<ProblemDescriptor> createQuickFix(String key) {
@@ -347,4 +313,74 @@ public class RedundantSuppressInspection extends GlobalInspectionTool {
final InspectionManager inspectionManagerEx = InspectionManager.getInstance(file.getProject());
return (GlobalInspectionContextBase)inspectionManagerEx.createNewGlobalContext(false);
}
private class LocalRedundantSuppressionInspection extends LocalInspectionTool implements UnfairLocalInspectionTool {
private final RedundantSuppressionDetector mySuppressor;
private final Set<String> myActiveTools;
private final Map<String, Set<PsiElement>> myToolToSuppressScopes;
private LocalRedundantSuppressionInspection(RedundantSuppressionDetector suppressor,
Set<String> activeTools,
Map<String, Set<PsiElement>> toolToSuppressScopes) {
mySuppressor = suppressor;
myActiveTools = activeTools;
myToolToSuppressScopes = toolToSuppressScopes;
}
@NotNull
@Override
public String getShortName() {
return SHORT_NAME;
}
@Nls
@NotNull
@Override
public String getDisplayName() {
return RedundantSuppressInspection.this.getDisplayName();
}
@NotNull
@Override
public PsiElementVisitor buildVisitor(@NotNull ProblemsHolder holder, boolean isOnTheFly) {
return new PsiElementVisitor() {
@Override
public void visitElement(PsiElement element) {
super.visitElement(element);
HashMap<PsiElement, Collection<String>> scopes = new HashMap<>();
boolean suppressAll = collectSuppressions(element, scopes, IGNORE_ALL, mySuppressor);
if (suppressAll) {
for (String suppressId : myActiveTools) {
if (isSuppressedFor(element, suppressId, myToolToSuppressScopes.get(suppressId))) {
return;
}
}
holder.registerProblem(element, mySuppressor.getHighlightingRange(element, SuppressionUtil.ALL),
InspectionsBundle.message("inspection.redundant.suppression.description"),
mySuppressor.createRemoveRedundantSuppressionFix(SuppressionUtil.ALL));
return;
}
Collection<String> suppressIds = scopes.get(element);
if (suppressIds != null) {
for (String suppressId : suppressIds) {
if (myActiveTools.contains(suppressId) &&
!isSuppressedFor(element, suppressId, myToolToSuppressScopes.get(suppressId)) &&
//suppression in local pass is intentionally disabled to pass ALL
!SuppressionUtil.inspectionResultSuppressed(element, LocalRedundantSuppressionInspection.this)) {
holder.registerProblem(element, mySuppressor.getHighlightingRange(element, suppressId),
InspectionsBundle.message("inspection.redundant.suppression.description"),
mySuppressor.createRemoveRedundantSuppressionFix(suppressId));
}
}
}
}
private boolean isSuppressedFor(PsiElement element, String suppressId, Set<PsiElement> suppressedPlaces) {
return suppressedPlaces != null &&
suppressedPlaces.stream().anyMatch(place -> mySuppressor.isSuppressionFor(element, place, suppressId));
}
};
}
}
}