Skip to content

Commit 71c74c5

Browse files
Fix handling of capitalization in class types (#22)
Co-authored-by: MiniDigger | Martin <admin@benndorf.dev>
1 parent 043435a commit 71c74c5

5 files changed

Lines changed: 64 additions & 13 deletions

File tree

codebook-lvt/src/main/java/io/papermc/codebook/lvt/LvtTypeSuggester.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,7 @@ private String suggestNameFromClassType(final ClassType type) throws IOException
116116
final String baseName = name.substring(1, name.length() - 1);
117117
final String simpleName = getSimpleName(baseName);
118118

119-
return Character.toLowerCase(simpleName.charAt(0)) + simpleName.substring(1);
119+
return LvtUtil.parseSimpleTypeName(simpleName);
120120
}
121121

122122
private static final Splitter dollarSplitter = Splitter.on('$');

codebook-lvt/src/main/java/io/papermc/codebook/lvt/LvtUtil.java

Lines changed: 53 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -41,15 +41,33 @@ public static String capitalize(final String name, final int index) {
4141
return Character.toUpperCase(name.charAt(index)) + name.substring(index + 1);
4242
}
4343

44-
public static @Nullable String decapitalize(final String name, final int index) {
45-
if (!Character.isUpperCase(name.charAt(index))) {
46-
// If the char isn't uppercase, that means it isn't following the typical `lowerCamelCase`
47-
// Java method naming scheme how we expect, so we can't be sure it means what we think it
48-
// means in this instance
49-
return null;
50-
} else {
51-
return Character.toLowerCase(name.charAt(index)) + name.substring(index + 1);
44+
public static String decapitalize(final String name) {
45+
boolean capturingGroup = false;
46+
final StringBuilder result = new StringBuilder();
47+
48+
for (int i = 0; i < name.length(); i++) {
49+
final char character = name.charAt(i);
50+
if (Character.isUpperCase(character)) {
51+
if (capturingGroup) {
52+
if (i < name.length() - 1 && Character.isLowerCase(name.charAt(i + 1))) {
53+
// Next char is lowercase, so this is the start of a new word
54+
result.append(character);
55+
} else {
56+
// Convert the leading capital to lowercase and append to the result
57+
result.append(Character.toLowerCase(character));
58+
}
59+
} else {
60+
// let's start a group, making sure to lowercase if it's the first char of the name
61+
capturingGroup = true;
62+
result.append(i == 0 ? Character.toLowerCase(character) : character);
63+
}
64+
} else {
65+
capturingGroup = false;
66+
result.append(character);
67+
}
5268
}
69+
70+
return result.toString();
5371
}
5472

5573
public static Predicate<String> equalsAny(final String... strings) {
@@ -108,4 +126,31 @@ public static boolean isStringAllUppercase(final String input) {
108126
public static boolean hasPrefix(final String text, final String prefix) {
109127
return text.length() > prefix.length() && text.startsWith(prefix);
110128
}
129+
130+
public static String parseSimpleTypeName(final String simpleName) {
131+
// Parse all capitalized types into lowercase
132+
// UUID -> uuid
133+
// AABB -> aabb
134+
if (LvtUtil.isStringAllUppercase(simpleName)) {
135+
return simpleName.toLowerCase();
136+
}
137+
138+
// Decapitalize
139+
// HelloWorld -> helloWorld
140+
// abstractUUIDFix -> abstractUuidFix
141+
// myCoolAABBClass -> myCoolAabbClass
142+
return LvtUtil.decapitalize(simpleName);
143+
}
144+
145+
@Nullable
146+
public static String parseSimpleTypeNameFromMethod(final String methodName, int prefix) {
147+
if (!Character.isUpperCase(methodName.charAt(prefix))) {
148+
// If the char isn't uppercase, that means it isn't following the typical `lowerCamelCase`
149+
// Java method naming scheme how we expect, so we can't be sure it means what we think it
150+
// means in this instance
151+
return null;
152+
} else {
153+
return LvtUtil.parseSimpleTypeName(methodName.substring(prefix));
154+
}
155+
}
111156
}

codebook-lvt/src/main/java/io/papermc/codebook/lvt/suggestion/NewPrefixSuggester.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,8 @@
2222

2323
package io.papermc.codebook.lvt.suggestion;
2424

25-
import static io.papermc.codebook.lvt.LvtUtil.decapitalize;
2625
import static io.papermc.codebook.lvt.LvtUtil.hasPrefix;
26+
import static io.papermc.codebook.lvt.LvtUtil.parseSimpleTypeNameFromMethod;
2727

2828
import io.papermc.codebook.lvt.suggestion.context.ContainerContext;
2929
import io.papermc.codebook.lvt.suggestion.context.method.MethodCallContext;
@@ -53,6 +53,6 @@ public class NewPrefixSuggester implements LvtSuggester {
5353
return result;
5454
}
5555

56-
return decapitalize(methodName, 3);
56+
return parseSimpleTypeNameFromMethod(methodName, 3);
5757
}
5858
}

codebook-lvt/src/main/java/io/papermc/codebook/lvt/suggestion/SingleVerbSuggester.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222

2323
package io.papermc.codebook.lvt.suggestion;
2424

25-
import static io.papermc.codebook.lvt.LvtUtil.decapitalize;
25+
import static io.papermc.codebook.lvt.LvtUtil.parseSimpleTypeNameFromMethod;
2626
import static io.papermc.codebook.lvt.LvtUtil.tryMatchPrefix;
2727

2828
import io.papermc.codebook.lvt.suggestion.context.ContainerContext;
@@ -49,6 +49,6 @@ public class SingleVerbSuggester implements LvtSuggester {
4949
return null;
5050
}
5151

52-
return decapitalize(methodName, prefix.length());
52+
return parseSimpleTypeNameFromMethod(methodName, prefix.length());
5353
}
5454
}

src/test/resources/io/papermc/codebook/lvt/LvtAssignmentSuggesterTest.csv

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ freeze,net/minecraft/core/RegistryAccess,()Lnet/minecraft/core/RegistryAccess.Fr
88
getName,io/paper/Paper,()Ljava/lang/String;,name
99
getSuperLongDumName,io/paper/Paper,()Ljava/lang/String;,superLongDumName
1010
getOrCreateSomething,io/paper/Paper,()Ljava/lang/String;,something
11+
getUUID,io/paper/Paper,()Ljava/util/UUID;,uuid
1112
# as
1213
asString,io/paper/Paper,()Ljava/lang/String;,string
1314
asLevel,io/paper/paper,()Lnet/minecraft/Level;,level
@@ -75,3 +76,8 @@ nextIntBetween,net/minecraft/util/RandomSource,(II)J,
7576
nextBoolean,net/minecraft/util/RandomSource,()Z,randomBoolean
7677
nextInt,net/minecraft/util/Mth,(Lnet/minecraft/util/RandomSource;)I,randomInt
7778
nextInt,net/minecraft/util/Mth,(I)I,
79+
# capitalization tests
80+
getDOMSource,io/paper/DOMSource,()Lio/paper/DOMSource;,domSource
81+
getThreadMXBean,java/lang/ManagementFactory,()Ljava/lang/management/ThreadMXBean;,threadMxBean
82+
getSectionYFromSectionIndex,net/minecraft/world/level/chunk/LevelChunkSection,()I,sectionYFromSectionIndex
83+
getLinkFSPath,io/paper/LinkFSPath,()Lio/paper/LinkFSPath;,linkFsPath

0 commit comments

Comments
 (0)