IDEA-310500 JavaCodeStyleManager returns more common names for fields and parameters

GitOrigin-RevId: 40dc2a001f35af6cc5cb7db8aeb4c0304016b9fd
This commit is contained in:
Mikhail Pyltsin
2023-01-20 16:50:07 +00:00
committed by intellij-monorepo-bot
parent 9c31aa87da
commit df163482cf
6 changed files with 129 additions and 16 deletions
@@ -8,6 +8,7 @@ import com.intellij.lang.jvm.actions.*
import com.intellij.openapi.components.service
import com.intellij.psi.*
import com.intellij.psi.codeStyle.JavaCodeStyleManager
import com.intellij.psi.codeStyle.VariableKind
import com.intellij.psi.util.createSmartPointer
import com.intellij.psi.util.parentOfTypes
import com.intellij.util.CommonJavaRefactoringUtil
@@ -37,7 +38,7 @@ internal abstract class CreateExecutableFromJavaUsageRequest<out T : PsiCall>(
return argumentList.expressions.map { expression ->
val argType: PsiType? = CommonJavaRefactoringUtil.getTypeByExpression(expression)
val type = CreateFromUsageUtils.getParameterTypeByArgumentType(argType, psiManager, scope)
val names = codeStyleManager.suggestSemanticNames(expression)
val names = codeStyleManager.suggestSemanticNames(expression, VariableKind.PARAMETER)
val expectedTypes = expectedTypes(type, ExpectedType.Kind.SUPERTYPE)
expectedParameter(expectedTypes, names)
}
@@ -572,6 +572,7 @@ public class JavaCodeStyleManagerImpl extends JavaCodeStyleManager {
@NotNull
private NamesByExprInfo suggestVariableNameByExpression(@NotNull PsiExpression expr, @Nullable VariableKind variableKind) {
final LinkedHashSet<String> names = new LinkedHashSet<>();
ContainerUtil.addIfNotNull(names, suggestVariableNameFromConstant(expr, variableKind));
ContainerUtil.addIfNotNull(names, suggestVariableNameFromLiterals(expr));
NamesByExprInfo byExpr = suggestVariableNameByExpressionOnly(expr, variableKind, false);
@@ -591,6 +592,19 @@ public class JavaCodeStyleManagerImpl extends JavaCodeStyleManager {
return new NamesByExprInfo(propertyName, names);
}
@Nullable
private static String suggestVariableNameFromConstant(@NotNull PsiExpression expr, @Nullable VariableKind kind) {
if (kind == null || kind == VariableKind.LOCAL_VARIABLE) {
return null;
}
PsiExpression expression = PsiUtil.skipParenthesizedExprDown(expr);
if (expression instanceof PsiReferenceExpression referenceExpression &&
referenceExpression.resolve() instanceof PsiEnumConstant enumConstant) {
return normalizeTypeName(getTypeName(enumConstant.getType()));
}
return null;
}
@Nullable
private static String suggestVariableNameFromLiterals(@NotNull PsiExpression expr) {
String text = findLiteralText(expr);
@@ -1166,6 +1180,12 @@ public class JavaCodeStyleManagerImpl extends JavaCodeStyleManager {
return suggestVariableNameByExpression(expression, null).names;
}
@NotNull
@Override
public Collection<String> suggestSemanticNames(@NotNull PsiExpression expression, @NotNull VariableKind kind) {
return suggestVariableNameByExpression(expression, kind).names;
}
@NotNull
private Collection<String> suggestSemanticNamesByType(@Nullable PsiType type, @NotNull VariableKind kind) {
return type == null ? Collections.emptyList() : doSuggestNamesByType(type, kind);
@@ -1174,13 +1194,10 @@ public class JavaCodeStyleManagerImpl extends JavaCodeStyleManager {
@Override
@NotNull
public SuggestedNameInfo suggestNames(@NotNull Collection<String> semanticNames, @NotNull VariableKind kind, @Nullable PsiType type) {
final Iterable<String> allSemanticNames;
if (kind == VariableKind.LOCAL_VARIABLE || !isEnum(type)) {
allSemanticNames = ContainerUtil.concat(semanticNames, suggestSemanticNamesByType(type, kind));
}
else {
allSemanticNames = ContainerUtil.concat(suggestSemanticNamesByType(type, kind), semanticNames);
}
final Iterable<String> allSemanticNames = ContainerUtil.concat(
semanticNames,
suggestSemanticNamesByType(type, kind)
);
final Set<String> suggestions = new LinkedHashSet<>(getSuggestionsByNames(allSemanticNames, kind, true));
final String propertyName = ContainerUtil.getFirstItem(semanticNames);
@@ -1197,12 +1214,6 @@ public class JavaCodeStyleManagerImpl extends JavaCodeStyleManager {
};
}
private static boolean isEnum(PsiType type) {
PsiClass aClass = PsiUtil.resolveClassInClassTypeOnly(type);
if (aClass == null) return false;
return aClass.isEnum();
}
@NonNls
@NotNull
private String changeIfNotIdentifier(@NotNull String name) {
@@ -247,6 +247,15 @@ public abstract class JavaCodeStyleManager {
@NotNull
public abstract Collection<String> suggestSemanticNames(@NotNull PsiExpression expression);
/**
* This method is not actually tied to Java Code Style and work similarly to {@link #suggestSemanticNames(PsiExpression)}
* Additionally, this method adds new names from the context, based on VariableKind
* <p>
* Should be used with {@link #suggestNames(Collection, VariableKind, PsiType)}.
*/
@NotNull
public abstract Collection<String> suggestSemanticNames(@NotNull PsiExpression expression, @NotNull VariableKind kind);
@NotNull
public abstract SuggestedNameInfo suggestNames(@NotNull Collection<String> semanticNames,
@NotNull VariableKind kind,
@@ -201,6 +201,12 @@ public class CoreJavaCodeStyleManager extends JavaCodeStyleManager {
return Collections.emptyList();
}
@NotNull
@Override
public Collection<String> suggestSemanticNames(@NotNull PsiExpression expression, @NotNull VariableKind kind) {
return Collections.emptyList();
}
@NotNull
@Override
public SuggestedNameInfo suggestNames(@NotNull Collection<String> semanticNames, @NotNull VariableKind kind, @Nullable PsiType type) {
@@ -5,8 +5,8 @@ class C {
void x(String s1, String s2) {}
private void y(E a) {
x(a.toString(), a.toString());
private void y(E e) {
x(e.toString(), e.toString());
}
}
@@ -0,0 +1,86 @@
// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package com.intellij.codeStyle;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiExpression;
import com.intellij.psi.PsiFile;
import com.intellij.psi.codeStyle.JavaCodeStyleManager;
import com.intellij.psi.codeStyle.VariableKind;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.psi.util.PsiUtilCore;
import com.intellij.testFramework.assertions.Assertions;
import com.intellij.testFramework.fixtures.LightJavaCodeInsightFixtureTestCase;
import org.intellij.lang.annotations.Language;
import org.jetbrains.annotations.NotNull;
import java.util.Collection;
public class CodeStyleManagerTest extends LightJavaCodeInsightFixtureTestCase {
public void testSuggestSemanticNameEnumConstantVariable() {
testSuggestedFirstName("""
public class Test {
public static void main(String[] args) {
check("Some", (Month.J<caret>ANUARY), 17);
}
private enum Month {
JANUARY
}
}
""", "january", VariableKind.LOCAL_VARIABLE);
}
public void testSuggestSemanticNameStringConstant() {
testSuggestedFirstName("""
public class Test {
public static void main(String[] args) {
check("Som<caret>e", (Month.JANUARY), 17);
}
private enum Month {
JANUARY
}
}
""", "Some", VariableKind.LOCAL_VARIABLE);
}
public void testSuggestSemanticNameVariableNameParameter() {
testSuggestedFirstName("""
public class Test {
public static void main(String[] args) {
Month month2 = Month.JANUARY;
check("Some", m<caret>onth2, 17);
}
private enum Month {
JANUARY
}
}
""", "month2", VariableKind.PARAMETER);
}
public void testSuggestSemanticNameEnumConstantParameter() {
testSuggestedFirstName("""
public class Test {
public static void main(String[] args) {
check("Some",(Month.J<caret>ANUARY), 17);
}
private enum Month {
JANUARY
}
}
""", "month", VariableKind.PARAMETER);
}
private void testSuggestedFirstName(@NotNull @Language("JAVA") String text, @NotNull String expected, @NotNull VariableKind parameter) {
PsiFile file = myFixture.configureByText("Test.java", text);
int offset = myFixture.getCaretOffset();
PsiElement element = PsiUtilCore.getElementAtOffset(file, offset);
PsiExpression expression = PsiTreeUtil.getParentOfType(element, PsiExpression.class, false);
final JavaCodeStyleManager javaCodeStyleManager = JavaCodeStyleManager.getInstance(getProject());
Collection<String> names = javaCodeStyleManager.suggestSemanticNames(expression, parameter);
Assertions.assertThat(names.iterator().next()).isEqualToIgnoringCase(expected);
}
}