PossibleHeapPollutionVarargsInspection: behavior changed according to new proposal:

1. Warn on compact/canonical constructor (and annotate it) when present
2. Create compact constructor and annotate it if not present
Review ID: IDEA-CR-56682

GitOrigin-RevId: 9ace593c6ae32490dd37f684054a2e17d93e81a8
This commit is contained in:
Tagir Valeev
2020-01-03 12:03:57 +00:00
committed by intellij-monorepo-bot
parent c1575fc46a
commit acffc2bef9
6 changed files with 43 additions and 9 deletions
@@ -7,6 +7,7 @@ import com.intellij.codeInsight.daemon.impl.analysis.GenericsHighlightUtil;
import com.intellij.codeInsight.daemon.impl.analysis.JavaGenericsUtil;
import com.intellij.codeInsight.intention.AddAnnotationPsiFix;
import com.intellij.openapi.application.WriteAction;
import com.intellij.openapi.command.WriteCommandAction;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.project.Project;
import com.intellij.pom.java.LanguageLevel;
@@ -69,11 +70,19 @@ public class PossibleHeapPollutionVarargsInspection extends AbstractBaseJavaLoca
@Override
public void applyFix(@NotNull Project project, @NotNull ProblemDescriptor descriptor) {
final PsiElement psiElement = descriptor.getPsiElement();
if (psiElement instanceof PsiIdentifier) {
final PsiModifierListOwner psiMethod = (PsiModifierListOwner)psiElement.getParent();
if (psiMethod != null) {
new AddAnnotationPsiFix(CommonClassNames.JAVA_LANG_SAFE_VARARGS, psiMethod, PsiNameValuePair.EMPTY_ARRAY).applyFix(project, descriptor);
}
if (!(psiElement instanceof PsiIdentifier)) return;
PsiModifierListOwner owner = (PsiModifierListOwner)psiElement.getParent();
if (owner instanceof PsiClass) {
PsiClass rec = (PsiClass)owner;
if (!rec.isRecord()) return;
String compactCtorText = "public " + rec.getName() + " {}";
PsiMethod ctor = JavaPsiFacade.getElementFactory(project).createMethodFromText(compactCtorText, owner);
PsiMethod firstMethod = ArrayUtil.getFirstElement(rec.getMethods());
owner = (PsiMethod)WriteCommandAction.writeCommandAction(owner.getContainingFile()).withName(getFamilyName())
.compute(() -> rec.addBefore(ctor, firstMethod));
}
if (owner instanceof PsiMethod) {
new AddAnnotationPsiFix(CommonClassNames.JAVA_LANG_SAFE_VARARGS, owner, PsiNameValuePair.EMPTY_ARRAY).applyFix(project, descriptor);
}
}
}
@@ -120,7 +129,6 @@ public class PossibleHeapPollutionVarargsInspection extends AbstractBaseJavaLoca
if (!PsiUtil.getLanguageLevel(method).isAtLeast(LanguageLevel.JDK_1_7)) return;
if (AnnotationUtil.isAnnotated(method, CommonClassNames.JAVA_LANG_SAFE_VARARGS, 0)) return;
if (!method.isVarArgs()) return;
if (JavaPsiRecordUtil.isCompactConstructor(method)) return;
final PsiParameter[] parameters = method.getParameterList().getParameters();
final PsiParameter psiParameter = parameters[parameters.length - 1];
@@ -139,7 +147,7 @@ public class PossibleHeapPollutionVarargsInspection extends AbstractBaseJavaLoca
PsiRecordComponent lastComponent = ArrayUtil.getLastElement(header.getRecordComponents());
if (lastComponent == null || !lastComponent.isVarArgs()) return;
PsiMethod constructor = JavaPsiRecordUtil.findCanonicalConstructor(aClass);
if (constructor != null && JavaPsiRecordUtil.isExplicitCanonicalConstructor(constructor)) return;
if (constructor != null && constructor.isPhysical()) return; // will be reported on constructor instead
final PsiType type = lastComponent.getType();
LOG.assertTrue(type instanceof PsiEllipsisType, "type: " + type.getCanonicalText() + "; param: " + lastComponent);
@@ -1,5 +1,7 @@
// "Annotate as @SafeVarargs" "true"
@SafeVarargs
public record Test(java.util.List<String>... args) {
@SafeVarargs
public Test {
}
}
@@ -0,0 +1,6 @@
// "Annotate as @SafeVarargs" "true"
record Rec<T>(T... args) {
@SafeVarargs
public Rec {
}
}
@@ -0,0 +1,11 @@
// "Annotate as @SafeVarargs" "true"
public record Test(java.util.List<String>... args) {
static final String FOO = "bar";
@SafeVarargs
public Test {
}
void test() {}
}
@@ -1,4 +1,4 @@
// "Annotate as @SafeVarargs" "false"
// "Annotate as @SafeVarargs" "true"
record Rec<T>(T... args) {
public R<caret>ec {
}
@@ -0,0 +1,7 @@
// "Annotate as @SafeVarargs" "true"
public record T<caret>est(java.util.List<String>... args) {
static final String FOO = "bar";
void test() {}
}