[util] Merge NameUtilCore#uniqName into UniqueNameGenerator

GitOrigin-RevId: a43f8908b639a6e5b562be99af5f880a85cfac74
This commit is contained in:
Tagir Valeev
2024-04-11 13:27:58 +02:00
committed by intellij-monorepo-bot
parent 5ae32b3ec9
commit 5caf42dc70
10 changed files with 85 additions and 54 deletions

View File

@@ -30,7 +30,7 @@ import com.intellij.util.CommonJavaRefactoringUtil;
import com.intellij.util.IncorrectOperationException;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.containers.MultiMap;
import com.intellij.util.text.NameUtilCore;
import com.intellij.util.text.UniqueNameGenerator;
import com.siyeh.ig.psiutils.*;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -349,12 +349,12 @@ public final class InlineUtil implements CommonJavaInlineUtil {
private static @NotNull String suggestClassName(@NotNull PsiElement place, @NotNull String name) {
PsiResolveHelper helper = PsiResolveHelper.getInstance(place.getProject());
return NameUtilCore.uniqName(
return UniqueNameGenerator.generateUniqueNameOneBased(
name,
n -> helper.resolveReferencedClass(n, place) != null ||
place instanceof PsiClass && place.getParent() instanceof PsiDeclarationStatement decl &&
decl.getParent() instanceof PsiCodeBlock block &&
SyntaxTraverser.psiTraverser(block).filter(PsiClass.class).find(cls -> n.equals(cls.getName())) != null);
n -> helper.resolveReferencedClass(n, place) == null &&
!(place instanceof PsiClass && place.getParent() instanceof PsiDeclarationStatement decl &&
decl.getParent() instanceof PsiCodeBlock block &&
SyntaxTraverser.psiTraverser(block).filter(PsiClass.class).find(cls -> n.equals(cls.getName())) != null));
}
public static boolean isChainingConstructor(PsiMethod constructor) {

View File

@@ -28,6 +28,7 @@ import com.intellij.util.BitUtil;
import com.intellij.util.IncorrectOperationException;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.text.NameUtilCore;
import com.intellij.util.text.UniqueNameGenerator;
import com.siyeh.ig.psiutils.ExpressionUtils;
import com.siyeh.ig.psiutils.MethodCallUtils;
import it.unimi.dsi.fastutil.objects.ReferenceOpenHashSet;
@@ -1089,8 +1090,9 @@ public class JavaCodeStyleManagerImpl extends JavaCodeStyleManager {
boolean allowShadowing,
Predicate<? super PsiVariable> canBeReused) {
PsiElement scope = PsiTreeUtil.getNonStrictParentOfType(place, PsiStatement.class, PsiCodeBlock.class, PsiMethod.class);
return NameUtilCore.uniqName(baseName, name -> hasConflictingVariable(place, name, allowShadowing) ||
lookForward && hasConflictingVariableAfterwards(scope, name, canBeReused));
return UniqueNameGenerator.generateUniqueNameOneBased(
baseName, name -> !hasConflictingVariable(place, name, allowShadowing) &&
(!lookForward || !hasConflictingVariableAfterwards(scope, name, canBeReused)));
}
private static boolean hasConflictingVariable(@Nullable PsiElement place, @NotNull String name, boolean allowShadowing) {

View File

@@ -4,8 +4,8 @@ import java.util.function.Consumer;
class A {
void anonymousToLambda(String s) {
String s12 = "";
Consumer<String> consumer = s13 -> {
String s2 = "";
Consumer<String> consumer = s3 -> {
String s1 = "";
};
}

View File

@@ -4,7 +4,7 @@ import java.util.function.Consumer;
class A {
void anonymousToLambda(String s) {
String s12 = "";
String s2 = "";
Consumer<String> consumer = new Consu<caret>mer<String>() {
@Override
public void accept(final String s) {

View File

@@ -6,7 +6,6 @@ import com.intellij.util.text.NameUtilCore;
import org.junit.Test;
import java.util.Arrays;
import java.util.Set;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
@@ -73,14 +72,4 @@ public class NameUtilTest {
final String[] result = NameUtil.splitNameIntoWords(name);
assertEquals(Arrays.asList(expected).toString(), Arrays.asList(result).toString());
}
@Test
public void testUniqName() {
assertEquals("best", NameUtilCore.uniqName("best", Set.of("test", "test1")::contains));
assertEquals("test1", NameUtilCore.uniqName("test", Set.of("test")::contains));
assertEquals("test2", NameUtilCore.uniqName("test", Set.of("test", "test1")::contains));
assertEquals("test3", NameUtilCore.uniqName("test", Set.of("test", "test1", "test2")::contains));
assertEquals("test3", NameUtilCore.uniqName("test1", Set.of("test", "test1", "test2")::contains));
assertEquals("test3", NameUtilCore.uniqName("test2", Set.of("test", "test1", "test2")::contains));
}
}

View File

@@ -6898,6 +6898,7 @@ c:com.intellij.util.text.UniqueNameGenerator
- s:generateUniqueName(java.lang.String,java.lang.String,java.lang.String,java.lang.String,java.lang.String,com.intellij.openapi.util.Condition):java.lang.String
- s:generateUniqueName(java.lang.String,java.lang.String,java.lang.String,java.util.Collection):java.lang.String
- s:generateUniqueName(java.lang.String,java.util.Collection):java.lang.String
- s:generateUniqueNameOneBased(java.lang.String,com.intellij.openapi.util.Condition):java.lang.String
- f:isUnique(java.lang.String):Z
- f:isUnique(java.lang.String,java.lang.String,java.lang.String):Z
- f:value(java.lang.String):Z

View File

@@ -673,7 +673,6 @@ f:com.intellij.util.text.NameUtilCore
- s:nameToWords(java.lang.String):java.lang.String[]
- s:nextWord(java.lang.String,I):I
- s:splitNameIntoWords(java.lang.String):java.lang.String[]
- s:uniqName(java.lang.String,java.util.function.Predicate):java.lang.String
f:com.intellij.util.text.SemVer
- java.lang.Comparable
- <init>(java.lang.String,I,I,I):V

View File

@@ -7,8 +7,6 @@ import org.jetbrains.annotations.NotNull;
import java.util.ArrayList;
import java.util.List;
import java.util.function.Predicate;
import java.util.regex.Pattern;
public final class NameUtilCore {
@@ -170,29 +168,4 @@ public final class NameUtilCore {
}
return ArrayUtilRt.toStringArray(array);
}
/**
* Generates a unique name
*
* @param origName original symbol name
* @param alreadyUsed a predicate that returns true if a supplied name is already used and we cannot use it
* @return the name based on the origName, which is definitely not used (typically by adding a numeric suffix)
*/
public static @NotNull String uniqName(@NotNull String origName, @NotNull Predicate<@NotNull String> alreadyUsed) {
if (!alreadyUsed.test(origName)) return origName;
String baseName = origName;
int index = 0;
Pattern pattern = Pattern.compile("(.+?)(\\d+)");
java.util.regex.Matcher matcher = pattern.matcher(baseName);
if (matcher.matches()) {
baseName = matcher.group(1);
index = Integer.parseInt(matcher.group(2));
}
while (true) {
String name = baseName + (++index);
if (!alreadyUsed.test(name)) {
return name;
}
}
}
}

View File

@@ -11,6 +11,7 @@ import org.jetbrains.annotations.Nullable;
import java.util.Collection;
import java.util.HashSet;
import java.util.Set;
import java.util.regex.Pattern;
public class UniqueNameGenerator implements Condition<String> {
private final Set<String> myExistingNames = new HashSet<>();
@@ -45,26 +46,78 @@ public class UniqueNameGenerator implements Condition<String> {
return generateUniqueName(defaultName, prefix, suffix, s -> !existingNames.contains(s));
}
/**
* Generates a unique name. Derived names are numbered starting from 2.
*
* @param defaultName original symbol name
* @param validator a predicate that returns false if a supplied name is already used and we cannot use it
* @return the name based on the defaultName, which is definitely not used (typically by adding a numeric suffix)
*/
public static @NlsSafe @NotNull String generateUniqueName(@NotNull String defaultName, @NotNull Condition<? super String> validator) {
return generateUniqueName(defaultName, "", "", validator);
}
/**
* Generates a unique name. Derived names are numbered starting from 1.
*
* @param defaultName original symbol name
* @param validator a predicate that returns false if a supplied name is already used and we cannot use it
* @return the name based on the defaultName, which is definitely not used (typically by adding a numeric suffix)
*/
public static @NlsSafe @NotNull String generateUniqueNameOneBased(@NotNull String defaultName, @NotNull Condition<? super String> validator) {
return generateUniqueName(defaultName, "", "", "", "", validator, 1);
}
/**
* Generates a unique name
*
* @param defaultName original symbol name
* @param prefix prefix to add before defaultName
* @param suffix suffix to add after defaultName
* @param validator a predicate that returns false if a supplied name is already used and we cannot use it
* @return the name based on the defaultName, which is definitely not used (typically by adding a numeric suffix)
*/
public static @NlsSafe @NotNull String generateUniqueName(@NotNull String defaultName, @NotNull String prefix, @NotNull String suffix, @NotNull Condition<? super String> validator) {
return generateUniqueName(defaultName, prefix, suffix, "", "", validator);
}
/**
* Generates a unique name
*
* @param defaultName original symbol name
* @param prefix prefix to add before defaultName
* @param suffix suffix to add after defaultName
* @param beforeNumber infix to separate defaultName and number
* @param afterNumber infix to separate number and suffix
* @param validator a predicate that returns false if a supplied name is already used and we cannot use it
* @return the name based on the defaultName, which is definitely not used (typically by adding a numeric suffix)
*/
public static @NlsSafe @NotNull String generateUniqueName(@NotNull String defaultName, @NotNull String prefix, @NotNull String suffix,
@NotNull String beforeNumber, @NotNull String afterNumber,
@NotNull Condition<? super String> validator) {
return generateUniqueName(defaultName, prefix, suffix, beforeNumber, afterNumber, validator, 2);
}
private static @NlsSafe @NotNull String generateUniqueName(@NotNull String defaultName, @NotNull String prefix, @NotNull String suffix,
@NotNull String beforeNumber, @NotNull String afterNumber,
@NotNull Condition<? super String> validator, int startingNumber) {
String defaultFullName = (prefix + defaultName + suffix).trim();
if (validator.value(defaultFullName)) {
return defaultFullName;
}
for (int i = 2; ; i++) {
String fullName = (prefix + defaultName + beforeNumber + i + afterNumber + suffix).trim();
if (validator.value(fullName)) {
return fullName;
String baseName = defaultName;
Pattern pattern = Pattern.compile("(.+?)" + Pattern.quote(beforeNumber) + "(\\d{1,9})");
java.util.regex.Matcher matcher = pattern.matcher(baseName);
int index = startingNumber;
if (matcher.matches()) {
baseName = matcher.group(1);
index = Integer.parseInt(matcher.group(2)) + 1;
}
while (true) {
String name = (prefix + baseName + beforeNumber + (index++) + afterNumber + suffix).trim();
if (validator.value(name)) {
return name;
}
}
}

View File

@@ -3,6 +3,8 @@ package com.intellij.util.text;
import org.junit.Test;
import java.util.Set;
import static org.junit.Assert.assertEquals;
/**
@@ -32,6 +34,18 @@ public class UniqueNameGeneratorTest {
assertEquals("qwerty2", generator.generateUniqueName("qwerty"));
assertEquals("qwerty3", generator.generateUniqueName("qwerty"));
}
@Test
public void testOneBased() {
assertEquals("xyz1", UniqueNameGenerator.generateUniqueNameOneBased("xyz", x -> !"xyz".equals(x)));
}
@Test
public void testStartingNumber() {
assertEquals("xyz129", UniqueNameGenerator.generateUniqueName("xyz128", Set.of("xyz128")));
assertEquals("xyz130", UniqueNameGenerator.generateUniqueName("xyz128", Set.of("xyz128", "xyz129")));
assertEquals("xyz123_2", UniqueNameGenerator.generateUniqueName("xyz123", "", "", "_", "", s -> !s.equals("xyz123")));
assertEquals("xyz_124", UniqueNameGenerator.generateUniqueName("xyz_123", "", "", "_", "", s -> !s.equals("xyz_123")));
}
@Test
public void testPrefixSuffix() {