Java: "Suppress for <x>" fix should not make code uncompilable (IDEA-358115)

GitOrigin-RevId: 754d0bac805a0e9d56489c63e5486d6e7e15a4db
This commit is contained in:
Bas Leijdekkers
2024-08-22 15:08:11 +02:00
committed by intellij-monorepo-bot
parent c9cf2bb994
commit 1a5e213e96
7 changed files with 67 additions and 22 deletions

View File

@@ -1,4 +1,4 @@
// Copyright 2000-2021 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.
// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package com.intellij.codeInspection;
import com.intellij.codeInsight.AnnotationUtil;
@@ -21,6 +21,7 @@ import com.intellij.psi.javadoc.PsiDocTag;
import com.intellij.psi.util.*;
import com.intellij.util.IncorrectOperationException;
import com.intellij.util.containers.ContainerUtil;
import com.siyeh.ig.psiutils.ExpressionUtils;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -253,36 +254,38 @@ public final class JavaSuppressionUtil {
private static PsiAnnotation createNewAnnotation(@NotNull Project project,
PsiElement container,
PsiAnnotation annotation,
@NotNull String id) throws IncorrectOperationException {
@NotNull String id) {
String escaped = '"' + StringUtil.escapeStringCharacters(id) + '"';
if (annotation == null) {
return JavaPsiFacade.getElementFactory(project)
.createAnnotationFromText("@" + SUPPRESS_INSPECTIONS_ANNOTATION_NAME + "(\"" + id + "\")", container);
.createAnnotationFromText("@" + SUPPRESS_INSPECTIONS_ANNOTATION_NAME + "(" + escaped + ")", container);
}
String currentSuppressedId = "\"" + id + "\"";
String annotationText = annotation.getText();
if (annotationText.contains("{")) {
int curlyBraceIndex = annotationText.lastIndexOf('}');
if (curlyBraceIndex > 0) {
String oldSuppressWarning = annotationText.substring(0, curlyBraceIndex);
if (oldSuppressWarning.contains(currentSuppressedId)) return null;
return JavaPsiFacade.getElementFactory(project).createAnnotationFromText(
oldSuppressWarning + ", " + currentSuppressedId + "})", container);
StringBuilder newAnnotationText = new StringBuilder("@").append(SUPPRESS_INSPECTIONS_ANNOTATION_NAME).append("(");
PsiAnnotationMemberValue value = annotation.findAttributeValue("value");
if (value instanceof PsiArrayInitializerMemberValue array) {
PsiAnnotationMemberValue[] initializers = array.getInitializers();
if (initializers.length > 0) {
newAnnotationText.append('{');
for (PsiAnnotationMemberValue initializer : initializers) {
newAnnotationText.append(initializer.getText()).append(',');
if (initializer instanceof PsiExpression expression) {
if (id.equals(ExpressionUtils.computeConstantExpression(expression))) return null;
}
}
newAnnotationText.append(escaped).append('}');
}
else {
throw new IncorrectOperationException(annotationText);
newAnnotationText.append(escaped);
}
}
else if (value instanceof PsiExpression expression) {
if (id.equals(ExpressionUtils.computeConstantExpression(expression))) return null;
newAnnotationText.append("{").append(expression.getText()).append(", ").append(escaped).append("}");
}
else {
PsiNameValuePair[] attributes = annotation.getParameterList().getAttributes();
if (attributes.length == 1) {
String suppressedWarnings = attributes[0].getText();
if (suppressedWarnings.contains(currentSuppressedId)) return null;
return JavaPsiFacade.getElementFactory(project).createAnnotationFromText(
"@" + SUPPRESS_INSPECTIONS_ANNOTATION_NAME + "({" + suppressedWarnings + ", " + currentSuppressedId + "})", container);
}
newAnnotationText.append(escaped);
}
return null;
return JavaPsiFacade.getElementFactory(project).createAnnotationFromText(newAnnotationText.append(")").toString(), container);
}
public static boolean canHave15Suppressions(@NotNull PsiElement file) {

View File

@@ -0,0 +1,7 @@
// "Suppress for class" "true"
@SuppressWarnings("unused")
class EmptyArray {
public void run() {
int i;
}
}

View File

@@ -0,0 +1,7 @@
// "Suppress for class" "true"
@SuppressWarnings("unused")
class EmptyArray {
public void run() {
int <caret>i;
}
}

View File

@@ -0,0 +1,7 @@
// "Suppress for class" "true"
@SuppressWarnings({"", "unused"})
class Value {
public void run() {
int i;
}
}

View File

@@ -0,0 +1,7 @@
// "Suppress for class" "true"
@SuppressWarnings({})
class EmptyArray {
public void run() {
int <caret>i;
}
}

View File

@@ -0,0 +1,7 @@
// "Suppress for class" "true"
@SuppressWarnings
class EmptyArray {
public void run() {
int <caret>i;
}
}

View File

@@ -0,0 +1,7 @@
// "Suppress for class" "true"
@SuppressWarnings(value="")
class Value {
public void run() {
int <caret>i;
}
}