Skip to content

Commit 3e784e4

Browse files
committed
fix: edge cases for JavaTypeName and JavaMemberName
1 parent 52cdedb commit 3e784e4

File tree

2 files changed

+33
-13
lines changed

2 files changed

+33
-13
lines changed

src/main/kotlin/JavaNotations.kt

Lines changed: 30 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,13 @@ import javax.lang.model.SourceVersion
1212
* using [SourceVersion.isKeyword].
1313
*/
1414
object JavaTypeName: StringNotation by UpperCamelCase {
15-
override fun print(word: Word) = UpperCamelCase.print(word).makeValidJavaIdentifier()
15+
override fun print(word: Word) = UpperCamelCase.print(
16+
Word(word.parts.mapIndexed { index, wordPart ->
17+
if (index == 0) wordPart.keepOnlyJavaIdentifierChars()
18+
else wordPart.keepOnlyJavaIdentifierContinuationChars()
19+
})
20+
)
21+
.neutralizeJavaReservedKeywords()
1622

1723
override fun toString() = this::class.java.simpleName!!
1824
}
@@ -28,11 +34,14 @@ object JavaMemberName: BaseStringNotation(camelCaseSplitRegex) {
2834
override fun transformPartAfterParse(index: Int, part: String) = part.toLowerCase(Locale.ROOT)
2935

3036
override fun print(word: Word) = word.parts
31-
.foldIndexed(StringBuffer()) { index, left, right ->
32-
val rightPart =
33-
if (left.contains(Regex("[a-zA-Z]"))) right.toFirstUpperOtherLowerCase()
34-
else right.toLowerCase()
35-
left.append(printBeforePart(index, rightPart)).append(rightPart)
37+
.foldIndexed(StringBuffer()) { index, existing, part ->
38+
val filteredPart =
39+
if (index == 0) part.keepOnlyJavaIdentifierChars()
40+
else part.keepOnlyJavaIdentifierContinuationChars()
41+
val nextPart =
42+
if (existing.contains(Regex("[a-zA-Z]"))) filteredPart.toFirstUpperOtherLowerCase()
43+
else filteredPart.toLowerCase()
44+
existing.append(printBeforePart(index, nextPart)).append(nextPart)
3645
}.toString().makeValidJavaIdentifier()
3746
}
3847

@@ -79,15 +88,24 @@ object JavaConstantName: StringNotation by ScreamingSnakeCase {
7988
override fun toString() = this::class.java.simpleName!!
8089
}
8190

82-
private fun String.makeValidJavaIdentifier() = this.keepOnlyJavaIdentifierChars().neutralizeJavaReservedKeywords().ifEmpty { "__" }
91+
private fun String.makeValidJavaIdentifier() = this.keepOnlyJavaIdentifierChars().neutralizeJavaReservedKeywords()
8392

8493
private fun String.keepOnlyJavaIdentifierChars() = this.chars()
8594
.skipWhile { !Character.isJavaIdentifierStart(it) }
86-
.filter { Character.isJavaIdentifierPart(it) }
87-
.collect({ StringBuilder() }, { left, right -> left.appendCodePoint(right) }, { left, right -> left.append(right) })
88-
.toString()
89-
90-
private fun String.neutralizeJavaReservedKeywords() = if (SourceVersion.isKeyword(this)) this + "_" else this
95+
.keepOnlyJavaIdentifierContinuationChars()
96+
.collectToString()
97+
98+
private fun String.keepOnlyJavaIdentifierContinuationChars() = this.chars().keepOnlyJavaIdentifierContinuationChars().collectToString()
99+
private fun IntStream.keepOnlyJavaIdentifierContinuationChars() = this.filter { Character.isJavaIdentifierPart(it) }
100+
private fun IntStream.collectToString() =
101+
this.collect({ StringBuilder() }, { left, right -> left.appendCodePoint(right) }, { left, right -> left.append(right) })
102+
.toString()
103+
104+
private fun String.neutralizeJavaReservedKeywords() = when {
105+
this == "" -> "__"
106+
SourceVersion.isKeyword(this) -> this + "_"
107+
else -> this
108+
}
91109

92110
private inline fun IntStream.skipWhile(crossinline condition: (Int) -> Boolean): IntStream {
93111
var found = false

src/test/kotlin/JavaNotationsTest.kt

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ class JavaTypeNameTest: BaseNotationTest(
66
printOnlyWords = listOf(
77
Word("I’m using", "Bad", "chaRacters!") to "ImusingBadCharacters",
88
Word("1", "type", "name", "4", "you") to "TypeName4You",
9+
Word("handles", "§eight", "correctly") to "HandlesEightCorrectly",
910
Word("removes", "upperCase") to "RemovesUppercase",
1011
Word("") to "__",
1112
Word("1") to "__",
@@ -21,6 +22,7 @@ class JavaMemberNameTest: BaseNotationTest(
2122
printOnlyWords = listOf(
2223
Word("I’m using", "Bad", "chaRacters!") to "imusingBadCharacters",
2324
Word("1", "Member", "name", "4", "you") to "memberName4You",
25+
Word("handles", "§eight", "correctly") to "handlesEightCorrectly",
2426
Word("_", "underscore", "start") to "_underscoreStart",
2527
Word("$", "dollar", "start") to "\$dollarStart",
2628
Word("a", "letter", "start") to "aLetterStart",
@@ -80,7 +82,7 @@ class JavaConstantNameTest: BaseNotationTest(
8082
Word("") to "__",
8183
Word("1") to "__",
8284
Word("8if") to "IF",
83-
Word("enum") to "enum_",
85+
Word("enum") to "ENUM",
8486
Word("_") to "__" ifJvmVersionIsAtLeast 9
8587
)
8688
)

0 commit comments

Comments
 (0)