Java: don't create final fields from parameters when this does not compile (IDEA-359981)

GitOrigin-RevId: 3a85c9310c8928cf65459ae1ff1825fabf31ec03
This commit is contained in:
Bas Leijdekkers
2024-10-02 20:13:41 +00:00
committed by intellij-monorepo-bot
parent e5ebf1ddb6
commit 95ed423db6
3 changed files with 33 additions and 14 deletions
@@ -20,13 +20,11 @@ import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.psi.util.PsiUtil;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.containers.MultiMap;
import com.siyeh.ig.psiutils.FinalUtils;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.Comparator;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.*;
import java.util.function.Function;
public final class BindFieldsFromParametersAction implements ModCommandAction {
@@ -159,18 +157,16 @@ public final class BindFieldsFromParametersAction implements ModCommandAction {
return members.stream().sorted(Comparator.comparingInt(o -> parameterList.getParameterIndex(o.getParameter()))).toList();
}
private static void processParameter(@NotNull Project project,
@NotNull PsiParameter parameter,
@NotNull Set<String> usedNames) {
private static void processParameter(@NotNull Project project, @NotNull PsiParameter parameter, @NotNull Set<String> usedNames) {
PsiType type = FieldFromParameterUtils.getSubstitutedType(parameter);
if (type == null) return;
JavaCodeStyleManager styleManager = JavaCodeStyleManager.getInstance(project);
String parameterName = parameter.getName();
String propertyName = styleManager.variableNameToPropertyName(parameterName, VariableKind.PARAMETER);
PsiClass targetClass = PsiTreeUtil.getParentOfType(parameter, PsiClass.class);
if (targetClass == null) return;
if (!(parameter.getDeclarationScope() instanceof PsiMethod method)) return;
PsiClass targetClass = method.getContainingClass();
if (targetClass == null) return;
boolean isMethodStatic = method.hasModifierProperty(PsiModifier.STATIC);
@@ -178,7 +174,6 @@ public final class BindFieldsFromParametersAction implements ModCommandAction {
SuggestedNameInfo suggestedNameInfo = styleManager.suggestVariableName(kind, propertyName, null, type);
String[] names = suggestedNameInfo.names;
boolean isFinal = !isMethodStatic && method.isConstructor();
String name = names[0];
for (String curName : names) {
if (!usedNames.contains(curName)) {
@@ -200,10 +195,15 @@ public final class BindFieldsFromParametersAction implements ModCommandAction {
}
}
}
String fieldName = usedNames.add(name) ? name : JavaCodeStyleManager.getInstance(project).suggestUniqueVariableName(name, parameter, true);
String fieldName = usedNames.add(name) ? name : styleManager.suggestUniqueVariableName(name, parameter, true);
FieldFromParameterUtils.createFieldAndAddAssignment(project, targetClass, method, parameter, type, fieldName, isMethodStatic, isFinal);
boolean maybeFinal = !isMethodStatic && method.isConstructor();
boolean isFinal = maybeFinal && targetClass.getConstructors().length == 1;
PsiField field = FieldFromParameterUtils.createFieldAndAddAssignment(
project, targetClass, method, parameter, type, fieldName, isMethodStatic, isFinal);
if (field != null && maybeFinal && !isFinal && FinalUtils.canBeFinal(field)) {
Objects.requireNonNull(field.getModifierList()).setModifierProperty(PsiModifier.FINAL, true);
}
}
private static boolean isFieldAssigned(PsiField field, PsiMethod method) {
@@ -0,0 +1,11 @@
// "Bind constructor parameters to fields" "true-preview"
class Xerxes {
private int myValue;
Xerxes(String s) {
}
<caret>Xerxes(int value) {
myValue = value;
}
}
@@ -0,0 +1,8 @@
// "Bind constructor parameters to fields" "true-preview"
class Xerxes {
Xerxes(String s) {
}
<caret>Xerxes(int value) {
}
}